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