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