Path: utzoo!utgpu!cs.utexas.edu!wuarchive!uunet!bfmny0!tneff From: tneff@bfmny0.BFM.COM (Tom Neff) Newsgroups: alt.sources Subject: Re: Program to set clock to NBS time Summary: NEWS IS FOR TEXT, SOURCE GROUPS ARE FOR SOURCE TEXT! Keywords: clock, time, set Message-ID: <39510307@bfmny0.BFM.COM> Date: 28 Dec 90 06:56:13 GMT References: <38@teqsoft.UUCP> Reply-To: tneff@bfmny0.BFM.COM (Tom Neff) Lines: 1072 In article <38@teqsoft.UUCP> jmc@teqsoft.UUCP (Jack Cloninger) writes: >Compressed uuencoded source... ###### ####### ####### ####### ####### ### # # # # # # ### # # # # # # ### ###### # # # # # # # # # # # # # # # # # ### ###### ####### ####### ####### # ### #! /bin/sh # This is a shell archive, meaning: # 1. Remove everything above the #! /bin/sh line. # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh (not csh) to create: # nbs_time.c # This archive created: Fri Dec 28 11:53:47 1990 export PATH; PATH=/bin:/usr/bin:$PATH if test -f 'nbs_time.c' then echo shar: "will not over-write existing file 'nbs_time.c'" else sed 's/^X//' << \SHAR_EOF > 'nbs_time.c' X/* CHK=0x0603 */ X/*+----------------------------------------------------------------------- X SCO XENIX SYSTEM V.2 (Others too?) X nbs_time.c -- call NBS, get time, hangup quickly, set system time, X wait for top of minute, execute /etc/setclock to update cmos clock X X Warren H. Tucker, 150 West Lake Drive, Mountain Park, GA 30075 X (404)587-5766 X X Note: must be root to execute X X Defined functions: X create_lock_file(lock_file_name) X hangup(sig) X hayes_dial() X hayes_send_cmd(cmd) X lclose() X lgetc(char_rtnd) X lgetc_timeout(timeout_msec) X lgets_timeout(lrwt) X lkill_buf() X lock_tty() X lopen() X lputc(lchar) X lputs_paced(pace_msec,string) X lrdchk() X lset_baud_rate(ioctl_flag) X lset_parity(ioctl_flag) X main(argc,argv,envp) X make_lock_name(ttyname,lock_file_name) X other_lock_name(first_lock_name) X to_lower(ch) X to_upper(ch) X ulcmpb(str1,str2) X ulindex(str1,str2) X unlock_tty() X usage() X valid_baud_rate(baud) X XSample execution: X% nbs - Xnbs_time XDialing 1(202)653-0351 ... INT to abort ... CONNECT 1200 X'47361 201 020050 UTC' XConnect time 1 second(s) XTime retrieved from standard: Mon Jul 18 22:00:50 1988 XWaiting for top of minute: Mon Jul 18 22:00:51 1988 XWaiting for top of minute: Mon Jul 18 22:00:52 1988 XWaiting for top of minute: Mon Jul 18 22:00:53 1988 XWaiting for top of minute: Mon Jul 18 22:00:54 1988 XWaiting for top of minute: Mon Jul 18 22:00:55 1988 XWaiting for top of minute: Mon Jul 18 22:00:56 1988 XWaiting for top of minute: Mon Jul 18 22:00:57 1988 XWaiting for top of minute: Mon Jul 18 22:00:58 1988 X/etc/setclock setting ... result: 0618220188 X X------------------------------------------------------------------------*/ X/*+:EDITS:*/ X/*:07-18-1988-22:07-wht-working! */ X/*:07-18-1988-17:27-wht-creation */ X X#include X#include X#include X#include X#include X#include X#include X#include X#include X#include X#include X X#ifndef ushort X#define ushort unsigned short X#endif X#ifndef uchar X#define uchar unsigned char X#endif X#ifndef uint X#define uint unsigned int X#endif X#ifndef ulong X#define ulong unsigned long X#endif X Xchar *lgets_timeout(struct lrwt *); Xchar *other_lock_name(char *); Xchar to_lower(char ); Xchar to_upper(char ); Xint create_lock_file(char *); Xint hayes_dial(void); Xint hayes_send_cmd(char *); Xint lgetc_timeout(unsigned long ); Xint lock_tty(void); Xint lopen(void); Xint lrdchk(void); Xint lset_baud_rate(int ); Xint main(int ,char * *,char * *); Xint make_lock_name(char *,char *); Xint ulcmpb(unsigned char *,unsigned char *); Xint ulindex(char *,char *); Xint valid_baud_rate(unsigned int ); Xvoid hangup(int ); Xvoid lclose(void); Xvoid lgetc(char *); Xvoid lkill_buf(void); Xvoid lputc(char ); Xvoid lputs_paced(int ,char *); Xvoid lset_parity(int ); Xvoid unlock_tty(void); X Xushort geteuid(); Xushort getuid(); Xlong nap(long); Xlong time(long *); X/* char *ctime(long *); */ X Xtypedef struct lrwt /* param to lgets_timeout in eculine.c */ X{ Xulong to1; /* timeout for 1st character (granularity 20) */ Xulong to2; /* timeout for each next char (granularity 20) */ Xint raw_flag; /* !=0, rtn full buffer, ==0, rtn filtered hayes result */ Xchar *buffer; /* buffer to fill */ Xint bufsize; /* size of buffer */ Xint count; /* from proc, count rcvd */ X} LRWT; X X#define EPOCH 40587 /* UNIX starts JD 2440587, */ X#define leap(y, m) ((y+m-1 - 70%m) / m) /* also known as 1/1/70 */ X#define TONE '*' X/* #define TIME "\n%05ld %03d %02d%02d%02d UTC" */ X#define TIME "%05ld %03d %02d%02d%02d UTC" X X/* for better source line utilization, frequent use of 'fprintf' and 'stderr' X warrants the following */ X#define pf printf X#define ff fprintf X#define se stderr X#define so stdout X X/* lopen() and related routines error codes */ X#define LOPEN_INVALID -1 /* for invalid tty name */ X#define LOPEN_UNKPID -2 /* unknown pid using line */ X#define LOPEN_LCKERR -3 /* lock file open error */ X#define LOPEN_NODEV -4 /* device does not exist */ X#define LOPEN_OPNFAIL -5 /* count not open line */ X#define LOPEN_ALREADY -6 /* line already open */ X Xextern char *revision; /* ecurev.c temp file from buildrev */ Xextern char *numeric_revision; /*ecunumrev.c */ X Xchar LLCKname[128]; /* lock file name */ Xchar Ltelno[64]; /* telephone number for remote or null */ Xchar Lline[64]; /* line name */ Xint Liofd; /* file descriptor for line */ Xint Lparity; /* 0==NONE, 'e' == even, 'o' == odd */ Xstruct termio Llv; /* attributes for the line to remote */ Xuint Lbaud; /* baud rate */ Xuint tbit_modem; /* Non-zero if Telebit modem. */ Xushort euid; Xushort uid; X X/*+------------------------------------------------------------------------- X to_upper() / to_lower() X one would think that these were relatively standard X types of thing, but MSC/Xenix specifies toupper() to convert to upper X case if not already and Unix says to adjust without testing, X so, two stupid little routines here X ASCII only -- no EBCDIC gradoo here please X--------------------------------------------------------------------------*/ Xchar to_upper(ch) Xregister char ch; X{ return( ((ch >= 'a') && (ch <= 'z')) ? ch - 0x20 : ch); X} /* end of to_upper() */ X Xchar to_lower(ch) Xregister char ch; X{ return( ((ch >= 'A') && (ch <= 'Z')) ? ch + 0x20 : ch); X} /* end of to_lower() */ X X/*+---------------------------------------------------------------------------- X ulcmpb(str1,str) -- Upper/Lower [case insensitive] Compare Bytes X X Returns -1 if strings are equal, else failing character position X If the second strings terminates with a null and both strings have matched X character for character until that point, then -1 is returned. X NOTE: this is not a test for complete equality of two strings, but allows X discovery of a string as a substring in a larger containing string. X-----------------------------------------------------------------------------*/ Xint Xulcmpb(str1,str2) Xregister unsigned char *str1; Xregister unsigned char *str2; X{ Xregister int istr; X X for( istr=0 ; ; ++istr ) X { X if(str2[istr] == '\0') /* if second string exhausts, match! */ X return(-1); X if((str1[istr] == '\0' ) || X ( to_upper(str1[istr]) != to_upper(str2[istr]) )) X return(istr); X } X /*NOTREACHED*/ X} /* end of ulcmpb */ X X/*+------------------------------------------------------------------------- X ulindex: Upper/Lower [case insensitive] Index functioni X X Returns position of 'str2' in 'str1' if found X If 'str2' is null, then 0 is returned (null matches anything) X Returns -1 if not found X X uses 'ulcmpb' X--------------------------------------------------------------------------*/ Xint ulindex(str1,str2) Xregister char *str1; /* the (target) string to search */ Xregister char *str2; /* the (comparand) string to search for */ X{ Xregister int istr1 = 0; /* moving index into str1 */ Xregister char *mstr = str1; /* moving string pointer */ X X if(str2[0] == '\0') /* null string matches anything */ X return(0); X while(1) X { X if(*mstr == '\0') /* if we exhaust target string, flunk */ X return(-1); X /* Can we find either case of first comparand char in target? */ X if( to_upper(*mstr) == to_upper(str2[0]) ) X { X /* we have a first char match... does rest of string match? */ X if(ulcmpb(mstr,str2) == -1) /* if the rest matches, ... */ X return(istr1); /* ... return match position */ X } X /* we did not match this time... increment istr1, mstr and try again */ X ++istr1; X ++mstr; X } X} /* end of ulindex */ X X/*+----------------------------------------------------------------------- X hangup(sig) -- terminate program (with comm line cleanup) X------------------------------------------------------------------------*/ Xvoid Xhangup(sig) Xint sig; X{ Xvoid lclose(); X X ff(se,"\n"); X if(Liofd != -1) X lclose(); /* close line */ X exit(sig); X} /* end of hangup */ X X/*+------------------------------------------------------------------------- X make_lock_name(ttyname,lock_file_name) X--------------------------------------------------------------------------*/ Xmake_lock_name(ttyname,lock_file_name) Xchar *ttyname; Xchar *lock_file_name; X{ Xregister int itmp; Xregister char *ttyptr; X X if((itmp = ulindex(ttyname,"/dev/tty")) != 0) X return(LOPEN_INVALID); X X itmp = ulindex(ttyname,"tty"); X X ttyptr = &ttyname[itmp]; X strcpy(lock_file_name,"/usr/spool/uucp/LCK.."); X strcat(lock_file_name,ttyptr); X return(0); X X} /* end of make_lock_name */ X X/*+----------------------------------------------------------------------- X create_lock_file() X X Returns 0 if lock file created,else error codes: X LOPEN_ if error X else pid of process currently busy on device X------------------------------------------------------------------------*/ Xcreate_lock_file(lock_file_name) Xchar *lock_file_name; X{ Xregister int fd_lockf; Xint pid; Xint old_umask; Xint erc = 0; X X old_umask = umask(0); X X if((fd_lockf = open(lock_file_name,O_CREAT | O_EXCL | O_RDWR,0666)) < 0) X { /* file already exists */ X if((fd_lockf = open(lock_file_name,O_RDWR,0666)) < 0) X { X erc = LOPEN_LCKERR; X goto RESTORE_UMASK; X } X else if(read(fd_lockf,(char *)&pid,sizeof(pid))) X { X if(kill(pid,0)) /* is owner pid already dead? */ X { X if(errno == ESRCH) /* this error sez so */ X { X pid = getpid(); /* so we will use it */ X lseek(fd_lockf,0L,0); X write(fd_lockf,(char *)&pid,sizeof(pid)); X close(fd_lockf); X erc = 0; X goto RESTORE_UMASK; X } X } X /* owner pid still active with lock */ X close(fd_lockf); X erc = pid; /* port is busy */ X goto RESTORE_UMASK; X } X else X { X close(fd_lockf); X erc = LOPEN_UNKPID; X goto RESTORE_UMASK; X } X } X pid = getpid(); X write(fd_lockf,(char *)&pid,sizeof(pid)); X X close(fd_lockf); X chmod(lock_file_name,0666); X XRESTORE_UMASK: X (void)umask(old_umask); X return(erc); X X} /* end of create_lock_file */ X X/*+------------------------------------------------------------------------- X other_lock_name(first_lock_name) X--------------------------------------------------------------------------*/ Xchar * Xother_lock_name(first_lock_name) Xchar *first_lock_name; X{ Xregister int itmp; Xstatic char other_lock_name[64]; X X strcpy(other_lock_name,first_lock_name); X itmp = strlen(other_lock_name) - 1; X if(islower(other_lock_name[itmp])) X other_lock_name[itmp] = toupper(other_lock_name[itmp]); X else if(isupper(other_lock_name[itmp])) X other_lock_name[itmp] = tolower(other_lock_name[itmp]); X X return(other_lock_name); X X} /* end of other_lock_name */ X X/*+------------------------------------------------------------------------- X lock_tty() X--------------------------------------------------------------------------*/ Xlock_tty() X{ Xregister int itmp; Xstruct stat ttystat; X X if(itmp = make_lock_name(Lline,LLCKname)) X return(itmp); X X if(stat(Lline,&ttystat) < 0) X return(LOPEN_NODEV); X X if(itmp = create_lock_file(LLCKname)) X return(itmp); X X if(itmp = create_lock_file(other_lock_name(LLCKname))) X { X unlink(LLCKname); X LLCKname[0] = 0; X return(itmp); X } X X} /* end of lock_tty */ X X/*+----------------------------------------------------------------------- X void unlock_tty() X------------------------------------------------------------------------*/ Xvoid Xunlock_tty() X{ X X if(LLCKname[0] == 0) X return; X X unlink(LLCKname); X unlink(other_lock_name(LLCKname)); X X LLCKname[0] = 0; X} /* end of unlock_tty */ X X/*+------------------------------------------------------------------------- X valid_baud_rate(baud) -- returns (positive) baud rate selector Xor -1 if invalid baud rate X--------------------------------------------------------------------------*/ Xvalid_baud_rate(baud) Xuint baud; X{ X switch(baud) X { X case 110: return(B110); X case 300: return(B300); X case 600: return(B600); X case 1200: return(B1200); X case 2400: return(B2400); X case 4800: return(B4800); X case 9600: return(B9600); X case 19200: return(EXTA); X case 38400: return(EXTB); X default: return(-1); X } X X} /* end of valid_baud_rate */ X X/*+----------------------------------------------------------------------- X lset_baud_rate(ioctl_flag) X X If 'ioctl_flag' is set,then ioctl(Liofd,TCSETA,&Llv) X is executed after setting baud rate X------------------------------------------------------------------------*/ Xlset_baud_rate(ioctl_flag) Xint ioctl_flag; X{ Xint baud_selector = valid_baud_rate(Lbaud); X X if(baud_selector < 0) X { X ff(se,"invalid baud rate: %u\n",Lbaud); X ff(se,"valid rates: 110,300,600,1200,2400,4800,9600,19200\n"); X return(1); X } X Llv.c_cflag &= ~CBAUD; X Llv.c_cflag |= baud_selector; X X if(ioctl_flag) X ioctl(Liofd,(int)TCSETA,(char *)&Llv); X return(1); X X} /* end of lset_baud_rate */ X X/*+----------------------------------------------------------------------- X lset_parity(ioctl_flag) X X If 'ioctl_flag' is set,then ioctl(Liofd,TCSETA,&Llv) X is executed after setting parity X------------------------------------------------------------------------*/ Xvoid Xlset_parity(ioctl_flag) Xint ioctl_flag; X{ X Llv.c_cflag &= ~(CS8 | PARENB | PARODD); X switch(to_lower(Lparity)) X { X case 'e': X Llv.c_cflag |= CS7 | PARENB; X Llv.c_iflag |= ISTRIP; X break; X case 'o': X Llv.c_cflag |= PARODD | CS7 | PARENB; X Llv.c_iflag |= ISTRIP; X break; X default: X ff(se,"invalid parity: %c ... defaulting to no parity\n"); X case 0: X case 'n': X Llv.c_cflag |= CS8; X Llv.c_iflag &= ~(ISTRIP); X Lparity = 0; X break; X } X X if(ioctl_flag) X ioctl(Liofd,(int)TCSETA,(char *)&Llv); X X} /* end of lset_parity */ X X/*+------------------------------------------------------------------------- X lgetc(char_rtnd) X--------------------------------------------------------------------------*/ Xvoid Xlgetc(char_rtnd) Xchar *char_rtnd; X{ X XREAD_AGAIN: X errno = 0; X if(read(Liofd,char_rtnd,1) < 1) X { X if(errno == EINTR) /* if signal interrupted, ... */ X goto READ_AGAIN; X hangup(254); X } X X} /* end of lgetc */ X X/*+------------------------------------------------------------------------- X lrdchk() -- rdchk(Liofd) X--------------------------------------------------------------------------*/ Xint Xlrdchk() X{ X return(rdchk(Liofd)); X X} /* end of lrdchk */ X X/*+----------------------------------------------------------------------- X lputc(lchar) -- write lchar to comm line X------------------------------------------------------------------------*/ Xvoid Xlputc(lchar) Xchar lchar; X{ X while(write(Liofd,&lchar,1) != 1) X { X if(errno == EINTR) X continue; X hangup(255); X } X} /* end of lputc */ X X/*+----------------------------------------------------------------------- X lputs_paced(pace_msec,string) -- write string to comm line X with time between each character X------------------------------------------------------------------------*/ Xvoid Xlputs_paced(pace_msec,string) Xregister int pace_msec; Xregister char *string; X{ Xregister long msec = (pace_msec) ? (long)pace_msec : (long)20; X X while(*string) X { X lputc(*string++); X nap(msec); X } X X} /* end of lputs_paced */ X X/*+------------------------------------------------------------------------- X char *lgets_timeout(LRWT *) X Xtypedef struct lrwt X{ Xulong to1; Xulong to2; Xint raw_flag; Xchar *buffer; Xint bufsize; Xint count; X} LRWT; X Xto1 and to2 are unsigned long values in milliseconds (not Xcurrently supported well under BSD4); to1 is the time to wait Xfor the first character, to2 the time to wait for subsequent Xcharacters. X Xif raw_flag 0, non-printables are stripped from beginning X and end of received characters (i.e., modem X response reads); NULs discarded, parity stripped Xif raw_flag 1, full raw read buffer returned Xif raw_flag 2, full buffer, NULs discarded, parity stripped X Xbuffer is address to read chars into X Xbufsize is buffer max size (allowing room for terminating null) Xwhich should be at least 2 if raw_size includes 0x80 bit, Xelse at least 12 characters if 0x80 omitted. X Xcount is a int which, at return, receives the actual count read X X--------------------------------------------------------------------------*/ Xchar * Xlgets_timeout(lrwt) XLRWT *lrwt; X{ Xregister int actual_count = 0; Xregister char *cptr = lrwt->buffer; Xint max_count = lrwt->bufsize; Xchar *rtn_val; Xint timeout_counter; Xint qc1; Xint qc2; Xlong quantum; Xlong ltmp; X X/* minimum wait is 60 msec */ X if(Lbaud < 300) X if(lrwt->to2 < 300L) lrwt->to2 = 300L; X if(Lbaud < 1200) X if(lrwt->to2 < 200L) lrwt->to2 = 200L; X else X if(lrwt->to2 < 60L) lrwt->to2 = 60L; X X/* shortest interval */ X ltmp = (lrwt->to1 < lrwt->to2) ? lrwt->to1 : lrwt->to2; X X/* calculate wait quantum */ X quantum = ltmp / 10L; /* try for ten ticks */ X if(quantum < 20L) X quantum = 20L; X qc1 = lrwt->to1 / quantum; X if(!qc1) qc1 = 1L; X qc2 = lrwt->to2 / quantum; X if(!qc2) qc2 = 1L; X X/* perform the lrtw function X input: qc1 is first nap count (for first charcters) X qc2 is 2nd nap count (for subsequent characters) X quantum is the nap period in milliseconds X cptr is char* to receive read string X max_count is max number of characters incl null X lrwt->raw_flag as described above X X output: lrwt->count is actual count of return result X lrwt->buffer is return read buffer X*/ X max_count--; /* leave room for null */ X X lrwt->raw_flag &= 0x0F; /* get rid of 0xF0 flags */ X timeout_counter = qc1; /* first timeout */ X *cptr = 0; /* init result string */ X while(timeout_counter--) X { X nap(quantum); X while(lrdchk()) X { X lgetc(cptr); X if(lrwt->raw_flag != 1) X { X *cptr &= 0x7F; X if(*cptr == 0) X continue; X } X X *++cptr = 0; X actual_count++; X if(--max_count == 0) X goto READ_LINE_POST_PROCESS; X timeout_counter = qc2; X } X } X XREAD_LINE_POST_PROCESS: X if(lrwt->raw_flag) X { X lrwt->count = actual_count; X return(lrwt->buffer); X } X cptr = lrwt->buffer; X while(((*cptr >0) && (*cptr < 0x20)) || (*cptr >= 0x7F)) X cptr++; X rtn_val = cptr; X actual_count = 0; X while(((*cptr &= 0x7F) >= 0x20) && (*cptr <= 0x7E)) X { X cptr++; X actual_count++; X } X *cptr = 0; X strcpy(lrwt->buffer,rtn_val); X lrwt->count = actual_count; X return(lrwt->buffer); X} /* end of lgets_timeout */ X X/*+------------------------------------------------------------------------- X lgetc_timeout(timeout_msec) X X reads one character from line unless timeout_msec passes with no receipt. X timeout_msec < 20 msec becomes 20 msec X return char (raw - parity bit preserved) if received, else -1 if timeout X--------------------------------------------------------------------------*/ Xint Xlgetc_timeout(timeout_msec) Xulong timeout_msec; X{ XLRWT lr; Xchar getc_buf[2]; /* room for one char + null */ X X lr.to1 = timeout_msec; X lr.to2 = timeout_msec; X lr.raw_flag = 1; /* full raw read */ X lr.buffer = getc_buf; X lr.bufsize = sizeof(getc_buf); X lgets_timeout(&lr); X return( (lr.count == 1) ? (int)getc_buf[0] : -1 ); X X} /* end of lgetc_timeout */ X X/*+------------------------------------------------------------------------- X lkill_buf() X--------------------------------------------------------------------------*/ Xvoid Xlkill_buf() X{ X ioctl(Liofd,(int)TCFLSH,(char *)2); /* flush input and output */ X} /* end of lkill_buf */ X X/*+---------------------------------------------------------------------- X lopen() Xreturns negative LOPEN_ codes if failure else positive pid using line Xelse 0 if successful open X------------------------------------------------------------------------*/ Xint Xlopen() X{ Xregister int itmp; X X if(Liofd >= 0) X return(LOPEN_ALREADY); X if(itmp = lock_tty()) /* get lock file */ X return(itmp); X Liofd = open(Lline,O_RDWR,0777); X if(Liofd < 0) X return(LOPEN_OPNFAIL); X else X { X ioctl(Liofd,(int)TCGETA,(char *)&Llv); X Llv.c_iflag = (IGNPAR | IGNBRK | IXOFF ); X Llv.c_cflag |= (CREAD | HUPCL); X Llv.c_lflag = 0; X X Llv.c_cc[VMIN] = 1; X Llv.c_cc[VTIME] = 1; X X lset_baud_rate(0); /* do not perform ioctl */ X lset_parity(1); /* do perform ioctl */ X } X X return(0); X X} /* end of lopen */ X X/*+----------------------------------------------------------------------- X lclose() X------------------------------------------------------------------------*/ Xvoid Xlclose() X{ X if(Liofd < 0) X return; X ioctl(Liofd,(int)TCGETA,(char *)&Llv); /* save initial state */ X Llv.c_cflag |= HUPCL; X ioctl(Liofd,(int)TCSETA,(char *)&Llv); X close(Liofd); X Liofd = -1; X unlock_tty(); /* kill lock file */ X X} /* end of lclose */ X X/*+------------------------------------------------------------------------- X hayes_send_cmd(cmd) X 0: success (cmd accepted) X -1: cannot talk to modem X--------------------------------------------------------------------------*/ Xhayes_send_cmd(cmd) Xchar *cmd; X{ Xregister char *cptr; Xint retry = 0; X X cptr = cmd; X lkill_buf(); X while(1) X { X lputc(0x07); /* something random */ X if(lgetc_timeout(500L) < 0) X { X if(retry) X return(-1); X retry = 1; X lputs_paced(0,"ATQ0E1V1\r"); X nap((long)1500); X lkill_buf(); X continue; X } X break; X } X while(*cptr) X { X lputc(*cptr++); X if(lgetc_timeout(500L) < 0) X return(-1); X } X lputc('\r'); X if(lgetc_timeout(500L) < 0) X return(-1); X return(0); X X} /* end of hayes_send_cmd */ X X/*+----------------------------------------------------------------------- X hayes_dial() Xreturns 1 on success (CONNECT), X 0 if failure to connect X -1 if cannot talk to modem X------------------------------------------------------------------------*/ Xint Xhayes_dial() X{ Xregister int itmp; Xchar s128[128]; Xint rtn_code = -1; /* assume fail, CONNECT will chg to zero */ Xint s7; XLRWT lr; X X s7 = 30; X if(tbit_modem) X { X strcpy(s128,"AT&FX14S52=2"); X if(itmp = hayes_send_cmd(s128)) X return(itmp); X nap(1000L); X sprintf(s128,"ATDT%s",Ltelno); X } X else X strcpy(s128,"ATV1E1S11=45DT" ); X X if(itmp = hayes_send_cmd(s128)) X return(itmp); X X nap(1000L); X/* some modems (ahem, the Hayes 2400) do not accurately honor S7 */ X lr.to1 = s7 * 3 * 1000L; X lr.to2 = 100L; X lr.raw_flag = 0; X lr.buffer = s128; X lr.bufsize = sizeof(s128); X ff(se,"Dialing %s ... INT to abort ... ",Ltelno); X fflush(se); X lgets_timeout(&lr); X if(lr.count) X ff(se,"%s\n",s128); X if(strncmp(s128,"CONNECT",7) == 0) X return(1); X return(0); X} /* end of hayes_dial */ X X/*+------------------------------------------------------------------------- X usage() X--------------------------------------------------------------------------*/ Xvoid Xusage() X{ X ff(se,"Usage: nbs_time [-][-e][-o][-n][-b#][-t#][-l][-H][-T]\n"); X ff(se,"Defaults 1200-N %s %s %s\n",Ltelno,Lline, X tbit_modem?"Telebit":"Hayes"); X ff(se," - use defaults\n"); X ff(se," -e even parity\n"); X ff(se," -o odd parity\n"); X ff(se," -n no parity\n"); X ff(se," -b# baud rate\n"); X ff(se," -t# telephone number\n"); X ff(se," -l line (/dev/tty??)\n"); X ff(se," -H Use Hayes commands\n"); X ff(se," -T Use Telebit commands\n"); X exit(253); X X} /* end of usage */ X X/*+------------------------------------------------------------------------- X main(argc,argv,envp) X X main() program forks to create rcvr process; then main() X becomes the xmtr process X------------------------------------------------------------------------*/ Xmain(argc,argv,envp) Xint argc; Xchar **argv; Xchar **envp; X{ Xchar *cptr; Xint iargv; Xint swchar; Xint itmp; XLRWT lr; Xchar rd_buf[64]; Xtime_t /*long*/ now; Xlong julian; Xlong connect_time; Xint day_of_year; Xint hour; Xint min; Xint sec; Xstruct tm *lt; X X setbuf(stderr,NULL); X setbuf(stdout,NULL); X X ff(se,"nbs_time\n"); X X/* init line variables */ X strcpy(Lline,"/dev/tty2a"); X strcpy(Ltelno,"1-202-653-0351"); X Liofd = -1; X Lbaud = 1200; X Lparity = 0; X tbit_modem = 1; X X if(argc < 2) X usage(); X X if((argc == 2) && (!strcmp(argv[1],"-"))) X ; X else X { X for(iargv = 1; iargv < argc; iargv++) X { X if(*argv[iargv] != '-') X continue; X switch(*(argv[iargv] + 1)) X { X case 'e': Lparity = 'e'; break; X case 'o': Lparity = 'o'; break; X case 'n': Lparity = 0 ; break; X case 'b': Lbaud = atoi(argv[iargv] + 2); break; X case 't': strcpy(Ltelno,argv[iargv] + 2); break; X case 'l': strcpy(Lline,argv[iargv] + 2); break; X case 'H': tbit_modem = 0; break; X case 'T': tbit_modem = 1; break; X default: usage(); X } X } X } X X uid = getuid(); X euid = geteuid(); X if((euid == 0) || (uid == 0)) /* if root running or prog text ... */ X nice(-40); X else X { X ff(se,"must be root\n"); X exit(252); X } X X signal(SIGHUP,hangup); X signal(SIGQUIT,hangup); X signal(SIGINT,hangup); X signal(SIGTERM,hangup); X X if(itmp = lopen()) X { X switch(itmp) X { X case LOPEN_INVALID: X ff(se,"invalid line name\n"); break; X case LOPEN_UNKPID: X ff(se,"unknown pid is using line\n"); break; X case LOPEN_LCKERR: X ff(se,"lock file error\n"); break; X case LOPEN_NODEV: X ff(se,"line does not exist\n"); break; X case LOPEN_ALREADY: X ff(se,"line already open\n"); break; X case LOPEN_OPNFAIL: X ff(se,"line open error\n"); break; X default: X ff(se,"pid %d using line\n",itmp); break; X } X exit(250); X } X X if(!hayes_dial()) X hangup(1); X connect_time = time((long *)0); X X for(itmp = 0; itmp < 30; itmp++) X { X if(lgetc_timeout(500L) == TONE) X break; X } X X lr.to1 = 1100L; X lr.to2 = 100L; X lr.raw_flag = 0; /* full raw read */ X lr.buffer = rd_buf; X lr.bufsize = sizeof(rd_buf); X X lgets_timeout(&lr); X X fputs("'",stdout); X fwrite(lr.buffer,1,lr.count,stdout); X fputs("'\n",stdout); X X lclose(); X fprintf(stdout,"Connect time %ld second(s)\n", X time((long *)0) - connect_time); X X if(sscanf(lr.buffer,TIME,&julian,&day_of_year,&hour,&min,&sec) != 5) X { X ff(se,"garbled result: '%s'\n",lr.buffer); X exit(240); X } X else X { X now = (((julian - EPOCH) * 24 + hour) * 60 + min) * 60 + sec; X if(stime(&now) < 0) X perror("stime"); X fputs("Time retrieved from standard: ",stdout); X fputs(ctime(&now), stdout); X lt = localtime(&now); X while(lt->tm_sec != 58) X { X nap(960L); X now = time((long *)0); X fputs("Waiting for top of minute: ",stdout); X fputs(ctime(&now), stdout); X lt = localtime(&now); X } X now += 60L; /* get top of next minute */ X lt = localtime(&now); X/* mmddhhmmyy */ X/* 0718213488 */ X X X/* The following statement was added because of a bug in the original code */ X lt->tm_mon++; X X sprintf(rd_buf,"/etc/setclock %02d%02d%02d%02d%02d", X lt->tm_mon,lt->tm_mday,lt->tm_hour,lt->tm_min,lt->tm_year); X fputs("/etc/setclock setting ... ",stdout); X system(rd_buf); X fputs("result: ",stdout); X system("/etc/setclock"); X } X exit(0); X X} /* end of main */ X X/* end of nbs_time.c */ SHAR_EOF fi exit 0 # End of shell archive