1 #ifndef lint 2 static char sccsid[] = "@(#)uucplock.c 4.6 (Berkeley) 06/25/83"; 3 #endif 4 /* 5 * defs that come from uucp.h 6 */ 7 #define NAMESIZE 15 8 #define FAIL -1 9 #define SAME 0 10 #define SLCKTIME 28800 /* system/device timeout (LCK.. files) in seconds (8 hours) */ 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 45 static 46 ulockf(file, atime) 47 char *file; 48 time_t atime; 49 { 50 struct stat stbuf; 51 time_t ptime; 52 int ret; 53 static int pid = -1; 54 static char tempfile[NAMESIZE]; 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 */ 68 return (FAIL); 69 } 70 } 71 ret = unlink(file); 72 ret = onelock(pid, tempfile, file); 73 if (ret != 0) 74 return (FAIL); 75 } 76 stlock(file); 77 return (0); 78 } 79 80 #define MAXLOCKS 10 /* maximum number of lock files */ 81 char *Lockfile[MAXLOCKS]; 82 int Nlocks = 0; 83 84 /*** 85 * stlock(name) put name in list of lock files 86 * char *name; 87 * 88 * return codes: none 89 */ 90 91 static 92 stlock(name) 93 char *name; 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 120 static 121 rmlock(name) 122 char *name; 123 { 124 int i; 125 126 for (i = 0; i < Nlocks; i++) { 127 if (Lockfile[i] == NULL) 128 continue; 129 if (name == NULL || strcmp(name, Lockfile[i]) == SAME) { 130 unlink(Lockfile[i]); 131 free(Lockfile[i]); 132 Lockfile[i] = NULL; 133 } 134 } 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 */ 150 static 151 isalock(name) 152 char *name; 153 { 154 struct stat xstat; 155 156 if (stat(name, &xstat) < 0) 157 return (0); 158 if (xstat.st_size != sizeof(int)) 159 return (0); 160 return (1); 161 } 162 163 static 164 onelock(pid, tempfile, name) 165 char *tempfile, *name; 166 { 167 int fd; 168 169 fd = creat(tempfile, 0444); 170 if (fd < 0) 171 return (-1); 172 write(fd,(char *)&pid, sizeof(int)); 173 close(fd); 174 if (link(tempfile, name) < 0) { 175 unlink(tempfile); 176 return (-1); 177 } 178 unlink(tempfile); 179 return (0); 180 } 181 182 /*** 183 * delock(s) remove a lock file 184 * char *s; 185 * 186 * return codes: 0 | FAIL 187 */ 188 189 delock(s) 190 char *s; 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 205 mlock(sys) 206 char *sys; 207 { 208 char lname[30]; 209 sprintf(lname, "%s.%s", LOCKPRE, sys); 210 return (ulockf(lname, (time_t) SLCKTIME ) < 0 ? FAIL : 0); 211 } 212