[net.sources] Modified version of dial

david@ukma.UUCP (David Herron, NPR Lover) (12/27/84)

: This is a shar archive.  Extract with sh, not csh.
: This archive ends with exit, so do not worry about trailing junk.
echo 'Extracting README'
sed 's/^X//' > README << '+ END-OF-FILE README'
X	This program is in use by us for one phone line
X	for dial in and dial out. There might be much better
X	solutions to the problem, but the best one is having
X	separate phone lines.
X
X	all our uucp and uux calls go with the -r parameter
X	and in the /usr/lib/crontab the uucico call is at follows
X
X 05 * * * * /etc/dial out; sleep 5; /etc/dial in
X
X	the program 'chmod' and 'owner' as follows:
X
X ---s--x--x  1 root        16384 Nov 25 15:42 /etc/dial
X
X-------------------------------------------------------------------
X
XModifications by David Herron, (ukma!david). [27-Dec-84]
X
XI had been doing something similar to this with shell files.
XHowever they left a few things to be desired.  My method here
Xwas to create a lock file when the port was enabled for dial-in.
XThis served to keep uucp/tip/kermit from trying to use the port
Xwhile it was in this mode.  So this creates 4 cases that need
Xto be checked for.  (read my code and manual page about this).
X
XI also had written a cute little program that made and destroyed
Xlock files for you.  Very convenient.
X
XNote that I don't follow his suggestion up there of making dial
Xset-uid.  I don't see where it is terribly safe to let the users
Xhave the power to make lines dial in/out.
X
XAs above, the intended use is:
X
X	1:  In the morning, enable 1 or more lines for outgoing.
X	    (this actually happens in the wee hours so our news
X	    feed gets polled).  Assumption is that most people
X	    are in their offices during the day and mostly need
X	    the modems to attach to outside computers.
X	2:  In the evening, disable some of the outgoing lines
X	    leaving 1 or 2 for outgoing.  Not all people are
X	    going to be gone, and uucp must still also work.
X
XI have just one line switching back and forth currently.
+ END-OF-FILE README
chmod 'u=rw,g=r,o=r' 'README'
echo '	-rw-r--r--  1 root         1758 Dec 27 04:37 README        (as sent)'
echo -n '	'
/bin/ls -l README
echo 'Extracting dial.8'
sed 's/^X//' > dial.8 << '+ END-OF-FILE dial.8'
X.TH DIAL 8 LOCAL
X.SH NAME
Xdial \- change the modem line to in or out
X.SH SYNOPSIS
Xdial \fBin\fP|\fBout\fP \fBttyxx\fP
X.SH DESCRIPTION
X.I Dial
Xchanges the modemline on ttyxx to a
X.I dialin
Xor
X.I dialout
Xline. 
XAppropriate checking is done to avoid conflicts with 
X.I uucp ,
X.I kermit
Xor
X.I tip
Xand people who are logged on from home.
X.sp
X.I Dial
Xchecks 4 cases:
X.IP 1)
XCreating a dial out line, lock file doesn't exist.
XThis is fine, disable the getty process.
X.IP 2)
XCreating a dial out line, lock file does exist.
XIf there is a process up for this line,
Xthe lock file is there to stop tip/uucp/kermit from trying to use the line.
XWe can remove the lock file and disable getty.
XOn the other hand, if there is NOT a process up,
Xsomebody else is using the line, so complain.
X.IP 3)
XCreating a dial in line, lock file doesn't exist.
XThis is fine.
XStart up a getty process and create a lock file
X(so that tip/uucp/kermit won't try to use the line).
X.IP 4)
XCreating a dial in line, lock file does exist.
XNothing to do, just complain.
X.PP
XIn all cases,
Xif the lock file exists and is very old (over 8 hours) then
X.I dial
Xgoes ahead and removes it.
X.SH DIAGNOSTICS
XThe error messages are self explanatory.
X.SH AUTHOR
XGertjan Vinkesteyn
X.br
XModified by David Herron (ukma!david) to handle the lock files better
Xand de-localize it.
+ END-OF-FILE dial.8
chmod 'u=rw,g=r,o=r' 'dial.8'
echo '	-rw-r--r--  1 root         1323 Dec 27 04:01 dial.8        (as sent)'
echo -n '	'
/bin/ls -l dial.8
echo 'Extracting dial.c'
sed 's/^X//' > dial.c << '+ END-OF-FILE dial.c'
X/*
X * dial.c -- handle switching of dial in and dial out lines.
X *
X *
X * Dial checks 4 cases:
X * 1) Creating a dial out line, lock file doesn't exist.
X *    This is fine, disable the getty process.
X * 2) Creating a dial out line, lock file does exist.
X *    If there is a process up for this line, the lock file is there to
X *    stop tip/uucp/kermit from trying to use the line.
X *    We can remove the lock file and disable getty.
X *    On the other hand, if there is NOT a process up, somebody else is using 
X *    the line, so complain.
X * 3) Creating a dial in line, lock file doesn't exist.
X *    This is fine.  Start up a getty process and create a lock file
X *    (so that tip/uucp/kermit won't try to use the line).
X * 4) Creating a dial in line, lock file does exist.
X *    Nothing to do, just complain.
X *
X * In all cases, if the lock file exists and is very old (over 8 hours) then
X * dial goes ahead and removes it.
X *
X * This program originally came from Gertjan Vinkesteyn (gertjan@txsil.UUCP),
X * but has been heavily modified by David Herron (david@ukma.UUCP).  I have
X * took out all the localized code, and made it do the 4 cases above.
X *
X */
X
X#include <stdio.h>
X#include <sys/types.h>
X#include <sys/stat.h>
X
Xchar	lck[40];
Xchar	devname[20];
X
X#define ROOTID	(0)
X#define UUCPID	(66)
X#define DAEMGRP	(1)
X
X#define TTYSFILE	("/etc/ttys")
X#define NEWTTYS		("/etc/newttys")
X
X#define SLCKTIME (28800) /* Time to allow lock files to live in seconds */
X
Xmain(argc, argv)
Xint	argc;
Xchar	**argv;
X{
X	register char	*p;
X	char	buf[10];
X	FILE	*Ti, *To;
X	struct stat	statbuf;
X	char *tty;
X	time_t ptime;
X	char *direction;
X
X	if (argc != 3)
X		usage();
X
X	tty = argv[2];
X	sprintf(lck, "/usr/spool/uucp/LCK..%s", tty);
X	sprintf(devname, "/dev/%s", tty);
X
X	direction = argv[1];
X	
X	if ((strcmp(direction, "in") == 0) || (strcmp(direction,"out") == 0)) {
X		if (access(lck) == 0) {
X			/*
X			 * Check to see if it matters whether or not
X			 * we can use it.
X			 */
X			if (stat(lck, &statbuf) < 0) {
X				fprintf(stderr,"stat failed on %s\n", lck);
X				Abort();
X			}
X			time(&ptime);
X			if ((ptime - statbuf.st_ctime) >= SLCKTIME)
X				goto out;
X			if (strcmp(direction, "in") == 0) {
X				/*
X				 * Making an incoming line.  Must be an
X				 * outgoing line currently, right?  If there
X				 * is a lock file, then someone is using the
X				 * port, and we can't do anything with it.
X				 */
X				fprintf(stderr, "%s exists, program abort\n",
X					 lck);
X				Abort();
X			}
X			/* else, making it outgoing */
X
X			if ((Ti = fopen(TTYSFILE, "r")) == NULL) {
X				fprintf(stderr, "Cannot open `%s'\n", TTYSFILE);
X				Abort();
X			}
X			/*
X			 * If we are making an outgoing line, and
X			 * there is already a process up for it, then
X			 * that lock file is a fake meant to cause
X			 * tip/uucp/kermit to not try to open the
X			 * device.
X			 * Otherwise someone is using the line,
X			 * so we must respect the lock file.
X			 */
X			while ((p = fgets(buf, sizeof buf, Ti))) {
X				if (strncmp(&buf[2], tty, 5) == 0) {
X					/* check if a process up */
X					if (*p == '1')
X						break;
X				}
X			}
X			fclose(Ti);
X			/*
X			 * If p == NULL, we saw EOF, indicating that
X			 * there is not a process up on that line.
X			 */
X			if (p == NULL) {
X				fprintf(stderr, "%s exists, program abort\n",
X					 lck);
X				Abort();
X			}
X		}
Xout:
X		/* Get the status for the device file. */
X		if (stat(devname, &statbuf) < 0) {
X			fprintf(stderr,"stat failed\n");
X			Abort();
X		}
X		/* check ownership */
X		if (statbuf.st_uid != ROOTID && statbuf.st_uid != UUCPID) {
X			fprintf(stderr,
X	"root or uucp does not own `%s', somebody might be logged on\n", tty);
X			Abort();
X		}
X		if ((Ti = fopen(TTYSFILE, "r")) == NULL) {
X			fprintf(stderr, "Cannot open `%s'\n", TTYSFILE);
X			usage();
X		}
X		if ((To = fopen(NEWTTYS, "w")) == NULL) {
X			fprintf(stderr, "Cannot creat `%s'\n", NEWTTYS);
X			usage();
X		}
X		/* Read through and modify TTYSFILE */
X		while ((p = fgets(buf, sizeof buf, Ti))) {
X			if (strncmp(&buf[2], tty, 5) == 0) {
X				if (strcmp(direction,"in") == 0) {
X					*p = '1';
X					mklock(lck);
X				} else {
X					*p = '0';
X					if (chmod(devname, 0666) != 0)
X						fprintf(stderr,
X						"Cannot chmod `%s'\n", devname);
X					else 
X						chown(devname, UUCPID, DAEMGRP);
X					if (access(lck) == 0)
X						rmlock(lck);
X				}
X			}
X			fputs(buf, To);
X		}
X		fclose(To);
X		fclose(Ti);
X		if (unlink(TTYSFILE) == -1) {
X			fprintf(stderr, "Cannot unlink `%s'\n", TTYSFILE);
X			Abort();
X		}
X		if (link(NEWTTYS, TTYSFILE) == -1) {
X			fprintf(stderr, "Cannot link `%s' `%s'\n",
X				NEWTTYS, TTYSFILE);
X			fprintf(stderr,
X			   "FATAL. Now we don't have a `%s' file anymore!!\n",
X			    TTYSFILE);
X			Abort();
X		}
X		if (unlink(NEWTTYS) == -1) {
X			fprintf(stderr, "Cannot unlink `%s'\n", NEWTTYS);
X			Abort();
X		}
X	} else
X		usage();
X	if (kill (1, 1) != 0)
X		fprintf(stderr, "Cannot kill -1 1\n");
X}
X
Xusage()
X{
X	fprintf(stderr, "Usage: `dial in ttyxx' or `dial out ttyxx'\n");
X	exit();
X}
X
XAbort()
X{
X	fprintf(stderr, "dial abort\n");
X	exit(-1);
X}
X
X
X/*
X * isalock() -- Stolen direct from /usr/src/usr.bin/tip/uucplock.c which
X *	was stolen direct from /usr/src/usr.bin/uucp/{something}.
X *
X * Return Value:  0 if not a lock, 1 if it is.
X */
Xint isalock(s)
Xchar *s;
X{
X	struct stat xstat;
X
X	if (stat(s, &xstat) < 0)
X		return(0);
X	if (xstat.st_size != sizeof(int))
X		return(0);
X	return(1);
X}
X
X/*
X * rmlock() -- remove a lock file, checking that it actually IS a lock file.
X */
Xrmlock(s)
Xchar *s;
X{
X	if (!isalock(s)) {
X		fprintf(stderr, "dial: lock %s invalid\n", s);
X		return(1);
X	}
X	if (unlink(s) != 0)
X		perror("dial");
X}
X
X/*
X * mklock() -- make a proper lockfile.  They contain a process id.
X */
Xmklock(s)
Xchar *s;
X{
X	int fd, pid;
X
X	fd = creat(s, 0444);
X	if (fd < 0)
X		perror("dial");
X	pid = getpid();
X	write(fd, (char *)&pid, sizeof(int));
X	close(fd);
X}
+ END-OF-FILE dial.c
chmod 'u=rw,g=r,o=r' 'dial.c'
echo '	-rw-r--r--  1 root         5791 Dec 27 04:25 dial.c        (as sent)'
echo -n '	'
/bin/ls -l dial.c
echo 'Extracting makefile'
sed 's/^X//' > makefile << '+ END-OF-FILE makefile'
X
X# Makefile for uurmlock, fromtip and totip.
X
Xall: /usr/lib/uucp/uurmlock /usr/etc/dial
X
X/usr/lib/uucp/uurmlock: uulock
X	install -o uucp -g daemon -m 6711 -c uulock /usr/lib/uucp/uurmlock
X	ln /usr/lib/uucp/uurmlock /usr/lib/uucp/uumklock
Xuulock: uulock.c
X	cc -o uulock uulock.c
X
X/usr/etc/dial: dial
X	install -m 711 -c dial /usr/etc/dial
Xdial: dial.c
X	cc -o dial dial.c
+ END-OF-FILE makefile
chmod 'u=rw,g=r,o=r' 'makefile'
echo '	-rw-r--r--  1 root          369 Dec 27 04:27 makefile        (as sent)'
echo -n '	'
/bin/ls -l makefile
echo 'Extracting uulock.c'
sed 's/^X//' > uulock.c << '+ END-OF-FILE uulock.c'
X/* uulock.c -- Make and remove uucp lock files.
X *
X * [25-Oct-84 dsh]
X *
X * USAGE:   uurmlock name
X *	    uumklock name
X *
X * Make or remove a lock as indicated.
X */
X
X
X#include <stdio.h>
X#include <sys/file.h>
X#include <sys/types.h>
X#include <sys/stat.h>
X
X#define LCKPRE "/usr/spool/uucp/LCK."
X
X
X/* isalock() -- Stolen direct from /usr/src/usr.bin/tip/uucplock.c which
X *	was stolen direct from /usr/src/usr.bin/uucp/{something}.
X *
X * Return Value:  0 if not a lock, 1 if it is.
X */
Xint isalock(s)
Xchar *s;
X{
X	struct stat xstat;
X
X	if (stat(s, &xstat) < 0)
X		return(0);
X	if (xstat.st_size != sizeof(int))
X		return(0);
X	return(1);
X}
X
X
Xvoid usage(prgnam)
Xchar *prgnam;
X{
X	fprintf(stderr, "%s: lock-name    (lock-name is like \"tty03\")\n",
X		prgnam);
X	exit(1);
X	/*NOTREACHED*/
X}
X
X
X
Xmain(argc, argv)
Xint argc;
Xchar **argv;
X{
X	char *lockname, bf[120];
X	int fd, pid;
X
X	lockname = &bf[0];
X	if (argc != 2)
X		usage(argv[0]);
X	sprintf(lockname, "%s.%s", LCKPRE, argv[1]);
X
X	if (strcmp(argv[0], "uurmlock") == 0) {
X		if (!isalock(lockname)) {
X			fprintf(stderr, "%s: lock %s invalid\n", 
X				argv[0], lockname);
X			exit(1);
X			/*NOTREACHED*/
X		}
X		if (unlink(lockname) != 0)
X			perror(argv[0]);
X	}
X	else {
X		fd = creat(lockname, 0444);
X		if (fd < 0)
X			perror(argv[0]);
X		pid = getpid();
X		write(fd, (char *)&pid, sizeof(int));
X		close(fd);
X	}
X}
+ END-OF-FILE uulock.c
chmod 'u=rw,g=r,o=r' 'uulock.c'
echo '	-rw-r--r--  1 root         1335 Oct 25 20:11 uulock.c        (as sent)'
echo -n '	'
/bin/ls -l uulock.c
exit 0