[alt.sources] Program to set clock to NBS time

jmc@teqsoft.UUCP (Jack Cloninger) (12/27/90)

I am posting this for a friend from the SCO Mailing List who does not
have access to this newsgroup (Joe Huffman). Joe was responding to the
following request from another party on the mailing list.  The
following is the text of Joe's original posting and the uuencoded and
compressed source for nbs_time.c which sets the local computer time to
the time supplied by a dial-up connection to a Time Standards system.
It is written for SCO Xenix, but should be adaptable to other environments.
Disclaimer: I have neither tried not tested this software and pass it
on only as a service to the usenet community.


>From: Joe Huffman <joe@proto.com>
>Date: Tue, 25 Dec 90 9:39:06 PST
>Subject: nbs_time
>
>	I remember a program floating around a LONG time ago that would
>	dial up the Time Standards system (cannot remember the real name,
>	but they keep the standard time for everyone) using a modem
>	and then it recieves the correct time from them and resets the local
>	time on the computer for you.
>	
>	I would like to get such a program now that I have a need for it :)
>	
>	I remember one that working on UNIX (SCO Xenix to be more exact if I 
>	remember correctly, but have moved to SCO UNIX now and would like it
>	for that).
>	
>	If you have it or know of a location where I can get it, PLEASE
>	drop me a note or e-mail me the code.
>
>Did you ever find it?  I got a copy a couple days ago.  I had to modify
>it to work with a Telebit modem but it seems to work okay now.  If someone
>wants it I will be glad to mail it to them or perhaps I should put in an
>archive someplace (suggestions?).
>
>Joe Huffman
>Prototronics
>6490 Kaniksu Shores Circle
>Sandpoint, Idaho 83864-9445
>
>FAX: 208-263-8772
>Voice: 208-263-1695
>joe@proto.com

Compressed uuencoded source...

begin 600 nbs_time.c.Z
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
9R#^<:]N/.1?SY7 @S_I!\GA4F$5=%S5D'_Z)
 
end
-- 
Jack Cloninger, TeqSoft, 112 US Highway 1, Tequesta, FL 33469    B-)
...uunet!comtst!teqsoft!jmc       Phone: 407-747-7163  Fax: 407-747-0354
Disclaimer: I speak for myself, not my company, and give only opinion, not fact.

tneff@bfmny0.BFM.COM (Tom Neff) (12/28/90)

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 <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