home *** CD-ROM | disk | FTP | other *** search
- From: billd@fps.com (George Baily)
- Newsgroups: comp.protocols.time.ntp,alt.sources
- Subject: Tools for people using software clocks only with xntp.
- Message-ID: <18633@celit.fps.com>
- Date: 22 Jun 91 02:03:35 GMT
-
- This is an updated version of my tools for people using software only
- clocks with xntp. Against my better judgement, I'm cross-posting to
- alt.sources thinking that maybe some people who might like these might
- not read comp.protocols.time.ntp. Probably not but who knows?
-
- If the next paragraph makes no sense to you, go on to the README below.
-
- In any case, I've made a few improvements on these fairly trivial
- programs. tclock is quite a lot more efficient in terms of the use of
- system resources. I got rid of a lot of unneccessary system calls.
- The default output format is different but 4 formats are now available
- via command line switches. adjtime can now optionally wait for the
- adjustment to finish and it prints out the pending adjustment once
- per second while it waits. doadj makes use of this and also now
- puts the old value of tickadj back rather than wimping out and doing
- a tickadj -A.
-
- I made these things for myself and didn't really intend them for
- distribution so they are fairly hacked looking. I did try to clean
- them up a little more this time but they are still fairly rough.
- Fortunately, they are trivial enough that it doesn't really matter
- that much.
-
- Enjoy.
-
- ** README ********************************************************
-
- These programs are crude hacks but they make working with a software
- reference clock with no good hardware reference clock available a
- little easier.
-
- I try to synchronize my time with the phone company time recording. To
- do this, I first run "tclock" which stands for "text clock" which
- prints out the current time constantly in one of the following forms:
- -h: "\rHH:MM:SS.FF", -m "\rMM:SS.FF", -s "\rSS.FF", or -d (default)
- "\rSS.F". I currently have it set to print out every 0.1 seconds. I
- figure I can see the difference between times that are about .1 or .2
- off from each other so this is about as good as it gets when doing this
- stuff by hand. Anyway, I call the "time" number and watch the running
- tclock and try to guess how far off it is from the phone company time.
-
- After making a guess I then want to adjust it. "date(1)" is a pain.
- There is a variable delay between the time you hit return and the time
- that the clock is actually set. So I've written a program called
- "adjtime" which is simply a shell level access program to the
- adjtime(2) system call. It takes as it's parameter a single floating
- point number of the amount of seconds to adjust by. If you have your
- tickadj variable set to a small value (as ntp documentation always
- recomends), it will take a hell of a long time to make up differences
- large enough for humans to distinguish. For that reason, I've made a
- script called "doadj" which does a tickadj to make tickadj 10% of tick
- (normal default) while it runs adjtime. It then waits an appropriate
- amount of time for the tickadj to finish and runs "tickadj -a" to set
- things back to normal. You may not want to have (x)ntpd running when
- you do this since it might do it's own adjtime and wipe you out. If
- you leave it running and the time doesn't get adjusted, that's probably
- what happened. Just do it again. Adjtime can optionally take a "-w"
- flag which causes it to wait for the comepensation to finish before it
- exits and print out how much compensation is left once per second.
- This is a pacifier that I find I need.
-
- READ AND UNDERSTAND THE doadj SCRIPT BEFORE YOU RUN IT!
- It may need modification for your system.
-
- Now you can run tclock again and call the "time" number again to see
- how close you are. You may need to adjust again.
-
- If you keep track of how much you have to adjust over given time
- periods you can guess a good value for the drift compensation
- register. If you are using the software pseudo-clock from xntp, you
- can use this value for your fudge time1 value. You can refine it
- over longer and longer test periods as you keep using it.
-
- This stuff was written on and is used on BSD systems. I don't know if
- tclock will run on System V since I don't know if System V has
- setitimer(2) or some of the signal stuff. I don't care to port it and
- I won't support it. You're on your own.
-
- Usual disclaimers: Run this stuff at your own risk. Neither I nor my
- company are willing to take repsonsibility for this and in fact this
- whole posting could be a forgery made it look like it came from
- billd@fps.com so you'll have a hell of a time proving that I posted
- it. So there.
-
- --Bill Davidson billd@fps.com 6/21/91
-
- #! /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: README Makefile adjtime.c tclock.c doadj.sh
- # Wrapped by billd@celit on Mon May 20 20:26:18 1991
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'README' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'README'\"
- else
- echo shar: Extracting \"'README'\" \(2559 characters\)
- sed "s/^X//" >'README' <<'END_OF_FILE'
- X
- XThese programs are crude hacks but they make working with a software
- Xreference clock with no good hardware reference clock available a
- Xlittle easier.
- X
- XI try to synchronize my time with the phone company time recording. To
- Xdo this, I first run "tclock" which stands for "text clock" which
- Xprints out the current time constantly in the form "\rHH:MM:SS.FF". I
- Xcurrently have it set to print out every 0.1 seconds. I figure I can
- Xsee the difference between times that are about .2 off from each other
- Xso this is about as good as it gets when doing this stuff by hand.
- XAnyway, I call the "time" number and watch the running tclock and try
- Xto guess how far off it is from the phone company time.
- X
- XAfter making a guess I then want to adjust it. "date(1)" is a pain.
- XThere is a variable delay between the time you hit return and the time
- Xthat the clock is actually set. So I've written a program called
- X"adjtime" which is simply a shell level access program to the
- Xadjtime(2) system call. It takes as it's parameter a single floating
- Xpoint number of the amount of seconds to adjust by. If you have your
- Xtickadj variable set to a small value (as ntp documentation always
- Xrecomends), it will take a hell of a long time to make up differences
- Xlarge enough for humans to distinguish. For that reason, I've made a
- Xscript called "doadj" which does a tickadj to make tickadj 10% of tick
- X(normal default) while it runs adjtime. It then waits an appropriate
- Xamount of time for the tickadj to finish and runs "tickadj -A" to set
- Xthings back to normal. You may not want to have (x)ntpd running when
- Xyou do this since it might do it's own adjtime and wipe you out. If
- Xyou leave it running and the time doesn't get adjusted, that's probably
- Xwhat happened. Just do it again.
- X
- XREAD AND UNDERSTAND THE doadj SCRIPT BEFORE YOU RUN IT!
- XIt may need modification for your system.
- X
- XNow you can run tclock again and call the "time" number again to see
- Xhow close you are. You may need to adjust again.
- X
- XThis stuff was written on and is used on BSD systems. I don't know if
- Xtclock will run on System V since I don't know if System V has
- Xsetitimer(2) or some of the signal stuff. I don't care to port it and
- XI won't support it. You're on your own.
- X
- XUsual disclaimers: Run this stuff at your own risk. Neither I nor my
- Xcompany are willing to take repsonsibility for this and in fact this
- Xwhole posting could be a forgery made it look like it came from
- Xbilld@fps.com so you'll have a hell of a time proving that I posted
- Xit. So there.
- X
- X--Bill Davidson billd@fps.com 5/20/91
- END_OF_FILE
- if test 2559 -ne `wc -c <'README'`; then
- echo shar: \"'README'\" unpacked with wrong size!
- fi
- # end of 'README'
- fi
- if test -f 'Makefile' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'Makefile'\"
- else
- echo shar: Extracting \"'Makefile'\" \(368 characters\)
- sed "s/^X//" >'Makefile' <<'END_OF_FILE'
- X#
- X# quick hack Makefile
- X#
- X
- XCFLAGS= -O
- XPROGRAMS= adjtime tclock doadj
- XFILES= README Makefile adjtime.c tclock.c doadj.sh
- X
- Xall: $(PROGRAMS)
- X
- Xadjtime: adjtime.o
- X $(CC) $(CFLAGS) -o $@ $@.o
- X
- Xtclock: tclock.o
- X $(CC) $(CFLAGS) -o $@ $@.o
- X
- Xdoadj: doadj.sh
- X cp $@.sh $@
- X chmod +x $@
- X
- Xclean:
- X rm -f $(PROGRAMS) *.o
- X
- Xsoftclock.shar: $(FILES)
- X shar -o softclock.shar $(FILES)
- X
- END_OF_FILE
- if test 368 -ne `wc -c <'Makefile'`; then
- echo shar: \"'Makefile'\" unpacked with wrong size!
- fi
- # end of 'Makefile'
- fi
- if test -f 'adjtime.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'adjtime.c'\"
- else
- echo shar: Extracting \"'adjtime.c'\" \(1799 characters\)
- sed "s/^X//" >'adjtime.c' <<'END_OF_FILE'
- X/******************************************************************************
- X*
- X* ADJTIME - Apply the adjtime call with the value on the command
- X* line. Reports value of pending adjtime which you just wiped
- X* out (see adjtime(2)). Takes only one parameter: a floating
- X* point number which is the number of seconds to adjust by.
- X* Positive numbers speed up the clock, negative numbers slow
- X* it down.
- X*
- X* This program must be run by root to have any effect.
- X*
- X* You probably want to have tickadj set to a large value, say
- X* tick/10 (normal value). If you have a small value for ntp,
- X* you may want to temporarily run "tickadj -a 1000" before
- X* running adjtime and "tickadj -A" after running adjtime and
- X* after the clock has come into the value you want.
- X*
- X* This program makes it a little easier to get the system clock
- X* set to the proper time in the face of delays running date(1).
- X*
- X******************************************************************************/
- X
- X#include <stdio.h>
- X#include <ctype.h>
- X#include <sys/time.h>
- X
- Xdouble atof();
- Xvoid doadjtime();
- X
- X#define issign(x) (((x)=='-')||((x)=='+'))
- X
- Xvoid main( argc, argv )
- Xint argc;
- Xchar *argv[];
- X{
- X double diff;
- X char *val;
- X
- X if ( argc < 2 )
- X usage();
- X val = argv[1];
- X if ( isdigit(val[0]) || ( isdigit(val[1]) && issign(val[0]) ) ){
- X diff = atof(argv[1]);
- X doadjtime(diff);
- X }else
- X usage();
- X}
- X
- Xint usage()
- X{
- X fprintf(stderr,"usage: adjtime seconds\n");
- X exit(-1);
- X}
- X
- Xvoid doadjtime(diff)
- Xdouble diff;
- X{
- X struct timeval tp, otp;
- X
- X tp.tv_sec = (long)diff;
- X tp.tv_usec = (long)(1000000 * (diff - tp.tv_sec));
- X printf("adjusting %ld seconds, %ld useconds\n",tp.tv_sec,tp.tv_usec);
- X if ( adjtime( &tp, &otp ) ){
- X perror("adjtime");
- X exit(-1);
- X }else
- X printf("%ld %ld\n",otp.tv_sec,otp.tv_usec);
- X}
- X
- END_OF_FILE
- if test 1799 -ne `wc -c <'adjtime.c'`; then
- echo shar: \"'adjtime.c'\" unpacked with wrong size!
- fi
- # end of 'adjtime.c'
- fi
- if test -f 'tclock.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'tclock.c'\"
- else
- echo shar: Extracting \"'tclock.c'\" \(2924 characters\)
- sed "s/^X//" >'tclock.c' <<'END_OF_FILE'
- X/******************************************************************************
- X*
- X* TCLOCK - This program prints a text clock. It tries to do it
- X* ten times per second. It prints out accurate to 1/100th of
- X* a second. Quit with SIGINT (usually control-C).
- X*
- X* Needed Library Routines:
- X*
- X* gettimeofday(2)
- X* setitimer(2)
- X* sigpause(2)
- X* sigsetmask(2)
- X*
- X* exit(3)
- X* fflush(3)
- X* localtime(3)
- X* printf(3)
- X* signal(3)
- X*
- X******************************************************************************/
- X
- X#include <stdio.h>
- X#include <sys/time.h>
- X#include <sys/signal.h>
- X
- X/* set FREQ to the number of microseconds to sleep between printouts
- X I try to get it so that it prints out every 0.1 seconds. Due to
- X program overhead and resource sharing, this is usually a bit less
- X than 100000 microseconds (=0.1 seconds). If you get it right, the
- X hundredths place will stay constant. */
- X
- X#define FREQ 99990
- X
- Xvoid fsleep();
- X
- X/* cheap signal handler */
- Xint
- Xhandler()
- X{
- X printf("\n");
- X exit(0);
- X}
- X
- X/******************************************************************************
- X*
- X* Main program.
- X* Just an infinite loop getting and printing out the time.
- X* Sets up a signal handler to abort on SIGINT or SIGTERM.
- X*
- X* Library routines:
- X* gettimeofday(2)
- X* fflush(3)
- X* localtime(3)
- X* printf(3)
- X* signal(3)
- X*
- X******************************************************************************/
- Xvoid
- Xmain()
- X{
- X struct tm *tp;
- X struct timeval tv;
- X struct timezone tz;
- X
- X signal( SIGINT, handler );
- X signal( SIGTERM, handler );
- X while ( 1 ){
- X gettimeofday( &tv, &tz );
- X tp = localtime(&tv.tv_sec);
- X printf("\r%02d:%02d:%02d.%02d", tp->tm_hour, tp->tm_min, tp->tm_sec,
- X tv.tv_usec/10000 );
- X fflush(stdout);
- X fsleep( (unsigned long)0, (unsigned long)FREQ );
- X }
- X}
- X
- Xstatic void
- Xfsleeptrap()
- X{
- X /* Zen function */
- X}
- X
- X/******************************************************************************
- X*
- X* FSLEEP - Fine sleep function; sleeps at resolution of the
- X* interval timer (see setitimer(2)) or microseconds; whichever
- X* is worse.
- X*
- X* Library routines:
- X* setitimer(2)
- X* sigpause(2)
- X* sigsetmask(2)
- X* signal(3)
- X*
- X******************************************************************************/
- Xvoid
- Xfsleep( secs, usecs )
- Xunsigned long secs, usecs;
- X{
- X int omask, (*osig)();
- X struct itimerval tval[2];
- X
- X /* setup */
- X osig = signal( SIGALRM, fsleeptrap );
- X
- X if ( usecs >= 1000000L ){
- X secs += usecs / 1000000L;
- X usecs %= 1000000L;
- X }
- X tval[1].it_interval.tv_sec = 0L;
- X tval[1].it_interval.tv_usec = 0L;
- X tval[1].it_value.tv_sec = secs;
- X tval[1].it_value.tv_usec = usecs;
- X
- X /* more setup */
- X omask = sigsetmask( ( 1 << (SIGALRM-1) ) );
- X setitimer( ITIMER_REAL, &tval[1], &tval[0] );
- X
- X /* wait for interrupt */
- X sigpause( 0 );
- X
- X /* cleanup */
- X signal( SIGALRM, osig );
- X setitimer( ITIMER_REAL, &tval[0], &tval[1] );
- X sigsetmask( omask );
- X
- X return;
- X}
- END_OF_FILE
- if test 2924 -ne `wc -c <'tclock.c'`; then
- echo shar: \"'tclock.c'\" unpacked with wrong size!
- fi
- # end of 'tclock.c'
- fi
- if test -f 'doadj.sh' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'doadj.sh'\"
- else
- echo shar: Extracting \"'doadj.sh'\" \(698 characters\)
- sed "s/^X//" >'doadj.sh' <<'END_OF_FILE'
- X#!/bin/sh -x
- X#
- X# This script temporarily changes tickadj and runs adjtime to fix your
- X# system time. It's only parameter is the amount of time to adjust by
- X# which is passed to adjtime.
- X#
- X# set path so that you can find tickadj and adjtime
- X#
- XPATH="$PATH:/usr/local/etc"
- X#
- X# find tick/10 so you can make large adjustments with adjtime.
- X#
- Xticka=`echo tick/D |adb -k /vmunix /dev/mem |grep tick |awk '{printf("%d\n",$2/10)}'`
- X#
- X# set tickadj to a large value and do the adjtime.
- X#
- Xtickadj -a $ticka
- Xadjtime $1
- X#
- X# sleep long enough for the adjtime to finish.
- X#
- Xtim=`echo $1 | awk '{s=$1;if(s<0){s=-1*s};printf("%d\n",((10*s)+0.5))}'`
- Xsleep $tim
- X#
- X# Restore tickadj to it's proper value.
- X#
- Xtickadj -A
- END_OF_FILE
- if test 698 -ne `wc -c <'doadj.sh'`; then
- echo shar: \"'doadj.sh'\" unpacked with wrong size!
- fi
- # end of 'doadj.sh'
- fi
- echo shar: End of shell archive.
- exit 0
-