git-svn: trunk@2620
Tomasz Kojm authored on 2007/01/14 01:57:58... | ... |
@@ -1,3 +1,8 @@ |
1 |
+Sat Jan 13 17:55:25 CET 2007 (tk) |
|
2 |
+--------------------------------- |
|
3 |
+ * libclamav, freshclam: add dbdir locking mechanism (closes bb#113, #143) |
|
4 |
+ Patch from Mark Pizzolato |
|
5 |
+ |
|
1 | 6 |
Sat Jan 13 15:37:51 CET 2007 (acab) |
2 | 7 |
----------------------------------- |
3 | 8 |
* libclamav: add Upack support from Michal Spadlinski <gim913 * gmail.com> |
... | ... |
@@ -55,6 +55,8 @@ |
55 | 55 |
#include "shared/output.h" |
56 | 56 |
#include "shared/misc.h" |
57 | 57 |
|
58 |
+#include "libclamav/lockdb.h" |
|
59 |
+ |
|
58 | 60 |
#include "execute.h" |
59 | 61 |
#include "manager.h" |
60 | 62 |
#include "mirman.h" |
... | ... |
@@ -148,7 +150,7 @@ void help(void) |
148 | 148 |
mprintf("\n"); |
149 | 149 |
} |
150 | 150 |
|
151 |
-int download(const struct cfgstruct *copt, const struct optstruct *opt) |
|
151 |
+int download(const struct cfgstruct *copt, const struct optstruct *opt, const char *datadir) |
|
152 | 152 |
{ |
153 | 153 |
int ret = 0, try = 0, maxattempts = 0; |
154 | 154 |
struct cfgstruct *cpt; |
... | ... |
@@ -161,7 +163,15 @@ int download(const struct cfgstruct *copt, const struct optstruct *opt) |
161 | 161 |
logg("^You must specify at least one database mirror.\n"); |
162 | 162 |
return 56; |
163 | 163 |
} else { |
164 |
- |
|
164 |
+ while(cli_writelockdb(datadir, 0) == CL_ELOCKDB) { |
|
165 |
+ logg("*Waiting to lock database directory: %s\n", datadir); |
|
166 |
+ sleep(5); |
|
167 |
+ if(++try > 12) { |
|
168 |
+ logg("!Can't lock database directory: %s\n", datadir); |
|
169 |
+ return 61; |
|
170 |
+ } |
|
171 |
+ } |
|
172 |
+ try = 0; |
|
165 | 173 |
while(cpt) { |
166 | 174 |
ret = downloadmanager(copt, opt, cpt->strarg); |
167 | 175 |
alarm(0); |
... | ... |
@@ -182,9 +192,11 @@ int download(const struct cfgstruct *copt, const struct optstruct *opt) |
182 | 182 |
} |
183 | 183 |
|
184 | 184 |
} else { |
185 |
+ cli_unlockdb(datadir); |
|
185 | 186 |
return ret; |
186 | 187 |
} |
187 | 188 |
} |
189 |
+ cli_unlockdb(datadir); |
|
188 | 190 |
} |
189 | 191 |
|
190 | 192 |
return ret; |
... | ... |
@@ -489,7 +501,7 @@ int main(int argc, char **argv) |
489 | 489 |
#endif |
490 | 490 |
|
491 | 491 |
while(!terminate) { |
492 |
- ret = download(copt, opt); |
|
492 |
+ ret = download(copt, opt, newdir); |
|
493 | 493 |
|
494 | 494 |
if(ret > 1) { |
495 | 495 |
const char *arg = NULL; |
... | ... |
@@ -541,7 +553,7 @@ int main(int argc, char **argv) |
541 | 541 |
} |
542 | 542 |
|
543 | 543 |
} else |
544 |
- ret = download(copt, opt); |
|
544 |
+ ret = download(copt, opt, newdir); |
|
545 | 545 |
|
546 | 546 |
if(opt_check(opt, "on-error-execute")) { |
547 | 547 |
if(ret > 1) |
... | ... |
@@ -88,7 +88,8 @@ am_libclamav_la_OBJECTS = matcher-ac.lo matcher-bm.lo matcher-ncore.lo \ |
88 | 88 |
unrarfilter.lo unrarppm.lo unrar20.lo unrarcmd.lo pdf.lo \ |
89 | 89 |
spin.lo yc.lo elf.lo sis.lo uuencode.lo pst.lo phishcheck.lo \ |
90 | 90 |
phish_domaincheck_db.lo phish_whitelist.lo regex_list.lo \ |
91 |
- sha256.lo mspack.lo cab.lo entconv.lo hashtab.lo dconf.lo |
|
91 |
+ sha256.lo mspack.lo cab.lo entconv.lo hashtab.lo dconf.lo \ |
|
92 |
+ lockdb.lo |
|
92 | 93 |
libclamav_la_OBJECTS = $(am_libclamav_la_OBJECTS) |
93 | 94 |
DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir) |
94 | 95 |
depcomp = $(SHELL) $(top_srcdir)/depcomp |
... | ... |
@@ -376,7 +377,9 @@ libclamav_la_SOURCES = \ |
376 | 376 |
hashtab.c \ |
377 | 377 |
hashtab.h \ |
378 | 378 |
dconf.c \ |
379 |
- dconf.h |
|
379 |
+ dconf.h \ |
|
380 |
+ lockdb.c \ |
|
381 |
+ lockdb.h |
|
380 | 382 |
|
381 | 383 |
lib_LTLIBRARIES = libclamav.la |
382 | 384 |
all: all-am |
... | ... |
@@ -463,6 +466,7 @@ distclean-compile: |
463 | 463 |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/htmlnorm.Plo@am__quote@ |
464 | 464 |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/is_tar.Plo@am__quote@ |
465 | 465 |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/line.Plo@am__quote@ |
466 |
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lockdb.Plo@am__quote@ |
|
466 | 467 |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/matcher-ac.Plo@am__quote@ |
467 | 468 |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/matcher-bm.Plo@am__quote@ |
468 | 469 |
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/matcher-ncore.Plo@am__quote@ |
... | ... |
@@ -62,7 +62,7 @@ extern "C" |
62 | 62 |
#define CL_EIO -123 /* general I/O error */ |
63 | 63 |
#define CL_EFORMAT -124 /* bad format or broken file */ |
64 | 64 |
#define CL_ESUPPORT -125 /* not supported data format */ |
65 |
-#define CL_EFOO -126 /* fake error code */ |
|
65 |
+#define CL_ELOCKDB -126 /* can't lock DB directory */ |
|
66 | 66 |
|
67 | 67 |
/* NodalCore */ |
68 | 68 |
#define CL_ENCINIT -200 /* NodalCore initialization failed */ |
69 | 69 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,277 @@ |
0 |
+/* |
|
1 |
+ * Copyright (C) 2006 Mark Pizzolato <clamav-devel@subscriptions.pizzolato.net> |
|
2 |
+ * |
|
3 |
+ * This program is free software; you can redistribute it and/or modify |
|
4 |
+ * it under the terms of the GNU General Public License as published by |
|
5 |
+ * the Free Software Foundation; either version 2 of the License, or |
|
6 |
+ * (at your option) any later version. |
|
7 |
+ * |
|
8 |
+ * This program is distributed in the hope that it will be useful, |
|
9 |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
10 |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
11 |
+ * GNU General Public License for more details. |
|
12 |
+ * |
|
13 |
+ * You should have received a copy of the GNU General Public License |
|
14 |
+ * along with this program; if not, write to the Free Software |
|
15 |
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, |
|
16 |
+ * MA 02110-1301, USA. |
|
17 |
+ */ |
|
18 |
+ |
|
19 |
+/* |
|
20 |
+ * This is a problem, which from a purist point of view, best wants an |
|
21 |
+ * RW locking mechanism. |
|
22 |
+ * On Posix platforms, we leverage advisory locks provided by fcntl(). |
|
23 |
+ * Windows doesn't have a native interprocess RW exclusion mechanism, |
|
24 |
+ * one could be constructed from the services available, but it is somewhat |
|
25 |
+ * complicated. Meanwhile, we observe that in ClamAV, it is extremely rare |
|
26 |
+ * that there will ever be an occasion when multiple processes will be |
|
27 |
+ * reading the ClamAV database from a given directory at the same, and in |
|
28 |
+ * none of those possible cases would it matter if they serialized their |
|
29 |
+ * accesses. So, a simple mutual exclusion mechanism will suffice for both |
|
30 |
+ * the reader and writer locks on Windows. |
|
31 |
+ */ |
|
32 |
+ |
|
33 |
+#if HAVE_CONFIG_H |
|
34 |
+#include "clamav-config.h" |
|
35 |
+#endif |
|
36 |
+ |
|
37 |
+#include <stdio.h> |
|
38 |
+#include <stdarg.h> |
|
39 |
+#include <stdlib.h> |
|
40 |
+#include <string.h> |
|
41 |
+#include <ctype.h> |
|
42 |
+#ifndef C_WINDOWS |
|
43 |
+#include <unistd.h> |
|
44 |
+#include <fcntl.h> |
|
45 |
+#include <sys/stat.h> |
|
46 |
+#else |
|
47 |
+#include <windows.h> |
|
48 |
+#endif |
|
49 |
+ |
|
50 |
+#include "clamav.h" |
|
51 |
+#include "others.h" |
|
52 |
+ |
|
53 |
+#ifdef CL_THREAD_SAFE |
|
54 |
+#include <pthread.h> |
|
55 |
+pthread_mutex_t lock_mutex = PTHREAD_MUTEX_INITIALIZER; |
|
56 |
+#else |
|
57 |
+#define pthread_mutex_lock(arg) |
|
58 |
+#define pthread_mutex_unlock(arg) |
|
59 |
+#endif |
|
60 |
+ |
|
61 |
+struct dblock { |
|
62 |
+ struct dblock *lock_link; |
|
63 |
+ char lock_file[NAME_MAX]; |
|
64 |
+#ifndef C_WINDOWS |
|
65 |
+ int lock_fd; |
|
66 |
+#else |
|
67 |
+ HANDLE lock_fd; |
|
68 |
+#endif |
|
69 |
+ int lock_type; |
|
70 |
+}; |
|
71 |
+ |
|
72 |
+static struct dblock *dblocks = NULL; |
|
73 |
+ |
|
74 |
+static void cli_lockname(char *lock_file, size_t lock_file_size, const char *dbdirpath); |
|
75 |
+static int cli_lockdb(const char *dbdirpath, int wait, int writelock); |
|
76 |
+ |
|
77 |
+#ifdef DONT_LOCK_DBDIRS |
|
78 |
+ |
|
79 |
+int cli_readlockdb(const char *dbdirpath, int wait) |
|
80 |
+{ |
|
81 |
+ return CL_SUCCESS; |
|
82 |
+} |
|
83 |
+ |
|
84 |
+int cli_writelockdb(const char *dbdirpath, int wait) |
|
85 |
+{ |
|
86 |
+ return CL_SUCCESS; |
|
87 |
+} |
|
88 |
+ |
|
89 |
+int cli_unlockdb(const char *dbdirpath) |
|
90 |
+{ |
|
91 |
+ return CL_SUCCESS; |
|
92 |
+} |
|
93 |
+ |
|
94 |
+#else /* !DONT_LOCK_DBDIRS */ |
|
95 |
+ |
|
96 |
+int cli_readlockdb(const char *dbdirpath, int wait) |
|
97 |
+{ |
|
98 |
+ return cli_lockdb(dbdirpath, wait, 0); |
|
99 |
+} |
|
100 |
+ |
|
101 |
+int cli_writelockdb(const char *dbdirpath, int wait) |
|
102 |
+{ |
|
103 |
+ return cli_lockdb(dbdirpath, wait, 1); |
|
104 |
+} |
|
105 |
+ |
|
106 |
+int cli_unlockdb(const char *dbdirpath) |
|
107 |
+{ |
|
108 |
+ char lock_file[NAME_MAX]; |
|
109 |
+ struct dblock *lock; |
|
110 |
+#ifndef C_WINDOWS |
|
111 |
+ struct flock fl; |
|
112 |
+#endif |
|
113 |
+ |
|
114 |
+ cli_lockname(lock_file, sizeof(lock_file), dbdirpath); |
|
115 |
+ pthread_mutex_lock(&lock_mutex); |
|
116 |
+ for(lock=dblocks; lock; lock=lock->lock_link) |
|
117 |
+ if(!strcmp(lock_file, lock->lock_file)) |
|
118 |
+ break; |
|
119 |
+ if((!lock) || (lock->lock_type == -1)) { |
|
120 |
+ cli_errmsg("Database Directory: %s not locked\n", dbdirpath); |
|
121 |
+ pthread_mutex_unlock(&lock_mutex); |
|
122 |
+ return CL_ELOCKDB; |
|
123 |
+ } |
|
124 |
+#ifndef C_WINDOWS |
|
125 |
+ memset(&fl, 0, sizeof(fl)); |
|
126 |
+ fl.l_type = F_UNLCK; |
|
127 |
+ if(fcntl(lock->lock_fd, F_SETLK, &fl) == -1) { |
|
128 |
+#else |
|
129 |
+ if(!ReleaseMutex(lock->lock_fd)) { |
|
130 |
+#endif |
|
131 |
+ cli_errmsg("Error Unlocking Database Directory %s\n", dbdirpath); |
|
132 |
+ pthread_mutex_unlock(&lock_mutex); |
|
133 |
+ return CL_ELOCKDB; |
|
134 |
+ } |
|
135 |
+ lock->lock_type = -1; |
|
136 |
+ pthread_mutex_unlock(&lock_mutex); |
|
137 |
+ |
|
138 |
+ return CL_SUCCESS; |
|
139 |
+} |
|
140 |
+ |
|
141 |
+static int cli_lockdb(const char *dbdirpath, int wait, int writelock) |
|
142 |
+{ |
|
143 |
+ char lock_file[NAME_MAX]; |
|
144 |
+ struct dblock *lock; |
|
145 |
+#ifndef C_WINDOWS |
|
146 |
+ struct flock fl; |
|
147 |
+ mode_t old_mask; |
|
148 |
+#else |
|
149 |
+ DWORD LastError; |
|
150 |
+ SECURITY_ATTRIBUTES saAttr; |
|
151 |
+ SECURITY_DESCRIPTOR sdDesc; |
|
152 |
+#endif |
|
153 |
+ |
|
154 |
+ cli_lockname(lock_file, sizeof(lock_file), dbdirpath); |
|
155 |
+ pthread_mutex_lock(&lock_mutex); |
|
156 |
+ for(lock=dblocks; lock; lock=lock->lock_link) |
|
157 |
+ if(!strcmp(lock_file, lock->lock_file)) |
|
158 |
+ break; |
|
159 |
+ if(!lock) { |
|
160 |
+ lock = cli_calloc(1, sizeof(*lock)); |
|
161 |
+ if(!lock) { |
|
162 |
+ cli_errmsg("cli_lockdb(): Can't allocate lock structure to lock Database Directory: %s\n", dbdirpath); |
|
163 |
+ pthread_mutex_unlock(&lock_mutex); |
|
164 |
+ return CL_ELOCKDB; |
|
165 |
+ } |
|
166 |
+ lock->lock_link = dblocks; |
|
167 |
+ strcpy(lock->lock_file, lock_file); |
|
168 |
+ lock->lock_fd = -1; |
|
169 |
+ lock->lock_type = -1; |
|
170 |
+ dblocks = lock; |
|
171 |
+ } |
|
172 |
+ if(lock->lock_type != -1) { |
|
173 |
+ cli_errmsg("Database Directory: %s already %s locked\n", dbdirpath, (lock->lock_type? "write" : "read")); |
|
174 |
+ pthread_mutex_unlock(&lock_mutex); |
|
175 |
+ return CL_ELOCKDB; |
|
176 |
+ } |
|
177 |
+#ifndef C_WINDOWS |
|
178 |
+ if(lock->lock_fd == -1) { |
|
179 |
+ old_mask = umask(0); |
|
180 |
+ if(-1 == (lock->lock_fd = open(lock->lock_file, O_RDWR|O_CREAT|O_TRUNC, S_IRWXU|S_IRWXG|S_IROTH))) { |
|
181 |
+ if((writelock) || |
|
182 |
+ (-1 == (lock->lock_fd = open(lock->lock_file, O_RDWR, 0)))) { |
|
183 |
+ cli_errmsg("Can't %s Lock file for Database Directory: %s\n", (writelock ? "create" : "open"), dbdirpath); |
|
184 |
+ umask(old_mask); |
|
185 |
+ pthread_mutex_unlock(&lock_mutex); |
|
186 |
+ return CL_ELOCKDB; |
|
187 |
+ } |
|
188 |
+ } |
|
189 |
+ umask(old_mask); |
|
190 |
+ } |
|
191 |
+#else |
|
192 |
+ if(!lock->lock_fd) { |
|
193 |
+ /* Create a security descriptor which allows any process to acquire the Mutex */ |
|
194 |
+ InitializeSecurityDescriptor(&sdDesc, SECURITY_DESCRIPTOR_REVISION); |
|
195 |
+ SetSecurityDescriptorDacl(&sdDesc, TRUE, NULL, FALSE); |
|
196 |
+ saAttr.nLength = sizeof(saAttr); |
|
197 |
+ saAttr.bInheritHandle = FALSE; |
|
198 |
+ saAttr.lpSecurityDescriptor = &sdDesc; |
|
199 |
+ if(!(lock->lock_fd = CreateMutexA(&saAttr, TRUE, lock->lock_file))) { |
|
200 |
+ if((GetLastError() != ERROR_ACCESS_DENIED) || |
|
201 |
+ (!(lock->lock_fd = OpenMutexA(MUTEX_MODIFY_STATE, FALSE, lock->lock_file)))) { |
|
202 |
+ cli_errmsg("Can't Create Mutex Lock for Database Directory: %s\n", dbdirpath); |
|
203 |
+ pthread_mutex_unlock(&lock_mutex); |
|
204 |
+ return CL_ELOCKDB; |
|
205 |
+ } |
|
206 |
+ LastError = ERROR_ALREADY_EXISTS; |
|
207 |
+ } |
|
208 |
+ LastError = GetLastError(); |
|
209 |
+ } else { |
|
210 |
+ LastError = ERROR_ALREADY_EXISTS; |
|
211 |
+ } |
|
212 |
+#endif |
|
213 |
+ pthread_mutex_unlock(&lock_mutex); |
|
214 |
+ |
|
215 |
+#ifndef C_WINDOWS |
|
216 |
+ memset(&fl, 0, sizeof(fl)); |
|
217 |
+ fl.l_type = (writelock ? F_WRLCK : F_RDLCK); |
|
218 |
+ cli_dbgmsg("przed fcntl: %d\n", lock->lock_fd); |
|
219 |
+ if(fcntl(lock->lock_fd, ((wait) ? F_SETLKW : F_SETLK), &fl) == -1) { |
|
220 |
+ perror("FCNTL"); |
|
221 |
+ return CL_ELOCKDB; |
|
222 |
+ } |
|
223 |
+#else |
|
224 |
+ if(LastError == ERROR_ALREADY_EXISTS) { |
|
225 |
+ if(WAIT_TIMEOUT == WaitForSingleObject(lock->lock_fd, ((wait) ? INFINITE : 0))) { |
|
226 |
+ lock->lock_type = -1; |
|
227 |
+ return CL_ELOCKDB; |
|
228 |
+ } |
|
229 |
+ } |
|
230 |
+#endif |
|
231 |
+ lock->lock_type = writelock; |
|
232 |
+ |
|
233 |
+ return CL_SUCCESS; |
|
234 |
+} |
|
235 |
+ |
|
236 |
+static void cli_lockname(char *lock_file, size_t lock_file_size, const char *dbdirpath) |
|
237 |
+{ |
|
238 |
+ char *c; |
|
239 |
+ |
|
240 |
+ lock_file[lock_file_size-1] = '\0'; |
|
241 |
+#ifndef C_WINDOWS |
|
242 |
+ snprintf(lock_file, lock_file_size-1, "%s/.dbLock", dbdirpath); |
|
243 |
+ for (c=lock_file; *c; ++c) { |
|
244 |
+#else |
|
245 |
+ snprintf(lock_file, lock_file_size-1, "Global\\ClamAVDB-%s", dbdirpath); |
|
246 |
+ for (c=lock_file+16; *c; ++c) { |
|
247 |
+#endif |
|
248 |
+ switch (*c) { |
|
249 |
+#ifdef C_WINDOWS |
|
250 |
+ case '\\': |
|
251 |
+ *c = '/'; |
|
252 |
+#endif |
|
253 |
+ case '/': |
|
254 |
+ if(*(c-1) == '/') { /* compress imbedded // */ |
|
255 |
+ --c; |
|
256 |
+ strcpy(c, c+1); |
|
257 |
+ } else if((*(c-2) == '/') && (*(c-1) == '.')) { /* compress imbedded /./ */ |
|
258 |
+ c -= 2; |
|
259 |
+ strcpy(c, c+2); |
|
260 |
+ } |
|
261 |
+ break; |
|
262 |
+#ifdef C_WINDOWS |
|
263 |
+ default: |
|
264 |
+ if(islower(*c)) /* Normalize to upper case */ |
|
265 |
+ *c = toupper(*c); |
|
266 |
+ break; |
|
267 |
+#endif |
|
268 |
+ } |
|
269 |
+ } |
|
270 |
+#ifdef C_WINDOWS |
|
271 |
+ if('/' == lock_file[strlen(lock_file)-1]) /* Remove trailing / */ |
|
272 |
+ lock_file[strlen(lock_file)-1] = '\0'; |
|
273 |
+#endif |
|
274 |
+} |
|
275 |
+ |
|
276 |
+#endif /* DONT_LOCK_DBDIRS */ |
0 | 277 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,27 @@ |
0 |
+/* |
|
1 |
+ * Copyright (C) 2006 Mark Pizzolato <clamav-devel@subscriptions.pizzolato.net> |
|
2 |
+ * |
|
3 |
+ * This program is free software; you can redistribute it and/or modify |
|
4 |
+ * it under the terms of the GNU General Public License as published by |
|
5 |
+ * the Free Software Foundation; either version 2 of the License, or |
|
6 |
+ * (at your option) any later version. |
|
7 |
+ * |
|
8 |
+ * This program is distributed in the hope that it will be useful, |
|
9 |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
10 |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
11 |
+ * GNU General Public License for more details. |
|
12 |
+ * |
|
13 |
+ * You should have received a copy of the GNU General Public License |
|
14 |
+ * along with this program; if not, write to the Free Software |
|
15 |
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, |
|
16 |
+ * MA 02110-1301, USA. |
|
17 |
+ */ |
|
18 |
+ |
|
19 |
+#ifndef __LOCKDB_H |
|
20 |
+#define __LOCKDB_H |
|
21 |
+ |
|
22 |
+int cli_writelockdb(const char *dbdirpath, int wait); |
|
23 |
+int cli_readlockdb(const char *dbdirpath, int wait); |
|
24 |
+int cli_unlockdb(const char *dbdirpath); |
|
25 |
+ |
|
26 |
+#endif |
... | ... |
@@ -223,6 +223,8 @@ const char *cl_strerror(int clerror) |
223 | 223 |
return "Error loading NodalCore database"; |
224 | 224 |
case CL_ENCIO: |
225 | 225 |
return "NodalCore accelerator Input/Output error"; |
226 |
+ case CL_ELOCKDB: |
|
227 |
+ return "Unable to lock database directory"; |
|
226 | 228 |
default: |
227 | 229 |
return "Unknown error code"; |
228 | 230 |
} |
... | ... |
@@ -46,6 +46,17 @@ |
46 | 46 |
|
47 | 47 |
#define CLI_MAX_ALLOCATION 184549376 |
48 | 48 |
|
49 |
+/* Maximum filenames under various systems - njh */ |
|
50 |
+#ifndef NAME_MAX /* e.g. Linux */ |
|
51 |
+# ifdef MAXNAMELEN /* e.g. Solaris */ |
|
52 |
+# define NAME_MAX MAXNAMELEN |
|
53 |
+# else |
|
54 |
+# ifdef FILENAME_MAX /* e.g. SCO */ |
|
55 |
+# define NAME_MAX FILENAME_MAX |
|
56 |
+# endif |
|
57 |
+# endif |
|
58 |
+#endif |
|
59 |
+ |
|
49 | 60 |
/* internal clamav context */ |
50 | 61 |
typedef struct { |
51 | 62 |
const char **virname; |
... | ... |
@@ -49,6 +49,7 @@ |
49 | 49 |
#include "str.h" |
50 | 50 |
#include "defaults.h" |
51 | 51 |
#include "dconf.h" |
52 |
+#include "lockdb.h" |
|
52 | 53 |
|
53 | 54 |
#ifdef CL_EXPERIMENTAL |
54 | 55 |
#include "phish_whitelist.h" |
... | ... |
@@ -61,19 +62,6 @@ |
61 | 61 |
#include <stddef.h> |
62 | 62 |
#endif |
63 | 63 |
|
64 |
-/* Maximum filenames under various systems - njh */ |
|
65 |
-#ifndef NAME_MAX /* e.g. Linux */ |
|
66 |
-# ifdef MAXNAMELEN /* e.g. Solaris */ |
|
67 |
-# define NAME_MAX MAXNAMELEN |
|
68 |
-# else |
|
69 |
-# ifdef FILENAME_MAX /* e.g. SCO */ |
|
70 |
-# define NAME_MAX FILENAME_MAX |
|
71 |
-# else |
|
72 |
-# define NAME_MAX 256 |
|
73 |
-# endif |
|
74 |
-# endif |
|
75 |
-#endif |
|
76 |
- |
|
77 | 64 |
#ifdef CL_THREAD_SAFE |
78 | 65 |
# include <pthread.h> |
79 | 66 |
static pthread_mutex_t cli_ref_mutex = PTHREAD_MUTEX_INITIALIZER; |
... | ... |
@@ -1210,7 +1198,7 @@ int cl_loaddb(const char *filename, struct cl_engine **engine, unsigned int *sig |
1210 | 1210 |
return cli_load(filename, engine, signo, 0); |
1211 | 1211 |
} |
1212 | 1212 |
|
1213 |
-static int cli_loaddbdir(const char *dirname, struct cl_engine **engine, unsigned int *signo, unsigned int options) |
|
1213 |
+static int cli_loaddbdir_l(const char *dirname, struct cl_engine **engine, unsigned int *signo, unsigned int options) |
|
1214 | 1214 |
{ |
1215 | 1215 |
DIR *dd; |
1216 | 1216 |
struct dirent *dent; |
... | ... |
@@ -1285,6 +1273,25 @@ static int cli_loaddbdir(const char *dirname, struct cl_engine **engine, unsigne |
1285 | 1285 |
return CL_SUCCESS; |
1286 | 1286 |
} |
1287 | 1287 |
|
1288 |
+static int cli_loaddbdir(const char *dirname, struct cl_engine **engine, unsigned int *signo, unsigned int options) |
|
1289 |
+{ |
|
1290 |
+ int ret, try; |
|
1291 |
+ |
|
1292 |
+ |
|
1293 |
+ cli_dbgmsg("cli_loaddbdir: Acquiring dbdir lock\n"); |
|
1294 |
+ while(cli_readlockdb(dirname, 0) == CL_ELOCKDB) { |
|
1295 |
+ sleep(5); |
|
1296 |
+ if(try++ > 24) { |
|
1297 |
+ cli_errmsg("cl_load(): Unable to lock database directory: %s\n", dirname); |
|
1298 |
+ return CL_ELOCKDB; |
|
1299 |
+ } |
|
1300 |
+ } |
|
1301 |
+ |
|
1302 |
+ ret = cli_loaddbdir_l(dirname, engine, signo, options); |
|
1303 |
+ cli_unlockdb(dirname); |
|
1304 |
+ return ret; |
|
1305 |
+} |
|
1306 |
+ |
|
1288 | 1307 |
int cl_loaddbdir(const char *dirname, struct cl_engine **engine, unsigned int *signo) { |
1289 | 1308 |
return cli_loaddbdir(dirname, engine, signo, 0); |
1290 | 1309 |
} |