|
|
1.1 ! root 1: #include <stdio.h> ! 2: #include <sys/types.h> ! 3: #include <dir.h> ! 4: #include <sys/stat.h> ! 5: #include "string.h" ! 6: ! 7: /* imports */ ! 8: extern char *mktemp(); ! 9: extern long time(); ! 10: extern unsigned int sleep(); ! 11: ! 12: #define LOCKPREFIX "/tmp/L." ! 13: static char lockname[DIRSIZ+sizeof(LOCKPREFIX)] = { 0 }; ! 14: ! 15: /* break an old lock */ ! 16: static void ! 17: breaklock(file, lock) ! 18: char *file, *lock; ! 19: { ! 20: FILE *fp; ! 21: ! 22: fprintf(stderr, "mail: breaking lock\n"); ! 23: if ((fp=fopen("/usr/spool/mail/mail.log", "a")) != NULL) { ! 24: fprintf(fp, "lock-err file=%s lock=%s\n", file, lock); ! 25: fclose(fp); ! 26: } ! 27: unlink(lock); ! 28: } ! 29: ! 30: /* Lock the given file. The parameter "file" must contain at least one '/'. */ ! 31: extern void ! 32: lock(file) ! 33: char *file; ! 34: { ! 35: # define TMPLNAME "/tmp/mlXXXXX" ! 36: # define LOCKPREFIX "/tmp/L." ! 37: char tmplname[sizeof(TMPLNAME)]; ! 38: struct stat stbuf; ! 39: int fd; ! 40: ! 41: /* return if we are already in the middle of a lock */ ! 42: if (*lockname != '\0') { ! 43: fprintf(stderr, "mail: lockfile botch\n"); ! 44: exit(1); ! 45: } ! 46: ! 47: /* create a temporary file */ ! 48: (void)strcpy(tmplname, TMPLNAME); ! 49: (void)mktemp(tmplname); ! 50: if ((fd=creat(tmplname, 0444))<0) ! 51: return; ! 52: close(fd); ! 53: ! 54: /* Make a link to it with the lock file name. This will fail only ! 55: * if it already exists. ! 56: */ ! 57: (void)strcpy(lockname, LOCKPREFIX); ! 58: (void)strcat(lockname, strrchr(file, '/')+1); ! 59: lockname[DIRSIZ+sizeof("/tmp/")-1] = '\0'; ! 60: while (link(tmplname, lockname) < 0) { ! 61: long now; ! 62: ! 63: /* File is already locked. Break it if the lock is old. */ ! 64: sleep(2); ! 65: now = time((long *)0); ! 66: if (stat(lockname, &stbuf)==0 && stbuf.st_ctime+60 < now) { ! 67: if (stat(file, &stbuf)==0 && stbuf.st_mtime+180 >= now) ! 68: continue; ! 69: breaklock(file, lockname); ! 70: } ! 71: } ! 72: unlink(tmplname); ! 73: return; ! 74: } ! 75: ! 76: extern void ! 77: unlock() ! 78: { ! 79: if (*lockname != '\0') { ! 80: unlink(lockname); ! 81: *lockname = '\0'; ! 82: } ! 83: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.