xref: /original-bsd/usr.bin/tip/uucplock.c (revision a910c8b7)
1 #ifndef lint
2 static char sccsid[] = "@(#)uucplock.c	4.6 (Berkeley) 06/25/83";
3 #endif
4 /*
5  * defs that come from uucp.h
6  */
7 #define NAMESIZE 15
8 #define FAIL -1
9 #define SAME 0
10 #define SLCKTIME 28800	/* system/device timeout (LCK.. files) in seconds (8 hours) */
11 #define ASSERT(e, f, v) if (!(e)) {\
12 	fprintf(stderr, "AERROR - (%s) ", "e");\
13 	fprintf(stderr, f, v);\
14 	finish(FAIL);\
15 }
16 
17 #define LOCKPRE "/usr/spool/uucp/LCK."
18 
19 /*
20  * This code is taken almost directly from uucp and follows the same
21  * conventions.  This is important since uucp and tip should
22  * respect each others locks.
23  */
24 
25 	/*  ulockf 3.2  10/26/79  11:40:29  */
26 /* #include "uucp.h" */
27 #include <sys/types.h>
28 #include <sys/stat.h>
29 #include <stdio.h>
30 
31 /*******
32  *	ulockf(file, atime)
33  *	char *file;
34  *	time_t atime;
35  *
36  *	ulockf  -  this routine will create a lock file (file).
37  *	If one already exists, the create time is checked for
38  *	older than the age time (atime).
39  *	If it is older, an attempt will be made to unlink it
40  *	and create a new one.
41  *
42  *	return codes:  0  |  FAIL
43  */
44 
45 static
46 ulockf(file, atime)
47 	char *file;
48 	time_t atime;
49 {
50 	struct stat stbuf;
51 	time_t ptime;
52 	int ret;
53 	static int pid = -1;
54 	static char tempfile[NAMESIZE];
55 
56 	if (pid < 0) {
57 		pid = getpid();
58 		sprintf(tempfile, "/usr/spool/uucp/LTMP.%d", pid);
59 	}
60 	if (onelock(pid, tempfile, file) == -1) {
61 		/* lock file exists */
62 		/* get status to check age of the lock file */
63 		ret = stat(file, &stbuf);
64 		if (ret != -1) {
65 			time(&ptime);
66 			if ((ptime - stbuf.st_ctime) < atime) {
67 				/* file not old enough to delete */
68 				return (FAIL);
69 			}
70 		}
71 		ret = unlink(file);
72 		ret = onelock(pid, tempfile, file);
73 		if (ret != 0)
74 			return (FAIL);
75 	}
76 	stlock(file);
77 	return (0);
78 }
79 
80 #define MAXLOCKS 10	/* maximum number of lock files */
81 char *Lockfile[MAXLOCKS];
82 int Nlocks = 0;
83 
84 /***
85  *	stlock(name)	put name in list of lock files
86  *	char *name;
87  *
88  *	return codes:  none
89  */
90 
91 static
92 stlock(name)
93 	char *name;
94 {
95 	char *p;
96 	extern char *calloc();
97 	int i;
98 
99 	for (i = 0; i < Nlocks; i++) {
100 		if (Lockfile[i] == NULL)
101 			break;
102 	}
103 	ASSERT(i < MAXLOCKS, "TOO MANY LOCKS %d", i);
104 	if (i >= Nlocks)
105 		i = Nlocks++;
106 	p = calloc(strlen(name) + 1, sizeof (char));
107 	ASSERT(p != NULL, "CAN NOT ALLOCATE FOR %s", name);
108 	strcpy(p, name);
109 	Lockfile[i] = p;
110 	return;
111 }
112 
113 /***
114  *	rmlock(name)	remove all lock files in list
115  *	char *name;	or name
116  *
117  *	return codes: none
118  */
119 
120 static
121 rmlock(name)
122 	char *name;
123 {
124 	int i;
125 
126 	for (i = 0; i < Nlocks; i++) {
127 		if (Lockfile[i] == NULL)
128 			continue;
129 		if (name == NULL || strcmp(name, Lockfile[i]) == SAME) {
130 			unlink(Lockfile[i]);
131 			free(Lockfile[i]);
132 			Lockfile[i] = NULL;
133 		}
134 	}
135 }
136 
137 /*
138  * this stuff from pjw
139  *  /usr/pjw/bin/recover - check pids to remove unnecessary locks
140  *
141  *	isalock(name) returns 0 if the name is a lock
142  *
143  *	onelock(pid,tempfile,name) makes lock a name
144  *	on behalf of pid.  Tempfile must be in the same
145  *	file system as name.
146  *
147  *	lock(pid,tempfile,names) either locks all the
148  *	names or none of them
149  */
150 static
151 isalock(name)
152 	char *name;
153 {
154 	struct stat xstat;
155 
156 	if (stat(name, &xstat) < 0)
157 		return (0);
158 	if (xstat.st_size != sizeof(int))
159 		return (0);
160 	return (1);
161 }
162 
163 static
164 onelock(pid, tempfile, name)
165 	char *tempfile, *name;
166 {
167 	int fd;
168 
169 	fd = creat(tempfile, 0444);
170 	if (fd < 0)
171 		return (-1);
172 	write(fd,(char *)&pid, sizeof(int));
173 	close(fd);
174 	if (link(tempfile, name) < 0) {
175 		unlink(tempfile);
176 		return (-1);
177 	}
178 	unlink(tempfile);
179 	return (0);
180 }
181 
182 /***
183  *	delock(s)	remove a lock file
184  *	char *s;
185  *
186  *	return codes:  0  |  FAIL
187  */
188 
189 delock(s)
190 	char *s;
191 {
192 	char ln[30];
193 
194 	sprintf(ln, "%s.%s", LOCKPRE, s);
195 	rmlock(ln);
196 }
197 
198 /***
199  *	mlock(sys)	create system lock
200  *	char *sys;
201  *
202  *	return codes:  0  |  FAIL
203  */
204 
205 mlock(sys)
206 	char *sys;
207 {
208 	char lname[30];
209 	sprintf(lname, "%s.%s", LOCKPRE, sys);
210 	return (ulockf(lname, (time_t) SLCKTIME ) < 0 ? FAIL : 0);
211 }
212