|
|
1.1 ! root 1: #ifndef lint ! 2: static char sccsid[] = "@(#)ulockf.c 5.7 (Berkeley) 4/24/88"; ! 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: extern int errno; ! 16: ! 17: /*LINTLIBRARY*/ ! 18: ! 19: /* ! 20: * This routine will attempt to create a lock file (file). ! 21: * It makes sure that the lock file is valid if it already exists. ! 22: * ! 23: * return codes: SUCCESS | FAIL ! 24: */ ! 25: ulockf(hfile, atime) ! 26: char *hfile; ! 27: time_t atime; ! 28: { ! 29: register char *p; ! 30: register int i; ! 31: static char tempfile[NAMESIZE]; ! 32: char file[NAMESIZE]; ! 33: static int pid = -1; ! 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: syslog(LOG_WARNING, "%s: dead lock %s", Rmtname, file); ! 64: logent(file, "DEAD LOCK"); ! 65: (void) unlink(file); ! 66: sleep(5); /* avoid a possible race */ ! 67: if (i++ >= 5) { ! 68: syslog(LOG_ERR, "%s: can't get lockfile %s: %m", ! 69: Rmtname, tempfile); ! 70: cleanup(FAIL); ! 71: } ! 72: } ! 73: ! 74: for (i = 0; i < Nlocks; i++) { ! 75: if (Lockfile[i] == NULL) ! 76: break; ! 77: } ! 78: if (i >= MAXLOCKS) { ! 79: syslog(LOG_ERR, "Too many locks"); ! 80: cleanup(FAIL); ! 81: } ! 82: if (i >= Nlocks) ! 83: i = Nlocks++; ! 84: p = malloc((unsigned)(strlen(file)+1)); ! 85: if (p == NULL) { ! 86: syslog(LOG_ERR, "malloc failed: %m"); ! 87: cleanup(FAIL); ! 88: } ! 89: strcpy(p, file); ! 90: Lockfile[i] = p; ! 91: ! 92: return SUCCESS; ! 93: } ! 94: ! 95: /* ! 96: * remove all lock files in list or name ! 97: */ ! 98: rmlock(name) ! 99: register char *name; ! 100: { ! 101: register int i; ! 102: char file[MAXFULLNAME]; ! 103: ! 104: if (name != NULL) { ! 105: sprintf(file, "%s/LCK..%s", LockDirectory, name); ! 106: name = file; ! 107: } ! 108: for (i = 0; i < Nlocks; i++) { ! 109: if (Lockfile[i] == NULL) ! 110: continue; ! 111: if (name == NULL || strcmp(name, Lockfile[i]) == SAME) { ! 112: unlink(Lockfile[i]); ! 113: free(Lockfile[i]); ! 114: Lockfile[i] = NULL; ! 115: } ! 116: } ! 117: } ! 118: ! 119: /* ! 120: * makes lock a name on behalf of pid. Tempfile must be in the same ! 121: * file system as name. ! 122: */ ! 123: onelock(pid, tempfile, name) ! 124: int pid; ! 125: char *tempfile, *name; ! 126: { ! 127: register int fd, ret; ! 128: #ifdef VMS ! 129: fd = creat(name, LCKMODE, "1version"); ! 130: #else !VMS ! 131: fd = creat(tempfile, LCKMODE); ! 132: #endif !VMS ! 133: if (fd < 0) { ! 134: DEBUG(1,"Can't creat temp file %s ", tempfile); ! 135: DEBUG(1,"-- errno %d", errno); ! 136: return FAIL; ! 137: } ! 138: ret = write(fd, (char *)&pid, sizeof(int)); ! 139: (void) close(fd); ! 140: ! 141: if (ret != sizeof(int)) { ! 142: DEBUG(1,"Temp file write failed -- errno %d\n", errno); ! 143: #ifdef VMS ! 144: (void) unlink(name); ! 145: #else !VMS ! 146: (void) unlink(tempfile); ! 147: #endif !VMS ! 148: return FAIL; ! 149: } ! 150: #ifndef VMS ! 151: if (link(tempfile, name) < 0) { ! 152: (void) unlink(tempfile); ! 153: return FAIL; ! 154: } ! 155: unlink(tempfile); ! 156: #endif !VMS ! 157: return SUCCESS; ! 158: } ! 159: ! 160: #if !defined(BSD4_2) && !defined(USG) ! 161: /* ! 162: * update 'change' time for lock files ! 163: * ! 164: * Only update ctime, not mtime or atime. ! 165: * The 'chmod' method permits cu(I)-like programs ! 166: * to determine how long uucp has been on the line. ! 167: * The old "change access, mod, and change time" method ! 168: * can be had by defining OLDTOUCH ! 169: * ! 170: * return code - none ! 171: */ ! 172: ! 173: ultouch() ! 174: { ! 175: static time_t lasttouch = 0; ! 176: register int i; ! 177: struct ut { ! 178: time_t actime; ! 179: time_t modtime; ! 180: } ut; ! 181: ! 182: #ifdef USG ! 183: time(&Now.time); ! 184: t1.millitm = 0; ! 185: #else !USG ! 186: ftime(&Now); ! 187: #endif !USG ! 188: ut.actime = ut.modtime = Now.time; ! 189: /* Do not waste time touching locking files too often */ ! 190: /* (But, defend against backward time changes) */ ! 191: if (ut.actime >= lasttouch && ut.actime < lasttouch+60) ! 192: return; ! 193: lasttouch = ut.actime; ! 194: DEBUG(4, "ultouch\n", 0); ! 195: ! 196: for (i = 0; i < Nlocks; i++) { ! 197: if (Lockfile[i] == NULL) ! 198: continue; ! 199: #ifdef OLDTOUCH ! 200: utime(Lockfile[i], &ut); ! 201: #else !OLDTOUCH ! 202: chmod(Lockfile[i], LCKMODE); ! 203: #endif !OLDTOUCH ! 204: } ! 205: } ! 206: #endif !BSD4_2 && ! USG
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.