... | ... |
@@ -31,6 +31,9 @@ |
31 | 31 |
#include <sys/utsname.h> |
32 | 32 |
#endif |
33 | 33 |
#include <zlib.h> |
34 |
+#include <sys/types.h> |
|
35 |
+#include <sys/stat.h> |
|
36 |
+#include <dirent.h> |
|
34 | 37 |
|
35 | 38 |
#include "shared/optparser.h" |
36 | 39 |
#include "shared/misc.h" |
... | ... |
@@ -38,6 +41,7 @@ |
38 | 38 |
#include "libclamav/str.h" |
39 | 39 |
#include "libclamav/clamav.h" |
40 | 40 |
#include "libclamav/others.h" |
41 |
+#include "libclamav/readdb.h" |
|
41 | 42 |
#include "libclamav/bytecode.h" |
42 | 43 |
#include "libclamav/bytecode_detect.h" |
43 | 44 |
#include "target.h" |
... | ... |
@@ -58,11 +62,6 @@ static struct _cfgfile { |
58 | 58 |
{ NULL, 0 } |
59 | 59 |
}; |
60 | 60 |
|
61 |
-static const char *dbnames[] = { "main.cvd", "main.cld", "daily.cvd", |
|
62 |
- "daily.cld", "safebrowsing.cvd", |
|
63 |
- "safebrowsing.cld", "bytecode.cvd", |
|
64 |
- "bytecode.cld", NULL }; |
|
65 |
- |
|
66 | 61 |
static void printopts(struct optstruct *opts, int nondef) |
67 | 62 |
{ |
68 | 63 |
const struct optstruct *opt; |
... | ... |
@@ -306,6 +305,56 @@ static void print_build(struct cli_environment *env) |
306 | 306 |
env->dconf_level); |
307 | 307 |
} |
308 | 308 |
|
309 |
+static void print_dbs(const char *dir) |
|
310 |
+{ |
|
311 |
+ DIR *dd; |
|
312 |
+ struct dirent *dent; |
|
313 |
+ char *dbfile; |
|
314 |
+ unsigned int flevel = cl_retflevel(), cnt, sigs = 0; |
|
315 |
+ struct cl_cvd *cvd; |
|
316 |
+ |
|
317 |
+ if((dd = opendir(dir)) == NULL) { |
|
318 |
+ printf("print_dbs: Can't open directory %s\n", dir); |
|
319 |
+ return; |
|
320 |
+ } |
|
321 |
+ |
|
322 |
+ while((dent = readdir(dd))) { |
|
323 |
+ if(dent->d_ino) { |
|
324 |
+ if(CLI_DBEXT(dent->d_name)) { |
|
325 |
+ dbfile = (char *) malloc(strlen(dent->d_name) + strlen(dir) + 2); |
|
326 |
+ if(!dbfile) { |
|
327 |
+ printf("print_dbs: Can't allocate memory for dbfile\n"); |
|
328 |
+ return; |
|
329 |
+ } |
|
330 |
+ sprintf(dbfile, "%s"PATHSEP"%s", dir, dent->d_name); |
|
331 |
+ if(cli_strbcasestr(dbfile, ".cvd") || cli_strbcasestr(dbfile, ".cld")) { |
|
332 |
+ cvd = cl_cvdhead(dbfile); |
|
333 |
+ if(!cvd) { |
|
334 |
+ printf("%s: Can't get information about the database\n", dbfile); |
|
335 |
+ } else { |
|
336 |
+ const time_t t = cvd->stime; |
|
337 |
+ printf("%s: version %u, sigs: %u, built on %s", dent->d_name, cvd->version, cvd->sigs, ctime(&t)); |
|
338 |
+ sigs += cvd->sigs; |
|
339 |
+ if(cvd->fl > flevel) |
|
340 |
+ printf("%s: WARNING: This database requires f-level %u (current f-level: %u)\n", dent->d_name, cvd->fl, flevel); |
|
341 |
+ cl_cvdfree(cvd); |
|
342 |
+ } |
|
343 |
+ } else if(cli_strbcasestr(dbfile, ".cbc")) { |
|
344 |
+ printf("[3rd Party] %s: bytecode\n", dent->d_name); |
|
345 |
+ sigs++; |
|
346 |
+ } else { |
|
347 |
+ cnt = countlines(dbfile); |
|
348 |
+ printf("[3rd Party] %s: %u sig%c\n", dent->d_name, cnt, cnt > 1 ? 's' : ' '); |
|
349 |
+ sigs += cnt; |
|
350 |
+ } |
|
351 |
+ free(dbfile); |
|
352 |
+ } |
|
353 |
+ } |
|
354 |
+ } |
|
355 |
+ closedir(dd); |
|
356 |
+ printf("Total number of signatures: %u\n", sigs); |
|
357 |
+} |
|
358 |
+ |
|
309 | 359 |
int main(int argc, char **argv) |
310 | 360 |
{ |
311 | 361 |
const char *dir; |
... | ... |
@@ -313,8 +362,6 @@ int main(int argc, char **argv) |
313 | 313 |
struct optstruct *opts, *toolopts; |
314 | 314 |
const struct optstruct *opt; |
315 | 315 |
unsigned int i, j; |
316 |
- struct cl_cvd *cvd; |
|
317 |
- unsigned int flevel; |
|
318 | 316 |
struct cli_environment env; |
319 | 317 |
|
320 | 318 |
|
... | ... |
@@ -416,26 +463,13 @@ int main(int argc, char **argv) |
416 | 416 |
} |
417 | 417 |
dbdir[sizeof(dbdir) - 1] = 0; |
418 | 418 |
} |
419 |
+ |
|
420 |
+ printf("\nDatabase information\n--------------------\n"); |
|
419 | 421 |
printf("Database directory: %s\n", dbdir); |
420 | 422 |
if(strcmp(dbdir, clamd_dbdir)) |
421 | 423 |
printf("WARNING: freshclam.conf and clamd.conf point to different database directories\n"); |
422 |
- flevel = cl_retflevel(); |
|
423 |
- for(i = 0; dbnames[i]; i++) { |
|
424 |
- snprintf(path, sizeof(path), "%s"PATHSEP"%s", dbdir, dbnames[i]); |
|
425 |
- path[511] = 0; |
|
426 |
- if(!access(path, R_OK)) { |
|
427 |
- cvd = cl_cvdhead(path); |
|
428 |
- if(!cvd) { |
|
429 |
- printf("%s: Can't get information about the database\n", dbnames[i]); |
|
430 |
- } else { |
|
431 |
- const time_t t = cvd->stime; |
|
432 |
- printf("%s: version %u, sigs: %u, built on %s", dbnames[i], cvd->version, cvd->sigs, ctime(&t)); |
|
433 |
- if(cvd->fl > flevel) |
|
434 |
- printf("%s: WARNING: This database requires f-level %u (current f-level: %u)\n", dbnames[i], cvd->fl, flevel); |
|
435 |
- cl_cvdfree(cvd); |
|
436 |
- } |
|
437 |
- } |
|
438 |
- } |
|
424 |
+ print_dbs(dbdir); |
|
425 |
+ |
|
439 | 426 |
cli_detect_environment(&env); |
440 | 427 |
print_platform(&env); |
441 | 428 |
print_build(&env); |
... | ... |
@@ -348,3 +348,23 @@ int cli_is_abspath(const char *path) { |
348 | 348 |
return *path == '/'; |
349 | 349 |
#endif |
350 | 350 |
} |
351 |
+ |
|
352 |
+unsigned int countlines(const char *filename) |
|
353 |
+{ |
|
354 |
+ FILE *fh; |
|
355 |
+ char buff[1024]; |
|
356 |
+ unsigned int lines = 0; |
|
357 |
+ |
|
358 |
+ |
|
359 |
+ if((fh = fopen(filename, "r")) == NULL) |
|
360 |
+ return 0; |
|
361 |
+ |
|
362 |
+ while(fgets(buff, sizeof(buff), fh)) { |
|
363 |
+ if(buff[0] == '#') continue; |
|
364 |
+ lines++; |
|
365 |
+ } |
|
366 |
+ |
|
367 |
+ fclose(fh); |
|
368 |
+ return lines; |
|
369 |
+} |
|
370 |
+ |
... | ... |
@@ -53,5 +53,6 @@ const char *get_version(void); |
53 | 53 |
int match_regex(const char *filename, const char *pattern); |
54 | 54 |
int cfg_tcpsock(const struct optstruct *opts, struct sockaddr_in *server, in_addr_t defaultbind); |
55 | 55 |
int cli_is_abspath(const char *path); |
56 |
+unsigned int countlines(const char *filename); |
|
56 | 57 |
|
57 | 58 |
#endif |
... | ... |
@@ -263,25 +263,6 @@ static int utf16decode(const struct optstruct *opts) |
263 | 263 |
return 0; |
264 | 264 |
} |
265 | 265 |
|
266 |
-static unsigned int countlines(const char *filename) |
|
267 |
-{ |
|
268 |
- FILE *fh; |
|
269 |
- char buff[1024]; |
|
270 |
- unsigned int lines = 0; |
|
271 |
- |
|
272 |
- |
|
273 |
- if((fh = fopen(filename, "r")) == NULL) |
|
274 |
- return 0; |
|
275 |
- |
|
276 |
- while(fgets(buff, sizeof(buff), fh)) { |
|
277 |
- if(buff[0] == '#') continue; |
|
278 |
- lines++; |
|
279 |
- } |
|
280 |
- |
|
281 |
- fclose(fh); |
|
282 |
- return lines; |
|
283 |
-} |
|
284 |
- |
|
285 | 266 |
static char *getdsig(const char *host, const char *user, const unsigned char *data, unsigned int datalen, unsigned short mode) |
286 | 267 |
{ |
287 | 268 |
char buff[512], cmd[128], pass[30], *pt; |