|
|
1.1 root 1: #ifndef lint
2: static char sccsid[] = "@(#)ulockf.c 5.5 (Berkeley) 10/9/85";
3: #endif
4:
5: #include "uucp.h"
6: #include <sys/stat.h>
7: #include <errno.h>
8:
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;
15:
16: /*LINTLIBRARY*/
17:
18: /*
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.
21: *
22: * return codes: SUCCESS | FAIL
23: */
24: ulockf(hfile, atime)
25: char *hfile;
26: time_t atime;
27: {
28: register char *p;
29: register int i;
30: static char tempfile[NAMESIZE];
31: char file[NAMESIZE];
32: static int pid = -1;
33: extern int errno;
34:
35: if (pid < 0) {
36: pid = getpid();
37: sprintf(tempfile, "%s/LTMP.%d", LockDirectory, pid);
38: }
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;
45: /* get status to check age of the lock file */
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 */
50: }
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);
68: }
69:
70: for (i = 0; i < Nlocks; i++) {
71: if (Lockfile[i] == NULL)
72: break;
73: }
74: ASSERT(i < MAXLOCKS, "TOO MANY LOCKS", CNULL, i);
75: if (i >= Nlocks)
76: i = Nlocks++;
77: p = malloc((unsigned)(strlen(file)+1));
78: ASSERT(p != NULL, "CAN NOT ALLOCATE FOR", file, 0);
79: strcpy(p, file);
80: Lockfile[i] = p;
81:
82: return SUCCESS;
83: }
84:
85: /*
86: * remove all lock files in list or name
87: */
88: rmlock(name)
89: register char *name;
90: {
91: register int i;
92: char file[MAXFULLNAME];
93:
94: if (name != NULL) {
95: sprintf(file, "%s/LCK..%s", LockDirectory, name);
96: name = file;
97: }
98: for (i = 0; i < Nlocks; i++) {
99: if (Lockfile[i] == NULL)
100: continue;
101: if (name == NULL || strcmp(name, Lockfile[i]) == SAME) {
102: unlink(Lockfile[i]);
103: free(Lockfile[i]);
104: Lockfile[i] = NULL;
105: }
106: }
107: }
108:
109: /*
110: * makes lock a name on behalf of pid. Tempfile must be in the same
111: * file system as name.
112: */
113: onelock(pid, tempfile, name)
114: int pid;
115: char *tempfile, *name;
116: {
117: register int fd, ret;
118: #ifdef VMS
119: fd = creat(name, LCKMODE, "1version");
120: #else !VMS
121: fd = creat(tempfile, LCKMODE);
122: #endif !VMS
123: if (fd < 0) {
124: DEBUG(1,"Can't creat temp file %s ", tempfile);
125: DEBUG(1,"-- errno %d", errno);
126: return FAIL;
127: }
128: ret = write(fd, (char *)&pid, sizeof(int));
129: (void) close(fd);
130:
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);
143: return FAIL;
144: }
145: unlink(tempfile);
146: #endif !VMS
147: return SUCCESS;
148: }
149:
150: #if !defined(BSD4_2) && !defined(USG)
151: /*
152: * update 'change' time for lock files
153: *
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: {
165: static time_t lasttouch = 0;
166: register int i;
167: struct ut {
168: time_t actime;
169: time_t modtime;
170: } ut;
171:
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;
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);
191: #else !OLDTOUCH
192: chmod(Lockfile[i], LCKMODE);
193: #endif !OLDTOUCH
194: }
195: }
196: #endif !BSD4_2 && ! USG
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.