Program to set clock to NBS time
Tom Neff
tneff at bfmny0.BFM.COM
Fri Dec 28 17:56:13 AEST 1990
In article <38 at teqsoft.UUCP> jmc at 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 <stdio.h>
X#include <signal.h>
X#include <ctype.h>
X#include <sys/types.h>
X#include <sys/stat.h>
X#include <sys/ioctl.h>
X#include <time.h>
X#include <string.h>
X#include <fcntl.h>
X#include <errno.h>
X#include <termio.h>
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<name>][-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<name> 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
More information about the Alt.sources
mailing list