Commit | Line | Data |
---|---|---|
3f48242d | 1 | /* uucplock.c 4.3 81/11/29 */ |
5b6474c5 BJ |
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) | |
d8feebc2 SL |
45 | char *file; |
46 | time_t atime; | |
5b6474c5 BJ |
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 */ | |
3f48242d | 66 | return (FAIL); |
5b6474c5 BJ |
67 | } |
68 | } | |
69 | ret = unlink(file); | |
70 | ret = onelock(pid, tempfile, file); | |
71 | if (ret != 0) | |
3f48242d | 72 | return (FAIL); |
5b6474c5 BJ |
73 | } |
74 | stlock(file); | |
3f48242d | 75 | return (0); |
5b6474c5 BJ |
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) | |
d8feebc2 | 91 | char *name; |
5b6474c5 BJ |
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) | |
d8feebc2 | 120 | char *name; |
5b6474c5 BJ |
121 | { |
122 | int i; | |
123 | ||
124 | for (i = 0; i < Nlocks; i++) { | |
125 | if (Lockfile[i] == NULL) | |
126 | continue; | |
3f48242d | 127 | if (name == NULL || strcmp(name, Lockfile[i]) == SAME) { |
5b6474c5 BJ |
128 | unlink(Lockfile[i]); |
129 | free(Lockfile[i]); | |
130 | Lockfile[i] = NULL; | |
131 | } | |
132 | } | |
5b6474c5 BJ |
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) | |
d8feebc2 | 150 | char *name; |
5b6474c5 BJ |
151 | { |
152 | struct stat xstat; | |
153 | ||
3f48242d SL |
154 | if (stat(name, &xstat) < 0) |
155 | return (0); | |
156 | if (xstat.st_size != sizeof(int)) | |
157 | return (0); | |
158 | return (1); | |
5b6474c5 BJ |
159 | } |
160 | ||
161 | static | |
3f48242d SL |
162 | onelock(pid, tempfile, name) |
163 | char *tempfile, *name; | |
5b6474c5 BJ |
164 | { |
165 | int fd; | |
166 | ||
3f48242d SL |
167 | fd = creat(tempfile, 0444); |
168 | if (fd < 0) | |
169 | return (-1); | |
170 | write(fd,(char *)&pid, sizeof(int)); | |
5b6474c5 | 171 | close(fd); |
3f48242d | 172 | if (link(tempfile, name) < 0) { |
5b6474c5 | 173 | unlink(tempfile); |
3f48242d | 174 | return (-1); |
5b6474c5 BJ |
175 | } |
176 | unlink(tempfile); | |
3f48242d | 177 | return (0); |
5b6474c5 BJ |
178 | } |
179 | ||
180 | /*** | |
181 | * delock(s) remove a lock file | |
182 | * char *s; | |
183 | * | |
184 | * return codes: 0 | FAIL | |
185 | */ | |
186 | ||
187 | delock(s) | |
d8feebc2 | 188 | char *s; |
5b6474c5 BJ |
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) | |
d8feebc2 | 204 | char *sys; |
5b6474c5 BJ |
205 | { |
206 | char lname[30]; | |
207 | sprintf(lname, "%s.%s", LOCKPRE, sys); | |
3f48242d | 208 | return (ulockf(lname, (time_t) SLCKTIME ) < 0 ? FAIL : 0); |
5b6474c5 | 209 | } |