summaryrefslogtreecommitdiffstats
path: root/contrib/ntp/clockstuff/clktest.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/ntp/clockstuff/clktest.c')
-rw-r--r--contrib/ntp/clockstuff/clktest.c529
1 files changed, 529 insertions, 0 deletions
diff --git a/contrib/ntp/clockstuff/clktest.c b/contrib/ntp/clockstuff/clktest.c
new file mode 100644
index 0000000..86edf59d
--- /dev/null
+++ b/contrib/ntp/clockstuff/clktest.c
@@ -0,0 +1,529 @@
+/* clktest.c,v 3.1 1993/07/06 01:05:23 jbj Exp
+ * clktest - test the clock line discipline
+ *
+ * usage: clktest -b bps -f -t timeo -s cmd -c char1 -a char2 /dev/whatever
+ */
+
+#include <stdio.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <signal.h>
+#include <netinet/in.h>
+#include <sys/ioctl.h>
+#include <sys/time.h>
+#include <sys/file.h>
+#include <sgtty.h>
+
+#include "../include/ntp_fp.h"
+#include "../include/ntp.h"
+#include "../include/ntp_unixtime.h"
+
+#define STREQ(a, b) (*(a) == *(b) && strcmp((a), (b)) == 0)
+
+#if defined(ULT_2_0_SUCKS)
+#ifndef sigmask
+#define sigmask(m) (1<<(m))
+#endif
+#endif
+
+#ifndef STREAM
+#ifndef CLKLDISC
+CLOCK_LINE_DISCIPLINE_NEEDED_BY_THIS_PROGRAM;
+#endif
+#endif
+
+/*
+ * Mask for blocking SIGIO and SIGALRM
+ */
+#define BLOCKSIGMASK (sigmask(SIGIO)|sigmask(SIGALRM))
+
+/*
+ * speed table
+ */
+struct speeds {
+ int bps;
+ int rate;
+} speedtab[] = {
+ { 300, B300 },
+ { 1200, B1200 },
+ { 2400, B2400 },
+ { 4800, B4800 },
+ { 9600, B9600 },
+ { 19200, EXTA },
+ { 38400, EXTB },
+ { 0, 0 }
+};
+
+char *progname;
+int debug;
+
+#ifdef CLKLDISC
+#define DEFMAGIC '\r'
+#endif
+
+#ifdef CLKLDISC
+# ifdef STREAM
+# include <stropts.h>
+# ifdef HAVE_SYS_CLKDEFS_H
+# include <sys/clkdefs.h>
+# endif
+# define DEFMAGIC "\r"
+# endif
+#endif
+
+struct timeval timeout = { 0 };
+char *cmd = NULL;
+int cmdlen;
+int docmd = 0;
+#ifdef CLKLDISC
+u_long magic1 = DEFMAGIC;
+u_long magic2 = DEFMAGIC;
+#endif
+#ifdef STREAM
+char magic[32];
+#endif
+int speed = B9600;
+int ttflags = RAW|EVENP|ODDP;
+
+volatile int wasalarmed;
+volatile int iosig;
+
+struct timeval lasttv;
+
+extern u_long ustotslo[];
+extern u_long ustotsmid[];
+extern u_long ustotshi[];
+
+/*
+ * main - parse arguments and handle options
+ */
+int
+main(
+ int argc,
+ char *argv[]
+ )
+{
+ int c;
+ int errflg = 0;
+ struct speeds *spd;
+ u_long tmp;
+ int fd;
+ struct sgttyb ttyb;
+ struct itimerval itimer;
+ extern int ntp_optind;
+ extern char *ntp_optarg;
+ int alarming();
+ int ioready();
+
+ progname = argv[0];
+#ifdef STREAM
+ magic[0] = 0;
+#endif
+ while ((c = ntp_getopt(argc, argv, "a:b:c:dfs:t:")) != EOF)
+ switch (c) {
+#ifdef CLKLDISC
+ case 'a':
+#endif
+ case 'c':
+ if (!atouint(ntp_optarg, &tmp)) {
+ (void) fprintf(stderr,
+ "%s: argument for -%c must be integer\n",
+ progname, c);
+ errflg++;
+ break;
+ }
+#ifdef CLKLDISC
+ if (c == 'c')
+ magic1 = tmp;
+ else
+ magic2 = tmp;
+#endif
+#ifdef STREAM
+ magic[strlen(magic)+1] = '\0';
+ magic[strlen(magic)] = tmp;
+#endif
+ break;
+ case 'b':
+ if (!atouint(ntp_optarg, &tmp)) {
+ errflg++;
+ break;
+ }
+ spd = speedtab;
+ while (spd->bps != 0)
+ if ((int)tmp == spd->bps)
+ break;
+ if (spd->bps == 0) {
+ (void) fprintf(stderr,
+ "%s: speed %lu is unsupported\n",
+ progname, tmp);
+ errflg++;
+ } else {
+ speed = spd->rate;
+ }
+ break;
+ case 'd':
+ ++debug;
+ break;
+ case 'f':
+ ttflags |= CRMOD;
+ break;
+ case 's':
+ cmdlen = strlen(ntp_optarg);
+ if (cmdlen == 0)
+ errflg++;
+ else
+ cmd = ntp_optarg;
+ break;
+ case 't':
+ if (!atouint(ntp_optarg, &tmp))
+ errflg++;
+ else {
+ timeout.tv_sec = (long)tmp;
+ docmd = 1;
+ }
+ break;
+ default:
+ errflg++;
+ break;
+ }
+ if (errflg || ntp_optind+1 != argc) {
+ (void) fprintf(stderr,
+#ifdef CLKLDISC
+ "usage: %s [-b bps] [-c magic1] [-a magic2] [-f] [-s cmd] [-t timeo] tty_device\n",
+#endif
+#ifdef STREAM
+ "usage: %s [-b bps] [-c magic1] [-c magic2]... [-f] [-s cmd] [-t timeo] tty_device\n",
+#endif
+ progname);
+ exit(2);
+ }
+
+#ifdef STREAM
+ if (!strlen(magic))
+ strcpy(magic,DEFMAGIC);
+#endif
+
+ if (docmd)
+ fd = open(argv[ntp_optind], O_RDWR, 0777);
+ else
+ fd = open(argv[ntp_optind], O_RDONLY, 0777);
+ if (fd == -1) {
+ (void) fprintf(stderr, "%s: open(%s): ", progname,
+ argv[ntp_optind]);
+ perror("");
+ exit(1);
+ }
+
+ if (ioctl(fd, TIOCEXCL, (char *)0) < 0) {
+ (void) fprintf(stderr, "%s: ioctl(TIOCEXCL): ", progname);
+ perror("");
+ exit(1);
+ }
+
+ /*
+ * If we have the clock discipline, set the port to raw. Otherwise
+ * we run cooked.
+ */
+ ttyb.sg_ispeed = ttyb.sg_ospeed = speed;
+#ifdef CLKLDISC
+ ttyb.sg_erase = (char)magic1;
+ ttyb.sg_kill = (char)magic2;
+#endif
+ ttyb.sg_flags = (short)ttflags;
+ if (ioctl(fd, TIOCSETP, (char *)&ttyb) < 0) {
+ (void) fprintf(stderr, "%s: ioctl(TIOCSETP): ", progname);
+ perror("");
+ exit(1);
+ }
+
+ if (fcntl(fd, F_SETOWN, getpid()) == -1) {
+ (void) fprintf(stderr, "%s: fcntl(F_SETOWN): ", progname);
+ perror("");
+ exit(1);
+ }
+
+#ifdef CLKLDISC
+ {
+ int ldisc;
+ ldisc = CLKLDISC;
+ if (ioctl(fd, TIOCSETD, (char *)&ldisc) < 0) {
+ (void) fprintf(stderr, "%s: ioctl(TIOCSETD): ", progname);
+ perror("");
+ exit(1);
+ }
+ }
+#endif
+#ifdef STREAM
+ if (ioctl(fd, I_POP, 0) >=0 ) ;
+ if (ioctl(fd, I_PUSH, "clk") < 0) {
+ (void) fprintf(stderr, "%s: ioctl(I_PUSH): ", progname);
+ perror("");
+ exit(1);
+ }
+ if (ioctl(fd, CLK_SETSTR, magic) < 0) {
+ (void) fprintf(stderr, "%s: ioctl(CLK_SETSTR): ", progname);
+ perror("");
+ exit(1);
+ }
+#endif
+
+
+ (void) gettimeofday(&lasttv, (struct timezone *)0);
+ if (docmd) {
+ /*
+ * set non-blocking, async I/O on the descriptor
+ */
+ iosig = 0;
+ (void) signal(SIGIO, ioready);
+ if (fcntl(fd, F_SETFL, FNDELAY|FASYNC) < 0) {
+ (void) fprintf(stderr, "%s: fcntl(F_SETFL): ",
+ progname);
+ perror("");
+ exit(1);
+ }
+
+ /*
+ * Set up the alarm interrupt.
+ */
+ wasalarmed = 0;
+ (void) signal(SIGALRM, alarming);
+ itimer.it_interval = itimer.it_value = timeout;
+ setitimer(ITIMER_REAL, &itimer, (struct itimerval *)0);
+ doboth(fd);
+ }
+ doioonly(fd);
+}
+
+
+/*
+ * doboth - handle both I/O and alarms via SIGIO
+ */
+int
+doboth(
+ int fd
+ )
+{
+ int n;
+ int sawalarm;
+ int sawiosig;
+ int omask;
+ fd_set fds;
+ struct timeval tvzero;
+
+ sawalarm = 0;
+ sawiosig = 0;
+ FD_ZERO(&fds);
+ for (;;) {
+ omask = sigblock(BLOCKSIGMASK);
+ if (wasalarmed) { /* alarmed? */
+ sawalarm = 1;
+ wasalarmed = 0;
+ }
+ if (iosig) {
+ sawiosig = 1;
+ iosig = 0;
+ }
+
+ if (!sawalarm && !sawiosig) {
+ /*
+ * Nothing to do. Wait for something.
+ */
+ sigpause(omask);
+ if (wasalarmed) { /* alarmed? */
+ sawalarm = 1;
+ wasalarmed = 0;
+ }
+ if (iosig) {
+ sawiosig = 1;
+ iosig = 0;
+ }
+ }
+ (void)sigsetmask(omask);
+
+ if (sawiosig) {
+
+ do {
+ tvzero.tv_sec = tvzero.tv_usec = 0;
+ FD_SET(fd, &fds);
+ n = select(fd+1, &fds, (fd_set *)0,
+ (fd_set *)0, &tvzero);
+ if (n > 0)
+ doio(fd);
+ } while (n > 0);
+
+ if (n == -1) {
+ (void) fprintf(stderr, "%s: select: ",
+ progname);
+ perror("");
+ exit(1);
+ }
+ sawiosig = 0;
+ }
+ if (sawalarm) {
+ doalarm(fd);
+ sawalarm = 0;
+ }
+ }
+}
+
+
+/*
+ * doioonly - do I/O. This avoids the use of signals
+ */
+int
+doioonly(
+ int fd
+ )
+{
+ int n;
+ fd_set fds;
+
+ FD_ZERO(&fds);
+ for (;;) {
+ FD_SET(fd, &fds);
+ n = select(fd+1, &fds, (fd_set *)0, (fd_set *)0,
+ (struct timeval *)0);
+ if (n > 0)
+ doio(fd);
+ }
+}
+
+
+/*
+ * doio - read a buffer full of stuff and print it out
+ */
+int
+doio(
+ int fd
+ )
+{
+ register char *rp, *rpend;
+ register char *cp;
+ register int i;
+ char raw[512];
+ struct timeval tv, tvd;
+ int rlen;
+ int ind;
+ char cooked[2049];
+ static char *digits = "0123456789abcdef";
+
+ rlen = read(fd, raw, sizeof(raw));
+ if (rlen < 0) {
+ (void) fprintf(stderr, "%s: read(): ", progname);
+ perror("");
+ return;
+ }
+ if (rlen == 0) {
+ (void) printf("Zero length read\n");
+ return;
+ }
+
+ cp = cooked;
+ rp = raw;
+ rpend = &raw[rlen];
+ ind = 0;
+
+ while (rp < rpend) {
+ ind = 1;
+ if (isprint(*rp))
+ *cp++ = *rp;
+ else {
+ *cp++ = '<';
+ *cp++ = digits[((*rp)>>4) & 0xf];
+ *cp++ = digits[*rp & 0xf];
+ *cp++ = '>';
+ }
+ if (
+#ifdef CLKLDISC
+ (*rp == (char)magic1 || *rp == (char)magic2)
+#else
+ ( strchr( magic, *rp) != NULL )
+#endif
+ ) {
+ rp++;
+ ind = 0;
+ *cp = '\0';
+ if ((rpend - rp) < sizeof(struct timeval)) {
+ (void)printf(
+ "Too little data (%d): %s\n",
+ rpend-rp, cooked);
+ return;
+ }
+
+ tv.tv_sec = 0;
+ for (i = 0; i < 4; i++) {
+ tv.tv_sec <<= 8;
+ tv.tv_sec |= ((long)*rp++) & 0xff;
+ }
+ tv.tv_usec = 0;
+ for (i = 0; i < 4; i++) {
+ tv.tv_usec <<= 8;
+ tv.tv_usec |= ((long)*rp++) & 0xff;
+ }
+
+ tvd.tv_sec = tv.tv_sec - lasttv.tv_sec;
+ tvd.tv_usec = tv.tv_usec - lasttv.tv_usec;
+ if (tvd.tv_usec < 0) {
+ tvd.tv_usec += 1000000;
+ tvd.tv_sec--;
+ }
+
+ (void)printf("%lu.%06lu %lu.%06lu %s\n",
+ tv.tv_sec, tv.tv_usec, tvd.tv_sec, tvd.tv_usec,
+ cooked);
+ lasttv = tv;
+ } else {
+ rp++;
+ }
+ }
+
+ if (ind) {
+ *cp = '\0';
+ (void)printf("Incomplete data: %s\n", cooked);
+ }
+}
+
+
+/*
+ * doalarm - send a string out the port, if we have one.
+ */
+int
+doalarm(
+ int fd
+ )
+{
+ int n;
+
+ if (cmd == NULL || cmdlen <= 0)
+ return;
+
+ n = write(fd, cmd, cmdlen);
+
+ if (n < 0) {
+ (void) fprintf(stderr, "%s: write(): ", progname);
+ perror("");
+ } else if (n < cmdlen) {
+ (void) printf("Short write (%d bytes, should be %d)\n",
+ n, cmdlen);
+ }
+}
+
+
+/*
+ * alarming - receive alarm interupt
+ */
+void
+alarming(void)
+{
+ wasalarmed = 1;
+}
+
+/*
+ * ioready - handle SIGIO interrupt
+ */
+void
+ioready(void)
+{
+ iosig = 1;
+}
OpenPOWER on IntegriCloud