summaryrefslogtreecommitdiffabout
path: root/libetpan/src/data-types/maillock.c
Unidiff
Diffstat (limited to 'libetpan/src/data-types/maillock.c') (more/less context) (ignore whitespace changes)
-rw-r--r--libetpan/src/data-types/maillock.c301
1 files changed, 301 insertions, 0 deletions
diff --git a/libetpan/src/data-types/maillock.c b/libetpan/src/data-types/maillock.c
new file mode 100644
index 0000000..b1741d0
--- a/dev/null
+++ b/libetpan/src/data-types/maillock.c
@@ -0,0 +1,301 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * Copyright (C) 2001, 2005 - DINH Viet Hoa
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the libEtPan! project nor the names of its
16 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32/*
33 * $Id$
34 */
35
36#include "maillock.h"
37
38#include "libetpan-config.h"
39
40#include <sys/types.h>
41#include <sys/stat.h>
42#include <fcntl.h>
43#include <unistd.h>
44#include <stdio.h>
45#include <time.h>
46#include <string.h>
47#include "config.h"
48
49#ifdef HAVE_LIBLOCKFILE
50#include <lockfile.h>
51#endif
52
53/* ********************************************************************** */
54
55/* lock primitives */
56
57/* the lock code is modified from the dot lock file code from mail.local.c */
58
59/*
60 SENDMAIL LICENSE
61
62The following license terms and conditions apply, unless a different
63license is obtained from Sendmail, Inc., 6425 Christie Ave, Fourth Floor,
64Emeryville, CA 94608, or by electronic mail at license@sendmail.com.
65
66License Terms:
67
68Use, Modification and Redistribution (including distribution of any
69modified or derived work) in source and binary forms is permitted only if
70each of the following conditions is met:
71
721. Redistributions qualify as "freeware" or "Open Source Software" under
73 one of the following terms:
74
75 (a) Redistributions are made at no charge beyond the reasonable cost of
76 materials and delivery.
77
78 (b) Redistributions are accompanied by a copy of the Source Code or by an
79 irrevocable offer to provide a copy of the Source Code for up to three
80 years at the cost of materials and delivery. Such redistributions
81 must allow further use, modification, and redistribution of the Source
82 Code under substantially the same terms as this license. For the
83 purposes of redistribution "Source Code" means the complete compilable
84 and linkable source code of sendmail including all modifications.
85
862. Redistributions of source code must retain the copyright notices as they
87 appear in each source code file, these license terms, and the
88 disclaimer/limitation of liability set forth as paragraph 6 below.
89
903. Redistributions in binary form must reproduce the Copyright Notice,
91 these license terms, and the disclaimer/limitation of liability set
92 forth as paragraph 6 below, in the documentation and/or other materials
93 provided with the distribution. For the purposes of binary distribution
94 the "Copyright Notice" refers to the following language:
95 "Copyright (c) 1998-2002 Sendmail, Inc. All rights reserved."
96
974. Neither the name of Sendmail, Inc. nor the University of California nor
98 the names of their contributors may be used to endorse or promote
99 products derived from this software without specific prior written
100 permission. The name "sendmail" is a trademark of Sendmail, Inc.
101
1025. All redistributions must comply with the conditions imposed by the
103 University of California on certain embedded code, whose copyright
104 notice and conditions for redistribution are as follows:
105
106 (a) Copyright (c) 1988, 1993 The Regents of the University of
107 California. All rights reserved.
108
109 (b) Redistribution and use in source and binary forms, with or without
110 modification, are permitted provided that the following conditions
111 are met:
112
113 (i) Redistributions of source code must retain the above copyright
114 notice, this list of conditions and the following disclaimer.
115
116 (ii) Redistributions in binary form must reproduce the above
117 copyright notice, this list of conditions and the following
118 disclaimer in the documentation and/or other materials provided
119 with the distribution.
120
121 (iii) Neither the name of the University nor the names of its
122 contributors may be used to endorse or promote products derived
123 from this software without specific prior written permission.
124
1256. Disclaimer/Limitation of Liability: THIS SOFTWARE IS PROVIDED BY
126 SENDMAIL, INC. AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
127 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
128 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
129 NO EVENT SHALL SENDMAIL, INC., THE REGENTS OF THE UNIVERSITY OF
130 CALIFORNIA OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
131 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
132 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
133 USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
134 ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
135 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
136 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
137*/
138
139/*
140 TODO : lock, prefer fcntl() over flock()
141 AND use dotlock code above
142*/
143
144 #define LOCKTO_RM 300/* timeout for stale lockfile removal */
145 #define LOCKTO_GLOB 400/* global timeout for lockfile creation */
146
147static int lock_common(const char * filename, int fd, short locktype)
148{
149 char lockfilename[PATH_MAX];
150 struct flock lock;
151 /* dot lock file */
152 int statfailed = 0;
153 time_t start;
154 int r;
155 int res;
156
157 /* dot lock file */
158
159 if (strlen(filename) + 6 > PATH_MAX) {
160 res = -1;
161 goto err;
162 }
163
164 snprintf(lockfilename, PATH_MAX, "%s.lock", filename);
165
166#ifdef HAVE_LIBLOCKFILE
167 return lockfile_create(lockfilename, LOCKTO_GLOB, 0);
168#else
169
170 lock.l_start = 0;
171 lock.l_len = 0;
172 lock.l_pid = getpid();
173 lock.l_type = locktype;
174 lock.l_whence = SEEK_SET;
175
176 r = fcntl(fd, F_SETLKW, &lock);
177 if (r < 0) {
178 /* WARNING POSIX lock could not be applied */
179 }
180
181 time(&start);
182 while (1) {
183 int fd;
184 struct stat st;
185 time_t now;
186
187 /* global timeout */
188 time(&now);
189 if (now > start + LOCKTO_GLOB) {
190 res = -1;
191 goto unlock;
192 }
193
194 fd = open(lockfilename, O_WRONLY|O_EXCL|O_CREAT, 0);
195 if (fd >= 0) {
196 /* defeat lock checking programs which test pid */
197 write(fd, "0", 2);
198 close(fd);
199 break;
200 }
201
202 /* libEtPan! - adds a delay of 5 seconds between each tries */
203 sleep(5);
204
205 if (stat(lockfilename, &st) < 0) {
206 if (statfailed++ > 5) {
207 res = -1;
208 goto unlock;
209 }
210 continue;
211 }
212 statfailed = 0;
213 time(&now);
214
215 if (now < st.st_ctime + LOCKTO_RM)
216 continue;
217
218 /* try to remove stale lockfile */
219 if (unlink(lockfilename) < 0) {
220 res = -1;
221 goto unlock;
222 }
223
224 /*
225 libEtPan! - removes this delay of 5 seconds,
226 maybe it was misplaced ?
227 */
228#if 0
229 sleep(5);
230#endif
231 }
232
233 return 0;
234
235 unlock:
236 lock.l_start = 0;
237 lock.l_len = 0;
238 lock.l_pid = getpid();
239 lock.l_type = F_UNLCK;
240 lock.l_whence = SEEK_SET;
241
242 r = fcntl(fd, F_SETLK, &lock);
243 if (r < 0) {
244 /* WARNING POSIX lock could not be applied */
245 }
246#endif
247 err:
248 return res;
249}
250
251static int unlock_common(const char * filename, int fd)
252{
253 char lockfilename[PATH_MAX];
254 struct flock lock;
255 int r;
256
257 if (strlen(filename) + 6 > PATH_MAX)
258 return -1;
259
260 snprintf(lockfilename, PATH_MAX, "%s.lock", filename);
261
262#ifdef HAVE_LIBLOCKFILE
263 return lockfile_remove(lockfilename);
264#else
265
266 unlink(lockfilename);
267
268 lock.l_start = 0;
269 lock.l_len = 0;
270 lock.l_pid = getpid();
271 lock.l_type = F_UNLCK;
272 lock.l_whence = SEEK_SET;
273
274 r = fcntl(fd, F_SETLK, &lock);
275 if (r < 0) {
276 /* WARNING POSIX lock could not be applied */
277 }
278
279 return 0;
280#endif
281}
282
283int maillock_read_lock(const char * filename, int fd)
284{
285 return lock_common(filename, fd, F_RDLCK);
286}
287
288int maillock_read_unlock(const char * filename, int fd)
289{
290 return unlock_common(filename, fd);
291}
292
293int maillock_write_lock(const char * filename, int fd)
294{
295 return lock_common(filename, fd, F_WRLCK);
296}
297
298int maillock_write_unlock(const char * filename, int fd)
299{
300 return unlock_common(filename, fd);
301}