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