Deleted Added
full compact
lock.c (22347) lock.c (29964)
1/* lock.c: The opielock() library function.
2
1/* lock.c: The opielock() library function.
2
3%%% portions-copyright-cmetz
4Portions of this software are Copyright 1996 by Craig Metz, All Rights
3%%% portions-copyright-cmetz-96
4Portions of this software are Copyright 1996-1997 by Craig Metz, All Rights
5Reserved. The Inner Net License Version 2 applies to these portions of
6the software.
7You should have received a copy of the license with this software. If
8you didn't get a copy, you may request one from <license@inner.net>.
9
10Portions of this software are Copyright 1995 by Randall Atkinson and Dan
11McDonald, All Rights Reserved. All Rights under this copyright are assigned
12to the U.S. Naval Research Laboratory (NRL). The NRL Copyright Notice and
13License Agreement applies to this software.
14
15 History:
16
5Reserved. The Inner Net License Version 2 applies to these portions of
6the software.
7You should have received a copy of the license with this software. If
8you didn't get a copy, you may request one from <license@inner.net>.
9
10Portions of this software are Copyright 1995 by Randall Atkinson and Dan
11McDonald, All Rights Reserved. All Rights under this copyright are assigned
12to the U.S. Naval Research Laboratory (NRL). The NRL Copyright Notice and
13License Agreement applies to this software.
14
15 History:
16
17 Modified by cmetz for OPIE 2.31. Put locks in a separate dir.
18 Bug fixes.
17 Modified by cmetz for OPIE 2.3. Do refcounts whether or not we
18 actually lock. Fixed USER_LOCKING=0 case.
19 Modified by cmetz for OPIE 2.22. Added reference count for locks.
20 Changed lock filename/refcount symbol names to better indicate
21 that they're not user serviceable.
22 Modified by cmetz for OPIE 2.2. Use FUNCTION declaration et al.
23 Use "principal" instead of "name" to make it clearer.
24 Ifdef around some headers, be more careful about allowed
25 error return values. Check open() return value properly.
26 Avoid NULL.
27 Created at NRL for OPIE 2.2 from opiesubr2.c
28*/
29#include "opie_cfg.h"
30#if HAVE_STRING_H
31#include <string.h>
32#endif /* HAVE_STRING_H */
33#if HAVE_UNISTD_H
34#include <unistd.h>
35#endif /* HAVE_UNISTD_H */
19 Modified by cmetz for OPIE 2.3. Do refcounts whether or not we
20 actually lock. Fixed USER_LOCKING=0 case.
21 Modified by cmetz for OPIE 2.22. Added reference count for locks.
22 Changed lock filename/refcount symbol names to better indicate
23 that they're not user serviceable.
24 Modified by cmetz for OPIE 2.2. Use FUNCTION declaration et al.
25 Use "principal" instead of "name" to make it clearer.
26 Ifdef around some headers, be more careful about allowed
27 error return values. Check open() return value properly.
28 Avoid NULL.
29 Created at NRL for OPIE 2.2 from opiesubr2.c
30*/
31#include "opie_cfg.h"
32#if HAVE_STRING_H
33#include <string.h>
34#endif /* HAVE_STRING_H */
35#if HAVE_UNISTD_H
36#include <unistd.h>
37#endif /* HAVE_UNISTD_H */
38#include <sys/stat.h>
39#include <syslog.h>
36#include <fcntl.h>
37#if HAVE_STDLIB_H
38#include <stdlib.h>
39#endif /* HAVE_STDLIB_H */
40#include <fcntl.h>
41#if HAVE_STDLIB_H
42#include <stdlib.h>
43#endif /* HAVE_STDLIB_H */
44#include <errno.h>
40#include "opie.h"
41
45#include "opie.h"
46
47#if !HAVE_LSTAT
48#define lstat(x, y) stat(x, y)
49#endif /* !HAVE_LSTAT */
50
42int __opie_lockrefcount = 0;
43
44#if USER_LOCKING
45char *__opie_lockfilename = (char *)0;
46
47/* atexit() handler for opielock() */
48static VOIDRET opieunlockaeh FUNCTION_NOARGS
49{

--- 20 unchanged lines hidden (view full) ---

70
71 Return -1 on low-level error, 0 if ok, 1 on locking failure.
72*/
73int opielock FUNCTION((principal), char *principal)
74{
75#if USER_LOCKING
76 int fh, waits = 0, rval = -1, pid, t, i;
77 char buffer[128], buffer2[128], *c, *c2;
51int __opie_lockrefcount = 0;
52
53#if USER_LOCKING
54char *__opie_lockfilename = (char *)0;
55
56/* atexit() handler for opielock() */
57static VOIDRET opieunlockaeh FUNCTION_NOARGS
58{

--- 20 unchanged lines hidden (view full) ---

79
80 Return -1 on low-level error, 0 if ok, 1 on locking failure.
81*/
82int opielock FUNCTION((principal), char *principal)
83{
84#if USER_LOCKING
85 int fh, waits = 0, rval = -1, pid, t, i;
86 char buffer[128], buffer2[128], *c, *c2;
87 struct stat statbuf[2];
78
88
89 if (getuid() && geteuid()) {
90#if DEBUG
91 syslog(LOG_DEBUG, "opielock: requires superuser priveleges");
92#endif /* DEBUG */
93 return -1;
94 };
95
79 if (__opie_lockfilename) {
80 __opie_lockrefcount++;
81 return 0;
82 }
83
96 if (__opie_lockfilename) {
97 __opie_lockrefcount++;
98 return 0;
99 }
100
84 if (!(__opie_lockfilename = (char *)malloc(sizeof(OPIE_LOCK_PREFIX) + strlen(principal))))
101 if (!(__opie_lockfilename = (char *)malloc(sizeof(OPIE_LOCK_DIR) + 1 + strlen(principal))))
85 return -1;
86
102 return -1;
103
87 strcpy(__opie_lockfilename, OPIE_LOCK_PREFIX);
104 strcpy(__opie_lockfilename, OPIE_LOCK_DIR);
105
106 if (mkdir(__opie_lockfilename, 0700) < 0)
107 if (errno != EEXIST)
108 return -1;
109
110 if (lstat(__opie_lockfilename, &statbuf[0]) < 0)
111 return -1;
112
113 if (statbuf[0].st_uid) {
114#if DEBUG
115 syslog(LOG_DEBUG, "opielock: %s isn't owned by the superuser.", __opie_lockfilename);
116#endif /* DEBUG */
117 return -1;
118 };
119
120 if (!S_ISDIR(statbuf[0].st_mode)) {
121#if DEBUG
122 syslog(LOG_DEBUG, "opielock: %s isn't a directory.", __opie_lockfilename);
123#endif /* DEBUG */
124 return -1;
125 };
126
127 if ((statbuf[0].st_mode & 0777) != 00700) {
128#if DEBUG
129 syslog(LOG_DEBUG, "opielock: permissions on %s are not correct.", __opie_lockfilename);
130#endif /* DEBUG */
131 return -1;
132 };
133
134 strcat(__opie_lockfilename, "/");
88 strcat(__opie_lockfilename, principal);
89
135 strcat(__opie_lockfilename, principal);
136
90 fh = 0;
91 while (!fh)
137 fh = -1;
138 while (fh < 0) {
139 if (!lstat(__opie_lockfilename, &statbuf[0]))
140 if (!S_ISREG(statbuf[0].st_mode))
141 goto lockret;
142
92 if ((fh = open(__opie_lockfilename, O_WRONLY | O_CREAT | O_EXCL, 0600)) < 0) {
143 if ((fh = open(__opie_lockfilename, O_WRONLY | O_CREAT | O_EXCL, 0600)) < 0) {
93 if ((fh = open(__opie_lockfilename, O_RDWR, 0600)) < 0)
144 if (lstat(__opie_lockfilename, &statbuf[1]) < 0)
94 goto lockret;
145 goto lockret;
146 if (statbuf[0].st_ino != statbuf[1].st_ino)
147 goto lockret;
148 if (statbuf[0].st_mode != statbuf[1].st_mode)
149 goto lockret;
150 if ((fh = open(__opie_lockfilename, O_RDONLY, 0600)) < 0)
151 goto lockret;
95 if ((i = read(fh, buffer, sizeof(buffer))) <= 0)
96 goto lockret;
97
98 buffer[sizeof(buffer) - 1] = 0;
99 buffer[i - 1] = 0;
100
101 if (!(c = strchr(buffer, '\n')))
102 break;

--- 6 unchanged lines hidden (view full) ---

109 *(c2++) = 0;
110
111 if (!(pid = atoi(buffer)))
112 break;
113
114 if (!(t = atoi(c)))
115 break;
116
152 if ((i = read(fh, buffer, sizeof(buffer))) <= 0)
153 goto lockret;
154
155 buffer[sizeof(buffer) - 1] = 0;
156 buffer[i - 1] = 0;
157
158 if (!(c = strchr(buffer, '\n')))
159 break;

--- 6 unchanged lines hidden (view full) ---

166 *(c2++) = 0;
167
168 if (!(pid = atoi(buffer)))
169 break;
170
171 if (!(t = atoi(c)))
172 break;
173
117 if ((time(0) + OPIE_LOCK_TIMEOUT) < t)
174 if ((t + OPIE_LOCK_TIMEOUT) < time(0))
118 break;
119
120 if (kill(pid, 0))
121 break;
122
123 close(fh);
124 fh = 0;
125 sleep(1);
126 if (waits++ > 3) {
127 rval = 1;
128 goto lockret;
129 };
130 };
175 break;
176
177 if (kill(pid, 0))
178 break;
179
180 close(fh);
181 fh = 0;
182 sleep(1);
183 if (waits++ > 3) {
184 rval = 1;
185 goto lockret;
186 };
187 };
188 };
131
189
190 if (lstat(__opie_lockfilename, &statbuf[0]) < 0)
191 goto lockret;
192 if (fstat(fh, &statbuf[1]) < 0)
193 goto lockret;
194 if (!S_ISREG(statbuf[0].st_mode) || (statbuf[0].st_mode != statbuf[1].st_mode) || (statbuf[0].st_ino != statbuf[1].st_ino))
195 goto lockret;
196
132 sprintf(buffer, "%d\n%d\n", getpid(), time(0));
133 i = strlen(buffer) + 1;
134 if (lseek(fh, 0, SEEK_SET)) {
135 close(fh);
136 unlink(__opie_lockfilename);
137 fh = 0;
138 goto lockret;
139 };

--- 20 unchanged lines hidden (view full) ---

160 goto lockret;
161 };
162
163 __opie_lockrefcount++;
164 rval = 0;
165 atexit(opieunlockaeh);
166
167lockret:
197 sprintf(buffer, "%d\n%d\n", getpid(), time(0));
198 i = strlen(buffer) + 1;
199 if (lseek(fh, 0, SEEK_SET)) {
200 close(fh);
201 unlink(__opie_lockfilename);
202 fh = 0;
203 goto lockret;
204 };

--- 20 unchanged lines hidden (view full) ---

225 goto lockret;
226 };
227
228 __opie_lockrefcount++;
229 rval = 0;
230 atexit(opieunlockaeh);
231
232lockret:
168 if (fh)
233 if (fh >= 0)
169 close(fh);
234 close(fh);
235 if (!__opie_lockrefcount) {
236 free (__opie_lockfilename);
237 __opie_lockfilename = NULL;
238 };
170 return rval;
171#else /* USER_LOCKING */
172 __opie_lockrefcount++;
173 return 0;
174#endif /* USER_LOCKING */
175}
239 return rval;
240#else /* USER_LOCKING */
241 __opie_lockrefcount++;
242 return 0;
243#endif /* USER_LOCKING */
244}