|
|
1.1 ! root 1: /* %W% ! 2: */ ! 3: #include "uucp.h" ! 4: VERSION(%W%); ! 5: ! 6: #ifdef V7 ! 7: #define O_RDONLY 0 ! 8: #endif ! 9: ! 10: static void stlock(); ! 11: static int onelock(); ! 12: ! 13: #ifdef ATTSVKILL ! 14: /* ! 15: * create a lock file (file). ! 16: * If one already exists, send a signal 0 to the process--if ! 17: * it fails, then unlink it and make a new one. ! 18: * ! 19: * input: ! 20: * file - name of the lock file ! 21: * atime - is unused, but we keep it for lint compatibility with non-ATTSVKILL ! 22: * ! 23: * return: ! 24: * 0 -> success ! 25: * FAIL -> failure ! 26: */ ! 27: ulockf(file, atime) ! 28: register char *file; ! 29: time_t atime; ! 30: { ! 31: #ifdef ASCIILOCKS ! 32: static char pid[SIZEOFPID+2] = { '\0' }; /* +2 for '\n' and NULL */ ! 33: #else ! 34: static int pid = -1; ! 35: #endif ! 36: ! 37: static char tempfile[MAXNAMESIZE]; ! 38: ! 39: #ifdef V8 ! 40: char *cp; ! 41: #endif ! 42: ! 43: #ifdef ASCIILOCKS ! 44: if (pid[0] == '\0') { ! 45: (void) sprintf(pid, "%*d\n", SIZEOFPID, getpid()); ! 46: #else ! 47: if (pid < 0) { ! 48: pid = getpid(); ! 49: #endif ! 50: (void) sprintf(tempfile, "%s/LTMP.%d", X_LOCKDIR, getpid()); ! 51: } ! 52: ! 53: #ifdef V8 /* this wouldn't be a problem if we used lock directories */ ! 54: /* some day the truncation of system names will bite us */ ! 55: cp = strrchr(file, '/'); ! 56: if (cp++ != CNULL) ! 57: if (strlen(cp) > V8DIRSIZ) ! 58: *(cp+V8DIRSIZ) = NULLCHAR; ! 59: #endif V8 ! 60: if (onelock(pid, tempfile, file) == -1) { ! 61: (void) unlink(tempfile); ! 62: if (checkLock(file)) ! 63: return(FAIL); ! 64: else { ! 65: if (onelock(pid, tempfile, file)) { ! 66: (void) unlink(tempfile); ! 67: DEBUG(4,"ulockf failed in onelock()\n",""); ! 68: return(FAIL); ! 69: } ! 70: } ! 71: } ! 72: ! 73: stlock(file); ! 74: return(0); ! 75: } ! 76: ! 77: /* ! 78: * check to see if the lock file exists and is still active ! 79: * - use kill(pid,0) - (this only works on ATTSV and some hacked ! 80: * BSD systems at this time) ! 81: * return: ! 82: * 0 -> success (lock file removed - no longer active ! 83: * FAIL -> lock file still active ! 84: */ ! 85: checkLock(file) ! 86: register char *file; ! 87: { ! 88: register int ret; ! 89: int lpid = -1; ! 90: #ifdef ASCIILOCKS ! 91: char alpid[SIZEOFPID+2]; /* +2 for '\n' and NULL */ ! 92: #endif ! 93: int fd; ! 94: extern int errno; ! 95: ! 96: fd = open(file, O_RDONLY); ! 97: DEBUG(4, "ulockf file %s\n", file); ! 98: if (fd == -1) { ! 99: if (errno == ENOENT) /* file does not exist -- OK */ ! 100: return(0); ! 101: DEBUG(4,"Lock File--can't read (errno %d) --remove it!\n", errno); ! 102: goto unlk; ! 103: } ! 104: #ifdef ASCIILOCKS ! 105: ret = read(fd, (char *) alpid, SIZEOFPID+1); /* +1 for '\n' */ ! 106: (void) close(fd); ! 107: if (ret != (SIZEOFPID+1)) { ! 108: #else ! 109: ret = read(fd, (char *) &lpid, sizeof(int)); ! 110: (void) close(fd); ! 111: if (ret != sizeof(int)) { ! 112: #endif ! 113: ! 114: DEBUG(4, "Lock File--bad format--remove it!\n", ""); ! 115: goto unlk; ! 116: } ! 117: #ifdef ASCIILOCKS ! 118: lpid = atoi(alpid); ! 119: #endif ! 120: if ((ret=kill(lpid, 0)) == 0 || errno == EPERM) { ! 121: DEBUG(4, "Lock File--process still active--not removed\n",""); ! 122: return(FAIL); ! 123: } ! 124: else { /* process no longer active */ ! 125: DEBUG(4, "kill pid (%d), ", lpid); ! 126: DEBUG(4, "returned %d", ret); ! 127: DEBUG(4, "--ok to remove lock file (%s)\n", file); ! 128: } ! 129: unlk: ! 130: ! 131: if (unlink(file) != 0) { ! 132: DEBUG(4,"ulockf failed in unlink()\n",""); ! 133: return(FAIL); ! 134: } ! 135: return(0); ! 136: } ! 137: #else ! 138: ! 139: /* ! 140: * check to see if the lock file exists and is still active ! 141: * - consider the lock expired after SLCKTIME seconds. ! 142: * return: ! 143: * 0 -> success (lock file removed - no longer active ! 144: * FAIL -> lock file still active ! 145: */ ! 146: checkLock(file) ! 147: register char *file; ! 148: { ! 149: register int ret; ! 150: int lpid = -1; ! 151: int fd; ! 152: extern int errno; ! 153: struct stat stbuf; ! 154: time_t ptime, time(); ! 155: ! 156: fd = open(file, 0); ! 157: DEBUG(4, "ulockf file %s\n", file); ! 158: if (fd == -1) { ! 159: if (errno == ENOENT) /* file does not exist -- OK */ ! 160: return(0); ! 161: DEBUG(4,"Lock File--can't read (errno %d) --remove it!\n", errno); ! 162: goto unlk; ! 163: } ! 164: ret = stat(file, &stbuf); ! 165: if (ret != -1) { ! 166: (void) time(&ptime); ! 167: if ((ptime - stbuf.st_ctime) < SLCKTIME) { ! 168: ! 169: /* ! 170: * file not old enough to delete ! 171: */ ! 172: return(FAIL); ! 173: } ! 174: } ! 175: unlk: ! 176: DEBUG(4, "--ok to remove lock file (%s)\n", file); ! 177: ! 178: if (unlink(file) != 0) { ! 179: DEBUG(4,"ulockf failed in unlink()\n",""); ! 180: return(FAIL); ! 181: } ! 182: return(0); ! 183: } ! 184: ! 185: ! 186: /* ! 187: * create a lock file (file). ! 188: * If one already exists, the create time is checked for ! 189: * older than the age time (atime). ! 190: * If it is older, an attempt will be made to unlink it ! 191: * and create a new one. ! 192: * return: ! 193: * 0 -> success ! 194: * FAIL -> failure ! 195: */ ! 196: ulockf(file, atime) ! 197: register char *file; ! 198: time_t atime; ! 199: { ! 200: register int ret; ! 201: struct stat stbuf; ! 202: #ifdef ASCIILOCKS ! 203: static char pid[SIZEOFPID+2] = { '\0' }; /* +2 for '\n' and null */ ! 204: #else ! 205: static int pid = -1; ! 206: #endif ! 207: static char tempfile[MAXNAMESIZE]; ! 208: time_t ptime, time(); ! 209: #ifdef V8 ! 210: char *cp; ! 211: #endif ! 212: ! 213: ! 214: #ifdef ASCIILOCKS ! 215: if (pid[0] == '\0') { ! 216: (void) sprintf(pid, "%*d\n", SIZEOFPID, getpid()); ! 217: #else ! 218: if (pid < 0) { ! 219: pid = getpid(); ! 220: #endif ! 221: (void) sprintf(tempfile, "%s/LTMP.%d", X_LOCKDIR, getpid()); ! 222: } ! 223: #ifdef V8 /* this wouldn't be a problem if we used lock directories */ ! 224: /* some day the truncation of system names will bite us */ ! 225: cp = strrchr(file, '/'); ! 226: if (cp++ != CNULL) ! 227: if (strlen(cp) > V8DIRSIZ) ! 228: *(cp+V8DIRSIZ) = NULLCHAR; ! 229: #endif V8 ! 230: if (onelock(pid, tempfile, file) == -1) { ! 231: ! 232: /* ! 233: * lock file exists ! 234: * get status to check age of the lock file ! 235: */ ! 236: (void) unlink(tempfile); ! 237: ret = stat(file, &stbuf); ! 238: if (ret != -1) { ! 239: (void) time(&ptime); ! 240: if ((ptime - stbuf.st_ctime) < atime) { ! 241: ! 242: /* ! 243: * file not old enough to delete ! 244: */ ! 245: return(FAIL); ! 246: } ! 247: } ! 248: ret = unlink(file); ! 249: ret = onelock(pid, tempfile, file); ! 250: if (ret != 0) ! 251: return(FAIL); ! 252: } ! 253: stlock(file); ! 254: return(0); ! 255: } ! 256: #endif ! 257: ! 258: #define MAXLOCKS 10 /* maximum number of lock files */ ! 259: char *Lockfile[MAXLOCKS]; ! 260: int Nlocks = 0; ! 261: ! 262: /* ! 263: * put name in list of lock files ! 264: * return: ! 265: * none ! 266: */ ! 267: static ! 268: void ! 269: stlock(name) ! 270: char *name; ! 271: { ! 272: register int i; ! 273: char *p; ! 274: ! 275: for (i = 0; i < Nlocks; i++) { ! 276: if (Lockfile[i] == NULL) ! 277: break; ! 278: } ! 279: ASSERT(i < MAXLOCKS, "TOO MANY LOCKS", "", i); ! 280: if (i >= Nlocks) ! 281: i = Nlocks++; ! 282: p = calloc((unsigned) strlen(name) + 1, sizeof (char)); ! 283: ASSERT(p != NULL, "CAN NOT ALLOCATE FOR", name, 0); ! 284: (void) strcpy(p, name); ! 285: Lockfile[i] = p; ! 286: return; ! 287: } ! 288: ! 289: /* ! 290: * remove all lock files in list ! 291: * return: ! 292: * none ! 293: */ ! 294: void ! 295: rmlock(name) ! 296: register char *name; ! 297: { ! 298: register int i; ! 299: #ifdef V8 ! 300: char *cp; ! 301: ! 302: if (name != CNULL) { ! 303: cp = strrchr(name, '/'); ! 304: if (cp++ != CNULL) ! 305: if (strlen(cp) > V8DIRSIZ) ! 306: *(cp+V8DIRSIZ) = NULLCHAR; ! 307: } ! 308: #endif V8 ! 309: ! 310: ! 311: for (i = 0; i < Nlocks; i++) { ! 312: if (Lockfile[i] == NULL) ! 313: continue; ! 314: if (name == NULL || EQUALS(name, Lockfile[i])) { ! 315: (void) unlink(Lockfile[i]); ! 316: (void) free(Lockfile[i]); ! 317: Lockfile[i] = NULL; ! 318: } ! 319: } ! 320: return; ! 321: } ! 322: ! 323: ! 324: ! 325: /* ! 326: * remove a lock file ! 327: * return: ! 328: * 0 -> success ! 329: * FAIL -> failure ! 330: */ ! 331: delock(s) ! 332: char *s; ! 333: { ! 334: char ln[MAXNAMESIZE]; ! 335: ! 336: (void) sprintf(ln, "%s.%s", LOCKPRE, s); ! 337: BASENAME(ln, '/')[MAXBASENAME] = '\0'; ! 338: rmlock(ln); ! 339: } ! 340: ! 341: ! 342: /* ! 343: * create system lock ! 344: * return: ! 345: * 0 -> success ! 346: * FAIL -> failure ! 347: */ ! 348: mlock(sys) ! 349: char *sys; ! 350: { ! 351: char lname[MAXNAMESIZE]; ! 352: ! 353: (void) sprintf(lname, "%s.%s", LOCKPRE, sys); ! 354: BASENAME(lname, '/')[MAXBASENAME] = '\0'; ! 355: return(ulockf(lname, SLCKTIME) < 0 ? FAIL : 0); ! 356: } ! 357: ! 358: ! 359: /* ! 360: * update access and modify times for lock files ! 361: * return: ! 362: * none ! 363: */ ! 364: void ! 365: ultouch() ! 366: { ! 367: register int i; ! 368: time_t time(); ! 369: ! 370: struct ut { ! 371: time_t actime; ! 372: time_t modtime; ! 373: } ut; ! 374: ! 375: ut.actime = time(&ut.modtime); ! 376: for (i = 0; i < Nlocks; i++) { ! 377: if (Lockfile[i] == NULL) ! 378: continue; ! 379: utime(Lockfile[i], &ut); ! 380: } ! 381: return; ! 382: } ! 383: ! 384: /* ! 385: * makes a lock on behalf of pid. ! 386: * input: ! 387: * pid - process id ! 388: * tempfile - name of a temporary in the same file system ! 389: * name - lock file name (full path name) ! 390: * return: ! 391: * -1 - failed ! 392: * 0 - lock made successfully ! 393: */ ! 394: static ! 395: onelock(pid,tempfile,name) ! 396: #ifdef ASCIILOCKS ! 397: char *pid; ! 398: #else ! 399: int pid; ! 400: #endif ! 401: char *tempfile, *name; ! 402: { ! 403: register int fd; ! 404: char cb[100]; ! 405: ! 406: fd=creat(tempfile, 0444); ! 407: if(fd < 0){ ! 408: (void) sprintf(cb, "%s %s %d",tempfile, name, errno); ! 409: logent("ULOCKC", cb); ! 410: if((errno == EMFILE) || (errno == ENFILE)) ! 411: (void) unlink(tempfile); ! 412: return(-1); ! 413: } ! 414: #ifdef ASCIILOCKS ! 415: (void) write(fd, pid, SIZEOFPID+1); /* +1 for '\n' */ ! 416: #else ! 417: (void) write(fd,(char *) &pid,sizeof(int)); ! 418: #endif ! 419: (void) chmod(tempfile,0444); /* silly */ ! 420: (void) chown(tempfile, UUCPUID, UUCPGID); ! 421: (void) close(fd); ! 422: if(link(tempfile,name)<0){ ! 423: DEBUG(4, "%s: ", sys_errlist[errno]); ! 424: DEBUG(4, "link(%s, ", tempfile); ! 425: DEBUG(4, "%s)\n", name); ! 426: if(unlink(tempfile)< 0){ ! 427: (void) sprintf(cb, "ULK err %s %d", tempfile, errno); ! 428: logent("ULOCKLNK", cb); ! 429: } ! 430: return(-1); ! 431: } ! 432: if(unlink(tempfile)<0){ ! 433: (void) sprintf(cb, "%s %d",tempfile,errno); ! 434: logent("ULOCKF", cb); ! 435: } ! 436: return(0); ! 437: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.