aboutsummaryrefslogtreecommitdiffstats
path: root/lock.c
blob: dce53a74824cd0e7e3d5c0630dad07eaae974f78 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
/*	LOCK.C
 *
 *	File locking command routines
 *
 *	written by Daniel Lawrence
 */

#include <stdio.h>
#include "estruct.h"
#include "edef.h"
#include "efunc.h"

#if	BSD | SVR4
#include <sys/errno.h>

static char *lname[NLOCKS];		/* names of all locked files */
static int numlocks;			/* # of current locks active */

/*
 * lockchk:
 *	check a file for locking and add it to the list
 *
 * char *fname;			file to check for a lock
 */
int lockchk(char *fname)
{
	int i;		/* loop indexes */
	int status;	/* return status */

	/* check to see if that file is already locked here */
	if (numlocks > 0)
		for (i = 0; i < numlocks; ++i)
			if (strcmp(fname, lname[i]) == 0)
				return TRUE;

	/* if we have a full locking table, bitch and leave */
	if (numlocks == NLOCKS) {
		mlwrite("LOCK ERROR: Lock table full");
		return ABORT;
	}

	/* next, try to lock it */
	status = lock(fname);
	if (status == ABORT)	/* file is locked, no override */
		return ABORT;
	if (status == FALSE)	/* locked, overriden, dont add to table */
		return TRUE;

	/* we have now locked it, add it to our table */
	lname[++numlocks - 1] = (char *) malloc(strlen(fname) + 1);
	if (lname[numlocks - 1] == NULL) {	/* malloc failure */
		undolock(fname);	/* free the lock */
		mlwrite("Cannot lock, out of memory");
		--numlocks;
		return ABORT;
	}

	/* everthing is cool, add it to the table */
	strcpy(lname[numlocks - 1], fname);
	return TRUE;
}

/*
 * lockrel:
 *	release all the file locks so others may edit
 */
int lockrel(void)
{
	int i;		/* loop index */
	int status;	/* status of locks */
	int s;		/* status of one unlock */

	status = TRUE;
	if (numlocks > 0)
		for (i = 0; i < numlocks; ++i) {
			if ((s = unlock(lname[i])) != TRUE)
				status = s;
			free(lname[i]);
		}
	numlocks = 0;
	return status;
}

/*
 * lock:
 *	Check and lock a file from access by others
 *	returns	TRUE = files was not locked and now is
 *		FALSE = file was locked and overridden
 *		ABORT = file was locked, abort command
 *
 * char *fname;		file name to lock
 */
int lock(char *fname)
{
	char *locker;	/* lock error message */
	int status;	/* return status */
	char msg[NSTRING];	/* message string */

	/* attempt to lock the file */
	locker = dolock(fname);
	if (locker == NULL)	/* we win */
		return TRUE;

	/* file failed...abort */
	if (strncmp(locker, "LOCK", 4) == 0) {
		lckerror(locker);
		return ABORT;
	}

	/* someone else has it....override? */
	strcpy(msg, "File in use by ");
	strcat(msg, locker);
	strcat(msg, ", override?");
	status = mlyesno(msg);	/* ask them */
	if (status == TRUE)
		return FALSE;
	else
		return ABORT;
}

/*
 * unlock:
 *	Unlock a file
 *	this only warns the user if it fails
 *
 * char *fname;		file to unlock
 */
int unlock(char *fname)
{
	char *locker;	/* undolock return string */

	/* unclock and return */
	locker = undolock(fname);
	if (locker == NULL)
		return TRUE;

	/* report the error and come back */
	lckerror(locker);
	return FALSE;
}

/*
 * report a lock error
 *
 * char *errstr;	lock error string to print out
 */
void lckerror(char *errstr)
{
	char obuf[NSTRING];	/* output buffer for error message */

	strcpy(obuf, errstr);
	strcat(obuf, " - ");
	strcat(obuf, strerror(errno));
	mlwrite(obuf);
}
#endif