386BSD 0.1 development
authorWilliam F. Jolitz <wjolitz@soda.berkeley.edu>
Sat, 20 Apr 1991 23:00:27 +0000 (15:00 -0800)
committerWilliam F. Jolitz <wjolitz@soda.berkeley.edu>
Sat, 20 Apr 1991 23:00:27 +0000 (15:00 -0800)
Work on file usr/src/usr.sbin/timed/timedc/cmds.c
Work on file usr/src/usr.sbin/timed/timedc/timedc.8
Work on file usr/src/usr.sbin/timed/timedc/cmdtab.c
Work on file usr/src/usr.sbin/timed/timedc/timedc.h
Work on file usr/src/usr.sbin/timed/timedc/timedc.c

Co-Authored-By: Lynne Greer Jolitz <ljolitz@cardio.ucsf.edu>
Synthesized-from: 386BSD-0.1

usr/src/usr.sbin/timed/timedc/cmds.c [new file with mode: 0644]
usr/src/usr.sbin/timed/timedc/cmdtab.c [new file with mode: 0644]
usr/src/usr.sbin/timed/timedc/timedc.8 [new file with mode: 0644]
usr/src/usr.sbin/timed/timedc/timedc.c [new file with mode: 0644]
usr/src/usr.sbin/timed/timedc/timedc.h [new file with mode: 0644]

