Commit | Line | Data |
---|---|---|
d8feebc2 | 1 | /* uucplock.c 4.2 81/11/20 */ |
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 */ | |
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) | |
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; | |
127 | if (name == NULL | |
128 | || strcmp(name, Lockfile[i]) == SAME) { | |
129 | unlink(Lockfile[i]); | |
130 | free(Lockfile[i]); | |
131 | Lockfile[i] = NULL; | |
132 | } | |
133 | } | |
134 | return; | |
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 | ||
156 | if(stat(name,&xstat)<0) | |
157 | return(0); | |
158 | if(xstat.st_size!=sizeof(int)) | |
159 | return(0); | |
160 | return(1); | |
161 | } | |
162 | ||
163 | static | |
164 | onelock(pid,tempfile,name) | |
d8feebc2 | 165 | char *tempfile,*name; |
5b6474c5 BJ |
166 | { |
167 | int fd; | |
168 | ||
169 | fd=creat(tempfile,0444); | |
170 | if(fd<0) | |
171 | return(-1); | |
172 | write(fd,(char *) &pid,sizeof(int)); | |
173 | close(fd); | |
174 | if(link(tempfile,name)<0) { | |
175 | unlink(tempfile); | |
176 | return(-1); | |
177 | } | |
178 | unlink(tempfile); | |
179 | return(0); | |
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); | |
210 | return(ulockf(lname, (time_t) SLCKTIME ) < 0 ? FAIL : 0); | |
211 | } |