int main( int argc, char *argv[] ) { int c, i; int quiet = 0; int errflg = 0; char *progname; extern int ntp_optind; extern char *ntp_optarg; progname = argv[0]; if (argc==2 && argv[1][0] != '-') { /* old Linux format, for compatability */ if ((i = atoi(argv[1])) > 0) { txc.time_tick = i; txc.modes = ADJ_TIMETICK; } else { fprintf(stderr, "Silly value for tick: %s\n", argv[1]); errflg++; } } else { while ((c = ntp_getopt(argc, argv, "a:qt:")) != EOF) { switch (c) { case 'a': if ((i=atoi(ntp_optarg)) > 0) { txc.tickadj = i; txc.modes |= ADJ_TICKADJ; } else { (void) fprintf(stderr, "%s: unlikely value for tickadj: %s\n", progname, ntp_optarg); errflg++; } break; case 'q': quiet = 1; break; case 't': if ((i=atoi(ntp_optarg)) > 0) { txc.time_tick = i; txc.modes |= ADJ_TIMETICK; } else { (void) fprintf(stderr, "%s: unlikely value for tick: %s\n", progname, ntp_optarg); errflg++; } break; default: fprintf(stderr, "Usage: %s [tick_value]\n-or- %s [ -q ] [ -t tick ] [ -a tickadj ]\n", progname, progname); errflg++; break; } } } if (!errflg) { if (__adjtimex(&txc) < 0) perror("adjtimex"); else if (!quiet) printf("tick = %ld\ntick_adj = %d\n", txc.time_tick, txc.tickadj); } exit(errflg ? 1 : 0); }
/* * main - parse arguments and handle options */ int main( int argc, char *argv[] ) { int c; int errflg = 0; off_t tickadj_offset; off_t tick_offset; off_t dosync_offset; off_t noprintf_offset; int tickadj, ktickadj; /* HMS: Why isn't this u_long? */ int tick, ktick; /* HMS: Why isn't this u_long? */ int dosynctodr; int noprintf; int hz; int hz_int, hz_hundredths; int recommend_tickadj; long tmp; progname = argv[0]; while ((c = ntp_getopt(argc, argv, "a:Adkpqst:")) != EOF) { switch (c) { case 'a': writetickadj = atoi(ntp_optarg); if (writetickadj <= 0) { (void) fprintf(stderr, "%s: unlikely value for tickadj: %s\n", progname, ntp_optarg); errflg++; } #if defined SCO5_CLOCK if (writetickadj % HZ) { writetickadj = (writetickadj / HZ) * HZ; (void) fprintf(stderr, "tickadj truncated to: %d\n", writetickadj); } #endif /* SCO5_CLOCK */ break; case 'A': writeopttickadj = 1; break; case 'd': ++debug; break; case 'k': dokmem = 1; break; case 'p': setnoprintf = 1; break; case 'q': quiet = 1; break; case 's': unsetdosync = 1; break; case 't': writetick = atoi(ntp_optarg); if (writetick <= 0) { (void) fprintf(stderr, "%s: unlikely value for tick: %s\n", progname, ntp_optarg); errflg++; } break; default: errflg++; break; } } if (errflg || ntp_optind != argc) { (void) fprintf(stderr, "usage: %s [-Adkpqs] [-a newadj] [-t newtick]\n", progname); exit(2); } getoffsets(&tick_offset, &tickadj_offset, &dosync_offset, &noprintf_offset); if (debug) { (void) printf("tick offset = %lu\n", (unsigned long)tick_offset); (void) printf("tickadj offset = %lu\n", (unsigned long)tickadj_offset); (void) printf("dosynctodr offset = %lu\n", (unsigned long)dosync_offset); (void) printf("noprintf offset = %lu\n", (unsigned long)noprintf_offset); } if (writetick && (tick_offset == 0)) { (void) fprintf(stderr, "No tick kernel variable\n"); errflg++; } if (writeopttickadj && (tickadj_offset == 0)) { (void) fprintf(stderr, "No tickadj kernel variable\n"); errflg++; } if (unsetdosync && (dosync_offset == 0)) { (void) fprintf(stderr, "No dosynctodr kernel variable\n"); errflg++; } if (setnoprintf && (noprintf_offset == 0)) { (void) fprintf(stderr, "No noprintf kernel variable\n"); errflg++; } if (tick_offset != 0) { readvar(fd, tick_offset, &tick); #if defined(TICK_NANO) && defined(K_TICK_NAME) if (!quiet) (void) printf("KERNEL %s = %d nsec\n", K_TICK_NAME, tick); #endif /* TICK_NANO && K_TICK_NAME */ #ifdef TICK_NANO tick /= 1000; #endif } else { tick = 0; } if (tickadj_offset != 0) { readvar(fd, tickadj_offset, &tickadj); #ifdef SCO5_CLOCK /* scale from nsec/sec to usec/tick */ tickadj /= (1000L * HZ); #endif /*SCO5_CLOCK */ #if defined(TICKADJ_NANO) && defined(K_TICKADJ_NAME) if (!quiet) (void) printf("KERNEL %s = %d nsec\n", K_TICKADJ_NAME, tickadj); #endif /* TICKADJ_NANO && K_TICKADJ_NAME */ #ifdef TICKADJ_NANO tickadj += 999; tickadj /= 1000; #endif } else { tickadj = 0; } if (dosync_offset != 0) { readvar(fd, dosync_offset, &dosynctodr); } if (noprintf_offset != 0) { readvar(fd, noprintf_offset, &noprintf); } (void) close(fd); if (unsetdosync && dosync_offset == 0) { (void) fprintf(stderr, "%s: can't find %s in namelist\n", progname, #ifdef K_DOSYNCTODR_NAME K_DOSYNCTODR_NAME #else /* not K_DOSYNCTODR_NAME */ "dosynctodr" #endif /* not K_DOSYNCTODR_NAME */ ); exit(1); } hz = HZ; #if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK) hz = (int) sysconf (_SC_CLK_TCK); #endif /* not HAVE_SYSCONF && _SC_CLK_TCK */ #ifdef OVERRIDE_HZ hz = DEFAULT_HZ; #endif ktick = tick; #ifdef PRESET_TICK tick = PRESET_TICK; #endif /* PRESET_TICK */ #ifdef TICKADJ_NANO tickadj /= 1000; if (tickadj == 0) tickadj = 1; #endif ktickadj = tickadj; #ifdef PRESET_TICKADJ tickadj = (PRESET_TICKADJ) ? PRESET_TICKADJ : 1; #endif /* PRESET_TICKADJ */ if (!quiet) { if (tick_offset != 0) { (void) printf("KERNEL tick = %d usec (from %s kernel variable)\n", ktick, #ifdef K_TICK_NAME K_TICK_NAME #else "<this can't happen>" #endif ); } #ifdef PRESET_TICK (void) printf("PRESET tick = %d usec\n", tick); #endif /* PRESET_TICK */ if (tickadj_offset != 0) { (void) printf("KERNEL tickadj = %d usec (from %s kernel variable)\n", ktickadj, #ifdef K_TICKADJ_NAME K_TICKADJ_NAME #else "<this can't happen>" #endif ); } #ifdef PRESET_TICKADJ (void) printf("PRESET tickadj = %d usec\n", tickadj); #endif /* PRESET_TICKADJ */ if (dosync_offset != 0) { (void) printf("dosynctodr is %s\n", dosynctodr ? "on" : "off"); } if (noprintf_offset != 0) { (void) printf("kernel level printf's: %s\n", noprintf ? "off" : "on"); } } if (tick <= 0) { (void) fprintf(stderr, "%s: the value of tick is silly!\n", progname); exit(1); } hz_int = (int)(1000000L / (long)tick); hz_hundredths = (int)((100000000L / (long)tick) - ((long)hz_int * 100L)); if (!quiet) { (void) printf("KERNEL hz = %d\n", hz); (void) printf("calculated hz = %d.%02d Hz\n", hz_int, hz_hundredths); } #if defined SCO5_CLOCK recommend_tickadj = 100; #else /* SCO5_CLOCK */ tmp = (long) tick * 500L; recommend_tickadj = (int)(tmp / 1000000L); if (tmp % 1000000L > 0) { recommend_tickadj++; } #ifdef MIN_REC_TICKADJ if (recommend_tickadj < MIN_REC_TICKADJ) { recommend_tickadj = MIN_REC_TICKADJ; } #endif /* MIN_REC_TICKADJ */ #endif /* SCO5_CLOCK */ if ((!quiet) && (tickadj_offset != 0)) { (void) printf("recommended value of tickadj = %d us\n", recommend_tickadj); } if ( writetickadj == 0 && !writeopttickadj && !unsetdosync && writetick == 0 && !setnoprintf) { exit(errflg ? 1 : 0); } if (writetickadj == 0 && writeopttickadj) { writetickadj = recommend_tickadj; } fd = openfile(file, O_WRONLY); if (setnoprintf && (noprintf_offset != 0)) { if (!quiet) { (void) fprintf(stderr, "setting noprintf: "); (void) fflush(stderr); } writevar(fd, noprintf_offset, 1); if (!quiet) { (void) fprintf(stderr, "done!\n"); } } if ((writetick > 0) && (tick_offset != 0)) { if (!quiet) { (void) fprintf(stderr, "writing tick, value %d: ", writetick); (void) fflush(stderr); } writevar(fd, tick_offset, writetick); if (!quiet) { (void) fprintf(stderr, "done!\n"); } } if ((writetickadj > 0) && (tickadj_offset != 0)) { if (!quiet) { (void) fprintf(stderr, "writing tickadj, value %d: ", writetickadj); (void) fflush(stderr); } #ifdef SCO5_CLOCK /* scale from usec/tick to nsec/sec */ writetickadj *= (1000L * HZ); #endif /* SCO5_CLOCK */ writevar(fd, tickadj_offset, writetickadj); if (!quiet) { (void) fprintf(stderr, "done!\n"); } } if (unsetdosync && (dosync_offset != 0)) { if (!quiet) { (void) fprintf(stderr, "zeroing dosynctodr: "); (void) fflush(stderr); } writevar(fd, dosync_offset, 0); if (!quiet) { (void) fprintf(stderr, "done!\n"); } } (void) close(fd); return(errflg ? 1 : 0); }
/* Implementation based on [1]. [1] http://www.kernel.org/doc/man-pages/online/pages/man3/getopt.3.html */ int ntp_getopt_long(int argc, char *const argv[], const char *optstring, const struct option *longopts, int *longindex) { const struct option* o = longopts; const struct option* match = NULL; int num_matches = 0; size_t argument_name_length = 0; const char* current_argument = NULL; int retval = -1; ntp_optarg = NULL; ntp_optopt = 0; if (ntp_optind >= argc) return -1; if (strlen(argv[ntp_optind]) < 3 || strncmp(argv[ntp_optind], "--", 2) != 0) return ntp_getopt(argc, argv, optstring); /* It's an option; starts with -- and is longer than two chars. */ current_argument = argv[ntp_optind] + 2; argument_name_length = strcspn(current_argument, "="); for (; o->name; ++o) { if (strncmp(o->name, current_argument, argument_name_length) == 0) { match = o; ++num_matches; } } if (num_matches == 1) { /* If longindex is not NULL, it points to a variable which is set to the index of the long option relative to longopts. */ if (longindex) *longindex = (match - longopts); /* If flag is NULL, then getopt_long() shall return val. Otherwise, getopt_long() returns 0, and flag shall point to a variable which shall be set to val if the option is found, but left unchanged if the option is not found. */ if (match->flag) *(match->flag) = match->val; retval = match->flag ? 0 : match->val; if (match->has_arg != no_argument) { ntp_optarg = strchr(argv[ntp_optind], '='); if (ntp_optarg != NULL) ++ntp_optarg; if (match->has_arg == required_argument) { /* Only scan the next argv for required arguments. Behavior is not specified, but has been observed with Ubuntu and Mac OSX. */ if (ntp_optarg == NULL && ++ntp_optind < argc) { ntp_optarg = argv[ntp_optind]; } if (ntp_optarg == NULL) retval = ':'; } } else if (strchr(argv[ntp_optind], '=')) { /* An argument was provided to a non-argument option. I haven't seen this specified explicitly, but both GNU and BSD-based implementations show this behavior. */ retval = '?'; } } else { /* Unknown option or ambiguous match. */ retval = '?'; } ++ntp_optind; return retval; }
int main( int argc, char *argv[] ) { struct timeval remains; struct sigvec vec; MsgBuf msg; char ch; int nofork = 0; int fd; progname = argv[0]; #ifdef LOG_LOCAL6 openlog("adjtimed", LOG_PID, LOG_LOCAL6); #else openlog("adjtimed", LOG_PID); #endif while ((ch = ntp_getopt(argc, argv, "hkrvdfp:")) != EOF) { switch (ch) { case 'k': case 'r': if ((mqid = msgget(KEY, 0)) != -1) { if (msgctl(mqid, IPC_RMID, (struct msqid_ds *)0) == -1) { msyslog(LOG_ERR, "remove old message queue: %m"); perror("adjtimed: remove old message queue"); exit(1); } } if (ch == 'k') exit(0); break; case 'v': ++verbose, nofork = 1; break; case 'd': ++sysdebug; break; case 'f': nofork = 1; break; case 'p': fputs("adjtimed: -p option ignored\n", stderr); break; default: puts("usage: adjtimed -hkrvdf"); puts("-h\thelp"); puts("-k\tkill existing adjtimed, if any"); puts("-r\trestart (kills existing adjtimed, if any)"); puts("-v\tdebug output (repeat for more output)"); puts("-d\tsyslog output (repeat for more output)"); puts("-f\tno fork"); msyslog(LOG_ERR, "usage error"); exit(1); } /* switch */ } /* while */ if (!nofork) { switch (fork()) { case 0: close(fileno(stdin)); close(fileno(stdout)); close(fileno(stderr)); #ifdef TIOCNOTTY if ((fd = open("/dev/tty")) != -1) { ioctl(fd, TIOCNOTTY, 0); close(fd); } #else setpgrp(); #endif break; case -1: msyslog(LOG_ERR, "fork: %m"); perror("adjtimed: fork"); exit(1); default: exit(0); } /* switch */ } /* if */ if (nofork) { setvbuf(stdout, NULL, _IONBF, BUFSIZ); setvbuf(stderr, NULL, _IONBF, BUFSIZ); } msyslog(LOG_INFO, "started"); if (verbose) printf("adjtimed: started\n"); if (InitClockRate() == -1) Exit(2); (void)signal(SIGHUP, SIG_IGN); (void)signal(SIGINT, SIG_IGN); (void)signal(SIGQUIT, SIG_IGN); (void)signal(SIGTERM, Cleanup); vec.sv_handler = ResetClockRate; vec.sv_flags = 0; vec.sv_mask = ~0; sigvector(SIGALRM, &vec, (struct sigvec *)0); if (msgget(KEY, IPC_CREAT|IPC_EXCL) == -1) { if (errno == EEXIST) { msyslog(LOG_ERR, "message queue already exists, use -r to remove it"); fputs("adjtimed: message queue already exists, use -r to remove it\n", stderr); Exit(1); } msyslog(LOG_ERR, "create message queue: %m"); perror("adjtimed: create message queue"); Exit(1); } if ((mqid = msgget(KEY, 0)) == -1) { msyslog(LOG_ERR, "get message queue id: %m"); perror("adjtimed: get message queue id"); Exit(1); } /* Lock process in memory to improve response time */ if (plock(PROCLOCK)) { msyslog(LOG_ERR, "plock: %m"); perror("adjtimed: plock"); Cleanup(); } /* Also raise process priority. * If we do not get run when we want, this leads to bad timekeeping * and "Previous time adjustment didn't complete" gripes from xntpd. */ if (nice(-10) == -1) { msyslog(LOG_ERR, "nice: %m"); perror("adjtimed: nice"); Cleanup(); } for (;;) { if (msgrcv(mqid, &msg.msgp, MSGSIZE, CLIENT, 0) == -1) { if (errno == EINTR) continue; msyslog(LOG_ERR, "read message: %m"); perror("adjtimed: read message"); Cleanup(); } switch (msg.msgb.code) { case DELTA1: case DELTA2: AdjustClockRate(&msg.msgb.tv, &remains); if (msg.msgb.code == DELTA2) { msg.msgb.tv = remains; msg.msgb.mtype = SERVER; while (msgsnd(mqid, &msg.msgp, MSGSIZE, 0) == -1) { if (errno == EINTR) continue; msyslog(LOG_ERR, "send message: %m"); perror("adjtimed: send message"); Cleanup(); } } if (remains.tv_sec + remains.tv_usec != 0L) { if (verbose) { printf("adjtimed: previous correction remaining %.6fs\n", tvtod(remains)); } if (sysdebug) { msyslog(LOG_INFO, "previous correction remaining %.6fs", tvtod(remains)); } } break; default: fprintf(stderr, "adjtimed: unknown message code %d\n", msg.msgb.code); msyslog(LOG_ERR, "unknown message code %d", msg.msgb.code); } /* switch */ } /* loop */ } /* main */
/* * main - parse arguments and handle options */ int ntpdcmain( int argc, char *argv[] ) { extern int ntp_optind; delay_time.l_ui = 0; delay_time.l_uf = DEFDELAY; #ifdef SYS_VXWORKS clear_globals(); taskPrioritySet(taskIdSelf(), 100 ); #endif init_lib(); /* sets up ipv4_works, ipv6_works */ ssl_applink(); /* Check to see if we have IPv6. Otherwise default to IPv4 */ if (!ipv6_works) ai_fam_default = AF_INET; progname = argv[0]; { int optct = ntpOptionProcess(&ntpdcOptions, argc, argv); argc -= optct; argv += optct; } if (HAVE_OPT(IPV4)) ai_fam_templ = AF_INET; else if (HAVE_OPT(IPV6)) ai_fam_templ = AF_INET6; else ai_fam_templ = ai_fam_default; if (HAVE_OPT(COMMAND)) { int cmdct = STACKCT_OPT( COMMAND ); const char** cmds = STACKLST_OPT( COMMAND ); while (cmdct-- > 0) { ADDCMD(*cmds++); } } debug = DESC(DEBUG_LEVEL).optOccCt; if (HAVE_OPT(INTERACTIVE)) { interactive = 1; } if (HAVE_OPT(NUMERIC)) { showhostnames = 0; } if (HAVE_OPT(LISTPEERS)) { ADDCMD("listpeers"); } if (HAVE_OPT(PEERS)) { ADDCMD("peers"); } if (HAVE_OPT(SHOWPEERS)) { ADDCMD("dmpeers"); } if (ntp_optind == argc) { ADDHOST(DEFHOST); } else { for (; ntp_optind < argc; ntp_optind++) ADDHOST(argv[ntp_optind]); } if (numcmds == 0 && interactive == 0 && isatty(fileno(stdin)) && isatty(fileno(stderr))) { interactive = 1; } #if 0 ai_fam_templ = ai_fam_default; while ((c = ntp_getopt(argc, argv, "46c:dilnps")) != EOF) switch (c) { case '4': ai_fam_templ = AF_INET; break; case '6': ai_fam_templ = AF_INET6; break; case 'c': ADDCMD(ntp_optarg); break; case 'd': ++debug; break; case 'i': interactive = 1; break; case 'l': ADDCMD("listpeers"); break; case 'n': showhostnames = 0; break; case 'p': ADDCMD("peers"); break; case 's': ADDCMD("dmpeers"); break; default: errflg++; break; } if (errflg) { (void) fprintf(stderr, "usage: %s [-46dilnps] [-c cmd] host ...\n", progname); exit(2); } if (ntp_optind == argc) { ADDHOST(DEFHOST); } else { for (; ntp_optind < argc; ntp_optind++) ADDHOST(argv[ntp_optind]); } if (numcmds == 0 && interactive == 0 && isatty(fileno(stdin)) && isatty(fileno(stderr))) { interactive = 1; } #endif #ifndef SYS_WINNT /* Under NT cannot handle SIGINT, WIN32 spawns a handler */ if (interactive) (void) signal_no_reset(SIGINT, abortcmd); #endif /* SYS_WINNT */ /* * Initialize the packet data buffer */ pktdatasize = INITDATASIZE; pktdata = emalloc(INITDATASIZE); if (numcmds == 0) { (void) openhost(chosts[0]); getcmds(); } else { int ihost; int icmd; for (ihost = 0; ihost < numhosts; ihost++) { if (openhost(chosts[ihost])) for (icmd = 0; icmd < numcmds; icmd++) { if (numhosts > 1) printf ("--- %s ---\n",chosts[ihost]); docmd(ccmds[icmd]); } } } #ifdef SYS_WINNT WSACleanup(); #endif return(0); } /* main end */