Annotation of embedaddon/ntp/clockstuff/clktest.c, revision 1.1.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>