Annotation of embedaddon/ntp/clockstuff/clktest.c, revision 1.1
1.1 ! misho 1: /* clktest.c,v 3.1 1993/07/06 01:05:23 jbj Exp
! 2: * clktest - test the clock line discipline
! 3: *
! 4: * usage: clktest -b bps -f -t timeo -s cmd -c char1 -a char2 /dev/whatever
! 5: */
! 6:
! 7: #include "clktest-opts.h"
! 8:
! 9: #define STREQ(a, b) (*(a) == *(b) && strcmp((a), (b)) == 0)
! 10:
! 11: #if defined(ULT_2_0_SUCKS)
! 12: #ifndef sigmask
! 13: #define sigmask(m) (1<<(m))
! 14: #endif
! 15: #endif
! 16:
! 17: #ifndef STREAM
! 18: # ifndef CLKLDISC
! 19: CLOCK_LINE_DISCIPLINE_NEEDED_BY_THIS_PROGRAM;
! 20: # endif
! 21: #else
! 22: # ifdef CLKLDISC
! 23: ONLY_ONE_CLOCK_LINE_DISCIPLINE_FOR_THIS_PROGRAM;
! 24: # endif
! 25: #endif
! 26:
! 27: /*
! 28: * Mask for blocking SIGIO and SIGALRM
! 29: */
! 30: #define BLOCKSIGMASK (sigmask(SIGIO)|sigmask(SIGALRM))
! 31:
! 32: #define progname clktestOptions.pzProgName
! 33:
! 34: struct timeval timeout = { 0 };
! 35: char *cmd = NULL;
! 36: int cmdlen;
! 37:
! 38: #ifdef CLKLDISC
! 39: u_long magic1 = DEFMAGIC;
! 40: u_long magic2 = DEFMAGIC;
! 41: #endif
! 42:
! 43: int speed = B9600;
! 44: int ttflags = RAW|EVENP|ODDP;
! 45:
! 46: volatile int wasalarmed;
! 47: volatile int iosig;
! 48:
! 49: struct timeval lasttv;
! 50:
! 51: extern u_long ustotslo[];
! 52: extern u_long ustotsmid[];
! 53: extern u_long ustotshi[];
! 54:
! 55: int alarming();
! 56: int ioready();
! 57:
! 58: /*
! 59: * main - parse arguments and handle options
! 60: */
! 61: int
! 62: main(
! 63: int argc,
! 64: char *argv[]
! 65: )
! 66: {
! 67: int fd;
! 68: struct sgttyb ttyb;
! 69: struct itimerval itimer;
! 70:
! 71: #ifdef STREAM
! 72: magic[0] = 0;
! 73: #endif
! 74:
! 75: {
! 76: int ct = optionProcess( &clktestOptions, argc, argv );
! 77: if (HAVE_OPT(COMMAND) && (strlen(OPT_ARG(COMMAND)) == 0)) {
! 78: fputs( "The command option string must not be empty\n", stderr );
! 79: USAGE( EXIT_FAILURE );
! 80: }
! 81:
! 82: if ((argc -= ct) != 1) {
! 83: fputs( "Missing tty device name\n", stderr );
! 84: USAGE( EXIT_FAILURE );
! 85: }
! 86: argv += ct;
! 87: }
! 88: #ifdef STREAM
! 89: if (!strlen(magic))
! 90: strcpy(magic,DEFMAGIC);
! 91: #endif
! 92:
! 93: fd = open(*argv, HAVE_OPT(TIMEOUT) ? O_RDWR : O_RDONLY, 0777);
! 94: if (fd == -1) {
! 95: fprintf(stderr, "%s: open(%s): ", progname, *argv);
! 96: perror("");
! 97: exit(1);
! 98: }
! 99:
! 100: if (ioctl(fd, TIOCEXCL, (char *)0) < 0) {
! 101: (void) fprintf(stderr, "%s: ioctl(TIOCEXCL): ", progname);
! 102: perror("");
! 103: exit(1);
! 104: }
! 105:
! 106: /*
! 107: * If we have the clock discipline, set the port to raw. Otherwise
! 108: * we run cooked.
! 109: */
! 110: ttyb.sg_ispeed = ttyb.sg_ospeed = speed;
! 111: #ifdef CLKLDISC
! 112: ttyb.sg_erase = (char)magic1;
! 113: ttyb.sg_kill = (char)magic2;
! 114: #endif
! 115: ttyb.sg_flags = (short)ttflags;
! 116: if (ioctl(fd, TIOCSETP, (char *)&ttyb) < 0) {
! 117: (void) fprintf(stderr, "%s: ioctl(TIOCSETP): ", progname);
! 118: perror("");
! 119: exit(1);
! 120: }
! 121:
! 122: if (fcntl(fd, F_SETOWN, getpid()) == -1) {
! 123: (void) fprintf(stderr, "%s: fcntl(F_SETOWN): ", progname);
! 124: perror("");
! 125: exit(1);
! 126: }
! 127:
! 128: #ifdef CLKLDISC
! 129: {
! 130: int ldisc;
! 131: ldisc = CLKLDISC;
! 132: if (ioctl(fd, TIOCSETD, (char *)&ldisc) < 0) {
! 133: (void) fprintf(stderr, "%s: ioctl(TIOCSETD): ", progname);
! 134: perror("");
! 135: exit(1);
! 136: }
! 137: }
! 138: #endif
! 139: #ifdef STREAM
! 140: if (ioctl(fd, I_POP, 0) >=0 ) ;
! 141: if (ioctl(fd, I_PUSH, "clk") < 0) {
! 142: (void) fprintf(stderr, "%s: ioctl(I_PUSH): ", progname);
! 143: perror("");
! 144: exit(1);
! 145: }
! 146: if (ioctl(fd, CLK_SETSTR, magic) < 0) {
! 147: (void) fprintf(stderr, "%s: ioctl(CLK_SETSTR): ", progname);
! 148: perror("");
! 149: exit(1);
! 150: }
! 151: #endif
! 152:
! 153:
! 154: (void) gettimeofday(&lasttv, (struct timezone *)0);
! 155: if (HAVE_OPT(TIMEOUT)) {
! 156: /*
! 157: * set non-blocking, async I/O on the descriptor
! 158: */
! 159: iosig = 0;
! 160: (void) signal(SIGIO, ioready);
! 161: if (fcntl(fd, F_SETFL, FNDELAY|FASYNC) < 0) {
! 162: (void) fprintf(stderr, "%s: fcntl(F_SETFL): ",
! 163: progname);
! 164: perror("");
! 165: exit(1);
! 166: }
! 167:
! 168: /*
! 169: * Set up the alarm interrupt.
! 170: */
! 171: wasalarmed = 0;
! 172: (void) signal(SIGALRM, alarming);
! 173: timeout.tv_sec = OPT_VALUE_TIMEOUT;
! 174: itimer.it_interval = itimer.it_value = timeout;
! 175: setitimer(ITIMER_REAL, &itimer, (struct itimerval *)0);
! 176: doboth(fd);
! 177: }
! 178: doioonly(fd);
! 179: }
! 180:
! 181:
! 182: /*
! 183: * doboth - handle both I/O and alarms via SIGIO
! 184: */
! 185: int
! 186: doboth(
! 187: int fd
! 188: )
! 189: {
! 190: int n;
! 191: int sawalarm;
! 192: int sawiosig;
! 193: int omask;
! 194: fd_set fds;
! 195: struct timeval tvzero;
! 196:
! 197: sawalarm = 0;
! 198: sawiosig = 0;
! 199: FD_ZERO(&fds);
! 200: for (;;) {
! 201: omask = sigblock(BLOCKSIGMASK);
! 202: if (wasalarmed) { /* alarmed? */
! 203: sawalarm = 1;
! 204: wasalarmed = 0;
! 205: }
! 206: if (iosig) {
! 207: sawiosig = 1;
! 208: iosig = 0;
! 209: }
! 210:
! 211: if (!sawalarm && !sawiosig) {
! 212: /*
! 213: * Nothing to do. Wait for something.
! 214: */
! 215: sigpause(omask);
! 216: if (wasalarmed) { /* alarmed? */
! 217: sawalarm = 1;
! 218: wasalarmed = 0;
! 219: }
! 220: if (iosig) {
! 221: sawiosig = 1;
! 222: iosig = 0;
! 223: }
! 224: }
! 225: (void)sigsetmask(omask);
! 226:
! 227: if (sawiosig) {
! 228:
! 229: do {
! 230: tvzero.tv_sec = tvzero.tv_usec = 0;
! 231: FD_SET(fd, &fds);
! 232: n = select(fd+1, &fds, (fd_set *)0,
! 233: (fd_set *)0, &tvzero);
! 234: if (n > 0)
! 235: doio(fd);
! 236: } while (n > 0);
! 237:
! 238: if (n == -1) {
! 239: (void) fprintf(stderr, "%s: select: ",
! 240: progname);
! 241: perror("");
! 242: exit(1);
! 243: }
! 244: sawiosig = 0;
! 245: }
! 246: if (sawalarm) {
! 247: doalarm(fd);
! 248: sawalarm = 0;
! 249: }
! 250: }
! 251: }
! 252:
! 253:
! 254: /*
! 255: * doioonly - do I/O. This avoids the use of signals
! 256: */
! 257: int
! 258: doioonly(
! 259: int fd
! 260: )
! 261: {
! 262: int n;
! 263: fd_set fds;
! 264:
! 265: FD_ZERO(&fds);
! 266: for (;;) {
! 267: FD_SET(fd, &fds);
! 268: n = select(fd+1, &fds, (fd_set *)0, (fd_set *)0,
! 269: (struct timeval *)0);
! 270: if (n > 0)
! 271: doio(fd);
! 272: }
! 273: }
! 274:
! 275:
! 276: /*
! 277: * doio - read a buffer full of stuff and print it out
! 278: */
! 279: int
! 280: doio(
! 281: int fd
! 282: )
! 283: {
! 284: register char *rp, *rpend;
! 285: register char *cp;
! 286: register int i;
! 287: char raw[512];
! 288: struct timeval tv, tvd;
! 289: int rlen;
! 290: int ind;
! 291: char cooked[2049];
! 292: static char *digits = "0123456789abcdef";
! 293:
! 294: rlen = read(fd, raw, sizeof(raw));
! 295: if (rlen < 0) {
! 296: (void) fprintf(stderr, "%s: read(): ", progname);
! 297: perror("");
! 298: return;
! 299: }
! 300: if (rlen == 0) {
! 301: (void) printf("Zero length read\n");
! 302: return;
! 303: }
! 304:
! 305: cp = cooked;
! 306: rp = raw;
! 307: rpend = &raw[rlen];
! 308: ind = 0;
! 309:
! 310: while (rp < rpend) {
! 311: ind = 1;
! 312: if (isprint(*rp))
! 313: *cp++ = *rp;
! 314: else {
! 315: *cp++ = '<';
! 316: *cp++ = digits[((*rp)>>4) & 0xf];
! 317: *cp++ = digits[*rp & 0xf];
! 318: *cp++ = '>';
! 319: }
! 320: if (
! 321: #ifdef CLKLDISC
! 322: (*rp == (char)magic1 || *rp == (char)magic2)
! 323: #else
! 324: ( strchr( magic, *rp) != NULL )
! 325: #endif
! 326: ) {
! 327: rp++;
! 328: ind = 0;
! 329: *cp = '\0';
! 330: if ((rpend - rp) < sizeof(struct timeval)) {
! 331: (void)printf(
! 332: "Too little data (%d): %s\n",
! 333: rpend-rp, cooked);
! 334: return;
! 335: }
! 336:
! 337: tv.tv_sec = 0;
! 338: for (i = 0; i < 4; i++) {
! 339: tv.tv_sec <<= 8;
! 340: tv.tv_sec |= ((long)*rp++) & 0xff;
! 341: }
! 342: tv.tv_usec = 0;
! 343: for (i = 0; i < 4; i++) {
! 344: tv.tv_usec <<= 8;
! 345: tv.tv_usec |= ((long)*rp++) & 0xff;
! 346: }
! 347:
! 348: tvd.tv_sec = tv.tv_sec - lasttv.tv_sec;
! 349: tvd.tv_usec = tv.tv_usec - lasttv.tv_usec;
! 350: if (tvd.tv_usec < 0) {
! 351: tvd.tv_usec += 1000000;
! 352: tvd.tv_sec--;
! 353: }
! 354:
! 355: (void)printf("%lu.%06lu %lu.%06lu %s\n",
! 356: tv.tv_sec, tv.tv_usec, tvd.tv_sec, tvd.tv_usec,
! 357: cooked);
! 358: lasttv = tv;
! 359: } else {
! 360: rp++;
! 361: }
! 362: }
! 363:
! 364: if (ind) {
! 365: *cp = '\0';
! 366: (void)printf("Incomplete data: %s\n", cooked);
! 367: }
! 368: }
! 369:
! 370:
! 371: /*
! 372: * doalarm - send a string out the port, if we have one.
! 373: */
! 374: int
! 375: doalarm(
! 376: int fd
! 377: )
! 378: {
! 379: int n;
! 380:
! 381: if (! HAVE_OPT(COMMAND))
! 382: return;
! 383:
! 384: n = write(fd, cmd, cmdlen);
! 385:
! 386: if (n < 0) {
! 387: (void) fprintf(stderr, "%s: write(): ", progname);
! 388: perror("");
! 389: } else if (n < cmdlen) {
! 390: (void) printf("Short write (%d bytes, should be %d)\n",
! 391: n, cmdlen);
! 392: }
! 393: }
! 394:
! 395:
! 396: /*
! 397: * alarming - receive alarm interupt
! 398: */
! 399: void
! 400: alarming(void)
! 401: {
! 402: wasalarmed = 1;
! 403: }
! 404:
! 405: /*
! 406: * ioready - handle SIGIO interrupt
! 407: */
! 408: void
! 409: ioready(void)
! 410: {
! 411: iosig = 1;
! 412: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>