1 /* uucplock.c 4.1 81/05/09 */ 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 128 || strcmp(name, Lockfile[i]) == SAME) { 129 unlink(Lockfile[i]); 130 free(Lockfile[i]); 131 Lockfile[i] = NULL; 132 } 133 } 134 return; 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