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