Radix cross Linux

The main Radix cross Linux repository contains the build scripts of packages, which have the most complete and common functionality for desktop machines

452 Commits   2 Branches   1 Tag
     5         kx /*
     5         kx                             NO WARRANTY
     5         kx 
     5         kx     THERE IS NO WARRANTY FOR THIS PROGRAM, TO THE EXTENT PERMITTED BY
     5         kx   APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
     5         kx   HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
     5         kx   OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
     5         kx   THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     5         kx   PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
     5         kx   IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
     5         kx   ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
     5         kx 
     5         kx   IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL
     5         kx   ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
     5         kx   REDISTRIBUTE THE PROGRAM, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
     5         kx   GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
     5         kx   USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
     5         kx   DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
     5         kx   PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
     5         kx   EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
     5         kx   SUCH DAMAGES.
     5         kx 
     5         kx  */
     5         kx 
     5         kx #ifndef lint
     5         kx 	char sccsid[]="@(#) netdate.c 1.16 85/08/21";
     5         kx #endif
     5         kx #include <sys/param.h>
     5         kx #include <sys/stat.h>
     5         kx #include <sys/ioctl.h>
     5         kx #include <sys/socket.h>
     5         kx #include <time.h>
     5         kx 
     5         kx #include <netinet/in.h>
     5         kx 
     5         kx #include <fcntl.h>
     5         kx #include <string.h>
     5         kx #include <stdlib.h>
     5         kx #include <unistd.h>
     5         kx #include <stdio.h>
     5         kx #include <netdb.h>
     5         kx #include <setjmp.h>
     5         kx #include <signal.h>
     5         kx #include <utmp.h>
     5         kx #define WTMP "/var/log/wtmp"
     5         kx 
     5         kx #ifndef __GLIBC__
     5         kx struct utmp wtmp[2] = {
     5         kx 	{ 0, 0, "|", "", 0, "", "", 0},
     5         kx 	{ 0, 0, "{", "", 0, "", "", 0}
     5         kx };
     5         kx #else
     5         kx struct utmp wtmp[2] = {
     5         kx   { 0, 0, "|", "", "", "", {0, 0}, 0, {0, 0}, {0, 0, 0, 0}, "" },
     5         kx   { 0, 0, "|", "", "", "", {0, 0}, 0, {0, 0}, {0, 0, 0, 0}, "" },
     5         kx };
     5         kx #endif
     5         kx 
     5         kx char *service = "time";
     5         kx char *defaultproto = "udp";
     5         kx /* difference between 1900 (RFC868) and 1970 (UNIX) base times */
     5         kx #define NETBASE  2208988800u
     5         kx 
     5         kx long limit = 5;
     5         kx #define MAXHOSTS 20
     5         kx 
     5         kx #define LOCALHOST "localhost"
     5         kx char *whoami;
     5         kx char hostname[65];
     5         kx struct timeval now;
     5         kx struct timehost {
     5         kx 	char *hostname;
     5         kx 	short local;
     5         kx 	short bad;
     5         kx 	char *protoname;
     5         kx 	long protonumber;
     5         kx 	int socktype;
     5         kx 	struct timeval asked;
     5         kx 	struct timeval then;
     5         kx 	struct timeval acked;
     5         kx 	long difference;
     5         kx 	long count;
     5         kx } timehosts[MAXHOSTS];
     5         kx struct timehost *tophost = &timehosts[MAXHOSTS];
     5         kx 
     5         kx void	usage (void);
     5         kx int	setproto (char *, struct timehost *);
     5         kx int	getdiff (struct timehost *);
     5         kx int	getdate (struct timehost *);
     5         kx void	printit (struct timehost *);
     5         kx void	tvsub (struct timeval *, struct timeval *, struct timeval *);
     5         kx void	printdiff (char *, struct timeval *);
     5         kx void	timeout (int);
     5         kx long	getport (char *protoname);
     5         kx 
     5         kx static int internettime (struct timehost *thishost);
     5         kx struct timehost *mungediffs(struct timehost *);
     5         kx 
     5         kx 
     5         kx void
     5         kx usage (void)
     5         kx {
     5         kx 	fprintf (stderr,
     5         kx "usage: %s [ -l limit ] host ...\n"
     5         kx "%s tries to find a group of at least two hosts whose times agree\n"
     5         kx "within %ld seconds, and sets the time to that of the first host in the group.\n",
     5         kx 		whoami, whoami, limit);
     5         kx 	fprintf (stderr,
     5         kx "The limit may be set with the -l option.  Setting it to zero (or supplying\n"
     5         kx "only one host name argument) will set the time to that of the first host to\n"
     5         kx "respond. The caller must be super-user for the system time to be set.\n");
     5         kx 
     5         kx 	exit (1);
     5         kx }
     5         kx 
     5         kx int rdate = 0;
     5         kx int verbose = 0;
     5         kx int debug = 0;
     5         kx 
     5         kx int
     5         kx main (int argc, char **argv)
     5         kx {
     5         kx 	register struct timehost *thishost;
     5         kx 	int hostargs = 0;
     5         kx 
     5         kx 	/* skip warning: unused argc */
     5         kx 	argc = argc;
     5         kx 
     5         kx 	if ((whoami = rindex(*argv, '/')) != NULL)
     5         kx 		whoami++;
     5         kx 	else
     5         kx 		whoami = *argv;
     5         kx 	if (strcmp (whoami, "rdate") == 0) {	/* emulate SMI rdate command */
     5         kx 		rdate = 1;
     5         kx 		defaultproto = "tcp";
     5         kx 		limit = 0;
     5         kx 	}
     5         kx 	if (gethostname(hostname, (int)sizeof (hostname)) == -1) {
     5         kx 		perror ("gethostname");
     5         kx 		exit (1);
     5         kx 	}
     5         kx 	while (*++argv != NULL && **argv == '-') {
     5         kx 		switch (argv[0][1]) {
     5         kx 		case 'd':
     5         kx 			debug++;
     5         kx 			break;
     5         kx 		case 'v':
     5         kx 			verbose++;
     5         kx 			break;
     5         kx 		case 'l':
     5         kx 			if (*++argv == NULL)
     5         kx 				usage();
     5         kx 			limit = atoi(*argv);
     5         kx 			break;
     5         kx 		default:
     5         kx 			fprintf (stderr, "Unknown option:  %s\n", *argv);
     5         kx 			usage();
     5         kx 			break;
     5         kx 		}
     5         kx 	}
     5         kx 	if (*argv == NULL)
     5         kx 		usage();
     5         kx 	if (debug)
     5         kx 		fprintf (stderr, "%s: rdate %d; verbose %d; limit %ld.\n",
     5         kx 			whoami, rdate, verbose, limit);
     5         kx 	for (thishost = &timehosts[0]; *argv != NULL; argv++) {
     5         kx 		if (thishost >= tophost) {
     5         kx 			fprintf(stderr, "Too many hosts: ignoring");
     5         kx 			do {
     5         kx 				fprintf (stderr, " %s", *argv);
     5         kx 			} while (*++argv != NULL);
     5         kx 			fprintf (stderr, "\n");
     5         kx 			break;
     5         kx 		}
     5         kx 		if (setproto(*argv, thishost))
     5         kx 			continue;
     5         kx 		thishost -> hostname = *argv;
     5         kx 		thishost -> bad = 0;
     5         kx 		if (strcmp (thishost -> hostname, LOCALHOST) == 0)
     5         kx 			thishost -> local = 1;
     5         kx 		if (++hostargs == 1 && argv[1] == NULL)	/* Only one host arg, */
     5         kx 			limit = 0;			/* so just set to it. */
     5         kx 		if (limit == 0) {
     5         kx 			if (!getdate(thishost))
     5         kx 				continue;
     5         kx 			exit(0);
     5         kx 		}
     5         kx 		if (!getdiff (thishost))
     5         kx 			continue;
     5         kx 		thishost++;
     5         kx 	}
     5         kx 	if (limit == 0)
     5         kx 		exit(1);
     5         kx 	if (thishost == &timehosts[0])
     5         kx 		exit(1);
     5         kx 	if ((thishost = mungediffs(thishost)) == NULL) {
     5         kx 		fprintf (stderr,
     5         kx 			"No two hosts agree on the time within %ld seconds\n",
     5         kx 			limit);
     5         kx 		exit(1);
     5         kx 	}
     5         kx 	if (!getdate (thishost))
     5         kx 		exit (1);
     5         kx 	exit(0);
     5         kx }
     5         kx 
     5         kx int
     5         kx setproto(char *what, struct timehost *thishost)
     5         kx {
     5         kx 	static	char *protoname;
     5         kx 	static	long protonumber;
     5         kx 	static	int socktype;
     5         kx 	register struct protoent *pp;
     5         kx 
     5         kx 	setprotoent(1);
     5         kx 	if ((pp = getprotobyname (what)) == NULL) {
     5         kx 		if (protoname == NULL)
     5         kx 			if (!setproto(defaultproto, thishost)) {
     5         kx 				fprintf(stderr,
     5         kx 		"Default protocol %s was not found in /etc/protocols.\n",
     5         kx 						defaultproto);
     5         kx 				exit(1);
     5         kx 			}
     5         kx 		thishost -> protoname = protoname;
     5         kx 		thishost -> protonumber = protonumber;
     5         kx 		thishost -> socktype = socktype;
     5         kx 		return(0);
     5         kx 	}
     5         kx 	protoname = what;	/*pp -> p_name;	this is static:  don't use it.*/
     5         kx 	protonumber = pp -> p_proto;
     5         kx 	switch (protonumber) {
     5         kx 		case IPPROTO_TCP:
     5         kx 			socktype = SOCK_STREAM;
     5         kx 			if (debug)
     5         kx 				fprintf(stderr, "%s SOCK_STREAM\n", protoname);
     5         kx 			break;
     5         kx 		case IPPROTO_UDP:
     5         kx 			socktype = SOCK_DGRAM;
     5         kx 			if (debug)
     5         kx 				fprintf(stderr, "%s SOCK_DGRAM\n", protoname);
     5         kx 			break;
     5         kx 		default:
     5         kx 			fprintf(stderr, "Unknown protocol:  %s\n", protoname);
     5         kx 			exit(1);
     5         kx 			break;
     5         kx 	}
     5         kx 	return(1);
     5         kx }
     5         kx 
     5         kx int
     5         kx getdiff(struct timehost *thishost)
     5         kx {
     5         kx 	if (!internettime (thishost))
     5         kx 		return(0);
     5         kx 	thishost -> difference = thishost -> then.tv_sec - now.tv_sec;
     5         kx 	if (!rdate)
     5         kx 		printit(thishost);
     5         kx 	return(1);
     5         kx }
     5         kx 
     5         kx 
     5         kx /*
     5         kx 	Find the largest group of hosts which agree within the limit
     5         kx 	and return the first of that group.  If no two hosts agree,
     5         kx 	give up.
     5         kx  */
     5         kx 
     5         kx struct timehost *
     5         kx mungediffs(struct timehost *tophost)
     5         kx {
     5         kx 	register struct timehost *thishost, *ahost, *goodhost;
     5         kx 	long diff;
     5         kx 
     5         kx 	tophost--;	/* simplifies the comparisons */
     5         kx 	goodhost = &timehosts[0];
     5         kx 	for (thishost = &timehosts[0]; thishost < tophost; thishost++) {
     5         kx 		if (thishost -> bad)
     5         kx 			continue;
     5         kx 		thishost -> count = 1;
     5         kx 		if (verbose)
     5         kx 			printf ("%s", thishost -> hostname);
     5         kx 		for (ahost = thishost + 1; ahost <= tophost; ahost++) {
     5         kx 			if (thishost -> bad)
     5         kx 				continue;
     5         kx 			diff = ahost -> difference - thishost -> difference;
     5         kx 			if (abs(diff) < limit) {
     5         kx 				thishost -> count++;
     5         kx 				if (verbose)
     5         kx 					printf (" %s", ahost -> hostname);
     5         kx 			}
     5         kx 		}
     5         kx 		if (verbose) {
     5         kx 			printf (" %ld\n", thishost -> count);
     5         kx 			(void)fflush(stdout);
     5         kx 		}
     5         kx 		if (thishost -> count > goodhost -> count)
     5         kx 			goodhost = thishost;
     5         kx 	}
     5         kx 	if (goodhost -> count > 1)
     5         kx 		return(goodhost);
     5         kx 	return(NULL);
     5         kx }
     5         kx 
     5         kx int
     5         kx getdate (struct timehost *thishost)
     5         kx {
     5         kx 	int set = 0;
     5         kx 
     5         kx 	if (!internettime (thishost))
     5         kx 		return (0);
     5         kx 	if (thishost -> local) {
     5         kx 		printf ("Local host %s has best time, so not setting date\n",
     5         kx 			hostname);
     5         kx 		printit(thishost);
     5         kx 		exit(0);
     5         kx 	}
     5         kx 	if (limit != 0
     5         kx 	&& abs((thishost -> then.tv_sec - now.tv_sec) - thishost -> difference)
     5         kx 	    > limit) {
     5         kx 		fprintf (stderr,
     5         kx 		"Time from %s has varied more than the limit of %ld seconds\n",
     5         kx 			thishost -> hostname, limit);
     5         kx 		printit(thishost);
     5         kx 		exit(1);
     5         kx 	}
     5         kx 	if (settimeofday (&thishost -> then, (struct timezone *)0) == -1)
     5         kx 		perror ("netdate: settimeofday");
     5         kx 	else {
     5         kx 		int wf;
     5         kx 		if ((wf = open(WTMP, 1)) >= 0) {
     5         kx 			wtmp[0].ut_time = now.tv_sec;
     5         kx 			wtmp[1].ut_time = thishost -> then.tv_sec;
     5         kx 			(void)lseek(wf, 0L, 2);
     5         kx 			(void)write(wf, (char *)wtmp, sizeof(wtmp));
     5         kx 			(void)close(wf);
     5         kx 		}
     5         kx 		set = 1;
     5         kx 	}
     5         kx 	printit(thishost);
     5         kx 	return(set);
     5         kx }
     5         kx 
     5         kx void
     5         kx printit(struct timehost *thishost)
     5         kx {
     5         kx 	struct tm *tp;
     5         kx 	struct timeval diff;
     5         kx 	char newstring[128];
     5         kx 
     5         kx 	if (rdate)
     5         kx 		printf ("%s", ctime((const time_t *)&thishost -> then.tv_sec));
     5         kx 	else {
     5         kx 		(void)sprintf(newstring, "%s ", thishost -> hostname);
     5         kx 		tvsub(&diff, &thishost -> then, &now);
     5         kx 		printdiff(&newstring[strlen(newstring)], &diff);
     5         kx 		printf ("%-24s %.19s.%03ld", newstring,
     5         kx 			ctime((const time_t *)&thishost -> then.tv_sec),
     5         kx 				thishost -> then.tv_usec / 1000);
     5         kx 		if (verbose) {
     5         kx 			tp = localtime((const time_t *)&thishost -> acked);
     5         kx 			printf(" at %02d:%02d:%02d.%03ld",
     5         kx 				tp -> tm_hour, tp -> tm_min, tp -> tm_sec,
     5         kx 				thishost -> acked.tv_usec / 1000);
     5         kx 			tvsub(&diff, &thishost -> acked, &thishost -> asked);
     5         kx 			printdiff(newstring, &diff);
     5         kx 			printf(" delay %s", newstring);
     5         kx 		}
     5         kx 		printf("\n");
     5         kx 	}
     5         kx 	(void)fflush (stdout);
     5         kx }
     5         kx 
     5         kx void
     5         kx tvsub(tdiff, t1, t0)
     5         kx struct timeval *tdiff, *t1, *t0;
     5         kx {
     5         kx 	tdiff->tv_sec = t1->tv_sec - t0->tv_sec;
     5         kx 	tdiff->tv_usec = t1->tv_usec - t0->tv_usec;
     5         kx 	if (tdiff->tv_sec < 0 && tdiff->tv_usec > 0)
     5         kx 		tdiff->tv_sec++, tdiff->tv_usec -= 1000000;
     5         kx 	if (tdiff->tv_sec > 0 && tdiff->tv_usec < 0)
     5         kx 		tdiff->tv_sec--, tdiff->tv_usec += 1000000;
     5         kx }
     5         kx 
     5         kx void
     5         kx printdiff(char *where, struct timeval *diff)
     5         kx {
     5         kx 	(void) sprintf (where, "%c%d.%.03d",
     5         kx 		(diff->tv_sec < 0 || diff->tv_usec < 0) ? '-' : '+',
     5         kx 		abs(diff->tv_sec), abs(diff->tv_usec) / 1000);
     5         kx }
     5         kx 
     5         kx static	jmp_buf jb;
     5         kx void
     5         kx timeout( int arg )
     5         kx {
     5         kx 	arg = arg;
     5         kx 	longjmp(jb, 1);
     5         kx }
     5         kx 
     5         kx static int
     5         kx internettime (struct timehost *thishost)
     5         kx {
     5         kx 	register struct hostent *hp;
     5         kx 	struct sockaddr_in sin;
     5         kx 	long port;
     5         kx 	int nread;
     5         kx 	static int s = -1;
     5         kx 
     5         kx 	if (thishost -> local) {
     5         kx 		if (gettimeofday (&now, (struct timezone *)0) == -1) {
     5         kx 			perror ("netdate: gettimeofday");
     5         kx 			exit (1);
     5         kx 		}
     5         kx 		thishost -> asked = now;
     5         kx 		thishost -> then = now;
     5         kx 		thishost -> acked = now;
     5         kx 		return(1);
     5         kx 	}
     5         kx 	timerclear(&thishost -> then);
     5         kx 	if (setjmp(jb))
     5         kx 		goto bad;
     5         kx 	(void)signal(SIGALRM, timeout);
     5         kx 	if (s != -1)
     5         kx 		(void) close (s), s = -1;
     5         kx 	port = getport(thishost -> protoname);
     5         kx 	bzero((char *)&sin, sizeof (sin));
     5         kx 	sethostent(1);
     5         kx 	if ((hp = gethostbyname(thishost -> hostname)) == NULL) {
     5         kx 		fprintf(stderr, "%s: %s: unknown host\n",
     5         kx 			whoami, thishost -> hostname);
     5         kx 		goto out;
     5         kx 	}
     5         kx 	sin.sin_family = hp->h_addrtype;
     5         kx 	(void)alarm(20);
     5         kx 	s = socket(hp->h_addrtype, thishost -> socktype, 0 /*protonumber*/);
     5         kx 	if (s < 0) {
     5         kx 		perror("netdate: socket");
     5         kx 		(void)alarm(0);
     5         kx 		goto out;
     5         kx 	}
     5         kx 	if (thishost -> socktype == SOCK_STREAM) {
     5         kx 		if (bind(s, (struct sockaddr *)&sin, sizeof (sin)) < 0) {
     5         kx 			perror("netdate: bind");
     5         kx 			goto bad;
     5         kx 		}
     5         kx 	}
     5         kx 	bcopy(hp->h_addr, (char *)&sin.sin_addr, hp->h_length);
     5         kx 	sin.sin_port = port;
     5         kx 	(void)gettimeofday (&thishost -> asked, (struct timezone *)0);
     5         kx 	if (connect(s, (struct sockaddr *)&sin, sizeof (sin)) < 0) {
     5         kx 		perror("netdate: connect");
     5         kx 		goto bad;
     5         kx 	}
     5         kx 
     5         kx 	if (thishost -> socktype == SOCK_DGRAM) {
     5         kx 		if (send (s, "\n", 1, 0) < 0) {
     5         kx 			perror ("netdate: send");
     5         kx 			goto bad;
     5         kx 		}
     5         kx 	}
     5         kx 	nread = recv (s, (char *)&thishost -> then, sizeof (thishost -> then), 0);
     5         kx 	(void)gettimeofday (&thishost -> acked, (struct timezone *)0);
     5         kx 	(void)alarm(0);
     5         kx 	now = thishost -> acked;
     5         kx 
     5         kx 	if (nread != 4) {
     5         kx 		perror ("netdate: read");
     5         kx 		goto bad;
     5         kx 	}
     5         kx 
     5         kx 	/* RFC 868 only allows seconds, but what the hell */
     5         kx 	if (nread == sizeof(thishost -> then))
     5         kx 		thishost -> then.tv_usec = ntohl(thishost -> then.tv_usec);
     5         kx 	else
     5         kx 		thishost -> then.tv_usec = 0L;
     5         kx 	thishost -> then.tv_sec = ntohl (thishost -> then.tv_sec) - NETBASE;
     5         kx 	return (1);	/* don't close before returning to avoid delays */
     5         kx bad:
     5         kx 	(void)alarm(0);
     5         kx 	(void) close (s), s = -1;
     5         kx out:
     5         kx 	if (gettimeofday (&now, (struct timezone *)0) == -1) {
     5         kx 		perror ("netdate: gettimeofday");
     5         kx 		exit (1);
     5         kx 	}
     5         kx 	thishost -> asked = now;
     5         kx 	thishost -> then = now;
     5         kx 	thishost -> acked = now;
     5         kx 	thishost -> bad = 1;
     5         kx 	fprintf (stderr, "Connection with %s to %s failed.\n",
     5         kx 		thishost -> protoname, thishost -> hostname);
     5         kx 	return(0);
     5         kx }
     5         kx 
     5         kx long
     5         kx getport(char *protoname)
     5         kx {
     5         kx 	register struct servent *sp;
     5         kx 	static long port;
     5         kx 
     5         kx 	if (port != 0)
     5         kx 		return(port);
     5         kx 	if ((sp = getservbyname(service, protoname)) == 0) {
     5         kx 		fprintf(stderr, "%s: %s/%s: unknown service\n",
     5         kx 			whoami, service, protoname);
     5         kx 		exit(1);
     5         kx 	}
     5         kx 	return (port = sp->s_port);
     5         kx }