1 /*
2 * lckfiles.c set_lock() and release_lock(), for maintaining
3 * little file.lck style lockfiles. this isn't what
4 * we would call a standard mechanism. but it's simple.
5 *
6 * it's also not completely integrated with the editor --
7 * for instance, one can probably bypass the locking mechanism
8 * in various ways. it is intended as an _aid_ to multiple
9 * edits. _not_ a cure-all. it works well for the people
10 * at Baan who contributed the code. i make no other claims
11 * for it.
12 *
13 * operation: if the global "usefilelock" is on, then when
14 * "file" is edited, a "file.lck" is created, containing the
15 * username of the user doing the editing. when a file is
16 * edited for which there already exists a .lck file, the buffer
17 * mode "locked" is set to true and "locker" is set to the name
18 * of the user that created the .lck. this information will
19 * appear on the status line, as "locked by pgf", and the
20 * buffer will be marked readonly. the .lck file will be
21 * deleted at most of the appropriate times.
22 *
23 * $Id: lckfiles.c,v 1.13 2020/01/17 22:36:39 tom Exp $
24 *
25 */
26
27 #include "estruct.h"
28 #include "edef.h"
29
30 #if OPT_LCKFILES
31
32 #ifndef HAVE_LONG_FILE_NAMES
33 You probably would not want this code:
34 there are no checks on filename length when adding.lck to the end.
35 #endif
36
37 static void
get_lock_owner(char * lockfile,char * who,int n)38 get_lock_owner(char *lockfile, char *who, int n)
39 {
40 FILE *fp;
41 int l;
42 if ((fp = fopen(lockfile, FOPEN_READ)) != (FILE *) 0) {
43 l = read(fileno(fp), who, (size_t) (n - 1));
44 if (l < 0) {
45 (void) strcpy(who, "'Can't read .lck'");
46 } else {
47 who[l - 1] = EOS; /* Strip \n */
48 }
49 fclose(fp);
50 } else {
51 (void) strcpy(who, "'Can't open .lck'");
52 }
53 }
54
55 static char *
ourname(void)56 ourname(void)
57 {
58 char *np;
59 np = getenv("LOGNAME");
60 if (!np)
61 np = getenv("USER");
62 if (!np)
63 np = "unknown";
64 return np;
65 }
66
67 int
set_lock(const char * fname,char * who,int n)68 set_lock(const char *fname, char *who, int n)
69 {
70 char lockfile[NFILEN];
71 FILE *fp;
72
73 sprintf(lockfile, "%s.lck", fname);
74
75 if (ffexists(lockfile)) {
76 /* Lockfile exists */
77 get_lock_owner(lockfile, who, n);
78 mlwrite("[%s]", who);
79 return FALSE; /* Can't set lock */
80 } else {
81 if ((fp = fopen(lockfile, FOPEN_WRITE)) != (FILE *) 0) {
82 (void) lsprintf(who, "%s\n", ourname());
83 write(fileno(fp), who, strlen(who));
84 fclose(fp);
85 } else {
86 (void) strcpy(who, "'Can't write .lck'");
87 mlwrite("[%s]", who);
88 return (FALSE); /* Can't set lock */
89 }
90 }
91 return TRUE; /* Lock ok */
92 }
93
94 void
release_lock(const char * fname)95 release_lock(const char *fname)
96 {
97 char lockfile[NFILEN];
98 char who[100];
99
100 if (fname && *fname) {
101 (void) lsprintf(lockfile, "%s.lck", fname);
102 get_lock_owner(lockfile, who, sizeof(who));
103 /* is it ours? */
104 if (strcmp(who, ourname()) == 0)
105 unlink(lockfile);
106 }
107 }
108 #endif
109