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} |