Commit | Line | Data |
---|---|---|
758edcef | 1 | #ifndef lint |
95f51977 | 2 | static char sccsid[] = "@(#)ulockf.c 5.5 (Berkeley) 10/9/85"; |
758edcef SL |
3 | #endif |
4 | ||
5 | #include "uucp.h" | |
758edcef | 6 | #include <sys/stat.h> |
4eac5393 | 7 | #include <errno.h> |
758edcef | 8 | |
4eac5393 JB |
9 | #define LCKMODE 0444 /* File mode for lock files */ |
10 | #define MAXLOCKS 16 /* Maximum number of lock files */ | |
11 | ||
12 | char *Lockfile[MAXLOCKS]; | |
13 | char *LockDirectory = LOCKDIR; | |
14 | int Nlocks = 0; | |
758edcef | 15 | |
a075b7ef JB |
16 | /*LINTLIBRARY*/ |
17 | ||
46b15d8a | 18 | /* |
4eac5393 JB |
19 | * This routine will attempt to create a lock file (file). |
20 | * It makes sure that the lock file is valid if it already exists. | |
758edcef | 21 | * |
a075b7ef | 22 | * return codes: SUCCESS | FAIL |
758edcef | 23 | */ |
1a85e9d2 RC |
24 | ulockf(hfile, atime) |
25 | char *hfile; | |
758edcef SL |
26 | time_t atime; |
27 | { | |
4eac5393 JB |
28 | register char *p; |
29 | register int i; | |
758edcef | 30 | static char tempfile[NAMESIZE]; |
1a85e9d2 | 31 | char file[NAMESIZE]; |
4eac5393 JB |
32 | static int pid = -1; |
33 | extern int errno; | |
758edcef SL |
34 | |
35 | if (pid < 0) { | |
36 | pid = getpid(); | |
4eac5393 | 37 | sprintf(tempfile, "%s/LTMP.%d", LockDirectory, pid); |
758edcef | 38 | } |
4eac5393 JB |
39 | sprintf(file, "%s/LCK..%s", LockDirectory, hfile); |
40 | i = 0; | |
41 | while (onelock(pid, tempfile, file) == -1) { /* lock file exists */ | |
42 | #if !defined(BSD4_2) && !defined(USG) | |
43 | struct stat stbuf; | |
44 | time_t ptime; | |
758edcef | 45 | /* get status to check age of the lock file */ |
4eac5393 JB |
46 | if (stat(file, &stbuf) == 0) { |
47 | (void) time(&ptime); | |
48 | if ((ptime - stbuf.st_ctime) < atime) | |
49 | return FAIL; /* file not old enough to delete */ | |
758edcef | 50 | } |
4eac5393 JB |
51 | #else BSD4_2 || USG |
52 | register int fd; | |
53 | fd = open(file, 0); | |
54 | if (fd >= 0) { | |
55 | int upid, ret; | |
56 | ret = read(fd, &upid, sizeof upid); | |
57 | close(fd); | |
58 | if (ret == sizeof upid && (kill(upid, 0) == 0 | |
59 | || errno != ESRCH)) | |
60 | return FAIL; /* process is still running */ | |
61 | } | |
62 | #endif BSD4_2 || USG | |
63 | assert("DEAD LOCK", file, errno); | |
64 | logent(file, "DEAD LOCK"); | |
65 | (void) unlink(file); | |
66 | sleep(5); /* avoid a possible race */ | |
67 | ASSERT(i++ < 5, "CAN'T GET LOCKFILE", tempfile, errno); | |
758edcef | 68 | } |
758edcef SL |
69 | |
70 | for (i = 0; i < Nlocks; i++) { | |
71 | if (Lockfile[i] == NULL) | |
72 | break; | |
73 | } | |
46b15d8a | 74 | ASSERT(i < MAXLOCKS, "TOO MANY LOCKS", CNULL, i); |
758edcef SL |
75 | if (i >= Nlocks) |
76 | i = Nlocks++; | |
4eac5393 JB |
77 | p = malloc((unsigned)(strlen(file)+1)); |
78 | ASSERT(p != NULL, "CAN NOT ALLOCATE FOR", file, 0); | |
79 | strcpy(p, file); | |
758edcef | 80 | Lockfile[i] = p; |
758edcef | 81 | |
4eac5393 JB |
82 | return SUCCESS; |
83 | } | |
758edcef | 84 | |
46b15d8a | 85 | /* |
4eac5393 | 86 | * remove all lock files in list or name |
758edcef | 87 | */ |
758edcef SL |
88 | rmlock(name) |
89 | register char *name; | |
90 | { | |
91 | register int i; | |
4eac5393 | 92 | char file[MAXFULLNAME]; |
758edcef | 93 | |
4eac5393 JB |
94 | if (name != NULL) { |
95 | sprintf(file, "%s/LCK..%s", LockDirectory, name); | |
96 | name = file; | |
97 | } | |
758edcef SL |
98 | for (i = 0; i < Nlocks; i++) { |
99 | if (Lockfile[i] == NULL) | |
100 | continue; | |
46b15d8a | 101 | if (name == NULL || strcmp(name, Lockfile[i]) == SAME) { |
758edcef SL |
102 | unlink(Lockfile[i]); |
103 | free(Lockfile[i]); | |
104 | Lockfile[i] = NULL; | |
105 | } | |
106 | } | |
758edcef SL |
107 | } |
108 | ||
758edcef | 109 | /* |
4eac5393 | 110 | * makes lock a name on behalf of pid. Tempfile must be in the same |
758edcef | 111 | * file system as name. |
758edcef | 112 | */ |
a075b7ef JB |
113 | onelock(pid, tempfile, name) |
114 | int pid; | |
4eac5393 | 115 | char *tempfile, *name; |
46b15d8a | 116 | { |
4eac5393 | 117 | register int fd, ret; |
46b15d8a RC |
118 | #ifdef VMS |
119 | fd = creat(name, LCKMODE, "1version"); | |
120 | #else !VMS | |
121 | fd = creat(tempfile, LCKMODE); | |
122 | #endif !VMS | |
4eac5393 JB |
123 | if (fd < 0) { |
124 | DEBUG(1,"Can't creat temp file %s ", tempfile); | |
125 | DEBUG(1,"-- errno %d", errno); | |
46b15d8a | 126 | return FAIL; |
758edcef | 127 | } |
4eac5393 JB |
128 | ret = write(fd, (char *)&pid, sizeof(int)); |
129 | (void) close(fd); | |
46b15d8a | 130 | |
4eac5393 JB |
131 | if (ret != sizeof(int)) { |
132 | DEBUG(1,"Temp file write failed -- errno %d\n", errno); | |
133 | #ifdef VMS | |
134 | (void) unlink(name); | |
135 | #else !VMS | |
136 | (void) unlink(tempfile); | |
137 | #endif !VMS | |
138 | return FAIL; | |
139 | } | |
140 | #ifndef VMS | |
141 | if (link(tempfile, name) < 0) { | |
142 | (void) unlink(tempfile); | |
46b15d8a | 143 | return FAIL; |
758edcef | 144 | } |
4eac5393 JB |
145 | unlink(tempfile); |
146 | #endif !VMS | |
46b15d8a | 147 | return SUCCESS; |
758edcef SL |
148 | } |
149 | ||
4eac5393 | 150 | #if !defined(BSD4_2) && !defined(USG) |
46b15d8a | 151 | /* |
46b15d8a | 152 | * update 'change' time for lock files |
758edcef | 153 | * |
758edcef SL |
154 | * Only update ctime, not mtime or atime. |
155 | * The 'chmod' method permits cu(I)-like programs | |
156 | * to determine how long uucp has been on the line. | |
157 | * The old "change access, mod, and change time" method | |
158 | * can be had by defining OLDTOUCH | |
159 | * | |
160 | * return code - none | |
161 | */ | |
162 | ||
163 | ultouch() | |
164 | { | |
758edcef SL |
165 | static time_t lasttouch = 0; |
166 | register int i; | |
167 | struct ut { | |
168 | time_t actime; | |
169 | time_t modtime; | |
170 | } ut; | |
171 | ||
4eac5393 JB |
172 | #ifdef USG |
173 | time(&Now.time); | |
174 | t1.millitm = 0; | |
175 | #else !USG | |
176 | ftime(&Now); | |
177 | #endif !USG | |
178 | ut.actime = ut.modtime = Now.time; | |
758edcef SL |
179 | /* Do not waste time touching locking files too often */ |
180 | /* (But, defend against backward time changes) */ | |
181 | if (ut.actime >= lasttouch && ut.actime < lasttouch+60) | |
182 | return; | |
183 | lasttouch = ut.actime; | |
184 | DEBUG(4, "ultouch\n", 0); | |
185 | ||
186 | for (i = 0; i < Nlocks; i++) { | |
187 | if (Lockfile[i] == NULL) | |
188 | continue; | |
189 | #ifdef OLDTOUCH | |
190 | utime(Lockfile[i], &ut); | |
46b15d8a | 191 | #else !OLDTOUCH |
758edcef | 192 | chmod(Lockfile[i], LCKMODE); |
46b15d8a | 193 | #endif !OLDTOUCH |
758edcef SL |
194 | } |
195 | } | |
4eac5393 | 196 | #endif !BSD4_2 && ! USG |