Home | History | Annotate | Line # | Download | only in ntpq
libntpq.c revision 1.1.1.1.6.1
      1  1.1.1.1.6.1    yamt /*	$NetBSD: libntpq.c,v 1.1.1.1.6.1 2012/04/17 00:03:49 yamt 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.1.6.1    yamt #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.1.6.1    yamt char peervars[NTPQ_BUFLEN];
     28  1.1.1.1.6.1    yamt int peervarlen = 0;
     29  1.1.1.1.6.1    yamt associd_t peervar_assoc = 0;
     30  1.1.1.1.6.1    yamt char clockvars[NTPQ_BUFLEN];
     31  1.1.1.1.6.1    yamt int clockvarlen = 0;
     32  1.1.1.1.6.1    yamt int clockvar_assoc = 0;
     33  1.1.1.1.6.1    yamt char sysvars[NTPQ_BUFLEN];
     34  1.1.1.1.6.1    yamt int sysvarlen = 0;
     35  1.1.1.1.6.1    yamt char *ntpq_resultbuffer[NTPQ_BUFLEN];
     36  1.1.1.1.6.1    yamt 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.1.6.1    yamt  *	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.1.6.1    yamt  *	maxlen		size_t	Max. number of bytes for varvalue
    121          1.1  kardel  *
    122          1.1  kardel  * Returns:
    123  1.1.1.1.6.1    yamt  *	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.1.6.1    yamt size_t
    128  1.1.1.1.6.1    yamt ntpq_getvar(
    129  1.1.1.1.6.1    yamt 	const char *	resultbuf,
    130  1.1.1.1.6.1    yamt 	size_t		datalen,
    131  1.1.1.1.6.1    yamt 	const char *	varname,
    132  1.1.1.1.6.1    yamt 	char *		varvalue,
    133  1.1.1.1.6.1    yamt 	size_t		maxlen)
    134  1.1.1.1.6.1    yamt {
    135  1.1.1.1.6.1    yamt 	char *	name;
    136  1.1.1.1.6.1    yamt 	char *	value;
    137  1.1.1.1.6.1    yamt 	int	idatalen;
    138  1.1.1.1.6.1    yamt 
    139  1.1.1.1.6.1    yamt 	value = NULL;
    140  1.1.1.1.6.1    yamt 	idatalen = (int)datalen;
    141  1.1.1.1.6.1    yamt 
    142  1.1.1.1.6.1    yamt 	while (nextvar(&idatalen, &resultbuf, &name, &value)) {
    143  1.1.1.1.6.1    yamt 		if (strcmp(varname, name) == 0) {
    144  1.1.1.1.6.1    yamt 			ntpq_stripquotes(varvalue, value, strlen(value), maxlen);
    145          1.1  kardel 
    146          1.1  kardel 			return strlen(varvalue);
    147  1.1.1.1.6.1    yamt 		}
    148  1.1.1.1.6.1    yamt 	}
    149          1.1  kardel 
    150  1.1.1.1.6.1    yamt 	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.1.6.1    yamt 	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  kardel  *
    221          1.1  kardel  * Returns:
    222          1.1  kardel  *	int		1 if the host connection could be set up, i.e.
    223          1.1  kardel  *			name resolution was succesful and/or IP address
    224          1.1  kardel  *			has been validated
    225          1.1  kardel  *  			- OR -
    226          1.1  kardel  *			0 (zero) if a failure occured
    227          1.1  kardel  ****************************************************************************/
    228          1.1  kardel 
    229          1.1  kardel int ntpq_openhost(char *hostname)
    230          1.1  kardel {
    231          1.1  kardel 	if ( openhost(hostname) )
    232          1.1  kardel 	{
    233          1.1  kardel 		numhosts = 1;
    234          1.1  kardel 	} else {
    235          1.1  kardel 		numhosts = 0;
    236          1.1  kardel 	}
    237          1.1  kardel 
    238          1.1  kardel 	return numhosts;
    239          1.1  kardel 
    240          1.1  kardel }
    241          1.1  kardel 
    242          1.1  kardel 
    243          1.1  kardel /*****************************************************************************
    244          1.1  kardel  *
    245          1.1  kardel  *  ntpq_closehost
    246          1.1  kardel  *
    247          1.1  kardel  *  Cleans up a connection by closing the used socket. Should be called
    248          1.1  kardel  *  when no further queries are required for the currently used host.
    249          1.1  kardel  *
    250          1.1  kardel  ****************************************************************************
    251          1.1  kardel  * Parameters:
    252          1.1  kardel  *	- none -
    253          1.1  kardel  *
    254          1.1  kardel  * Returns:
    255          1.1  kardel  *	int		0 (zero) if no host has been opened before
    256          1.1  kardel  *			- OR -
    257          1.1  kardel  *			the resultcode from the closesocket function call
    258          1.1  kardel  ****************************************************************************/
    259          1.1  kardel 
    260          1.1  kardel int ntpq_closehost(void)
    261          1.1  kardel {
    262          1.1  kardel 	if ( numhosts )
    263          1.1  kardel 	 return closesocket(sockfd);
    264          1.1  kardel 
    265          1.1  kardel 	return 0;
    266          1.1  kardel }
    267          1.1  kardel 
    268          1.1  kardel 
    269          1.1  kardel /*****************************************************************************
    270          1.1  kardel  *
    271          1.1  kardel  *  ntpq_read_associations
    272          1.1  kardel  *
    273          1.1  kardel  *  This function queries the ntp host for its associations and returns the
    274          1.1  kardel  *  number of associations found.
    275          1.1  kardel  *
    276          1.1  kardel  *  It takes an u_short array as its first parameter, this array holds the
    277          1.1  kardel  *  IDs of the associations,
    278          1.1  kardel  *  the function will not write more entries than specified with the
    279          1.1  kardel  *  max_entries parameter.
    280          1.1  kardel  *
    281          1.1  kardel  *  However, if more than max_entries associations were found, the return
    282          1.1  kardel  *  value of this function will reflect the real number, even if not all
    283          1.1  kardel  *  associations have been stored in the array.
    284          1.1  kardel  *
    285          1.1  kardel  ****************************************************************************
    286          1.1  kardel  * Parameters:
    287          1.1  kardel  *	resultbuf	u_short*Array that should hold the list of
    288          1.1  kardel  *				association IDs
    289          1.1  kardel  *	maxentries	int	maximum number of association IDs that can
    290          1.1  kardel  *				be stored in resultbuf
    291          1.1  kardel  *
    292          1.1  kardel  * Returns:
    293          1.1  kardel  *	int		number of association IDs stored in resultbuf
    294          1.1  kardel  *  			- OR -
    295          1.1  kardel  *			0 (zero) if a failure occured or no association has
    296          1.1  kardel  *			been returned.
    297          1.1  kardel  ****************************************************************************/
    298          1.1  kardel 
    299          1.1  kardel  int  ntpq_read_associations ( u_short resultbuf[], int max_entries )
    300          1.1  kardel {
    301          1.1  kardel     int i = 0;
    302          1.1  kardel 
    303          1.1  kardel     if (ntpq_dogetassoc()) {
    304          1.1  kardel 
    305          1.1  kardel         if(numassoc < max_entries)
    306          1.1  kardel           max_entries = numassoc;
    307          1.1  kardel 
    308          1.1  kardel         for (i=0;i<max_entries;i++)
    309          1.1  kardel             resultbuf[i] = assoc_cache[i].assid;
    310          1.1  kardel 
    311          1.1  kardel         return numassoc;
    312          1.1  kardel     }
    313          1.1  kardel 
    314          1.1  kardel     return 0;
    315          1.1  kardel }
    316          1.1  kardel 
    317          1.1  kardel 
    318          1.1  kardel 
    319          1.1  kardel 
    320          1.1  kardel /*****************************************************************************
    321          1.1  kardel  *
    322          1.1  kardel  *  ntpq_get_assocs
    323          1.1  kardel  *
    324          1.1  kardel  *  This function reads the associations of a previously selected (with
    325          1.1  kardel  *  ntpq_openhost) NTP host into its own (global) array and returns the
    326          1.1  kardel  *  number of associations found.
    327          1.1  kardel  *
    328          1.1  kardel  *  The obtained association IDs can be read by using the ntpq_get_assoc_id
    329          1.1  kardel  *  function.
    330          1.1  kardel  *
    331          1.1  kardel  ****************************************************************************
    332          1.1  kardel  * Parameters:
    333          1.1  kardel  *	- none -
    334          1.1  kardel  *
    335          1.1  kardel  * Returns:
    336          1.1  kardel  *	int		number of association IDs stored in resultbuf
    337          1.1  kardel  *  			- OR -
    338          1.1  kardel  *			0 (zero) if a failure occured or no association has
    339          1.1  kardel  *			been returned.
    340          1.1  kardel  ****************************************************************************/
    341          1.1  kardel 
    342          1.1  kardel  int  ntpq_get_assocs ( void )
    343          1.1  kardel {
    344          1.1  kardel     return ntpq_read_associations( ntpq_associations, MAXASSOC );
    345          1.1  kardel }
    346          1.1  kardel 
    347          1.1  kardel 
    348          1.1  kardel /*****************************************************************************
    349          1.1  kardel  *
    350          1.1  kardel  *  ntpq_get_assoc_number
    351          1.1  kardel  *
    352          1.1  kardel  *  This function returns for a given Association ID the association number
    353          1.1  kardel  *  in the internal association array, which is filled by the ntpq_get_assocs
    354          1.1  kardel  *  function.
    355          1.1  kardel  *
    356          1.1  kardel  ****************************************************************************
    357          1.1  kardel  * Parameters:
    358          1.1  kardel  *	associd		int	requested associaton ID
    359          1.1  kardel  *
    360          1.1  kardel  * Returns:
    361          1.1  kardel  *	int		the number of the association array element that is
    362          1.1  kardel  *			representing the given association ID
    363          1.1  kardel  *  			- OR -
    364          1.1  kardel  *			-1 if a failure occured or no matching association
    365          1.1  kardel  * 			ID has been found
    366          1.1  kardel  ****************************************************************************/
    367          1.1  kardel 
    368  1.1.1.1.6.1    yamt int ntpq_get_assoc_number ( associd_t associd )
    369          1.1  kardel {
    370  1.1.1.1.6.1    yamt 	int i;
    371          1.1  kardel 
    372  1.1.1.1.6.1    yamt 	for (i=0;i<numassoc;i++) {
    373  1.1.1.1.6.1    yamt 		if (assoc_cache[i].assid == associd)
    374  1.1.1.1.6.1    yamt 			return i;
    375  1.1.1.1.6.1    yamt 	}
    376          1.1  kardel 
    377  1.1.1.1.6.1    yamt 	return -1;
    378          1.1  kardel 
    379          1.1  kardel }
    380          1.1  kardel 
    381          1.1  kardel 
    382          1.1  kardel /*****************************************************************************
    383          1.1  kardel  *
    384          1.1  kardel  *  ntpq_read_assoc_peervars
    385          1.1  kardel  *
    386          1.1  kardel  *  This function reads the peervars variable-set of a specified association
    387          1.1  kardel  *  from a NTP host and writes it to the result buffer specified, honoring
    388          1.1  kardel  *  the maxsize limit.
    389          1.1  kardel  *
    390          1.1  kardel  *  It returns the number of bytes written or 0 when the variable-set is
    391          1.1  kardel  *  empty or failed to read.
    392          1.1  kardel  *
    393          1.1  kardel  ****************************************************************************
    394          1.1  kardel  * Parameters:
    395          1.1  kardel  *	associd		int	requested associaton ID
    396          1.1  kardel  *	resultbuf	char*	character buffer where the variable set
    397          1.1  kardel  *				should be stored
    398          1.1  kardel  *	maxsize		int	the maximum number of bytes that can be
    399          1.1  kardel  *				written to resultbuf
    400          1.1  kardel  *
    401          1.1  kardel  * Returns:
    402          1.1  kardel  *	int		number of chars that have been copied to
    403          1.1  kardel  *			resultbuf
    404          1.1  kardel  *			- OR -
    405          1.1  kardel  *			0 (zero) if an error occured
    406          1.1  kardel  ****************************************************************************/
    407          1.1  kardel 
    408  1.1.1.1.6.1    yamt int
    409  1.1.1.1.6.1    yamt ntpq_read_assoc_peervars(
    410  1.1.1.1.6.1    yamt 	associd_t	associd,
    411  1.1.1.1.6.1    yamt 	char *		resultbuf,
    412  1.1.1.1.6.1    yamt 	int		maxsize
    413  1.1.1.1.6.1    yamt 	)
    414  1.1.1.1.6.1    yamt {
    415  1.1.1.1.6.1    yamt 	const char *	datap;
    416  1.1.1.1.6.1    yamt 	int		res;
    417  1.1.1.1.6.1    yamt 	int		dsize;
    418  1.1.1.1.6.1    yamt 	u_short		rstatus;
    419  1.1.1.1.6.1    yamt 
    420  1.1.1.1.6.1    yamt 	res = doquery(CTL_OP_READVAR, associd, 0, 0, NULL, &rstatus,
    421  1.1.1.1.6.1    yamt 		      &dsize, &datap);
    422  1.1.1.1.6.1    yamt 	if (res != 0)
    423  1.1.1.1.6.1    yamt 		return 0;
    424  1.1.1.1.6.1    yamt 	if (dsize <= 0) {
    425  1.1.1.1.6.1    yamt 		if (numhosts > 1)
    426  1.1.1.1.6.1    yamt 			fprintf(stderr, "server=%s ", currenthost);
    427  1.1.1.1.6.1    yamt 		fprintf(stderr,
    428  1.1.1.1.6.1    yamt 			"***No information returned for association %d\n",
    429  1.1.1.1.6.1    yamt 			associd);
    430          1.1  kardel 
    431  1.1.1.1.6.1    yamt 		return 0;
    432  1.1.1.1.6.1    yamt 	}
    433  1.1.1.1.6.1    yamt 	if (dsize > maxsize)
    434  1.1.1.1.6.1    yamt 		dsize = maxsize;
    435  1.1.1.1.6.1    yamt 	memcpy(resultbuf, datap, dsize);
    436          1.1  kardel 
    437  1.1.1.1.6.1    yamt 	return dsize;
    438          1.1  kardel }
    439          1.1  kardel 
    440          1.1  kardel 
    441          1.1  kardel 
    442          1.1  kardel 
    443          1.1  kardel /*****************************************************************************
    444          1.1  kardel  *
    445          1.1  kardel  *  ntpq_read_sysvars
    446          1.1  kardel  *
    447          1.1  kardel  *  This function reads the sysvars variable-set from a NTP host and writes it
    448          1.1  kardel  *  to the result buffer specified, honoring the maxsize limit.
    449          1.1  kardel  *
    450          1.1  kardel  *  It returns the number of bytes written or 0 when the variable-set is empty
    451          1.1  kardel  *  or could not be read.
    452          1.1  kardel  *
    453          1.1  kardel  ****************************************************************************
    454          1.1  kardel  * Parameters:
    455          1.1  kardel  *	resultbuf	char*	character buffer where the variable set
    456          1.1  kardel  *				should be stored
    457          1.1  kardel  *	maxsize		int	the maximum number of bytes that can be
    458          1.1  kardel  *				written to resultbuf
    459          1.1  kardel  *
    460          1.1  kardel  * Returns:
    461          1.1  kardel  *	int		number of chars that have been copied to
    462          1.1  kardel  *			resultbuf
    463          1.1  kardel  *			- OR -
    464          1.1  kardel  *			0 (zero) if an error occured
    465          1.1  kardel  ****************************************************************************/
    466  1.1.1.1.6.1    yamt size_t
    467  1.1.1.1.6.1    yamt ntpq_read_sysvars(
    468  1.1.1.1.6.1    yamt 	char *	resultbuf,
    469  1.1.1.1.6.1    yamt 	size_t	maxsize
    470  1.1.1.1.6.1    yamt 	)
    471  1.1.1.1.6.1    yamt {
    472  1.1.1.1.6.1    yamt 	const char *	datap;
    473  1.1.1.1.6.1    yamt 	int		res;
    474  1.1.1.1.6.1    yamt 	int		i_dsize;
    475  1.1.1.1.6.1    yamt 	size_t		dsize;
    476  1.1.1.1.6.1    yamt 	u_short		rstatus;
    477          1.1  kardel 
    478  1.1.1.1.6.1    yamt 	res = doquery(CTL_OP_READVAR, 0, 0, 0, NULL, &rstatus,
    479  1.1.1.1.6.1    yamt 		      &i_dsize, &datap);
    480          1.1  kardel 
    481  1.1.1.1.6.1    yamt 	if (res != 0)
    482  1.1.1.1.6.1    yamt 		return 0;
    483  1.1.1.1.6.1    yamt 
    484  1.1.1.1.6.1    yamt 	if (i_dsize == 0) {
    485  1.1.1.1.6.1    yamt 		if (numhosts > 1)
    486  1.1.1.1.6.1    yamt 			fprintf(stderr, "server=%s ", currenthost);
    487  1.1.1.1.6.1    yamt 		fprintf(stderr, "***No sysvar information returned\n");
    488          1.1  kardel 
    489  1.1.1.1.6.1    yamt 		return 0;
    490  1.1.1.1.6.1    yamt 	} else {
    491  1.1.1.1.6.1    yamt 		dsize = max(0, i_dsize);
    492  1.1.1.1.6.1    yamt 		dsize = min(dsize, maxsize);
    493  1.1.1.1.6.1    yamt 		memcpy(resultbuf, datap, dsize);
    494  1.1.1.1.6.1    yamt 	}
    495          1.1  kardel 
    496  1.1.1.1.6.1    yamt 	return dsize;
    497          1.1  kardel }
    498          1.1  kardel 
    499          1.1  kardel 
    500          1.1  kardel /*****************************************************************************
    501          1.1  kardel  *  ntpq_get_assoc_allvars
    502          1.1  kardel  *
    503          1.1  kardel  *  With this function all association variables for the specified association
    504          1.1  kardel  *  ID can be requested from a NTP host. They are stored internally and can be
    505          1.1  kardel  *  read by using the ntpq_get_peervar or ntpq_get_clockvar functions.
    506          1.1  kardel  *
    507          1.1  kardel  *  Basically this is only a combination of the ntpq_get_assoc_peervars and
    508          1.1  kardel  *  ntpq_get_assoc_clockvars functions.
    509          1.1  kardel  *
    510          1.1  kardel  *  It returns 1 if both variable-sets (peervars and clockvars) were
    511          1.1  kardel  *  received successfully. If one variable-set or both of them weren't
    512          1.1  kardel  *  received,
    513          1.1  kardel  *
    514          1.1  kardel  ****************************************************************************
    515          1.1  kardel  * Parameters:
    516          1.1  kardel  *	associd		int	requested associaton ID
    517          1.1  kardel  *
    518          1.1  kardel  * Returns:
    519          1.1  kardel  *	int		nonzero if at least one variable set could be read
    520          1.1  kardel  * 			- OR -
    521          1.1  kardel  *			0 (zero) if an error occured and both variable sets
    522          1.1  kardel  *			could not be read
    523          1.1  kardel  ****************************************************************************/
    524  1.1.1.1.6.1    yamt  int  ntpq_get_assoc_allvars( associd_t associd  )
    525          1.1  kardel {
    526  1.1.1.1.6.1    yamt 	return ntpq_get_assoc_peervars ( associd ) &
    527  1.1.1.1.6.1    yamt 	       ntpq_get_assoc_clockvars( associd );
    528          1.1  kardel }
    529          1.1  kardel 
    530          1.1  kardel 
    531          1.1  kardel 
    532          1.1  kardel 
    533          1.1  kardel /*****************************************************************************
    534          1.1  kardel  *
    535          1.1  kardel  *  ntpq_get_sysvars
    536          1.1  kardel  *
    537          1.1  kardel  *  The system variables of a NTP host can be requested by using this function
    538          1.1  kardel  *  and afterwards using ntpq_get_sysvar to read the single variable values.
    539          1.1  kardel  *
    540          1.1  kardel  ****************************************************************************
    541          1.1  kardel  * Parameters:
    542          1.1  kardel  *	- none -
    543          1.1  kardel  *
    544          1.1  kardel  * Returns:
    545          1.1  kardel  *	int		nonzero if the variable set could be read
    546          1.1  kardel  * 			- OR -
    547          1.1  kardel  *			0 (zero) if an error occured and the sysvars
    548          1.1  kardel  *			could not be read
    549          1.1  kardel  ****************************************************************************/
    550  1.1.1.1.6.1    yamt int
    551  1.1.1.1.6.1    yamt ntpq_get_sysvars(void)
    552          1.1  kardel {
    553  1.1.1.1.6.1    yamt 	sysvarlen = ntpq_read_sysvars(sysvars, sizeof(sysvars));
    554  1.1.1.1.6.1    yamt 	if (sysvarlen <= 0)
    555  1.1.1.1.6.1    yamt 		return 0;
    556  1.1.1.1.6.1    yamt 	else
    557  1.1.1.1.6.1    yamt 		return 1;
    558          1.1  kardel }
    559          1.1  kardel 
    560          1.1  kardel 
    561          1.1  kardel /*****************************************************************************
    562          1.1  kardel  *
    563          1.1  kardel  *  ntp_get_peervar
    564          1.1  kardel  *
    565          1.1  kardel  *  This function uses the variable-set which was read by using
    566          1.1  kardel  *  ntp_get_peervars and searches for a variable specified with varname. If
    567          1.1  kardel  *  such a variable exists, it writes its value into
    568          1.1  kardel  *  varvalue (maxlen specifies the size of this target buffer).
    569          1.1  kardel  *
    570          1.1  kardel  ****************************************************************************
    571          1.1  kardel  * Parameters:
    572          1.1  kardel  *	varname		char*	requested variable name
    573          1.1  kardel  *	varvalue	char*	the buffer where the value should go into
    574          1.1  kardel  *	maxlen		int	maximum number of bytes that can be copied to
    575          1.1  kardel  *				varvalue
    576          1.1  kardel  *
    577          1.1  kardel  * Returns:
    578          1.1  kardel  *	int		number of bytes copied to varvalue
    579          1.1  kardel  * 			- OR -
    580          1.1  kardel  *			0 (zero) if an error occured or the variable could
    581          1.1  kardel  *			not be found
    582          1.1  kardel  ****************************************************************************/
    583          1.1  kardel int ntpq_get_peervar( const char *varname, char *varvalue, int maxlen)
    584          1.1  kardel {
    585          1.1  kardel     return ( ntpq_getvar(peervars,peervarlen,varname,varvalue,maxlen) );
    586          1.1  kardel }
    587          1.1  kardel 
    588          1.1  kardel 
    589          1.1  kardel 
    590          1.1  kardel /*****************************************************************************
    591          1.1  kardel  *
    592          1.1  kardel  *  ntpq_get_assoc_peervars
    593          1.1  kardel  *
    594          1.1  kardel  *  This function requests the peer variables of the specified association
    595          1.1  kardel  *  from a NTP host. In order to access the variable values, the function
    596          1.1  kardel  *  ntpq_get_peervar must be used.
    597          1.1  kardel  *
    598          1.1  kardel  ****************************************************************************
    599          1.1  kardel  * Parameters:
    600          1.1  kardel  *	associd		int	requested associaton ID
    601          1.1  kardel  *
    602          1.1  kardel  * Returns:
    603          1.1  kardel  *	int		1 (one) if the peervars have been read
    604          1.1  kardel  * 			- OR -
    605          1.1  kardel  *			0 (zero) if an error occured and the variable set
    606          1.1  kardel  *			could not be read
    607          1.1  kardel  ****************************************************************************/
    608  1.1.1.1.6.1    yamt int
    609  1.1.1.1.6.1    yamt ntpq_get_assoc_peervars(
    610  1.1.1.1.6.1    yamt 	associd_t associd
    611  1.1.1.1.6.1    yamt 	)
    612  1.1.1.1.6.1    yamt {
    613  1.1.1.1.6.1    yamt 	peervarlen = ntpq_read_assoc_peervars(associd, peervars,
    614  1.1.1.1.6.1    yamt 					      sizeof(peervars));
    615  1.1.1.1.6.1    yamt 	if (peervarlen <= 0) {
    616  1.1.1.1.6.1    yamt 		peervar_assoc = 0;
    617  1.1.1.1.6.1    yamt 
    618  1.1.1.1.6.1    yamt 		return 0;
    619  1.1.1.1.6.1    yamt 	}
    620  1.1.1.1.6.1    yamt 	peervar_assoc = associd;
    621  1.1.1.1.6.1    yamt 
    622  1.1.1.1.6.1    yamt 	return 1;
    623          1.1  kardel }
    624          1.1  kardel 
    625          1.1  kardel 
    626          1.1  kardel /*****************************************************************************
    627          1.1  kardel  *
    628          1.1  kardel  *  ntp_read_assoc_clockvars
    629          1.1  kardel  *
    630          1.1  kardel  *  This function reads the clockvars variable-set of a specified association
    631          1.1  kardel  *  from a NTP host and writes it to the result buffer specified, honoring
    632          1.1  kardel  *  the maxsize limit.
    633          1.1  kardel  *
    634          1.1  kardel  *  It returns the number of bytes written or 0 when the variable-set is
    635          1.1  kardel  *  empty or failed to read.
    636          1.1  kardel  *
    637          1.1  kardel  ****************************************************************************
    638          1.1  kardel  * Parameters:
    639          1.1  kardel  *	associd		int	requested associaton ID
    640          1.1  kardel  *	resultbuf	char*	character buffer where the variable set
    641          1.1  kardel  *				should be stored
    642          1.1  kardel  *	maxsize		int	the maximum number of bytes that can be
    643          1.1  kardel  *				written to resultbuf
    644          1.1  kardel  *
    645          1.1  kardel  * Returns:
    646          1.1  kardel  *	int		number of chars that have been copied to
    647          1.1  kardel  *			resultbuf
    648          1.1  kardel  *			- OR -
    649          1.1  kardel  *			0 (zero) if an error occured
    650          1.1  kardel  ****************************************************************************/
    651          1.1  kardel 
    652  1.1.1.1.6.1    yamt int
    653  1.1.1.1.6.1    yamt ntpq_read_assoc_clockvars(
    654  1.1.1.1.6.1    yamt 	associd_t	associd,
    655  1.1.1.1.6.1    yamt 	char *		resultbuf,
    656  1.1.1.1.6.1    yamt 	int		maxsize
    657  1.1.1.1.6.1    yamt 	)
    658          1.1  kardel {
    659  1.1.1.1.6.1    yamt 	const char *datap;
    660  1.1.1.1.6.1    yamt 	int res;
    661  1.1.1.1.6.1    yamt 	int dsize;
    662  1.1.1.1.6.1    yamt 	u_short rstatus;
    663          1.1  kardel 
    664  1.1.1.1.6.1    yamt 	res = ntpq_doquerylist(ntpq_varlist, CTL_OP_READCLOCK, associd,
    665  1.1.1.1.6.1    yamt 			       0, &rstatus, &dsize, &datap);
    666  1.1.1.1.6.1    yamt 	if (res != 0)
    667  1.1.1.1.6.1    yamt 		return 0;
    668          1.1  kardel 
    669  1.1.1.1.6.1    yamt 	if (dsize == 0) {
    670  1.1.1.1.6.1    yamt 		if (numhosts > 1) /* no information returned from server */
    671  1.1.1.1.6.1    yamt 			return 0;
    672  1.1.1.1.6.1    yamt 	} else {
    673  1.1.1.1.6.1    yamt 		if (dsize > maxsize)
    674  1.1.1.1.6.1    yamt 			dsize = maxsize;
    675  1.1.1.1.6.1    yamt 		memcpy(resultbuf, datap, dsize);
    676  1.1.1.1.6.1    yamt 	}
    677          1.1  kardel 
    678  1.1.1.1.6.1    yamt 	return dsize;
    679          1.1  kardel }
    680          1.1  kardel 
    681          1.1  kardel 
    682          1.1  kardel 
    683          1.1  kardel /*****************************************************************************
    684          1.1  kardel  *
    685          1.1  kardel  *  ntpq_get_assoc_clocktype
    686          1.1  kardel  *
    687          1.1  kardel  *  This function returns a clocktype value for a given association number
    688          1.1  kardel  *  (not ID!):
    689          1.1  kardel  *
    690          1.1  kardel  *  NTP_CLOCKTYPE_UNKNOWN   Unknown clock type
    691          1.1  kardel  *  NTP_CLOCKTYPE_BROADCAST Broadcast server
    692          1.1  kardel  *  NTP_CLOCKTYPE_LOCAL     Local clock
    693          1.1  kardel  *  NTP_CLOCKTYPE_UNICAST   Unicast server
    694          1.1  kardel  *  NTP_CLOCKTYPE_MULTICAST Multicast server
    695          1.1  kardel  *
    696          1.1  kardel  ****************************************************************************/
    697  1.1.1.1.6.1    yamt int
    698  1.1.1.1.6.1    yamt ntpq_get_assoc_clocktype(
    699  1.1.1.1.6.1    yamt 	int assoc_index
    700  1.1.1.1.6.1    yamt 	)
    701  1.1.1.1.6.1    yamt {
    702  1.1.1.1.6.1    yamt 	associd_t	associd;
    703  1.1.1.1.6.1    yamt 	int		i;
    704  1.1.1.1.6.1    yamt 	int		rc;
    705  1.1.1.1.6.1    yamt 	sockaddr_u	dum_store;
    706  1.1.1.1.6.1    yamt 	char		dstadr[LENHOSTNAME];
    707  1.1.1.1.6.1    yamt 	char		resultbuf[NTPQ_BUFLEN];
    708  1.1.1.1.6.1    yamt 
    709  1.1.1.1.6.1    yamt 	if (assoc_index < 0 || assoc_index >= numassoc)
    710  1.1.1.1.6.1    yamt 		return -1;
    711  1.1.1.1.6.1    yamt 
    712  1.1.1.1.6.1    yamt 	associd = assoc_cache[assoc_index].assid;
    713  1.1.1.1.6.1    yamt 	if (associd == peervar_assoc) {
    714  1.1.1.1.6.1    yamt 		rc = ntpq_get_peervar("dstadr", dstadr, sizeof(dstadr));
    715  1.1.1.1.6.1    yamt 	} else {
    716  1.1.1.1.6.1    yamt 		i = ntpq_read_assoc_peervars(associd, resultbuf,
    717  1.1.1.1.6.1    yamt 					     sizeof(resultbuf));
    718  1.1.1.1.6.1    yamt 		if (i <= 0)
    719  1.1.1.1.6.1    yamt 			return -1;
    720  1.1.1.1.6.1    yamt 		rc = ntpq_getvar(resultbuf, i, "dstadr", dstadr,
    721  1.1.1.1.6.1    yamt 				 sizeof(dstadr));
    722  1.1.1.1.6.1    yamt 	}
    723          1.1  kardel 
    724  1.1.1.1.6.1    yamt 	if (0 != rc && decodenetnum(dstadr, &dum_store))
    725  1.1.1.1.6.1    yamt 		return ntpq_decodeaddrtype(&dum_store);
    726          1.1  kardel 
    727  1.1.1.1.6.1    yamt 	return -1;
    728          1.1  kardel }
    729          1.1  kardel 
    730          1.1  kardel 
    731          1.1  kardel 
    732          1.1  kardel /*****************************************************************************
    733          1.1  kardel  *
    734          1.1  kardel  *  ntpq_get_assoc_clockvars
    735          1.1  kardel  *
    736          1.1  kardel  *  With this function the clock variables of the specified association are
    737          1.1  kardel  *  requested from a NTP host. This makes only sense for associations with
    738          1.1  kardel  *  the type 'l' (Local Clock) and you should check this with
    739          1.1  kardel  *  ntpq_get_assoc_clocktype for each association, before you use this function
    740          1.1  kardel  *  on it.
    741          1.1  kardel  *
    742          1.1  kardel  ****************************************************************************
    743          1.1  kardel  * Parameters:
    744          1.1  kardel  *	associd		int	requested associaton ID
    745          1.1  kardel  *
    746          1.1  kardel  * Returns:
    747          1.1  kardel  *	int		1 (one) if the clockvars have been read
    748          1.1  kardel  * 			- OR -
    749          1.1  kardel  *			0 (zero) if an error occured and the variable set
    750          1.1  kardel  *			could not be read
    751          1.1  kardel  ****************************************************************************/
    752  1.1.1.1.6.1    yamt int  ntpq_get_assoc_clockvars( associd_t associd )
    753          1.1  kardel {
    754  1.1.1.1.6.1    yamt 	if (NTP_CLOCKTYPE_LOCAL != ntpq_get_assoc_clocktype(
    755  1.1.1.1.6.1    yamt 	    ntpq_get_assoc_number(associd)))
    756  1.1.1.1.6.1    yamt 		return 0;
    757  1.1.1.1.6.1    yamt 	clockvarlen = ntpq_read_assoc_clockvars( associd, clockvars,
    758  1.1.1.1.6.1    yamt 						 sizeof(clockvars) );
    759  1.1.1.1.6.1    yamt 	if ( clockvarlen <= 0 ) {
    760  1.1.1.1.6.1    yamt 		clockvar_assoc = 0;
    761  1.1.1.1.6.1    yamt 		return 0;
    762  1.1.1.1.6.1    yamt 	} else {
    763  1.1.1.1.6.1    yamt 		clockvar_assoc = associd;
    764  1.1.1.1.6.1    yamt 		return 1;
    765  1.1.1.1.6.1    yamt 	}
    766          1.1  kardel }
    767          1.1  kardel 
    768          1.1  kardel 
    769