cast (time_t) and lseek(fd,0L...) for pdp11s
[unix-history] / usr / src / usr.bin / uucp / libuu / ulockf.c
CommitLineData
758edcef
SL
1#ifndef lint
2static char sccsid[] = "@(#)ulockf.c 5.1 (Berkeley) %G%";
3#endif
4
5#include "uucp.h"
6#include <sys/types.h>
7#include <sys/stat.h>
8
9
10extern time_t time();
11
12/* File mode for lock files */
13#define LCKMODE 0444
14
15/*******
16 * ulockf(file, atime)
17 * char *file;
18 * time_t atime;
19 *
20 * ulockf - this routine will create a lock file (file).
21 * If one already exists, the create time is checked for
22 * older than the age time (atime).
23 * If it is older, an attempt will be made to unlink it
24 * and create a new one.
25 *
26 * return codes: 0 | FAIL
27 */
28
29ulockf(file, atime)
30register char *file;
31time_t atime;
32{
33 struct stat stbuf;
34 time_t ptime;
35 register int ret;
36 static int pid = -1;
37 static char tempfile[NAMESIZE];
38
39 if (pid < 0) {
40 pid = getpid();
41 sprintf(tempfile, "LTMP.%d", pid);
42 }
43 if (onelock(pid, tempfile, file) == -1) {
44 /* lock file exists */
45 /* get status to check age of the lock file */
46 ret = stat(file, &stbuf);
47 if (ret != -1) {
48 time(&ptime);
49 if ((ptime - stbuf.st_ctime) < atime) {
50 /* file not old enough to delete */
51 return(FAIL);
52 }
53 }
54 ret = unlink(file);
55 ret = onelock(pid, tempfile, file);
56 if (ret != 0)
57 return(FAIL);
58 }
59 stlock(file);
60 return(0);
61}
62
63
64#define MAXLOCKS 10 /* maximum number of lock files */
65char *Lockfile[MAXLOCKS];
66int Nlocks = 0;
67
68/***
69 * stlock(name) put name in list of lock files
70 * char *name;
71 *
72 * return codes: none
73 */
74
75stlock(name)
76register char *name;
77{
78 register char *p;
79 register int i;
80
81 for (i = 0; i < Nlocks; i++) {
82 if (Lockfile[i] == NULL)
83 break;
84 }
85 ASSERT(i < MAXLOCKS, "TOO MANY LOCKS", "", i);
86 if (i >= Nlocks)
87 i = Nlocks++;
88 p = calloc((unsigned)(strlen(name)+1), sizeof (char));
89 ASSERT(p != NULL, "CAN NOT ALLOCATE FOR", name, 0);
90 strcpy(p, name);
91 Lockfile[i] = p;
92 return;
93}
94
95
96/***
97 * rmlock(name) remove all lock files in list
98 * char *name; or name
99 *
100 * return codes: none
101 */
102
103rmlock(name)
104register char *name;
105{
106 register int i;
107
108 for (i = 0; i < Nlocks; i++) {
109 if (Lockfile[i] == NULL)
110 continue;
111 if (name == NULL
112 || strcmp(name, Lockfile[i]) == SAME) {
113 unlink(Lockfile[i]);
114 free(Lockfile[i]);
115 Lockfile[i] = NULL;
116 }
117 }
118 return;
119}
120
121
122/*
123 * this stuff from pjw
124 * /usr/pjw/bin/recover - Check pids to remove unnecessary locks.
125 * isalock(name) returns 0 if the name is a lock.
126 * unlock(name) unlocks name if it is a lock.
127 * onelock(pid,tempfile,name) makes lock a name
128 * on behalf of pid. Tempfile must be in the same
129 * file system as name.
130 * lock(pid,tempfile,names) either locks all the
131 * names or none of them.
132 */
133isalock(name) char *name;
134{
135 struct stat xstat;
136 if(stat(name,&xstat)<0) return(0);
137 if(xstat.st_size!=sizeof(int)) return(0);
138 return(1);
139}
140unlock(name) char *name;
141{
142 if(isalock(name)) return(unlink(name));
143 else return(-1);
144}
145onelock(pid,tempfile,name) char *tempfile,*name;
146{ register int fd;
147 fd=creat(tempfile,LCKMODE);
148 if(fd<0) return(-1);
149 write(fd,(char *) &pid,sizeof(int));
150 close(fd);
151 if(link(tempfile,name)<0)
152 { unlink(tempfile);
153 return(-1);
154 }
155 unlink(tempfile);
156 return(0);
157}
158lock(pid,tempfile,names) char *tempfile;
159register char **names;
160{ register int i,j;
161 for(i=0;names[i]!=0;i++)
162 { if(onelock(pid,tempfile,names[i])==0) continue;
163 for(j=0;j<i;j++) unlink(names[j]);
164 return(-1);
165 }
166 return(0);
167}
168
169#define LOCKPRE "LCK."
170
171/***
172 * delock(s) remove a lock file
173 * char *s;
174 *
175 * return codes: 0 | FAIL
176 */
177
178delock(s)
179char *s;
180{
181 char ln[30];
182
183 sprintf(ln, "%s.%s", LOCKPRE, s);
184 rmlock(ln);
185}
186
187
188/***
189 * mlock(sys) create system lock
190 * char *sys;
191 *
192 * return codes: 0 | FAIL
193 */
194
195mlock(sys)
196char *sys;
197{
198 char lname[30];
199 sprintf(lname, "%s.%s", LOCKPRE, sys);
200 return(ulockf(lname, (time_t) SLCKTIME ) < 0 ? FAIL : 0);
201}
202
203
204/***
205 * ultouch() update 'change' time for lock files
206 *
207 * -- mod by rti!trt --
208 * Only update ctime, not mtime or atime.
209 * The 'chmod' method permits cu(I)-like programs
210 * to determine how long uucp has been on the line.
211 * The old "change access, mod, and change time" method
212 * can be had by defining OLDTOUCH
213 *
214 * return code - none
215 */
216
217ultouch()
218{
219 time_t time();
220 static time_t lasttouch = 0;
221 register int i;
222 struct ut {
223 time_t actime;
224 time_t modtime;
225 } ut;
226
227 ut.actime = time(&ut.modtime);
228 /* Do not waste time touching locking files too often */
229 /* (But, defend against backward time changes) */
230 if (ut.actime >= lasttouch && ut.actime < lasttouch+60)
231 return;
232 lasttouch = ut.actime;
233 DEBUG(4, "ultouch\n", 0);
234
235 for (i = 0; i < Nlocks; i++) {
236 if (Lockfile[i] == NULL)
237 continue;
238#ifdef OLDTOUCH
239 utime(Lockfile[i], &ut);
240#else
241 chmod(Lockfile[i], LCKMODE);
242#endif
243 }
244}