1 /* clktest.c,v 3.1 1993/07/06 01:05:23 jbj Exp
2 * clktest - test the clock line discipline
4 * usage: clktest -b bps -f -t timeo -s cmd -c char1 -a char2 /dev/whatever
10 #include <sys/socket.h>
12 #include <netinet/in.h>
13 #include <sys/ioctl.h>
18 #include "../include/ntp_fp.h"
19 #include "../include/ntp.h"
20 #include "../include/ntp_unixtime.h"
22 #define STREQ(a, b) (*(a) == *(b) && strcmp((a), (b)) == 0)
24 #if defined(ULT_2_0_SUCKS)
26 #define sigmask(m) (1<<(m))
32 CLOCK_LINE_DISCIPLINE_NEEDED_BY_THIS_PROGRAM;
37 * Mask for blocking SIGIO and SIGALRM
39 #define BLOCKSIGMASK (sigmask(SIGIO)|sigmask(SIGALRM))
68 # ifdef HAVE_SYS_CLKDEFS_H
69 # include <sys/clkdefs.h>
71 # define DEFMAGIC "\r"
75 struct timeval timeout = { 0 };
80 u_long magic1 = DEFMAGIC;
81 u_long magic2 = DEFMAGIC;
87 int ttflags = RAW|EVENP|ODDP;
89 volatile int wasalarmed;
92 struct timeval lasttv;
94 extern u_long ustotslo[];
95 extern u_long ustotsmid[];
96 extern u_long ustotshi[];
99 * main - parse arguments and handle options
113 struct itimerval itimer;
114 extern int ntp_optind;
115 extern char *ntp_optarg;
123 while ((c = ntp_getopt(argc, argv, "a:b:c:dfs:t:")) != EOF)
129 if (!atouint(ntp_optarg, &tmp)) {
130 (void) fprintf(stderr,
131 "%s: argument for -%c must be integer\n",
143 magic[strlen(magic)+1] = '\0';
144 magic[strlen(magic)] = tmp;
148 if (!atouint(ntp_optarg, &tmp)) {
153 while (spd->bps != 0)
154 if ((int)tmp == spd->bps)
157 (void) fprintf(stderr,
158 "%s: speed %lu is unsupported\n",
172 cmdlen = strlen(ntp_optarg);
179 if (!atouint(ntp_optarg, &tmp))
182 timeout.tv_sec = (long)tmp;
190 if (errflg || ntp_optind+1 != argc) {
191 (void) fprintf(stderr,
193 "usage: %s [-b bps] [-c magic1] [-a magic2] [-f] [-s cmd] [-t timeo] tty_device\n",
196 "usage: %s [-b bps] [-c magic1] [-c magic2]... [-f] [-s cmd] [-t timeo] tty_device\n",
204 strcpy(magic,DEFMAGIC);
208 fd = open(argv[ntp_optind], O_RDWR, 0777);
210 fd = open(argv[ntp_optind], O_RDONLY, 0777);
212 (void) fprintf(stderr, "%s: open(%s): ", progname,
218 if (ioctl(fd, TIOCEXCL, (char *)0) < 0) {
219 (void) fprintf(stderr, "%s: ioctl(TIOCEXCL): ", progname);
225 * If we have the clock discipline, set the port to raw. Otherwise
228 ttyb.sg_ispeed = ttyb.sg_ospeed = speed;
230 ttyb.sg_erase = (char)magic1;
231 ttyb.sg_kill = (char)magic2;
233 ttyb.sg_flags = (short)ttflags;
234 if (ioctl(fd, TIOCSETP, (char *)&ttyb) < 0) {
235 (void) fprintf(stderr, "%s: ioctl(TIOCSETP): ", progname);
240 if (fcntl(fd, F_SETOWN, getpid()) == -1) {
241 (void) fprintf(stderr, "%s: fcntl(F_SETOWN): ", progname);
250 if (ioctl(fd, TIOCSETD, (char *)&ldisc) < 0) {
251 (void) fprintf(stderr, "%s: ioctl(TIOCSETD): ", progname);
258 if (ioctl(fd, I_POP, 0) >=0 ) ;
259 if (ioctl(fd, I_PUSH, "clk") < 0) {
260 (void) fprintf(stderr, "%s: ioctl(I_PUSH): ", progname);
264 if (ioctl(fd, CLK_SETSTR, magic) < 0) {
265 (void) fprintf(stderr, "%s: ioctl(CLK_SETSTR): ", progname);
272 (void) gettimeofday(&lasttv, (struct timezone *)0);
275 * set non-blocking, async I/O on the descriptor
278 (void) signal(SIGIO, ioready);
279 if (fcntl(fd, F_SETFL, FNDELAY|FASYNC) < 0) {
280 (void) fprintf(stderr, "%s: fcntl(F_SETFL): ",
287 * Set up the alarm interrupt.
290 (void) signal(SIGALRM, alarming);
291 itimer.it_interval = itimer.it_value = timeout;
292 setitimer(ITIMER_REAL, &itimer, (struct itimerval *)0);
300 * doboth - handle both I/O and alarms via SIGIO
312 struct timeval tvzero;
318 omask = sigblock(BLOCKSIGMASK);
319 if (wasalarmed) { /* alarmed? */
328 if (!sawalarm && !sawiosig) {
330 * Nothing to do. Wait for something.
333 if (wasalarmed) { /* alarmed? */
342 (void)sigsetmask(omask);
347 tvzero.tv_sec = tvzero.tv_usec = 0;
349 n = select(fd+1, &fds, (fd_set *)0,
350 (fd_set *)0, &tvzero);
356 (void) fprintf(stderr, "%s: select: ",
372 * doioonly - do I/O. This avoids the use of signals
385 n = select(fd+1, &fds, (fd_set *)0, (fd_set *)0,
386 (struct timeval *)0);
394 * doio - read a buffer full of stuff and print it out
401 register char *rp, *rpend;
405 struct timeval tv, tvd;
409 static char *digits = "0123456789abcdef";
411 rlen = read(fd, raw, sizeof(raw));
413 (void) fprintf(stderr, "%s: read(): ", progname);
418 (void) printf("Zero length read\n");
433 *cp++ = digits[((*rp)>>4) & 0xf];
434 *cp++ = digits[*rp & 0xf];
439 (*rp == (char)magic1 || *rp == (char)magic2)
441 ( strchr( magic, *rp) != NULL )
447 if ((rpend - rp) < sizeof(struct timeval)) {
449 "Too little data (%d): %s\n",
455 for (i = 0; i < 4; i++) {
457 tv.tv_sec |= ((long)*rp++) & 0xff;
460 for (i = 0; i < 4; i++) {
462 tv.tv_usec |= ((long)*rp++) & 0xff;
465 tvd.tv_sec = tv.tv_sec - lasttv.tv_sec;
466 tvd.tv_usec = tv.tv_usec - lasttv.tv_usec;
467 if (tvd.tv_usec < 0) {
468 tvd.tv_usec += 1000000;
472 (void)printf("%lu.%06lu %lu.%06lu %s\n",
473 tv.tv_sec, tv.tv_usec, tvd.tv_sec, tvd.tv_usec,
483 (void)printf("Incomplete data: %s\n", cooked);
489 * doalarm - send a string out the port, if we have one.
498 if (cmd == NULL || cmdlen <= 0)
501 n = write(fd, cmd, cmdlen);
504 (void) fprintf(stderr, "%s: write(): ", progname);
506 } else if (n < cmdlen) {
507 (void) printf("Short write (%d bytes, should be %d)\n",
514 * alarming - receive alarm interupt
523 * ioready - handle SIGIO interrupt