v20i069: remtime - Remote Time Synchronization without ntp, Part01/01
Clarence Dold
dold at mitisft.convergent.com
Wed Jun 26 06:01:25 AEST 1991
Submitted-by: Clarence Dold <dold at mitisft.convergent.com>
Posting-number: Volume 20, Issue 69
Archive-name: remtime/part01
Environment: SYSVR3, SYSVr4, INET
This is a utility that I use on a network of SysV machines.
I don't have ntp, and I don't need incredible accuracy. This keeps the
systems within a couple of seconds of each other.
I have one system that is slaved to NBS via modem once a week.
The others all run 'remtime' to it at boot time, and periodically.
#!/bin/sh -f
# This is a shell archive, meaning:
# 1. Remove everything above the "#!/bin/sh -f" line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create:
# Wrapped by dold at tsdold.Convergent.COM - Sat Jun 22 09:19:01 PDT 1991
# size 5063 bytes -- remtime.c
# This archive created: Sat Jun 22 09:19:01 PDT 1991
export PATH; PATH=/bin:/usr/bin:$PATH
echo shar: "extracting 'remtime.c'" '(5063 characters)'
if test -f 'remtime.c'
then
echo shar: "will not over-write existing file 'remtime.c'"
else
sed 's/^X//' << \SHAR_EOF > 'remtime.c'
X#ifdef COMMENT
X
Xset tabstop=4
XThis works on the S/Series, as well as the SPC and U6000.
XYou need a host that is running the timeservice. Any sysVr4 machine should.
X'tsdold' does. tsdold is synched to WWV on Sunday morning.
X
XFor sysVr3 SPC and S/Series:
Xcc -#Oo remtime remtime.c -lsocket -lc_s
Xor
Xcc -#go remtime -DDEBUG remtime.c -lsocket -lc_s
X
XFor sysVr4 SPC and S/8400:
Xcc -#Oo remtime remtime.c -lsocket -lnsl
X
XFor IBM RS6000:
Xcc -Oo remtime remtime.c
X
X#endif /* COMMENT */
X
Xstatic char *Author = " dold at Convergent.COM ";
X#include <stdio.h>
X#include <sys/types.h>
X#include <netinet/in.h>
X#include <sys/socket.h>
X#include <netdb.h>
X#include <time.h>
X
X#define EPOCH 0x83aa7e80 /* The start of UNIX time */
X#define TOOMUCH 100 * 3600
X#define TOOLIT 3 /* granularity of one, desired of two */
Xextern int errno;
X
Xint
Xmain(argc, argv)
Xint argc;
Xchar **argv;
X{
X struct sockaddr_in sin;
X struct hostent *host;
X struct servent *serv;
X time_t intime, mytime, oldtime;
X unsigned long delta;
X int sock, con, rd;
X
X
X if (2 > argc){
X fprintf(stderr, "Usage: %s hostname\n", argv[0]);
X exit(-1);
X }
X
X if (serv = getservbyname ( "time", "tcp" )) /* assignment non-NULL */
X sin.sin_port = serv->s_port;
X else {
X perror("Cannot locate time service");
X exit(errno);
X }
X
X if (host = gethostbyname(argv[1])) {
X sin.sin_family = host->h_addrtype;
X memcpy((caddr_t)&sin.sin_addr, host->h_addr, host->h_length);
X } else {
X fprintf(stderr, "Cannot resolve host name\n");
X exit(errno);
X }
X
X if ( (-1) != (sock = socket(AF_INET, SOCK_STREAM, 0))) {
X con = connect(sock, (struct sockaddr *) &sin, sizeof(sin));
X } else {
X perror("socket");
X exit(errno);
X }
X
X if ( sizeof(intime) != (rd = read(sock, &mytime, sizeof(intime)))){
X fprintf(stderr, "Remote time service not available\n");
X exit(-1);
X }
X
X intime = ntohl(mytime); /* Handle Byte-order for Intel */
X mytime = intime - EPOCH;
X
X
X oldtime = time(0);
X
X delta = mytime - oldtime;
X#ifdef DEBUG
X fprintf(stderr, "Received %x, (less epoch) = %x, %s",
X intime, mytime, ctime(&mytime));
X fprintf(stderr, "Delta: %d\n", delta);
X#endif
X
X if ( !delta || delta < TOOLIT || delta > (unsigned)(-TOOLIT) ){
X printf("Time is in agreement with %s\n", argv[1]);
X exit(0);
X }
X
X if ( delta > TOOMUCH && delta < (unsigned)(-TOOMUCH) ){
X printf("This program won't adjust more than %d hours,\n\
X Remote time is %s", TOOMUCH/3600, ctime(&mytime));
X printf("\t Local time is %s", ctime(&oldtime));
X exit(-1);
X }
X
X printf("Current system clock is %s", ctime(&oldtime));
X
X setrtc(mytime);
X
X
X mytime = time(0);
X printf("Time is now %s", ctime(&mytime));
X
X return(0);
X}
X/* +++++++++++++++ end of main() ++++++++++++++++ */
X
X#if mc68k || i386 /* Routine common to Convergent Systems */
X#include <sys/syslocal.h>
X#include <utmp.h>
X#include <fcntl.h>
X int fd_wtmp;
X struct utmp utmp[2] = {
X {"", "", OTIME_MSG, 0, OLD_TIME, 0, 0, 0},
X {"", "", NTIME_MSG, 0, NEW_TIME, 0, 0, 0}
X };
X#else /* Not a recognized box */
Xunsigned long delta;
Xchar dateline[30];
X#endif
X
Xint
Xsetrtc(clock)
Xtime_t clock;
X{
Xstruct tm *tm;
X
X
X#if mc68k /* Convergent SysVr3 S/Series family */
X#include <sys/rtc.h>
Xstruct rtc rtc;
X tm = gmtime(&clock);
X rtc.sec10 = tm->tm_sec / 10;
X rtc.sec1 = tm->tm_sec % 10;
X rtc.min10 = tm->tm_min / 10;
X rtc.min1 = tm->tm_min % 10;
X rtc.hr10 = tm->tm_hour / 10;
X rtc.hr1 = tm->tm_hour % 10;
X rtc.day10 = tm->tm_mday / 10;
X rtc.day1 = tm->tm_mday % 10;
X tm->tm_mon++; /* tm struct numbers from 0 RTC wants 1-12 */
X rtc.mon10 = tm->tm_mon / 10;
X rtc.mon1 = tm->tm_mon % 10;
X rtc.yr10 = tm->tm_year / 10;
X rtc.yr1 = tm->tm_year % 10;
X rtc.wkday = tm->tm_wday;
X
X#elif i386 /* Convergent / Unisys SPC / U6000 family */
X#include <sys/todc.h>
X struct todc rtc;
X tm = localtime(&clock);
X rtc.todc_year = tm->tm_year;
X rtc.todc_month = tm->tm_mon; /*SPC RTC wants 0-11 */
X rtc.todc_day = tm->tm_mday;
X rtc.todc_hour = tm->tm_hour;
X rtc.todc_minute = tm->tm_min;
X rtc.todc_second = tm->tm_sec;
X rtc.todc_dow = tm->tm_wday;
X rtc.todc_millisec = 0;
X
X#else /* undefined system */
X printf("Setting system clock to %s\twaiting for next even minute to set RTC\n", ctime(&clock));
X
X tm = localtime(&clock);
X delta = 60 - tm->tm_sec;
X sleep(delta); /* wait for nearest minute to stab RTC */
X
X clock += delta;
X tm = localtime(&clock); /* catch any date changes, TZ, etc. */
X
X sprintf(dateline, "date %.02d%.02d%.02d%.02d%.02d >/dev/null",
X tm->tm_mon+1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_year);
X
X system(dateline);
X#endif /* unknown hardware */
X
X
X#if mc68k || i386 /* Routine common to Convergent Systems */
X
X printf("Setting system clock to %s", ctime(&clock));
X if (syslocal(SYSL_WTRTC, &rtc)) perror("Write Real Time Clock");
X
X utmp[0].ut_time = time(0);
X if (stime(&clock)) {
X perror("Set system time");
X } else {
X utmp[1].ut_time = clock;
X utmp[0].ut_pid = utmp[1].ut_pid = getpid();
X pututline(&utmp[0]);
X pututline(&utmp[1]);
X if ((fd_wtmp = open(WTMP_FILE, O_WRONLY|O_APPEND)) >0){
X (void) write(fd_wtmp, (char *)utmp, sizeof(utmp));
X }
X }
X
X#endif /* either of the Convergent Systems */
X
X}
SHAR_EOF
if test 5063 -ne "`wc -c < 'remtime.c'`"
then
echo shar: "error transmitting 'remtime.c'" '(should have been 5063 characters)'
fi
fi
exit 0
# End of shell archive
--
---
Clarence A Dold - dold at tsmiti.Convergent.COM
...pyramid!ctnews!tsmiti!dold
exit 0 # Just in case...
--
Kent Landfield INTERNET: kent at sparky.IMD.Sterling.COM
Sterling Software, IMD UUCP: uunet!sparky!kent
Phone: (402) 291-8300 FAX: (402) 291-4362
Please send comp.sources.misc-related mail to kent at uunet.uu.net.
More information about the Comp.sources.misc
mailing list