• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-WNDR4500v2-V1.0.0.60_1.0.38/ap/gpl/timemachine/netatalk-2.2.0/contrib/timelord/
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
70int	debug = 0;
71char	*bad = "Bad request!";
72char	buf[ 4624 ];
73char	*server;
74
75void 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 */
91void
92goaway(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
102int 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}
267