sandy@turnkey.TCC.COM (Sanford 'Sandy' Zelkovitz) (07/21/88)
The following is a program which was uploaded to my BBS which causes your computer to call the National Bureau of Standards and retrieve the exact time. It then calls /etc/setclock and updates your system clock. Please note that this program, to the best of my knowledge, only runs under SCO Xenix. Sanford ( Sandy ) Zelkovitz XBBS - 714-898-8634 P.S. The way that I compiled the code, under Xenix286, is as follows: cc -Mm2e -O nbs_time.c -lx -o nbs_time ----------------------- cut here for nbs_time.c ---------------------------- /* CHK=0x0603 */ /*+----------------------------------------------------------------------- SCO XENIX SYSTEM V.2 (Others too?) nbs_time.c -- call NBS, get time, hangup quickly, set system time, wait for top of minute, execute /etc/setclock to update cmos clock Warren H. Tucker, 150 West Lake Drive, Mountain Park, GA 30075 (404)587-5766 Note: must be root to execute Defined functions: create_lock_file(lock_file_name) hangup(sig) hayes_dial() hayes_send_cmd(cmd) lclose() lgetc(char_rtnd) lgetc_timeout(timeout_msec) lgets_timeout(lrwt) lkill_buf() lock_tty() lopen() lputc(lchar) lputs_paced(pace_msec,string) lrdchk() lset_baud_rate(ioctl_flag) lset_parity(ioctl_flag) main(argc,argv,envp) make_lock_name(ttyname,lock_file_name) other_lock_name(first_lock_name) to_lower(ch) to_upper(ch) ulcmpb(str1,str2) ulindex(str1,str2) unlock_tty() usage() valid_baud_rate(baud) Sample execution: % nbs - nbs_time Dialing 1(202)653-0351 ... INT to abort ... CONNECT 1200 '47361 201 020050 UTC' Connect time 1 second(s) Time retrieved from standard: Mon Jul 18 22:00:50 1988 Waiting for top of minute: Mon Jul 18 22:00:51 1988 Waiting for top of minute: Mon Jul 18 22:00:52 1988 Waiting for top of minute: Mon Jul 18 22:00:53 1988 Waiting for top of minute: Mon Jul 18 22:00:54 1988 Waiting for top of minute: Mon Jul 18 22:00:55 1988 Waiting for top of minute: Mon Jul 18 22:00:56 1988 Waiting for top of minute: Mon Jul 18 22:00:57 1988 Waiting for top of minute: Mon Jul 18 22:00:58 1988 /etc/setclock setting ... result: 0618220188 ------------------------------------------------------------------------*/ /*+:EDITS:*/ /*:07-18-1988-22:07-wht-working! */ /*:07-18-1988-17:27-wht-creation */ #include <stdio.h> #include <signal.h> #include <ctype.h> #include <sys/types.h> #include <sys/stat.h> #include <sys/ioctl.h> #include <time.h> #include <string.h> #include <fcntl.h> #include <errno.h> #include <termio.h> #ifndef ushort #define ushort unsigned short #endif #ifndef uchar #define uchar unsigned char #endif #ifndef uint #define uint unsigned int #endif #ifndef ulong #define ulong unsigned long #endif char *lgets_timeout(struct lrwt *); char *other_lock_name(char *); char to_lower(char ); char to_upper(char ); int create_lock_file(char *); int hayes_dial(void); int hayes_send_cmd(char *); int lgetc_timeout(unsigned long ); int lock_tty(void); int lopen(void); int lrdchk(void); int lset_baud_rate(int ); int main(int ,char * *,char * *); int make_lock_name(char *,char *); int ulcmpb(unsigned char *,unsigned char *); int ulindex(char *,char *); int valid_baud_rate(unsigned int ); void hangup(int ); void lclose(void); void lgetc(char *); void lkill_buf(void); void lputc(char ); void lputs_paced(int ,char *); void lset_parity(int ); void unlock_tty(void); ushort geteuid(); ushort getuid(); long nap(long); long time(long *); char *ctime(long *); typedef struct lrwt /* param to lgets_timeout in eculine.c */ { ulong to1; /* timeout for 1st character (granularity 20) */ ulong to2; /* timeout for each next char (granularity 20) */ int raw_flag; /* !=0, rtn full buffer, ==0, rtn filtered hayes result */ char *buffer; /* buffer to fill */ int bufsize; /* size of buffer */ int count; /* from proc, count rcvd */ } LRWT; #define EPOCH 40587 /* UNIX starts JD 2440587, */ #define leap(y, m) ((y+m-1 - 70%m) / m) /* also known as 1/1/70 */ #define TONE '*' /* #define TIME "\n%05ld %03d %02d%02d%02d UTC" */ #define TIME "%05ld %03d %02d%02d%02d UTC" /* for better source line utilization, frequent use of 'fprintf' and 'stderr' warrants the following */ #define pf printf #define ff fprintf #define se stderr #define so stdout /* lopen() and related routines error codes */ #define LOPEN_INVALID -1 /* for invalid tty name */ #define LOPEN_UNKPID -2 /* unknown pid using line */ #define LOPEN_LCKERR -3 /* lock file open error */ #define LOPEN_NODEV -4 /* device does not exist */ #define LOPEN_OPNFAIL -5 /* count not open line */ #define LOPEN_ALREADY -6 /* line already open */ extern char *revision; /* ecurev.c temp file from buildrev */ extern char *numeric_revision; /*ecunumrev.c */ char LLCKname[128]; /* lock file name */ char Ltelno[64]; /* telephone number for remote or null */ char Lline[64]; /* line name */ int Liofd; /* file descriptor for line */ int Lparity; /* 0==NONE, 'e' == even, 'o' == odd */ struct termio Llv; /* attributes for the line to remote */ uint Lbaud; /* baud rate */ ushort euid; ushort uid; /*+------------------------------------------------------------------------- to_upper() / to_lower() one would think that these were relatively standard types of thing, but MSC/Xenix specifies toupper() to convert to upper case if not already and Unix says to adjust without testing, so, two stupid little routines here ASCII only -- no EBCDIC gradoo here please --------------------------------------------------------------------------*/ char to_upper(ch) register char ch; { return( ((ch >= 'a') && (ch <= 'z')) ? ch - 0x20 : ch); } /* end of to_upper() */ char to_lower(ch) register char ch; { return( ((ch >= 'A') && (ch <= 'Z')) ? ch + 0x20 : ch); } /* end of to_lower() */ /*+---------------------------------------------------------------------------- ulcmpb(str1,str) -- Upper/Lower [case insensitive] Compare Bytes Returns -1 if strings are equal, else failing character position If the second strings terminates with a null and both strings have matched character for character until that point, then -1 is returned. NOTE: this is not a test for complete equality of two strings, but allows discovery of a string as a substring in a larger containing string. -----------------------------------------------------------------------------*/ int ulcmpb(str1,str2) register unsigned char *str1; register unsigned char *str2; { register int istr; for( istr=0 ; ; ++istr ) { if(str2[istr] == '\0') /* if second string exhausts, match! */ return(-1); if((str1[istr] == '\0' ) || ( to_upper(str1[istr]) != to_upper(str2[istr]) )) return(istr); } /*NOTREACHED*/ } /* end of ulcmpb */ /*+------------------------------------------------------------------------- ulindex: Upper/Lower [case insensitive] Index functioni Returns position of 'str2' in 'str1' if found If 'str2' is null, then 0 is returned (null matches anything) Returns -1 if not found uses 'ulcmpb' --------------------------------------------------------------------------*/ int ulindex(str1,str2) register char *str1; /* the (target) string to search */ register char *str2; /* the (comparand) string to search for */ { register int istr1 = 0; /* moving index into str1 */ register char *mstr = str1; /* moving string pointer */ if(str2[0] == '\0') /* null string matches anything */ return(0); while(1) { if(*mstr == '\0') /* if we exhaust target string, flunk */ return(-1); /* Can we find either case of first comparand char in target? */ if( to_upper(*mstr) == to_upper(str2[0]) ) { /* we have a first char match... does rest of string match? */ if(ulcmpb(mstr,str2) == -1) /* if the rest matches, ... */ return(istr1); /* ... return match position */ } /* we did not match this time... increment istr1, mstr and try again */ ++istr1; ++mstr; } } /* end of ulindex */ /*+----------------------------------------------------------------------- hangup(sig) -- terminate program (with comm line cleanup) ------------------------------------------------------------------------*/ void hangup(sig) int sig; { void lclose(); ff(se,"\n"); if(Liofd != -1) lclose(); /* close line */ exit(sig); } /* end of hangup */ /*+------------------------------------------------------------------------- make_lock_name(ttyname,lock_file_name) --------------------------------------------------------------------------*/ make_lock_name(ttyname,lock_file_name) char *ttyname; char *lock_file_name; { register int itmp; register char *ttyptr; if((itmp = ulindex(ttyname,"/dev/tty")) != 0) return(LOPEN_INVALID); itmp = ulindex(ttyname,"tty"); ttyptr = &ttyname[itmp]; strcpy(lock_file_name,"/usr/spool/uucp/LCK.."); strcat(lock_file_name,ttyptr); return(0); } /* end of make_lock_name */ /*+----------------------------------------------------------------------- create_lock_file() Returns 0 if lock file created,else error codes: LOPEN_ if error else pid of process currently busy on device ------------------------------------------------------------------------*/ create_lock_file(lock_file_name) char *lock_file_name; { register int fd_lockf; int pid; int old_umask; int erc = 0; old_umask = umask(0); if((fd_lockf = open(lock_file_name,O_CREAT | O_EXCL | O_RDWR,0666)) < 0) { /* file already exists */ if((fd_lockf = open(lock_file_name,O_RDWR,0666)) < 0) { erc = LOPEN_LCKERR; goto RESTORE_UMASK; } else if(read(fd_lockf,(char *)&pid,sizeof(pid))) { if(kill(pid,0)) /* is owner pid already dead? */ { if(errno == ESRCH) /* this error sez so */ { pid = getpid(); /* so we will use it */ lseek(fd_lockf,0L,0); write(fd_lockf,(char *)&pid,sizeof(pid)); close(fd_lockf); erc = 0; goto RESTORE_UMASK; } } /* owner pid still active with lock */ close(fd_lockf); erc = pid; /* port is busy */ goto RESTORE_UMASK; } else { close(fd_lockf); erc = LOPEN_UNKPID; goto RESTORE_UMASK; } } pid = getpid(); write(fd_lockf,(char *)&pid,sizeof(pid)); close(fd_lockf); chmod(lock_file_name,0666); RESTORE_UMASK: (void)umask(old_umask); return(erc); } /* end of create_lock_file */ /*+------------------------------------------------------------------------- other_lock_name(first_lock_name) --------------------------------------------------------------------------*/ char * other_lock_name(first_lock_name) char *first_lock_name; { register int itmp; static char other_lock_name[64]; strcpy(other_lock_name,first_lock_name); itmp = strlen(other_lock_name) - 1; if(islower(other_lock_name[itmp])) other_lock_name[itmp] = toupper(other_lock_name[itmp]); else if(isupper(other_lock_name[itmp])) other_lock_name[itmp] = tolower(other_lock_name[itmp]); return(other_lock_name); } /* end of other_lock_name */ /*+------------------------------------------------------------------------- lock_tty() --------------------------------------------------------------------------*/ lock_tty() { register int itmp; struct stat ttystat; if(itmp = make_lock_name(Lline,LLCKname)) return(itmp); if(stat(Lline,&ttystat) < 0) return(LOPEN_NODEV); if(itmp = create_lock_file(LLCKname)) return(itmp); if(itmp = create_lock_file(other_lock_name(LLCKname))) { unlink(LLCKname); LLCKname[0] = 0; return(itmp); } } /* end of lock_tty */ /*+----------------------------------------------------------------------- void unlock_tty() ------------------------------------------------------------------------*/ void unlock_tty() { if(LLCKname[0] == 0) return; unlink(LLCKname); unlink(other_lock_name(LLCKname)); LLCKname[0] = 0; } /* end of unlock_tty */ /*+------------------------------------------------------------------------- valid_baud_rate(baud) -- returns (positive) baud rate selector or -1 if invalid baud rate --------------------------------------------------------------------------*/ valid_baud_rate(baud) uint baud; { switch(baud) { case 110: return(B110); case 300: return(B300); case 600: return(B600); case 1200: return(B1200); case 2400: return(B2400); case 4800: return(B4800); case 9600: return(B9600); case 19200: return(EXTA); case 38400: return(EXTB); default: return(-1); } } /* end of valid_baud_rate */ /*+----------------------------------------------------------------------- lset_baud_rate(ioctl_flag) If 'ioctl_flag' is set,then ioctl(Liofd,TCSETA,&Llv) is executed after setting baud rate ------------------------------------------------------------------------*/ lset_baud_rate(ioctl_flag) int ioctl_flag; { int baud_selector = valid_baud_rate(Lbaud); if(baud_selector < 0) { ff(se,"invalid baud rate: %u\n",Lbaud); ff(se,"valid rates: 110,300,600,1200,2400,4800,9600,19200\n"); return(1); } Llv.c_cflag &= ~CBAUD; Llv.c_cflag |= baud_selector; if(ioctl_flag) ioctl(Liofd,(int)TCSETA,(char *)&Llv); return(1); } /* end of lset_baud_rate */ /*+----------------------------------------------------------------------- lset_parity(ioctl_flag) If 'ioctl_flag' is set,then ioctl(Liofd,TCSETA,&Llv) is executed after setting parity ------------------------------------------------------------------------*/ void lset_parity(ioctl_flag) int ioctl_flag; { Llv.c_cflag &= ~(CS8 | PARENB | PARODD); switch(to_lower(Lparity)) { case 'e': Llv.c_cflag |= CS7 | PARENB; Llv.c_iflag |= ISTRIP; break; case 'o': Llv.c_cflag |= PARODD | CS7 | PARENB; Llv.c_iflag |= ISTRIP; break; default: ff(se,"invalid parity: %c ... defaulting to no parity\n"); case 0: case 'n': Llv.c_cflag |= CS8; Llv.c_iflag &= ~(ISTRIP); Lparity = 0; break; } if(ioctl_flag) ioctl(Liofd,(int)TCSETA,(char *)&Llv); } /* end of lset_parity */ /*+------------------------------------------------------------------------- lgetc(char_rtnd) --------------------------------------------------------------------------*/ void lgetc(char_rtnd) char *char_rtnd; { READ_AGAIN: errno = 0; if(read(Liofd,char_rtnd,1) < 1) { if(errno == EINTR) /* if signal interrupted, ... */ goto READ_AGAIN; hangup(254); } } /* end of lgetc */ /*+------------------------------------------------------------------------- lrdchk() -- rdchk(Liofd) --------------------------------------------------------------------------*/ int lrdchk() { return(rdchk(Liofd)); } /* end of lrdchk */ /*+----------------------------------------------------------------------- lputc(lchar) -- write lchar to comm line ------------------------------------------------------------------------*/ void lputc(lchar) char lchar; { while(write(Liofd,&lchar,1) != 1) { if(errno == EINTR) continue; hangup(255); } } /* end of lputc */ /*+----------------------------------------------------------------------- lputs_paced(pace_msec,string) -- write string to comm line with time between each character ------------------------------------------------------------------------*/ void lputs_paced(pace_msec,string) register int pace_msec; register char *string; { register long msec = (pace_msec) ? (long)pace_msec : (long)20; while(*string) { lputc(*string++); nap(msec); } } /* end of lputs_paced */ /*+------------------------------------------------------------------------- char *lgets_timeout(LRWT *) typedef struct lrwt { ulong to1; ulong to2; int raw_flag; char *buffer; int bufsize; int count; } LRWT; to1 and to2 are unsigned long values in milliseconds (not currently supported well under BSD4); to1 is the time to wait for the first character, to2 the time to wait for subsequent characters. if raw_flag 0, non-printables are stripped from beginning and end of received characters (i.e., modem response reads); NULs discarded, parity stripped if raw_flag 1, full raw read buffer returned if raw_flag 2, full buffer, NULs discarded, parity stripped buffer is address to read chars into bufsize is buffer max size (allowing room for terminating null) which should be at least 2 if raw_size includes 0x80 bit, else at least 12 characters if 0x80 omitted. count is a int which, at return, receives the actual count read --------------------------------------------------------------------------*/ char * lgets_timeout(lrwt) LRWT *lrwt; { register int actual_count = 0; register char *cptr = lrwt->buffer; int max_count = lrwt->bufsize; char *rtn_val; int timeout_counter; int qc1; int qc2; long quantum; long ltmp; /* minimum wait is 60 msec */ if(Lbaud < 300) if(lrwt->to2 < 300L) lrwt->to2 = 300L; if(Lbaud < 1200) if(lrwt->to2 < 200L) lrwt->to2 = 200L; else if(lrwt->to2 < 60L) lrwt->to2 = 60L; /* shortest interval */ ltmp = (lrwt->to1 < lrwt->to2) ? lrwt->to1 : lrwt->to2; /* calculate wait quantum */ quantum = ltmp / 10L; /* try for ten ticks */ if(quantum < 20L) quantum = 20L; qc1 = lrwt->to1 / quantum; if(!qc1) qc1 = 1L; qc2 = lrwt->to2 / quantum; if(!qc2) qc2 = 1L; /* perform the lrtw function input: qc1 is first nap count (for first charcters) qc2 is 2nd nap count (for subsequent characters) quantum is the nap period in milliseconds cptr is char* to receive read string max_count is max number of characters incl null lrwt->raw_flag as described above output: lrwt->count is actual count of return result lrwt->buffer is return read buffer */ max_count--; /* leave room for null */ lrwt->raw_flag &= 0x0F; /* get rid of 0xF0 flags */ timeout_counter = qc1; /* first timeout */ *cptr = 0; /* init result string */ while(timeout_counter--) { nap(quantum); while(lrdchk()) { lgetc(cptr); if(lrwt->raw_flag != 1) { *cptr &= 0x7F; if(*cptr == 0) continue; } *++cptr = 0; actual_count++; if(--max_count == 0) goto READ_LINE_POST_PROCESS; timeout_counter = qc2; } } READ_LINE_POST_PROCESS: if(lrwt->raw_flag) { lrwt->count = actual_count; return(lrwt->buffer); } cptr = lrwt->buffer; while(((*cptr >0) && (*cptr < 0x20)) || (*cptr >= 0x7F)) cptr++; rtn_val = cptr; actual_count = 0; while(((*cptr &= 0x7F) >= 0x20) && (*cptr <= 0x7E)) { cptr++; actual_count++; } *cptr = 0; strcpy(lrwt->buffer,rtn_val); lrwt->count = actual_count; return(lrwt->buffer); } /* end of lgets_timeout */ /*+------------------------------------------------------------------------- lgetc_timeout(timeout_msec) reads one character from line unless timeout_msec passes with no receipt. timeout_msec < 20 msec becomes 20 msec return char (raw - parity bit preserved) if received, else -1 if timeout --------------------------------------------------------------------------*/ int lgetc_timeout(timeout_msec) ulong timeout_msec; { LRWT lr; char getc_buf[2]; /* room for one char + null */ lr.to1 = timeout_msec; lr.to2 = timeout_msec; lr.raw_flag = 1; /* full raw read */ lr.buffer = getc_buf; lr.bufsize = sizeof(getc_buf); lgets_timeout(&lr); return( (lr.count == 1) ? (int)getc_buf[0] : -1 ); } /* end of lgetc_timeout */ /*+------------------------------------------------------------------------- lkill_buf() --------------------------------------------------------------------------*/ void lkill_buf() { ioctl(Liofd,(int)TCFLSH,(char *)2); /* flush input and output */ } /* end of lkill_buf */ /*+---------------------------------------------------------------------- lopen() returns negative LOPEN_ codes if failure else positive pid using line else 0 if successful open ------------------------------------------------------------------------*/ int lopen() { register int itmp; if(Liofd >= 0) return(LOPEN_ALREADY); if(itmp = lock_tty()) /* get lock file */ return(itmp); Liofd = open(Lline,O_RDWR,0777); if(Liofd < 0) return(LOPEN_OPNFAIL); else { ioctl(Liofd,(int)TCGETA,(char *)&Llv); Llv.c_iflag = (IGNPAR | IGNBRK | IXOFF ); Llv.c_cflag |= (CREAD | HUPCL); Llv.c_lflag = 0; Llv.c_cc[VMIN] = 1; Llv.c_cc[VTIME] = 1; lset_baud_rate(0); /* do not perform ioctl */ lset_parity(1); /* do perform ioctl */ } return(0); } /* end of lopen */ /*+----------------------------------------------------------------------- lclose() ------------------------------------------------------------------------*/ void lclose() { if(Liofd < 0) return; ioctl(Liofd,(int)TCGETA,(char *)&Llv); /* save initial state */ Llv.c_cflag |= HUPCL; ioctl(Liofd,(int)TCSETA,(char *)&Llv); close(Liofd); Liofd = -1; unlock_tty(); /* kill lock file */ } /* end of lclose */ /*+------------------------------------------------------------------------- hayes_send_cmd(cmd) 0: success (cmd accepted) -1: cannot talk to modem --------------------------------------------------------------------------*/ hayes_send_cmd(cmd) char *cmd; { register char *cptr; int retry = 0; cptr = cmd; lkill_buf(); while(1) { lputc(0x07); /* something random */ if(lgetc_timeout(500L) < 0) { if(retry) return(-1); retry = 1; lputs_paced(0,"ATQ0E1V1\r"); nap((long)1500); lkill_buf(); continue; } break; } while(*cptr) { lputc(*cptr++); if(lgetc_timeout(500L) < 0) return(-1); } lputc('\r'); if(lgetc_timeout(500L) < 0) return(-1); return(0); } /* end of hayes_send_cmd */ /*+----------------------------------------------------------------------- hayes_dial() returns 1 on success (CONNECT), 0 if failure to connect -1 if cannot talk to modem ------------------------------------------------------------------------*/ int hayes_dial() { register int itmp; char s128[128]; int rtn_code = -1; /* assume fail, CONNECT will chg to zero */ int s7; LRWT lr; s7 = 30; strcpy(s128,"ATV1E1S11=45DT" ); strcat(s128,Ltelno); if(itmp = hayes_send_cmd(s128)) return(itmp); /* some modems (ahem, the Hayes 2400) do not accurately honor S7 */ lr.to1 = s7 * 3 * 1000L; lr.to2 = 100L; lr.raw_flag = 0; lr.buffer = s128; lr.bufsize = sizeof(s128); ff(se,"Dialing %s ... INT to abort ... ",Ltelno); fflush(se); lgets_timeout(&lr); if(lr.count) ff(se,"%s\n",s128); if(strncmp(s128,"CONNECT",7) == 0) return(1); return(0); } /* end of hayes_dial */ /*+------------------------------------------------------------------------- usage() --------------------------------------------------------------------------*/ void usage() { ff(se,"Usage: nbs_time [-][-e][-o][-n][-b#][-t#]\n"); ff(se,"Defaults 1200-N %s %s\n",Ltelno,Lline); ff(se," - use defaults\n"); ff(se," -e even parity\n"); ff(se," -o odd parity\n"); ff(se," -n no parity\n"); ff(se," -b# baud rate\n"); ff(se," -t# telephone number\n"); ff(se," -l<name> line (/dev/tty??)\n"); exit(253); } /* end of usage */ /*+------------------------------------------------------------------------- main(argc,argv,envp) main() program forks to create rcvr process; then main() becomes the xmtr process ------------------------------------------------------------------------*/ main(argc,argv,envp) int argc; char **argv; char **envp; { char *cptr; int iargv; int swchar; int itmp; LRWT lr; char rd_buf[64]; long now; long julian; long connect_time; int day_of_year; int hour; int min; int sec; struct tm *lt; setbuf(stderr,NULL); setbuf(stdout,NULL); ff(se,"nbs_time\n"); /* init line variables */ strcpy(Lline,"/dev/tty1a"); strcpy(Ltelno,"1(202)653-0351"); Liofd = -1; Lbaud = 1200; Lparity = 0; if(argc < 2) usage(); if((argc == 2) && (!strcmp(argv[1],"-"))) ; else { for(iargv = 1; iargv < argc; iargv++) { if(*argv[iargv] != '-') continue; switch(*(argv[iargv] + 1)) { case 'e': Lparity = 'e'; break; case 'o': Lparity = 'o'; break; case 'n': Lparity = 0 ; break; case 'b': Lbaud = atoi(argv[iargv] + 2); break; case 't': strcpy(Ltelno,argv[iargv] + 2); break; case 'l': strcpy(Lline,argv[iargv] + 2); break; default: usage(); } } } uid = getuid(); euid = geteuid(); if((euid == 0) || (uid == 0)) /* if root running or prog text ... */ nice(-40); else { ff(se,"must be root\n"); exit(252); } signal(SIGHUP,hangup); signal(SIGQUIT,hangup); signal(SIGINT,hangup); signal(SIGTERM,hangup); if(itmp = lopen()) { switch(itmp) { case LOPEN_INVALID: ff(se,"invalid line name\n"); break; case LOPEN_UNKPID: ff(se,"unknown pid is using line\n"); break; case LOPEN_LCKERR: ff(se,"lock file error\n"); break; case LOPEN_NODEV: ff(se,"line does not exist\n"); break; case LOPEN_ALREADY: ff(se,"line already open\n"); break; case LOPEN_OPNFAIL: ff(se,"line open error\n"); break; default: ff(se,"pid %d using line\n",itmp); break; } exit(250); } if(!hayes_dial()) hangup(1); connect_time = time((long *)0); for(itmp = 0; itmp < 30; itmp++) { if(lgetc_timeout(500L) == TONE) break; } lr.to1 = 1100L; lr.to2 = 100L; lr.raw_flag = 0; /* full raw read */ lr.buffer = rd_buf; lr.bufsize = sizeof(rd_buf); lgets_timeout(&lr); fputs("'",stdout); fwrite(lr.buffer,1,lr.count,stdout); fputs("'\n",stdout); lclose(); fprintf(stdout,"Connect time %ld second(s)\n", time((long *)0) - connect_time); if(sscanf(lr.buffer,TIME, &julian, &day_of_year, &hour, &min, &sec) != 5) { ff(se,"garbled result: '%s'\n",lr.buffer); exit(240); } else { now = (((julian - EPOCH) * 24 + hour) * 60 + min) * 60 + sec; if(stime(&now) < 0) perror("stime"); fputs("Time retrieved from standard: ",stdout); fputs(ctime(&now), stdout); lt = localtime(&now); while(lt->tm_sec != 58) { nap(960L); now = time((long *)0); fputs("Waiting for top of minute: ",stdout); fputs(ctime(&now), stdout); lt = localtime(&now); } now += 60L; /* get top of next minute */ lt = localtime(&now); /* mmddhhmmyy */ /* 0718213488 */ sprintf(rd_buf,"/etc/setclock %02d%02d%02d%02d%02d", lt->tm_mon,lt->tm_mday,lt->tm_hour,lt->tm_min,lt->tm_year); fputs("/etc/setclock setting ... ",stdout); system(rd_buf); fputs("result: ",stdout); system("/etc/setclock"); } exit(0); } /* end of main */ /* end of nbs_time.c */