Add date from 4.4BSD-Lite Release 2
authorJason Self <j@jxself.org>
Sun, 2 Dec 2018 17:44:18 +0000 (09:44 -0800)
committerJason Self <j@jxself.org>
Sun, 2 Dec 2018 17:44:18 +0000 (09:44 -0800)
Signed-off-by: Jason Self <j@jxself.org>
usr/src/bin/date/Makefile [new file with mode: 0644]
usr/src/bin/date/date.1 [new file with mode: 0644]
usr/src/bin/date/date.c [new file with mode: 0644]
usr/src/bin/date/extern.h [new file with mode: 0644]
usr/src/bin/date/netdate.c [new file with mode: 0644]

diff --git a/usr/src/bin/date/Makefile b/usr/src/bin/date/Makefile
new file mode 100644 (file)
index 0000000..7dfc15e
--- /dev/null
@@ -0,0 +1,8 @@
+#      @(#)Makefile    8.1 (Berkeley) 5/31/93
+
+PROG=  date
+SRCS=  date.c netdate.c
+DPADD= ${LIBUTIL}
+LDADD= -lutil
+
+.include <bsd.prog.mk>
diff --git a/usr/src/bin/date/date.1 b/usr/src/bin/date/date.1
new file mode 100644 (file)
index 0000000..85b13e2
--- /dev/null
@@ -0,0 +1,213 @@
+.\" Copyright (c) 1980, 1990, 1993
+.\"    The Regents of the University of California.  All rights reserved.
+.\"
+.\" This code is derived from software contributed to Berkeley by
+.\" the Institute of Electrical and Electronics Engineers, Inc.
+.\"
+.\" 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. 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.
+.\"
+.\"     @(#)date.1     8.3 (Berkeley) 4/28/95
+.\"
+.Dd April 28, 1995
+.Dt DATE 1
+.Os
+.Sh NAME
+.Nm date
+.Nd display or set date and time
+.Sh SYNOPSIS
+.Nm date
+.Op Fl d Ar dst
+.Op Fl r Ar seconds
+.Op Fl t Ar minutes_west
+.Op Fl nu
+.Op Cm + Ns Ar format
+.Op [yy[mm[dd[hh]]]]mm[\&.ss]
+.Sh DESCRIPTION
+.Nm Date
+displays the current date and time when invoked without arguments.
+Providing arguments will format the date and time in a user-defined
+way or set the date.
+Only the superuser may set the date.
+.Pp
+The options are as follows:
+.Bl -tag -width Ds
+.It Fl d
+Set the kernel's value for daylight savings time.
+If
+.Ar dst
+is non-zero, future calls
+to
+.Xr gettimeofday 2
+will return a non-zero
+.Ql tz_dsttime  .
+.It Fl n
+The utility
+.Xr timed 8
+is used to synchronize the clocks on groups of machines.
+By default, if
+.Xr timed
+is running,
+.Nm date
+will set the time on all of the machines in the local group.
+The
+.Fl n
+option stops
+.Nm date
+from setting the time for other than the current machine.
+.It Fl r
+Print out the date and time in
+.Ar seconds
+from the Epoch.
+.It Fl t
+Set the kernel's value for minutes west of
+.Tn GMT .
+.Ar Minutes_west
+specifies the number of minutes returned in
+.Ql tz_minuteswest  
+by future calls to
+.Xr gettimeofday 2 .
+.It Fl u
+Display or set the date in
+.Tn UCT
+(universal) time.
+.El
+.Pp
+An operand with a leading plus (``+'') sign signals a user-defined format
+string which specifies the format in which to display the date and time.
+The format string may contain any of the conversion specifications described
+in the 
+.Xr strftime 3
+manual page, as well as any arbitrary text.
+A <newline> character is always output after the characters specified by
+the format string.
+The format string for the default display is:
+.Bd -literal -offset indent
+``%a %b %e %H:%M:%S %Z %Y''.
+.Ed
+.Pp
+If an operand does not have a leading plus sign, it is interpreted as
+a value for setting the system's notion of the current date and time.
+The canonical representation for setting the date and time is:
+.Pp
+.Bl -tag -width Ds -compact -offset indent
+.It Ar yy
+Year in abbreviated form (.e.g 89 for 1989).
+.It Ar mm
+Numeric month.
+A number from 1 to 12.
+.It Ar dd
+Day, a number from 1 to 31.
+.It Ar hh
+Hour, a number from 0 to 23.
+.It Ar mm
+Minutes, a number from 0 to 59.
+.It Ar .ss
+Seconds, a number from 0 to 61 (59 plus a a maximum of two leap seconds).
+.El
+.Pp
+Everything but the minutes is optional.
+.Pp
+Time changes for Daylight Saving and Standard time and leap seconds
+and years are handled automatically.
+.Sh EXAMPLES
+The command:
+.Bd -literal -offset indent
+date ``+DATE: %m/%d/%y%nTIME: %H:%M:%S''
+.Ed
+.Pp
+will display:
+.Bd -literal -offset indent
+DATE: 11/21/87
+TIME: 13:36:16
+.Ed
+.Pp
+The command:
+.Bd -literal -offset indent
+date 8506131627
+.Ed
+.Pp
+sets the date to
+.Dq Li "June 13, 1985, 4:27 PM" .
+.Pp
+The command:
+.Bd -literal -offset indent
+date 1432
+.Ed
+.Pp
+sets the time to
+.Li "2:32 PM" ,
+without modifying the date.
+.Sh ENVIRONMENTAL VARIABLES
+The following environment variables affect the execution of
+.Nm date :
+.Bl -tag -width TZ
+.It Ev TZ
+The timezone to use when displaying dates.
+See
+.Xr environ 7
+for more information.
+.El
+.Sh FILES
+.Bl -tag -width /var/log/messages -compact
+.It Pa /var/log/wtmp
+A record of date resets and time changes.
+.It Pa /var/log/messages
+A record of the user setting the time.
+.El
+.Sh SEE ALSO
+.Xr gettimeofday 2 ,
+.Xr strftime 3 ,
+.Xr utmp 5 ,
+.Xr timed 8
+.Rs
+.%T "TSP: The Time Synchronization Protocol"
+.%A R. Gusella
+.%A S. Zatti
+.Re
+.Sh DIAGNOSTICS
+Exit status is 0 on success, 1 if unable to set the date, and 2
+if able to set the local date, but unable to set it globally.
+.Pp
+Occasionally, when
+.Xr timed
+synchronizes the time on many hosts, the setting of a new time value may
+require more than a few seconds.
+On these occasions,
+.Nm date
+prints:
+.Ql Network time being set .
+The message
+.Ql Communication error with timed
+occurs when the communication
+between
+.Nm date
+and
+.Xr timed
+fails.
+.Sh STANDARDS
+The
+.Nm date
+command is expected to be compatible with
+.St -p1003.2 .
diff --git a/usr/src/bin/date/date.c b/usr/src/bin/date/date.c
new file mode 100644 (file)
index 0000000..420d19b
--- /dev/null
@@ -0,0 +1,233 @@
+/*
+ * Copyright (c) 1985, 1987, 1988, 1993
+ *     The 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. 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 copyright[] =
+"@(#) Copyright (c) 1985, 1987, 1988, 1993\n\
+       The Regents of the University of California.  All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)date.c     8.2 (Berkeley) 4/28/95";
+#endif /* not lint */
+
+#include <sys/param.h>
+#include <sys/time.h>
+
+#include <ctype.h>
+#include <err.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <syslog.h>
+#include <unistd.h>
+
+#include "extern.h"
+
+time_t tval;
+int retval, nflag;
+
+static void setthetime __P((char *));
+static void badformat __P((void));
+static void usage __P((void));
+
+int logwtmp __P((char *, char *, char *));
+
+int
+main(argc, argv)
+       int argc;
+       char **argv;
+{
+       extern int optind;
+       extern char *optarg;
+       struct timezone tz;
+       int ch, rflag;
+       char *format, buf[1024];
+
+       tz.tz_dsttime = tz.tz_minuteswest = 0;
+       rflag = 0;
+       while ((ch = getopt(argc, argv, "d:nr:ut:")) != -1)
+               switch((char)ch) {
+               case 'd':               /* daylight savings time */
+                       tz.tz_dsttime = atoi(optarg) ? 1 : 0;
+                       break;
+               case 'n':               /* don't set network */
+                       nflag = 1;
+                       break;
+               case 'r':               /* user specified seconds */
+                       rflag = 1;
+                       tval = atol(optarg);
+                       break;
+               case 'u':               /* do everything in GMT */
+                       (void)setenv("TZ", "GMT0", 1);
+                       break;
+               case 't':               /* minutes west of GMT */
+                                       /* error check; don't allow "PST" */
+                       if (isdigit(*optarg)) {
+                               tz.tz_minuteswest = atoi(optarg);
+                               break;
+                       }
+                       /* FALLTHROUGH */
+               default:
+                       usage();
+               }
+       argc -= optind;
+       argv += optind;
+
+       /*
+        * If -d or -t, set the timezone or daylight savings time; this
+        * doesn't belong here, there kernel should not know about either.
+        */
+       if ((tz.tz_minuteswest || tz.tz_dsttime) &&
+           settimeofday(NULL, &tz))
+               err(1, "settimeofday");
+
+       if (!rflag && time(&tval) == -1)
+               err(1, "time");
+
+       format = "%a %b %e %H:%M:%S %Z %Y";
+
+       /* allow the operands in any order */
+       if (*argv && **argv == '+') {
+               format = *argv + 1;
+               ++argv;
+       }
+
+       if (*argv) {
+               setthetime(*argv);
+               ++argv;
+       }
+
+       if (*argv && **argv == '+')
+               format = *argv + 1;
+
+       (void)strftime(buf, sizeof(buf), format, localtime(&tval));
+       (void)printf("%s\n", buf);
+       exit(retval);
+}
+
+#define        ATOI2(ar)       ((ar)[0] - '0') * 10 + ((ar)[1] - '0'); (ar) += 2;
+void
+setthetime(p)
+       register char *p;
+{
+       register struct tm *lt;
+       struct timeval tv;
+       char *dot, *t;
+
+       for (t = p, dot = NULL; *t; ++t) {
+               if (isdigit(*t))
+                       continue;
+               if (*t == '.' && dot == NULL) {
+                       dot = t;
+                       continue;
+               }
+               badformat();
+       }
+
+       lt = localtime(&tval);
+
+       if (dot != NULL) {                      /* .ss */
+               *dot++ = '\0';
+               if (strlen(dot) != 2)
+                       badformat();
+               lt->tm_sec = ATOI2(dot);
+               if (lt->tm_sec > 61)
+                       badformat();
+       } else
+               lt->tm_sec = 0;
+
+       switch (strlen(p)) {
+       case 10:                                /* yy */
+               lt->tm_year = ATOI2(p);
+               if (lt->tm_year < 69)           /* hack for 2000 ;-} */
+                       lt->tm_year += 100;
+               /* FALLTHROUGH */
+       case 8:                                 /* mm */
+               lt->tm_mon = ATOI2(p);
+               if (lt->tm_mon > 12)
+                       badformat();
+               --lt->tm_mon;                   /* time struct is 0 - 11 */
+               /* FALLTHROUGH */
+       case 6:                                 /* dd */
+               lt->tm_mday = ATOI2(p);
+               if (lt->tm_mday > 31)
+                       badformat();
+               /* FALLTHROUGH */
+       case 4:                                 /* hh */
+               lt->tm_hour = ATOI2(p);
+               if (lt->tm_hour > 23)
+                       badformat();
+               /* FALLTHROUGH */
+       case 2:                                 /* mm */
+               lt->tm_min = ATOI2(p);
+               if (lt->tm_min > 59)
+                       badformat();
+               break;
+       default:
+               badformat();
+       }
+
+       /* convert broken-down time to GMT clock time */
+       if ((tval = mktime(lt)) == -1)
+               badformat();
+
+       /* set the time */
+       if (nflag || netsettime(tval)) {
+               logwtmp("|", "date", "");
+               tv.tv_sec = tval;
+               tv.tv_usec = 0;
+               if (settimeofday(&tv, NULL)) {
+                       perror("date: settimeofday");
+                       exit(1);
+               }
+               logwtmp("{", "date", "");
+       }
+
+       if ((p = getlogin()) == NULL)
+               p = "???";
+       syslog(LOG_AUTH | LOG_NOTICE, "date set by %s", p);
+}
+
+static void
+badformat()
+{
+       warnx("illegal time format");
+       usage();
+}
+
+static void
+usage()
+{
+       (void)fprintf(stderr,
+           "usage: date [-nu] [-d dst] [-r seconds] [-t west] [+format]\n");
+       (void)fprintf(stderr, "            [yy[mm[dd[hh]]]]mm[.ss]]\n");
+       exit(1);
+}
diff --git a/usr/src/bin/date/extern.h b/usr/src/bin/date/extern.h
new file mode 100644 (file)
index 0000000..fd0b00a
--- /dev/null
@@ -0,0 +1,32 @@
+/*-
+ * Copyright (c) 1993
+ *     The 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. 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.
+ *
+ *     @(#)extern.h    8.1 (Berkeley) 5/31/93
+ */
+
+int    netsettime __P((time_t));
diff --git a/usr/src/bin/date/netdate.c b/usr/src/bin/date/netdate.c
new file mode 100644 (file)
index 0000000..417dc15
--- /dev/null
@@ -0,0 +1,179 @@
+/*-
+ * Copyright (c) 1990, 1993
+ *     The 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. 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[] = "@(#)netdate.c  8.2 (Berkeley) 4/28/95";
+#endif /* not lint */
+
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+
+#include <netinet/in.h>
+#include <netdb.h>
+#define TSPTYPES
+#include <protocols/timed.h>
+
+#include <err.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "extern.h"
+
+#define        WAITACK         2       /* seconds */
+#define        WAITDATEACK     5       /* seconds */
+
+extern int retval;
+
+/*
+ * Set the date in the machines controlled by timedaemons by communicating the
+ * new date to the local timedaemon.  If the timedaemon is in the master state,
+ * it performs the correction on all slaves.  If it is in the slave state, it
+ * notifies the master that a correction is needed.
+ * Returns 0 on success.  Returns > 0 on failure, setting retval to 2;
+ */
+int
+netsettime(tval)
+       time_t tval;
+{
+       struct timeval tout;
+       struct servent *sp;
+       struct tsp msg;
+       struct sockaddr_in sin, dest, from;
+       fd_set ready;
+       long waittime;
+       int s, length, port, timed_ack, found, err;
+       char hostname[MAXHOSTNAMELEN];
+
+       if ((sp = getservbyname("timed", "udp")) == NULL) {
+               warnx("udp/timed: unknown service");
+               return (retval = 2);
+       }
+
+       memset(&dest, 0, sizeof(dest));
+       dest.sin_port = sp->s_port;
+       dest.sin_family = AF_INET;
+       dest.sin_addr.s_addr = htonl((u_long)INADDR_ANY);
+       s = socket(AF_INET, SOCK_DGRAM, 0);
+       if (s < 0) {
+               if (errno != EPROTONOSUPPORT)
+                       warn("timed");
+               return (retval = 2);
+       }
+
+       memset(&sin, 0, sizeof(sin));
+       sin.sin_family = AF_INET;
+       for (port = IPPORT_RESERVED - 1; port > IPPORT_RESERVED / 2; port--) {
+               sin.sin_port = htons((u_short)port);
+               if (bind(s, (struct sockaddr *)&sin, sizeof(sin)) >= 0)
+                       break;
+               if (errno == EADDRINUSE)
+                       continue;
+               if (errno != EADDRNOTAVAIL)
+                       warn("bind");
+               goto bad;
+       }
+       if (port == IPPORT_RESERVED / 2) {
+               warnx("all ports in use");
+               goto bad;
+       }
+       msg.tsp_type = TSP_SETDATE;
+       msg.tsp_vers = TSPVERSION;
+       if (gethostname(hostname, sizeof(hostname))) {
+               warn("gethostname");
+               goto bad;
+       }
+       (void)strncpy(msg.tsp_name, hostname, sizeof(hostname));
+       msg.tsp_seq = htons((u_short)0);
+       msg.tsp_time.tv_sec = htonl((u_long)tval);
+       msg.tsp_time.tv_usec = htonl((u_long)0);
+       length = sizeof(struct sockaddr_in);
+       if (connect(s, (struct sockaddr *)&dest, length) < 0) {
+               warn("connect");
+               goto bad;
+       }
+       if (send(s, (char *)&msg, sizeof(struct tsp), 0) < 0) {
+               if (errno != ECONNREFUSED)
+                       warn("send");
+               goto bad;
+       }
+
+       timed_ack = -1;
+       waittime = WAITACK;
+loop:
+       tout.tv_sec = waittime;
+       tout.tv_usec = 0;
+
+       FD_ZERO(&ready);
+       FD_SET(s, &ready);
+       found = select(FD_SETSIZE, &ready, (fd_set *)0, (fd_set *)0, &tout);
+
+       length = sizeof(err);
+       if (!getsockopt(s,
+           SOL_SOCKET, SO_ERROR, (char *)&err, &length) && err) {
+               if (err != ECONNREFUSED)
+                       warn("send (delayed error)");
+               goto bad;
+       }
+
+       if (found > 0 && FD_ISSET(s, &ready)) {
+               length = sizeof(struct sockaddr_in);
+               if (recvfrom(s, &msg, sizeof(struct tsp), 0,
+                   (struct sockaddr *)&from, &length) < 0) {
+                       if (errno != ECONNREFUSED)
+                               warn("recvfrom");
+                       goto bad;
+               }
+               msg.tsp_seq = ntohs(msg.tsp_seq);
+               msg.tsp_time.tv_sec = ntohl(msg.tsp_time.tv_sec);
+               msg.tsp_time.tv_usec = ntohl(msg.tsp_time.tv_usec);
+               switch (msg.tsp_type) {
+               case TSP_ACK:
+                       timed_ack = TSP_ACK;
+                       waittime = WAITDATEACK;
+                       goto loop;
+               case TSP_DATEACK:
+                       (void)close(s);
+                       return (0);
+               default:
+                       warnx("wrong ack received from timed: %s", 
+                           tsptype[msg.tsp_type]);
+                       timed_ack = -1;
+                       break;
+               }
+       }
+       if (timed_ack == -1)
+               warnx("can't reach time daemon, time set locally");
+
+bad:
+       (void)close(s);
+       return (retval = 2);
+}