📄 ntpq_ops.c
字号:
/* * ntpq_ops.c - subroutines which are called to perform operations by ntpq */#include <stdio.h>#include <ctype.h>#include <sys/types.h>#include <sys/time.h>#include "ntpq.h"#include "ntp_stdlib.h"extern char * chosts[];extern char currenthost[];extern int numhosts;int maxhostlen;/* * Declarations for command handlers in here */static int checkassocid P((u_int32));static char * strsave P((char *));static struct varlist *findlistvar P((struct varlist *, char *));static void doaddvlist P((struct varlist *, char *));static void dormvlist P((struct varlist *, char *));static void doclearvlist P((struct varlist *));static void makequerydata P((struct varlist *, int *, char *));static int doquerylist P((struct varlist *, int, int, int, u_short *, int *, char **));static void doprintvlist P((struct varlist *, FILE *));static void addvars P((struct parse *, FILE *));static void rmvars P((struct parse *, FILE *));static void clearvars P((struct parse *, FILE *));static void showvars P((struct parse *, FILE *));static int dolist P((struct varlist *, int, int, int, FILE *));static void readlist P((struct parse *, FILE *));static void writelist P((struct parse *, FILE *));static void readvar P((struct parse *, FILE *));static void writevar P((struct parse *, FILE *));static void clocklist P((struct parse *, FILE *));static void clockvar P((struct parse *, FILE *));static int findassidrange P((u_int32, u_int32, int *, int *));static void mreadlist P((struct parse *, FILE *));static void mreadvar P((struct parse *, FILE *));static int dogetassoc P((FILE *));static void printassoc P((int, FILE *));static void associations P((struct parse *, FILE *));static void lassociations P((struct parse *, FILE *));static void passociations P((struct parse *, FILE *));static void lpassociations P((struct parse *, FILE *));#ifdef UNUSEDstatic void radiostatus P((struct parse *, FILE *));#endif /* UNUSED */static void pstatus P((struct parse *, FILE *));static long when P((l_fp *, l_fp *, l_fp *));static char * prettyinterval P((char *, long));static int doprintpeers P((struct varlist *, int, int, int, char *, FILE *, int));static int dogetpeers P((struct varlist *, int, FILE *, int));static void dopeers P((int, FILE *, int));static void peers P((struct parse *, FILE *));static void lpeers P((struct parse *, FILE *));static void doopeers P((int, FILE *, int));static void opeers P((struct parse *, FILE *));static void lopeers P((struct parse *, FILE *));/* * Commands we understand. Ntpdc imports this. */struct xcmd opcmds[] = { { "associations", associations, { NO, NO, NO, NO }, { "", "", "", "" }, "print list of association ID's and statuses for the server's peers" }, { "passociations", passociations, { NO, NO, NO, NO }, { "", "", "", "" }, "print list of associations returned by last associations command" }, { "lassociations", lassociations, { NO, NO, NO, NO }, { "", "", "", "" }, "print list of associations including all client information" }, { "lpassociations", lpassociations, { NO, NO, NO, NO }, { "", "", "", "" }, "print last obtained list of associations, including client information" }, { "addvars", addvars, { NTP_STR, NO, NO, NO }, { "name[=value][,...]", "", "", "" }, "add variables to the variable list or change their values" }, { "rmvars", rmvars, { NTP_STR, NO, NO, NO }, { "name[,...]", "", "", "" }, "remove variables from the variable list" }, { "clearvars", clearvars, { NO, NO, NO, NO }, { "", "", "", "" }, "remove all variables from the variable list" }, { "showvars", showvars, { NO, NO, NO, NO }, { "", "", "", "" }, "print variables on the variable list" }, { "readlist", readlist, { OPT|NTP_UINT, NO, NO, NO }, { "assocID", "", "", "" }, "read the system or peer variables included in the variable list" }, { "rl", readlist, { OPT|NTP_UINT, NO, NO, NO }, { "assocID", "", "", "" }, "read the system or peer variables included in the variable list" }, { "writelist", writelist, { OPT|NTP_UINT, NO, NO, NO }, { "assocID", "", "", "" }, "write the system or peer variables included in the variable list" }, { "readvar", readvar, { OPT|NTP_UINT, OPT|NTP_STR, NO, NO }, { "assocID", "name=value[,...]", "", "" }, "read system or peer variables" }, { "rv", readvar, { OPT|NTP_UINT, OPT|NTP_STR, NO, NO }, { "assocID", "name=value[,...]", "", "" }, "read system or peer variables" }, { "writevar", writevar, { NTP_UINT, NTP_STR, NO, NO }, { "assocID", "name=value,[...]", "", "" }, "write system or peer variables" }, { "mreadlist", mreadlist, { NTP_UINT, NTP_UINT, NO, NO }, { "assocID", "assocID", "", "" }, "read the peer variables in the variable list for multiple peers" }, { "mrl", mreadlist, { NTP_UINT, NTP_UINT, NO, NO }, { "assocID", "assocID", "", "" }, "read the peer variables in the variable list for multiple peers" }, { "mreadvar", mreadvar, { NTP_UINT, NTP_UINT, OPT|NTP_STR, NO }, { "assocID", "assocID", "name=value[,...]", "" }, "read peer variables from multiple peers" }, { "mrv", mreadvar, { NTP_UINT, NTP_UINT, OPT|NTP_STR, NO }, { "assocID", "assocID", "name=value[,...]", "" }, "read peer variables from multiple peers" }, { "clocklist", clocklist, { OPT|NTP_UINT, NO, NO, NO }, { "assocID", "", "", "" }, "read the clock variables included in the variable list" }, { "cl", clocklist, { OPT|NTP_UINT, NO, NO, NO }, { "assocID", "", "", "" }, "read the clock variables included in the variable list" }, { "clockvar", clockvar, { OPT|NTP_UINT, OPT|NTP_STR, NO, NO }, { "assocID", "name=value[,...]", "", "" }, "read clock variables" }, { "cv", clockvar, { OPT|NTP_UINT, OPT|NTP_STR, NO, NO }, { "assocID", "name=value[,...]", "", "" }, "read clock variables" }, { "pstatus", pstatus, { NTP_UINT, NO, NO, NO }, { "assocID", "", "", "" }, "print status information returned for a peer" }, { "peers", peers, { OPT|IP_VERSION, NO, NO, NO }, { "-4|-6", "", "", "" }, "obtain and print a list of the server's peers [IP version]" }, { "lpeers", lpeers, { OPT|IP_VERSION, NO, NO, NO }, { "-4|-6", "", "", "" }, "obtain and print a list of all peers and clients [IP version]" }, { "opeers", opeers, { OPT|IP_VERSION, NO, NO, NO }, { "-4|-6", "", "", "" }, "print peer list the old way, with dstadr shown rather than refid [IP version]" }, { "lopeers", lopeers, { OPT|IP_VERSION, NO, NO, NO }, { "-4|-6", "", "", "" }, "obtain and print a list of all peers and clients showing dstadr [IP version]" }, { 0, 0, { NO, NO, NO, NO }, { "-4|-6", "", "", "" }, "" }};/* * Variable list data space */#define MAXLIST 64 /* maximum number of variables in list */#define LENHOSTNAME 256 /* host name is 256 characters long *//* * Old CTL_PST defines for version 2. */#define OLD_CTL_PST_CONFIG 0x80#define OLD_CTL_PST_AUTHENABLE 0x40#define OLD_CTL_PST_AUTHENTIC 0x20#define OLD_CTL_PST_REACH 0x10#define OLD_CTL_PST_SANE 0x08#define OLD_CTL_PST_DISP 0x04#define OLD_CTL_PST_SEL_REJECT 0#define OLD_CTL_PST_SEL_SELCAND 1#define OLD_CTL_PST_SEL_SYNCCAND 2#define OLD_CTL_PST_SEL_SYSPEER 3char flash2[] = " .+* "; /* flash decode for version 2 */char flash3[] = " x.-+#*o"; /* flash decode for peer status version 3 */struct varlist { char *name; char *value;} varlist[MAXLIST] = { { 0, 0 } };/* * Imported from ntpq.c */extern int showhostnames;extern int rawmode;extern struct servent *server_entry;extern struct association assoc_cache[];extern int numassoc;extern u_char pktversion;extern struct ctl_var peer_var[];/* * For quick string comparisons */#define STREQ(a, b) (*(a) == *(b) && strcmp((a), (b)) == 0)/* * checkassocid - return the association ID, checking to see if it is valid */static intcheckassocid( u_int32 value ){ if (value == 0 || value >= 65536) { (void) fprintf(stderr, "***Invalid association ID specified\n"); return 0; } return (int)value;}/* * strsave - save a string * XXX - should be in libntp.a */static char *strsave( char *str ){ char *cp; u_int len; len = strlen(str) + 1; if ((cp = (char *)malloc(len)) == NULL) { (void) fprintf(stderr, "Malloc failed!!\n"); exit(1); } memmove(cp, str, len); return (cp);}/* * findlistvar - look for the named variable in a list and return if found */static struct varlist *findlistvar( struct varlist *list, char *name ){ register struct varlist *vl; for (vl = list; vl < list + MAXLIST && vl->name != 0; vl++) if (STREQ(name, vl->name)) return vl; if (vl < list + MAXLIST) return vl; return (struct varlist *)0;}/* * doaddvlist - add variable(s) to the variable list */static voiddoaddvlist( struct varlist *vlist, char *vars ){ register struct varlist *vl; int len; char *name; char *value; len = strlen(vars); while (nextvar(&len, &vars, &name, &value)) { vl = findlistvar(vlist, name); if (vl == 0) { (void) fprintf(stderr, "Variable list full\n"); return; } if (vl->name == 0) { vl->name = strsave(name); } else if (vl->value != 0) { free(vl->value); vl->value = 0; } if (value != 0) vl->value = strsave(value); }}/* * dormvlist - remove variable(s) from the variable list */static voiddormvlist( struct varlist *vlist, char *vars ){ register struct varlist *vl; int len; char *name; char *value; len = strlen(vars); while (nextvar(&len, &vars, &name, &value)) { vl = findlistvar(vlist, name); if (vl == 0 || vl->name == 0) { (void) fprintf(stderr, "Variable `%s' not found\n", name); } else { free((void *)vl->name); if (vl->value != 0) free(vl->value); for ( ; (vl+1) < (varlist+MAXLIST) && (vl+1)->name != 0; vl++) { vl->name = (vl+1)->name; vl->value = (vl+1)->value; } vl->name = vl->value = 0; } }}/* * doclearvlist - clear a variable list */static voiddoclearvlist( struct varlist *vlist ){ register struct varlist *vl; for (vl = vlist; vl < vlist + MAXLIST && vl->name != 0; vl++) { free((void *)vl->name); vl->name = 0; if (vl->value != 0) { free(vl->value); vl->value = 0; } }}/* * makequerydata - form a data buffer to be included with a query */static voidmakequerydata( struct varlist *vlist, int *datalen, char *data ){ register struct varlist *vl; register char *cp, *cpend; register int namelen, valuelen; register int totallen; cp = data; cpend = data + *datalen; for (vl = vlist; vl < vlist + MAXLIST && vl->name != 0; vl++) { namelen = strlen(vl->name); if (vl->value == 0) valuelen = 0; else valuelen = strlen(vl->value); totallen = namelen + valuelen + (valuelen != 0) + (cp != data); if (cp + totallen > cpend) break; if (cp != data) *cp++ = ','; memmove(cp, vl->name, (unsigned)namelen); cp += namelen; if (valuelen != 0) { *cp++ = '='; memmove(cp, vl->value, (unsigned)valuelen); cp += valuelen; } } *datalen = cp - data;}/* * doquerylist - send a message including variables in a list */static intdoquerylist( struct varlist *vlist, int op, int associd, int auth, u_short *rstatus, int *dsize, char **datap ){ char data[CTL_MAX_DATA_LEN]; int datalen; datalen = sizeof(data); makequerydata(vlist, &datalen, data); return doquery(op, associd, auth, datalen, data, rstatus, dsize, datap);}/* * doprintvlist - print the variables on a list */static voiddoprintvlist( struct varlist *vlist, FILE *fp ){ register struct varlist *vl; if (vlist->name == 0) { (void) fprintf(fp, "No variables on list\n"); } else { for (vl = vlist; vl < vlist + MAXLIST && vl->name != 0; vl++) { if (vl->value == 0) { (void) fprintf(fp, "%s\n", vl->name); } else { (void) fprintf(fp, "%s=%s\n", vl->name, vl->value); } } }}/* * addvars - add variables to the variable list *//*ARGSUSED*/static voidaddvars( struct parse *pcmd, FILE *fp ){ doaddvlist(varlist, pcmd->argval[0].string);}/* * rmvars - remove variables from the variable list *//*ARGSUSED*/static voidrmvars( struct parse *pcmd, FILE *fp ){ dormvlist(varlist, pcmd->argval[0].string);}/* * clearvars - clear the variable list *//*ARGSUSED*/static voidclearvars( struct parse *pcmd, FILE *fp ){ doclearvlist(varlist);}/* * showvars - show variables on the variable list *//*ARGSUSED*/static voidshowvars( struct parse *pcmd, FILE *fp ){ doprintvlist(varlist, fp);}/* * dolist - send a request with the given list of variables */static intdolist( struct varlist *vlist, int associd, int op, int type, FILE *fp ){ char *datap; int res; int dsize; u_short rstatus; res = doquerylist(vlist, op, associd, 0, &rstatus, &dsize, &datap); if (res != 0) return 0; if (numhosts > 1) (void) fprintf(fp, "server=%s ", currenthost); if (dsize == 0) { if (associd == 0) (void) fprintf(fp, "No system%s variables returned\n", (type == TYPE_CLOCK) ? " clock" : ""); else (void) fprintf(fp, "No information returned for%s association %u\n", (type == TYPE_CLOCK) ? " clock" : "", associd); return 1; } (void) fprintf(fp,"assID=%d ",associd); printvars(dsize, datap, (int)rstatus, type, fp); return 1;}/* * readlist - send a read variables request with the variables on the list */static voidreadlist( struct parse *pcmd, FILE *fp ){ int associd; if (pcmd->nargs == 0) { associd = 0; } else { /* HMS: I think we want the u_int32 target here, not the u_long */ if (pcmd->argval[0].uval == 0) associd = 0; else if ((associd = checkassocid(pcmd->argval[0].uval)) == 0) return; } (void) dolist(varlist, associd, CTL_OP_READVAR, (associd == 0) ? TYPE_SYS : TYPE_PEER, fp);}/* * writelist - send a write variables request with the variables on the list */static voidwritelist( struct parse *pcmd, FILE *fp ){ char *datap; int res; int associd; int dsize; u_short rstatus; if (pcmd->nargs == 0) { associd = 0; } else { /* HMS: Do we really want uval here? */ if (pcmd->argval[0].uval == 0) associd = 0; else if ((associd = checkassocid(pcmd->argval[0].uval)) == 0)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -