Time Services from the U.S. Naval Observatory
Stephen Friedl and Ed Schaefer
As a system administrator one of your many tasks is
setting the system
time. To automate this task, a client machine could
call a remote
(or server) system, obtain the time from the server,
set the time on the client. This article addresses a
C utility, utc
(Listing 1), which calls the U.S. Naval Observatory
(USNO), in Washington
D.C. (1-202-653-0351), to obtain as accurate a time
as is available
The USNO Time Format
The USNO provides time data once per second in the format
Figure 1. The Julian Date measures the number of days
mean noon 1 January 4713 B.C. on the Julian proleptic
corresponds to the period of the earliest known astronomical
and forms a common starting point for numerous time
and date systems.
The Modified Julian Date (MJD) provided by the Observatory
JD minus 240000.5 (the ".5" shifts the start
of a measured
day from noon to midnight). Since both UNIX and USNO
keep time using
Greenwich Mean Time (GMT), time zones are eliminated.
The Systems File
Since this utility uses the ubiquitous Call UNIX utility,
you first set up the UNIX Systems file for the USNO
and a speed of 1200 bits per second:
usno Nvr ACU 1200 1-202-653-0351
This entry attaches a phone number and speed to a system
name -- the typical login information is not required
won't be using this. Speeds above 1200 bits per second
are not supported;
they would be counterproductive in any case because
of the increased
delays inherent in the way commonly used error control
The utc Utility Options
The options for utc are:
-s-- specify to set system time via stime()
-c sysn -- specify system name to dial via
Systems file (usno in our definition)
-D nn -- specify debug level
-d -- don't route cu's stderr
to /dev/null (for debug)
If no options are specified, no cu is spawned and the
is printed internally in the USNO minute format.
Executing the cu Command
The heart of the utc utility is creating a pipe between
cu command and the shell, using the popen() function
call. (For more information on programming the pipe,
the UNIX Pipe in C," Sys Admin, July/August 1993).
cu command is actually piped in the cu_open() function
and a FILE pointer is returned to the calling set_time()
function. After cu connects, the routine reads output
USNO using the normal stream reading function, fgets().
cu_open() also makes the utc utility a process group
leader via the setpgrp() function call. Since cu typically
spawns an extra process (one for reading, one for writing),
a self-contained process group makes it easier to terminate
involved in setting the time should this be necessary.
implementation of setpgrp() on your system -- some UNIX
variants use setsid().)
Parsing the USNO Output String
After the connection is made to USNO, the convert_to_time()
function parses the line from USNO format and returns
the UNIX time,
defined as the number of seconds since midnight 01/01/1970.
returns 0 for the marker and an error if the five expected
fields can not be parsed. utc assumes the UNIX time
when five valid times are received sequentially, each
being one second
greater than the prior time. The marker line is ignored
in the count
and is not considered an error condition.
The alarm() function is set so that utc will terminate
within 60 seconds if no valid input is received. If
a valid UNIX time, utc kills the cu child processes
with the kill() function, and closes the USNO pipe using
Finally, if the set-system-time option is on, the system
is set to the time received from USNO. Before calling
however, utc compares the old system time to the new
The most obvious error condition is a user other than
to set the system time.
The utc utility obtains the GMT time from the USNO
and optionally sets system time, but the error checking
A time-range-check-in-hours option could prove useful
change the time if the proposed change from USNO is
more than a certain
number of minutes or hours).
Also, a clever system administrator could set the utc
up as part of a timeserver account for others to use,
the need for a long-distance telephone call to Washington,
Curry, David A. Using C on the UNIX System.
Sebastopol, CA: O'Reilly & Associates, 1989.
About the Authors
Stephen Friedl is an independent software and network
in Tustin, California, and has been working with C and
his first exposure on a Z8000 machine in 1981. He develops
software, does training and system administration, and
is a volunteer
tutor of English as a second language to a cool group
He can be reached via email at email@example.com.
Ed Schaefer is a frequent contributer to Sys Admin.
He is an Informix software developer and UNIX system
administrator at jeTECH Data Systems of Moorpark, CA,
where he develops
Time and Attendance Software. He can be reached at firstname.lastname@example.org.