dold@mitisft.convergent.com (Clarence Dold) (06/26/91)
Submitted-by: Clarence Dold <dold@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@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@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@tsmiti.Convergent.COM ...pyramid!ctnews!tsmiti!dold exit 0 # Just in case... -- Kent Landfield INTERNET: kent@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@uunet.uu.net.