Research V7 development
[unix-history] / usr / src / cmd / uucp / ulockf.c
CommitLineData
128be09c
N
1#include "uucp.h"
2#include <sys/types.h>
3#include <sys/stat.h>
4
5
6/*******
7 * ulockf(file, atime)
8 * char *file;
9 * time_t atime;
10 *
11 * ulockf - this routine will create a lock file (file).
12 * If one already exists, the create time is checked for
13 * older than the age time (atime).
14 * If it is older, an attempt will be made to unlink it
15 * and create a new one.
16 *
17 * return codes: 0 | FAIL
18 */
19
20ulockf(file, atime)
21char *file;
22time_t atime;
23{
24 struct stat stbuf;
25 time_t ptime;
26 int ret;
27 static int pid = -1;
28 static char tempfile[NAMESIZE];
29
30 if (pid < 0) {
31 pid = getpid();
32 sprintf(tempfile, "LTMP.%d", pid);
33 }
34 if (onelock(pid, tempfile, file) == -1) {
35 /* lock file exists */
36 /* get status to check age of the lock file */
37 ret = stat(file, &stbuf);
38 ASSERT(ret != -1, "LOCK PROBLEM - %s", file);
39
40 time(&ptime);
41 if ((ptime - stbuf.st_ctime) < atime) {
42 /* file not old enough to delete */
43 return(FAIL);
44 }
45
46 ret = unlink(file);
47 ASSERT(ret != -1, "LOCK PROBLEM - %s", file);
48
49 ret = onelock(pid, tempfile, file);
50 ASSERT(ret == 0, "LOCK PROBLEM - %s", file);
51 }
52 stlock(file);
53 return(0);
54}
55
56
57#define MAXLOCKS 10 /* maximum number of lock files */
58char *Lockfile[MAXLOCKS];
59int Nlocks = 0;
60
61/***
62 * stlock(name) put name in list of lock files
63 * char *name;
64 *
65 * return codes: none
66 */
67
68stlock(name)
69char *name;
70{
71 char *p;
72 extern char *calloc();
73 int i;
74
75 for (i = 0; i < Nlocks; i++) {
76 if (Lockfile[i] == NULL)
77 break;
78 }
79 ASSERT(i < MAXLOCKS, "TOO MANY LOCKS %d", i);
80 if (i >= Nlocks)
81 i = Nlocks++;
82 p = calloc(strlen(name) + 1, sizeof (char));
83 ASSERT(p != NULL, "CAN NOT ALLOCATE FOR %s", name);
84 strcpy(p, name);
85 Lockfile[i] = p;
86 return;
87}
88
89
90/***
91 * rmlock(name) remove all lock files in list
92 * char *name; or name
93 *
94 * return codes: none
95 */
96
97rmlock(name)
98char *name;
99{
100 int i;
101
102 for (i = 0; i < Nlocks; i++) {
103 if (Lockfile[i] == NULL)
104 continue;
105 if (name == NULL
106 || strcmp(name, Lockfile[i]) == SAME) {
107 unlink(Lockfile[i]);
108 free(Lockfile[i]);
109 Lockfile[i] = NULL;
110 }
111 }
112 return;
113}
114
115
116/* this stuff from pjw */
117/* /usr/pjw/bin/recover - check pids to remove unnecessary locks */
118/* isalock(name) returns 0 if the name is a lock */
119/* unlock(name) unlocks name if it is a lock*/
120/* onelock(pid,tempfile,name) makes lock a name
121 on behalf of pid. Tempfile must be in the same
122 file system as name. */
123/* lock(pid,tempfile,names) either locks all the
124 names or none of them */
125isalock(name) char *name;
126{
127 struct stat xstat;
128 if(stat(name,&xstat)<0) return(0);
129 if(xstat.st_size!=sizeof(int)) return(0);
130 return(1);
131}
132unlock(name) char *name;
133{
134 if(isalock(name)) return(unlink(name));
135 else return(-1);
136}
137onelock(pid,tempfile,name) char *tempfile,*name;
138{ int fd;
139 fd=creat(tempfile,0444);
140 if(fd<0) return(-1);
141 write(fd,&pid,sizeof(int));
142 close(fd);
143 if(link(tempfile,name)<0)
144 { unlink(tempfile);
145 return(-1);
146 }
147 unlink(tempfile);
148 return(0);
149}
150lock(pid,tempfile,names) char *tempfile,**names;
151{ int i,j;
152 for(i=0;names[i]!=0;i++)
153 { if(onelock(pid,tempfile,names[i])==0) continue;
154 for(j=0;j<i;j++) unlink(names[j]);
155 return(-1);
156 }
157 return(0);
158}
159
160#define LOCKPRE "LCK."
161
162/***
163 * delock(s) remove a lock file
164 * char *s;
165 *
166 * return codes: 0 | FAIL
167 */
168
169delock(s)
170char *s;
171{
172 char ln[30];
173
174 sprintf(ln, "%s.%s", LOCKPRE, s);
175 rmlock(ln);
176}
177
178
179/***
180 * mlock(sys) create system lock
181 * char *sys;
182 *
183 * return codes: 0 | FAIL
184 */
185
186mlock(sys)
187char *sys;
188{
189 char lname[30];
190 sprintf(lname, "%s.%s", LOCKPRE, sys);
191 return(ulockf(lname, (time_t) 24*3600 ) < 0 ? FAIL : 0);
192}
193
194