|
|
1.1 ! root 1: #ifndef lint ! 2: static char sccsid[] = "@(#)ulockf.c 5.5 (Berkeley) 10/9/85"; ! 3: #endif ! 4: ! 5: #include "uucp.h" ! 6: #include <sys/stat.h> ! 7: #include <errno.h> ! 8: ! 9: #define LCKMODE 0444 /* File mode for lock files */ ! 10: #define MAXLOCKS 16 /* Maximum number of lock files */ ! 11: ! 12: char *Lockfile[MAXLOCKS]; ! 13: char *LockDirectory = LOCKDIR; ! 14: int Nlocks = 0; ! 15: ! 16: /*LINTLIBRARY*/ ! 17: ! 18: /* ! 19: * This routine will attempt to create a lock file (file). ! 20: * It makes sure that the lock file is valid if it already exists. ! 21: * ! 22: * return codes: SUCCESS | FAIL ! 23: */ ! 24: ulockf(hfile, atime) ! 25: char *hfile; ! 26: time_t atime; ! 27: { ! 28: register char *p; ! 29: register int i; ! 30: static char tempfile[NAMESIZE]; ! 31: char file[NAMESIZE]; ! 32: static int pid = -1; ! 33: extern int errno; ! 34: ! 35: if (pid < 0) { ! 36: pid = getpid(); ! 37: sprintf(tempfile, "%s/LTMP.%d", LockDirectory, pid); ! 38: } ! 39: sprintf(file, "%s/LCK..%s", LockDirectory, hfile); ! 40: i = 0; ! 41: while (onelock(pid, tempfile, file) == -1) { /* lock file exists */ ! 42: #if !defined(BSD4_2) && !defined(USG) ! 43: struct stat stbuf; ! 44: time_t ptime; ! 45: /* get status to check age of the lock file */ ! 46: if (stat(file, &stbuf) == 0) { ! 47: (void) time(&ptime); ! 48: if ((ptime - stbuf.st_ctime) < atime) ! 49: return FAIL; /* file not old enough to delete */ ! 50: } ! 51: #else BSD4_2 || USG ! 52: register int fd; ! 53: fd = open(file, 0); ! 54: if (fd >= 0) { ! 55: int upid, ret; ! 56: ret = read(fd, &upid, sizeof upid); ! 57: close(fd); ! 58: if (ret == sizeof upid && (kill(upid, 0) == 0 ! 59: || errno != ESRCH)) ! 60: return FAIL; /* process is still running */ ! 61: } ! 62: #endif BSD4_2 || USG ! 63: assert("DEAD LOCK", file, errno); ! 64: logent(file, "DEAD LOCK"); ! 65: (void) unlink(file); ! 66: sleep(5); /* avoid a possible race */ ! 67: ASSERT(i++ < 5, "CAN'T GET LOCKFILE", tempfile, errno); ! 68: } ! 69: ! 70: for (i = 0; i < Nlocks; i++) { ! 71: if (Lockfile[i] == NULL) ! 72: break; ! 73: } ! 74: ASSERT(i < MAXLOCKS, "TOO MANY LOCKS", CNULL, i); ! 75: if (i >= Nlocks) ! 76: i = Nlocks++; ! 77: p = malloc((unsigned)(strlen(file)+1)); ! 78: ASSERT(p != NULL, "CAN NOT ALLOCATE FOR", file, 0); ! 79: strcpy(p, file); ! 80: Lockfile[i] = p; ! 81: ! 82: return SUCCESS; ! 83: } ! 84: ! 85: /* ! 86: * remove all lock files in list or name ! 87: */ ! 88: rmlock(name) ! 89: register char *name; ! 90: { ! 91: register int i; ! 92: char file[MAXFULLNAME]; ! 93: ! 94: if (name != NULL) { ! 95: sprintf(file, "%s/LCK..%s", LockDirectory, name); ! 96: name = file; ! 97: } ! 98: for (i = 0; i < Nlocks; i++) { ! 99: if (Lockfile[i] == NULL) ! 100: continue; ! 101: if (name == NULL || strcmp(name, Lockfile[i]) == SAME) { ! 102: unlink(Lockfile[i]); ! 103: free(Lockfile[i]); ! 104: Lockfile[i] = NULL; ! 105: } ! 106: } ! 107: } ! 108: ! 109: /* ! 110: * makes lock a name on behalf of pid. Tempfile must be in the same ! 111: * file system as name. ! 112: */ ! 113: onelock(pid, tempfile, name) ! 114: int pid; ! 115: char *tempfile, *name; ! 116: { ! 117: register int fd, ret; ! 118: #ifdef VMS ! 119: fd = creat(name, LCKMODE, "1version"); ! 120: #else !VMS ! 121: fd = creat(tempfile, LCKMODE); ! 122: #endif !VMS ! 123: if (fd < 0) { ! 124: DEBUG(1,"Can't creat temp file %s ", tempfile); ! 125: DEBUG(1,"-- errno %d", errno); ! 126: return FAIL; ! 127: } ! 128: ret = write(fd, (char *)&pid, sizeof(int)); ! 129: (void) close(fd); ! 130: ! 131: if (ret != sizeof(int)) { ! 132: DEBUG(1,"Temp file write failed -- errno %d\n", errno); ! 133: #ifdef VMS ! 134: (void) unlink(name); ! 135: #else !VMS ! 136: (void) unlink(tempfile); ! 137: #endif !VMS ! 138: return FAIL; ! 139: } ! 140: #ifndef VMS ! 141: if (link(tempfile, name) < 0) { ! 142: (void) unlink(tempfile); ! 143: return FAIL; ! 144: } ! 145: unlink(tempfile); ! 146: #endif !VMS ! 147: return SUCCESS; ! 148: } ! 149: ! 150: #if !defined(BSD4_2) && !defined(USG) ! 151: /* ! 152: * update 'change' time for lock files ! 153: * ! 154: * Only update ctime, not mtime or atime. ! 155: * The 'chmod' method permits cu(I)-like programs ! 156: * to determine how long uucp has been on the line. ! 157: * The old "change access, mod, and change time" method ! 158: * can be had by defining OLDTOUCH ! 159: * ! 160: * return code - none ! 161: */ ! 162: ! 163: ultouch() ! 164: { ! 165: static time_t lasttouch = 0; ! 166: register int i; ! 167: struct ut { ! 168: time_t actime; ! 169: time_t modtime; ! 170: } ut; ! 171: ! 172: #ifdef USG ! 173: time(&Now.time); ! 174: t1.millitm = 0; ! 175: #else !USG ! 176: ftime(&Now); ! 177: #endif !USG ! 178: ut.actime = ut.modtime = Now.time; ! 179: /* Do not waste time touching locking files too often */ ! 180: /* (But, defend against backward time changes) */ ! 181: if (ut.actime >= lasttouch && ut.actime < lasttouch+60) ! 182: return; ! 183: lasttouch = ut.actime; ! 184: DEBUG(4, "ultouch\n", 0); ! 185: ! 186: for (i = 0; i < Nlocks; i++) { ! 187: if (Lockfile[i] == NULL) ! 188: continue; ! 189: #ifdef OLDTOUCH ! 190: utime(Lockfile[i], &ut); ! 191: #else !OLDTOUCH ! 192: chmod(Lockfile[i], LCKMODE); ! 193: #endif !OLDTOUCH ! 194: } ! 195: } ! 196: #endif !BSD4_2 && ! USG
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.