new config file parser

git-svn: trunk@1596
remotes/push_mirror/metadata
Tomasz Kojm 20 years ago
parent c543263ee0
commit 81837459eb
  1. 13
      clamav-devel/ChangeLog
  2. 3
      clamav-devel/clamd/Makefile.am
  3. 70
      clamav-devel/clamd/clamd.c
  4. 19
      clamav-devel/clamd/clamuko.c
  5. 35
      clamav-devel/clamd/defaults.h
  6. 11
      clamav-devel/clamd/localserver.c
  7. 2
      clamav-devel/clamd/others.c
  8. 51
      clamav-devel/clamd/scanner.c
  9. 133
      clamav-devel/clamd/server-th.c
  10. 16
      clamav-devel/clamd/session.c
  11. 29
      clamav-devel/clamd/tcpserver.c
  12. 10
      clamav-devel/clamdscan/client.c
  13. 134
      clamav-devel/etc/clamd.conf
  14. 34
      clamav-devel/etc/freshclam.conf
  15. 4
      clamav-devel/freshclam/defaults.h
  16. 60
      clamav-devel/freshclam/freshclam.c
  17. 28
      clamav-devel/freshclam/manager.c
  18. 12
      clamav-devel/freshclam/notify.c
  19. 363
      clamav-devel/shared/cfgparser.c
  20. 17
      clamav-devel/shared/cfgparser.h
  21. 4
      clamav-devel/shared/misc.c

@ -1,3 +1,16 @@
Wed Jun 1 02:39:14 CEST 2005 (tk)
----------------------------------
* misc/cfgparser.c: reimplementation of config parser:
- all options require arguments (old ones without
args must be now followed by boolean values: yes, no,
1, 0, or true, false)
- optional arguments (as in NotifyClamd) are no longer
supported
- default values are directly associated with options
* clamd/defaults.h: remove
* clamd, clamdscan, freshclam: use new parser scheme
* etc/clamd.conf: remove DisableDefaultScanOptions
Tue May 31 19:15:01 BST 2005 (njh)
----------------------------------
* libclamav/mbox.c: Fix mishandling of fast track uuencoded files

@ -1,5 +1,5 @@
#
# Copyright (C) 2002 - 2004 Tomasz Kojm <tkojm@clamav.net>
# Copyright (C) 2002 - 2005 Tomasz Kojm <tkojm@clamav.net>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@ -33,7 +33,6 @@ clamd_SOURCES = \
options.c \
options.h \
clamd.c \
defaults.h \
tcpserver.c \
tcpserver.h \
localserver.c \

