keith@sequoia.execu.com (Keith Pyle) (11/29/90)
rdate is functionally similar to the rdate command found in SunOS 4.1. It is not based on or written with knowledge of source code from SunOS. rdate provides a means for setting the date of the local machine from another machine through use of the TCP time protocol defined in RFC868. Extensions are provided over the SunOS rdate: (1) to allow specification of multiple time servers, (2) to simply display the server(s) time and not set the local machine's date, and (3) to optionally use the adjtime system call, if available, to gradually adjust the local time. ----- cut here and run through unshar or sh ----- #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh <file", e.g.. If this archive is complete, you # will see the following message at the end: # "End of shell archive." # Contents: INSTALL MANIFEST Makefile PORTING README port.c rdate.8 # rdate.c rdate.h sockio.c # Wrapped by keith@lime on Wed Nov 28 13:04:37 1990 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f 'INSTALL' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'INSTALL'\" else echo shar: Extracting \"'INSTALL'\" \(963 characters\) sed "s/^X//" >'INSTALL' <<'END_OF_FILE' XSoftware Requirements X--------------------- X X- C compiler X X- support for sockets X X- at least one machine providing timed service X XInstallation X------------ X X1) Unpack the package in an appropriate directory X X2) Edit the Makefile to specify the desired configuration items X X3) Issue the command 'make' to build the binary X X4) Test the program with the following commands (not run as root): X X ./rdate -d server X ./rdate server X X where server is a machine providing timed service. The first command X should display the server's time. The second should fail with an X error message: "couldn't set time of day: Not owner". X X5) Login as root X X6) Repeat the second command from step 4 if you wish to actually set X the local machine's date X X7) Type 'make install' to copy the binary and the man page to the X directories specified in the Makefile. X X8) Modify your system files (e.g., /etc/rc.local or root's crontab) X as appropriate for your use of rdate END_OF_FILE if test 963 -ne `wc -c <'INSTALL'`; then echo shar: \"'INSTALL'\" unpacked with wrong size! fi # end of 'INSTALL' fi if test -f 'MANIFEST' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'MANIFEST'\" else echo shar: Extracting \"'MANIFEST'\" \(248 characters\) sed "s/^X//" >'MANIFEST' <<'END_OF_FILE' XINSTALL Installation instructions XMANIFEST This file XMakefile The name says it XPORTING Comments on porting rdate to a new environment XREADME Some important comments Xrdate.8 man page for rdate X Xcode files: X Xrdate.c Xport.c Xsockio.c Xrdate.h END_OF_FILE if test 248 -ne `wc -c <'MANIFEST'`; then echo shar: \"'MANIFEST'\" unpacked with wrong size! fi # end of 'MANIFEST' fi if test -f 'Makefile' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'Makefile'\" else echo shar: Extracting \"'Makefile'\" \(875 characters\) sed "s/^X//" >'Makefile' <<'END_OF_FILE' X# rdate Makefile X X# --- Uncomment one set of the following flag definitions --- X X# For SunOS, Ultrix, HP/UX, or generic BSD X XCFLAGS = -O XLDFLAGS = X X# For Sequent Dynix X X# CFLAGS = -O X# LDFLAGS = -lseq X X# For other BSD which have adjtime(2) X X# CFLAGS = -O -DHAS_ADJTIME X# LDFLAGS = X X# For AIX, generic System V X X# CFLAGS = -O -DSYSV X# LDFLAGS = X X# For Unisys U6000 X X# CFLAGS = -O -DSYSV X# LDFLAGS = -lsocket X X# For Interactive 386/ix X X# CFLAGS = -O -DSYSV -D386IX X# LDFLAGS = -linet X X# --- Define the installation parameters --- X XBINDIR = /usr/local/bin XMANEXT = 8 XMANDIR = /usr/man/man$(MANEXT) X X# --- The following should not need to be changed --- X XRDATE_OBJS = rdate.o port.o sockio.o X Xall: rdate X Xrdate: $(RDATE_OBJS) X cc $(CFLAGS) -o rdate $(RDATE_OBJS) $(LDFLAGS) X Xrdate.o port.o: $($@:.o=.c) rdate.h X Xinstall: X cp rdate $(BINDIR) X cp rdate.8 $(MANDIR)/rdate.$(MANEXT) END_OF_FILE if test 875 -ne `wc -c <'Makefile'`; then echo shar: \"'Makefile'\" unpacked with wrong size! fi # end of 'Makefile' fi if test -f 'PORTING' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'PORTING'\" else echo shar: Extracting \"'PORTING'\" \(1651 characters\) sed "s/^X//" >'PORTING' <<'END_OF_FILE' XPorting X------- X XThe initial porting effort identified three items which were version Xspecific. Each of the affect areas of the code is wrapped in cpp(1) Xdirectives to allow selection of known alternatives through appropriate X#define statements. The file rdate.h uses preset cpp(1) definitions X(e.g., sun on SunOS systems) to specify the correct set of #define Xstatements, where possible. It is still necessary to specify some Xflags through the Makefile. The current code has been ported to and Xtested on the following hardware/software combinations: X XHP 9000/825, HP/UX A.B7.00 XSun 3, SunOS 4.1 XSequent Symmetry, DYNIX 3.0.17 XVAX 3602, Ultrix 3.1 XPS/2, AIX XUnisys U6000/51, System Vr3 XInteractive 386/ix X XTo port rdate to another environment: X X1) Determine if your system is BSD-like or System V-like: does it use X settimeofday(2) or stime(2), respectively? X X2) If it is BSD-like, does it have adjtime(2)? X X3) Modify Makefile, and possibly rdate.h, according to the following: X X If it is BSD-like and does not have adjtime(2), just use the generic X BSD compile and link flags. X X If it is BSD-like and has adjtime(2), use the BSD flags which define X HAS_ADJTIME or modify rdate.h (in the manner used for sun and ultrix) X to automatically define this). X X If it is System V-like, start by using the generic System V flags. X If this results in undefined references at link time, there is X probably a special link flag to include the socket routines. Delve X into the manuals and determine what standard you vendor has chosen X to set. X X4) If this still isn't sufficient, get out the Veg-O-Matic and X start slicing and dicing. X END_OF_FILE if test 1651 -ne `wc -c <'PORTING'`; then echo shar: \"'PORTING'\" unpacked with wrong size! fi # end of 'PORTING' fi if test -f 'README' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'README'\" else echo shar: Extracting \"'README'\" \(2288 characters\) sed "s/^X//" >'README' <<'END_OF_FILE' XKeith's rdate X XCopyright (c) 1990, W. Keith Pyle, Austin, Texas X XDescription X----------- X Xrdate is functionally similar to the rdate command found in SunOS 4.1. XIt is not based on or written with knowledge of source code from XSunOS. rdate provides a means for setting the date of the local Xmachine from another machine through use of the TCP time protocol Xdefined in RFC868. Extensions are provided over the SunOS rdate: (1) Xto allow specification of multiple time servers, (2) to simply display Xthe server(s) time and not set the local machine's date, and (3) to Xoptionally use the adjtime system call, if available, to gradually Xadjust the local time. X Xrdate has been ported to: X XHP 9000/825, HP/UX A.B7.00 XSun 3, SunOS 4.1 XSequent Symmetry, DYNIX 3.0.17 XVAX 3602, Ultrix 3.1 XPS/2, AIX XUnisys U6000/51, System Vr3 XInteractive 386/ix X XSee the man page for more information on the command. XSee the file INSTALL for installation instructions. XSee the file PORTING for porting comments. X XQualifications X-------------- X XThis program may be copied, transferred, or used in any manner subject Xto the following conditions: X X1) The original README and MANIFEST files must be retained X in any subsequent source distributions, whether unaltered or not. X X2) Neither the author nor his employer make any express or implied X warranties as to the fitness of this program for any particular X purpose. The user assumes full responsible for the use of this X program and any consequences of its use whether due to defect, X misuse, abuse, etc. X X3) The origin of this program must not be misrepresented, either X by explicit claim or omission. X X4) Altered versions of this program must be clearly identified as X such and may not be represented as the original. X X5) This program may not be sold in any form without the express X written consent of the author. X X6) Should any of the above be held unenforceable, the remainder shall X remain in force. X XContacting the Author X--------------------- X XReports of bugs, requests for enhancements, comments, compliments, and Xflames may be sent to the author at the following address. X XKeith Pyle UUCP: ...!uunet!execu!keith XExecucom Systems Corp., Austin, Texas Internet: keith@execu.com END_OF_FILE if test 2288 -ne `wc -c <'README'`; then echo shar: \"'README'\" unpacked with wrong size! fi # end of 'README' fi if test -f 'port.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'port.c'\" else echo shar: Extracting \"'port.c'\" \(1201 characters\) sed "s/^X//" >'port.c' <<'END_OF_FILE' X/* port --- routines to deal with sockets and ports for user programs */ X X/* Copyright (c) 1990, W. Keith Pyle, Austin, Texas */ X X#include "rdate.h" X X/* ------------------------------------------------------------------------- */ X Xopen_port(host, port) X Xchar *host; Xint port; X X{ X int socket_fd; X X struct hostent *hentry; X struct sockaddr_in sa; X X /* Make sure there is a host name specified */ X X if (host == NULL || *host == '\0') { X X errno = EDESTADDRREQ; X return(-1); X } X X /* Get the host file entry for the named host */ X X if ((hentry = gethostbyname(host)) == NULL) { X X errno = ECONNREFUSED; X return(-1); X } X X /* Clear the socket structure */ X X bzero((char *)&sa, sizeof(sa)); X X /* Put the host's address in the socket structure */ X X bcopy(hentry->h_addr, (char *)&sa.sin_addr, hentry->h_length); X X /* Set the address type and port */ X X sa.sin_family = hentry->h_addrtype; X sa.sin_port = htons((unsigned short)port); X X /* Open the socket */ X X if ((socket_fd = socket(hentry->h_addrtype, SOCK_STREAM, 0)) < 0) X return(-1); X X /* Connect to the port */ X X if (connect(socket_fd, (struct sockaddr *)&sa, sizeof(sa)) < 0) X return(-1); X X /* Return the socket descriptor */ X X return(socket_fd); X} END_OF_FILE if test 1201 -ne `wc -c <'port.c'`; then echo shar: \"'port.c'\" unpacked with wrong size! fi # end of 'port.c' fi if test -f 'rdate.8' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'rdate.8'\" else echo shar: Extracting \"'rdate.8'\" \(2296 characters\) sed "s/^X//" >'rdate.8' <<'END_OF_FILE' X.TH "RDATE" 8L "14 November 1990" "Execucom" "LOCAL USER COMMANDS" X.SH NAME Xrdate \- set the system date/time from a remote host X.SH SYNOPSIS X.LP X.B rdate X[ X.B \-adD X] X.I host X[ X.I host X] ... X.SH DESCRIPTION X.B rdate Xuses a specified remote host as a time server and resets the local system Xdate/time to the value supplied by the remote host. One or more hosts Xcan be specified on the command line. X.B rdate Xwill use the value from the first host which responds. Thus, the date/time Xcan be reset even if the primary time server does not respond. X.LP XWhen a host has responded to the X.B rdate Xrequest and the local date/time has been set, the name of the responding Xhost and the time will be displayed on standard output. X.LP X.B rdate Xuses the TCP Time Protocol service specified in RFC868. This service Xprovides the number of seconds since 00:00:00 1 January 1900 GMT on port 37. XThe returned value is corrected to the Unix epoch, 00:00:00 1 January 1970 XGMT. Depending on the command line options, this value is used X(1) to reset the local machine's date/time immediately to the new value, X(2) to adjust the local machine's date/time gradually to the new value, Xor (3) for display only. The default is to reset the local date/time. XSince the system calls used to modify the date/time Xare privileged, X.B rdate Xmust be run by root to successfully change the local date/time. X.LP X.B rdate Xis often used in a startup file such as /etc/rc.local to set the system Xdate/time. X.SH OPTIONS X.TP X.B \-a XUse the server's time to gradually adjust the local date/time to the new Xvalue. XThis technique guarantees that there are no time discontinuities as the Xtime is changed. X.ft I X(N.B.: XThe system call to gradually adjust time Xis not available on all versions of Unix and this Xoption will not be provided on those systems.) X.ft R X.TP X.B \-d XDisplay the time from the first server to respond. XDo not adjust or set the local machine's date/time. X.TP X.B \-D XDisplay the time from all servers that respond. XDo not adjust or set the local machine's date/time. X.SH AUTHOR XKeith Pyle X.SH DIAGNOSTICS XThe exit status is 0 for mormal execution. If none of the specified hosts Xrespond or if the time can not changed, the exit status is set to 1. Syntax Xerrors result in a usage message and an exit status of 2. END_OF_FILE if test 2296 -ne `wc -c <'rdate.8'`; then echo shar: \"'rdate.8'\" unpacked with wrong size! fi # end of 'rdate.8' fi if test -f 'rdate.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'rdate.c'\" else echo shar: Extracting \"'rdate.c'\" \(3339 characters\) sed "s/^X//" >'rdate.c' <<'END_OF_FILE' X/* rdate --- get the date from the date server on a specified host */ X/* and reset the local system date/time */ X X/* Copyright (c) 1990, W. Keith Pyle, Austin, Texas */ X X#include "rdate.h" X Xextern int optind; Xextern int opterr; X Xvoid change_time(); X X/* ------------------------------------------------------------------------- */ X Xmain(argc, argv) X Xint argc; Xchar *argv[]; X X{ X int adjust; X int argno; X int display_all; X int display_only; X int flag; X int socket_fd; X int success; X X unsigned long tod; X X adjust = FALSE; X display_all = FALSE; X display_only = FALSE; X opterr = 0; X success = FALSE; X X while ((flag = getopt(argc, argv, "adD")) != EOF) { X X switch (flag) { X X case 'a': X X#ifdef HAS_ADJTIME X adjust = TRUE; X#else X (void)fprintf(stderr, "-a not supported on this system\n"); X exit(1); X#endif X break; X X case 'd': X X display_only = TRUE; X break; X X case 'D': X X display_only = TRUE; X display_all = TRUE; X break; X X default: X X (void)fprintf(stderr, "%s: invalid argument: %c\n", argv[0], X flag); X exit(1); X } X } X X /* Was a host specified? */ X X if ((argc - optind) < 1) { X X (void)fprintf(stderr, "usage: %s [-ad] host [host] ...\n", argv[0]); X exit(2); X } X X /* Try the hosts in order until one of them responds */ X X for (argno = optind ; argno < argc ; argno++) { X X /* Open the timed port on the host specified by the argument */ X X if ((socket_fd = open_port(argv[argno], TIME_PORT)) < 0) X continue; X X /* Get the time value */ X X if (read_socket(socket_fd, (char *)&tod, sizeof(int)) == sizeof(int)) { X X success = TRUE; X X /* Convert tod to host byte order and correct it to Unix time */ X /* (timed returns seconds since 00:00:00 1 January 1900 GMT) */ X X tod = ntohl(tod); X tod -= 2208988800; X X if (!display_only) X change_time(tod, adjust); X X /* Display the value and where we got it */ X X (void)printf("%s%s: %s", X display_only ? "" : (adjust ? "adjusted to " : "set to "), X argv[argno], ctime((time_t *)&tod)); X X if (!display_all) X break; X } X X (void)close(socket_fd); X } X X /* Was an attempt successful? */ X X if (!success) { X X (void)fprintf(stderr, "couldn't get time from any listed host\n"); X exit(1); X } X X /* We're done */ X X (void)close(socket_fd); X exit(0); X /* NOTREACHED */ X} X X/* ------------------------------------------------------------------------- */ X Xvoid Xchange_time(tod, adjust) X Xunsigned long tod; Xint adjust; X X{ X#ifndef SYSV X struct timeval timeval; X X /* Put it in the timeval structure for settimeofday */ X X timeval.tv_sec = tod; X timeval.tv_usec = 0; X#endif X X /* Are we to adjust the time or just set it? */ X X if (adjust) { X X#ifdef HAS_ADJTIME X struct timeval currtime; X X /* Get the local time and determine the adjustment */ X X if (gettimeofday(&currtime, (struct timezone *)NULL) < 0) { X X perror("couldn't get local time of day"); X exit(1); X } X X timeval.tv_sec -= currtime.tv_sec; X timeval.tv_usec -= currtime.tv_usec; X X /* Adjust it */ X X if (adjtime(&timeval, (struct timeval *)NULL) < 0) { X X perror("couldn't adjust time"); X exit(1); X } X#endif X } X X /* Set the time of day, but leave the timezone alone */ X X#ifndef SYSV X else if (settimeofday(&timeval, (struct timezone *)NULL) < 0) { X#else X else if (stime(&tod) < 0) { X#endif X X perror("couldn't set time of day"); X exit(1); X } X X return; X} END_OF_FILE if test 3339 -ne `wc -c <'rdate.c'`; then echo shar: \"'rdate.c'\" unpacked with wrong size! fi # end of 'rdate.c' fi if test -f 'rdate.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'rdate.h'\" else echo shar: Extracting \"'rdate.h'\" \(688 characters\) sed "s/^X//" >'rdate.h' <<'END_OF_FILE' X/* rdate.h --- include file for remote server date setting utility */ X X/* Copyright (c) 1990, W. Keith Pyle, Austin, Texas */ X X#if defined(sun) || defined(ultrix) X#define HAS_ADJTIME X#endif X X#if defined(hpux) X#define bcopy(from, to, count) memcpy(to, from, count) X#define bzero(to, count) memset(to, 0, count) X#endif X X#if defined(SYSV) && defined(HAS_ADJTIME) X#undef HAS_ADJTIME X#endif X X#include <stdio.h> X#include <errno.h> X#include <time.h> X#include <sys/types.h> X#include <sys/time.h> X#include <sys/uio.h> X#include <sys/socket.h> X#include <netinet/in.h> X#include <netdb.h> X X#ifdef 386IX X#include <net/errno.h> X#endif X X#define TIME_PORT 37 X X#define FALSE 0 X#define TRUE 1 X Xvoid exit(); END_OF_FILE if test 688 -ne `wc -c <'rdate.h'`; then echo shar: \"'rdate.h'\" unpacked with wrong size! fi # end of 'rdate.h' fi if test -f 'sockio.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'sockio.c'\" else echo shar: Extracting \"'sockio.c'\" \(866 characters\) sed "s/^X//" >'sockio.c' <<'END_OF_FILE' X/* sockio --- read and write routines for use with sockets */ X X/* Copyright (c) 1990, W. Keith Pyle, Austin, Texas */ X X/* ------------------------------------------------------------------------- */ X Xread_socket(socket_fd, buffer, size) X Xint socket_fd; Xregister char *buffer; Xregister int size; X X{ X register int bytes; X register int n; X X bytes = 0; X X while (bytes < size) { X X if ((n = read(socket_fd, buffer + bytes, size - bytes)) < 0) X return(n); X X bytes += n; X } X X return(bytes); X} X X/* ------------------------------------------------------------------------- */ X Xwrite_socket(socket_fd, buffer, size) X Xint socket_fd; Xregister char *buffer; Xregister int size; X X{ X register int bytes; X register int n; X X bytes = 0; X X while (bytes < size) { X X if ((n = write(socket_fd, buffer + bytes, size - bytes)) < 0) X return(n); X X bytes += n; X } X X return(bytes); X} END_OF_FILE if test 866 -ne `wc -c <'sockio.c'`; then echo shar: \"'sockio.c'\" unpacked with wrong size! fi # end of 'sockio.c' fi echo shar: End of shell archive. exit 0 ----------------------------------------------------------------------------- Keith Pyle UUCP: ...!cs.utexas.edu!execu!keith Execucom Systems Corp., Austin, Texas Internet: keith@execu.com "It's 10 o'clock. Do you know where Disclaimer: Everything I say is your child processes are?" true unless I use the word 'the'. -----------------------------------------------------------------------------
keith@sequoia.execu.com (Keith Pyle) (11/29/90)
A small oops in the source posting: in the rdate.h and Makefile, the string 386IX should be I386IX. Last minute changes always bite... -- ----------------------------------------------------------------------------- Keith Pyle UUCP: ...!cs.utexas.edu!execu!keith Execucom Systems Corp., Austin, Texas Internet: keith@execu.com "It's 10 o'clock. Do you know where Disclaimer: Everything I say is your child processes are?" true unless I use the word 'the'. -----------------------------------------------------------------------------