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>