Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Posting-Version: version B 2.10.1 6/24/83; site bu-cs.UUCP Path: utzoo!watmath!clyde!burl!ulysses!allegra!mit-eddie!genrad!panda!talcott!harvard!bu-cs!root From: root@bu-cs.UUCP (Barry Shein) Newsgroups: net.sources Subject: Re: new setdate (source for a B.U. 4.2bsd version) Message-ID: <209@bu-cs.UUCP> Date: Sun, 3-Mar-85 17:39:35 EST Article-I.D.: bu-cs.209 Posted: Sun Mar 3 17:39:35 1985 Date-Received: Tue, 5-Mar-85 01:47:32 EST References: <413@unisoft.UUCP> Organization: Boston Univ Comp. Sci. Lines: 228 This made me think of something we use here that I wrote. It is only useful to those running TCP/IP (4.2bsd) although I suppose it could be adapted to some other net. Look at it a bit before relying on it, it is very simple: Rdate just execs itself on a remote system to generate a string which, when passed to system() will set the local time. Some will consider this too naive to be relied on as a remote time-server which is technically true but it is going to be more accurate than just looking at your watch. By accurate I mean: Will bring two systems into very close time which may or may not be the correct time. --------------------CUT HERE: /usr/man/man8/rdate.8-------------------- .TH RDATE 8L "20 Aug 1984" .UC 4 .SH NAME rdate \- remote date and time service .SH SYNOPSIS .B rdate [ .B \-h host ] [ .B \-u user ] [ .B \-p passwd ] [ .B \-s ] [ .B \-t ] .SH DESCRIPTION .I Rdate sets the system's date and time by querying another system over the network. .PP The .I host should default to a reasonable value or can be overridden with the .B \-h flag followed by the host name. Obviously this other host must also have this service. .PP You must be logged in as the super-user in order to set the date on the current system. Unfortunately, you must not be logged in as the super-user in order to access the remote system (these are both intentional features.) .PP To get around this you must specify a non-privileged user name and password for an account on the remote machine. This can be done either on the command line via the .B \-u and .B \-p commands for .I user and .I password respectively or, if either is missing, you will be prompted from the terminal. It is probably better to let .B rdate prompt for the password as it is more secure (it will not echo.) .PP The .B \-s flag is for server mode and causes .B rdate to simply put out the system's current date and time in a format that can be executed to set the date and time. This is the form that is used on the remote machine by the local .B rdate. .PP If the .B \-t flag is used .B rdate only prints the date command to the standard output rather than actually setting the date. This could be useful to check that the remote system has a reasonable date before actually setting it. .SH FILES /etc/hosts .br /etc/services .SH SEE ALSO rsh(1C), rexec(3X) .SH AUTHOR Barry Shein, Boston University Distributed Systems Group --------------------CUT HERE rdate.c-------------------- #include#include #include /* * Very simple remote date routine for 4.2bsd * Barry Shein, Boston University * * The basic idea is that in one mode rdate remote-execs * a copy of rdate on another machine with an appropiate * flag. This remote rdate will produce the string for a * UNIX date command which, when locally exec'd, will * set the date. * Net delays are not taken into account. */ #define RDATE "/etc/rdate -s" #define DEFHOST "bu-cs" /* YOUR REMOTE HOST HERE */ char *myname ; int tflag = 0 ; usage() { fprintf(stderr, "Usage: %s [-s][-h host][-u user][-p passwd]\n",myname) ; exit(1) ; } main(argc,argv) int argc ; char **argv ; { struct servent *s ; char *host = NULL, *user = NULL, *passwd = NULL ; char buf[BUFSIZ] ; int rfd, i ; char *getpass() ; myname = *argv ; --argc ; while(argc--) { ++argv ; if(**argv == '-') switch((*argv)[1]) { case 'h' : /* other remote host */ if(argc < 1) usage() ; host = *++argv ; --argc ; break ; case 'u' : /* user name to rexec under */ if(argc < 1) usage() ; user = *++argv ; --argc ; break ; case 'p' : /* passwd to rexec under */ /* note: if omitted will use getpass */ if(argc < 1) usage() ; passwd = *++argv ; --argc ; break ; case 's' : /* I am the remote */ rdate() ; exit(0) ; case 't' : /* just testing */ ++tflag ; break ; default : usage() ; } else usage() ; } if(host == NULL) host = DEFHOST ; if(user == NULL) { printf("(%s) User: ",host) ; gets(buf) ; user = (char *) malloc(strlen(buf)+1) ; strcpy(user,buf) ; } if(passwd == NULL) { sprintf(buf,"(%s) Password: ",host) ; passwd = getpass(buf) ; } if((s = getservbyname("exec","tcp")) == NULL) { perror("exec/tcp") ; exit(1) ; } if((rfd = rexec(&host,s->s_port,user,passwd,RDATE,(int *)0)) < 0) { perror("rexec") ; exit(1) ; } if((i = read(rfd,buf,BUFSIZ)) <= 0) { fprintf(stderr,"protocol failure\n") ; exit(1) ; } buf[i] = '\0' ; /* * Should probably be some error checking * at the minimum, did we get a 'date' command * back? */ if(tflag) { i = 0 ; fputs(buf,stdout) ; } else i = system(buf) ; exit(i) ; } /* * Rdate - just generate a UNIX date command for 'now' * on the standard output */ rdate() { long int d ; struct tm *t, *localtime() ; d = time(0) ; t = localtime(&d) ; printf("date %02d%02d%02d%02d%02d.%02d\n", t->tm_year,t->tm_mon+1,t->tm_mday, t->tm_hour,t->tm_min,t->tm_sec) ; }