xref: /original-bsd/usr.bin/mail/lock.c (revision 264c46cb)
1 #
2 
3 /*
4  * A mailing program.
5  *
6  * Stuff to do version 7 style locking.
7  */
8 
9 #include "rcv.h"
10 #include <sys/stat.h>
11 
12 static char *SccsId = "@(#)lock.c	2.3 10/05/82";
13 
14 char	*maillock	= ".lock";		/* Lock suffix for mailname */
15 char	*lockname	= "/usr/spool/mail/tmXXXXXX";
16 char	locktmp[30];				/* Usable lock temporary */
17 static char		curlock[50];		/* Last used name of lock */
18 static	int		locked;			/* To note that we locked it */
19 
20 /*
21  * Lock the specified mail file by setting the file mailfile.lock.
22  * We must, of course, be careful to remove the lock file by a call
23  * to unlock before we stop.  The algorithm used here is to see if
24  * the lock exists, and if it does, to check its modify time.  If it
25  * is older than 5 minutes, we assume error and set our own file.
26  * Otherwise, we wait for 5 seconds and try again.
27  */
28 
29 lock(file)
30 char *file;
31 {
32 	register int f;
33 	struct stat sbuf;
34 	long curtime;
35 
36 	if (file == NOSTR) {
37 		printf("Locked = %d\n", locked);
38 		return(0);
39 	}
40 	if (locked)
41 		return(0);
42 	strcpy(curlock, file);
43 	strcat(curlock, maillock);
44 	strcpy(locktmp, lockname);
45 	mktemp(locktmp);
46 	remove(locktmp);
47 	for (;;) {
48 		f = lock1(locktmp, curlock);
49 		if (f == 0) {
50 			locked = 1;
51 			return(0);
52 		}
53 		if (stat(curlock, &sbuf) < 0)
54 			return(0);
55 		time(&curtime);
56 		if (curtime < sbuf.st_ctime + 300) {
57 			sleep(5);
58 			continue;
59 		}
60 		remove(curlock);
61 	}
62 }
63 
64 /*
65  * Remove the mail lock, and note that we no longer
66  * have it locked.
67  */
68 
69 unlock()
70 {
71 
72 	remove(curlock);
73 	locked = 0;
74 }
75 
76 /*
77  * Attempt to set the lock by creating the temporary file,
78  * then doing a link/unlink.  If it fails, return -1 else 0
79  */
80 
81 lock1(tempfile, name)
82 	char tempfile[], name[];
83 {
84 	register int fd;
85 
86 	fd = creat(tempfile, 0);
87 	if (fd < 0)
88 		return(-1);
89 	close(fd);
90 	if (link(tempfile, name) < 0) {
91 		remove(tempfile);
92 		return(-1);
93 	}
94 	remove(tempfile);
95 	return(0);
96 }
97