@ -49,7 +49,6 @@
#include "tcpserver.h"
#include "localserver.h"
#include "others.h"
#include "defaults.h"
#include "memory.h"
#include "output.h"
#include "shared.h"
@ -101,9 +100,9 @@ void clamd(struct optstruct *opt)
if(optc(opt, 'c'))
cfgfile = getargc(opt, 'c');
else
cfgfile = CL_DEFAULT_CFG;
cfgfile = CONFDIR"/clamd.conf";
if((copt = parsecfg(cfgfile, 1)) == NULL) {
if((copt = getcfg(cfgfile, 1)) == NULL) {
fprintf(stderr, "ERROR: Can't open/parse the config file %s\n", cfgfile);
exit(1);
}
@ -112,29 +111,16 @@ void clamd(struct optstruct *opt)
/* initialize logger */
if(cfgopt(copt, "LogFileUnlock"))
logg_lock = 0;
logg_lock = cfgopt(copt, "LogFileUnlock")->enabled;
logg_time = cfgopt(copt, "LogTime")->enabled;
logok = cfgopt(copt, "LogClean")->enabled;
logg_size = cfgopt(copt, "LogFileMaxSize")->numarg;
logg_verbose = cfgopt(copt, "LogVerbose")->enabled;
if(cfgopt(copt, "LogTime"))
logg_time = 1;
if(cfgopt(copt, "LogClean"))
logok = 1;
if((cpt = cfgopt(copt, "LogFileMaxSize")))
logg_size = cpt->numarg;
else
logg_size = CL_DEFAULT_LOGSIZE;
if(cfgopt(copt, "Debug")) /* enable debug messages in libclamav */
if(cfgopt(copt, "Debug")->enabled) /* enable debug messages in libclamav */
cl_debug();
if(cfgopt(copt, "LogVerbose"))
logg_verbose = 1;
else
logg_verbose = 0;
if((cpt = cfgopt(copt, "LogFile"))) {
if((cpt = cfgopt(copt, "LogFile"))->enabled) {
logg_file = cpt->strarg;
if(strlen(logg_file) < 2 || (logg_file[0] != '/' && logg_file[0] != '\\' && logg_file[1] != ':')) {
fprintf(stderr, "ERROR: LogFile requires full path.\n");
@ -148,16 +134,14 @@ void clamd(struct optstruct *opt)
} else
logg_file = NULL;
#if defined(USE_SYSLOG) && !defined(C_AIX)
if(cfgopt(copt, "LogSyslog")) {
if(cfgopt(copt, "LogSyslog")->enabled) {
int fac = LOG_LOCAL6;
if((cpt = cfgopt(copt, "LogFacility"))) {
if((fac = logg_facility(cpt->strarg)) == -1) {
fprintf(stderr, "ERROR: LogFacility: %s: No such facility.\n", cpt->strarg);
exit(1);
}
cpt = cfgopt(copt, "LogFacility");
if((fac = logg_facility(cpt->strarg)) == -1) {
fprintf(stderr, "ERROR: LogFacility: %s: No such facility.\n", cpt->strarg);
exit(1);
}
openlog("clamd", LOG_PID, fac);
@ -183,13 +167,13 @@ void clamd(struct optstruct *opt)
/* check socket type */
if(cfgopt(copt, "TCPSocket") && cfgopt(copt, "LocalSocket")) {
fprintf(stderr, "ERROR: You can select one mode only (local/TCP).\n");
logg("!Two modes (local & TCP) selected.\n");
if(cfgopt(copt, "TCPSocket")->enabled && cfgopt(copt, "LocalSocket")->enabled) {
fprintf(stderr, "ERROR: You can only select one mode (local or TCP).\n");
logg("!Two modes (local and TCP) selected.\n");
exit(1);
} else if(cfgopt(copt, "TCPSocket")) {
} else if(cfgopt(copt, "TCPSocket")->enabled) {
tcpsock = 1;
} else if(cfgopt(copt, "LocalSocket")) {
} else if(cfgopt(copt, "LocalSocket")->enabled) {
tcpsock = 0;
} else {
fprintf(stderr, "ERROR: You must select server type (local/tcp).\n");
@ -199,14 +183,14 @@ void clamd(struct optstruct *opt)
/* drop privileges */
#ifndef C_OS2
if(geteuid() == 0 && (cpt = cfgopt(copt, "User"))) {
if(geteuid() == 0 && (cpt = cfgopt(copt, "User"))->enabled) {
if((user = getpwnam(cpt->strarg)) == NULL) {
fprintf(stderr, "ERROR: Can't get information about user %s.\n", cpt->strarg);
logg("!Can't get information about user %s.\n", cpt->strarg);
exit(1);
}
if(cfgopt(copt, "AllowSupplementaryGroups")) {
if(cfgopt(copt, "AllowSupplementaryGroups")->enabled) {
#ifdef HAVE_INITGROUPS
if(initgroups(cpt->strarg, user->pw_gid)) {
fprintf(stderr, "ERROR: initgroups() failed.\n");
@ -243,18 +227,14 @@ void clamd(struct optstruct *opt)
#endif
/* set the temporary dir */
if((cpt = cfgopt(copt, "TemporaryDirectory")))
if((cpt = cfgopt(copt, "TemporaryDirectory"))->enabled)
cl_settempdir(cpt->strarg, 0);
if(cfgopt(copt, "LeaveTemporaryFiles"))
if(cfgopt(copt, "LeaveTemporaryFiles")->enabled)
cl_settempdir(NULL, 1);
/* load the database(s) */
if((cpt = cfgopt(copt, "DatabaseDirectory")) || (cpt = cfgopt(copt, "DataDirectory")))
dbdir = cpt->strarg;
else
dbdir = cl_retdbdir();
dbdir = cfgopt(copt, "DatabaseDirectory")->strarg;
logg("Reading databases from %s\n", dbdir);
if((ret = cl_loaddbdir(dbdir, &root, &virnum))) {
@ -277,7 +257,7 @@ void clamd(struct optstruct *opt)
}
/* fork into background */
if(!cfgopt(copt, "Foreground"))
if(!cfgopt(copt, "Foreground")->enabled)
daemonize();
if(tcpsock)

@ -1,5 +1,5 @@
/*
* Copyright (C) 2002 - 2004 Tomasz Kojm <tkojm@clamav.net>
* Copyright (C) 2002 - 2005 Tomasz Kojm <tkojm@clamav.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -35,7 +35,6 @@
#include "cfgparser.h"
#include "dazukoio.h"
#include "clamuko.h"
#include "defaults.h"
#include "output.h"
struct dazuko_access *acc;
@ -92,15 +91,15 @@ void *clamukoth(void *arg)
logg("Clamuko: Correctly registered with Dazuko.\n");
/* access mask */
if(cfgopt(tharg->copt, "ClamukoScanOnOpen")) {
if(cfgopt(tharg->copt, "ClamukoScanOnOpen")->enabled) {
logg("Clamuko: Scan-on-open mode activated.\n");
mask |= DAZUKO_ON_OPEN;
}
if(cfgopt(tharg->copt, "ClamukoScanOnClose")) {
if(cfgopt(tharg->copt, "ClamukoScanOnClose")->enabled) {
logg("Clamuko: Scan-on-close mode activated.\n");
mask |= DAZUKO_ON_CLOSE;
}
if(cfgopt(tharg->copt, "ClamukoScanOnExec")) {
if(cfgopt(tharg->copt, "ClamukoScanOnExec")->enabled) {
logg("Clamuko: Scan-on-exec mode activated.\n");
mask |= DAZUKO_ON_EXEC;
}
@ -117,7 +116,7 @@ void *clamukoth(void *arg)
return NULL;
}
if((pt = cfgopt(tharg->copt, "ClamukoIncludePath"))) {
if((pt = cfgopt(tharg->copt, "ClamukoIncludePath"))->enabled) {
while(pt) {
if((dazukoAddIncludePath(pt->strarg))) {
logg("!Clamuko: Dazuko -> Can't include path %s\n", pt->strarg);
@ -134,7 +133,7 @@ void *clamukoth(void *arg)
return NULL;
}
if((pt = cfgopt(tharg->copt, "ClamukoExcludePath"))) {
if((pt = cfgopt(tharg->copt, "ClamukoExcludePath"))->enabled) {
while(pt) {
if((dazukoAddExcludePath(pt->strarg))) {
logg("!Clamuko: Dazuko -> Can't exclude path %s\n", pt->strarg);
@ -147,11 +146,7 @@ void *clamukoth(void *arg)
}
}
if((pt = cfgopt(tharg->copt, "ClamukoMaxFileSize"))) {
sizelimit = pt->numarg;
} else
sizelimit = CL_DEFAULT_CLAMUKOMAXFILESIZE;
sizelimit = cfgopt(tharg->copt, "ClamukoMaxFileSize")->numarg;
if(sizelimit)
logg("Clamuko: Max file size limited to %d bytes.\n", sizelimit);
else

@ -1,35 +0,0 @@
/*
* Copyright (C) 2002 Tomasz Kojm <zolw@konarski.edu.pl>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __DEFAULTS_H
#define __DEFAULTS_H
#define CL_DEFAULT_CFG CONFDIR"/clamd.conf"
#define CL_DEFAULT_BACKLOG 15
#define CL_DEFAULT_MAXTHREADS 10
#define CL_DEFAULT_SCANTIMEOUT 120
#define CL_DEFAULT_LOGSIZE 1048576
#define CL_DEFAULT_CLAMUKOMAXFILESIZE 5 * 1048576
#define CL_DEFAULT_SELFCHECK 1800
#define CL_DEFAULT_MAXWHILEWAIT 120
#define CL_DEFAULT_MAXPORTSCAN 1000
#define CL_DEFAULT_MAXDIRREC 15
#define CL_DEFAULT_STREAMMAXLEN 10 * 1048576
#define CL_DEFAULT_IDLETIMEOUT 30
#endif

@ -1,5 +1,5 @@
/*
* Copyright (C) 2002 - 2004 Tomasz Kojm <tkojm@clamav.net>
* Copyright (C) 2002 - 2005 Tomasz Kojm <tkojm@clamav.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -31,7 +31,6 @@
#include "options.h"
#include "cfgparser.h"
#include "defaults.h"
#include "others.h"
#include "server.h"
#include "output.h"
@ -64,7 +63,7 @@ int localserver(const struct optstruct *opt, const struct cfgstruct *copt, struc
logg("!Socket file %s is in use by another process.\n", server.sun_path);
exit(1);
}
if(cfgopt(copt, "FixStaleSocket")) {
if(cfgopt(copt, "FixStaleSocket")->enabled) {
logg("^Socket file %s exists. Unclean shutdown? Removing...\n", server.sun_path);
if(unlink(server.sun_path) == -1) {
estr = strerror(errno);
@ -89,11 +88,7 @@ int localserver(const struct optstruct *opt, const struct cfgstruct *copt, struc
logg("Unix socket file %s\n", server.sun_path);
if((cpt = cfgopt(copt, "MaxConnectionQueueLength")))
backlog = cpt->numarg;
else
backlog = CL_DEFAULT_BACKLOG;
backlog = cfgopt(copt, "MaxConnectionQueueLength")->numarg;
logg("Setting connection queue length to %d\n", backlog);
if(listen(sockfd, backlog) == -1) {

@ -77,7 +77,7 @@ void virusaction(const char *filename, const char *virname, const struct cfgstru
pid_t pid;
struct cfgstruct *cpt;
if(!(cpt = cfgopt(copt, "VirusEvent")))
if(!(cpt = cfgopt(copt, "VirusEvent"))->enabled)
return;
/* NB: we need to fork here since this function modifies the environment.

@ -45,7 +45,6 @@
#include "cfgparser.h"
#include "others.h"
#include "scanner.h"
#include "defaults.h"
#include "memory.h"
#include "shared.h"
#include "output.h"
@ -102,11 +101,7 @@ int dirscan(const char *dirname, const char **virname, unsigned long int *scanne
int ret = 0, scanret = 0, maxdirrec = 0;
if((cpt = cfgopt(copt, "MaxDirectoryRecursion")))
maxdirrec = cpt->numarg;
else
maxdirrec = CL_DEFAULT_MAXDIRREC;
maxdirrec = cfgopt(copt, "MaxDirectoryRecursion")->numarg;
if(maxdirrec) {
if(*reclev > maxdirrec) {
logg("*Directory recursion limit exceeded at %s\n", dirname);
@ -139,14 +134,14 @@ int dirscan(const char *dirname, const char **virname, unsigned long int *scanne
/* stat the file */
if(lstat(fname, &statbuf) != -1) {
if((S_ISDIR(statbuf.st_mode) && !S_ISLNK(statbuf.st_mode)) || (S_ISLNK(statbuf.st_mode) && (checksymlink(fname) == 1) && cfgopt(copt, "FollowDirectorySymlinks"))) {
if((S_ISDIR(statbuf.st_mode) && !S_ISLNK(statbuf.st_mode)) || (S_ISLNK(statbuf.st_mode) && (checksymlink(fname) == 1) && cfgopt(copt, "FollowDirectorySymlinks")->enabled)) {
if(dirscan(fname, virname, scanned, root, limits, options, copt, odesc, reclev, contscan) == 1) {
free(fname);
closedir(dd);
return 1;
}
} else {
if(S_ISREG(statbuf.st_mode) || (S_ISLNK(statbuf.st_mode) && (checksymlink(fname) == 2) && cfgopt(copt, "FollowFileSymlinks"))) {
if(S_ISREG(statbuf.st_mode) || (S_ISLNK(statbuf.st_mode) && (checksymlink(fname) == 2) && cfgopt(copt, "FollowFileSymlinks")->enabled)) {
#ifdef C_LINUX
if(procdev && (statbuf.st_dev == procdev))
@ -219,7 +214,7 @@ int scan(const char *filename, unsigned long int *scanned, const struct cl_node
switch(sb.st_mode & S_IFMT) {
case S_IFLNK:
if(!cfgopt(copt, "FollowFileSymlinks"))
if(!cfgopt(copt, "FollowFileSymlinks")->enabled)
break;
/* else go to the next case */
case S_IFREG:
@ -297,7 +292,7 @@ int scanfd(const int fd, unsigned long int *scanned, const struct cl_node *root,
int scanstream(int odesc, unsigned long int *scanned, const struct cl_node *root, const struct cl_limits *limits, int options, const struct cfgstruct *copt)
{
int ret, portscan = CL_DEFAULT_MAXPORTSCAN, sockfd, port = 0, acceptd;
int ret, portscan = 1000, sockfd, port = 0, acceptd;
int tmpd, bread, retval, timeout, btread, min_port, max_port;
long int size = 0, maxsize = 0;
short bound = 0, rnd_port_first = 1;
@ -310,22 +305,14 @@ int scanstream(int odesc, unsigned long int *scanned, const struct cl_node *root
/* get min port */
if((cpt = cfgopt(copt, "StreamMinPort"))) {
if(cpt->numarg < 1024 || cpt->numarg > 65535)
min_port = 1024;
else
min_port = cpt->numarg;
} else
min_port = cfgopt(copt, "StreamMinPort")->numarg;
if(min_port < 1024 || min_port > 65535)
min_port = 1024;
/* get max port */
if((cpt = cfgopt(copt, "StreamMaxPort"))) {
if(cpt->numarg < min_port || cpt->numarg > 65535)
max_port = 65535;
else
max_port = cpt->numarg;
} else
max_port = 2048;
max_port = cfgopt(copt, "StreamMaxPort")->numarg;
if(max_port < min_port || max_port > 65535)
max_port = 65535;
/* bind to a free port */
while(!bound && --portscan) {
@ -343,7 +330,7 @@ int scanstream(int odesc, unsigned long int *scanned, const struct cl_node *root
server.sin_family = AF_INET;
server.sin_port = htons(port);
if((cpt = cfgopt(copt, "TCPAddr"))) {
if((cpt = cfgopt(copt, "TCPAddr"))->enabled) {
pthread_mutex_lock(&gh_mutex);
if((he = gethostbyname(cpt->strarg)) == 0) {
logg("!gethostbyname(%s) error: %s\n", cpt->strarg);
@ -365,11 +352,7 @@ int scanstream(int odesc, unsigned long int *scanned, const struct cl_node *root
bound = 1;
}
if((cpt = cfgopt(copt, "ReadTimeout")))
timeout = cpt->numarg;
else
timeout = CL_DEFAULT_SCANTIMEOUT;
timeout = cfgopt(copt, "ReadTimeout")->numarg;
if(timeout == 0)
timeout = -1;
@ -418,11 +401,7 @@ int scanstream(int odesc, unsigned long int *scanned, const struct cl_node *root
return -1;
}
if((cpt = cfgopt(copt, "StreamMaxLength")))
maxsize = cpt->numarg;
else
maxsize = CL_DEFAULT_STREAMMAXLEN;
maxsize = cfgopt(copt, "StreamMaxLength")->numarg;
btread = sizeof(buff);
@ -439,7 +418,7 @@ int scanstream(int odesc, unsigned long int *scanned, const struct cl_node *root
mdprintf(odesc, "Temporary file -> write ERROR\n");
logg("!ScanStream %d: Can't write to temporary file.\n", port);
close(tmpd);
if(!cfgopt(copt, "LeaveTemporaryFiles"))
if(!cfgopt(copt, "LeaveTemporaryFiles")->enabled)
unlink(tmpname);
free(tmpname);
return -1;
@ -469,7 +448,7 @@ int scanstream(int odesc, unsigned long int *scanned, const struct cl_node *root
lseek(tmpd, 0, SEEK_SET);
ret = cl_scandesc(tmpd, &virname, scanned, root, limits, options);
close(tmpd);
if(!cfgopt(copt, "LeaveTemporaryFiles"))
if(!cfgopt(copt, "LeaveTemporaryFiles")->enabled)
unlink(tmpname);
free(tmpname);

@ -1,5 +1,5 @@
/*
* Copyright (C) 2002 - 2004 Tomasz Kojm <tkojm@clamav.net>
* Copyright (C) 2002 - 2005 Tomasz Kojm <tkojm@clamav.net>
* Trog <trog@clamav.net>
*
* This program is free software; you can redistribute it and/or modify
@ -35,7 +35,6 @@
#include "server.h"
#include "thrmgr.h"
#include "session.h"
#include "defaults.h"
#include "clamuko.h"
#include "others.h"
#include "memory.h"
@ -75,12 +74,7 @@ void scanner_thread(void *arg)
sigfillset(&sigset);
pthread_sigmask(SIG_SETMASK, &sigset, NULL);
if((cpt = cfgopt(conn->copt, "ReadTimeout"))) {
timeout = cpt->numarg;
} else {
timeout = CL_DEFAULT_SCANTIMEOUT;
}
timeout = cfgopt(conn->copt, "ReadTimeout")->numarg;
if(!timeout)
timeout = -1;
@ -188,11 +182,7 @@ static struct cl_node *reload_db(struct cl_node *root, const struct cfgstruct *c
root = NULL;
}
if((cpt = cfgopt(copt, "DatabaseDirectory")) || (cpt = cfgopt(copt, "DataDirectory"))) {
dbdir = cpt->strarg;
} else {
dbdir = cl_retdbdir();
}
dbdir = cfgopt(copt, "DatabaseDirectory")->strarg;
logg("Reading databases from %s\n", dbdir);
if(dbstat == NULL) {
@ -225,7 +215,7 @@ static struct cl_node *reload_db(struct cl_node *root, const struct cfgstruct *c
int acceptloop_th(int socketd, struct cl_node *root, const struct cfgstruct *copt)
{
int new_sd, max_threads, stdopt;
int new_sd, max_threads;
unsigned int options = 0;
threadpool_t *thr_pool;
struct sigaction sigact;
@ -256,7 +246,7 @@ int acceptloop_th(int socketd, struct cl_node *root, const struct cfgstruct *cop
/* save the PID */
mainpid = getpid();
if((cpt = cfgopt(copt, "PidFile"))) {
if((cpt = cfgopt(copt, "PidFile"))->enabled) {
FILE *fd;
old_umask = umask(0006);
if((fd = fopen(cpt->strarg, "w")) == NULL) {
@ -269,95 +259,55 @@ int acceptloop_th(int socketd, struct cl_node *root, const struct cfgstruct *cop
}
logg("*Listening daemon: PID: %d\n", getpid());
if((cpt = cfgopt(copt, "MaxThreads"))) {
max_threads = cpt->numarg;
} else {
max_threads = CL_DEFAULT_MAXTHREADS;
}
max_threads = cfgopt(copt, "MaxThreads")->numarg;
if(cfgopt(copt, "DisableDefaultScanOptions")) {
logg("RECOMMENDED OPTIONS DISABLED.\n");
stdopt = 0;
} else {
options |= CL_SCAN_STDOPT;
stdopt = 1;
}
if(stdopt || cfgopt(copt, "ScanArchive") || cfgopt(copt, "ClamukoScanArchive")) {
if(cfgopt(copt, "ScanArchive")->enabled || cfgopt(copt, "ClamukoScanArchive")->enabled) {
/* set up limits */
memset(&limits, 0, sizeof(struct cl_limits));
if((cpt = cfgopt(copt, "ArchiveMaxFileSize"))) {
if((limits.maxfilesize = cpt->numarg)) {
logg("Archive: Archived file size limit set to %d bytes.\n", limits.maxfilesize);
} else {
logg("^Archive: File size limit protection disabled.\n");
}
} else {
limits.maxfilesize = 10485760;
if((limits.maxfilesize = cfgopt(copt, "ArchiveMaxFileSize")->numarg)) {
logg("Archive: Archived file size limit set to %d bytes.\n", limits.maxfilesize);
} else {
logg("^Archive: File size limit protection disabled.\n");
}
if((cpt = cfgopt(copt, "ArchiveMaxRecursion"))) {
if((limits.maxreclevel = cpt->numarg)) {
logg("Archive: Recursion level limit set to %d.\n", limits.maxreclevel);
} else {
logg("^Archive: Recursion level limit protection disabled.\n");
}
} else {
limits.maxreclevel = 8;
if((limits.maxreclevel = cfgopt(copt, "ArchiveMaxRecursion")->numarg)) {
logg("Archive: Recursion level limit set to %d.\n", limits.maxreclevel);
} else {
logg("^Archive: Recursion level limit protection disabled.\n");
}
if((cpt = cfgopt(copt, "ArchiveMaxFiles"))) {
if((limits.maxfiles = cpt->numarg)) {
logg("Archive: Files limit set to %d.\n", limits.maxfiles);
} else {
logg("^Archive: Files limit protection disabled.\n");
}
} else {
limits.maxfiles = 1000;
if((limits.maxfiles = cfgopt(copt, "ArchiveMaxFiles")->numarg)) {
logg("Archive: Files limit set to %d.\n", limits.maxfiles);
} else {
logg("^Archive: Files limit protection disabled.\n");
}
if((cpt = cfgopt(copt, "ArchiveMaxCompressionRatio"))) {
if((limits.maxratio = cpt->numarg)) {
logg("Archive: Compression ratio limit set to %d.\n", limits.maxratio);
} else {
logg("^Archive: Compression ratio limit disabled.\n");
}
} else {
limits.maxratio = 250;
if((limits.maxratio = cfgopt(copt, "ArchiveMaxCompressionRatio")->numarg)) {
logg("Archive: Compression ratio limit set to %d.\n", limits.maxratio);
} else {
logg("^Archive: Compression ratio limit disabled.\n");
}
if(cfgopt(copt, "ArchiveLimitMemoryUsage")) {
if(cfgopt(copt, "ArchiveLimitMemoryUsage")->enabled) {
limits.archivememlim = 1;
logg("Archive: Limited memory usage.\n");
} else {
limits.archivememlim = 0;
}
}
if(stdopt || cfgopt(copt, "ScanArchive")) {
if(cfgopt(copt, "ScanArchive")->enabled) {
logg("Archive support enabled.\n");
options |= CL_SCAN_ARCHIVE;
if(cfgopt(copt, "ScanRAR")) {
logg("Archive: RAR support enabled.\n");
} else {
logg("Archive: RAR support disabled.\n");
options |= CL_SCAN_DISABLERAR;
}
if(cfgopt(copt, "ArchiveBlockEncrypted")) {
if(cfgopt(copt, "ArchiveBlockEncrypted")->enabled) {
logg("Archive: Blocking encrypted archives.\n");
options |= CL_SCAN_BLOCKENCRYPTED;
}
if(cfgopt(copt, "ArchiveBlockMax")) {
if(cfgopt(copt, "ArchiveBlockMax")->enabled) {
logg("Archive: Blocking archives that exceed limits.\n");
options |= CL_SCAN_BLOCKMAX;
}
@ -366,11 +316,11 @@ int acceptloop_th(int socketd, struct cl_node *root, const struct cfgstruct *cop
logg("Archive support disabled.\n");
}
if(stdopt || cfgopt(copt, "ScanPE")) {
if(cfgopt(copt, "ScanPE")->enabled) {
logg("Portable Executable support enabled.\n");
options |= CL_SCAN_PE;
if(cfgopt(copt, "DetectBrokenExecutables")) {
if(cfgopt(copt, "DetectBrokenExecutables")->enabled) {
logg("Detection of broken executables enabled.\n");
options |= CL_SCAN_BLOCKBROKEN;
}
@ -379,11 +329,11 @@ int acceptloop_th(int socketd, struct cl_node *root, const struct cfgstruct *cop
logg("Portable Executable support disabled.\n");
}
if(stdopt || cfgopt(copt, "ScanMail")) {
if(cfgopt(copt, "ScanMail")->enabled) {
logg("Mail files support enabled.\n");
options |= CL_SCAN_MAIL;
if(cfgopt(copt, "MailFollowURLs")) {
if(cfgopt(copt, "MailFollowURLs")->enabled) {
logg("Mail: URL scanning enabled.\n");
options |= CL_SCAN_MAILURL;
}
@ -392,26 +342,21 @@ int acceptloop_th(int socketd, struct cl_node *root, const struct cfgstruct *cop
logg("Mail files support disabled.\n");
}
if(stdopt || cfgopt(copt, "ScanOLE2")) {
if(cfgopt(copt, "ScanOLE2")->enabled) {
logg("OLE2 support enabled.\n");
options |= CL_SCAN_OLE2;
} else {
logg("OLE2 support disabled.\n");
}
if(stdopt || cfgopt(copt, "ScanHTML")) {
if(cfgopt(copt, "ScanHTML")->enabled) {
logg("HTML support enabled.\n");
options |= CL_SCAN_HTML;
} else {
logg("HTML support disabled.\n");
}
if((cpt = cfgopt(copt, "SelfCheck"))) {
selfchk = cpt->numarg;
} else {
selfchk = CL_DEFAULT_SELFCHECK;
}
selfchk = cfgopt(copt, "SelfCheck")->numarg;
if(!selfchk) {
logg("Self checking disabled.\n");
} else {
@ -421,7 +366,7 @@ int acceptloop_th(int socketd, struct cl_node *root, const struct cfgstruct *cop
pthread_attr_init(&thattr);
pthread_attr_setdetachstate(&thattr, PTHREAD_CREATE_DETACHED);
if(cfgopt(copt, "ClamukoScanOnLine") || cfgopt(copt, "ClamukoScanOnAccess"))
if(cfgopt(copt, "ClamukoScanOnAccess")->enabled)
#ifdef CLAMUKO
{
pthread_attr_init(&clamuko_attr);
@ -483,11 +428,7 @@ int acceptloop_th(int socketd, struct cl_node *root, const struct cfgstruct *cop
pthread_mutex_init(&exit_mutex, NULL);
pthread_mutex_init(&reload_mutex, NULL);
if((cpt = cfgopt(copt, "IdleTimeout")))
idletimeout = cpt->numarg;
else
idletimeout = CL_DEFAULT_IDLETIMEOUT;
idletimeout = cfgopt(copt, "IdleTimeout")->numarg;
if((thr_pool=thrmgr_new(max_threads, idletimeout, scanner_thread)) == NULL) {
logg("!thrmgr_new failed\n");
@ -512,7 +453,7 @@ int acceptloop_th(int socketd, struct cl_node *root, const struct cfgstruct *cop
logg("SIGHUP caught: re-opening log file.\n");
logg_close();
sighup = 0;
if(!logg_file && (cpt = cfgopt(copt, "LogFile")))
if(!logg_file && (cpt = cfgopt(copt, "LogFile"))->enabled)
logg_file = cpt->strarg;
}
@ -563,7 +504,7 @@ int acceptloop_th(int socketd, struct cl_node *root, const struct cfgstruct *cop
time(&reloaded_time);
pthread_mutex_unlock(&reload_mutex);
#ifdef CLAMUKO
if(cfgopt(copt, "ClamukoScanOnLine") || cfgopt(copt, "ClamukoScanOnAccess")) {
if(cfgopt(copt, "ClamukoScanOnAccess")->enabled) {
logg("Stopping and restarting Clamuko.\n");
pthread_kill(clamuko_pid, SIGUSR1);
pthread_join(clamuko_pid, NULL);
@ -581,7 +522,7 @@ int acceptloop_th(int socketd, struct cl_node *root, const struct cfgstruct *cop
*/
thrmgr_destroy(thr_pool);
#ifdef CLAMUKO
if(cfgopt(copt, "ClamukoScanOnLine") || cfgopt(copt, "ClamukoScanOnAccess")) {
if(cfgopt(copt, "ClamukoScanOnAccess")->enabled) {
logg("Stopping Clamuko.\n");
pthread_kill(clamuko_pid, SIGUSR1);
pthread_join(clamuko_pid, NULL);
@ -594,7 +535,7 @@ int acceptloop_th(int socketd, struct cl_node *root, const struct cfgstruct *cop
close(socketd);
#ifndef C_OS2
if((cpt = cfgopt(copt, "LocalSocket"))) {
if((cpt = cfgopt(copt, "LocalSocket"))->enabled) {
if(unlink(cpt->strarg) == -1)
logg("!Can't unlink the socket file %s\n", cpt->strarg);
else
@ -602,7 +543,7 @@ int acceptloop_th(int socketd, struct cl_node *root, const struct cfgstruct *cop
}
#endif
if((cpt = cfgopt(copt, "PidFile"))) {
if((cpt = cfgopt(copt, "PidFile"))->enabled) {
if(unlink(cpt->strarg) == -1)
logg("!Can't unlink the pid file %s\n", cpt->strarg);
else

@ -34,7 +34,6 @@
#include "cfgparser.h"
#include "others.h"
#include "defaults.h"
#include "scanner.h"
#include "server.h"
#include "clamuko.h"
@ -82,13 +81,13 @@ int command(int desc, const struct cl_node *root, const struct cl_limits *limits
if(!strncmp(buff, CMD1, strlen(CMD1))) { /* SCAN */
if(scan(buff + strlen(CMD1) + 1, NULL, root, limits, options, copt, desc, 0) == -2)
if(cfgopt(copt, "ExitOnOOM"))
if(cfgopt(copt, "ExitOnOOM")->enabled)
return COMMAND_SHUTDOWN;
} else if(!strncmp(buff, CMD2, strlen(CMD2))) { /* RAWSCAN */
opt = options & ~CL_SCAN_ARCHIVE;
if(scan(buff + strlen(CMD2) + 1, NULL, root, NULL, opt, copt, desc, 0) == -2)
if(cfgopt(copt, "ExitOnOOM"))
if(cfgopt(copt, "ExitOnOOM")->enabled)
return COMMAND_SHUTDOWN;
} else if(!strncmp(buff, CMD3, strlen(CMD3))) { /* QUIT */
@ -103,19 +102,14 @@ int command(int desc, const struct cl_node *root, const struct cl_limits *limits
} else if(!strncmp(buff, CMD6, strlen(CMD6))) { /* CONTSCAN */
if(scan(buff + strlen(CMD6) + 1, NULL, root, limits, options, copt, desc, 1) == -2)
if(cfgopt(copt, "ExitOnOOM"))
if(cfgopt(copt, "ExitOnOOM")->enabled)
return COMMAND_SHUTDOWN;
} else if(!strncmp(buff, CMD7, strlen(CMD7))) { /* VERSION */
const char *dbdir;
const char *dbdir = cfgopt(copt, "DatabaseDirectory")->strarg;
char *path;
struct cl_cvd *daily;
if((cpt = cfgopt(copt, "DatabaseDirectory")) || (cpt = cfgopt(copt, "DataDirectory")))
dbdir = cpt->strarg;
else
dbdir = cl_retdbdir();
if(!(path = mmalloc(strlen(dbdir) + 11))) {
mdprintf(desc, "Memory allocation error - SHUTDOWN forced\n");
return COMMAND_SHUTDOWN;
@ -138,7 +132,7 @@ int command(int desc, const struct cl_node *root, const struct cl_limits *limits
} else if(!strncmp(buff, CMD8, strlen(CMD8))) { /* STREAM */
if(scanstream(desc, NULL, root, limits, options, copt) == CL_EMEM)
if(cfgopt(copt, "ExitOnOOM"))
if(cfgopt(copt, "ExitOnOOM")->enabled)
return COMMAND_SHUTDOWN;
} else if(!strncmp(buff, CMD9, strlen(CMD9))) { /* SESSION */

@ -1,5 +1,5 @@
/*
* Copyright (C) 2002 Tomasz Kojm <zolw@konarski.edu.pl>
* Copyright (C) 2002 - 2005 Tomasz Kojm <tkojm@clamav.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -30,10 +30,8 @@
#include <errno.h>
#include <netdb.h>
#include "options.h"
#include "cfgparser.h"
#include "defaults.h"
#include "others.h"
#include "server.h"
#include "output.h"
@ -52,8 +50,7 @@ int tcpserver(const struct optstruct *opt, const struct cfgstruct *copt, struct
server.sin_family = AF_INET;
server.sin_port = htons(cfgopt(copt, "TCPSocket")->numarg);
if((taddr = cfgopt(copt, "TCPAddr"))) {
if((taddr = cfgopt(copt, "TCPAddr"))->enabled) {
if ((he = gethostbyname(taddr->strarg)) == 0) {
logg("!gethostbyname(%s) error: %s\n", taddr->strarg, strerror(errno));
exit(1);
@ -65,9 +62,6 @@ int tcpserver(const struct optstruct *opt, const struct cfgstruct *copt, struct
if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
estr = strerror(errno);
/*
fprintf(stderr, "ERROR: socket() error: %s\n", estr);
*/
logg("!socket() error: %s\n", estr);
exit(1);
}
@ -78,38 +72,25 @@ int tcpserver(const struct optstruct *opt, const struct cfgstruct *copt, struct
if(bind(sockfd, (struct sockaddr *) &server, sizeof(struct sockaddr_in)) == -1) {
estr = strerror(errno);
/*
fprintf(stderr, "ERROR: can't bind(): %s\n", estr);
*/
logg("!bind() error: %s\n", estr);
exit(1);
} else {
if ( taddr != NULL && *taddr->strarg )
if(taddr->enabled)
logg("Bound to address %s on port %d\n", taddr->strarg, cfgopt(copt, "TCPSocket")->numarg);
else
logg("Bound to port %d\n", cfgopt(copt, "TCPSocket")->numarg);
}
if((cpt = cfgopt(copt, "MaxConnectionQueueLength")))
backlog = cpt->numarg;
else
backlog = CL_DEFAULT_BACKLOG;
backlog = cfgopt(copt, "MaxConnectionQueueLength")->numarg;
logg("Setting connection queue length to %d\n", backlog);
if(listen(sockfd, backlog) == -1) {
estr = strerror(errno);
/*
fprintf(stderr, "ERROR: listen() error: %s\n", estr);
*/
logg("!listen() error: %s\n", estr);
exit(1);
}
/* if(cfgopt(copt, "UseProcesses"))
acceptloop_proc(sockfd, root, copt);
else */
acceptloop_th(sockfd, root, copt);
acceptloop_th(sockfd, root, copt);
return 0;
}

@ -318,7 +318,7 @@ int dconnect(const struct optstruct *opt)
if(!clamav_conf)
clamav_conf = DEFAULT_CFG;
if((copt = parsecfg(clamav_conf, 1)) == NULL) {
if((copt = getcfg(clamav_conf, 1)) == NULL) {
mprintf("@Can't parse the configuration file.\n");
return -1;
}
@ -329,10 +329,10 @@ int dconnect(const struct optstruct *opt)
/* Set default address to connect to */
server2.sin_addr.s_addr = inet_addr("127.0.0.1");
if(cfgopt(copt, "TCPSocket") && cfgopt(copt, "LocalSocket")) {
if(cfgopt(copt, "TCPSocket")->enabled && cfgopt(copt, "LocalSocket")->enabled) {
mprintf("@Clamd is not configured properly.\n");
return -1;
} else if((cpt = cfgopt(copt, "LocalSocket"))) {
} else if((cpt = cfgopt(copt, "LocalSocket"))->enabled) {
server.sun_family = AF_UNIX;
strncpy(server.sun_path, cpt->strarg, sizeof(server.sun_path));
@ -350,7 +350,7 @@ int dconnect(const struct optstruct *opt)
return -1;
}
} else if((cpt = cfgopt(copt, "TCPSocket"))) {
} else if((cpt = cfgopt(copt, "TCPSocket"))->enabled) {
if((sockd = socket(SOCKET_INET, SOCK_STREAM, 0)) < 0) {
perror("socket()");
@ -361,7 +361,7 @@ int dconnect(const struct optstruct *opt)
server2.sin_family = AF_INET;
server2.sin_port = htons(cpt->numarg);
if((cpt = cfgopt(copt, "TCPAddr"))) {
if((cpt = cfgopt(copt, "TCPAddr"))->enabled) {
if ((he = gethostbyname(cpt->strarg)) == 0) {
close(sockd);
perror("gethostbyname()");

@ -1,5 +1,5 @@
##
## Example config file for the Clam AV daemon
## Example config file for the Clam AV daemyes
## Please read the clamd.conf(5) manual before editing this file.
##
@ -18,8 +18,8 @@ Example
# copy the configuration file, change the LogFile variable, and run
# the daemon with --config-file option).
# This option disables log file locking.
# Default: disabled
#LogFileUnlock
# Default: no
#LogFileUnlock yes
# Maximal size of the log file.
# Value of 0 disables the limit.
@ -30,17 +30,17 @@ Example
#LogFileMaxSize 2M
# Log time with each message.
# Default: disabled
#LogTime
# Default: no
#LogTime yes
# Also log clean files. Useful in debugging but drastically increases the
# log size.
# Default: disabled
#LogClean
# Default: no
#LogClean yes
# Use system logger (can work together with LogFile).
# Default: disabled
#LogSyslog
# Default: no
#LogSyslog yes
# Specify the type of syslog messages - please refer to 'man syslog'
# for facility names.
@ -48,8 +48,8 @@ Example
#LogFacility LOG_MAIL
# Enable verbose logging.
# Default: disabled
#LogVerbose
# Default: no
#LogVerbose yes
# This option allows you to save a process identifier of the listening
# daemon (main thread).
@ -68,22 +68,22 @@ Example
# recommend the local mode.
# Path to a local socket file the daemon will listen on.
# Default: disabled
# Default: disabled (must be specified by a user)
LocalSocket /tmp/clamd
# Remove stale socket after unclean shutdown.
# Default: disabled
FixStaleSocket
# Default: no
#FixStaleSocket yes
# TCP port address.
# Default: disabled
# Default: no
#TCPSocket 3310
# TCP address.
# By default we bind to INADDR_ANY, probably not wise.
# Enable the following to provide some degree of protection
# Enable the following to provide some degree of protectiyes
# from the outside world.
# Default: disabled
# Default: no
#TCPAddr 127.0.0.1
# Maximum length the queue of pending connections may grow to.
@ -123,12 +123,12 @@ FixStaleSocket
#MaxDirectoryRecursion 20
# Follow directory symlinks.
# Default: disabled
#FollowDirectorySymlinks
# Default: no
#FollowDirectorySymlinks yes
# Follow regular file symlinks.
# Default: disabled
#FollowFileSymlinks
# Default: no
#FollowFileSymlinks yes
# Perform internal sanity check (database integrity and freshness).
# Default: 1800 (30 min)
@ -136,38 +136,31 @@ FixStaleSocket
# Execute a command when virus is found. In the command string %v will
# be replaced by a virus name.
# Default: disabled
# Default: no
#VirusEvent /usr/local/bin/send_sms 123456789 "VIRUS ALERT: %v"
# Run as a selected user (clamd must be started by root).
# Default: disabled
# Default: don't drop privileges
#User clamav
# Initialize supplementary group access (clamd must be started by root).
# Default: disabled
#AllowSupplementaryGroups
# Default: no
#AllowSupplementaryGroups no
# Stop daemon when libclamav reports out of memory condition.
#ExitOnOOM
#ExitOnOOM yes
# Don't fork into background.
# Default: disabled
#Foreground
# Default: no
#Foreground yes
# Enable debug messages in libclamav.
# Default: disabled
#Debug
# Default: no
#Debug yes
# Do not remove temporary files (for debug purposes).
# Default: disabled
#LeaveTemporaryFiles
# By default clamd uses scan options recommended by libclamav. This option
# disables recommended options and allows you to enable selected ones below.
# DO NOT TOUCH IT unless you know what you are doing.
# Default: disabled
#DisableDefaultScanOptions
# Default: no
#LeaveTemporaryFiles yes
##
## Executable files
@ -178,13 +171,13 @@ FixStaleSocket
# ClamAV to perform a deeper analysis of executable files and it's also
# required for decompression of popular executable packers such as UPX, FSG,
# and Petite.
# Default: enabled
#ScanPE
# Default: yes
#ScanPE yes
# With this option clamav will try to detect broken executables and mark
# them as Broken.Executable
# Default: disabled
#DetectBrokenExecutables
# Default: no
#DetectBrokenExecutables yes
##
@ -192,22 +185,22 @@ FixStaleSocket
##
# This option enables scanning of Microsoft Office document macros.
# Default: enabled
#ScanOLE2
# Default: yes
#ScanOLE2 yes
##
## Mail files
##
# Enable internal e-mail scanner.
# Default: enabled
#ScanMail
# Default: yes
#ScanMail yes
# If an email contains URLs ClamAV can download and scan them.
# WARNING: This option may open your system to a DoS attack.
# Never use it on loaded servers.
# Default: disabled
#MailFollowURLs
# Default: no
#MailFollowURLs no
##
@ -215,8 +208,8 @@ FixStaleSocket
##
# Perform HTML normalisation and decryption of MS Script Encoder code.
# Default: enabled
#ScanHTML
# Default: yes
#ScanHTML yes
##
@ -224,15 +217,8 @@ FixStaleSocket
##
# ClamAV can scan within archives and compressed files.
# Default: enabled
#ScanArchive
# Due to license issues libclamav does not support RAR 3.0 archives (only the
# old 2.0 format is supported). Because some users report stability problems
# with unrarlib it's disabled by default and you must uncomment the directive
# below to enable RAR 2.0 support.
# Default: disabled
#ScanRAR
# Default: yes
#ScanArchive yes
# The options below protect your system against Denial of Service attacks
# using archive bombs.
@ -247,7 +233,7 @@ FixStaleSocket
# deep the process should be continued.
# Value of 0 disables the limit.
# Default: 8
#ArchiveMaxRecursion 9
#ArchiveMaxRecursion 10
# Number of files to be scanned within an archive.
# Value of 0 disables the limit.
@ -262,18 +248,18 @@ FixStaleSocket
# Use slower but memory efficient decompression algorithm.
# only affects the bzip2 decompressor.
# Default: disabled
#ArchiveLimitMemoryUsage
# Default: no
#ArchiveLimitMemoryUsage yes
# Mark encrypted archives as viruses (Encrypted.Zip, Encrypted.RAR).
# Default: disabled
#ArchiveBlockEncrypted
# Default: no
#ArchiveBlockEncrypted no
# Mark archives as viruses (e.g. RAR.ExceededFileSize, Zip.ExceededFilesLimit)
# if ArchiveMaxFiles, ArchiveMaxFileSize, or ArchiveMaxRecursion limit is
# reached.
# Default: disabled
#ArchiveBlockMax
# Default: no
#ArchiveBlockMax no
##
@ -283,14 +269,14 @@ FixStaleSocket
##
# Enable Clamuko. Dazuko (/dev/dazuko) must be configured and running.
# Default: disabled
#ClamukoScanOnAccess
# Default: no
#ClamukoScanOnAccess yes
# Set access mask for Clamuko.
# Default: disabled
#ClamukoScanOnOpen
#ClamukoScanOnClose
#ClamukoScanOnExec
# Default: no
#ClamukoScanOnOpen yes
#ClamukoScanOnClose yes
#ClamukoScanOnExec yes
# Set the include paths (all files in them will be scanned). You can have
# multiple ClamukoIncludePath directives but each directory must be added
@ -301,7 +287,7 @@ FixStaleSocket
# Set the exclude paths. All subdirectories are also excluded.
# Default: disabled
#ClamukoExcludePath /home/guru
#ClamukoExcludePath /home/bofh
# Don't scan files larger than ClamukoMaxFileSize
# Value of 0 disables the limit.

@ -18,19 +18,19 @@ Example
#UpdateLogFile /var/log/freshclam.log
# Enable verbose logging.
# Default: disabled
#LogVerbose
# Default: no
#LogVerbose yes
# Use system logger (can work together with UpdateLogFile).
# Default: disabled
#LogSyslog
# Default: no
#LogSyslog yes
# Specify the type of syslog messages - please refer to 'man syslog'
# for facility names.
# Default: LOG_LOCAL6
#LogFacility LOG_MAIL
# This option allows you to save the process identifier of the daemon
# This option allows you to save the process identifier of the daemyes
# Default: disabled
#PidFile /var/run/freshclam.pid
@ -40,18 +40,19 @@ Example
#DatabaseOwner clamav
# Initialize supplementary group access (freshclam must be started by root).
# Default: disabled
#AllowSupplementaryGroups
# Default: no
#AllowSupplementaryGroups yes
# Use DNS to verify virus database version. Freshclam uses DNS TXT records
# to verify database and software versions. With this directive you can change
# the database verification domain.
# Default: enabled, pointing to current.cvd.clamav.net
# WARNING: Do not touch it unless you're configuring freshclam to use your
# own database verification domain.
# Default: current.cvd.clamav.net
#DNSDatabaseInfo current.cvd.clamav.net
# Uncomment the following line and replace XY with your country
# code. See http://www.iana.org/cctld/cctld-whois.htm for the full list.
# Default: There is no default, which results in an error when running freshclam
#DatabaseMirror db.XY.clamav.net
# database.clamav.net is a round-robin record which points to our most
@ -81,11 +82,8 @@ DatabaseMirror database.clamav.net
#LocalIPAddress aaa.bbb.ccc.ddd
# Send the RELOAD command to clamd.
# Default: disabled
#NotifyClamd
# By default it uses the hardcoded configuration file but you can force an
# another one.
#NotifyClamd /config/file/path
# Default: no
#NotifyClamd /path/to/clamd.conf
# Run command after successful database update.
# Default: disabled
@ -96,9 +94,9 @@ DatabaseMirror database.clamav.net
#OnErrorExecute command
# Don't fork into background.
# Default: disabled
#Foreground
# Default: no
#Foreground yes
# Enable debug messages in libclamav.
# Default: disabled
#Debug
# Default: no
#Debug yes

@ -1,5 +1,5 @@
/*
* Copyright (C) 2002 Tomasz Kojm <zolw@konarski.edu.pl>
* Copyright (C) 2002 - 2005 Tomasz Kojm <tkojm@clamav.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -36,6 +36,4 @@
#define UNPGROUP "clamav"
#endif
#define CL_DEFAULT_CHECKS 12
#define CL_DEFAULT_MAXATTEMPTS 3
#define CL_MAX_CHILDREN 5

@ -112,11 +112,11 @@ int freshclam(struct optstruct *opt)
/* parse the config file */
if((cfgfile = getargl(opt, "config-file"))) {
copt = parsecfg(cfgfile, 1);
copt = getcfg(cfgfile, 1);
} else {
/* TODO: force strict permissions on freshclam.conf */
if((copt = parsecfg((cfgfile = CONFDIR"/freshclam.conf"), 1)) == NULL)
copt = parsecfg((cfgfile = CONFDIR"/clamd.conf"), 1);
if((copt = getcfg((cfgfile = CONFDIR"/freshclam.conf"), 1)) == NULL)
copt = getcfg((cfgfile = CONFDIR"/clamd.conf"), 1);
}
if(!copt) {
@ -127,7 +127,7 @@ int freshclam(struct optstruct *opt)
if(optl(opt, "http-proxy") || optl(opt, "proxy-user"))
mprintf("WARNING: Proxy settings are now only configurable in the config file.\n");
if(cfgopt(copt, "HTTPProxyPassword")) {
if(cfgopt(copt, "HTTPProxyPassword")->enabled) {
if(stat(cfgfile, &statbuf) == -1) {
mprintf("@Can't stat %s (critical error)\n", cfgfile);
return 56;
@ -144,7 +144,7 @@ int freshclam(struct optstruct *opt)
/* freshclam shouldn't work with root privileges */
if(optc(opt, 'u')) {
unpuser = getargc(opt, 'u');
} else if((cpt = cfgopt(copt, "DatabaseOwner"))) {
} else if((cpt = cfgopt(copt, "DatabaseOwner"))->enabled) {
unpuser = cpt->strarg;
} else {
unpuser = UNPUSER;
@ -156,7 +156,7 @@ int freshclam(struct optstruct *opt)
exit(60); /* this is critical problem, so we just exit here */
}
if(cfgopt(copt, "AllowSupplementaryGroups")) {
if(cfgopt(copt, "AllowSupplementaryGroups")->enabled) {
#ifdef HAVE_INITGROUPS
if(initgroups(unpuser, user->pw_gid)) {
mprintf("@initgroups() failed.\n");
@ -186,7 +186,7 @@ int freshclam(struct optstruct *opt)
/* initialize some important variables */
if(optl(opt, "debug") || cfgopt(copt, "Debug"))
if(optl(opt, "debug") || cfgopt(copt, "Debug")->enabled)
cl_debug();
if(optc(opt, 'v'))
@ -205,7 +205,7 @@ int freshclam(struct optstruct *opt)
/* initialize logger */
if(cfgopt(copt, "LogVerbose"))
if(cfgopt(copt, "LogVerbose")->enabled)
logg_verbose = 1;
if(optc(opt, 'l')) {
@ -214,7 +214,7 @@ int freshclam(struct optstruct *opt)
mprintf("!Problem with internal logger.\n");
exit(62);
}
} else if((cpt = cfgopt(copt, "UpdateLogFile"))) {
} else if((cpt = cfgopt(copt, "UpdateLogFile"))->enabled) {
logg_file = cpt->strarg;
if(logg("--------------------------------------\n")) {
mprintf("!Problem with internal logger.\n");
@ -224,10 +224,10 @@ int freshclam(struct optstruct *opt)
logg_file = NULL;
#if defined(USE_SYSLOG) && !defined(C_AIX)
if(cfgopt(copt, "LogSyslog")) {
if(cfgopt(copt, "LogSyslog")->enabled) {
int fac = LOG_LOCAL6;
if((cpt = cfgopt(copt, "LogFacility"))) {
if((cpt = cfgopt(copt, "LogFacility"))->enabled) {
if((fac = logg_facility(cpt->strarg)) == -1) {
mprintf("!LogFacility: %s: No such facility.\n", cpt->strarg);
exit(62);
@ -241,14 +241,10 @@ int freshclam(struct optstruct *opt)
#endif
/* change the current working directory */
if(optl(opt, "datadir")) {
if(optl(opt, "datadir"))
newdir = getargl(opt, "datadir");
} else {
if((cpt = cfgopt(copt, "DatabaseDirectory")))
newdir = cpt->strarg;
else
newdir = VIRUSDBDIR;
}
else
newdir = cfgopt(copt, "DatabaseDirectory")->strarg;
if(chdir(newdir)) {
mprintf("Can't change dir to %s\n", newdir);
@ -264,20 +260,17 @@ int freshclam(struct optstruct *opt)
memset(&sigact, 0, sizeof(struct sigaction));
sigact.sa_handler = daemon_sighandler;
if(optc(opt, 'c')) {
if(optc(opt, 'c'))
checks = atoi(getargc(opt, 'c'));
} else if((cpt = cfgopt(copt, "Checks"))) {
checks = cpt->numarg;
} else {
checks = CL_DEFAULT_CHECKS;
}
else
checks = cfgopt(copt, "Checks")->numarg;
if(checks <= 0) {
mprintf("@Number of checks must be a positive integer.\n");
exit(41);
}
if(!cfgopt(copt, "DNSDatabaseInfo")) {
if(!cfgopt(copt, "DNSDatabaseInfo")->enabled || optl(opt, "no-dns")) {
if(checks > 50) {
mprintf("@Number of checks must be between 1 and 50.\n");
exit(41);
@ -286,12 +279,12 @@ int freshclam(struct optstruct *opt)
bigsleep = 24 * 3600 / checks;
if(!cfgopt(copt, "Foreground"))
if(!cfgopt(copt, "Foreground")->enabled)
daemonize();
if (optc(opt, 'p')) {
pidfile = getargc(opt, 'p');
} else if ((cpt = cfgopt(copt, "PidFile"))) {
} else if ((cpt = cfgopt(copt, "PidFile"))->enabled) {
pidfile = cpt->strarg;
}
if (pidfile) {
@ -315,7 +308,7 @@ int freshclam(struct optstruct *opt)
if(optl(opt, "on-error-execute"))
arg = getargl(opt, "on-error-execute");
else if((cpt = cfgopt(copt, "OnErrorExecute")))
else if((cpt = cfgopt(copt, "OnErrorExecute"))->enabled)
arg = cpt->strarg;
if(arg)
@ -353,7 +346,7 @@ int freshclam(struct optstruct *opt)
if(ret > 1)
system(getargl(opt, "on-error-execute"));
} else if((cpt = cfgopt(copt, "OnErrorExecute"))) {
} else if((cpt = cfgopt(copt, "OnErrorExecute"))->enabled) {
if(ret > 1)
system(cpt->strarg);
}
@ -370,15 +363,10 @@ int download(const struct cfgstruct *copt, const struct optstruct *opt)
struct cfgstruct *cpt;
if((cpt = cfgopt(copt, "MaxAttempts")))
maxattempts = cpt->numarg;
else
maxattempts = CL_DEFAULT_MAXATTEMPTS;
maxattempts = cfgopt(copt, "MaxAttempts")->numarg;
mprintf("*Max retries == %d\n", maxattempts);
if((cpt = cfgopt(copt, "DatabaseMirror")) == NULL) {
if(!(cpt = cfgopt(copt, "DatabaseMirror"))->enabled) {
mprintf("@You must specify at least one database mirror.\n");
return 56;
} else {

@ -76,10 +76,7 @@ int downloadmanager(const struct cfgstruct *copt, const struct optstruct *opt, c
#endif
#ifdef HAVE_RESOLV_H
if((cpt = cfgopt(copt, "DNSDatabaseInfo")))
dnsdbinfo = cpt->strarg;
else
dnsdbinfo = "current.cvd.clamav.net";
dnsdbinfo = cfgopt(copt, "DNSDatabaseInfo")->strarg;
if(optl(opt, "no-dns")) {
dnsreply = NULL;
@ -150,7 +147,7 @@ int downloadmanager(const struct cfgstruct *copt, const struct optstruct *opt, c
if(optl(opt, "localip")) {
localip = getargl(opt, "localip");
} else if((cpt = cfgopt(copt, "LocalIPAddress"))) {
} else if((cpt = cfgopt(copt, "LocalIPAddress"))->enabled) {
localip = cpt->strarg;
}
@ -179,7 +176,7 @@ int downloadmanager(const struct cfgstruct *copt, const struct optstruct *opt, c
free(dnsreply);
if(updated) {
if(cfgopt(copt, "HTTPProxyServer")) {
if(cfgopt(copt, "HTTPProxyServer")->enabled) {
mprintf("Database updated (%d signatures) from %s\n", signo, hostname);
logg("Database updated (%d signatures) from %s\n", signo, hostname);
} else {
@ -194,18 +191,14 @@ int downloadmanager(const struct cfgstruct *copt, const struct optstruct *opt, c
clamav_conf = CONFDIR"/clamd.conf";
notify(clamav_conf);
} else if((cpt = cfgopt(copt, "NotifyClamd"))) {
const char *clamav_conf = cpt->strarg;
if(!clamav_conf)
clamav_conf = CONFDIR"/clamd.conf";
notify(clamav_conf);
} else if((cpt = cfgopt(copt, "NotifyClamd"))->enabled) {
notify(cpt->strarg);
}
#endif
if(optl(opt, "on-update-execute"))
arg = getargl(opt, "on-update-execute");
else if((cpt = cfgopt(copt, "OnUpdateExecute")))
else if((cpt = cfgopt(copt, "OnUpdateExecute"))->enabled)
arg = cpt->strarg;
if(arg) {
@ -263,14 +256,14 @@ int downloaddb(const char *localname, const char *remotename, const char *hostna
}
/* Initialize proxy settings */
if((cpt = cfgopt(copt, "HTTPProxyServer"))) {
if((cpt = cfgopt(copt, "HTTPProxyServer"))->enabled) {
proxy = cpt->strarg;
if(strncasecmp(proxy, "http://", 7) == 0)
proxy += 7;
if((cpt = cfgopt(copt, "HTTPProxyUsername"))) {
if((cpt = cfgopt(copt, "HTTPProxyUsername"))->enabled) {
user = cpt->strarg;
if((cpt = cfgopt(copt, "HTTPProxyPassword"))) {
if((cpt = cfgopt(copt, "HTTPProxyPassword"))->enabled) {
pass = cpt->strarg;
} else {
mprintf("HTTPProxyUsername requires HTTPProxyPassword\n");
@ -280,7 +273,7 @@ int downloaddb(const char *localname, const char *remotename, const char *hostna
}
}
if((cpt = cfgopt(copt, "HTTPProxyPort")))
if((cpt = cfgopt(copt, "HTTPProxyPort"))->enabled)
port = cpt->numarg;
mprintf("Connecting via %s\n", proxy);
@ -295,7 +288,6 @@ int downloaddb(const char *localname, const char *remotename, const char *hostna
hostfd = wwwconnect(hostname, proxy, port, ipaddr, localip);
if(hostfd < 0) {
mprintf("@No servers could be reached. Giving up\n");
if(current)
cl_cvdfree(current);
return 52;

@ -1,5 +1,5 @@
/*
* Copyright (C) 2002, 2003 Tomasz Kojm <zolw@konarski.edu.pl>
* Copyright (C) 2002 - 2005 Tomasz Kojm <tkojm@clamav.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -47,15 +47,15 @@ int notify(const char *cfgfile)
char *socktype;
if((copt = parsecfg(cfgfile, 1)) == NULL) {
if((copt = getcfg(cfgfile, 1)) == NULL) {
mprintf("@Clamd was NOT notified: Can't find or parse configuration file %s\n", cfgfile);
return 1;
}
if(cfgopt(copt, "TCPSocket") && cfgopt(copt, "LocalSocket")) {
if(cfgopt(copt, "TCPSocket")->enabled && cfgopt(copt, "LocalSocket")->enabled) {
mprintf("@Clamd was NOT notified: Both socket types (TCP and local) declared in %s\n", cfgfile);
return 1;
} else if((cpt = cfgopt(copt, "LocalSocket"))) {
} else if((cpt = cfgopt(copt, "LocalSocket"))->enabled) {
socktype = "UNIX";
server.sun_family = AF_UNIX;
strncpy(server.sun_path, cpt->strarg, sizeof(server.sun_path));
@ -73,7 +73,7 @@ int notify(const char *cfgfile)
return 1;
}
} else if((cpt = cfgopt(copt, "TCPSocket"))) {
} else if((cpt = cfgopt(copt, "TCPSocket"))->enabled) {
socktype = "TCP";
#ifdef PF_INET
@ -89,7 +89,7 @@ int notify(const char *cfgfile)
server2.sin_family = AF_INET;
server2.sin_port = htons(cpt->numarg);
if ((cpt = cfgopt(copt, "TCPAddr"))) {
if((cpt = cfgopt(copt, "TCPAddr"))->enabled) {
if ((he = gethostbyname(cpt->strarg)) == 0) {
perror("gethostbyname()");
mprintf("@Clamd was NOT notified: Can't resolve hostname '%s'\n", cpt->strarg);

@ -1,5 +1,5 @@
/*
* Copyright (C) 2002 - 2004 Tomasz Kojm <tkojm@clamav.net>
* Copyright (C) 2002 - 2005 Tomasz Kojm <tkojm@clamav.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -32,110 +32,122 @@
#include "memory.h"
#include "misc.h"
struct cfgstruct *parsecfg(const char *cfgfile, int messages)
static int regcfg(struct cfgstruct **copt, char *optname, char *strarg, int numarg, short multiple);
struct cfgstruct *getcfg(const char *cfgfile, int verbose)
{
char buff[LINE_LENGTH], *name, *arg;
FILE *fs;
int line = 0, i, found, ctype, calc;
int line = 0, i, found, ctype, calc, val;
struct cfgstruct *copt = NULL;
struct cfgoption *pt;
struct cfgoption cfg_options[] = {
{"LogFile", OPT_STR},
{"LogFileUnlock", OPT_NOARG},
{"LogFileMaxSize", OPT_COMPSIZE},
{"LogTime", OPT_NOARG},
{"LogClean", OPT_NOARG},
{"LogVerbose", OPT_NOARG}, /* clamd + freshclam */
{"LogSyslog", OPT_NOARG},
{"LogFacility", OPT_STR},
{"PidFile", OPT_STR},
{"TemporaryDirectory", OPT_STR},
{"DisableDefaultScanOptions", OPT_NOARG},
{"ScanPE", OPT_NOARG},
{"DetectBrokenExecutables", OPT_NOARG},
{"ScanMail", OPT_NOARG},
{"MailFollowURLs", OPT_NOARG},
{"ScanHTML", OPT_NOARG},
{"ScanOLE2", OPT_NOARG},
{"ScanArchive", OPT_NOARG},
{"ScanRAR", OPT_NOARG},
{"ArchiveMaxFileSize", OPT_COMPSIZE},
{"ArchiveMaxRecursion", OPT_NUM},
{"ArchiveMaxFiles", OPT_NUM},
{"ArchiveMaxCompressionRatio", OPT_NUM},
{"ArchiveLimitMemoryUsage", OPT_NOARG},
{"ArchiveBlockEncrypted", OPT_NOARG},
{"ArchiveBlockMax", OPT_NOARG},
{"DataDirectory", OPT_STR}, /* obsolete */
{"DatabaseDirectory", OPT_STR}, /* clamd + freshclam */
{"TCPAddr", OPT_STR},
{"TCPSocket", OPT_NUM},
{"LocalSocket", OPT_STR},
{"MaxConnectionQueueLength", OPT_NUM},
{"StreamMaxLength", OPT_COMPSIZE},
{"StreamMinPort", OPT_NUM},
{"StreamMaxPort", OPT_NUM},
{"MaxThreads", OPT_NUM},
{"ReadTimeout", OPT_NUM},
{"IdleTimeout", OPT_NUM},
{"MaxDirectoryRecursion", OPT_NUM},
{"FollowDirectorySymlinks", OPT_NOARG},
{"FollowFileSymlinks", OPT_NOARG},
{"ExitOnOOM", OPT_NOARG},
{"Foreground", OPT_NOARG}, /* clamd + freshclam */
{"Debug", OPT_NOARG},
{"LeaveTemporaryFiles", OPT_NOARG},
{"FixStaleSocket", OPT_NOARG},
{"User", OPT_STR},
{"AllowSupplementaryGroups", OPT_NOARG},
{"SelfCheck", OPT_NUM},
{"VirusEvent", OPT_FULLSTR},
{"ClamukoScanOnLine", OPT_NOARG}, /* old name */
{"ClamukoScanOnAccess", OPT_NOARG},
{"ClamukoScanOnOpen", OPT_NOARG},
{"ClamukoScanOnClose", OPT_NOARG},
{"ClamukoScanOnExec", OPT_NOARG},
{"ClamukoIncludePath", OPT_STR},
{"ClamukoExcludePath", OPT_STR},
{"ClamukoMaxFileSize", OPT_COMPSIZE},
{"ClamukoScanArchive", OPT_NOARG},
{"DatabaseOwner", OPT_STR}, /* freshclam */
{"Checks", OPT_NUM}, /* freshclam */
{"UpdateLogFile", OPT_STR}, /* freshclam */
{"DNSDatabaseInfo", OPT_STR}, /* freshclam */
{"DatabaseMirror", OPT_STR}, /* freshclam */
{"MaxAttempts", OPT_NUM}, /* freshclam */
{"HTTPProxyServer", OPT_STR}, /* freshclam */
{"HTTPProxyPort", OPT_NUM}, /* freshclam */
{"HTTPProxyUsername", OPT_STR}, /* freshclam */
{"HTTPProxyPassword", OPT_STR}, /* freshclam */
{"NotifyClamd", OPT_OPTARG}, /* freshclam */
{"OnUpdateExecute", OPT_FULLSTR}, /* freshclam */
{"OnErrorExecute", OPT_FULLSTR}, /* freshclam */
{"LocalIPAddress", OPT_STR}, /* freshclam */
{"LogFile", OPT_STR, -1, NULL, 0},
{"LogFileUnlock", OPT_BOOL, 0, NULL, 0},
{"LogFileMaxSize", OPT_COMPSIZE, 1048576, NULL, 0},
{"LogTime", OPT_BOOL, 0, NULL, 0},
{"LogClean", OPT_BOOL, 0, NULL, 0},
{"LogVerbose", OPT_BOOL, 0, NULL, 0}, /* clamd + freshclam */
{"LogSyslog", OPT_BOOL, 0, NULL, 0},
{"LogFacility", OPT_STR, -1, "LOG_LOCAL6", 0},
{"PidFile", OPT_STR, -1, NULL, 0},
{"TemporaryDirectory", OPT_STR, -1, NULL, 0},
{"ScanPE", OPT_BOOL, 1, NULL, 0},
{"DetectBrokenExecutables", OPT_BOOL, 0, NULL, 0},
{"ScanMail", OPT_BOOL, 1, NULL, 0},
{"MailFollowURLs", OPT_BOOL, 0, NULL, 0},
{"ScanHTML", OPT_BOOL, 1, NULL, 0},
{"ScanOLE2", OPT_BOOL, 1, NULL, 0},
{"ScanArchive", OPT_BOOL, 1, NULL, 0},
{"ArchiveMaxFileSize", OPT_COMPSIZE, 10485760, NULL, 0},
{"ArchiveMaxRecursion", OPT_NUM, 8, NULL, 0},
{"ArchiveMaxFiles", OPT_NUM, 1000, NULL, 0},
{"ArchiveMaxCompressionRatio", OPT_NUM, 250, NULL, 0},
{"ArchiveLimitMemoryUsage", OPT_BOOL, 0, NULL, 0},
{"ArchiveBlockEncrypted", OPT_BOOL, 0, NULL, 0},
{"ArchiveBlockMax", OPT_BOOL, 0, NULL, 0},
{"DatabaseDirectory", OPT_STR, -1, DATADIR, 0}, /* clamd + freshclam */
{"TCPAddr", OPT_STR, -1, NULL, 0},
{"TCPSocket", OPT_NUM, -1, NULL, 0},
{"LocalSocket", OPT_STR, -1, NULL, 0},
{"MaxConnectionQueueLength", OPT_NUM, 15, NULL, 0},
{"StreamMaxLength", OPT_COMPSIZE, 10485760, NULL, 0},
{"StreamMinPort", OPT_NUM, 1024, NULL, 0},
{"StreamMaxPort", OPT_NUM, 2048, NULL, 0},
{"MaxThreads", OPT_NUM, 10, NULL, 0},
{"ReadTimeout", OPT_NUM, 120, NULL, 0},
{"IdleTimeout", OPT_NUM, 30, NULL, 0},
{"MaxDirectoryRecursion", OPT_NUM, 15, NULL, 0},
{"FollowDirectorySymlinks", OPT_BOOL, 0, NULL, 0},
{"FollowFileSymlinks", OPT_BOOL, 0, NULL, 0},
{"ExitOnOOM", OPT_BOOL, 0, NULL, 0},
{"Foreground", OPT_BOOL, 0, NULL, 0}, /* clamd + freshclam */
{"Debug", OPT_BOOL, 0, NULL, 0},
{"LeaveTemporaryFiles", OPT_BOOL, 0, NULL, 0},
{"FixStaleSocket", OPT_BOOL, 0, NULL, 0},
{"User", OPT_STR, -1, NULL, 0},
{"AllowSupplementaryGroups", OPT_BOOL, 0, NULL, 0},
{"SelfCheck", OPT_NUM, 1800, NULL, 0},
{"VirusEvent", OPT_FULLSTR, -1, NULL, 0},
{"ClamukoScanOnAccess", OPT_BOOL, 0, NULL, 0},
{"ClamukoScanOnOpen", OPT_BOOL, 0, NULL, 0},
{"ClamukoScanOnClose", OPT_BOOL, 0, NULL, 0},
{"ClamukoScanOnExec", OPT_BOOL, 0, NULL, 0},
{"ClamukoIncludePath", OPT_STR, 0, NULL, 0},
{"ClamukoExcludePath", OPT_STR, 0, NULL, 0},
{"ClamukoMaxFileSize", OPT_COMPSIZE, 5242880, NULL, 0},
{"ClamukoScanArchive", OPT_BOOL, 0, NULL, 0},
{"DatabaseOwner", OPT_STR, -1, NULL, 0}, /* freshclam */
{"Checks", OPT_NUM, 12, NULL, 0}, /* freshclam */
{"UpdateLogFile", OPT_STR, -1, NULL, 0}, /* freshclam */
{"DNSDatabaseInfo", OPT_STR, -1, "current.cvd.clamav.net", 0}, /* freshclam */
{"DatabaseMirror", OPT_STR, -1, NULL, 1}, /* freshclam */
{"MaxAttempts", OPT_NUM, 3, NULL, 0}, /* freshclam */
{"HTTPProxyServer", OPT_STR, -1, NULL, 0}, /* freshclam */
{"HTTPProxyPort", OPT_NUM, -1, NULL, 0}, /* freshclam */
{"HTTPProxyUsername", OPT_STR, -1, NULL, 0}, /* freshclam */
{"HTTPProxyPassword", OPT_STR, -1, NULL, 0}, /* freshclam */
{"NotifyClamd", OPT_STR, -1, NULL, 0}, /* freshclam */
{"OnUpdateExecute", OPT_FULLSTR, -1, NULL, 0}, /* freshclam */
{"OnErrorExecute", OPT_FULLSTR, -1, NULL, 0}, /* freshclam */
{"LocalIPAddress", OPT_STR, -1, NULL, 0}, /* freshclam */
{0, 0}
};
if((fs = fopen(cfgfile, "r")) == NULL)
for(i = 0; ; i++) {
pt = &cfg_options[i];
if(!pt->name)
break;
if(regcfg(&copt, strdup(pt->name), pt->strarg ? strdup(pt->strarg) : NULL, pt->numarg, pt->multiple) < 0) {
fprintf(stderr, "ERROR: Can't register new options (not enough memory)\n");
freecfg(copt);
return NULL;
}
}
if((fs = fopen(cfgfile, "r")) == NULL) {
/* do not print error message here! */
freecfg(copt);
return NULL;
}
while(fgets(buff, LINE_LENGTH, fs)) {
line++;
if(buff[0] == '#')
continue;
if(!strncmp("Example", buff, 7)) {
if(messages)
if(verbose)
fprintf(stderr, "ERROR: Please edit the example config file %s.\n", cfgfile);
fclose(fs);
freecfg(copt);
return NULL;
}
if((name = cli_strtok(buff, 0, " \r\n"))) {
arg = cli_strtok(buff, 1, " \r\n");
found = 0;
@ -147,41 +159,61 @@ struct cfgstruct *parsecfg(const char *cfgfile, int messages)
switch(pt->argtype) {
case OPT_STR:
if(!arg) {
if(messages)
fprintf(stderr, "ERROR: Parse error at line %d: Option %s requires string as argument.\n", line, name);
if(verbose)
fprintf(stderr, "ERROR: Parse error at line %d: Option %s requires string argument.\n", line, name);
fclose(fs);
freecfg(copt);
return NULL;
}
if(regcfg(&copt, name, arg, -1, pt->multiple) < 0) {
fprintf(stderr, "ERROR: Can't register new options (not enough memory)\n");
fclose(fs);
freecfg(copt);
return NULL;
}
copt = regcfg(copt, name, arg, 0);
break;
case OPT_FULLSTR:
/* an ugly hack of the above case */
if(!arg) {
if(messages)
fprintf(stderr, "ERROR: Parse error at line %d: Option %s requires string as argument.\n", line, name);
if(verbose)
fprintf(stderr, "ERROR: Parse error at line %d: Option %s requires string argument.\n", line, name);
fclose(fs);
freecfg(copt);
return NULL;
}
/* FIXME: this one is an ugly hack of the above case */
free(arg);
arg = strstr(buff, " ");
arg = strdup(++arg);
copt = regcfg(copt, name, arg, 0);
if(regcfg(&copt, name, arg, -1, pt->multiple) < 0) {
fprintf(stderr, "ERROR: Can't register new options (not enough memory)\n");
fclose(fs);
freecfg(copt);
return NULL;
}
break;
case OPT_NUM:
if(!arg || !isnumb(arg)) {
if(messages)
if(verbose)
fprintf(stderr, "ERROR: Parse error at line %d: Option %s requires numerical argument.\n", line, name);
fclose(fs);
freecfg(copt);
return NULL;
}
if(regcfg(&copt, name, NULL, atoi(arg), pt->multiple) < 0) {
fprintf(stderr, "ERROR: Can't register new options (not enough memory)\n");
fclose(fs);
freecfg(copt);
free(arg);
return NULL;
}
copt = regcfg(copt, name, NULL, atoi(arg));
free(arg);
break;
case OPT_COMPSIZE:
if(!arg) {
if(messages)
if(verbose)
fprintf(stderr, "ERROR: Parse error at line %d: Option %s requires argument.\n", line, name);
fclose(fs);
freecfg(copt);
return NULL;
}
ctype = tolower(arg[strlen(arg) - 1]);
@ -189,9 +221,10 @@ struct cfgstruct *parsecfg(const char *cfgfile, int messages)
char *cpy = (char *) mcalloc(strlen(arg), sizeof(char));
strncpy(cpy, arg, strlen(arg) - 1);
if(!isnumb(cpy)) {
if(messages)
if(verbose)
fprintf(stderr, "ERROR: Parse error at line %d: Option %s requires numerical (raw/K/M) argument.\n", line, name);
fclose(fs);
freecfg(copt);
return NULL;
}
if(ctype == 'm')
@ -201,44 +234,69 @@ struct cfgstruct *parsecfg(const char *cfgfile, int messages)
free(cpy);
} else {
if(!isnumb(arg)) {
if(messages)
if(verbose)
fprintf(stderr, "ERROR: Parse error at line %d: Option %s requires numerical (raw/K/M) argument.\n", line, name);
fclose(fs);
freecfg(copt);
return NULL;
}
calc = atoi(arg);
}
copt = regcfg(copt, name, NULL, calc);
free(arg);
break;
case OPT_NOARG:
if(arg) {
if(messages)
fprintf(stderr, "ERROR: Parse error at line %d: Option %s doesn't support arguments (got '%s').\n", line, name, arg);
if(regcfg(&copt, name, NULL, calc, pt->multiple) < 0) {
fprintf(stderr, "ERROR: Can't register new options (not enough memory)\n");
fclose(fs);
freecfg(copt);
return NULL;
}
copt = regcfg(copt, name, NULL, 0);
break;
case OPT_OPTARG:
copt = regcfg(copt, name, arg, 0);
case OPT_BOOL:
if(!arg) {
if(verbose)
fprintf(stderr, "ERROR: Parse error at line %d: Option %s requires boolean argument.\n", line, name);
fclose(fs);
freecfg(copt);
return NULL;
}
if(!strcasecmp(arg, "yes") || !strcmp(arg, "1") || !strcasecmp(arg, "true")) {
val = 1;
} else if(!strcasecmp(arg, "no") || !strcmp(arg, "0") || !strcasecmp(arg, "false")) {
val = 0;
} else {
if(verbose)
fprintf(stderr, "ERROR: Parse error at line %d: Option %s requires boolean argument.\n", line, name);
fclose(fs);
freecfg(copt);
return NULL;
}
free(arg);
if(regcfg(&copt, name, NULL, val, pt->multiple) < 0) {
fprintf(stderr, "ERROR: Can't register new options (not enough memory)\n");
fclose(fs);
freecfg(copt);
return NULL;
}
break;
default:
if(messages)
if(verbose)
fprintf(stderr, "ERROR: Parse error at line %d: Option %s is of unknown type %d\n", line, name, pt->argtype);
free(name);
free(arg);
break;
freecfg(copt);
return NULL;
}
}
} else
break;
}
}
if(!found) {
if(messages)
if(verbose)
fprintf(stderr, "ERROR: Parse error at line %d: Unknown option %s.\n", line, name);
fclose(fs);
freecfg(copt);
return NULL;
}
}
@ -253,7 +311,7 @@ void freecfg(struct cfgstruct *copt)
struct cfgstruct *handler;
struct cfgstruct *arg;
while (copt) {
while(copt) {
arg = copt->nextarg;
while(arg) {
if(arg->strarg) {
@ -265,12 +323,12 @@ void freecfg(struct cfgstruct *copt)
} else
arg = arg->nextarg;
}
if(copt->optname) {
if(copt->optname)
free(copt->optname);
}
if(copt->strarg) {
if(copt->strarg)
free(copt->strarg);
}
handler = copt;
copt = copt->next;
free(handler);
@ -278,48 +336,79 @@ void freecfg(struct cfgstruct *copt)
return;
}
struct cfgstruct *regcfg(struct cfgstruct *copt, char *optname, char *strarg, int numarg)
struct cfgstruct *cfgopt(const struct cfgstruct *copt, const char *optname)
{
struct cfgstruct *handler;
handler = (struct cfgstruct *) copt;
while(1) {
if(handler) {
if(handler->optname)
if(!strcmp(handler->optname, optname))
return handler;
} else break;
handler = handler->next;
}
return NULL;
}
static int regcfg(struct cfgstruct **copt, char *optname, char *strarg, int numarg, short multiple)
{
struct cfgstruct *newnode, *pt;
newnode = (struct cfgstruct *) mmalloc(sizeof(struct cfgstruct));
if(!newnode)
return -1;
newnode->optname = optname;
newnode->nextarg = NULL;
newnode->next = NULL;
newnode->enabled = 0;
newnode->multiple = multiple;
if(strarg)
if(strarg) {
newnode->strarg = strarg;
else {
newnode->enabled = 1;
} else {
newnode->strarg = NULL;
newnode->numarg = numarg;
}
if((pt = cfgopt(copt, optname))) {
while(pt->nextarg)
pt = pt->nextarg;
newnode->numarg = numarg;
if(numarg != -1 && numarg != 0)
newnode->enabled = 1;
pt->nextarg = newnode;
return copt;
} else {
newnode->next = copt;
return newnode;
}
}
if((pt = cfgopt(*copt, optname))) {
if(pt->multiple) {
struct cfgstruct *cfgopt(const struct cfgstruct *copt, const char *optname)
{
struct cfgstruct *handler;
if(pt->enabled) {
while(pt->nextarg)
pt = pt->nextarg;
handler = (struct cfgstruct *) copt;
pt->nextarg = newnode;
} else {
pt->strarg = newnode->strarg;
pt->numarg = newnode->numarg;
pt->enabled = newnode->enabled;
free(newnode);
}
return 3; /* registered additional argument */
while(1) {
if(handler) {
if(handler->optname)
if(!strcmp(handler->optname, optname))
return handler;
} else break;
handler = handler->next;
}
} else {
pt->strarg = newnode->strarg;
pt->numarg = newnode->numarg;
pt->enabled = newnode->enabled;
free(newnode);
return 2;
}
return NULL;
} else {
newnode->next = *copt;
*copt = newnode;
return 1;
}
}

@ -1,5 +1,5 @@
/*
* Copyright (C) 2002 - 2004 Tomasz Kojm <tkojm@clamav.net>
* Copyright (C) 2002 - 2005 Tomasz Kojm <tkojm@clamav.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -21,31 +21,32 @@
#define LINE_LENGTH 1024
#define OPT_STR 1 /* string argument */
#define OPT_NUM 2 /* numerical argument */
#define OPT_COMPSIZE 3 /* convert kilobytes (k) and megabytes (m) to bytes */
#define OPT_NOARG 4 /* no argument */
#define OPT_OPTARG 5 /* argument is optional, it's registered as string */
#define OPT_FULLSTR 6 /* string argument, but get a full line */
#define OPT_BOOL 4 /* boolean value */
#define OPT_FULLSTR 5 /* string argument, but get a full line */
struct cfgoption {
const char *name;
int argtype;
int numarg;
const char *strarg;
short multiple;
};
struct cfgstruct {
char *optname;
char *strarg;
int numarg;
short enabled;
short multiple;
struct cfgstruct *nextarg;
struct cfgstruct *next;
};
struct cfgstruct *parsecfg(const char *cfgfile, int messages);
struct cfgstruct *regcfg(struct cfgstruct *copt, char *optname, char *strarg, int numarg);
struct cfgstruct *getcfg(const char *cfgfile, int verbose);
struct cfgstruct *cfgopt(const struct cfgstruct *copt, const char *optname);

@ -44,8 +44,8 @@ char *freshdbdir(void)
/* try to find fresh directory */
dbdir = cl_retdbdir();
if((copt = parsecfg(CONFDIR"/clamd.conf", 0))) {
if((cpt = cfgopt(copt, "DatabaseDirectory")) || (cpt = cfgopt(copt, "DataDirectory"))) {
if((copt = getcfg(CONFDIR"/clamd.conf", 0))) {
if((cpt = cfgopt(copt, "DatabaseDirectory"))->enabled || (cpt = cfgopt(copt, "DataDirectory"))->enabled) {
if(strcmp(dbdir, cpt->strarg)) {
char *daily = (char *) mmalloc(strlen(cpt->strarg) + strlen(dbdir) + 15);
sprintf(daily, "%s/daily.cvd", cpt->strarg);

Loading…
Cancel
Save