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