diff --git a/usr/src/usr.sbin/timed/timedc/cmds.c b/usr/src/usr.sbin/timed/timedc/cmds.c
new file mode 100644 (file)
index 0000000..cfb325b
--- /dev/null
@@ -0,0 +1,396 @@
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)cmds.c     2.8 (Berkeley) 3/2/91";
+#endif /* not lint */
+
+#include "timedc.h"
+#include <netinet/in_systm.h>
+#include <netinet/ip.h>
+#include <netinet/ip_icmp.h>
+#define TSPTYPES
+#include <protocols/timed.h>
+#include <sys/file.h>
+
+int id;
+int sock;
+int sock_raw;
+char hostname[MAXHOSTNAMELEN];
+struct hostent *hp, *gethostbyname();
+struct sockaddr_in server;
+extern int measure_delta;
+int bytenetorder(), bytehostorder();
+char *strcpy();
+
+/*
+ * Clockdiff computes the difference between the time of the machine on 
+ * which it is called and the time of the machines given as argument.
+ * The time differences measured by clockdiff are obtained using a sequence
+ * of ICMP TSTAMP messages which are returned to the sender by the IP module
+ * in the remote machine.
+ * In order to compare clocks of machines in different time zones, the time 
+ * is transmitted (as a 32-bit value) in milliseconds since midnight UT. 
+ * If a hosts uses a different time format, it should set the high order
+ * bit of the 32-bit quantity it transmits.
+ * However, VMS apparently transmits the time in milliseconds since midnight
+ * local time (rather than GMT) without setting the high order bit. 
+ * Furthermore, it does not understand daylight-saving time.  This makes 
+ * clockdiff behaving inconsistently with hosts running VMS.
+ *
+ * In order to reduce the sensitivity to the variance of message transmission 
+ * time, clockdiff sends a sequence of messages.  Yet, measures between 
+ * two `distant' hosts can be affected by a small error. The error can, however,
+ * be reduced by increasing the number of messages sent in each measurement.
+ */
+
+clockdiff(argc, argv)
+int argc;
+char *argv[];
+{
+       int measure_status;
+       struct timeval ack;
+       int measure();
+
+       if(argc < 2)  {
+               printf("Usage: clockdiff host ... \n");
+               return;
+       }
+
+       id = getpid();
+       (void)gethostname(hostname,sizeof(hostname));
+
+       while (argc > 1) {
+               argc--; argv++;
+               hp = gethostbyname(*argv);
+               if (hp == NULL) {
+                       fprintf(stderr, "timed: %s: ", *argv);
+                       herror((char *)NULL);
+                       continue;
+               }
+               server.sin_family = hp->h_addrtype;
+               bcopy(hp->h_addr, &(server.sin_addr.s_addr), hp->h_length); 
+               ack.tv_sec = 10;
+               ack.tv_usec = 0;
+               if ((measure_status = measure(&ack, &server)) < 0) {
+                       perror("measure");
+                       return;
+               }
+               switch (measure_status) {
+
+               case HOSTDOWN:
+                       printf("%s is down\n", hp->h_name);
+                       continue;
+                       break;
+               case NONSTDTIME:
+                       printf("%s time transmitted in a non-standard format\n",                                                 hp->h_name);
+                       continue;
+                       break;
+               case UNREACHABLE:
+                       printf("%s is unreachable\n", hp->h_name);
+                       continue;
+                       break;
+               default:
+                       break;
+               }
+
+               if (measure_delta > 0)
+                       printf("time on %s is %d ms. ahead of time on %s\n", 
+                                               hp->h_name, measure_delta,
+                                               hostname);
+               else
+                       if (measure_delta == 0)
+                               printf("%s and %s have the same time\n", 
+                                               hp->h_name, hostname);
+                       else
+                            printf("time on %s is %d ms. behind time on %s\n",
+                                       hp->h_name, -measure_delta, hostname);
+       }
+       return;
+}
+/*
+ * finds location of master timedaemon
+ */
+
+msite(argc)
+int argc;
+{
+       int length;
+       int cc;
+       fd_set ready;
+       struct sockaddr_in dest;
+       struct timeval tout;
+       struct sockaddr_in from;
+       struct tsp msg;
+       struct servent *srvp;
+
+       if (argc != 1) {
+               printf("Usage: msite\n");
+               return;
+       }
+
+       srvp = getservbyname("timed", "udp");
+       if (srvp == 0) {
+               fprintf(stderr, "udp/timed: unknown service\n");
+               return;
+       }
+       dest.sin_port = srvp->s_port;
+       dest.sin_family = AF_INET;
+
+       (void)gethostname(hostname, sizeof(hostname));
+       hp = gethostbyname(hostname);
+       if (hp == NULL) {
+               fprintf(stderr, "timed: %s: ", hostname);
+               herror((char *)NULL);
+               return;
+       }
+       bcopy(hp->h_addr, &dest.sin_addr.s_addr, hp->h_length);
+
+       (void)strcpy(msg.tsp_name, hostname);
+       msg.tsp_type = TSP_MSITE;
+       msg.tsp_vers = TSPVERSION;
+       bytenetorder(&msg);
+       length = sizeof(struct sockaddr_in);
+       if (sendto(sock, (char *)&msg, sizeof(struct tsp), 0, 
+           (struct sockaddr *)&dest, length) < 0) {
+               perror("sendto");
+               return;
+       }
+
+       tout.tv_sec = 15;
+       tout.tv_usec = 0;
+       FD_ZERO(&ready);
+       FD_SET(sock, &ready);
+       if (select(FD_SETSIZE, &ready, (fd_set *)0, (fd_set *)0, &tout)) {
+               length = sizeof(struct sockaddr_in);
+               cc = recvfrom(sock, (char *)&msg, sizeof(struct tsp), 0, 
+                   (struct sockaddr *)&from, &length);
+               if (cc < 0) {
+                       perror("recvfrom");
+                       return;
+               }
+               bytehostorder(&msg);
+               if (msg.tsp_type == TSP_ACK)
+                       printf("master timedaemon runs on %s\n", msg.tsp_name);
+               else
+                       printf("received wrong ack: %s\n", 
+                                               tsptype[msg.tsp_type]);
+       } else
+               printf("communication error\n");
+}
+
+/*
+ * quits timedc
+ */
+
+quit()
+{
+       exit(0);
+}
+
+#define MAXH   4       /* max no. of hosts where election can occur */
+
+/*
+ * Causes the election timer to expire on the selected hosts
+ * It sends just one udp message per machine, relying on
+ * reliability of communication channel.
+ */
+
+testing(argc, argv)
+int argc;
+char *argv[];
+{
+       int length;
+       int nhosts;
+       struct servent *srvp;
+       struct sockaddr_in sin[MAXH];
+       struct tsp msg;
+
+       if(argc < 2)  {
+               printf("Usage: testing host ...\n");
+               return;
+       }
+
+       srvp = getservbyname("timed", "udp");
+       if (srvp == 0) {
+               fprintf(stderr, "udp/timed: unknown service\n");
+               return;
+       }       
+
+       nhosts = 0;
+       while (argc > 1) {
+               argc--; argv++;
+               hp = gethostbyname(*argv);
+               if (hp == NULL) {
+                       fprintf(stderr, "timed: %s: ", *argv);
+                       herror((char *)NULL);
+                       argc--; argv++;
+                       continue;
+               }
+               sin[nhosts].sin_port = srvp->s_port;
+               sin[nhosts].sin_family = hp->h_addrtype;
+               bcopy(hp->h_addr, &(sin[nhosts].sin_addr.s_addr), hp->h_length);
+               if (++nhosts == MAXH)
+                       break;
+       }
+
+       msg.tsp_type = TSP_TEST;
+       msg.tsp_vers = TSPVERSION;
+       (void)gethostname(hostname, sizeof(hostname));
+       (void)strcpy(msg.tsp_name, hostname);
+       bytenetorder(&msg);     /* it is not really necessary here */
+       while (nhosts-- > 0) {
+               length = sizeof(struct sockaddr_in);
+               if (sendto(sock, (char *)&msg, sizeof(struct tsp), 0, 
+                   (struct sockaddr *)&sin[nhosts], length) < 0) {
+                       perror("sendto");
+                       return;
+               }
+       }
+}
+
+/*
+ * Enables or disables tracing on local timedaemon
+ */
+
+tracing(argc, argv)
+int argc;
+char *argv[];
+{
+       int onflag;
+       int length;
+       int cc;
+       fd_set ready;
+       struct sockaddr_in dest;
+       struct timeval tout;
+       struct sockaddr_in from;
+       struct tsp msg;
+       struct servent *srvp;
+
+       if (argc != 2) {
+               printf("Usage: tracing { on | off }\n");
+               return;
+       }
+
+       srvp = getservbyname("timed", "udp");
+       if (srvp == 0) {
+               fprintf(stderr, "udp/timed: unknown service\n");
+               return;
+       }       
+       dest.sin_port = srvp->s_port;
+       dest.sin_family = AF_INET;
+
+       (void)gethostname(hostname,sizeof(hostname));
+       hp = gethostbyname(hostname);
+       bcopy(hp->h_addr, &dest.sin_addr.s_addr, hp->h_length);
+
+       if (strcmp(argv[1], "on") == 0) {
+               msg.tsp_type = TSP_TRACEON;
+               onflag = ON;
+       } else {
+               msg.tsp_type = TSP_TRACEOFF;
+               onflag = OFF;
+       }
+
+       (void)strcpy(msg.tsp_name, hostname);
+       msg.tsp_vers = TSPVERSION;
+       bytenetorder(&msg);
+       length = sizeof(struct sockaddr_in);
+       if (sendto(sock, (char *)&msg, sizeof(struct tsp), 0, 
+           (struct sockaddr *)&dest, length) < 0) {
+               perror("sendto");
+               return;
+       }
+
+       tout.tv_sec = 5;
+       tout.tv_usec = 0;
+       FD_ZERO(&ready);
+       FD_SET(sock, &ready);
+       if (select(FD_SETSIZE, &ready, (fd_set *)0, (fd_set *)0, &tout)) {
+               length = sizeof(struct sockaddr_in);
+               cc = recvfrom(sock, (char *)&msg, sizeof(struct tsp), 0, 
+                   (struct sockaddr *)&from, &length);
+               if (cc < 0) {
+                       perror("recvfrom");
+                       return;
+               }
+               bytehostorder(&msg);
+               if (msg.tsp_type == TSP_ACK)
+                       if (onflag)
+                               printf("timed tracing enabled\n");
+                       else
+                               printf("timed tracing disabled\n");
+               else
+                       printf("wrong ack received: %s\n", 
+                                               tsptype[msg.tsp_type]);
+       } else
+               printf("communication error\n");
+}
+
+priv_resources()
+{
+       int port;
+       struct sockaddr_in sin;
+
+       sock = socket(AF_INET, SOCK_DGRAM, 0);
+       if (sock < 0) {
+               perror("opening socket");
+               return(-1);
+       }
+
+       sin.sin_family = AF_INET;
+       sin.sin_addr.s_addr = 0;
+       for (port = IPPORT_RESERVED - 1; port > IPPORT_RESERVED / 2; port--) {
+               sin.sin_port = htons((u_short)port);
+               if (bind(sock, (struct sockaddr *)&sin, sizeof (sin)) >= 0)
+                       break;
+               if (errno != EADDRINUSE && errno != EADDRNOTAVAIL) {
+                       perror("bind");
+                       (void) close(sock);
+                       return(-1);
+               }
+       }
+       if (port == IPPORT_RESERVED / 2) {
+               fprintf(stderr, "all reserved ports in use\n");
+               (void) close(sock);
+               return(-1);
+       }
+
+       sock_raw = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP); 
+       if (sock_raw < 0)  {
+               perror("opening raw socket");
+               (void) close(sock_raw);
+               return(-1);
+       }
+       return(1);
+}
diff --git a/usr/src/usr.sbin/timed/timedc/cmdtab.c b/usr/src/usr.sbin/timed/timedc/cmdtab.c
new file mode 100644 (file)
index 0000000..5516fba
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)cmdtab.c   2.6 (Berkeley) 6/1/90";
+#endif /* not lint */
+
+#include "timedc.h"
+
+int    clockdiff(), help(), msite(), quit(), testing(), tracing();
+
+char   clockdiffhelp[] =       "measures clock differences between machines";
+char   helphelp[] =            "gets help on commands";
+char   msitehelp[] =           "finds location of master";
+char   quithelp[] =            "exits timedc";
+char   testinghelp[] =         "causes election timers to expire";
+char   tracinghelp[] =         "turns tracing on or off";
+
+struct cmd cmdtab[] = {
+       { "clockdiff",  clockdiffhelp,  clockdiff,      0 },
+       { "election",   testinghelp,    testing,        1 },
+       { "help",       helphelp,       help,           0 },
+       { "msite",      msitehelp,      msite,          0 },
+       { "quit",       quithelp,       quit,           0 },
+       { "trace",      tracinghelp,    tracing,        1 },
+       { "?",          helphelp,       help,           0 },
+};
+
+int    NCMDS = sizeof (cmdtab) / sizeof (cmdtab[0]);
diff --git a/usr/src/usr.sbin/timed/timedc/timedc.8 b/usr/src/usr.sbin/timed/timedc/timedc.8
new file mode 100644 (file)
index 0000000..f3112df
--- /dev/null
@@ -0,0 +1,136 @@
+.\" Copyright (c) 1980, 1991 Regents of the University of California.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\"    must display the following acknowledgement:
+.\"    This product includes software developed by the University of
+.\"    California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\"    may be used to endorse or promote products derived from this software
+.\"    without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\"     @(#)timedc.8   6.6 (Berkeley) 3/16/91
+.\"
+.Dd March 16, 1991
+.Dt TIMEDC 8
+.Os BSD 4.3
+.ad
+.Sh NAME
+.Nm timedc
+.Nd timed control program
+.Sh SYNOPSIS
+.Nm timedc
+.Oo Ar command\ \&
+.Op Ar argument ...
+.Oc
+.Sh DESCRIPTION
+.Nm Timedc
+is used to control the operation of the
+.Xr timed 8
+program.
+It may be used to:
+.Bl -bullet
+.It
+Measure the differences between machines' clocks,
+.It 
+Find the location where the master time server is running,
+.It
+Enable or disable tracing of messages received by
+.Xr timed ,
+and
+.It
+Perform various debugging actions.
+.El
+.Pp
+Without any arguments,
+.Nm timedc
+will prompt for commands from the standard input.
+If arguments are supplied,
+.Nm timedc
+interprets the first argument as a command and the remaining
+arguments as parameters to the command.  The standard input
+may be redirected causing
+.Nm timedc
+to read commands from a file.
+Commands may be abbreviated;
+recognized commands are:
+.Pp
+.Bl -tag -width Ds -compact
+.It Ic \&? Op Ar command ...
+.It Ic help Op Ar command ...
+Print a short description of each command specified in the argument list,
+or, if no arguments are given, a list of the recognized commands.
+.Pp
+.It Ic clockdiff Ar host ...
+Compute the differences between the clock of the host machine
+and the clocks of the machines given as arguments.
+.Pp
+.It Xo
+.Ic trace
+.Li \&{ Ar on Li \&|
+.Ar off \&}
+.Xc
+Enable or disable the tracing of incoming messages to
+.Xr timed
+in the file
+.Pa /var/log/timed.log.
+.Pp
+.It Ic quit
+Exit from timedc.
+.El
+.Pp
+Other commands may be included for use in testing and debugging
+.Xr timed ;
+the help command and
+the program source may be consulted for details.
+.Sh FILES
+.Bl -tag -width /var/log/timed.masterlog -compact
+.It Pa /var/log/timed.log
+tracing file for timed
+.It Pa /var/log/timed.masterlog
+log file for master timed
+.El
+.Sh SEE ALSO
+.Xr date 1 ,
+.Xr adjtime 2 ,
+.Xr icmp 4 ,
+.Xr timed 8 ,
+.Rs
+.%T "TSP: The Time Synchronization Protocol for UNIX 4.3BSD"
+.%A R. Gusella
+.%A S. Zatti
+.Re
+.Sh DIAGNOSTICS
+.Bl -tag -width Ds -compact
+.It ?Ambiguous command
+abbreviation matches more than one command
+.It ?Invalid command
+no match found
+.It ?Privileged command
+command can be executed by root only
+.El
+.Sh HISTORY
+The
+.Nm
+command appeared in
+.Bx 4.3 .
diff --git a/usr/src/usr.sbin/timed/timedc/timedc.c b/usr/src/usr.sbin/timed/timedc/timedc.c
new file mode 100644 (file)
index 0000000..fe136bd
--- /dev/null
@@ -0,0 +1,266 @@
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+char copyright[] =
+"@(#) Copyright (c) 1983 Regents of the University of California.\n\
+ All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)timedc.c   2.10 (Berkeley) 3/5/91";
+#endif /* not lint */
+
+#include "timedc.h"
+#include <signal.h>
+#include <ctype.h>
+#include <setjmp.h>
+#include <syslog.h>
+
+int    top;
+int    margc;
+int    fromatty;
+char   *margv[20];
+char   cmdline[200];
+jmp_buf        toplevel;
+void   intr();
+int priv_resources();
+struct cmd *getcmd();
+
+
+main(argc, argv)
+       char *argv[];
+{
+       register struct cmd *c;
+
+       openlog("timedc", LOG_ODELAY, LOG_AUTH);
+
+       /*
+        * security dictates!
+        */
+       if (priv_resources() < 0) {
+               fprintf(stderr, "Could not get privileged resources\n");
+               exit(1);
+       }
+       (void) setuid(getuid());
+
+       if (--argc > 0) {
+               c = getcmd(*++argv);
+               if (c == (struct cmd *)-1) {
+                       printf("?Ambiguous command\n");
+                       exit(1);
+               }
+               if (c == 0) {
+                       printf("?Invalid command\n");
+                       exit(1);
+               }
+               if (c->c_priv && getuid()) {
+                       printf("?Privileged command\n");
+                       exit(1);
+               }
+               (*c->c_handler)(argc, argv);
+               exit(0);
+       }
+       fromatty = isatty(fileno(stdin));
+       top = setjmp(toplevel) == 0;
+       if (top)
+               (void) signal(SIGINT, intr);
+       for (;;) {
+               cmdscanner(top);
+               top = 1;
+       }
+}
+
+void
+intr()
+{
+       if (!fromatty)
+               exit(0);
+       longjmp(toplevel, 1);
+}
+
+/*
+ * Command parser.
+ */
+cmdscanner(top)
+       int top;
+{
+       register struct cmd *c;
+       extern int help();
+
+       if (!top)
+               putchar('\n');
+       for (;;) {
+               if (fromatty) {
+                       printf("timedc> ");
+                       (void) fflush(stdout);
+               }
+               if (fgets(cmdline, sizeof(cmdline), stdin) == 0)
+                       quit();
+               if (cmdline[0] == 0)
+                       break;
+               makeargv();
+               c = getcmd(margv[0]);
+               if (c == (struct cmd *)-1) {
+                       printf("?Ambiguous command\n");
+                       continue;
+               }
+               if (c == 0) {
+                       printf("?Invalid command\n");
+                       continue;
+               }
+               if (c->c_priv && getuid()) {
+                       printf("?Privileged command\n");
+                       continue;
+               }
+               (*c->c_handler)(margc, margv);
+       }
+       longjmp(toplevel, 0);
+}
+
+struct cmd *
+getcmd(name)
+       register char *name;
+{
+       register char *p, *q;
+       register struct cmd *c, *found;
+       register int nmatches, longest;
+       extern struct cmd cmdtab[];
+       extern int NCMDS;
+
+       longest = 0;
+       nmatches = 0;
+       found = 0;
+       for (c = cmdtab; c < &cmdtab[NCMDS]; c++) {
+               p = c->c_name;
+               for (q = name; *q == *p++; q++)
+                       if (*q == 0)            /* exact match? */
+                               return(c);
+               if (!*q) {                      /* the name was a prefix */
+                       if (q - name > longest) {
+                               longest = q - name;
+                               nmatches = 1;
+                               found = c;
+                       } else if (q - name == longest)
+                               nmatches++;
+               }
+       }
+       if (nmatches > 1)
+               return((struct cmd *)-1);
+       return(found);
+}
+
+/*
+ * Slice a string up into argc/argv.
+ */
+makeargv()
+{
+       register char *cp;
+       register char **argp = margv;
+
+       margc = 0;
+       for (cp = cmdline; *cp;) {
+               while (isspace(*cp))
+                       cp++;
+               if (*cp == '\0')
+                       break;
+               *argp++ = cp;
+               margc += 1;
+               while (*cp != '\0' && !isspace(*cp))
+                       cp++;
+               if (*cp == '\0')
+                       break;
+               *cp++ = '\0';
+       }
+       *argp++ = 0;
+}
+
+#define HELPINDENT (sizeof ("directory"))
+
+/*
+ * Help command.
+ */
+help(argc, argv)
+       int argc;
+       char *argv[];
+{
+       register struct cmd *c;
+       extern struct cmd cmdtab[];
+
+       if (argc == 1) {
+               register int i, j, w;
+               int columns, width = 0, lines;
+               extern int NCMDS;
+
+               printf("Commands may be abbreviated.  Commands are:\n\n");
+               for (c = cmdtab; c < &cmdtab[NCMDS]; c++) {
+                       int len = strlen(c->c_name);
+
+                       if (len > width)
+                               width = len;
+               }
+               width = (width + 8) &~ 7;
+               columns = 80 / width;
+               if (columns == 0)
+                       columns = 1;
+               lines = (NCMDS + columns - 1) / columns;
+               for (i = 0; i < lines; i++) {
+                       for (j = 0; j < columns; j++) {
+                               c = cmdtab + j * lines + i;
+                               printf("%s", c->c_name);
+                               if (c + lines >= &cmdtab[NCMDS]) {
+                                       printf("\n");
+                                       break;
+                               }
+                               w = strlen(c->c_name);
+                               while (w < width) {
+                                       w = (w + 8) &~ 7;
+                                       putchar('\t');
+                               }
+                       }
+               }
+               return;
+       }
+       while (--argc > 0) {
+               register char *arg;
+               arg = *++argv;
+               c = getcmd(arg);
+               if (c == (struct cmd *)-1)
+                       printf("?Ambiguous help command %s\n", arg);
+               else if (c == (struct cmd *)0)
+                       printf("?Invalid help command %s\n", arg);
+               else
+                       printf("%-*s\t%s\n", HELPINDENT,
+                               c->c_name, c->c_help);
+       }
+}
diff --git a/usr/src/usr.sbin/timed/timedc/timedc.h b/usr/src/usr.sbin/timed/timedc/timedc.h
new file mode 100644 (file)
index 0000000..5dcce7b
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *     @(#)timedc.h    2.4 (Berkeley) 6/1/90
+ */
+
+#include <sys/param.h>
+#include <stdio.h>
+#include <sys/time.h>
+#include <errno.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <arpa/inet.h>
+
+extern int errno;
+
+#define ON             1
+#define OFF            0
+
+#define MSGS           6
+#define TRIALS         5
+
+#define GOOD           1
+#define UNREACHABLE    2
+#define NONSTDTIME     3
+#define HOSTDOWN       0x7fffffff
+
+struct cmd {
+       char    *c_name;                /* command name */
+       char    *c_help;                /* help message */
+       int     (*c_handler)();         /* routine to do the work */
+       int     c_priv;                 /* privileged command */
+};