Commit | Line | Data |
---|---|---|
05862919 SL |
1 | #ifndef lint |
2 | static char sccsid[] = "@(#)uucplock.c 4.6 (Berkeley) %G%"; | |
3 | #endif | |
5b6474c5 BJ |
4 | /* |
5 | * defs that come from uucp.h | |
6 | */ | |
7 | #define NAMESIZE 15 | |
8 | #define FAIL -1 | |
9 | #define SAME 0 | |
6b46907f | 10 | #define SLCKTIME 28800 /* system/device timeout (LCK.. files) in seconds (8 hours) */ |
5b6474c5 BJ |
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) | |
d8feebc2 SL |
47 | char *file; |
48 | time_t atime; | |
5b6474c5 BJ |
49 | { |
50 | struct stat stbuf; | |
51 | time_t ptime; | |
52 | int ret; | |
53 | static int pid = -1; | |
6b46907f | 54 | static char tempfile[NAMESIZE]; |
5b6474c5 BJ |
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 */ | |
3f48242d | 68 | return (FAIL); |
5b6474c5 BJ |
69 | } |
70 | } | |
71 | ret = unlink(file); | |
72 | ret = onelock(pid, tempfile, file); | |
73 | if (ret != 0) | |
3f48242d | 74 | return (FAIL); |
5b6474c5 BJ |
75 | } |
76 | stlock(file); | |
3f48242d | 77 | return (0); |
5b6474c5 BJ |
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) | |
d8feebc2 | 93 | char *name; |
5b6474c5 BJ |
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) | |
d8feebc2 | 122 | char *name; |
5b6474c5 BJ |
123 | { |
124 | int i; | |
125 | ||
126 | for (i = 0; i < Nlocks; i++) { | |
127 | if (Lockfile[i] == NULL) | |
128 | continue; | |
3f48242d | 129 | if (name == NULL || strcmp(name, Lockfile[i]) == SAME) { |
5b6474c5 BJ |
130 | unlink(Lockfile[i]); |
131 | free(Lockfile[i]); | |
132 | Lockfile[i] = NULL; | |
133 | } | |
134 | } | |
5b6474c5 BJ |
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) | |
d8feebc2 | 152 | char *name; |
5b6474c5 BJ |
153 | { |
154 | struct stat xstat; | |
155 | ||
3f48242d SL |
156 | if (stat(name, &xstat) < 0) |
157 | return (0); | |
158 | if (xstat.st_size != sizeof(int)) | |
159 | return (0); | |
160 | return (1); | |
5b6474c5 BJ |
161 | } |
162 | ||
163 | static | |
3f48242d SL |
164 | onelock(pid, tempfile, name) |
165 | char *tempfile, *name; | |
5b6474c5 BJ |
166 | { |
167 | int fd; | |
168 | ||
3f48242d SL |
169 | fd = creat(tempfile, 0444); |
170 | if (fd < 0) | |
171 | return (-1); | |
172 | write(fd,(char *)&pid, sizeof(int)); | |
5b6474c5 | 173 | close(fd); |
3f48242d | 174 | if (link(tempfile, name) < 0) { |
5b6474c5 | 175 | unlink(tempfile); |
3f48242d | 176 | return (-1); |
5b6474c5 BJ |
177 | } |
178 | unlink(tempfile); | |
3f48242d | 179 | return (0); |
5b6474c5 BJ |
180 | } |
181 | ||
182 | /*** | |
183 | * delock(s) remove a lock file | |
184 | * char *s; | |
185 | * | |
186 | * return codes: 0 | FAIL | |
187 | */ | |
188 | ||
189 | delock(s) | |
d8feebc2 | 190 | char *s; |
5b6474c5 BJ |
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) | |
d8feebc2 | 206 | char *sys; |
5b6474c5 BJ |
207 | { |
208 | char lname[30]; | |
209 | sprintf(lname, "%s.%s", LOCKPRE, sys); | |
3f48242d | 210 | return (ulockf(lname, (time_t) SLCKTIME ) < 0 ? FAIL : 0); |
5b6474c5 | 211 | } |