|
|
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.