1 /*	LOCK:	File locking command routines for MicroEMACS
2 		written by Daniel Lawrence
3 								*/
4 
5 #include <stdio.h>
6 #include "estruct.h"
7 #include "eproto.h"
8 #include "edef.h"
9 #include "elang.h"
10 
11 #if	FILOCK
12 
13 #if BSD
14 #undef BSD
15 #include <sys/param.h>
16 #endif
17 
18 #if	BSD || FREEBSD || WMCS || SUN || XENIX || HPUX8 || HPUX9 || AVIION || USG || AIX || AUX
19 #include <sys/errno.h>
20 #if !(defined(BSD) && (BSD >= 199103))
21 extern int sys_nerr;		/* number of system error messages defined */
22 extern char *sys_errlist[];	/* list of message texts */
23 #endif
24 #endif
25 
26 #if	MSC
27 #include <errno.h>
28 #else
29 extern int errno;		/* current error */
30 #endif
31 
32 char *lname[NLOCKS];	/* names of all locked files */
33 int numlocks;		/* # of current locks active */
34 
35 /* lockchk:	check a file for locking and add it to the list */
36 
lockchk(fname)37 lockchk(fname)
38 
39 char *fname;	/* file to check for a lock */
40 
41 {
42 	register int i;		/* loop indexes */
43 	register int status;	/* return status */
44 
45 	/* check to see if that file is already locked here */
46 	if (numlocks > 0)
47 		for (i=0; i < numlocks; ++i)
48 			if (strcmp(fname, lname[i]) == 0)
49 				return(TRUE);
50 
51 	/* if we have a full locking table, bitch and leave */
52 	if (numlocks == NLOCKS) {
53 		mlwrite(TEXT173);
54 /*                      "LOCK ERROR: Lock table full" */
55 		return(ABORT);
56 	}
57 
58 	/* next, try to lock it */
59 	status = xlock(fname);
60 	if (status == ABORT)	/* file is locked, no override */
61 		return(ABORT);
62 	if (status == FALSE)	/* locked, overriden, dont add to table */
63 		return(TRUE);
64 
65 	/* we have now locked it, add it to our table */
66 	lname[++numlocks - 1] = (char *)room(strlen(fname) + 1);
67 	if (lname[numlocks - 1] == NULL) {	/* room failure */
68 		undolock(fname);		/* free the lock */
69 		mlwrite(TEXT174);
70 /*                      "Cannot lock, out of memory" */
71 		--numlocks;
72 		return(ABORT);
73 	}
74 
75 	/* everthing is cool, add it to the table */
76 	strcpy(lname[numlocks-1], fname);
77 	return(TRUE);
78 }
79 
80 /*	lockrel:	release all the file locks so others may edit */
81 
lockrel()82 lockrel()
83 
84 {
85 	register int i;		/* loop index */
86 	register int status;	/* status of locks */
87 	register int s;		/* status of one unlock */
88 
89 	status = TRUE;
90 	while (numlocks-- > 0) {
91 		if ((s = xunlock(lname[numlocks])) != TRUE)
92 			status = s;
93 		free(lname[numlocks]);
94 	}
95 	return(status);
96 }
97 
98 /* lock:	Check and lock a file from access by others
99 		returns	TRUE = files was not locked and now is
100 			FALSE = file was locked and overridden
101 			ABORT = file was locked, abort command
102 */
103 
xlock(fname)104 xlock(fname)
105 
106 char *fname;	/* file name to lock */
107 
108 {
109 	register char *locker;	/* lock error message */
110 	register int status;	/* return status */
111 	char msg[NSTRING];	/* message string */
112 
113 	/* attempt to lock the file */
114 	locker = dolock(fname);
115 	if (locker == NULL)	/* we win */
116 		return(TRUE);
117 
118 	/* file failed...abort */
119 	if (strncmp(locker, TEXT175, 4) == 0) {
120 /*                          "LOCK" */
121 		lckerror(locker);
122 		return(ABORT);
123 	}
124 
125 	/* someone else has it....override? */
126 	strcpy(msg, TEXT176);
127 /*                  "File in use by " */
128 	strcat(msg, locker);
129 	strcat(msg, TEXT177);
130 /*                  ", overide?" */
131 	status = mlyesno(msg);		/* ask them */
132 	if (status == TRUE)
133 		return(FALSE);
134 	else
135 		return(ABORT);
136 }
137 
138 /*	xunlock: Unlock a file
139 		this only warns the user if it fails
140 							*/
141 
xunlock(fname)142 xunlock(fname)
143 
144 char *fname;	/* file to unlock */
145 
146 {
147 	register char *locker;	/* undolock return string */
148 
149 	/* unclock and return */
150 	locker = undolock(fname);
151 	if (locker == NULL)
152 		return(TRUE);
153 
154 	/* report the error and come back */
155 	lckerror(locker);
156 	return(FALSE);
157 }
158 
lckerror(errstr)159 lckerror(errstr)	/* report a lock error */
160 
161 char *errstr;		/* lock error string to print out */
162 
163 {
164 	char obuf[NSTRING];	/* output buffer for error message */
165 
166 	strcpy(obuf, errstr);
167 	strcat(obuf, " - ");
168 #if	BSD || FREEBSD || WMCS || SUN || XENIX || HPUX8 || HPUX9 || AVIION || USG || AIX || AUX
169 	if (errno < sys_nerr)
170 		strcat(obuf, sys_errlist[errno]);
171 	else
172 		strcat(obuf, TEXT178);
173 /*                           "[can not get system error message]" */
174 #else
175 	strcat(obuf, "Error # ");
176 	strcat(obuf, int_asc(errno));
177 #endif
178 	mlwrite(obuf);
179 	update(TRUE);
180 }
181 #else
lckhello()182 lckhello()	/* dummy function */
183 {
184 }
185 #endif
186