📄 ntpq.c
字号:
*/ if (!havehost) { (void) fprintf(stderr, "***No host open, use `host' command\n"); return -1; } done = 0; sequence++; again: /* * send a request */ res = sendrequest(opcode, associd, auth, qsize, qdata); if (res != 0) return res; /* * Get the response. If we got a standard error, print a message */ res = getresponse(opcode, associd, rstatus, rsize, rdata, done); if (res > 0) { if (!done && (res == ERR_TIMEOUT || res == ERR_INCOMPLETE)) { if (res == ERR_INCOMPLETE) { /* * better bump the sequence so we don't * get confused about differing fragments. */ sequence++; } done = 1; goto again; } if (numhosts > 1) (void) fprintf(stderr, "server=%s ", currenthost); switch(res) { case CERR_BADFMT: (void) fprintf(stderr, "***Server reports a bad format request packet\n"); break; case CERR_PERMISSION: (void) fprintf(stderr, "***Server disallowed request (authentication?)\n"); break; case CERR_BADOP: (void) fprintf(stderr, "***Server reports a bad opcode in request\n"); break; case CERR_BADASSOC: (void) fprintf(stderr, "***Association ID %d unknown to server\n",associd); break; case CERR_UNKNOWNVAR: (void) fprintf(stderr, "***A request variable unknown to the server\n"); break; case CERR_BADVALUE: (void) fprintf(stderr, "***Server indicates a request variable was bad\n"); break; case ERR_UNSPEC: (void) fprintf(stderr, "***Server returned an unspecified error\n"); break; case ERR_TIMEOUT: (void) fprintf(stderr, "***Request timed out\n"); break; case ERR_INCOMPLETE: (void) fprintf(stderr, "***Response from server was incomplete\n"); break; case ERR_TOOMUCH: (void) fprintf(stderr, "***Buffer size exceeded for returned data\n"); break; default: (void) fprintf(stderr, "***Server returns unknown error code %d\n", res); break; } } return res;}/* * getcmds - read commands from the standard input and execute them */static voidgetcmds(void){#if defined(HAVE_LIBREADLINE) || defined(HAVE_LIBEDIT) char *line; for (;;) { if ((line = readline(interactive?prompt:"")) == NULL) return; if (*line) add_history(line); docmd(line); free(line); }#else /* not (HAVE_LIBREADLINE || HAVE_LIBEDIT) */ char line[MAXLINE]; for (;;) { if (interactive) {#ifdef VMS /* work around a problem with mixing stdout & stderr */ fputs("",stdout);#endif (void) fputs(prompt, stderr); (void) fflush(stderr); } if (fgets(line, sizeof line, stdin) == NULL) return; docmd(line); }#endif /* not (HAVE_LIBREADLINE || HAVE_LIBEDIT) */}#ifndef SYS_WINNT /* Under NT cannot handle SIGINT, WIN32 spawns a handler *//* * abortcmd - catch interrupts and abort the current command */static RETSIGTYPEabortcmd( int sig ){ if (current_output == stdout) (void) fflush(stdout); putc('\n', stderr); (void) fflush(stderr); if (jump) longjmp(interrupt_buf, 1);}#endif /* SYS_WINNT *//* * docmd - decode the command line and execute a command */static voiddocmd( const char *cmdline ){ char *tokens[1+MAXARGS+2]; struct parse pcmd; int ntok; static int i; struct xcmd *xcmd; /* * Tokenize the command line. If nothing on it, return. */ tokenize(cmdline, tokens, &ntok); if (ntok == 0) return; /* * Find the appropriate command description. */ i = findcmd(tokens[0], builtins, opcmds, &xcmd); if (i == 0) { (void) fprintf(stderr, "***Command `%s' unknown\n", tokens[0]); return; } else if (i >= 2) { (void) fprintf(stderr, "***Command `%s' ambiguous\n", tokens[0]); return; } /* * Save the keyword, then walk through the arguments, interpreting * as we go. */ pcmd.keyword = tokens[0]; pcmd.nargs = 0; for (i = 0; i < MAXARGS && xcmd->arg[i] != NO; i++) { if ((i+1) >= ntok) { if (!(xcmd->arg[i] & OPT)) { printusage(xcmd, stderr); return; } break; } if ((xcmd->arg[i] & OPT) && (*tokens[i+1] == '>')) break; if (!getarg(tokens[i+1], (int)xcmd->arg[i], &pcmd.argval[i])) return; pcmd.nargs++; } i++; if (i < ntok && *tokens[i] == '>') { char *fname; if (*(tokens[i]+1) != '\0') fname = tokens[i]+1; else if ((i+1) < ntok) fname = tokens[i+1]; else { (void) fprintf(stderr, "***No file for redirect\n"); return; } current_output = fopen(fname, "w"); if (current_output == NULL) { (void) fprintf(stderr, "***Error opening %s: ", fname); perror(""); return; } i = 1; /* flag we need a close */ } else { current_output = stdout; i = 0; /* flag no close */ } if (interactive && setjmp(interrupt_buf)) { jump = 0; return; } else { jump++; (xcmd->handler)(&pcmd, current_output); jump = 0; /* HMS: 961106: was after fclose() */ if (i) (void) fclose(current_output); }}/* * tokenize - turn a command line into tokens */static voidtokenize( const char *line, char **tokens, int *ntok ){ register const char *cp; register char *sp; static char tspace[MAXLINE]; sp = tspace; cp = line; for (*ntok = 0; *ntok < MAXTOKENS; (*ntok)++) { tokens[*ntok] = sp; while (ISSPACE(*cp)) cp++; if (ISEOL(*cp)) break; do { *sp++ = *cp++; } while (!ISSPACE(*cp) && !ISEOL(*cp)); *sp++ = '\0'; }}/* * findcmd - find a command in a command description table */static intfindcmd( register char *str, struct xcmd *clist1, struct xcmd *clist2, struct xcmd **cmd ){ register struct xcmd *cl; register int clen; int nmatch; struct xcmd *nearmatch = NULL; struct xcmd *clist; clen = strlen(str); nmatch = 0; if (clist1 != 0) clist = clist1; else if (clist2 != 0) clist = clist2; else return 0; again: for (cl = clist; cl->keyword != 0; cl++) { /* do a first character check, for efficiency */ if (*str != *(cl->keyword)) continue; if (strncmp(str, cl->keyword, (unsigned)clen) == 0) { /* * Could be extact match, could be approximate. * Is exact if the length of the keyword is the * same as the str. */ if (*((cl->keyword) + clen) == '\0') { *cmd = cl; return 1; } nmatch++; nearmatch = cl; } } /* * See if there is more to do. If so, go again. Sorry about the * goto, too much looking at BSD sources... */ if (clist == clist1 && clist2 != 0) { clist = clist2; goto again; } /* * If we got extactly 1 near match, use it, else return number * of matches. */ if (nmatch == 1) { *cmd = nearmatch; return 1; } return nmatch;}/* * getarg - interpret an argument token */static intgetarg( char *str, int code, arg_v *argp ){ int isneg; char *cp, *np; static const char *digits = "0123456789"; switch (code & ~OPT) { case NTP_STR: argp->string = str; break; case NTP_ADD: if (!getnetnum(str, &(argp->netnum), (char *)0, 0)) { return 0; } break; case NTP_INT: case NTP_UINT: isneg = 0; np = str; if (*np == '&') { np++; isneg = atoi(np); if (isneg <= 0) { (void) fprintf(stderr, "***Association value `%s' invalid/undecodable\n", str); return 0; } if (isneg > numassoc) { if (numassoc == 0) { (void) fprintf(stderr, "***Association for `%s' unknown (max &%d)\n", str, numassoc); return 0; } else { isneg = numassoc; } } argp->uval = assoc_cache[isneg-1].assid; break; } if (*np == '-') { np++; isneg = 1; } argp->uval = 0; do { cp = strchr(digits, *np); if (cp == NULL) { (void) fprintf(stderr, "***Illegal integer value %s\n", str); return 0; } argp->uval *= 10; argp->uval += (cp - digits); } while (*(++np) != '\0'); if (isneg) { if ((code & ~OPT) == NTP_UINT) { (void) fprintf(stderr, "***Value %s should be unsigned\n", str); return 0; } argp->ival = -argp->ival; } break; case IP_VERSION: if (!strcmp("-6", str)) argp->ival = 6 ; else if (!strcmp("-4", str)) argp->ival = 4 ; else { (void) fprintf(stderr, "***Version must be either 4 or 6\n"); return 0; } break; } return 1;}/* * getnetnum - given a host name, return its net number * and (optional) full name */intgetnetnum( const char *hname, struct sockaddr_storage *num, char *fullhost, int af ){ int sockaddr_len; struct addrinfo hints, *ai = NULL; sockaddr_len = (af == AF_INET) ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6); memset((char *)&hints, 0, sizeof(struct addrinfo)); hints.ai_flags = AI_CANONNAME;#ifdef AI_ADDRCONFIG hints.ai_flags |= AI_ADDRCONFIG;#endif /* decodenetnum works with addresses only */ if (decodenetnum(hname, num)) { if (fullhost != 0) { getnameinfo((struct sockaddr *)num, sockaddr_len, fullhost, sizeof(fullhost), NULL, 0, NI_NUMERICHOST); } return 1; } else if (getaddrinfo(hname, "ntp", &hints, &ai) == 0) { memmove((char *)num, ai->ai_addr, ai->ai_addrlen); if (ai->ai_canonname != 0) (void) strcpy(fullhost, ai->ai_canonname); return 1; } else { (void) fprintf(stderr, "***Can't find host %s\n", hname); return 0; } /*NOTREACHED*/}/* * nntohost - convert network number to host name. This routine enforces * the showhostnames setting. */char *nntohost( struct sockaddr_storage *netnum ){ if (!showhostnames) return stoa(netnum); if ((netnum->ss_family == AF_INET) && ISREFCLOCKADR(netnum)) return refnumtoa(netnum); return socktohost(netnum);}/* * rtdatetolfp - decode an RT-11 date into an l_fp */static intrtdatetolfp( char *str, l_fp *lfp ){ register char *cp; register int i; struct calendar cal; char buf[4]; static const char *months[12] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; cal.yearday = 0; /* * An RT-11 date looks like: * * d[d]-Mth-y[y] hh:mm:ss * * (No docs, but assume 4-digit years are also legal...) * * d[d]-Mth-y[y[y[y]]] hh:mm:ss */ cp = str; if (!isdigit((int)*cp)) { if (*cp == '-') { /* * Catch special case */ L_CLR(lfp); return 1; } return 0; } cal.monthday = (u_char) (*cp++ - '0'); /* ascii dependent */ if (isdigit((int)*cp)) { cal.monthday = (u_char)((cal.monthday << 3) + (cal.monthday << 1)); cal.monthday = (u_char)(cal.monthday + *cp++ - '0'); } if (*cp++ != '-') return 0; for (i = 0; i < 3; i++) buf[i] = *cp++; buf[3] = '\0'; for (i = 0; i < 12; i++) if (STREQ(buf, months[i])) break; if (i == 12) return 0; cal.month = (u_char)(i + 1); if (*cp++ != '-') return 0; if (!isdigit((int)*cp)) return 0; cal.year = (u_short)(*cp++ - '0'); if (isdigit((int)*cp)) { cal.year = (u_short)((cal.year << 3) + (cal.year << 1)); cal.year = (u_short)(*cp++ - '0'); } if (isdigit((int)*cp)) { cal.year = (u_short)((cal.year << 3) + (cal.year << 1)); cal.year = (u_short)(cal.year + *cp++ - '0'); } if (isdigit((int)*cp)) { cal.year = (u_short)((cal.year << 3) + (cal.year << 1)); cal.year = (u_short)(cal.year + *cp++ - '0'); } /* * Catch special case. If cal.year == 0 this is a zero timestamp. */ if (cal.year == 0) { L_CLR(lfp); return 1; } if (*cp++ != ' ' || !isdigit((int)*cp)) return 0; cal.hour = (u_char)(*cp++ - '0'); if (isdigit((int)*cp)) { cal.hour = (u_char)((cal.hour << 3) + (cal.hour << 1)); cal.hour = (u_char)(cal.hour + *cp++ - '0'); } if (*cp++ != ':' || !isdigit((int)*cp)) return 0; cal.minute = (u_char)(*cp++ - '0'); if (isdigit((int)*cp)) { cal.minute = (u_char)((cal.minute << 3) + (cal.minute << 1)); cal.minute = (u_char)(cal.minute + *cp++ - '0'); } if (*cp++ != ':' || !isdigit((int)*cp)) return 0; cal.second = (u_char)(*cp++ - '0'); if (isdigit((int)*cp)) { cal.second = (u_char)((cal.second << 3) + (cal.second << 1)); cal.second = (u_char)(cal.second + *cp++ - '0'); } /* * For RT-11, 1972 seems to be the pivot year */ if (cal.year < 72) cal.year += 2000; if (cal.year < 100) cal.year += 1900; lfp->l_ui = caltontp(&cal); lfp->l_uf = 0; return 1;}/* * decodets - decode a timestamp into an l_fp format number, with * consideration of fuzzball formats. */intdecodets( char *str, l_fp *lfp ){ /* * If it starts with a 0x, decode as hex. */ if (*str == '0' && (*(str+1) == 'x' || *(str+1) == 'X'))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -