|
|
1.1 ! root 1: #ifndef lint ! 2: static char sccsid[] = "@(#)ulockf.c 5.1 (Berkeley) 7/2/83"; ! 3: #endif ! 4: ! 5: #include "uucp.h" ! 6: #include <sys/types.h> ! 7: #include <sys/stat.h> ! 8: ! 9: ! 10: extern time_t time(); ! 11: ! 12: /* File mode for lock files */ ! 13: #define LCKMODE 0444 ! 14: ! 15: /******* ! 16: * ulockf(file, atime) ! 17: * char *file; ! 18: * time_t atime; ! 19: * ! 20: * ulockf - this routine will create a lock file (file). ! 21: * If one already exists, the create time is checked for ! 22: * older than the age time (atime). ! 23: * If it is older, an attempt will be made to unlink it ! 24: * and create a new one. ! 25: * ! 26: * return codes: 0 | FAIL ! 27: */ ! 28: ! 29: ulockf(file, atime) ! 30: register char *file; ! 31: time_t atime; ! 32: { ! 33: struct stat stbuf; ! 34: time_t ptime; ! 35: register int ret; ! 36: static int pid = -1; ! 37: static char tempfile[NAMESIZE]; ! 38: ! 39: if (pid < 0) { ! 40: pid = getpid(); ! 41: sprintf(tempfile, "LTMP.%d", pid); ! 42: } ! 43: if (onelock(pid, tempfile, file) == -1) { ! 44: /* lock file exists */ ! 45: /* get status to check age of the lock file */ ! 46: ret = stat(file, &stbuf); ! 47: if (ret != -1) { ! 48: time(&ptime); ! 49: if ((ptime - stbuf.st_ctime) < atime) { ! 50: /* file not old enough to delete */ ! 51: return(FAIL); ! 52: } ! 53: } ! 54: ret = unlink(file); ! 55: ret = onelock(pid, tempfile, file); ! 56: if (ret != 0) ! 57: return(FAIL); ! 58: } ! 59: stlock(file); ! 60: return(0); ! 61: } ! 62: ! 63: ! 64: #define MAXLOCKS 10 /* maximum number of lock files */ ! 65: char *Lockfile[MAXLOCKS]; ! 66: int Nlocks = 0; ! 67: ! 68: /*** ! 69: * stlock(name) put name in list of lock files ! 70: * char *name; ! 71: * ! 72: * return codes: none ! 73: */ ! 74: ! 75: stlock(name) ! 76: register char *name; ! 77: { ! 78: register char *p; ! 79: register int i; ! 80: ! 81: for (i = 0; i < Nlocks; i++) { ! 82: if (Lockfile[i] == NULL) ! 83: break; ! 84: } ! 85: ASSERT(i < MAXLOCKS, "TOO MANY LOCKS", "", i); ! 86: if (i >= Nlocks) ! 87: i = Nlocks++; ! 88: p = calloc((unsigned)(strlen(name)+1), sizeof (char)); ! 89: ASSERT(p != NULL, "CAN NOT ALLOCATE FOR", name, 0); ! 90: strcpy(p, name); ! 91: Lockfile[i] = p; ! 92: return; ! 93: } ! 94: ! 95: ! 96: /*** ! 97: * rmlock(name) remove all lock files in list ! 98: * char *name; or name ! 99: * ! 100: * return codes: none ! 101: */ ! 102: ! 103: rmlock(name) ! 104: register char *name; ! 105: { ! 106: register int i; ! 107: ! 108: for (i = 0; i < Nlocks; i++) { ! 109: if (Lockfile[i] == NULL) ! 110: continue; ! 111: if (name == NULL ! 112: || strcmp(name, Lockfile[i]) == SAME) { ! 113: unlink(Lockfile[i]); ! 114: free(Lockfile[i]); ! 115: Lockfile[i] = NULL; ! 116: } ! 117: } ! 118: return; ! 119: } ! 120: ! 121: ! 122: /* ! 123: * this stuff from pjw ! 124: * /usr/pjw/bin/recover - Check pids to remove unnecessary locks. ! 125: * isalock(name) returns 0 if the name is a lock. ! 126: * unlock(name) unlocks name if it is a lock. ! 127: * onelock(pid,tempfile,name) makes lock a name ! 128: * on behalf of pid. Tempfile must be in the same ! 129: * file system as name. ! 130: * lock(pid,tempfile,names) either locks all the ! 131: * names or none of them. ! 132: */ ! 133: isalock(name) char *name; ! 134: { ! 135: struct stat xstat; ! 136: if(stat(name,&xstat)<0) return(0); ! 137: if(xstat.st_size!=sizeof(int)) return(0); ! 138: return(1); ! 139: } ! 140: unlock(name) char *name; ! 141: { ! 142: if(isalock(name)) return(unlink(name)); ! 143: else return(-1); ! 144: } ! 145: onelock(pid,tempfile,name) char *tempfile,*name; ! 146: { register int fd; ! 147: fd=creat(tempfile,LCKMODE); ! 148: if(fd<0) return(-1); ! 149: write(fd,(char *) &pid,sizeof(int)); ! 150: close(fd); ! 151: if(link(tempfile,name)<0) ! 152: { unlink(tempfile); ! 153: return(-1); ! 154: } ! 155: unlink(tempfile); ! 156: return(0); ! 157: } ! 158: lock(pid,tempfile,names) char *tempfile; ! 159: register char **names; ! 160: { register int i,j; ! 161: for(i=0;names[i]!=0;i++) ! 162: { if(onelock(pid,tempfile,names[i])==0) continue; ! 163: for(j=0;j<i;j++) unlink(names[j]); ! 164: return(-1); ! 165: } ! 166: return(0); ! 167: } ! 168: ! 169: #define LOCKPRE "LCK." ! 170: ! 171: /*** ! 172: * delock(s) remove a lock file ! 173: * char *s; ! 174: * ! 175: * return codes: 0 | FAIL ! 176: */ ! 177: ! 178: delock(s) ! 179: char *s; ! 180: { ! 181: char ln[30]; ! 182: ! 183: sprintf(ln, "%s.%s", LOCKPRE, s); ! 184: rmlock(ln); ! 185: } ! 186: ! 187: ! 188: /*** ! 189: * mlock(sys) create system lock ! 190: * char *sys; ! 191: * ! 192: * return codes: 0 | FAIL ! 193: */ ! 194: ! 195: mlock(sys) ! 196: char *sys; ! 197: { ! 198: char lname[30]; ! 199: sprintf(lname, "%s.%s", LOCKPRE, sys); ! 200: return(ulockf(lname, (time_t) SLCKTIME ) < 0 ? FAIL : 0); ! 201: } ! 202: ! 203: ! 204: /*** ! 205: * ultouch() update 'change' time for lock files ! 206: * ! 207: * -- mod by rti!trt -- ! 208: * Only update ctime, not mtime or atime. ! 209: * The 'chmod' method permits cu(I)-like programs ! 210: * to determine how long uucp has been on the line. ! 211: * The old "change access, mod, and change time" method ! 212: * can be had by defining OLDTOUCH ! 213: * ! 214: * return code - none ! 215: */ ! 216: ! 217: ultouch() ! 218: { ! 219: time_t time(); ! 220: static time_t lasttouch = 0; ! 221: register int i; ! 222: struct ut { ! 223: time_t actime; ! 224: time_t modtime; ! 225: } ut; ! 226: ! 227: ut.actime = time(&ut.modtime); ! 228: /* Do not waste time touching locking files too often */ ! 229: /* (But, defend against backward time changes) */ ! 230: if (ut.actime >= lasttouch && ut.actime < lasttouch+60) ! 231: return; ! 232: lasttouch = ut.actime; ! 233: DEBUG(4, "ultouch\n", 0); ! 234: ! 235: for (i = 0; i < Nlocks; i++) { ! 236: if (Lockfile[i] == NULL) ! 237: continue; ! 238: #ifdef OLDTOUCH ! 239: utime(Lockfile[i], &ut); ! 240: #else ! 241: chmod(Lockfile[i], LCKMODE); ! 242: #endif ! 243: } ! 244: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.