diff options
Diffstat (limited to 'sbin/slattach')
-rw-r--r-- | sbin/slattach/Makefile | 3 | ||||
-rw-r--r-- | sbin/slattach/slattach.c | 36 | ||||
-rw-r--r-- | sbin/slattach/uucplock.c | 143 |
3 files changed, 172 insertions, 10 deletions
diff --git a/sbin/slattach/Makefile b/sbin/slattach/Makefile index bdc48a9..e1b2845 100644 --- a/sbin/slattach/Makefile +++ b/sbin/slattach/Makefile @@ -1,8 +1,9 @@ # @(#)Makefile 5.4 (Berkeley) 5/11/90 # -# $Header: /a/cvs/386BSD/src/sbin/slattach/Makefile,v 1.5 1993/08/29 18:11:14 rgrimes Exp $ +# $Header: /home/ncvs/src/sbin/slattach/Makefile,v 1.4 1994/08/23 08:28:30 rich Exp $ PROG= slattach +SRCS= slattach.c uucplock.c MAN8= slattach.8 MLINKS= slattach.8 slip.8 LDADD= -lutil diff --git a/sbin/slattach/slattach.c b/sbin/slattach/slattach.c index b8e28a4..ee4c98d 100644 --- a/sbin/slattach/slattach.c +++ b/sbin/slattach/slattach.c @@ -77,6 +77,8 @@ void acquire_line(); /* get tty device as controling terminal */ int fd = -1; char *dev = (char *)0; /* path name of the tty (e.g. /dev/tty01) */ +char *dvname; /* basename of dev */ +int locked = 0; /* uucp lock */ int flow_control = 0; /* non-zero to enable hardware flow control. */ int modem_control = HUPCL; /* !CLOCAL+HUPCL iff we watch carrier. */ int comstate; /* TIOCMGET current state of serial driver */ @@ -122,7 +124,6 @@ int main(int argc, char **argv) int option; extern char *optarg; extern int optind; - char *cp; while ((option = getopt(argc, argv, "ace:fhlnr:s:u:zK:O:S:")) != EOF) { switch (option) { @@ -199,9 +200,9 @@ int main(int argc, char **argv) strncat(tty_path, dev, 10); dev = tty_path; } - cp = strrchr(dev, '/'); /* always succeeds */ - cp++; /* trailing tty pathname component */ - sprintf(pidfilename, "%sslattach.%s.pid", _PATH_VARRUN, cp); + dvname = strrchr(dev, '/'); /* always succeeds */ + dvname++; /* trailing tty pathname component */ + sprintf(pidfilename, "%sslattach.%s.pid", _PATH_VARRUN, dvname); printf("%s\n",pidfilename); if (!foreground) @@ -251,7 +252,10 @@ void acquire_line() int ttydisc = TTYDISC; FILE *pidfile; - ioctl(fd, TIOCSETD, &ttydisc); /* reset to tty discipline */ + if (ioctl(fd, TIOCSETD, &ttydisc) < 0) { /* reset to tty discipline */ + syslog(LOG_ERR, "ioctl(TIOCSETD): %m"); + exit_handler(1); + } (void)close(STDIN_FILENO); /* close FDs before forking. */ (void)close(STDOUT_FILENO); @@ -260,7 +264,10 @@ void acquire_line() (void)close(fd); signal(SIGHUP, SIG_IGN); /* ignore HUP signal when parent dies. */ - daemon(0,0); /* fork, setsid, chdir /, and close std*. */ + if (daemon(0,0)) { /* fork, setsid, chdir /, and close std*. */ + syslog(LOG_ERR, "daemon(0,0): %m"); + exit_handler(1); + } while (getppid () != 1) sleep (1); /* Wait for parent to die. */ @@ -274,8 +281,15 @@ void acquire_line() if ((int)signal(SIGHUP,sighup_handler) < 0) /* Re-enable HUP signal */ syslog(LOG_NOTICE,"cannot install SIGHUP handler: %m"); + /* unlock not needed here, always re-lock with new pid */ + if (uu_lock(dvname)) { + syslog(LOG_ERR, "can't lock %s", dev); + exit_handler(1); + } + locked = 1; + if ((fd = open(dev, O_RDWR | O_NONBLOCK, 0)) < 0) { - syslog(LOG_ERR, "open(%s) fd=%d: %m", dev, fd); + syslog(LOG_ERR, "open(%s) %m", dev); exit_handler(1); } (void)dup2(fd, STDIN_FILENO); @@ -286,8 +300,10 @@ void acquire_line() fd = STDIN_FILENO; /* acquire the serial line as a controling terminal. */ - if (ioctl(fd, TIOCSCTTY, 0) < 0) - syslog(LOG_NOTICE,"ioctl(TIOCSCTTY) failed: %m"); + if (ioctl(fd, TIOCSCTTY, 0) < 0) { + syslog(LOG_ERR,"ioctl(TIOCSCTTY): %m"); + exit_handler(1); + } /* Make us the foreground process group associated with the slip line which is our controlling terminal. */ if (tcsetpgrp(fd, getpid()) < 0) @@ -514,6 +530,8 @@ void exit_handler(int ret) */ if (fd != -1) close(fd); + if (locked) + uu_unlock(dvname); /* Remove the PID file */ (void)unlink(pidfilename); diff --git a/sbin/slattach/uucplock.c b/sbin/slattach/uucplock.c new file mode 100644 index 0000000..fb0f7c0 --- /dev/null +++ b/sbin/slattach/uucplock.c @@ -0,0 +1,143 @@ +/* + * Copyright (c) 1988, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef lint +static char sccsid[] = "@(#)uucplock.c 8.1 (Berkeley) 6/6/93"; +#endif /* not lint */ + +#include <sys/types.h> +#include <sys/file.h> +#include <sys/dir.h> +#include <errno.h> +#include <syslog.h> +#include <unistd.h> +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> + +#define _PATH_LOCKDIRNAME "/var/spool/lock/LCK..%s" + +/* Forward declarations */ +static int put_pid (int fd, pid_t pid); +static pid_t get_pid (int fd); + +/* + * uucp style locking routines + * return: 0 - success + * -1 - failure + */ + +int uu_lock (char *ttyname) +{ + int fd; + pid_t pid; + char tbuf[sizeof(_PATH_LOCKDIRNAME) + MAXNAMLEN]; + + (void)sprintf(tbuf, _PATH_LOCKDIRNAME, ttyname); + fd = open(tbuf, O_RDWR|O_CREAT|O_EXCL, 0660); + if (fd < 0) { + /* + * file is already locked + * check to see if the process holding the lock still exists + */ + fd = open(tbuf, O_RDWR, 0); + if (fd < 0) { + syslog(LOG_ERR, "lock open: %m"); + return(-1); + } + if ((pid = get_pid (fd)) == -1) { + syslog(LOG_ERR, "lock read: %m"); + (void)close(fd); + return(-1); + } + + if (kill(pid, 0) == 0 || errno != ESRCH) { + (void)close(fd); /* process is still running */ + return(-1); + } + /* + * The process that locked the file isn't running, so + * we'll lock it ourselves + */ + if (lseek(fd, 0L, L_SET) < 0) { + syslog(LOG_ERR, "lock lseek: %m"); + (void)close(fd); + return(-1); + } + /* fall out and finish the locking process */ + } + pid = getpid(); + if (!put_pid (fd, pid)) { + syslog(LOG_ERR, "lock write: %m"); + (void)close(fd); + (void)unlink(tbuf); + return(-1); + } + (void)close(fd); + return(0); +} + +int uu_unlock (char *ttyname) +{ + char tbuf[sizeof(_PATH_LOCKDIRNAME) + MAXNAMLEN]; + + (void)sprintf(tbuf, _PATH_LOCKDIRNAME, ttyname); + return(unlink(tbuf)); +} + +static int put_pid (int fd, pid_t pid) +{ + char buf [32]; + int len; + + len = sprintf (buf, "%10ld\n", pid); + return write (fd, buf, len) == len; +} + +static pid_t get_pid (int fd) +{ + int bytes_read; + char buf [32]; + pid_t pid; + + bytes_read = read (fd, buf, sizeof (buf) - 1); + if (bytes_read > 0) { + buf [bytes_read] = '\0'; + pid = strtol (buf, (char **) NULL, 10); + } + else + pid = -1; + return pid; +} + +/* end of uucplock.c */ |