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