Update
[uemacs.git] / src / pklock.c
bloba842225b322d721666c5c82f1ba173e6db518de2
1 /* PKLOCK.C
3 * locking routines as modified by Petri Kutvonen
4 */
6 #include "estruct.h"
7 #include "edef.h"
8 #include "efunc.h"
10 #if (FILOCK && BSD) || SVR4
11 #include <sys/types.h>
12 #include <sys/stat.h>
13 #include <unistd.h>
14 #include <stdio.h>
15 #include <fcntl.h>
16 #ifdef SVR4
17 #include <string.h>
18 #else
19 #include <strings.h>
20 #endif
21 #include <errno.h>
23 #define MAXLOCK 512
24 #define MAXNAME 128
26 #if defined(SVR4) && ! defined(__linux__)
27 #include <sys/systeminfo.h>
29 int gethostname(char *name, int namelen)
31 return sysinfo(SI_HOSTNAME, name, namelen);
33 #endif
37 /**********************
39 * if successful, returns NULL
40 * if file locked, returns username of person locking the file
41 * if other error, returns "LOCK ERROR: explanation"
43 *********************/
44 char *dolock(char *fname)
46 int fd, n;
47 static char lname[MAXLOCK], locker[MAXNAME + 1];
48 int mask;
49 struct stat sbuf;
51 strcat(strcpy(lname, fname), ".lock~");
53 /* check that we are not being cheated, qname must point to */
54 /* a regular file - even this code leaves a small window of */
55 /* vulnerability but it is rather hard to exploit it */
57 #if defined(S_IFLNK)
58 if (lstat(lname, &sbuf) == 0)
59 #else
60 if (stat(lname, &sbuf) == 0)
61 #endif
62 #if defined(S_ISREG)
63 if (!S_ISREG(sbuf.st_mode))
64 #else
65 if (!(((sbuf.st_mode) & 070000) == 0)) /* SysV R2 */
66 #endif
67 return "LOCK ERROR: not a regular file";
69 mask = umask(0);
70 fd = open(lname, O_RDWR | O_CREAT, 0666);
71 umask(mask);
72 if (fd < 0) {
73 if (errno == EACCES)
74 return NULL;
75 #ifdef EROFS
76 if (errno == EROFS)
77 return NULL;
78 #endif
79 return "LOCK ERROR: cannot access lock file";
81 if ((n = read(fd, locker, MAXNAME)) < 1) {
82 lseek(fd, 0, SEEK_SET);
83 /* strcpy(locker, getlogin()); */
84 cuserid(locker);
85 strcat(locker + strlen(locker), "@");
86 gethostname(locker + strlen(locker), 64);
87 write(fd, locker, strlen(locker));
88 close(fd);
89 return NULL;
91 locker[n > MAXNAME ? MAXNAME : n] = 0;
92 return locker;
96 /*********************
98 * undolock -- unlock the file fname
100 * if successful, returns NULL
101 * if other error, returns "LOCK ERROR: explanation"
103 *********************/
105 char *undolock(char *fname)
107 static char lname[MAXLOCK];
109 strcat(strcpy(lname, fname), ".lock~");
110 if (unlink(lname) != 0) {
111 if (errno == EACCES || errno == ENOENT)
112 return NULL;
113 #ifdef EROFS
114 if (errno == EROFS)
115 return NULL;
116 #endif
117 return "LOCK ERROR: cannot remove lock file";
120 return NULL;
122 #endif