2 * Copyright (c) 1990,1992 Regents of The University of Michigan.
3 * All Rights Reserved. See COPYRIGHT.
5 * The "timelord protocol" was reverse engineered from Timelord,
6 * distributed with CAP, Copyright (c) 1990, The University of
7 * Melbourne. The following copyright, supplied by The University
8 * of Melbourne, may apply to this code:
10 * This version of timelord.c is based on code distributed
11 * by the University of Melbourne as part of the CAP package.
13 * The tardis/Timelord package for Macintosh/CAP is
14 * Copyright (c) 1990, The University of Melbourne.
17 #include <sys/param.h>
18 #include <sys/types.h>
22 #include <netatalk/at.h>
23 #include <netatalk/endian.h>
24 #include <atalk/atp.h>
36 #define EPOCH 0x7C25B080 /* 00:00:00 GMT Jan 1, 1970 for Mac */
39 char *bad = "Bad request!";
48 if (( s = rindex( p, '/' )) == NULL ) {
53 fprintf( stderr, "Usage:\t%s -d -n nbpname\n", s );
58 * Unregister ourself on signal.
63 if ( nbp_unrgstr( server, "TimeLord", "*" ) < 0 ) {
64 syslog( LOG_ERR, "Can't unregister %s", server );
67 syslog( LOG_INFO, "going down" );
77 struct sockaddr_at sat;
78 struct atp_block atpb;
83 char hostname[ MAXHOSTNAMELEN ];
86 long req, mtime, resp;
90 if ( gethostname( hostname, sizeof( hostname )) < 0 ) {
91 perror( "gethostname" );
94 if (( server = index( hostname, '.' )) != 0 ) {
99 while (( c = getopt( ac, av, "dn:" )) != EOF ) {
108 fprintf( stderr, "Unknown option -- '%c'\n", c );
114 * Disassociate from controlling tty.
121 dt = getdtablesize();
122 for ( i = 0; i < dt; i++ ) {
125 if (( i = open( "/dev/tty", O_RDWR )) >= 0 ) {
126 (void)ioctl( i, TIOCNOTTY, 0 );
127 setpgrp( 0, getpid());
139 if (( p = rindex( *av, '/' )) == NULL ) {
146 openlog( p, LOG_PID );
148 openlog( p, LOG_NDELAY|LOG_PID, LOG_DAEMON );
151 /* allocate memory */
152 memset (&sat.sat_addr, 0, sizeof (sat.sat_addr));
154 if (( atp = atp_open( ATADDR_ANYPORT, &sat.sat_addr )) == NULL ) {
155 syslog( LOG_ERR, "main: atp_open: %m" );
159 if ( nbp_rgstr( atp_sockaddr( atp ), server, "TimeLord", "*" ) < 0 ) {
160 syslog( LOG_ERR, "Can't register %s", server );
163 syslog( LOG_INFO, "%s:TimeLord started", server );
165 sv.sv_handler = goaway;
168 if ( sigvec( SIGHUP, &sv, 0 ) < 0 ) {
169 syslog( LOG_ERR, "main: sigvec: %m" );
172 if ( sigvec( SIGTERM, &sv, 0 ) < 0 ) {
173 syslog( LOG_ERR, "main: sigvec: %m" );
179 * Something seriously wrong with atp, since these assigns must
182 atpb.atp_saddr = &sat;
183 atpb.atp_rreqdata = buf;
184 bzero( &sat, sizeof( struct sockaddr_at ));
185 atpb.atp_rreqdlen = sizeof( buf );
186 if ( atp_rreq( atp, &atpb ) < 0 ) {
187 syslog( LOG_ERR, "main: atp_rreq: %m" );
192 bcopy( p, &req, sizeof( long ));
198 if ( atpb.atp_rreqdlen > 5 ) {
199 bcopy( p + 1, &mtime, sizeof( long ));
200 mtime = ntohl( mtime );
201 syslog( LOG_INFO, "gettime from %s %s was %u",
202 (*( p + 5 ) == '\0' ) ? "<unknown>" : p + 5,
203 ( *p == 0 ) ? "at boot" : "in chooser",
206 syslog( LOG_INFO, "gettime" );
209 if ( gettimeofday( &tv, &tz ) < 0 ) {
210 syslog( LOG_ERR, "main: gettimeofday: %m" );
213 if (( tm = localtime( &tv.tv_sec )) == 0 ) {
214 perror( "localtime" );
218 mtime = tv.tv_sec + tm->tm_gmtoff + EPOCH;
219 mtime = htonl( mtime );
222 bcopy( &resp, buf, sizeof( long ));
223 bcopy( &mtime, buf + sizeof( long ), sizeof( long ));
224 iov.iov_len = sizeof( long ) + sizeof( long );
228 syslog( LOG_ERR, bad );
231 bcopy( &resp, buf, sizeof( long ));
232 *( buf + 4 ) = (unsigned char)strlen( bad );
233 strcpy( buf + 5, bad );
234 iov.iov_len = sizeof( long ) + 2 + strlen( bad );
239 atpb.atp_sresiov = &iov;
240 atpb.atp_sresiovcnt = 1;
241 if ( atp_sresp( atp, &atpb ) < 0 ) {
242 syslog( LOG_ERR, "main: atp_sresp: %m" );