|
|
1.1 root 1: #ifndef lint
2: static char sccsid[] = "@(#)ulockf.c 5.7 (Berkeley) 4/24/88";
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: extern int errno;
16:
17: /*LINTLIBRARY*/
18:
19: /*
20: * This routine will attempt to create a lock file (file).
21: * It makes sure that the lock file is valid if it already exists.
22: *
23: * return codes: SUCCESS | FAIL
24: */
25: ulockf(hfile, atime)
26: char *hfile;
27: time_t atime;
28: {
29: register char *p;
30: register int i;
31: static char tempfile[NAMESIZE];
32: char file[NAMESIZE];
33: static int pid = -1;
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: syslog(LOG_WARNING, "%s: dead lock %s", Rmtname, file);
64: logent(file, "DEAD LOCK");
65: (void) unlink(file);
66: sleep(5); /* avoid a possible race */
67: if (i++ >= 5) {
68: syslog(LOG_ERR, "%s: can't get lockfile %s: %m",
69: Rmtname, tempfile);
70: cleanup(FAIL);
71: }
72: }
73:
74: for (i = 0; i < Nlocks; i++) {
75: if (Lockfile[i] == NULL)
76: break;
77: }
78: if (i >= MAXLOCKS) {
79: syslog(LOG_ERR, "Too many locks");
80: cleanup(FAIL);
81: }
82: if (i >= Nlocks)
83: i = Nlocks++;
84: p = malloc((unsigned)(strlen(file)+1));
85: if (p == NULL) {
86: syslog(LOG_ERR, "malloc failed: %m");
87: cleanup(FAIL);
88: }
89: strcpy(p, file);
90: Lockfile[i] = p;
91:
92: return SUCCESS;
93: }
94:
95: /*
96: * remove all lock files in list or name
97: */
98: rmlock(name)
99: register char *name;
100: {
101: register int i;
102: char file[MAXFULLNAME];
103:
104: if (name != NULL) {
105: sprintf(file, "%s/LCK..%s", LockDirectory, name);
106: name = file;
107: }
108: for (i = 0; i < Nlocks; i++) {
109: if (Lockfile[i] == NULL)
110: continue;
111: if (name == NULL || strcmp(name, Lockfile[i]) == SAME) {
112: unlink(Lockfile[i]);
113: free(Lockfile[i]);
114: Lockfile[i] = NULL;
115: }
116: }
117: }
118:
119: /*
120: * makes lock a name on behalf of pid. Tempfile must be in the same
121: * file system as name.
122: */
123: onelock(pid, tempfile, name)
124: int pid;
125: char *tempfile, *name;
126: {
127: register int fd, ret;
128: #ifdef VMS
129: fd = creat(name, LCKMODE, "1version");
130: #else !VMS
131: fd = creat(tempfile, LCKMODE);
132: #endif !VMS
133: if (fd < 0) {
134: DEBUG(1,"Can't creat temp file %s ", tempfile);
135: DEBUG(1,"-- errno %d", errno);
136: return FAIL;
137: }
138: ret = write(fd, (char *)&pid, sizeof(int));
139: (void) close(fd);
140:
141: if (ret != sizeof(int)) {
142: DEBUG(1,"Temp file write failed -- errno %d\n", errno);
143: #ifdef VMS
144: (void) unlink(name);
145: #else !VMS
146: (void) unlink(tempfile);
147: #endif !VMS
148: return FAIL;
149: }
150: #ifndef VMS
151: if (link(tempfile, name) < 0) {
152: (void) unlink(tempfile);
153: return FAIL;
154: }
155: unlink(tempfile);
156: #endif !VMS
157: return SUCCESS;
158: }
159:
160: #if !defined(BSD4_2) && !defined(USG)
161: /*
162: * update 'change' time for lock files
163: *
164: * Only update ctime, not mtime or atime.
165: * The 'chmod' method permits cu(I)-like programs
166: * to determine how long uucp has been on the line.
167: * The old "change access, mod, and change time" method
168: * can be had by defining OLDTOUCH
169: *
170: * return code - none
171: */
172:
173: ultouch()
174: {
175: static time_t lasttouch = 0;
176: register int i;
177: struct ut {
178: time_t actime;
179: time_t modtime;
180: } ut;
181:
182: #ifdef USG
183: time(&Now.time);
184: t1.millitm = 0;
185: #else !USG
186: ftime(&Now);
187: #endif !USG
188: ut.actime = ut.modtime = Now.time;
189: /* Do not waste time touching locking files too often */
190: /* (But, defend against backward time changes) */
191: if (ut.actime >= lasttouch && ut.actime < lasttouch+60)
192: return;
193: lasttouch = ut.actime;
194: DEBUG(4, "ultouch\n", 0);
195:
196: for (i = 0; i < Nlocks; i++) {
197: if (Lockfile[i] == NULL)
198: continue;
199: #ifdef OLDTOUCH
200: utime(Lockfile[i], &ut);
201: #else !OLDTOUCH
202: chmod(Lockfile[i], LCKMODE);
203: #endif !OLDTOUCH
204: }
205: }
206: #endif !BSD4_2 && ! USG
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.