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