home *** CD-ROM | disk | FTP | other *** search
- From: wht@n4hgf.Mt-Park.GA.US (Warren Tucker)
- Newsgroups: alt.sources
- Subject: cmostime3 part 01/02 (was Re: Program to set clock to NBS time)
- Message-ID: <276@n4hgf.Mt-Park.GA.US>
- Date: 29 Dec 90 03:08:06 GMT
-
- As it went out to comp.sources.misc a while back,
- the much nicer cmostime; replaces nbs_time, which had a life of six days,
- but doesn't seem to want to die :-)
-
- Two parts.
-
- ---- Cut Here and unpack ----
- #!/bin/sh
- # This is cmostime3, a shell archive (shar 3.04)
- # made 01/17/1990 06:14 UTC by gatech!kd4nc!n4hgf!wht (wht%n4hgf@gatech.edu)
- # Source directory /u1/src/cmos
- #
- # existing files WILL be overwritten
- #
- # This is part 1 of a multipart archive
- # do not concatenate these parts, unpack them in order with /bin/sh
- #
- # This shar contains:
- # MANIFEST
- # README
- # Makefile
- # CMOSstime.c
- # NBSsetclk.c
- # at_cmos.h
- # cmos_disp.c
- # dev_cmos.c
- # dev_cmos.h
- # set_24hr.c
- #
- touch 2>&1 | fgrep '[-amc]' > /tmp/s3_touch$$
- if [ -s /tmp/s3_touch$$ ]
- then
- TOUCH=can
- else
- TOUCH=cannot
- fi
- rm -f /tmp/s3_touch$$
- if test -r s3_seq_.tmp
- then echo "Must unpack archives in sequence!"
- next=`cat s3_seq_.tmp`; echo "Please unpack part $next next"
- exit 1; fi
- echo "x - extracting MANIFEST (Text)"
- sed 's/^X//' << 'SHAR_EOF' > MANIFEST &&
- X-rw-r--r-- 1 wht wht 3601 Jan 5 20:52 CMOSstime.c
- X-rw-r--r-- 1 wht wht 1418 Jan 5 20:56 Makefile
- X-rw-r--r-- 1 wht wht 24170 Jan 5 20:53 NBSsetclk.c
- X-rw-r--r-- 1 wht wht 3793 Jan 5 20:56 README
- X-rw-r--r-- 1 wht wht 3746 Jan 5 20:53 at_cmos.h
- X-rw-r--r-- 1 wht wht 3964 Jan 5 20:53 cmos_disp.c
- X-rw-r--r-- 1 wht wht 4600 Jan 5 20:54 dev_cmos.c
- X-rw-r--r-- 1 wht wht 661 Jan 5 20:54 dev_cmos.h
- X-rw-r--r-- 1 wht wht 1250 Jan 5 20:55 set_24hr.c
- SHAR_EOF
- chmod 0644 MANIFEST || echo "restore of MANIFEST fails"
- if [ $TOUCH = can ]
- then
- touch -m 0117011490 MANIFEST
- fi
- echo "x - extracting README (Text)"
- sed 's/^X//' << 'SHAR_EOF' > README &&
- Xcmostime3 AT CMOS RAM TIME UTILITIES FOR SCO UNIX AND XENIX V/286&386
- X...gatech!kd4nc!n4hgf!wht (wht%n4hgf@gatech.edu) - Wed Dec 27 1989
- X
- XOverview
- X---------------------------------------------------------------------
- XSCO UNIX and XENIX supports the AT cmos ram with two devices (/dev/cmos,
- X/dev/clock), programs /etc/setclock and /lib/cvtdate and a shell script
- X/etc/asktime. However, there is no way to set the system time or the
- Xcmos clock ACCURATELY using these tools since seconds are not in the
- Xparadigm of setclock or /dev/clock. One can, however, set the cmos
- Xclock accurately by the direct manipulation of /dev/cmos. By reading
- X/dev/cmos, one can get the correct time and set the system time with
- Xstime(S).
- X
- XThis collection of UNIX/XENIX V programs allows you to:
- X
- X1) set the AT cmos clock and system time very accurately by calling
- X the Naval Observatory ((202)653-0351 in DC) using NBSsetclk,
- X
- X2) set the system clock from the (somewhat drifty) cmos clock
- X by using CMOSstime,
- X
- X3) display "interesting" things in the cmos ram by using cmos_disp.
- X
- XThese programs have been proven to work on the Compaq Deskpro 286
- Xand 386 using SCO XENIX/286 2.2.1 and XENIX/386 2.3.1.
- X
- XNBSsetclk
- X---------------------------------------------------------------------
- XNBSsetclk assumes a Hayes modem is connected to the line and that
- Xcommand recognition is enabled. /dev/tty1a is used by default. The
- Xprogram tries up to 40 times (40 seconds) to read the time, making it
- Xlikely that you will succeed. However, the program will terminate
- Xbefore the minimum 1 minute connect charge has expired. NBSsetclk MUST
- Xbe run by root. Why waste a long distance call only to have stime()
- Xfail? Most users will use the default parameters of this program by
- Xinvoking it with
- X NBSsetclk -
- XRunning the program with no parameters gives you the options available.
- X
- XExit status codes for the NBSsetclk:
- X1-n signal values if program killed
- X200 illogical cmos device behavior (when reading clock)
- X249 stime() call failed
- X250 could not open communications line
- X251 /dev/cmos read&write access denied
- X252 user is not root
- X253 usage
- X254 couldn't get time from line (after 40 retries! BAD line conditions)
- X255 couldn't establish a connection
- X
- XCMOSstime
- X---------------------------------------------------------------------
- XCMOStime reads the cmos clock and sets the system time to the second.
- XRun it in your /etc/rc in place of the rather klunky 'asktime'. The
- Xprogram returns exit status 0 if it succeeds, 1 for most failures
- X(stime() failure or /dev/cmos read access failure), or 200 for the rare
- Xcases where the cmos device appears to be acting up.
- X
- Xcmos_disp
- X---------------------------------------------------------------------
- XThis is an experimental program that displays information contained
- Xin the cmos ram. It has some bugs in it (on my systems, it reports
- Xno floppy drives, when I in fact have one). The information used to
- Xbuild the program came from the sketchy notes in the IBM AT Technical
- XReference Manual. Look in header file 'at_cmos.h' and source file
- X'cmos_disp.c' for notes I have made about empirical "discoveries".
- XThere are certainly some discrepancies, particularly on machines
- Xother than the IBM AT.
- X
- Xset_24hr.c
- X---------------------------------------------------------------------
- XOnce or twice during a power main glitch, the 24-hour mode bit got
- Xreset. This program sets the bit.
- X
- XAcknowlegments
- X---------------------------------------------------------------------
- XThe routines for converting mm/dd/yy hh:mm:ss to seconds since
- Xthe epoch were adapted from the 'tm_to_time.c' module in Emmet P.
- XGray's conversion of arc to unix.
- X
- XThe concepts of parsing the Naval Observatory data stream came from
- Xan anonymous author's nbs.c (which read the data stream from stdin).
- SHAR_EOF
- chmod 0644 README || echo "restore of README fails"
- if [ $TOUCH = can ]
- then
- touch -m 0105205690 README
- fi
- echo "x - extracting Makefile (Text)"
- sed 's/^X//' << 'SHAR_EOF' > Makefile &&
- X# CHK=0xDF23
- X# Makefile for cmos/rtc programs
- X#+:EDITS:
- X#:02-03-1989-19:46-wht-386 release
- X
- XSHELL = /bin/sh
- X
- X.SUFFIXES:
- X.SUFFIXES: .o .c .h
- X
- XC_LD_COMMON = -i -s
- XCFLAGS = -c -O -K $(C_LD_COMMON)
- XLIB = -lx
- X#.c.o:; fcrc -u $*.c ; $(CC) $(CFLAGS) $*.c
- X
- XNBSSETCLK_OFILES = \
- X NBSsetclk.o\
- X dev_cmos.o
- X
- XCMOSSTIME_OFILES = \
- X CMOSstime.o\
- X dev_cmos.o
- X
- XCMOS_DISP_OFILES = \
- X cmos_disp.o\
- X dev_cmos.o
- X
- XS24H_DISP_OFILES = \
- X set_24hr.o\
- X dev_cmos.o
- X
- XSHAR_FILES = \
- X README\
- X Makefile\
- X CMOSstime.c\
- X NBSsetclk.c\
- X at_cmos.h\
- X cmos_disp.c\
- X dev_cmos.c\
- X dev_cmos.h\
- X set_24hr.c
- X
- Xall: NBSsetclk CMOSstime cmos_disp
- X
- XNBSsetclk: $(NBSSETCLK_OFILES)
- X $(CC) $(C_LD_COMMON) $(NBSSETCLK_OFILES) $(LIB) -o $@
- X
- XCMOSstime: $(CMOSSTIME_OFILES)
- X $(CC) $(C_LD_COMMON) $(CMOSSTIME_OFILES) $(LIB) -o $@
- X
- Xcmos_disp: $(CMOS_DISP_OFILES)
- X $(CC) $(C_LD_COMMON) $(CMOS_DISP_OFILES) $(LIB) -o $@
- X
- Xset_24hr: $(S24H_DISP_OFILES)
- X $(CC) $(C_LD_COMMON) $(S24H_DISP_OFILES) $(LIB) -o $@
- X
- Xshar:
- X ls -l $(SHAR_FILES) > MANIFEST
- X shar -c -ncmostime3 -l30 -ocmostime3. MANIFEST $(SHAR_FILES)
- X
- Xclean:
- X -rm -f *.o
- X
- Xclobber: clean
- X rm -f NBSsetclk CMOSstime cmos_disp set_24hr \
- X cmostime.sh.1 cmostime.sh.2 MANIFEST
- X
- XMANIFEST: $(SHAR1_FILES) $(SHAR2_FILES)
- X echo 'List of files in cmostime.sh.{1,2}' > MANIFEST
- X ls -l $(SHAR1_FILES) $(SHAR2_FILES) > MANIFEST
- X
- XNBS_setclk.o: at_cmos.h dev_cmos.h
- X
- XCMOSstime.o: dev_cmos.h
- X
- Xcmos_disp.o: at_cmos.h dev_cmos.h
- SHAR_EOF
- chmod 0644 Makefile || echo "restore of Makefile fails"
- if [ $TOUCH = can ]
- then
- touch -m 0105205690 Makefile
- fi
- echo "x - extracting CMOSstime.c (Text)"
- sed 's/^X//' << 'SHAR_EOF' > CMOSstime.c &&
- X/* CHK=0xFC70 */
- X/* vi: set tabstop=4 shiftwidth=4: */
- X/*+-------------------------------------------------------------------------
- X CMOSstime.c -- read cmos clock then stime()
- X ...!gatech!kd4nc!n4hgf!wht
- X
- X Defined functions:
- X date_to_epochsecs(year,month,day,hour,min,sec)
- X days_since_epoch(year,month,day)
- X leap_year(yr)
- X main(argc,argv,envp)
- X
- X--------------------------------------------------------------------------*/
- X/*+:EDITS:*/
- X/*:12-04-1989-20:14-wht-support UNIX 3.2 */
- X/*:02-03-1989-19:50-wht-386 release */
- X/*:07-23-1988-18:59-wht-release */
- X/*:07-22-1988-19:34-wht-creation */
- X
- X#include <stdio.h>
- X#include <fcntl.h>
- X#include <sys/types.h>
- X#include <time.h>
- X
- X#include "dev_cmos.h"
- X
- Xint leap_year(int );
- Xint days_since_epoch(int ,int ,int );
- Xlong date_to_epochsecs(int ,int ,int ,int ,int ,int );
- X
- Xchar *ctime();
- Xint stime(long *);
- Xlong time(long *);
- X
- Xchar *cmos = "/dev/cmos";
- X
- X/*+-------------------------------------------------------------------------
- X leap_year(yr) -- returns 1 if leap year, 0 otherwise
- X--------------------------------------------------------------------------*/
- Xint
- Xleap_year(yr)
- Xint yr;
- X{
- X return((yr % 4 == 0) && (yr % 100 != 0) || (yr % 400 == 0));
- X} /* end of leap_year */
- X
- X/*+-------------------------------------------------------------------------
- X days_since_epoch(year,month,day)
- XReturn the number of days between Jan 1, 1970 and year,month,day
- Xyear is full year (e.g., 1988)
- Xmonth is 0-11
- Xday is 0-30 (must be legal day in month)
- X--------------------------------------------------------------------------*/
- Xint
- Xdays_since_epoch(year,month,day)
- Xint year;
- Xint month;
- Xregister int day;
- X{
- Xregister int mm;
- Xregister int yy;
- Xstatic char days_per_month[] = {31,28,31,30,31,30,31,31,30,31,30,31};
- X
- X day++; /* adjust for day 0-n instead of 1-n */
- X
- X for(yy = 1970; yy < year; ++yy)
- X {
- X day += 365;
- X if(leap_year(yy))
- X day++;
- X }
- X for(mm = 0; mm < month; ++mm)
- X day += days_per_month[mm] + (mm == 1 && leap_year(yy));
- X
- X return(day);
- X
- X} /* end of days_since_epoch */
- X
- X/*+-------------------------------------------------------------------------
- X date_to_epochsecs(year,month,day,hour,min,sec)
- XConvert arguments into long seconds since 1/1/1970
- Xyear is full year (e.g., 1988)
- Xmonth is 0-11
- Xday is 0-30 (must be legal day in month)
- Xhour is 0-23, min and sec 0-59
- X--------------------------------------------------------------------------*/
- Xlong
- Xdate_to_epochsecs(year,month,day,hour,min,sec)
- Xint year;
- Xint month;
- Xint day;
- Xint hour;
- Xint min;
- Xint sec;
- X{
- Xregister int m1;
- Xregister int m2;
- Xlong t;
- Xstruct tm *tp;
- Xstruct tm *localtime();
- X
- X t = (days_since_epoch(year,month,day) - 1) * 86400L
- X + (hour * 3600L) + (min * 60L) + sec;
- X#if !defined(M_UNIX)
- X /* correct for the time zone */
- X tp = localtime(&t);
- X m1 = tp->tm_hour * 60 + tp->tm_min;
- X m2 = (hour * 60) + min;
- X t -= ((m1 - m2 + 720 + 1440) % 1440 - 720) * 60L;
- X#endif
- X
- X return(t);
- X
- X} /* end of date_to_epochsecs */
- X
- X/*+-------------------------------------------------------------------------
- X main(argc,argv,envp)
- X--------------------------------------------------------------------------*/
- Xmain(argc,argv,envp)
- Xint argc;
- Xchar **argv;
- Xchar **envp;
- X{
- Xint year,month,day,hour,min,sec;
- Xint fdcmos;
- Xlong now;
- X
- X setbuf(stdout,NULL);
- X setbuf(stderr,NULL);
- X
- X if((fdcmos = open(cmos,O_RDONLY)) < 0)
- X {
- X perror(cmos);
- X exit(1);
- X }
- X
- X get_clock(fdcmos,&year,&month,&day,&hour,&min,&sec);
- X now = date_to_epochsecs(year,month,day,hour,min,sec);
- X if(stime(&now))
- X {
- X perror("stime");
- X exit(1);
- X }
- X time(&now);
- X fputs("System time after stime(): ",stdout);
- X fputs(ctime(&now),stdout);
- X
- X exit(0);
- X} /* end of main */
- SHAR_EOF
- chmod 0644 CMOSstime.c || echo "restore of CMOSstime.c fails"
- if [ $TOUCH = can ]
- then
- touch -m 0105205290 CMOSstime.c
- fi
- echo "x - extracting NBSsetclk.c (Text)"
- sed 's/^X//' << 'SHAR_EOF' > NBSsetclk.c &&
- X/* CHK=0x9B09 */
- X/* vi: set tabstop=4 shiftwidth=4: */
- X/*+-----------------------------------------------------------------------
- X NBSsetclk.c -- call NBS, get time, hangup QUICKly, set system time,
- X update cmos clock (/dev/cmos)
- X ...!gatech!kd4nc!n4hgf!wht
- X
- X Defined functions:
- X create_lock_file(lock_file_name)
- X hangup(sig)
- X hayes_dial()
- X hayes_modem_init(cmd)
- 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 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 unlock_tty()
- X usage()
- X valid_baud_rate(baud)
- X
- X Note: must be root to execute
- X
- X Exit status codes for the program:
- X 1-n signal values if program killed
- X 200 illogical cmos device behavior (when reading clock)
- X 249 stime() call failed
- X 250 could not open communications line
- X 251 /dev/cmos read&write access denied
- X 252 user is not root
- X 253 usage
- X 254 couldn't get time from line (after 40 retries! BAD line conditions)
- X 255 could not establish a connection or line error
- X
- X------------------------------------------------------------------------*/
- X/*+:EDITS:*/
- X/*:12-27-1989-15:46-wht-use getopt */
- X/*:12-27-1989-15:42-wht-time was of by one second (bitch,bitch,bitch) */
- X/*:12-04-1989-20:14-wht-support UNIX 3.2 */
- X/*:05-18-1989-15:12-wht-improve hangup() error reporting */
- X/*:05-18-1989-15:04-wht-use ltoggle_dtr: close/open chg'd baudrate */
- X/*:02-03-1989-19:50-wht-386 release */
- X/*:12-07-1988-15:13-wht-show cmos time before setting it */
- X/*:07-23-1988-19:03-wht-release */
- X/*:07-23-1988-13:11-wht-get good parsed time before hanging up w/max retries */
- X/*:07-23-1988-12:50-wht-do not use setclock ... messes up new system time */
- X/*:07-22-1988-20:17-wht-change output format */
- 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#include "dev_cmos.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
- Xvoid usage(void);
- Xvoid hangup(int );
- Xint make_lock_name(char *,char *);
- Xint create_lock_file(char *);
- Xchar *other_lock_name(char *);
- Xint lock_tty(void );
- Xvoid unlock_tty(void );
- Xint valid_baud_rate(unsigned int );
- Xint lset_baud_rate(int );
- Xvoid lset_parity(int );
- Xvoid lgetc(char *);
- Xvoid lputc(char );
- Xvoid lputs_paced(int ,char *);
- Xchar *lgets_timeout(struct lrwt *);
- Xint lgetc_timeout(unsigned long );
- Xvoid lkill_buf(void );
- Xint lopen(void );
- Xvoid lclose(void );
- Xint hayes_send_cmd(char *);
- Xint hayes_dial(void );
- X
- Xushort geteuid();
- Xushort getuid();
- Xlong nap(long);
- Xlong time(long *);
- Xchar *ctime();
- X
- Xtypedef struct lrwt /* param to lgets_timeout in eculine.c */
- X{
- X ulong to1; /* timeout for 1st character (granularity 20) */
- X ulong to2; /* timeout for each next char (granularity 20) */
- X int raw_flag; /* !=0, rtn full buffer, ==0, rtn filtered hayes result */
- X char *buffer; /* buffer to fill */
- X int bufsize; /* size of buffer */
- X int 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 NBSTONE '*' /* time "hack" */
- X#define NBSFMT "%05ld %03d %02d%02d%02d UTC"
- X
- 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 */
- Xint Lmodem_already_init = 0;
- 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 Ltermio; /* attributes for the line to remote */
- Xuint Lbaud; /* baud rate */
- Xushort euid;
- Xushort uid;
- Xchar *cmos = "/dev/cmos";
- X
- X/*+-------------------------------------------------------------------------
- X usage()
- X--------------------------------------------------------------------------*/
- Xvoid
- Xusage()
- X{
- X ff(se,"Usage: NBSsetclk [-][-e][-o][-n][-b#][-t#][-l<name>]\n");
- X ff(se,"Defaults 1200-N %s %s\n",Ltelno,Lline);
- 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 (e.g., /dev/tty2A)\n");
- X exit(253);
- X
- X} /* end of usage */
- X
- X/*+-----------------------------------------------------------------------
- X hangup(sig) -- terminate program (with comm line cleanup)
- X------------------------------------------------------------------------*/
- Xvoid
- Xhangup(sig)
- Xint sig;
- X{
- Xvoid lclose();
- X
- X ff(se,"\nhangup %d (see code)\n",sig);
- 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)
- Xregister char *ttyname;
- Xchar *lock_file_name;
- X{
- X if(strncmp(ttyname,"/dev/tty",8))
- X return(LOPEN_INVALID);
- X
- X strcpy(lock_file_name,"/usr/spool/uucp/LCK..");
- X strcat(lock_file_name,ttyname + 8);
- 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 Everybody's uucp is diffeent - hack this if you like
- X------------------------------------------------------------------------*/
- Xcreate_lock_file(lock_file_name)
- Xchar *lock_file_name;
- X{
- Xregister int fdlock;
- Xint pid;
- Xint old_umask;
- X
- X old_umask = umask(0);
- X
- X if((fdlock = open(lock_file_name,O_CREAT | O_EXCL | O_RDWR,0666)) < 0)
- X { /* file already exists */
- X if((fdlock = open(lock_file_name,O_RDWR,0666)) < 0)
- X {
- X umask(old_umask);
- X return(LOPEN_LCKERR);
- X }
- X
- X if(read(fdlock,(char *)&pid,sizeof(pid)) > 0)
- X {
- X if(kill(pid,0) && (errno == ESRCH)) /* is owner dead? */
- X {
- X pid = getpid();
- X lseek(fdlock,0L,0);
- X write(fdlock,(char *)&pid,sizeof(pid));
- X close(fdlock);
- X umask(old_umask);
- X return(0);
- X }
- X /* owner pid still active with lock */
- X close(fdlock);
- X umask(old_umask);
- X return(pid);
- X }
- X close(fdlock);
- X umask(old_umask);
- X return(LOPEN_UNKPID);
- X }
- X pid = getpid();
- X write(fdlock,(char *)&pid,sizeof(pid));
- X close(fdlock);
- X chmod(lock_file_name,0666);
- X umask(old_umask);
- X return(0);
- 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 unlink(LLCKname);
- X unlink(other_lock_name(LLCKname));
- 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} /* end of valid_baud_rate */
- X
- X/*+-----------------------------------------------------------------------
- X lset_baud_rate(ioctl_flag)
- X
- X If 'ioctl_flag' is set,then ioctl(Liofd,TCSETA,&Ltermio)
- 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 Ltermio.c_cflag &= ~CBAUD;
- X Ltermio.c_cflag |= baud_selector;
- X
- X if(ioctl_flag)
- X ioctl(Liofd,(int)TCSETA,(char *)&Ltermio);
- 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,&Ltermio)
- X is executed after setting parity
- X------------------------------------------------------------------------*/
- Xvoid
- Xlset_parity(ioctl_flag)
- Xint ioctl_flag;
- X{
- X Ltermio.c_cflag &= ~(CS8 | PARENB | PARODD);
- X switch(Lparity)
- X {
- X case 'e':
- X Ltermio.c_cflag |= CS7 | PARENB;
- X Ltermio.c_iflag |= ISTRIP;
- X break;
- X case 'o':
- X Ltermio.c_cflag |= PARODD | CS7 | PARENB;
- X Ltermio.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 Ltermio.c_cflag |= CS8;
- X Ltermio.c_iflag &= ~(ISTRIP);
- X Lparity = 0;
- X break;
- X }
- X
- X if(ioctl_flag)
- X ioctl(Liofd,(int)TCSETA,(char *)&Ltermio);
- X
- X} /* end of lset_parity */
- X
- X/*+-------------------------------------------------------------------------
- X lgetc(char_rtnd)
- X--------------------------------------------------------------------------*/
- Xvoid
- Xlgetc(char_rtnd)
- Xchar *char_rtnd;
- X{
- X if(read(Liofd,char_rtnd,1) < 1)
- X {
- X perror("line read error");
- X hangup(255);
- X }
- X} /* end of lgetc */
- X
- X/*+-----------------------------------------------------------------------
- X lputc(lchar) -- write lchar to comm line
- X------------------------------------------------------------------------*/
- Xvoid
- Xlputc(lchar)
- Xchar lchar;
- X{
- Xregister int itmp;
- X
- X if((itmp = write(Liofd,&lchar,1)) < 1)
- X {
- X if(itmp < 0)
- X perror("\nline write error");
- X else
- X fputs("\nline write error\n",se);
- 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 : 20L;
- 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
- XRefer to LWRT structure.
- X
- Xto1 and to2 are unsigned long values in milliseconds (not currently
- Xsupported well under BSD4); to1 is the time to wait for the first
- Xcharacter, to2 the time to wait for subsequent characters.
- 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) which
- Xshould be at least 2 if raw_size includes 0x80 bit, else at least 12
- Xcharacters 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,qc2;
- Xlong quantum,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(rdchk(Liofd))
- 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 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 | O_NDELAY,0777);
- X if(Liofd < 0)
- X return(LOPEN_OPNFAIL);
- X else
- X {
- X ioctl(Liofd,(int)TCGETA,(char *)&Ltermio);
- X Ltermio.c_iflag = (IGNPAR | IGNBRK | IXOFF );
- X Ltermio.c_cflag |= (CREAD | HUPCL);
- X Ltermio.c_lflag = 0;
- X
- X Ltermio.c_cc[VMIN] = 1;
- X Ltermio.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/*+-----------------------------------------------------------------------
- SHAR_EOF
- echo "End of cmostime3 part 1"
- echo "File NBSsetclk.c is continued in part 2"
- echo "2" > s3_seq_.tmp
- exit 0
-
- ----------------------------------------------------------------------------
- Warren Tucker emory!n4hgf!wht or wht@n4hgf.Mt-Park.GA.US
- "I was 35 years old before I knew a pie was meant to be eaten." - Moe Howard
-