Home | History | Annotate | Line # | Download | only in ntpq
libntpq.c revision 1.1.1.2.16.1
      1  1.1.1.2.16.1     snj /*	$NetBSD: libntpq.c,v 1.1.1.2.16.1 2014/12/25 02:13:07 snj Exp $	*/
      2           1.1  kardel 
      3           1.1  kardel /*****************************************************************************
      4           1.1  kardel  *
      5           1.1  kardel  *  libntpq.c
      6           1.1  kardel  *
      7           1.1  kardel  *  This is the wrapper library for ntpq, the NTP query utility.
      8           1.1  kardel  *  This library reuses the sourcecode from ntpq and exports a number
      9           1.1  kardel  *  of useful functions in a library that can be linked against applications
     10           1.1  kardel  *  that need to query the status of a running ntpd. The whole
     11           1.1  kardel  *  communcation is based on mode 6 packets.
     12           1.1  kardel  *
     13           1.1  kardel  ****************************************************************************/
     14       1.1.1.2  kardel #define LIBNTPQ_C
     15           1.1  kardel #define NO_MAIN_ALLOWED 1
     16           1.1  kardel /* #define BUILD_AS_LIB		Already provided by the Makefile */
     17           1.1  kardel 
     18           1.1  kardel #include "ntpq.c"
     19           1.1  kardel #include "libntpq.h"
     20           1.1  kardel 
     21           1.1  kardel /* Function Prototypes */
     22           1.1  kardel 
     23           1.1  kardel 
     24           1.1  kardel const char *Version = "libntpq 0.3beta";
     25           1.1  kardel 
     26           1.1  kardel /* global variables used for holding snapshots of data */
     27       1.1.1.2  kardel char peervars[NTPQ_BUFLEN];
     28       1.1.1.2  kardel int peervarlen = 0;
     29       1.1.1.2  kardel associd_t peervar_assoc = 0;
     30       1.1.1.2  kardel char clockvars[NTPQ_BUFLEN];
     31       1.1.1.2  kardel int clockvarlen = 0;
     32       1.1.1.2  kardel int clockvar_assoc = 0;
     33       1.1.1.2  kardel char sysvars[NTPQ_BUFLEN];
     34       1.1.1.2  kardel int sysvarlen = 0;
     35       1.1.1.2  kardel char *ntpq_resultbuffer[NTPQ_BUFLEN];
     36       1.1.1.2  kardel unsigned short ntpq_associations[MAXASSOC];
     37           1.1  kardel struct ntpq_varlist ntpq_varlist[MAXLIST];
     38           1.1  kardel 
     39           1.1  kardel /*****************************************************************************
     40           1.1  kardel  *
     41           1.1  kardel  *  ntpq_stripquotes
     42           1.1  kardel  *
     43           1.1  kardel  *  Parses a given character buffer srcbuf and removes all quoted
     44           1.1  kardel  *  characters. The resulting string is copied to the specified
     45           1.1  kardel  *  resultbuf character buffer.  E.g. \" will be translated into "
     46           1.1  kardel  *
     47           1.1  kardel  ****************************************************************************
     48           1.1  kardel  * Parameters:
     49           1.1  kardel  *	resultbuf	char*	The resulting string without quoted
     50           1.1  kardel  *				characters
     51           1.1  kardel  *	srcbuf		char*	The buffer holding the original string
     52           1.1  kardel  *	datalen		int	The number of bytes stored in srcbuf
     53           1.1  kardel  *	maxlen		int	Max. number of bytes for resultbuf
     54           1.1  kardel  *
     55           1.1  kardel  * Returns:
     56           1.1  kardel  *	int		number of chars that have been copied to
     57           1.1  kardel  *			resultbuf
     58           1.1  kardel  ****************************************************************************/
     59           1.1  kardel 
     60           1.1  kardel int ntpq_stripquotes ( char *resultbuf, char *srcbuf, int datalen, int maxlen )
     61           1.1  kardel {
     62           1.1  kardel 	char* tmpbuf = srcbuf;
     63           1.1  kardel 
     64           1.1  kardel 	while ( *tmpbuf != 0 )
     65           1.1  kardel 	{
     66           1.1  kardel 		if ( *tmpbuf == '\"' )
     67           1.1  kardel 		{
     68           1.1  kardel 			tmpbuf++;
     69           1.1  kardel 			continue;
     70           1.1  kardel 		}
     71           1.1  kardel 
     72           1.1  kardel 		if ( *tmpbuf == '\\' )
     73           1.1  kardel 		{
     74           1.1  kardel 			tmpbuf++;
     75           1.1  kardel 			switch ( *tmpbuf )
     76           1.1  kardel 			{
     77           1.1  kardel 				/* ignore if end of string */
     78           1.1  kardel 				case 0:
     79           1.1  kardel 					continue;
     80           1.1  kardel 				/* skip and do not copy */
     81           1.1  kardel 				case '\"': /* quotes */
     82           1.1  kardel 				case 'n': /*newline*/
     83           1.1  kardel 				case 'r': /*carriage return*/
     84           1.1  kardel 				case 'g': /*bell*/
     85           1.1  kardel 				case 't': /*tab*/
     86           1.1  kardel 					tmpbuf++;
     87           1.1  kardel 					continue;
     88           1.1  kardel 			}
     89           1.1  kardel 		}
     90           1.1  kardel 
     91           1.1  kardel 		*resultbuf++ = *tmpbuf++;
     92           1.1  kardel 
     93           1.1  kardel 	}
     94           1.1  kardel 
     95           1.1  kardel 	*resultbuf = 0;
     96           1.1  kardel 	return strlen(resultbuf);
     97           1.1  kardel }
     98           1.1  kardel 
     99           1.1  kardel 
    100           1.1  kardel /*****************************************************************************
    101           1.1  kardel  *
    102           1.1  kardel  *  ntpq_getvar
    103           1.1  kardel  *
    104           1.1  kardel  *  This function parses a given buffer for a variable/value pair and
    105           1.1  kardel  *  copies the value of the requested variable into the specified
    106           1.1  kardel  *  varvalue buffer.
    107           1.1  kardel  *
    108           1.1  kardel  *  It returns the number of bytes copied or zero for an empty result
    109           1.1  kardel  *  (=no matching variable found or empty value)
    110           1.1  kardel  *
    111           1.1  kardel  ****************************************************************************
    112           1.1  kardel  * Parameters:
    113           1.1  kardel  *	resultbuf	char*	The resulting string without quoted
    114           1.1  kardel  *				characters
    115       1.1.1.2  kardel  *	datalen		size_t	The number of bytes stored in
    116           1.1  kardel  *							resultbuf
    117           1.1  kardel  *	varname		char*	Name of the required variable
    118           1.1  kardel  *	varvalue	char*	Where the value of the variable should
    119           1.1  kardel  *							be stored
    120       1.1.1.2  kardel  *	maxlen		size_t	Max. number of bytes for varvalue
    121           1.1  kardel  *
    122           1.1  kardel  * Returns:
    123       1.1.1.2  kardel  *	size_t		number of chars that have been copied to
    124           1.1  kardel  *			varvalue
    125           1.1  kardel  ****************************************************************************/
    126           1.1  kardel 
    127       1.1.1.2  kardel size_t
    128       1.1.1.2  kardel ntpq_getvar(
    129       1.1.1.2  kardel 	const char *	resultbuf,
    130       1.1.1.2  kardel 	size_t		datalen,
    131       1.1.1.2  kardel 	const char *	varname,
    132       1.1.1.2  kardel 	char *		varvalue,
    133       1.1.1.2  kardel 	size_t		maxlen)
    134       1.1.1.2  kardel {
    135       1.1.1.2  kardel 	char *	name;
    136       1.1.1.2  kardel 	char *	value;
    137       1.1.1.2  kardel 	int	idatalen;
    138       1.1.1.2  kardel 
    139       1.1.1.2  kardel 	value = NULL;
    140       1.1.1.2  kardel 	idatalen = (int)datalen;
    141       1.1.1.2  kardel 
    142       1.1.1.2  kardel 	while (nextvar(&idatalen, &resultbuf, &name, &value)) {
    143       1.1.1.2  kardel 		if (strcmp(varname, name) == 0) {
    144       1.1.1.2  kardel 			ntpq_stripquotes(varvalue, value, strlen(value), maxlen);
    145           1.1  kardel 
    146           1.1  kardel 			return strlen(varvalue);
    147       1.1.1.2  kardel 		}
    148       1.1.1.2  kardel 	}
    149           1.1  kardel 
    150       1.1.1.2  kardel 	return 0;
    151           1.1  kardel }
    152           1.1  kardel 
    153           1.1  kardel 
    154           1.1  kardel /*****************************************************************************
    155           1.1  kardel  *
    156           1.1  kardel  *  ntpq_queryhost
    157           1.1  kardel  *
    158           1.1  kardel  *  Sends a mode 6 query packet to the current open host (see
    159           1.1  kardel  *  ntpq_openhost) and stores the requested variable set in the specified
    160           1.1  kardel  *  character buffer.
    161           1.1  kardel  *  It returns the number of bytes read or zero for an empty result
    162           1.1  kardel  *  (=no answer or empty value)
    163           1.1  kardel  *
    164           1.1  kardel  ****************************************************************************
    165           1.1  kardel  * Parameters:
    166           1.1  kardel  *      VARSET		u_short	Which variable set should be
    167           1.1  kardel  *				read (PEERVARS or CLOCKVARS)
    168           1.1  kardel  *	association	int	The association ID that should be read
    169           1.1  kardel  *				0 represents the ntpd instance itself
    170           1.1  kardel  *	resultbuf	char*	The resulting string without quoted
    171           1.1  kardel  *				characters
    172           1.1  kardel  *	maxlen		int	Max. number of bytes for varvalue
    173           1.1  kardel  *
    174           1.1  kardel  * Returns:
    175           1.1  kardel  *	int		number of bytes that have been copied to
    176           1.1  kardel  *			resultbuf
    177           1.1  kardel  *  			- OR -
    178           1.1  kardel  *			0 (zero) if no reply has been received or
    179           1.1  kardel  *			another failure occured
    180           1.1  kardel  ****************************************************************************/
    181           1.1  kardel 
    182           1.1  kardel int ntpq_queryhost(unsigned short VARSET, unsigned short association, char *resultbuf, int maxlen)
    183           1.1  kardel {
    184       1.1.1.2  kardel 	const char *datap;
    185           1.1  kardel 	int res;
    186           1.1  kardel 	int dsize;
    187           1.1  kardel 	u_short rstatus;
    188           1.1  kardel 
    189           1.1  kardel 	if ( numhosts > 0 )
    190           1.1  kardel 		res = doquery(VARSET,association,0,0, (char *)0, &rstatus, &dsize, &datap);
    191           1.1  kardel 	else
    192           1.1  kardel 		return 0;
    193           1.1  kardel 
    194           1.1  kardel 	if ( ( res != 0) || ( dsize == 0 ) ) /* no data */
    195           1.1  kardel 		return 0;
    196           1.1  kardel 
    197           1.1  kardel 	if ( dsize > maxlen)
    198           1.1  kardel 		dsize = maxlen;
    199           1.1  kardel 
    200           1.1  kardel 
    201           1.1  kardel 	/* fill result resultbuf */
    202           1.1  kardel 	memcpy(resultbuf, datap, dsize);
    203           1.1  kardel 
    204           1.1  kardel 	return dsize;
    205           1.1  kardel }
    206           1.1  kardel 
    207           1.1  kardel 
    208           1.1  kardel 
    209           1.1  kardel /*****************************************************************************
    210           1.1  kardel  *
    211           1.1  kardel  *  ntpq_openhost
    212           1.1  kardel  *
    213           1.1  kardel  *  Sets up a connection to the ntpd instance of a specified host. Note:
    214           1.1  kardel  *  There is no real "connection" established because NTP solely works
    215           1.1  kardel  *  based on UDP.
    216           1.1  kardel  *
    217           1.1  kardel  ****************************************************************************
    218           1.1  kardel  * Parameters:
    219           1.1  kardel  *	hostname	char*	Hostname/IP of the host running ntpd
    220  1.1.1.2.16.1     snj  *	fam		int	Address Family (AF_INET, AF_INET6, or 0)
    221           1.1  kardel  *
    222           1.1  kardel  * Returns:
    223           1.1  kardel  *	int		1 if the host connection could be set up, i.e.
    224           1.1  kardel  *			name resolution was succesful and/or IP address
    225           1.1  kardel  *			has been validated
    226           1.1  kardel  *  			- OR -
    227           1.1  kardel  *			0 (zero) if a failure occured
    228           1.1  kardel  ****************************************************************************/
    229           1.1  kardel 
    230  1.1.1.2.16.1     snj int
    231  1.1.1.2.16.1     snj ntpq_openhost(
    232  1.1.1.2.16.1     snj 	char *hostname,
    233  1.1.1.2.16.1     snj 	int fam
    234  1.1.1.2.16.1     snj 	)
    235           1.1  kardel {
    236  1.1.1.2.16.1     snj 	if ( openhost(hostname, fam) )
    237           1.1  kardel 	{
    238           1.1  kardel 		numhosts = 1;
    239           1.1  kardel 	} else {
    240           1.1  kardel 		numhosts = 0;
    241           1.1  kardel 	}
    242           1.1  kardel 
    243           1.1  kardel 	return numhosts;
    244           1.1  kardel 
    245           1.1  kardel }
    246           1.1  kardel 
    247           1.1  kardel 
    248           1.1  kardel /*****************************************************************************
    249           1.1  kardel  *
    250           1.1  kardel  *  ntpq_closehost
    251           1.1  kardel  *
    252           1.1  kardel  *  Cleans up a connection by closing the used socket. Should be called
    253           1.1  kardel  *  when no further queries are required for the currently used host.
    254           1.1  kardel  *
    255           1.1  kardel  ****************************************************************************
    256           1.1  kardel  * Parameters:
    257           1.1  kardel  *	- none -
    258           1.1  kardel  *
    259           1.1  kardel  * Returns:
    260           1.1  kardel  *	int		0 (zero) if no host has been opened before
    261           1.1  kardel  *			- OR -
    262           1.1  kardel  *			the resultcode from the closesocket function call
    263           1.1  kardel  ****************************************************************************/
    264           1.1  kardel 
    265           1.1  kardel int ntpq_closehost(void)
    266           1.1  kardel {
    267           1.1  kardel 	if ( numhosts )
    268           1.1  kardel 	 return closesocket(sockfd);
    269           1.1  kardel 
    270           1.1  kardel 	return 0;
    271           1.1  kardel }
    272           1.1  kardel 
    273           1.1  kardel 
    274           1.1  kardel /*****************************************************************************
    275           1.1  kardel  *
    276           1.1  kardel  *  ntpq_read_associations
    277           1.1  kardel  *
    278           1.1  kardel  *  This function queries the ntp host for its associations and returns the
    279           1.1  kardel  *  number of associations found.
    280           1.1  kardel  *
    281           1.1  kardel  *  It takes an u_short array as its first parameter, this array holds the
    282           1.1  kardel  *  IDs of the associations,
    283           1.1  kardel  *  the function will not write more entries than specified with the
    284           1.1  kardel  *  max_entries parameter.
    285           1.1  kardel  *
    286           1.1  kardel  *  However, if more than max_entries associations were found, the return
    287           1.1  kardel  *  value of this function will reflect the real number, even if not all
    288           1.1  kardel  *  associations have been stored in the array.
    289           1.1  kardel  *
    290           1.1  kardel  ****************************************************************************
    291           1.1  kardel  * Parameters:
    292           1.1  kardel  *	resultbuf	u_short*Array that should hold the list of
    293           1.1  kardel  *				association IDs
    294           1.1  kardel  *	maxentries	int	maximum number of association IDs that can
    295           1.1  kardel  *				be stored in resultbuf
    296           1.1  kardel  *
    297           1.1  kardel  * Returns:
    298           1.1  kardel  *	int		number of association IDs stored in resultbuf
    299           1.1  kardel  *  			- OR -
    300           1.1  kardel  *			0 (zero) if a failure occured or no association has
    301           1.1  kardel  *			been returned.
    302           1.1  kardel  ****************************************************************************/
    303           1.1  kardel 
    304           1.1  kardel  int  ntpq_read_associations ( u_short resultbuf[], int max_entries )
    305           1.1  kardel {
    306           1.1  kardel     int i = 0;
    307           1.1  kardel 
    308           1.1  kardel     if (ntpq_dogetassoc()) {
    309           1.1  kardel 
    310           1.1  kardel         if(numassoc < max_entries)
    311           1.1  kardel           max_entries = numassoc;
    312           1.1  kardel 
    313           1.1  kardel         for (i=0;i<max_entries;i++)
    314           1.1  kardel             resultbuf[i] = assoc_cache[i].assid;
    315           1.1  kardel 
    316           1.1  kardel         return numassoc;
    317           1.1  kardel     }
    318           1.1  kardel 
    319           1.1  kardel     return 0;
    320           1.1  kardel }
    321           1.1  kardel 
    322           1.1  kardel 
    323           1.1  kardel 
    324           1.1  kardel 
    325           1.1  kardel /*****************************************************************************
    326           1.1  kardel  *
    327           1.1  kardel  *  ntpq_get_assocs
    328           1.1  kardel  *
    329           1.1  kardel  *  This function reads the associations of a previously selected (with
    330           1.1  kardel  *  ntpq_openhost) NTP host into its own (global) array and returns the
    331           1.1  kardel  *  number of associations found.
    332           1.1  kardel  *
    333           1.1  kardel  *  The obtained association IDs can be read by using the ntpq_get_assoc_id
    334           1.1  kardel  *  function.
    335           1.1  kardel  *
    336           1.1  kardel  ****************************************************************************
    337           1.1  kardel  * Parameters:
    338           1.1  kardel  *	- none -
    339           1.1  kardel  *
    340           1.1  kardel  * Returns:
    341           1.1  kardel  *	int		number of association IDs stored in resultbuf
    342           1.1  kardel  *  			- OR -
    343           1.1  kardel  *			0 (zero) if a failure occured or no association has
    344           1.1  kardel  *			been returned.
    345           1.1  kardel  ****************************************************************************/
    346           1.1  kardel 
    347           1.1  kardel  int  ntpq_get_assocs ( void )
    348           1.1  kardel {
    349           1.1  kardel     return ntpq_read_associations( ntpq_associations, MAXASSOC );
    350           1.1  kardel }
    351           1.1  kardel 
    352           1.1  kardel 
    353           1.1  kardel /*****************************************************************************
    354           1.1  kardel  *
    355           1.1  kardel  *  ntpq_get_assoc_number
    356           1.1  kardel  *
    357           1.1  kardel  *  This function returns for a given Association ID the association number
    358           1.1  kardel  *  in the internal association array, which is filled by the ntpq_get_assocs
    359           1.1  kardel  *  function.
    360           1.1  kardel  *
    361           1.1  kardel  ****************************************************************************
    362           1.1  kardel  * Parameters:
    363           1.1  kardel  *	associd		int	requested associaton ID
    364           1.1  kardel  *
    365           1.1  kardel  * Returns:
    366           1.1  kardel  *	int		the number of the association array element that is
    367           1.1  kardel  *			representing the given association ID
    368           1.1  kardel  *  			- OR -
    369           1.1  kardel  *			-1 if a failure occured or no matching association
    370           1.1  kardel  * 			ID has been found
    371           1.1  kardel  ****************************************************************************/
    372           1.1  kardel 
    373       1.1.1.2  kardel int ntpq_get_assoc_number ( associd_t associd )
    374           1.1  kardel {
    375       1.1.1.2  kardel 	int i;
    376           1.1  kardel 
    377       1.1.1.2  kardel 	for (i=0;i<numassoc;i++) {
    378       1.1.1.2  kardel 		if (assoc_cache[i].assid == associd)
    379       1.1.1.2  kardel 			return i;
    380       1.1.1.2  kardel 	}
    381           1.1  kardel 
    382       1.1.1.2  kardel 	return -1;
    383           1.1  kardel 
    384           1.1  kardel }
    385           1.1  kardel 
    386           1.1  kardel 
    387           1.1  kardel /*****************************************************************************
    388           1.1  kardel  *
    389           1.1  kardel  *  ntpq_read_assoc_peervars
    390           1.1  kardel  *
    391           1.1  kardel  *  This function reads the peervars variable-set of a specified association
    392           1.1  kardel  *  from a NTP host and writes it to the result buffer specified, honoring
    393           1.1  kardel  *  the maxsize limit.
    394           1.1  kardel  *
    395           1.1  kardel  *  It returns the number of bytes written or 0 when the variable-set is
    396           1.1  kardel  *  empty or failed to read.
    397           1.1  kardel  *
    398           1.1  kardel  ****************************************************************************
    399           1.1  kardel  * Parameters:
    400           1.1  kardel  *	associd		int	requested associaton ID
    401           1.1  kardel  *	resultbuf	char*	character buffer where the variable set
    402           1.1  kardel  *				should be stored
    403           1.1  kardel  *	maxsize		int	the maximum number of bytes that can be
    404           1.1  kardel  *				written to resultbuf
    405           1.1  kardel  *
    406           1.1  kardel  * Returns:
    407           1.1  kardel  *	int		number of chars that have been copied to
    408           1.1  kardel  *			resultbuf
    409           1.1  kardel  *			- OR -
    410           1.1  kardel  *			0 (zero) if an error occured
    411           1.1  kardel  ****************************************************************************/
    412           1.1  kardel 
    413       1.1.1.2  kardel int
    414       1.1.1.2  kardel ntpq_read_assoc_peervars(
    415       1.1.1.2  kardel 	associd_t	associd,
    416       1.1.1.2  kardel 	char *		resultbuf,
    417       1.1.1.2  kardel 	int		maxsize
    418       1.1.1.2  kardel 	)
    419       1.1.1.2  kardel {
    420       1.1.1.2  kardel 	const char *	datap;
    421       1.1.1.2  kardel 	int		res;
    422       1.1.1.2  kardel 	int		dsize;
    423       1.1.1.2  kardel 	u_short		rstatus;
    424       1.1.1.2  kardel 
    425       1.1.1.2  kardel 	res = doquery(CTL_OP_READVAR, associd, 0, 0, NULL, &rstatus,
    426       1.1.1.2  kardel 		      &dsize, &datap);
    427       1.1.1.2  kardel 	if (res != 0)
    428       1.1.1.2  kardel 		return 0;
    429       1.1.1.2  kardel 	if (dsize <= 0) {
    430       1.1.1.2  kardel 		if (numhosts > 1)
    431       1.1.1.2  kardel 			fprintf(stderr, "server=%s ", currenthost);
    432       1.1.1.2  kardel 		fprintf(stderr,
    433       1.1.1.2  kardel 			"***No information returned for association %d\n",
    434       1.1.1.2  kardel 			associd);
    435           1.1  kardel 
    436       1.1.1.2  kardel 		return 0;
    437       1.1.1.2  kardel 	}
    438       1.1.1.2  kardel 	if (dsize > maxsize)
    439       1.1.1.2  kardel 		dsize = maxsize;
    440       1.1.1.2  kardel 	memcpy(resultbuf, datap, dsize);
    441           1.1  kardel 
    442       1.1.1.2  kardel 	return dsize;
    443           1.1  kardel }
    444           1.1  kardel 
    445           1.1  kardel 
    446           1.1  kardel 
    447           1.1  kardel 
    448           1.1  kardel /*****************************************************************************
    449           1.1  kardel  *
    450           1.1  kardel  *  ntpq_read_sysvars
    451           1.1  kardel  *
    452           1.1  kardel  *  This function reads the sysvars variable-set from a NTP host and writes it
    453           1.1  kardel  *  to the result buffer specified, honoring the maxsize limit.
    454           1.1  kardel  *
    455           1.1  kardel  *  It returns the number of bytes written or 0 when the variable-set is empty
    456           1.1  kardel  *  or could not be read.
    457           1.1  kardel  *
    458           1.1  kardel  ****************************************************************************
    459           1.1  kardel  * Parameters:
    460           1.1  kardel  *	resultbuf	char*	character buffer where the variable set
    461           1.1  kardel  *				should be stored
    462           1.1  kardel  *	maxsize		int	the maximum number of bytes that can be
    463           1.1  kardel  *				written to resultbuf
    464           1.1  kardel  *
    465           1.1  kardel  * Returns:
    466           1.1  kardel  *	int		number of chars that have been copied to
    467           1.1  kardel  *			resultbuf
    468           1.1  kardel  *			- OR -
    469           1.1  kardel  *			0 (zero) if an error occured
    470           1.1  kardel  ****************************************************************************/
    471       1.1.1.2  kardel size_t
    472       1.1.1.2  kardel ntpq_read_sysvars(
    473       1.1.1.2  kardel 	char *	resultbuf,
    474       1.1.1.2  kardel 	size_t	maxsize
    475       1.1.1.2  kardel 	)
    476       1.1.1.2  kardel {
    477       1.1.1.2  kardel 	const char *	datap;
    478       1.1.1.2  kardel 	int		res;
    479       1.1.1.2  kardel 	int		i_dsize;
    480       1.1.1.2  kardel 	size_t		dsize;
    481       1.1.1.2  kardel 	u_short		rstatus;
    482           1.1  kardel 
    483       1.1.1.2  kardel 	res = doquery(CTL_OP_READVAR, 0, 0, 0, NULL, &rstatus,
    484       1.1.1.2  kardel 		      &i_dsize, &datap);
    485           1.1  kardel 
    486       1.1.1.2  kardel 	if (res != 0)
    487       1.1.1.2  kardel 		return 0;
    488       1.1.1.2  kardel 
    489       1.1.1.2  kardel 	if (i_dsize == 0) {
    490       1.1.1.2  kardel 		if (numhosts > 1)
    491       1.1.1.2  kardel 			fprintf(stderr, "server=%s ", currenthost);
    492       1.1.1.2  kardel 		fprintf(stderr, "***No sysvar information returned\n");
    493           1.1  kardel 
    494       1.1.1.2  kardel 		return 0;
    495       1.1.1.2  kardel 	} else {
    496       1.1.1.2  kardel 		dsize = max(0, i_dsize);
    497       1.1.1.2  kardel 		dsize = min(dsize, maxsize);
    498       1.1.1.2  kardel 		memcpy(resultbuf, datap, dsize);
    499       1.1.1.2  kardel 	}
    500           1.1  kardel 
    501       1.1.1.2  kardel 	return dsize;
    502           1.1  kardel }
    503           1.1  kardel 
    504           1.1  kardel 
    505           1.1  kardel /*****************************************************************************
    506           1.1  kardel  *  ntpq_get_assoc_allvars
    507           1.1  kardel  *
    508           1.1  kardel  *  With this function all association variables for the specified association
    509           1.1  kardel  *  ID can be requested from a NTP host. They are stored internally and can be
    510           1.1  kardel  *  read by using the ntpq_get_peervar or ntpq_get_clockvar functions.
    511           1.1  kardel  *
    512           1.1  kardel  *  Basically this is only a combination of the ntpq_get_assoc_peervars and
    513           1.1  kardel  *  ntpq_get_assoc_clockvars functions.
    514           1.1  kardel  *
    515           1.1  kardel  *  It returns 1 if both variable-sets (peervars and clockvars) were
    516           1.1  kardel  *  received successfully. If one variable-set or both of them weren't
    517           1.1  kardel  *  received,
    518           1.1  kardel  *
    519           1.1  kardel  ****************************************************************************
    520           1.1  kardel  * Parameters:
    521           1.1  kardel  *	associd		int	requested associaton ID
    522           1.1  kardel  *
    523           1.1  kardel  * Returns:
    524           1.1  kardel  *	int		nonzero if at least one variable set could be read
    525           1.1  kardel  * 			- OR -
    526           1.1  kardel  *			0 (zero) if an error occured and both variable sets
    527           1.1  kardel  *			could not be read
    528           1.1  kardel  ****************************************************************************/
    529       1.1.1.2  kardel  int  ntpq_get_assoc_allvars( associd_t associd  )
    530           1.1  kardel {
    531       1.1.1.2  kardel 	return ntpq_get_assoc_peervars ( associd ) &
    532       1.1.1.2  kardel 	       ntpq_get_assoc_clockvars( associd );
    533           1.1  kardel }
    534           1.1  kardel 
    535           1.1  kardel 
    536           1.1  kardel 
    537           1.1  kardel 
    538           1.1  kardel /*****************************************************************************
    539           1.1  kardel  *
    540           1.1  kardel  *  ntpq_get_sysvars
    541           1.1  kardel  *
    542           1.1  kardel  *  The system variables of a NTP host can be requested by using this function
    543           1.1  kardel  *  and afterwards using ntpq_get_sysvar to read the single variable values.
    544           1.1  kardel  *
    545           1.1  kardel  ****************************************************************************
    546           1.1  kardel  * Parameters:
    547           1.1  kardel  *	- none -
    548           1.1  kardel  *
    549           1.1  kardel  * Returns:
    550           1.1  kardel  *	int		nonzero if the variable set could be read
    551           1.1  kardel  * 			- OR -
    552           1.1  kardel  *			0 (zero) if an error occured and the sysvars
    553           1.1  kardel  *			could not be read
    554           1.1  kardel  ****************************************************************************/
    555       1.1.1.2  kardel int
    556       1.1.1.2  kardel ntpq_get_sysvars(void)
    557           1.1  kardel {
    558       1.1.1.2  kardel 	sysvarlen = ntpq_read_sysvars(sysvars, sizeof(sysvars));
    559       1.1.1.2  kardel 	if (sysvarlen <= 0)
    560       1.1.1.2  kardel 		return 0;
    561       1.1.1.2  kardel 	else
    562       1.1.1.2  kardel 		return 1;
    563           1.1  kardel }
    564           1.1  kardel 
    565           1.1  kardel 
    566           1.1  kardel /*****************************************************************************
    567           1.1  kardel  *
    568           1.1  kardel  *  ntp_get_peervar
    569           1.1  kardel  *
    570           1.1  kardel  *  This function uses the variable-set which was read by using
    571           1.1  kardel  *  ntp_get_peervars and searches for a variable specified with varname. If
    572           1.1  kardel  *  such a variable exists, it writes its value into
    573           1.1  kardel  *  varvalue (maxlen specifies the size of this target buffer).
    574           1.1  kardel  *
    575           1.1  kardel  ****************************************************************************
    576           1.1  kardel  * Parameters:
    577           1.1  kardel  *	varname		char*	requested variable name
    578           1.1  kardel  *	varvalue	char*	the buffer where the value should go into
    579           1.1  kardel  *	maxlen		int	maximum number of bytes that can be copied to
    580           1.1  kardel  *				varvalue
    581           1.1  kardel  *
    582           1.1  kardel  * Returns:
    583           1.1  kardel  *	int		number of bytes copied to varvalue
    584           1.1  kardel  * 			- OR -
    585           1.1  kardel  *			0 (zero) if an error occured or the variable could
    586           1.1  kardel  *			not be found
    587           1.1  kardel  ****************************************************************************/
    588           1.1  kardel int ntpq_get_peervar( const char *varname, char *varvalue, int maxlen)
    589           1.1  kardel {
    590           1.1  kardel     return ( ntpq_getvar(peervars,peervarlen,varname,varvalue,maxlen) );
    591           1.1  kardel }
    592           1.1  kardel 
    593           1.1  kardel 
    594           1.1  kardel 
    595           1.1  kardel /*****************************************************************************
    596           1.1  kardel  *
    597           1.1  kardel  *  ntpq_get_assoc_peervars
    598           1.1  kardel  *
    599           1.1  kardel  *  This function requests the peer variables of the specified association
    600           1.1  kardel  *  from a NTP host. In order to access the variable values, the function
    601           1.1  kardel  *  ntpq_get_peervar must be used.
    602           1.1  kardel  *
    603           1.1  kardel  ****************************************************************************
    604           1.1  kardel  * Parameters:
    605           1.1  kardel  *	associd		int	requested associaton ID
    606           1.1  kardel  *
    607           1.1  kardel  * Returns:
    608           1.1  kardel  *	int		1 (one) if the peervars have been read
    609           1.1  kardel  * 			- OR -
    610           1.1  kardel  *			0 (zero) if an error occured and the variable set
    611           1.1  kardel  *			could not be read
    612           1.1  kardel  ****************************************************************************/
    613       1.1.1.2  kardel int
    614       1.1.1.2  kardel ntpq_get_assoc_peervars(
    615       1.1.1.2  kardel 	associd_t associd
    616       1.1.1.2  kardel 	)
    617       1.1.1.2  kardel {
    618       1.1.1.2  kardel 	peervarlen = ntpq_read_assoc_peervars(associd, peervars,
    619       1.1.1.2  kardel 					      sizeof(peervars));
    620       1.1.1.2  kardel 	if (peervarlen <= 0) {
    621       1.1.1.2  kardel 		peervar_assoc = 0;
    622       1.1.1.2  kardel 
    623       1.1.1.2  kardel 		return 0;
    624       1.1.1.2  kardel 	}
    625       1.1.1.2  kardel 	peervar_assoc = associd;
    626       1.1.1.2  kardel 
    627       1.1.1.2  kardel 	return 1;
    628           1.1  kardel }
    629           1.1  kardel 
    630           1.1  kardel 
    631           1.1  kardel /*****************************************************************************
    632           1.1  kardel  *
    633           1.1  kardel  *  ntp_read_assoc_clockvars
    634           1.1  kardel  *
    635           1.1  kardel  *  This function reads the clockvars variable-set of a specified association
    636           1.1  kardel  *  from a NTP host and writes it to the result buffer specified, honoring
    637           1.1  kardel  *  the maxsize limit.
    638           1.1  kardel  *
    639           1.1  kardel  *  It returns the number of bytes written or 0 when the variable-set is
    640           1.1  kardel  *  empty or failed to read.
    641           1.1  kardel  *
    642           1.1  kardel  ****************************************************************************
    643           1.1  kardel  * Parameters:
    644           1.1  kardel  *	associd		int	requested associaton ID
    645           1.1  kardel  *	resultbuf	char*	character buffer where the variable set
    646           1.1  kardel  *				should be stored
    647           1.1  kardel  *	maxsize		int	the maximum number of bytes that can be
    648           1.1  kardel  *				written to resultbuf
    649           1.1  kardel  *
    650           1.1  kardel  * Returns:
    651           1.1  kardel  *	int		number of chars that have been copied to
    652           1.1  kardel  *			resultbuf
    653           1.1  kardel  *			- OR -
    654           1.1  kardel  *			0 (zero) if an error occured
    655           1.1  kardel  ****************************************************************************/
    656           1.1  kardel 
    657       1.1.1.2  kardel int
    658       1.1.1.2  kardel ntpq_read_assoc_clockvars(
    659       1.1.1.2  kardel 	associd_t	associd,
    660       1.1.1.2  kardel 	char *		resultbuf,
    661       1.1.1.2  kardel 	int		maxsize
    662       1.1.1.2  kardel 	)
    663           1.1  kardel {
    664       1.1.1.2  kardel 	const char *datap;
    665       1.1.1.2  kardel 	int res;
    666       1.1.1.2  kardel 	int dsize;
    667       1.1.1.2  kardel 	u_short rstatus;
    668           1.1  kardel 
    669       1.1.1.2  kardel 	res = ntpq_doquerylist(ntpq_varlist, CTL_OP_READCLOCK, associd,
    670       1.1.1.2  kardel 			       0, &rstatus, &dsize, &datap);
    671       1.1.1.2  kardel 	if (res != 0)
    672       1.1.1.2  kardel 		return 0;
    673           1.1  kardel 
    674       1.1.1.2  kardel 	if (dsize == 0) {
    675       1.1.1.2  kardel 		if (numhosts > 1) /* no information returned from server */
    676       1.1.1.2  kardel 			return 0;
    677       1.1.1.2  kardel 	} else {
    678       1.1.1.2  kardel 		if (dsize > maxsize)
    679       1.1.1.2  kardel 			dsize = maxsize;
    680       1.1.1.2  kardel 		memcpy(resultbuf, datap, dsize);
    681       1.1.1.2  kardel 	}
    682           1.1  kardel 
    683       1.1.1.2  kardel 	return dsize;
    684           1.1  kardel }
    685           1.1  kardel 
    686           1.1  kardel 
    687           1.1  kardel 
    688           1.1  kardel /*****************************************************************************
    689           1.1  kardel  *
    690           1.1  kardel  *  ntpq_get_assoc_clocktype
    691           1.1  kardel  *
    692           1.1  kardel  *  This function returns a clocktype value for a given association number
    693           1.1  kardel  *  (not ID!):
    694           1.1  kardel  *
    695           1.1  kardel  *  NTP_CLOCKTYPE_UNKNOWN   Unknown clock type
    696           1.1  kardel  *  NTP_CLOCKTYPE_BROADCAST Broadcast server
    697           1.1  kardel  *  NTP_CLOCKTYPE_LOCAL     Local clock
    698           1.1  kardel  *  NTP_CLOCKTYPE_UNICAST   Unicast server
    699           1.1  kardel  *  NTP_CLOCKTYPE_MULTICAST Multicast server
    700           1.1  kardel  *
    701           1.1  kardel  ****************************************************************************/
    702       1.1.1.2  kardel int
    703       1.1.1.2  kardel ntpq_get_assoc_clocktype(
    704       1.1.1.2  kardel 	int assoc_index
    705       1.1.1.2  kardel 	)
    706       1.1.1.2  kardel {
    707       1.1.1.2  kardel 	associd_t	associd;
    708       1.1.1.2  kardel 	int		i;
    709       1.1.1.2  kardel 	int		rc;
    710       1.1.1.2  kardel 	sockaddr_u	dum_store;
    711       1.1.1.2  kardel 	char		dstadr[LENHOSTNAME];
    712       1.1.1.2  kardel 	char		resultbuf[NTPQ_BUFLEN];
    713       1.1.1.2  kardel 
    714       1.1.1.2  kardel 	if (assoc_index < 0 || assoc_index >= numassoc)
    715       1.1.1.2  kardel 		return -1;
    716       1.1.1.2  kardel 
    717       1.1.1.2  kardel 	associd = assoc_cache[assoc_index].assid;
    718       1.1.1.2  kardel 	if (associd == peervar_assoc) {
    719       1.1.1.2  kardel 		rc = ntpq_get_peervar("dstadr", dstadr, sizeof(dstadr));
    720       1.1.1.2  kardel 	} else {
    721       1.1.1.2  kardel 		i = ntpq_read_assoc_peervars(associd, resultbuf,
    722       1.1.1.2  kardel 					     sizeof(resultbuf));
    723       1.1.1.2  kardel 		if (i <= 0)
    724       1.1.1.2  kardel 			return -1;
    725       1.1.1.2  kardel 		rc = ntpq_getvar(resultbuf, i, "dstadr", dstadr,
    726       1.1.1.2  kardel 				 sizeof(dstadr));
    727       1.1.1.2  kardel 	}
    728           1.1  kardel 
    729       1.1.1.2  kardel 	if (0 != rc && decodenetnum(dstadr, &dum_store))
    730       1.1.1.2  kardel 		return ntpq_decodeaddrtype(&dum_store);
    731           1.1  kardel 
    732       1.1.1.2  kardel 	return -1;
    733           1.1  kardel }
    734           1.1  kardel 
    735           1.1  kardel 
    736           1.1  kardel 
    737           1.1  kardel /*****************************************************************************
    738           1.1  kardel  *
    739           1.1  kardel  *  ntpq_get_assoc_clockvars
    740           1.1  kardel  *
    741           1.1  kardel  *  With this function the clock variables of the specified association are
    742           1.1  kardel  *  requested from a NTP host. This makes only sense for associations with
    743           1.1  kardel  *  the type 'l' (Local Clock) and you should check this with
    744           1.1  kardel  *  ntpq_get_assoc_clocktype for each association, before you use this function
    745           1.1  kardel  *  on it.
    746           1.1  kardel  *
    747           1.1  kardel  ****************************************************************************
    748           1.1  kardel  * Parameters:
    749           1.1  kardel  *	associd		int	requested associaton ID
    750           1.1  kardel  *
    751           1.1  kardel  * Returns:
    752           1.1  kardel  *	int		1 (one) if the clockvars have been read
    753           1.1  kardel  * 			- OR -
    754           1.1  kardel  *			0 (zero) if an error occured and the variable set
    755           1.1  kardel  *			could not be read
    756           1.1  kardel  ****************************************************************************/
    757       1.1.1.2  kardel int  ntpq_get_assoc_clockvars( associd_t associd )
    758           1.1  kardel {
    759       1.1.1.2  kardel 	if (NTP_CLOCKTYPE_LOCAL != ntpq_get_assoc_clocktype(
    760       1.1.1.2  kardel 	    ntpq_get_assoc_number(associd)))
    761       1.1.1.2  kardel 		return 0;
    762       1.1.1.2  kardel 	clockvarlen = ntpq_read_assoc_clockvars( associd, clockvars,
    763       1.1.1.2  kardel 						 sizeof(clockvars) );
    764       1.1.1.2  kardel 	if ( clockvarlen <= 0 ) {
    765       1.1.1.2  kardel 		clockvar_assoc = 0;
    766       1.1.1.2  kardel 		return 0;
    767       1.1.1.2  kardel 	} else {
    768       1.1.1.2  kardel 		clockvar_assoc = associd;
    769       1.1.1.2  kardel 		return 1;
    770       1.1.1.2  kardel 	}
    771           1.1  kardel }
    772           1.1  kardel 
    773           1.1  kardel 
    774