]> arthur.barton.de Git - netatalk.git/blob - contrib/timelord/timelord.c
bbdff1c0f1f71fbedae0b2036127bca8f61fcc5a
[netatalk.git] / contrib / timelord / timelord.c
1 /*
2  * $Id: timelord.c,v 1.7 2002-01-04 04:45:47 sibaz Exp $
3  *
4  * Copyright (c) 1990,1992 Regents of The University of Michigan.
5  * All Rights Reserved. See COPYRIGHT.
6  *
7  * The "timelord protocol" was reverse engineered from Timelord,
8  * distributed with CAP, Copyright (c) 1990, The University of
9  * Melbourne.  The following copyright, supplied by The University
10  * of Melbourne, may apply to this code:
11  *
12  *      This version of timelord.c is based on code distributed
13  *      by the University of Melbourne as part of the CAP package.
14  *
15  *      The tardis/Timelord package for Macintosh/CAP is
16  *      Copyright (c) 1990, The University of Melbourne.
17  */
18
19 #ifdef HAVE_CONFIG_H
20 #include "config.h"
21 #endif /* HAVE_CONFIG_H */
22
23 #include <sys/param.h>
24 #include <sys/types.h>
25 #include <sys/time.h>
26 #include <sys/file.h>
27 #include <sys/uio.h>
28
29 #include <unistd.h>
30
31 #include <netatalk/at.h>
32 #include <netatalk/endian.h>
33 #include <atalk/atp.h>
34 #include <atalk/nbp.h>
35
36 #include <time.h>
37 #ifdef HAVE_SGTTY_H
38 #include <sgtty.h>
39 #endif /* HAVE_SGTTY_H */
40 #include <errno.h>
41 #include <signal.h>
42 #pragma warn "testing 123"
43 #include <atalk/logger.h>
44 #include <stdio.h>
45 #include <string.h>
46 #ifdef HAVE_NETDB_H
47 #include <netdb.h>
48 #endif /* HAVE_NETDB_H */
49
50 #ifdef HAVE_FCNTL_H
51 #include <fcntl.h>
52 #endif /* HAVE_FCNTL_H */
53 #ifdef HAVE_SYS_FCNTL_H
54 #include <sys/fcntl.h>
55 #endif /* HAVE_SYS_FCNTL_H */
56
57 #ifdef HAVE_TERMIOS_H
58 #include <termios.h>
59 #endif /* HAVE_TERMIOS_H */
60 #ifdef HAVE_SYS_TERMIOS_H
61 #include <sys/termios.h>
62 #endif /* HAVE_SYS_TERMIOS_H */
63
64 #define TL_GETTIME      0
65 #define TL_OK           12
66 #define TL_BAD          10
67 #define EPOCH           0x7C25B080      /* 00:00:00 GMT Jan 1, 1970 for Mac */
68
69 int     debug = 0;
70 char    *bad = "Bad request!";
71 char    buf[ 4624 ];
72 char    *server;
73
74 void usage( char *p )
75 {
76     char        *s;
77
78     if (( s = rindex( p, '/' )) == NULL ) {
79         s = p;
80     } else {
81         s++;
82     }
83     fprintf( stderr, "Usage:\t%s -d -n nbpname\n", s );
84     exit( 1 );
85 }
86
87 /*
88  * Unregister ourself on signal.
89  */
90 void
91 goaway(int signal)
92 {
93     if ( nbp_unrgstr( server, "TimeLord", "*", NULL ) < 0 ) {
94         LOG(log_error, logtype_default, "Can't unregister %s", server );
95         exit( 1 );
96     }
97     LOG(log_info, logtype_default, "going down" );
98     exit( 0 );
99 }
100
101 int main( int ac, char **av )
102 {
103     ATP                 atp;
104     struct sockaddr_at  sat;
105     struct atp_block    atpb;
106     struct timeval      tv;
107     struct timezone     tz;
108     struct iovec        iov;
109     struct tm           *tm;
110     char                hostname[ MAXHOSTNAMELEN ];
111     char                *p;
112     int                 c;
113     long                req, mtime, resp;
114     extern char         *optarg;
115     extern int          optind;
116
117     if ( gethostname( hostname, sizeof( hostname )) < 0 ) {
118         perror( "gethostname" );
119         exit( 1 );
120     }
121     if (( server = index( hostname, '.' )) != 0 ) {
122         *server = '\0';
123     }
124     server = hostname;
125
126     while (( c = getopt( ac, av, "dn:" )) != EOF ) {
127         switch ( c ) {
128         case 'd' :
129             debug++;
130             break;
131         case 'n' :
132             server = optarg;
133             break;
134         default :
135             fprintf( stderr, "Unknown option -- '%c'\n", c );
136             usage( *av );
137         }
138     }
139
140     /*
141      * Disassociate from controlling tty.
142      */
143     if ( !debug ) {
144         int             i, dt;
145
146         switch ( fork()) {
147         case 0 :
148             dt = getdtablesize();
149             for ( i = 0; i < dt; i++ ) {
150                 (void)close( i );
151             }
152             if (( i = open( "/dev/tty", O_RDWR )) >= 0 ) {
153                 (void)ioctl( i, TIOCNOTTY, 0 );
154                 setpgid( 0, getpid());
155                 (void)close( i );
156             }
157             break;
158         case -1 :
159             perror( "fork" );
160             exit( 1 );
161         default :
162             exit( 0 );
163         }
164     }
165
166     if (( p = rindex( *av, '/' )) == NULL ) {
167         p = *av;
168     } else {
169         p++;
170     }
171
172 #ifdef ultrix
173     openlog( p, LOG_PID );
174 #else /* ultrix */
175     set_processname(p);
176     syslog_setup(log_debug, logtype_default, logoption_ndelay|logoption_pid, logfacility_daemon );
177 #endif /* ultrix */
178
179     /* allocate memory */
180     memset (&sat.sat_addr, 0, sizeof (sat.sat_addr));
181
182     if (( atp = atp_open( ATADDR_ANYPORT, &sat.sat_addr )) == NULL ) {
183         LOG(log_error, logtype_default, "main: atp_open: %s", strerror( errno ) );
184         exit( 1 );
185     }
186
187     if ( nbp_rgstr( atp_sockaddr( atp ), server, "TimeLord", "*" ) < 0 ) {
188         LOG(log_error, logtype_default, "Can't register %s", server );
189         exit( 1 );
190     }
191     LOG(log_info, logtype_default, "%s:TimeLord started", server );
192
193         signal(SIGHUP, goaway);
194         signal(SIGTERM, goaway);
195
196     for (;;) {
197         /*
198          * Something seriously wrong with atp, since these assigns must
199          * be in the loop...
200          */
201         atpb.atp_saddr = &sat;
202         atpb.atp_rreqdata = buf;
203         bzero( &sat, sizeof( struct sockaddr_at ));
204         atpb.atp_rreqdlen = sizeof( buf );
205         if ( atp_rreq( atp, &atpb ) < 0 ) {
206             LOG(log_error, logtype_default, "main: atp_rreq: %s", strerror( errno ) );
207             exit( 1 );
208         }
209
210         p = buf;
211         bcopy( p, &req, sizeof( long ));
212         req = ntohl( req );
213         p += sizeof( long );
214
215         switch( req ) {
216         case TL_GETTIME :
217             if ( atpb.atp_rreqdlen > 5 ) {
218                     bcopy( p + 1, &mtime, sizeof( long ));
219                     mtime = ntohl( mtime );
220                     LOG(log_info, logtype_default, "gettime from %s %s was %lu",
221                             (*( p + 5 ) == '\0' ) ? "<unknown>" : p + 5,
222                             ( *p == 0 ) ? "at boot" : "in chooser",
223                             mtime );
224             } else {
225                     LOG(log_info, logtype_default, "gettime" );
226             }
227
228             if ( gettimeofday( &tv, &tz ) < 0 ) {
229                 LOG(log_error, logtype_default, "main: gettimeofday: %s", strerror( errno ) );
230                 exit( 1 );
231             }
232             if (( tm = gmtime( &tv.tv_sec )) == 0 ) {
233                 perror( "localtime" );
234                 exit( 1 );
235             }
236
237             mtime = tv.tv_sec + EPOCH;
238             mtime = htonl( mtime );
239
240             resp = TL_OK;
241             bcopy( &resp, buf, sizeof( long ));
242             bcopy( &mtime, buf + sizeof( long ), sizeof( long ));
243             iov.iov_len = sizeof( long ) + sizeof( long );
244             break;
245
246         default :
247             LOG(log_error, logtype_default, bad );
248
249             resp = TL_BAD;
250             bcopy( &resp, buf, sizeof( long ));
251             *( buf + 4 ) = (unsigned char)strlen( bad );
252             strcpy( buf + 5, bad );
253             iov.iov_len = sizeof( long ) + 2 + strlen( bad );
254             break;
255         }
256
257         iov.iov_base = buf;
258         atpb.atp_sresiov = &iov;
259         atpb.atp_sresiovcnt = 1;
260         if ( atp_sresp( atp, &atpb ) < 0 ) {
261             LOG(log_error, logtype_default, "main: atp_sresp: %s", strerror( errno ) );
262             exit( 1 );
263         }
264     }
265 }