1161754Sru/*	$OpenBSD: uucplock.c,v 1.11 2006/03/16 19:32:46 deraadt Exp $	*/
288276Smarkm/*	$NetBSD: uucplock.c,v 1.7 1997/02/11 09:24:08 mrg Exp $	*/
388276Smarkm
488275Smarkm/*
588275Smarkm * Copyright (c) 1988, 1993
688275Smarkm *	The Regents of the University of California.  All rights reserved.
788275Smarkm *
888275Smarkm * Redistribution and use in source and binary forms, with or without
988275Smarkm * modification, are permitted provided that the following conditions
1088275Smarkm * are met:
1188275Smarkm * 1. Redistributions of source code must retain the above copyright
1288275Smarkm *    notice, this list of conditions and the following disclaimer.
1388275Smarkm * 2. Redistributions in binary form must reproduce the above copyright
1488275Smarkm *    notice, this list of conditions and the following disclaimer in the
1588275Smarkm *    documentation and/or other materials provided with the distribution.
16161754Sru * 3. Neither the name of the University nor the names of its contributors
1788275Smarkm *    may be used to endorse or promote products derived from this software
1888275Smarkm *    without specific prior written permission.
1988275Smarkm *
2088275Smarkm * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2188275Smarkm * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2288275Smarkm * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2388275Smarkm * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2488275Smarkm * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2588275Smarkm * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2688275Smarkm * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2788275Smarkm * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2888275Smarkm * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2988275Smarkm * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3088275Smarkm * SUCH DAMAGE.
3188275Smarkm */
3288275Smarkm
3388276Smarkm#include <sys/cdefs.h>
3488276Smarkm__FBSDID("$FreeBSD: releng/10.3/usr.bin/tip/tip/uucplock.c 178736 2008-05-03 02:29:02Z bms $");
3588276Smarkm
3688275Smarkm#ifndef lint
3788276Smarkm#if 0
3888275Smarkmstatic char sccsid[] = "@(#)uucplock.c	8.1 (Berkeley) 6/6/93";
39161754Srustatic const char rcsid[] = "$OpenBSD: uucplock.c,v 1.11 2006/03/16 19:32:46 deraadt Exp $";
4088276Smarkm#endif
4188275Smarkm#endif /* not lint */
4288275Smarkm
4388275Smarkm#include <sys/types.h>
4488275Smarkm#include <sys/file.h>
4588276Smarkm#include <sys/dirent.h>
4688276Smarkm#include <stdio.h>
4788276Smarkm#include <string.h>
4888276Smarkm#include <signal.h>
4988276Smarkm#include <unistd.h>
5088276Smarkm#include <stdlib.h>
5188275Smarkm#include <errno.h>
52161781Sru#include "tip.h"
5388275Smarkm#include "pathnames.h"
5488275Smarkm
55161754Sru/*
5688275Smarkm * uucp style locking routines
5788275Smarkm * return: 0 - success
58161754Sru *	  -1 - failure
5988275Smarkm */
6088275Smarkm
6188276Smarkmint
62161754Sruuu_lock(char *ttyname)
6388275Smarkm{
64161754Sru	int fd, len;
6588275Smarkm	char tbuf[sizeof(_PATH_LOCKDIRNAME) + MAXNAMLEN];
6688276Smarkm	char text_pid[81];
67161754Sru	pid_t pid;
6888275Smarkm
6988276Smarkm	(void)snprintf(tbuf, sizeof tbuf, _PATH_LOCKDIRNAME, ttyname);
7088275Smarkm	fd = open(tbuf, O_RDWR|O_CREAT|O_EXCL, 0660);
7188275Smarkm	if (fd < 0) {
7288275Smarkm		/*
7388275Smarkm		 * file is already locked
7488275Smarkm		 * check to see if the process holding the lock still exists
7588275Smarkm		 */
7688275Smarkm		fd = open(tbuf, O_RDWR, 0);
7788275Smarkm		if (fd < 0) {
7888276Smarkm			perror(tbuf);
7988276Smarkm			fprintf(stderr, "Can't open lock file.\n");
8088275Smarkm			return(-1);
8188275Smarkm		}
8288276Smarkm		len = read(fd, text_pid, sizeof(text_pid)-1);
83161754Sru		if (len<=0) {
8488276Smarkm			perror(tbuf);
8588275Smarkm			(void)close(fd);
8688276Smarkm			fprintf(stderr, "Can't read lock file.\n");
8788275Smarkm			return(-1);
8888275Smarkm		}
8988276Smarkm		text_pid[len] = 0;
9088276Smarkm		pid = atol(text_pid);
9188275Smarkm
9288275Smarkm		if (kill(pid, 0) == 0 || errno != ESRCH) {
9388275Smarkm			(void)close(fd);	/* process is still running */
9488275Smarkm			return(-1);
9588275Smarkm		}
9688275Smarkm		/*
9788275Smarkm		 * The process that locked the file isn't running, so
9888275Smarkm		 * we'll lock it ourselves
9988275Smarkm		 */
100161754Sru		fprintf(stderr, "Stale lock on %s PID=%ld... overriding.\n",
101161754Sru			ttyname, (long)pid);
10288276Smarkm		if (lseek(fd, (off_t)0, SEEK_SET) < 0) {
10388276Smarkm			perror(tbuf);
10488275Smarkm			(void)close(fd);
10588276Smarkm			fprintf(stderr, "Can't seek lock file.\n");
10688275Smarkm			return(-1);
10788275Smarkm		}
10888275Smarkm		/* fall out and finish the locking process */
10988275Smarkm	}
11088275Smarkm	pid = getpid();
111161754Sru	(void)snprintf(text_pid, sizeof text_pid, "%10ld\n", (long)pid);
11288276Smarkm	len = strlen(text_pid);
11388276Smarkm	if (write(fd, text_pid, len) != len) {
11488275Smarkm		(void)close(fd);
11588275Smarkm		(void)unlink(tbuf);
11688275Smarkm		perror("lock write");
11788275Smarkm		return(-1);
11888275Smarkm	}
11988275Smarkm	(void)close(fd);
12088275Smarkm	return(0);
12188275Smarkm}
12288275Smarkm
12388276Smarkmint
124161754Sruuu_unlock(char *ttyname)
12588275Smarkm{
12688275Smarkm	char tbuf[sizeof(_PATH_LOCKDIRNAME) + MAXNAMLEN];
12788275Smarkm
12888276Smarkm	(void)snprintf(tbuf, sizeof tbuf, _PATH_LOCKDIRNAME, ttyname);
129178736Sbms	unexcl();
13088275Smarkm	return(unlink(tbuf));
13188275Smarkm}
132