uucplock.c revision 24417
124417Sbrian/* 224417Sbrian * Copyright (c) 1988, 1993 324417Sbrian * The Regents of the University of California. All rights reserved. 424417Sbrian * 524417Sbrian * Redistribution and use in source and binary forms, with or without 624417Sbrian * modification, are permitted provided that the following conditions 724417Sbrian * are met: 824417Sbrian * 1. Redistributions of source code must retain the above copyright 924417Sbrian * notice, this list of conditions and the following disclaimer. 1024417Sbrian * 2. Redistributions in binary form must reproduce the above copyright 1124417Sbrian * notice, this list of conditions and the following disclaimer in the 1224417Sbrian * documentation and/or other materials provided with the distribution. 1324417Sbrian * 3. All advertising materials mentioning features or use of this software 1424417Sbrian * must display the following acknowledgement: 1524417Sbrian * This product includes software developed by the University of 1624417Sbrian * California, Berkeley and its contributors. 1724417Sbrian * 4. Neither the name of the University nor the names of its contributors 1824417Sbrian * may be used to endorse or promote products derived from this software 1924417Sbrian * without specific prior written permission. 2024417Sbrian * 2124417Sbrian * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2224417Sbrian * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2324417Sbrian * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2424417Sbrian * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2524417Sbrian * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2624417Sbrian * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2724417Sbrian * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2824417Sbrian * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2924417Sbrian * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3024417Sbrian * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3124417Sbrian * SUCH DAMAGE. 3224417Sbrian */ 3324417Sbrian 3424417Sbrian#ifndef lint 3524417Sbrianstatic const char sccsid[] = "@(#)uucplock.c 8.1 (Berkeley) 6/6/93"; 3624417Sbrian#endif /* not lint */ 3724417Sbrian 3824417Sbrian#include <sys/types.h> 3924417Sbrian#include <sys/file.h> 4024417Sbrian#include <dirent.h> 4124417Sbrian#include <errno.h> 4224417Sbrian#ifndef USE_PERROR 4324417Sbrian#include <syslog.h> 4424417Sbrian#endif 4524417Sbrian#include <unistd.h> 4624417Sbrian#include <signal.h> 4724417Sbrian#include <stdio.h> 4824417Sbrian#include <stdlib.h> 4924417Sbrian#include <paths.h> 5024417Sbrian 5124417Sbrian#define LOCKFMT "LCK..%s" 5224417Sbrian 5324417Sbrian/* Forward declarations */ 5424417Sbrianstatic int put_pid (int fd, pid_t pid); 5524417Sbrianstatic pid_t get_pid (int fd); 5624417Sbrian 5724417Sbrian/* 5824417Sbrian * uucp style locking routines 5924417Sbrian * return: 0 - success 6024417Sbrian * -1 - failure 6124417Sbrian */ 6224417Sbrian 6324417Sbrianint uu_lock (char *ttyname) 6424417Sbrian{ 6524417Sbrian int fd; 6624417Sbrian pid_t pid; 6724417Sbrian char tbuf[sizeof(_PATH_UUCPLOCK) + MAXNAMLEN]; 6824417Sbrian 6924417Sbrian (void)sprintf(tbuf, _PATH_UUCPLOCK LOCKFMT, ttyname); 7024417Sbrian fd = open(tbuf, O_RDWR|O_CREAT|O_EXCL, 0660); 7124417Sbrian if (fd < 0) { 7224417Sbrian /* 7324417Sbrian * file is already locked 7424417Sbrian * check to see if the process holding the lock still exists 7524417Sbrian */ 7624417Sbrian fd = open(tbuf, O_RDWR, 0); 7724417Sbrian if (fd < 0) { 7824417Sbrian#ifndef USE_PERROR 7924417Sbrian syslog(LOG_ERR, "lock open: %m"); 8024417Sbrian#else 8124417Sbrian perror("lock open"); 8224417Sbrian#endif 8324417Sbrian return(-1); 8424417Sbrian } 8524417Sbrian if ((pid = get_pid (fd)) == -1) { 8624417Sbrian#ifndef USE_PERROR 8724417Sbrian syslog(LOG_ERR, "lock read: %m"); 8824417Sbrian#else 8924417Sbrian perror("lock read"); 9024417Sbrian#endif 9124417Sbrian (void)close(fd); 9224417Sbrian return(-1); 9324417Sbrian } 9424417Sbrian 9524417Sbrian if (kill(pid, 0) == 0 || errno != ESRCH) { 9624417Sbrian (void)close(fd); /* process is still running */ 9724417Sbrian return(-1); 9824417Sbrian } 9924417Sbrian /* 10024417Sbrian * The process that locked the file isn't running, so 10124417Sbrian * we'll lock it ourselves 10224417Sbrian */ 10324417Sbrian if (lseek(fd, (off_t) 0, L_SET) < 0) { 10424417Sbrian#ifndef USE_PERROR 10524417Sbrian syslog(LOG_ERR, "lock lseek: %m"); 10624417Sbrian#else 10724417Sbrian perror("lock lseek"); 10824417Sbrian#endif 10924417Sbrian (void)close(fd); 11024417Sbrian return(-1); 11124417Sbrian } 11224417Sbrian /* fall out and finish the locking process */ 11324417Sbrian } 11424417Sbrian pid = getpid(); 11524417Sbrian if (!put_pid (fd, pid)) { 11624417Sbrian#ifndef USE_PERROR 11724417Sbrian syslog(LOG_ERR, "lock write: %m"); 11824417Sbrian#else 11924417Sbrian perror("lock write"); 12024417Sbrian#endif 12124417Sbrian (void)close(fd); 12224417Sbrian (void)unlink(tbuf); 12324417Sbrian return(-1); 12424417Sbrian } 12524417Sbrian (void)close(fd); 12624417Sbrian return(0); 12724417Sbrian} 12824417Sbrian 12924417Sbrianint uu_unlock (char *ttyname) 13024417Sbrian{ 13124417Sbrian char tbuf[sizeof(_PATH_UUCPLOCK) + MAXNAMLEN]; 13224417Sbrian 13324417Sbrian (void)sprintf(tbuf, _PATH_UUCPLOCK LOCKFMT, ttyname); 13424417Sbrian return(unlink(tbuf)); 13524417Sbrian} 13624417Sbrian 13724417Sbrianstatic int put_pid (int fd, pid_t pid) 13824417Sbrian{ 13924417Sbrian char buf[32]; 14024417Sbrian int len; 14124417Sbrian 14224417Sbrian len = sprintf (buf, "%10d\n", pid); 14324417Sbrian return write (fd, buf, len) == len; 14424417Sbrian} 14524417Sbrian 14624417Sbrianstatic pid_t get_pid (int fd) 14724417Sbrian{ 14824417Sbrian int bytes_read; 14924417Sbrian char buf[32]; 15024417Sbrian pid_t pid; 15124417Sbrian 15224417Sbrian bytes_read = read (fd, buf, sizeof (buf) - 1); 15324417Sbrian if (bytes_read > 0) { 15424417Sbrian buf[bytes_read] = '\0'; 15524417Sbrian pid = strtol (buf, (char **) NULL, 10); 15624417Sbrian } else 15724417Sbrian pid = -1; 15824417Sbrian return pid; 15924417Sbrian} 16024417Sbrian 16124417Sbrian/* end of uucplock.c */ 162