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