123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227 |
- #include "gpsd_config.h"
- #include <getopt.h>
- #include <limits.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <unistd.h>
- #include "gps.h"
- #include "ntpshm.h"
- #include "revision.h"
- #include "timespec.h"
- #include "os_compat.h"
- #define NTPSEGMENTS 256
- static struct shmTime *segments[NTPSEGMENTS + 1];
- int main(int argc, char **argv)
- {
- int option;
- int i;
- bool killall = false;
- bool offset = false;
- bool verbose = false;
- int nsamples = INT_MAX;
- time_t timeout = (time_t)0, starttime = time(NULL);
-
- struct shm_stat_t shm_stat_old[NTPSEGMENTS + 1];
- char *whoami;
-
- (whoami = strrchr(argv[0], '/')) ? ++whoami : (whoami = argv[0]);
- memset( shm_stat_old, 0 ,sizeof( shm_stat_old));
- while ((option = getopt(argc, argv, "?hn:ost:vV")) != -1) {
- switch (option) {
- case '?':
- case 'h':
- (void)fprintf(
- stderr,
- "usage: ntpshmmon [-?] [-h] [-n nsamples] [-o] [-s] [-t nseconds] [-v] [-V]\n"
- " -? print this help\n"
- " -h print this help\n"
- " -n nsamples exit after nsamples\n"
- " -o replace Seen@ with Offset\n"
- " -s remove SHMs and exit\n"
- " -t nseconds exit after nseconds\n"
- " -v be verbose\n"
- " -V print version and exit\n"
- );
- exit(EXIT_SUCCESS);
- case 'n':
- nsamples = atoi(optarg);
- break;
- case 'o':
- offset = true;
- break;
- case 's':
- killall = true;
- break;
- case 't':
- timeout = (time_t)atoi(optarg);
- break;
- case 'v':
- verbose = true;
- break;
- case 'V':
- (void)fprintf(stderr, "%s: version %s (revision %s)\n",
- whoami, VERSION, REVISION);
- exit(EXIT_SUCCESS);
- default:
-
- break;
- }
- }
-
- for (i = 0; i < NTPSEGMENTS; i++) {
- segments[i] = shm_get(i, false, true);
- if (verbose && segments[i] != NULL)
- (void)fprintf(stderr, "unit %d opened\n", i);
- }
- if (killall) {
- struct shmTime **pp;
- for (pp = segments; pp < segments + NTPSEGMENTS; pp++)
- if (*pp != NULL)
- (void)shmdt((void *)(*pp));
- exit(EXIT_SUCCESS);
- }
-
- setvbuf(stdout, NULL, _IOLBF, 0);
- (void)printf("%s: version %s\n", whoami, VERSION);
- if (offset) {
- (void)printf("# Name Offset Clock Real L Prc\n");
- } else {
- (void)printf("# Name Seen@ Clock Real L Prc\n");
- }
- do {
-
- struct shm_stat_t shm_stat;
- struct timespec delay;
- char ts_buf1[TIMESPEC_LEN];
- char ts_buf2[TIMESPEC_LEN];
- char ts_buf3[TIMESPEC_LEN];
- for (i = 0; i < NTPSEGMENTS; i++) {
- long long diff;
- enum segstat_t status = ntp_read(segments[i], &shm_stat, false);
- if (verbose)
- (void)fprintf(stderr, "unit %d status %d\n", i, status);
- switch(status) {
- case OK:
-
- diff = timespec_diff_ns(shm_stat.tvr, shm_stat_old[i].tvr);
- if ( 0 == diff) {
-
- break;
- }
- diff = timespec_diff_ns(shm_stat.tvt, shm_stat_old[i].tvt);
- if ( 0 == diff) {
-
- break;
- }
-
- clock_gettime(CLOCK_REALTIME, &shm_stat.tvc);
- if (offset) {
- diff = timespec_diff_ns(shm_stat.tvr, shm_stat.tvt);
- printf("sample %s %20.9f %s %s %d %3d\n",
- ntp_name(i),
- (double)diff * 1e-9,
- timespec_str(&shm_stat.tvr, ts_buf1,
- sizeof(ts_buf1)),
- timespec_str(&shm_stat.tvt, ts_buf2,
- sizeof(ts_buf2)),
- shm_stat.leap, shm_stat.precision);
- } else {
- printf("sample %s %s %s %s %d %3d\n",
- ntp_name(i),
- timespec_str(&shm_stat.tvc, ts_buf1,
- sizeof(ts_buf1)),
- timespec_str(&shm_stat.tvr, ts_buf2,
- sizeof(ts_buf2)),
- timespec_str(&shm_stat.tvt, ts_buf3,
- sizeof(ts_buf3)),
- shm_stat.leap, shm_stat.precision);
- }
- --nsamples;
-
- shm_stat_old[i] = shm_stat;
- break;
- case NO_SEGMENT:
- break;
- case NOT_READY:
-
- break;
- case BAD_MODE:
- (void)fprintf(stderr,
- "ntpshmmon: unknown mode %d on segment %s\n",
- shm_stat.status, ntp_name(i));
- break;
- case CLASH:
-
- break;
- default:
- (void)fprintf(stderr,
- "ntpshmmon: unknown status %d on segment %s\n",
- status, ntp_name(i));
- break;
- }
- }
-
-
- if ( timeout ) {
-
- if ( time(NULL) > (starttime + timeout ) ) {
-
- break;
- }
- }
-
- delay.tv_sec = 0;
- delay.tv_nsec = 1000000L;
- nanosleep(&delay, NULL);
- } while ( 0 < nsamples );
- exit(EXIT_SUCCESS);
- }
|