|
|
1.1 root 1: /* %W%
2: */
3: #include "uucp.h"
4: VERSION(%W%);
5:
6: #ifdef V7
7: #define O_RDONLY 0
8: #endif
9:
10: static void stlock();
11: static int onelock();
12:
13: #ifdef ATTSVKILL
14: /*
15: * create a lock file (file).
16: * If one already exists, send a signal 0 to the process--if
17: * it fails, then unlink it and make a new one.
18: *
19: * input:
20: * file - name of the lock file
21: * atime - is unused, but we keep it for lint compatibility with non-ATTSVKILL
22: *
23: * return:
24: * 0 -> success
25: * FAIL -> failure
26: */
27: ulockf(file, atime)
28: register char *file;
29: time_t atime;
30: {
31: #ifdef ASCIILOCKS
32: static char pid[SIZEOFPID+2] = { '\0' }; /* +2 for '\n' and NULL */
33: #else
34: static int pid = -1;
35: #endif
36:
37: static char tempfile[MAXNAMESIZE];
38:
39: #ifdef V8
40: char *cp;
41: #endif
42:
43: #ifdef ASCIILOCKS
44: if (pid[0] == '\0') {
45: (void) sprintf(pid, "%*d\n", SIZEOFPID, getpid());
46: #else
47: if (pid < 0) {
48: pid = getpid();
49: #endif
50: (void) sprintf(tempfile, "%s/LTMP.%d", X_LOCKDIR, getpid());
51: }
52:
53: #ifdef V8 /* this wouldn't be a problem if we used lock directories */
54: /* some day the truncation of system names will bite us */
55: cp = strrchr(file, '/');
56: if (cp++ != CNULL)
57: if (strlen(cp) > V8DIRSIZ)
58: *(cp+V8DIRSIZ) = NULLCHAR;
59: #endif V8
60: if (onelock(pid, tempfile, file) == -1) {
61: (void) unlink(tempfile);
62: if (checkLock(file))
63: return(FAIL);
64: else {
65: if (onelock(pid, tempfile, file)) {
66: (void) unlink(tempfile);
67: DEBUG(4,"ulockf failed in onelock()\n","");
68: return(FAIL);
69: }
70: }
71: }
72:
73: stlock(file);
74: return(0);
75: }
76:
77: /*
78: * check to see if the lock file exists and is still active
79: * - use kill(pid,0) - (this only works on ATTSV and some hacked
80: * BSD systems at this time)
81: * return:
82: * 0 -> success (lock file removed - no longer active
83: * FAIL -> lock file still active
84: */
85: checkLock(file)
86: register char *file;
87: {
88: register int ret;
89: int lpid = -1;
90: #ifdef ASCIILOCKS
91: char alpid[SIZEOFPID+2]; /* +2 for '\n' and NULL */
92: #endif
93: int fd;
94: extern int errno;
95:
96: fd = open(file, O_RDONLY);
97: DEBUG(4, "ulockf file %s\n", file);
98: if (fd == -1) {
99: if (errno == ENOENT) /* file does not exist -- OK */
100: return(0);
101: DEBUG(4,"Lock File--can't read (errno %d) --remove it!\n", errno);
102: goto unlk;
103: }
104: #ifdef ASCIILOCKS
105: ret = read(fd, (char *) alpid, SIZEOFPID+1); /* +1 for '\n' */
106: (void) close(fd);
107: if (ret != (SIZEOFPID+1)) {
108: #else
109: ret = read(fd, (char *) &lpid, sizeof(int));
110: (void) close(fd);
111: if (ret != sizeof(int)) {
112: #endif
113:
114: DEBUG(4, "Lock File--bad format--remove it!\n", "");
115: goto unlk;
116: }
117: #ifdef ASCIILOCKS
118: lpid = atoi(alpid);
119: #endif
120: if ((ret=kill(lpid, 0)) == 0 || errno == EPERM) {
121: DEBUG(4, "Lock File--process still active--not removed\n","");
122: return(FAIL);
123: }
124: else { /* process no longer active */
125: DEBUG(4, "kill pid (%d), ", lpid);
126: DEBUG(4, "returned %d", ret);
127: DEBUG(4, "--ok to remove lock file (%s)\n", file);
128: }
129: unlk:
130:
131: if (unlink(file) != 0) {
132: DEBUG(4,"ulockf failed in unlink()\n","");
133: return(FAIL);
134: }
135: return(0);
136: }
137: #else
138:
139: /*
140: * check to see if the lock file exists and is still active
141: * - consider the lock expired after SLCKTIME seconds.
142: * return:
143: * 0 -> success (lock file removed - no longer active
144: * FAIL -> lock file still active
145: */
146: checkLock(file)
147: register char *file;
148: {
149: register int ret;
150: int lpid = -1;
151: int fd;
152: extern int errno;
153: struct stat stbuf;
154: time_t ptime, time();
155:
156: fd = open(file, 0);
157: DEBUG(4, "ulockf file %s\n", file);
158: if (fd == -1) {
159: if (errno == ENOENT) /* file does not exist -- OK */
160: return(0);
161: DEBUG(4,"Lock File--can't read (errno %d) --remove it!\n", errno);
162: goto unlk;
163: }
164: ret = stat(file, &stbuf);
165: if (ret != -1) {
166: (void) time(&ptime);
167: if ((ptime - stbuf.st_ctime) < SLCKTIME) {
168:
169: /*
170: * file not old enough to delete
171: */
172: return(FAIL);
173: }
174: }
175: unlk:
176: DEBUG(4, "--ok to remove lock file (%s)\n", file);
177:
178: if (unlink(file) != 0) {
179: DEBUG(4,"ulockf failed in unlink()\n","");
180: return(FAIL);
181: }
182: return(0);
183: }
184:
185:
186: /*
187: * create a lock file (file).
188: * If one already exists, the create time is checked for
189: * older than the age time (atime).
190: * If it is older, an attempt will be made to unlink it
191: * and create a new one.
192: * return:
193: * 0 -> success
194: * FAIL -> failure
195: */
196: ulockf(file, atime)
197: register char *file;
198: time_t atime;
199: {
200: register int ret;
201: struct stat stbuf;
202: #ifdef ASCIILOCKS
203: static char pid[SIZEOFPID+2] = { '\0' }; /* +2 for '\n' and null */
204: #else
205: static int pid = -1;
206: #endif
207: static char tempfile[MAXNAMESIZE];
208: time_t ptime, time();
209: #ifdef V8
210: char *cp;
211: #endif
212:
213:
214: #ifdef ASCIILOCKS
215: if (pid[0] == '\0') {
216: (void) sprintf(pid, "%*d\n", SIZEOFPID, getpid());
217: #else
218: if (pid < 0) {
219: pid = getpid();
220: #endif
221: (void) sprintf(tempfile, "%s/LTMP.%d", X_LOCKDIR, getpid());
222: }
223: #ifdef V8 /* this wouldn't be a problem if we used lock directories */
224: /* some day the truncation of system names will bite us */
225: cp = strrchr(file, '/');
226: if (cp++ != CNULL)
227: if (strlen(cp) > V8DIRSIZ)
228: *(cp+V8DIRSIZ) = NULLCHAR;
229: #endif V8
230: if (onelock(pid, tempfile, file) == -1) {
231:
232: /*
233: * lock file exists
234: * get status to check age of the lock file
235: */
236: (void) unlink(tempfile);
237: ret = stat(file, &stbuf);
238: if (ret != -1) {
239: (void) time(&ptime);
240: if ((ptime - stbuf.st_ctime) < atime) {
241:
242: /*
243: * file not old enough to delete
244: */
245: return(FAIL);
246: }
247: }
248: ret = unlink(file);
249: ret = onelock(pid, tempfile, file);
250: if (ret != 0)
251: return(FAIL);
252: }
253: stlock(file);
254: return(0);
255: }
256: #endif
257:
258: #define MAXLOCKS 10 /* maximum number of lock files */
259: char *Lockfile[MAXLOCKS];
260: int Nlocks = 0;
261:
262: /*
263: * put name in list of lock files
264: * return:
265: * none
266: */
267: static
268: void
269: stlock(name)
270: char *name;
271: {
272: register int i;
273: char *p;
274:
275: for (i = 0; i < Nlocks; i++) {
276: if (Lockfile[i] == NULL)
277: break;
278: }
279: ASSERT(i < MAXLOCKS, "TOO MANY LOCKS", "", i);
280: if (i >= Nlocks)
281: i = Nlocks++;
282: p = calloc((unsigned) strlen(name) + 1, sizeof (char));
283: ASSERT(p != NULL, "CAN NOT ALLOCATE FOR", name, 0);
284: (void) strcpy(p, name);
285: Lockfile[i] = p;
286: return;
287: }
288:
289: /*
290: * remove all lock files in list
291: * return:
292: * none
293: */
294: void
295: rmlock(name)
296: register char *name;
297: {
298: register int i;
299: #ifdef V8
300: char *cp;
301:
302: if (name != CNULL) {
303: cp = strrchr(name, '/');
304: if (cp++ != CNULL)
305: if (strlen(cp) > V8DIRSIZ)
306: *(cp+V8DIRSIZ) = NULLCHAR;
307: }
308: #endif V8
309:
310:
311: for (i = 0; i < Nlocks; i++) {
312: if (Lockfile[i] == NULL)
313: continue;
314: if (name == NULL || EQUALS(name, Lockfile[i])) {
315: (void) unlink(Lockfile[i]);
316: (void) free(Lockfile[i]);
317: Lockfile[i] = NULL;
318: }
319: }
320: return;
321: }
322:
323:
324:
325: /*
326: * remove a lock file
327: * return:
328: * 0 -> success
329: * FAIL -> failure
330: */
331: delock(s)
332: char *s;
333: {
334: char ln[MAXNAMESIZE];
335:
336: (void) sprintf(ln, "%s.%s", LOCKPRE, s);
337: BASENAME(ln, '/')[MAXBASENAME] = '\0';
338: rmlock(ln);
339: }
340:
341:
342: /*
343: * create system lock
344: * return:
345: * 0 -> success
346: * FAIL -> failure
347: */
348: mlock(sys)
349: char *sys;
350: {
351: char lname[MAXNAMESIZE];
352:
353: (void) sprintf(lname, "%s.%s", LOCKPRE, sys);
354: BASENAME(lname, '/')[MAXBASENAME] = '\0';
355: return(ulockf(lname, SLCKTIME) < 0 ? FAIL : 0);
356: }
357:
358:
359: /*
360: * update access and modify times for lock files
361: * return:
362: * none
363: */
364: void
365: ultouch()
366: {
367: register int i;
368: time_t time();
369:
370: struct ut {
371: time_t actime;
372: time_t modtime;
373: } ut;
374:
375: ut.actime = time(&ut.modtime);
376: for (i = 0; i < Nlocks; i++) {
377: if (Lockfile[i] == NULL)
378: continue;
379: utime(Lockfile[i], &ut);
380: }
381: return;
382: }
383:
384: /*
385: * makes a lock on behalf of pid.
386: * input:
387: * pid - process id
388: * tempfile - name of a temporary in the same file system
389: * name - lock file name (full path name)
390: * return:
391: * -1 - failed
392: * 0 - lock made successfully
393: */
394: static
395: onelock(pid,tempfile,name)
396: #ifdef ASCIILOCKS
397: char *pid;
398: #else
399: int pid;
400: #endif
401: char *tempfile, *name;
402: {
403: register int fd;
404: char cb[100];
405:
406: fd=creat(tempfile, 0444);
407: if(fd < 0){
408: (void) sprintf(cb, "%s %s %d",tempfile, name, errno);
409: logent("ULOCKC", cb);
410: if((errno == EMFILE) || (errno == ENFILE))
411: (void) unlink(tempfile);
412: return(-1);
413: }
414: #ifdef ASCIILOCKS
415: (void) write(fd, pid, SIZEOFPID+1); /* +1 for '\n' */
416: #else
417: (void) write(fd,(char *) &pid,sizeof(int));
418: #endif
419: (void) chmod(tempfile,0444); /* silly */
420: (void) chown(tempfile, UUCPUID, UUCPGID);
421: (void) close(fd);
422: if(link(tempfile,name)<0){
423: DEBUG(4, "%s: ", sys_errlist[errno]);
424: DEBUG(4, "link(%s, ", tempfile);
425: DEBUG(4, "%s)\n", name);
426: if(unlink(tempfile)< 0){
427: (void) sprintf(cb, "ULK err %s %d", tempfile, errno);
428: logent("ULOCKLNK", cb);
429: }
430: return(-1);
431: }
432: if(unlink(tempfile)<0){
433: (void) sprintf(cb, "%s %d",tempfile,errno);
434: logent("ULOCKF", cb);
435: }
436: return(0);
437: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.