|
|
1.1 root 1: #ifndef lint
2: static char sccsid[] = "@(#)ulockf.c 5.1 (Berkeley) 7/2/83";
3: #endif
4:
5: #include "uucp.h"
6: #include <sys/types.h>
7: #include <sys/stat.h>
8:
9:
10: extern 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:
29: ulockf(file, atime)
30: register char *file;
31: time_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 */
65: char *Lockfile[MAXLOCKS];
66: int Nlocks = 0;
67:
68: /***
69: * stlock(name) put name in list of lock files
70: * char *name;
71: *
72: * return codes: none
73: */
74:
75: stlock(name)
76: register 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:
103: rmlock(name)
104: register 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: */
133: isalock(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: }
140: unlock(name) char *name;
141: {
142: if(isalock(name)) return(unlink(name));
143: else return(-1);
144: }
145: onelock(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: }
158: lock(pid,tempfile,names) char *tempfile;
159: register 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:
178: delock(s)
179: char *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:
195: mlock(sys)
196: char *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:
217: ultouch()
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.