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