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