git-svn: trunk@166
Tomasz Kojm authored on 2003/12/29 14:31:52... | ... |
@@ -1,3 +1,10 @@ |
1 |
+Mon Dec 29 06:19:54 CET 2003 (tk) |
|
2 |
+--------------------------------- |
|
3 |
+ * freshclam: it's now configurable via freshclam.conf (which may be merged |
|
4 |
+ with clamav.conf). The old command line options are accepted |
|
5 |
+ but most of them will have no effect. WARNING: Some things |
|
6 |
+ may be temporary broken. |
|
7 |
+ |
|
1 | 8 |
Sat Dec 27 17:29:30 GMT 2003 (njh) |
2 | 9 |
---------------------------------- |
3 | 10 |
* clamav-devel: Moved --sign data to private area |
... | ... |
@@ -81,7 +81,7 @@ dnl there is now a CREATE_PREFIX_TARGET_H in this file as a shorthand for |
81 | 81 |
dnl PREFIX_CONFIG_H from a target.h file, however w/o the target.h ever created |
82 | 82 |
dnl (the prefix is a bit different, since we add an extra -target- and -host-) |
83 | 83 |
dnl |
84 |
-dnl @version: $Id: aclocal.m4,v 1.15 2003/12/08 18:57:39 kojm Exp $ |
|
84 |
+dnl @version: $Id: aclocal.m4,v 1.16 2003/12/29 05:31:52 kojm Exp $ |
|
85 | 85 |
dnl @author Guido Draheim <guidod@gmx.de> STATUS: used often |
86 | 86 |
|
87 | 87 |
AC_DEFUN([AC_CREATE_TARGET_H], |
... | ... |
@@ -4041,7 +4041,7 @@ dnl AC_COMPILE_CHECK_SIZEOF(ptrdiff_t, $headers) |
4041 | 4041 |
dnl AC_COMPILE_CHECK_SIZEOF(off_t, $headers) |
4042 | 4042 |
dnl |
4043 | 4043 |
dnl @author Kaveh Ghazi <ghazi@caip.rutgers.edu> |
4044 |
-dnl @version $Id: aclocal.m4,v 1.15 2003/12/08 18:57:39 kojm Exp $ |
|
4044 |
+dnl @version $Id: aclocal.m4,v 1.16 2003/12/29 05:31:52 kojm Exp $ |
|
4045 | 4045 |
dnl |
4046 | 4046 |
AC_DEFUN([AC_COMPILE_CHECK_SIZEOF], |
4047 | 4047 |
[changequote(<<, >>)dnl |
... | ... |
@@ -41,7 +41,7 @@ struct cfgstruct *parsecfg(const char *cfgfile) |
41 | 41 |
{"LogFileUnlock", OPT_NOARG}, |
42 | 42 |
{"LogFileMaxSize", OPT_COMPSIZE}, |
43 | 43 |
{"LogTime", OPT_NOARG}, |
44 |
- {"LogVerbose", OPT_NOARG}, |
|
44 |
+ {"LogVerbose", OPT_NOARG}, /* clamd + freshclam */ |
|
45 | 45 |
{"LogSyslog", OPT_NOARG}, |
46 | 46 |
{"PidFile", OPT_STR}, |
47 | 47 |
{"MaxFileSize", OPT_COMPSIZE}, |
... | ... |
@@ -53,7 +53,8 @@ struct cfgstruct *parsecfg(const char *cfgfile) |
53 | 53 |
{"ArchiveMaxFiles", OPT_NUM}, |
54 | 54 |
{"ArchiveMaxCompressionRatio", OPT_NUM}, |
55 | 55 |
{"ArchiveLimitMemoryUsage", OPT_NOARG}, |
56 |
- {"DataDirectory", OPT_STR}, |
|
56 |
+ {"DataDirectory", OPT_STR}, /* obsolete */ |
|
57 |
+ {"DatabaseDirectory", OPT_STR}, /* clamd + freshclam */ |
|
57 | 58 |
{"TCPAddr", OPT_STR}, |
58 | 59 |
{"TCPSocket", OPT_NUM}, |
59 | 60 |
{"LocalSocket", OPT_STR}, |
... | ... |
@@ -81,12 +82,23 @@ struct cfgstruct *parsecfg(const char *cfgfile) |
81 | 81 |
{"ClamukoExcludePath", OPT_STR}, |
82 | 82 |
{"ClamukoMaxFileSize", OPT_COMPSIZE}, |
83 | 83 |
{"ClamukoScanArchive", OPT_NOARG}, |
84 |
+ {"DatabaseOwner", OPT_STR}, /* freshclam */ |
|
85 |
+ {"Checks", OPT_NUM}, /* freshclam */ |
|
86 |
+ {"UpdateLogFile", OPT_STR}, /* freshclam */ |
|
87 |
+ {"DatabaseMirror", OPT_STR}, /* freshclam */ |
|
88 |
+ {"MaxAttempts", OPT_NUM}, /* freshclam */ |
|
89 |
+ {"HTTPProxyServer", OPT_STR}, /* freshclam */ |
|
90 |
+ {"HTTPProxyPort", OPT_STR}, /* freshclam */ |
|
91 |
+ {"HTTPProxyUsername", OPT_STR}, /* freshclam */ |
|
92 |
+ {"HTTPProxyPassword", OPT_STR}, /* freshclam */ |
|
93 |
+ {"NotifyClamd", OPT_OPTARG}, /* freshclam */ |
|
94 |
+ {"OnUpdateExecute", OPT_FULLSTR}, /* freshclam */ |
|
95 |
+ {"OnErrorExecute", OPT_FULLSTR}, /* freshclam */ |
|
84 | 96 |
{0, 0} |
85 | 97 |
}; |
86 | 98 |
|
87 | 99 |
|
88 | 100 |
if((fs = fopen(cfgfile, "r")) == NULL) { |
89 |
- fprintf(stderr, "ERROR: Can't open config file %s !\n", cfgfile); |
|
90 | 101 |
return NULL; |
91 | 102 |
} |
92 | 103 |
|
... | ... |
@@ -70,7 +70,7 @@ void clamd(struct optstruct *opt) |
70 | 70 |
cfgfile = CL_DEFAULT_CFG; |
71 | 71 |
|
72 | 72 |
if((copt = parsecfg(cfgfile)) == NULL) { |
73 |
- fprintf(stderr, "ERROR: Can't parse the config file %s\n", cfgfile); |
|
73 |
+ fprintf(stderr, "ERROR: Can't open/parse the config file %s\n", cfgfile); |
|
74 | 74 |
exit(1); |
75 | 75 |
} |
76 | 76 |
|
... | ... |
@@ -170,7 +170,7 @@ void clamd(struct optstruct *opt) |
170 | 170 |
|
171 | 171 |
/* load the database(s) */ |
172 | 172 |
|
173 |
- if((cpt = cfgopt(copt, "DataDirectory"))) |
|
173 |
+ if((cpt = cfgopt(copt, "DatabaseDirectory")) || (cpt = cfgopt(copt, "DataDirectory"))) |
|
174 | 174 |
dbdir = cpt->strarg; |
175 | 175 |
else |
176 | 176 |
dbdir = cl_retdbdir(); |
... | ... |
@@ -113,7 +113,7 @@ int acceptloop_proc(int socketd, struct cl_node *root, const struct cfgstruct *c |
113 | 113 |
logg("Maximal number of childs: %d\n", childs); |
114 | 114 |
session = (int *) mcalloc(childs, sizeof(int)); |
115 | 115 |
|
116 |
- if((cpt = cfgopt(copt, "DataDirectory"))) |
|
116 |
+ if((cpt = cfgopt(copt, "DatabaseDirectory")) || (cpt = cfgopt(copt, "DataDirectory"))) |
|
117 | 117 |
dbdir = cpt->strarg; |
118 | 118 |
else |
119 | 119 |
dbdir = cl_retdbdir(); |
... | ... |
@@ -165,7 +165,7 @@ void *threadwatcher(void *arg) |
165 | 165 |
} else |
166 | 166 |
logg("Timeout set to %d seconds.\n", timeout); |
167 | 167 |
|
168 |
- if((cpt = cfgopt(thwarg->copt, "DataDirectory"))) |
|
168 |
+ if((cpt = cfgopt(thwarg->copt, "DatabaseDirectory")) || (cpt = cfgopt(thwarg->copt, "DataDirectory"))) |
|
169 | 169 |
dbdir = cpt->strarg; |
170 | 170 |
else |
171 | 171 |
dbdir = cl_retdbdir(); |
... | ... |
@@ -9294,11 +9294,21 @@ _ACEOF |
9294 | 9294 |
|
9295 | 9295 |
|
9296 | 9296 |
if test ! -r "$cfg_dir/clamav.conf"; then |
9297 |
- INSTALL_CONF_TRUE= |
|
9298 |
- INSTALL_CONF_FALSE='#' |
|
9297 |
+ INSTALL_CLAMAV_CONF_TRUE= |
|
9298 |
+ INSTALL_CLAMAV_CONF_FALSE='#' |
|
9299 | 9299 |
else |
9300 |
- INSTALL_CONF_TRUE='#' |
|
9301 |
- INSTALL_CONF_FALSE= |
|
9300 |
+ INSTALL_CLAMAV_CONF_TRUE='#' |
|
9301 |
+ INSTALL_CLAMAV_CONF_FALSE= |
|
9302 |
+fi |
|
9303 |
+ |
|
9304 |
+ |
|
9305 |
+ |
|
9306 |
+if test ! -r "$cfg_dir/freshclam.conf"; then |
|
9307 |
+ INSTALL_FRESHCLAM_CONF_TRUE= |
|
9308 |
+ INSTALL_FRESHCLAM_CONF_FALSE='#' |
|
9309 |
+else |
|
9310 |
+ INSTALL_FRESHCLAM_CONF_TRUE='#' |
|
9311 |
+ INSTALL_FRESHCLAM_CONF_FALSE= |
|
9302 | 9312 |
fi |
9303 | 9313 |
|
9304 | 9314 |
|
... | ... |
@@ -10228,10 +10238,17 @@ echo "$as_me: error: conditional \"AMDEP\" was never defined. |
10228 | 10228 |
Usually this means the macro was only invoked conditionally." >&2;} |
10229 | 10229 |
{ (exit 1); exit 1; }; } |
10230 | 10230 |
fi |
10231 |
-if test -z "${INSTALL_CONF_TRUE}" && test -z "${INSTALL_CONF_FALSE}"; then |
|
10232 |
- { { echo "$as_me:$LINENO: error: conditional \"INSTALL_CONF\" was never defined. |
|
10231 |
+if test -z "${INSTALL_CLAMAV_CONF_TRUE}" && test -z "${INSTALL_CLAMAV_CONF_FALSE}"; then |
|
10232 |
+ { { echo "$as_me:$LINENO: error: conditional \"INSTALL_CLAMAV_CONF\" was never defined. |
|
10233 |
+Usually this means the macro was only invoked conditionally." >&5 |
|
10234 |
+echo "$as_me: error: conditional \"INSTALL_CLAMAV_CONF\" was never defined. |
|
10235 |
+Usually this means the macro was only invoked conditionally." >&2;} |
|
10236 |
+ { (exit 1); exit 1; }; } |
|
10237 |
+fi |
|
10238 |
+if test -z "${INSTALL_FRESHCLAM_CONF_TRUE}" && test -z "${INSTALL_FRESHCLAM_CONF_FALSE}"; then |
|
10239 |
+ { { echo "$as_me:$LINENO: error: conditional \"INSTALL_FRESHCLAM_CONF\" was never defined. |
|
10233 | 10240 |
Usually this means the macro was only invoked conditionally." >&5 |
10234 |
-echo "$as_me: error: conditional \"INSTALL_CONF\" was never defined. |
|
10241 |
+echo "$as_me: error: conditional \"INSTALL_FRESHCLAM_CONF\" was never defined. |
|
10235 | 10242 |
Usually this means the macro was only invoked conditionally." >&2;} |
10236 | 10243 |
{ (exit 1); exit 1; }; } |
10237 | 10244 |
fi |
... | ... |
@@ -10794,8 +10811,10 @@ s,@CPP@,$CPP,;t t |
10794 | 10794 |
s,@LIBTOOL@,$LIBTOOL,;t t |
10795 | 10795 |
s,@DBDIR@,$DBDIR,;t t |
10796 | 10796 |
s,@CFGDIR@,$CFGDIR,;t t |
10797 |
-s,@INSTALL_CONF_TRUE@,$INSTALL_CONF_TRUE,;t t |
|
10798 |
-s,@INSTALL_CONF_FALSE@,$INSTALL_CONF_FALSE,;t t |
|
10797 |
+s,@INSTALL_CLAMAV_CONF_TRUE@,$INSTALL_CLAMAV_CONF_TRUE,;t t |
|
10798 |
+s,@INSTALL_CLAMAV_CONF_FALSE@,$INSTALL_CLAMAV_CONF_FALSE,;t t |
|
10799 |
+s,@INSTALL_FRESHCLAM_CONF_TRUE@,$INSTALL_FRESHCLAM_CONF_TRUE,;t t |
|
10800 |
+s,@INSTALL_FRESHCLAM_CONF_FALSE@,$INSTALL_FRESHCLAM_CONF_FALSE,;t t |
|
10799 | 10801 |
s,@LIBCLAMAV_LIBS@,$LIBCLAMAV_LIBS,;t t |
10800 | 10802 |
s,@CLAMD_LIBS@,$CLAMD_LIBS,;t t |
10801 | 10803 |
s,@FRESHCLAM_LIBS@,$FRESHCLAM_LIBS,;t t |
... | ... |
@@ -196,7 +196,8 @@ AC_SUBST(CFGDIR) |
196 | 196 |
AC_DEFINE_UNQUOTED(CONFDIR,"$cfg_dir",) |
197 | 197 |
|
198 | 198 |
dnl Do not overwrite the current config file |
199 |
-AM_CONDITIONAL(INSTALL_CONF, test ! -r "$cfg_dir/clamav.conf") |
|
199 |
+AM_CONDITIONAL(INSTALL_CLAMAV_CONF, test ! -r "$cfg_dir/clamav.conf") |
|
200 |
+AM_CONDITIONAL(INSTALL_FRESHCLAM_CONF, test ! -r "$cfg_dir/freshclam.conf") |
|
200 | 201 |
|
201 | 202 |
if test "$test_urandom" = "yes" |
202 | 203 |
then |
... | ... |
@@ -17,12 +17,14 @@ |
17 | 17 |
# along with this program; if not, write to the Free Software |
18 | 18 |
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
19 | 19 |
|
20 |
-EXTRA_DIST = clamav.conf |
|
20 |
+EXTRA_DIST = clamav.conf freshclam.conf |
|
21 | 21 |
CFGINST = @CFGDIR@ |
22 | 22 |
|
23 |
-if INSTALL_CONF |
|
24 |
- |
|
25 | 23 |
install: |
26 | 24 |
$(mkinstalldirs) $(DESTDIR)$(CFGINST) |
25 |
+if INSTALL_CLAMAV_CONF |
|
27 | 26 |
@$(INSTALL_DATA) clamav.conf $(DESTDIR)$(CFGINST) |
28 | 27 |
endif |
28 |
+if INSTALL_FRESHCLAM_CONF |
|
29 |
+ @$(INSTALL_DATA) freshclam.conf $(DESTDIR)$(CFGINST) |
|
30 |
+endif |
... | ... |
@@ -117,7 +117,7 @@ am__include = @am__include@ |
117 | 117 |
am__quote = @am__quote@ |
118 | 118 |
install_sh = @install_sh@ |
119 | 119 |
|
120 |
-EXTRA_DIST = clamav.conf |
|
120 |
+EXTRA_DIST = clamav.conf freshclam.conf |
|
121 | 121 |
CFGINST = @CFGDIR@ |
122 | 122 |
subdir = etc |
123 | 123 |
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs |
... | ... |
@@ -176,8 +176,6 @@ check: check-am |
176 | 176 |
all-am: Makefile |
177 | 177 |
|
178 | 178 |
installdirs: |
179 |
- |
|
180 |
-@INSTALL_CONF_FALSE@install: install-am |
|
181 | 179 |
install-exec: install-exec-am |
182 | 180 |
install-data: install-data-am |
183 | 181 |
uninstall: uninstall-am |
... | ... |
@@ -247,9 +245,10 @@ uninstall-am: uninstall-info-am |
247 | 247 |
mostlyclean-libtool uninstall uninstall-am uninstall-info-am |
248 | 248 |
|
249 | 249 |
|
250 |
-@INSTALL_CONF_TRUE@install: |
|
251 |
-@INSTALL_CONF_TRUE@ $(mkinstalldirs) $(DESTDIR)$(CFGINST) |
|
252 |
-@INSTALL_CONF_TRUE@ @$(INSTALL_DATA) clamav.conf $(DESTDIR)$(CFGINST) |
|
250 |
+install: |
|
251 |
+ $(mkinstalldirs) $(DESTDIR)$(CFGINST) |
|
252 |
+@INSTALL_CLAMAV_CONF_TRUE@ @$(INSTALL_DATA) clamav.conf $(DESTDIR)$(CFGINST) |
|
253 |
+@INSTALL_FRESHCLAM_CONF_TRUE@ @$(INSTALL_DATA) freshclam.conf $(DESTDIR)$(CFGINST) |
|
253 | 254 |
# Tell versions [3.59,3.63) of GNU make to not export all variables. |
254 | 255 |
# Otherwise a system limit (for SysV at least) may be exceeded. |
255 | 256 |
.NOEXPORT: |
... | ... |
@@ -39,10 +39,10 @@ Example |
39 | 39 |
# daemon (main thread). |
40 | 40 |
#PidFile /var/run/clamd.pid |
41 | 41 |
|
42 |
-# Path to a directory containing .db files. |
|
42 |
+# Path to the database directory. |
|
43 | 43 |
# Default is the hardcoded directory (mostly /usr/local/share/clamav, |
44 |
-# it depends on installation options). |
|
45 |
-#DataDirectory /var/lib/clamav |
|
44 |
+# but it depends on installation options). |
|
45 |
+#DatabaseDirectory /var/lib/clamav |
|
46 | 46 |
|
47 | 47 |
# The daemon works in local or network mode. Currently the local mode is |
48 | 48 |
# recommended for security reasons. |
49 | 49 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,34 @@ |
0 |
+## |
|
1 |
+## Example config file for freshclam |
|
2 |
+## Please read the clamav.conf(5) manual before editing this file. |
|
3 |
+## |
|
4 |
+ |
|
5 |
+# Comment or remove the line below. |
|
6 |
+Example |
|
7 |
+ |
|
8 |
+# Path to the database directory. |
|
9 |
+#DatabaseDirectory /var/lib/clamav |
|
10 |
+ |
|
11 |
+#UpdateLogFile /var/log/freshclam.log |
|
12 |
+ |
|
13 |
+# Enable verbose logging. |
|
14 |
+#LogVerbose |
|
15 |
+ |
|
16 |
+# Freshclam must be able to write to the database directory. |
|
17 |
+#DatabaseOwner clamav |
|
18 |
+ |
|
19 |
+DatabaseMirror database.clamav.net |
|
20 |
+MaxAttempts 3 |
|
21 |
+ |
|
22 |
+#Checks 12 |
|
23 |
+ |
|
24 |
+#HTTPProxyServer myproxy.com |
|
25 |
+#HTTPProxyPort 1234 |
|
26 |
+#HTTPProxyUsername myusername |
|
27 |
+#HTTPProxyPassword mypass |
|
28 |
+ |
|
29 |
+#NotifyClamd [/optional/config/file/path] |
|
30 |
+ |
|
31 |
+#OnUpdateExecute command |
|
32 |
+ |
|
33 |
+#OnErrorExecute command |
0 | 34 |
deleted file mode 100644 |
... | ... |
@@ -1,273 +0,0 @@ |
1 |
-/* |
|
2 |
- * Copyright (C) 2002 Tomasz Kojm <zolw@konarski.edu.pl> |
|
3 |
- * |
|
4 |
- * This program is free software; you can redistribute it and/or modify |
|
5 |
- * it under the terms of the GNU General Public License as published by |
|
6 |
- * the Free Software Foundation; either version 2 of the License, or |
|
7 |
- * (at your option) any later version. |
|
8 |
- * |
|
9 |
- * This program is distributed in the hope that it will be useful, |
|
10 |
- * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
11 |
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
12 |
- * GNU General Public License for more details. |
|
13 |
- * |
|
14 |
- * You should have received a copy of the GNU General Public License |
|
15 |
- * along with this program; if not, write to the Free Software |
|
16 |
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
|
17 |
- */ |
|
18 |
- |
|
19 |
-#include <stdio.h> |
|
20 |
-#include <stdlib.h> |
|
21 |
-#include <string.h> |
|
22 |
-#include <ctype.h> |
|
23 |
- |
|
24 |
-#include "options.h" |
|
25 |
-#include "cfgfile.h" |
|
26 |
-#include "others.h" |
|
27 |
-#include "defaults.h" |
|
28 |
- |
|
29 |
- |
|
30 |
-struct cfgstruct *parsecfg(const char *cfgfile) |
|
31 |
-{ |
|
32 |
- char buff[LINE_LENGTH], *name, *arg; |
|
33 |
- FILE *fs; |
|
34 |
- int line = 0, i, found, ctype, calc; |
|
35 |
- struct cfgstruct *copt = NULL; |
|
36 |
- struct cfgoption *pt; |
|
37 |
- |
|
38 |
- struct cfgoption cfg_options[] = { |
|
39 |
- {"LogFile", OPT_STR}, |
|
40 |
- {"LogFileUnlock", OPT_NOARG}, |
|
41 |
- {"LogFileMaxSize", OPT_COMPSIZE}, |
|
42 |
- {"LogTime", OPT_NOARG}, |
|
43 |
- {"LogVerbose", OPT_NOARG}, |
|
44 |
- {"LogSyslog", OPT_NOARG}, |
|
45 |
- {"PidFile", OPT_STR}, |
|
46 |
- {"MaxFileSize", OPT_COMPSIZE}, |
|
47 |
- {"ScanMail", OPT_NOARG}, |
|
48 |
- {"ScanArchive", OPT_NOARG}, |
|
49 |
- {"ArchiveMaxFileSize", OPT_COMPSIZE}, |
|
50 |
- {"ArchiveMaxRecursion", OPT_NUM}, |
|
51 |
- {"ArchiveMaxFiles", OPT_NUM}, |
|
52 |
- {"ArchiveLimitMemoryUsage", OPT_NOARG}, |
|
53 |
- {"DataDirectory", OPT_STR}, |
|
54 |
- {"TCPSocket", OPT_NUM}, |
|
55 |
- {"LocalSocket", OPT_STR}, |
|
56 |
- {"MaxConnectionQueueLength", OPT_NUM}, |
|
57 |
- {"StreamSaveToDisk", OPT_NOARG}, |
|
58 |
- {"StreamMaxLength", OPT_COMPSIZE}, |
|
59 |
- {"MaxThreads", OPT_NUM}, |
|
60 |
- {"ThreadTimeout", OPT_NUM}, |
|
61 |
- {"MaxDirectoryRecursion", OPT_NUM}, |
|
62 |
- {"FollowDirectorySymlinks", OPT_NOARG}, |
|
63 |
- {"FollowFileSymlinks", OPT_NOARG}, |
|
64 |
- {"Foreground", OPT_NOARG}, |
|
65 |
- {"Debug", OPT_NOARG}, |
|
66 |
- {"FixStaleSocket", OPT_NOARG}, |
|
67 |
- {"User", OPT_STR}, |
|
68 |
- {"AllowSupplementaryGroups", OPT_NOARG}, |
|
69 |
- {"SelfCheck", OPT_NUM}, |
|
70 |
- {"VirusEvent", OPT_FULLSTR}, |
|
71 |
- {"ClamukoScanOnLine", OPT_NOARG}, |
|
72 |
- {"ClamukoScanOnOpen", OPT_NOARG}, |
|
73 |
- {"ClamukoScanOnClose", OPT_NOARG}, |
|
74 |
- {"ClamukoScanOnExec", OPT_NOARG}, |
|
75 |
- {"ClamukoIncludePath", OPT_STR}, |
|
76 |
- {"ClamukoExcludePath", OPT_STR}, |
|
77 |
- {"ClamukoMaxFileSize", OPT_COMPSIZE}, |
|
78 |
- {"ClamukoScanArchive", OPT_NOARG}, |
|
79 |
- {0, 0} |
|
80 |
- }; |
|
81 |
- |
|
82 |
- |
|
83 |
- if((fs = fopen(cfgfile, "r")) == NULL) { |
|
84 |
- fprintf(stderr, "ERROR: Can't open config file %s !\n", cfgfile); |
|
85 |
- return NULL; |
|
86 |
- } |
|
87 |
- |
|
88 |
- |
|
89 |
- while(fgets(buff, LINE_LENGTH, fs)) { |
|
90 |
- |
|
91 |
- line++; |
|
92 |
- |
|
93 |
- if(buff[0] == '#') |
|
94 |
- continue; |
|
95 |
- |
|
96 |
- if(!strncmp("Example", buff, 7)) { |
|
97 |
- fprintf(stderr, "ERROR: Please edit the example config file %s.\n", cfgfile); |
|
98 |
- return NULL; |
|
99 |
- } |
|
100 |
- |
|
101 |
- |
|
102 |
- if((name = tok(buff, 1))) { |
|
103 |
- arg = tok(buff, 2); |
|
104 |
- found = 0; |
|
105 |
- for(i = 0; ; i++) { |
|
106 |
- pt = &cfg_options[i]; |
|
107 |
- if(pt->name) { |
|
108 |
- if(!strcmp(name, pt->name)) { |
|
109 |
- found = 1; |
|
110 |
- switch(pt->argtype) { |
|
111 |
- case OPT_STR: |
|
112 |
- if(!arg) { |
|
113 |
- fprintf(stderr, "ERROR: Parse error at line %d: Option %s requires string as argument.\n", line, name); |
|
114 |
- return NULL; |
|
115 |
- } |
|
116 |
- copt = regcfg(copt, name, arg, 0); |
|
117 |
- break; |
|
118 |
- case OPT_FULLSTR: |
|
119 |
- if(!arg) { |
|
120 |
- fprintf(stderr, "ERROR: Parse error at line %d: Option %s requires string as argument.\n", line, name); |
|
121 |
- return NULL; |
|
122 |
- } |
|
123 |
- // FIXME: this one is an ugly hack of the above |
|
124 |
- // case |
|
125 |
- free(arg); |
|
126 |
- arg = strstr(buff, " "); |
|
127 |
- arg = strdup(++arg); |
|
128 |
- copt = regcfg(copt, name, arg, 0); |
|
129 |
- break; |
|
130 |
- case OPT_NUM: |
|
131 |
- if(!isnumb(arg)) { |
|
132 |
- fprintf(stderr, "ERROR: Parse error at line %d: Option %s requires numerical argument.\n", line, name); |
|
133 |
- return NULL; |
|
134 |
- } |
|
135 |
- copt = regcfg(copt, name, NULL, atoi(arg)); |
|
136 |
- break; |
|
137 |
- case OPT_COMPSIZE: |
|
138 |
- if(!arg) { |
|
139 |
- fprintf(stderr, "ERROR: Parse error at line %d: Option %s requires argument.\n", line, name); |
|
140 |
- return NULL; |
|
141 |
- } |
|
142 |
- ctype = tolower(arg[strlen(arg) - 1]); |
|
143 |
- if(ctype == 'm' || ctype == 'k') { |
|
144 |
- char *cpy = mcalloc(strlen(arg), sizeof(char)); |
|
145 |
- strncpy(cpy, arg, strlen(arg) - 1); |
|
146 |
- if(!isnumb(cpy)) { |
|
147 |
- fprintf(stderr, "ERROR: Parse error at line %d: Option %s requires numerical (raw/K/M) argument.\n", line, name); |
|
148 |
- return NULL; |
|
149 |
- } |
|
150 |
- if(ctype == 'm') |
|
151 |
- calc = atoi(cpy) * 1024 * 1024; |
|
152 |
- else |
|
153 |
- calc = atoi(cpy) * 1024; |
|
154 |
- free(cpy); |
|
155 |
- } else { |
|
156 |
- if(!isnumb(arg)) { |
|
157 |
- fprintf(stderr, "ERROR: Parse error at line %d: Option %s requires numerical (raw/K/M) argument.\n", line, name); |
|
158 |
- return NULL; |
|
159 |
- } |
|
160 |
- calc = atoi(arg); |
|
161 |
- } |
|
162 |
- copt = regcfg(copt, name, NULL, calc); |
|
163 |
- break; |
|
164 |
- case OPT_NOARG: |
|
165 |
- if(arg) { |
|
166 |
- fprintf(stderr, "ERROR: Parse error at line %d: Option %s doesn't support arguments.\n", line, name); |
|
167 |
- return NULL; |
|
168 |
- } |
|
169 |
- copt = regcfg(copt, name, NULL, 0); |
|
170 |
- break; |
|
171 |
- case OPT_OPTARG: |
|
172 |
- copt = regcfg(copt, name, arg, 0); |
|
173 |
- break; |
|
174 |
- } |
|
175 |
- } |
|
176 |
- } else |
|
177 |
- break; |
|
178 |
- } |
|
179 |
- |
|
180 |
- if(!found) { |
|
181 |
- fprintf(stderr, "ERROR: Parse error at line %d: Unknown option %s.\n", line, name); |
|
182 |
- return NULL; |
|
183 |
- } |
|
184 |
- } |
|
185 |
- } |
|
186 |
- |
|
187 |
- fclose(fs); |
|
188 |
- return copt; |
|
189 |
-} |
|
190 |
- |
|
191 |
-char *tok(const char *line, int field) |
|
192 |
-{ |
|
193 |
- int length, counter = 0, i, j = 0, k; |
|
194 |
- char *buffer; |
|
195 |
- |
|
196 |
- |
|
197 |
- length = strlen(line); |
|
198 |
- buffer = (char *) mcalloc(length, sizeof(char)); |
|
199 |
- |
|
200 |
- for(i = 0; i < length; i++) { |
|
201 |
- if(line[i] == ' ' || line[i] == '\n') { |
|
202 |
- counter++; |
|
203 |
- if(counter == field) |
|
204 |
- break; |
|
205 |
- |
|
206 |
- for(k = 0; k < length; k++) |
|
207 |
- buffer[k] = 0; |
|
208 |
- |
|
209 |
- j = 0; |
|
210 |
- while((line[i+1] == ' ' || line[i+1] == '\n') && i < length) |
|
211 |
- i++; |
|
212 |
- } else { |
|
213 |
- if(line[i] != ' ') { |
|
214 |
- buffer[j]=line[i]; |
|
215 |
- j++; |
|
216 |
- } |
|
217 |
- } |
|
218 |
- } |
|
219 |
- |
|
220 |
- chomp(buffer); /* preventive */ |
|
221 |
- |
|
222 |
- if(strlen(buffer) == 0) { |
|
223 |
- free(buffer); |
|
224 |
- return NULL; |
|
225 |
- } else |
|
226 |
- return realloc(buffer, strlen(buffer) + 1); |
|
227 |
-} |
|
228 |
- |
|
229 |
-struct cfgstruct *regcfg(struct cfgstruct *copt, const char *optname, const char *strarg, int numarg) |
|
230 |
-{ |
|
231 |
- struct cfgstruct *newnode, *pt; |
|
232 |
- |
|
233 |
- newnode = (struct cfgstruct *) mmalloc(sizeof(struct cfgstruct)); |
|
234 |
- newnode->optname = optname; |
|
235 |
- newnode->nextarg = NULL; |
|
236 |
- newnode->next = NULL; |
|
237 |
- |
|
238 |
- if(strarg) |
|
239 |
- newnode->strarg = strarg; |
|
240 |
- else { |
|
241 |
- newnode->strarg = NULL; |
|
242 |
- newnode->numarg = numarg; |
|
243 |
- } |
|
244 |
- |
|
245 |
- if((pt = cfgopt(copt, optname))) { |
|
246 |
- while(pt->nextarg) |
|
247 |
- pt = pt->nextarg; |
|
248 |
- |
|
249 |
- pt->nextarg = newnode; |
|
250 |
- return copt; |
|
251 |
- } else { |
|
252 |
- newnode->next = copt; |
|
253 |
- return newnode; |
|
254 |
- } |
|
255 |
-} |
|
256 |
- |
|
257 |
-struct cfgstruct *cfgopt(const struct cfgstruct *copt, const char *optname) |
|
258 |
-{ |
|
259 |
- struct cfgstruct *handler; |
|
260 |
- |
|
261 |
- handler = (struct cfgstruct *) copt; |
|
262 |
- |
|
263 |
- while(1) { |
|
264 |
- if(handler) { |
|
265 |
- if(handler->optname) |
|
266 |
- if(!strcmp(handler->optname, optname)) |
|
267 |
- return handler; |
|
268 |
- } else break; |
|
269 |
- handler = handler->next; |
|
270 |
- } |
|
271 |
- |
|
272 |
- return NULL; |
|
273 |
-} |
... | ... |
@@ -22,8 +22,6 @@ |
22 | 22 |
|
23 | 23 |
#define VIRUSDBDIR DATADIR |
24 | 24 |
|
25 |
-#define DEFAULT_CFG CONFDIR"/clamav.conf" |
|
26 |
- |
|
27 | 25 |
#define MIRROR_CFG "/mirrors.txt" |
28 | 26 |
|
29 | 27 |
#define MIRROR "/mirror" |
... | ... |
@@ -41,3 +39,5 @@ |
41 | 41 |
#else |
42 | 42 |
#define UNPGROUP "clamav" |
43 | 43 |
#endif |
44 |
+ |
|
45 |
+#define CL_DEFAULT_CHECKS 6 |
... | ... |
@@ -42,18 +42,36 @@ |
42 | 42 |
int freshclam(struct optstruct *opt) |
43 | 43 |
{ |
44 | 44 |
int ret; |
45 |
- char *newdir; |
|
45 |
+ char *newdir, *cfgfile; |
|
46 |
+ struct cfgstruct *copt, *cpt; |
|
46 | 47 |
#ifndef C_CYGWIN |
47 |
- struct passwd *user; |
|
48 | 48 |
char *unpuser; |
49 |
+ struct passwd *user; |
|
50 |
+#endif |
|
49 | 51 |
|
50 |
- if(optc(opt, 'u')) |
|
51 |
- unpuser = getargc(opt, 'u'); |
|
52 |
- else |
|
53 |
- unpuser = UNPUSER; |
|
54 | 52 |
|
53 |
+ /* parse the config file */ |
|
54 |
+ if((cfgfile = getargc(opt, 'c'))) { |
|
55 |
+ copt = parsecfg(cfgfile); |
|
56 |
+ } else { |
|
57 |
+ /* TODO: force strict permissions on freshclam.conf */ |
|
58 |
+ if((copt = parsecfg((cfgfile = CONFDIR"/freshclam.conf"))) == NULL) |
|
59 |
+ copt = parsecfg((cfgfile = CONFDIR"/clamav.conf")); |
|
60 |
+ } |
|
61 |
+ |
|
62 |
+ if(!copt) { |
|
63 |
+ mprintf("!Can't parse the config file %s\n", cfgfile); |
|
64 |
+ return 56; |
|
65 |
+ } |
|
66 |
+ |
|
67 |
+#ifndef C_CYGWIN |
|
55 | 68 |
/* freshclam shouldn't work with root priviledges */ |
56 |
- if(!getuid()) { |
|
69 |
+ if((cpt = cfgopt(copt, "DatabaseOwner")) == NULL) |
|
70 |
+ unpuser = UNPUSER; |
|
71 |
+ else |
|
72 |
+ unpuser = cpt->strarg; |
|
73 |
+ |
|
74 |
+ if(!getuid()) { |
|
57 | 75 |
if((user = getpwnam(unpuser)) == NULL) { |
58 | 76 |
mprintf("@Can't get information about user %s.\n", unpuser); |
59 | 77 |
exit(60); /* this is critical problem, so we just exit here */ |
... | ... |
@@ -67,7 +85,7 @@ int freshclam(struct optstruct *opt) |
67 | 67 |
|
68 | 68 |
/* initialize some important variables */ |
69 | 69 |
|
70 |
- if(optl(opt, "debug")) |
|
70 |
+ if(optl(opt, "debug") || cfgopt(copt, "Debug")) |
|
71 | 71 |
cl_debug(); |
72 | 72 |
|
73 | 73 |
mprintf_disabled = 0; |
... | ... |
@@ -93,23 +111,29 @@ int freshclam(struct optstruct *opt) |
93 | 93 |
|
94 | 94 |
/* initialize logger */ |
95 | 95 |
|
96 |
- if(optl(opt, "log-verbose")) logverbose = 1; |
|
97 |
- else logverbose = 0; |
|
96 |
+ if(optl(opt, "log-verbose") || cfgopt(copt, "LogVerbose")) |
|
97 |
+ logverbose = 1; |
|
98 |
+ else |
|
99 |
+ logverbose = 0; |
|
98 | 100 |
|
99 |
- if(optc(opt, 'l')) { |
|
100 |
- logfile = getargc(opt, 'l'); |
|
101 |
+ if((cpt = cfgopt(copt, "UpdateLogFile"))) { |
|
102 |
+ logfile = cpt->strarg; |
|
101 | 103 |
if(logg("--------------------------------------\n")) { |
102 | 104 |
mprintf("!Problem with internal logger.\n"); |
103 | 105 |
mexit(1); |
104 | 106 |
} |
105 |
- } else |
|
107 |
+ } else |
|
106 | 108 |
logfile = NULL; |
107 | 109 |
|
108 |
- /* change current working directory */ |
|
109 |
- if(optl(opt, "datadir")) |
|
110 |
+ /* change the current working directory */ |
|
111 |
+ if(optl(opt, "datadir")) { |
|
110 | 112 |
newdir = getargl(opt, "datadir"); |
111 |
- else |
|
112 |
- newdir = VIRUSDBDIR; |
|
113 |
+ } else { |
|
114 |
+ if((cpt = cfgopt(copt, "DatabaseDirectory"))) |
|
115 |
+ newdir = cpt->strarg; |
|
116 |
+ else |
|
117 |
+ newdir = VIRUSDBDIR; |
|
118 |
+ } |
|
113 | 119 |
|
114 | 120 |
if(chdir(newdir)) { |
115 | 121 |
mprintf("Can't change dir to %s\n", newdir); |
... | ... |
@@ -121,38 +145,36 @@ int freshclam(struct optstruct *opt) |
121 | 121 |
if(optc(opt, 'd')) { |
122 | 122 |
int bigsleep, checks; |
123 | 123 |
|
124 |
- if(!optc(opt, 'c')) { |
|
125 |
- mprintf("@Daemon mode requires -c (--checks) option.\n"); |
|
126 |
- mexit(40); |
|
127 |
- } |
|
128 |
- |
|
129 |
- checks = atoi(getargc(opt, 'c')); |
|
124 |
+ if((cpt = cfgopt(copt, "Checks"))) |
|
125 |
+ checks = cpt->numarg; |
|
126 |
+ else |
|
127 |
+ checks = CL_DEFAULT_CHECKS; |
|
130 | 128 |
|
131 | 129 |
if(checks <= 0 || checks > 50) { |
132 |
- mprintf("@Wrong number of checks\n"); |
|
130 |
+ mprintf("@Number of checks must be between 1 and 50.\n"); |
|
133 | 131 |
mexit(41); |
134 | 132 |
} |
135 | 133 |
|
136 |
- bigsleep = 24*3600 / checks; |
|
134 |
+ bigsleep = 24 * 3600 / checks; |
|
137 | 135 |
daemonize(); |
138 | 136 |
|
139 | 137 |
while(1) { |
140 |
- ret = download(opt); |
|
138 |
+ ret = download(copt); |
|
141 | 139 |
|
142 |
- if(optl(opt, "on-error-execute")) |
|
140 |
+ if((cpt = cfgopt(copt, "OnErrorExecute"))) |
|
143 | 141 |
if(ret > 1) |
144 |
- system(getargl(opt, "on-error-execute")); |
|
142 |
+ system(cpt->strarg); |
|
145 | 143 |
|
146 | 144 |
logg("\n--------------------------------------\n"); |
147 | 145 |
sleep(bigsleep); |
148 | 146 |
} |
149 | 147 |
|
150 | 148 |
} else |
151 |
- ret = download(opt); |
|
149 |
+ ret = download(copt); |
|
152 | 150 |
|
153 |
- if(optl(opt, "on-error-execute")) |
|
151 |
+ if((cpt = cfgopt(copt, "OnErrorExecute"))) |
|
154 | 152 |
if(ret > 1) |
155 |
- system(getargl(opt, "on-error-execute")); |
|
153 |
+ system(cpt->strarg); |
|
156 | 154 |
|
157 | 155 |
return(ret); |
158 | 156 |
} |
... | ... |
@@ -163,151 +185,54 @@ void d_timeout(int sig) |
163 | 163 |
exit(1); |
164 | 164 |
} |
165 | 165 |
|
166 |
-int download(struct optstruct *opt) |
|
166 |
+int download(const struct cfgstruct *copt) |
|
167 | 167 |
{ |
168 |
- int ret = 0; |
|
169 |
- mirrors *m = NULL, *h = NULL; |
|
170 |
- int mirror_used = 0; |
|
168 |
+ int ret = 0, try = 0, maxattempts = 0; |
|
171 | 169 |
struct sigaction sigalrm; |
170 |
+ struct cfgstruct *cpt; |
|
172 | 171 |
|
173 | 172 |
memset(&sigalrm, 0, sizeof(struct sigaction)); |
174 | 173 |
sigalrm.sa_handler = d_timeout; |
175 | 174 |
sigaction(SIGALRM, &sigalrm, NULL); |
176 | 175 |
|
177 |
- /* |
|
178 |
- * There's an error in __nss_hostname_digits_dots () from /lib/libc.so.6 |
|
179 |
- * which gets triggered here for some reason..... |
|
180 |
- * Calling fflush is a temp workaround |
|
181 |
- */ |
|
182 |
- fflush(NULL); |
|
183 |
- |
|
184 |
- h = m = parse_mirrorcfg(opt); |
|
185 |
- |
|
186 |
- while(m != NULL) |
|
187 |
- { |
|
188 |
- alarm(TIMEOUT); |
|
189 |
- ret = downloadmanager(opt, m->mirror); |
|
190 |
- alarm(0); |
|
191 |
- |
|
192 |
- if(ret == 0) |
|
193 |
- { |
|
194 |
- if(mirror_used) |
|
195 |
- { |
|
196 |
- logg("Database updated from mirror %s.\n", m->mirror); |
|
197 |
- mprintf("Database updated from mirror %s.\n", m->mirror); |
|
198 |
- } |
|
199 |
- |
|
200 |
- FREE_MIRROR(h); |
|
201 |
- return ret; |
|
202 |
- } |
|
203 |
- |
|
204 |
- /* Only continue if there is an error connecting to the host */ |
|
205 |
- if((ret != 52) && (ret != 54)) |
|
206 |
- { |
|
207 |
- FREE_MIRROR(h); |
|
208 |
- return ret; |
|
209 |
- } |
|
210 |
- |
|
211 |
- mprintf("Waiting 10 seconds...\n"); |
|
212 |
- sleep(10); |
|
213 |
- mirror_used++; |
|
214 |
- m = m->next; |
|
176 |
+ if((cpt = cfgopt(copt, "MaxAttempts"))) |
|
177 |
+ maxattempts = cpt->numarg; |
|
178 |
+ |
|
179 |
+ mprintf("*Max retries == %d\n", maxattempts); |
|
180 |
+ |
|
181 |
+ if((cpt = cfgopt(copt, "DatabaseMirror")) == NULL) { |
|
182 |
+ mprintf("@You must specify at least one database mirror.\n"); |
|
183 |
+ return 57; |
|
184 |
+ } else { |
|
185 |
+ |
|
186 |
+ while(cpt) { |
|
187 |
+ alarm(TIMEOUT); |
|
188 |
+ ret = downloadmanager(copt, cpt->strarg); |
|
189 |
+ alarm(0); |
|
190 |
+ |
|
191 |
+ if(ret == 52 || ret == 54) { |
|
192 |
+ if(try < maxattempts - 1) { |
|
193 |
+ mprintf("Trying again...\n"); |
|
194 |
+ logg("Trying again...\n"); |
|
195 |
+ try++; |
|
196 |
+ sleep(1); |
|
197 |
+ continue; |
|
198 |
+ } else { |
|
199 |
+ mprintf("Giving up...\n"); |
|
200 |
+ logg("Giving up...\n"); |
|
201 |
+ cpt = (struct cfgstruct *) cpt->nextarg; |
|
202 |
+ try = 0; |
|
203 |
+ } |
|
204 |
+ |
|
205 |
+ } else { |
|
206 |
+ return ret; |
|
207 |
+ } |
|
208 |
+ } |
|
215 | 209 |
} |
216 | 210 |
|
217 |
- FREE_MIRROR(h); |
|
218 | 211 |
return ret; |
219 | 212 |
} |
220 | 213 |
|
221 |
-mirrors* parse_mirrorcfg(struct optstruct *opt) |
|
222 |
-{ |
|
223 |
- mirrors *head = NULL, *curr = NULL, *prev = NULL; |
|
224 |
- char *datadir = NULL, *mirrorcfg = NULL; |
|
225 |
- FILE *fd = NULL; |
|
226 |
- char buf[BUFSIZ]; |
|
227 |
- int hosts_found = 0; |
|
228 |
- |
|
229 |
- if(optl(opt, "datadir")) |
|
230 |
- { |
|
231 |
- datadir = getargl(opt, "datadir"); |
|
232 |
- } |
|
233 |
- else |
|
234 |
- { |
|
235 |
- datadir = DATADIR; |
|
236 |
- } |
|
237 |
- |
|
238 |
- if((mirrorcfg = malloc(sizeof(char) * (strlen(datadir) + strlen(MIRROR_CFG) + 1))) == NULL) |
|
239 |
- { |
|
240 |
- fprintf(stderr, "ERROR: Can't allocate sufficient memory\n"); |
|
241 |
- mexit(1); |
|
242 |
- } |
|
243 |
- |
|
244 |
- strcpy(mirrorcfg, datadir); |
|
245 |
- |
|
246 |
- strcat(mirrorcfg, MIRROR_CFG); |
|
247 |
- |
|
248 |
- if((fd = fopen(mirrorcfg, "r")) == NULL) |
|
249 |
- { |
|
250 |
- fprintf(stderr, "ERROR: Can't open mirror configuration file %s !\n", mirrorcfg); |
|
251 |
- free(mirrorcfg); |
|
252 |
- mexit(1); |
|
253 |
- } |
|
254 |
- |
|
255 |
- while(fgets(buf, BUFSIZ, fd)) |
|
256 |
- { |
|
257 |
- if(buf[0] == '#') |
|
258 |
- continue; |
|
259 |
- |
|
260 |
- if(strlen(buf) > 1) |
|
261 |
- { |
|
262 |
- if((curr = malloc(sizeof(struct _mirrors))) == NULL) |
|
263 |
- { |
|
264 |
- fprintf(stderr, "ERROR: Can't allocate sufficient memory\n"); |
|
265 |
- free(mirrorcfg); |
|
266 |
- FREE_MIRROR(head); |
|
267 |
- return NULL; |
|
268 |
- } |
|
269 |
- |
|
270 |
- curr->mirror = NULL; |
|
271 |
- curr->next = NULL; |
|
272 |
- |
|
273 |
- if(head == NULL) |
|
274 |
- head = curr; |
|
275 |
- |
|
276 |
- if(prev != NULL) |
|
277 |
- prev->next = curr; |
|
278 |
- |
|
279 |
- if((curr->mirror = malloc(sizeof(char) * (strlen(buf) +1))) == NULL) |
|
280 |
- { |
|
281 |
- fprintf(stderr, "ERROR: Can't allocate sufficient memory\n"); |
|
282 |
- free(mirrorcfg); |
|
283 |
- FREE_MIRROR(head); |
|
284 |
- return NULL; |
|
285 |
- } |
|
286 |
- |
|
287 |
- chomp(buf); |
|
288 |
- strcpy(curr->mirror, buf); |
|
289 |
- prev = curr; |
|
290 |
- hosts_found++; |
|
291 |
- } |
|
292 |
- } |
|
293 |
- |
|
294 |
- if(fclose(fd) != 0) |
|
295 |
- { |
|
296 |
- fprintf(stderr, "ERROR: Can't close fd !\n"); |
|
297 |
- } |
|
298 |
- |
|
299 |
- if(hosts_found == 0) |
|
300 |
- { |
|
301 |
- fprintf(stderr, "ERROR: No hosts defined in %s !\n", mirrorcfg); |
|
302 |
- FREE_MIRROR(head); |
|
303 |
- free(mirrorcfg); |
|
304 |
- mexit(1); |
|
305 |
- } |
|
306 |
- |
|
307 |
- free(mirrorcfg); |
|
308 |
- return head; |
|
309 |
-} |
|
310 |
- |
|
311 | 214 |
void daemonize(void) |
312 | 215 |
{ |
313 | 216 |
int i; |
... | ... |
@@ -331,7 +256,7 @@ void help(void) |
331 | 331 |
|
332 | 332 |
mprintf("\n"); |
333 | 333 |
mprintf(" Clam AntiVirus: freshclam "VERSION"\n"); |
334 |
- mprintf(" (c) 2002, 2003 Tomasz Kojm <zolw@konarski.edu.pl>\n\n"); |
|
334 |
+ mprintf(" (c) 2002, 2003 Tomasz Kojm <tkojm@clamav.net>\n\n"); |
|
335 | 335 |
|
336 | 336 |
mprintf(" --help -h show help\n"); |
337 | 337 |
mprintf(" --version -V print version number and exit\n"); |
... | ... |
@@ -341,19 +266,8 @@ void help(void) |
341 | 341 |
mprintf(" --stdout write to stdout instead of stderr\n"); |
342 | 342 |
mprintf(" (this help is always written to stdout)\n"); |
343 | 343 |
mprintf("\n"); |
344 |
- mprintf(" --user=USER -u USER run as USER\n"); |
|
345 | 344 |
mprintf(" --daemon -d run in daemon mode\n"); |
346 |
- mprintf(" --checks=#n -c #n #n checks by day, 1 <= n <= 50\n"); |
|
347 |
- mprintf(" --datadir=DIRECTORY download new database in DIRECTORY\n"); |
|
348 |
- mprintf(" --log=FILE -l FILE save download report in FILE\n"); |
|
349 |
- mprintf(" --log-verbose save additional informations\n"); |
|
350 |
- mprintf(" --http-proxy=hostname[:port] use proxy server hostname\n"); |
|
351 |
- mprintf(" --proxy-user=username:passwd use username/password for proxy auth\n"); |
|
352 |
-#ifdef BUILD_CLAMD |
|
353 |
- mprintf(" --daemon-notify[=/path/clamav.conf] send RELOAD command to clamd\n"); |
|
354 |
-#endif |
|
355 |
- mprintf(" --on-update-execute=COMMAND execute COMMAND after successful update\n"); |
|
356 |
- mprintf(" --on-error-execute=COMMAND execute COMMAND if errors occured\n"); |
|
345 |
+ mprintf(" --datadir=DIRECTORY download new databases into DIRECTORY\n"); |
|
357 | 346 |
mprintf("\n"); |
358 | 347 |
exit(0); |
359 | 348 |
} |
... | ... |
@@ -19,34 +19,12 @@ |
19 | 19 |
#ifndef __FRESHCLAM_H |
20 | 20 |
#define __FRESHCLAM_H |
21 | 21 |
|
22 |
-typedef struct _mirrors mirrors; |
|
23 |
- |
|
24 |
-struct _mirrors { |
|
25 |
- |
|
26 |
- char * mirror; |
|
27 |
- mirrors *next; |
|
28 |
-}; |
|
22 |
+#include "cfgfile.h" |
|
29 | 23 |
|
30 | 24 |
void help(void); |
31 | 25 |
void daemonize(void); |
32 |
-int download(struct optstruct *opt); |
|
33 |
-char * parse_mirror(struct optstruct *opt); |
|
34 |
-mirrors* parse_mirrorcfg(struct optstruct *opt); |
|
35 |
-void write_mirror(struct optstruct *opt, char *mirror); |
|
26 |
+int download(const struct cfgstruct *copt); |
|
36 | 27 |
|
37 | 28 |
#define mexit(i) exit(i) |
38 | 29 |
|
39 |
-mirrors *n; |
|
40 |
-#define FREE_MIRROR(m) \ |
|
41 |
-while(m) \ |
|
42 |
-{ \ |
|
43 |
- n = m->next; \ |
|
44 |
- if(m->mirror != NULL) \ |
|
45 |
- { \ |
|
46 |
- free(m->mirror); \ |
|
47 |
- } \ |
|
48 |
- free(m); \ |
|
49 |
- m = n; \ |
|
50 |
-} |
|
51 |
- |
|
52 | 30 |
#endif |
... | ... |
@@ -42,11 +42,12 @@ |
42 | 42 |
#include "shared.h" |
43 | 43 |
#include "notify.h" |
44 | 44 |
|
45 |
-int downloadmanager(const struct optstruct *opt, const char *hostname) |
|
45 |
+int downloadmanager(const struct cfgstruct *copt, const char *hostname) |
|
46 | 46 |
{ |
47 | 47 |
time_t currtime; |
48 | 48 |
int ret, updated = 0, signo = 0; |
49 | 49 |
char ipaddr[16]; |
50 |
+ struct cfgstruct *cpt; |
|
50 | 51 |
|
51 | 52 |
|
52 | 53 |
time(&currtime); |
... | ... |
@@ -60,19 +61,19 @@ int downloadmanager(const struct optstruct *opt, const char *hostname) |
60 | 60 |
|
61 | 61 |
memset(ipaddr, 0, sizeof(ipaddr)); |
62 | 62 |
|
63 |
- if((ret = downloaddb(DB1NAME, "main.cvd", hostname, ipaddr, &signo, opt)) > 50) |
|
63 |
+ if((ret = downloaddb(DB1NAME, "main.cvd", hostname, ipaddr, &signo, copt)) > 50) |
|
64 | 64 |
return ret; |
65 | 65 |
else if(ret == 0) |
66 | 66 |
updated = 1; |
67 | 67 |
|
68 | 68 |
/* if ipaddr[0] != 0 it will use it to connect to the web host */ |
69 |
- if((ret = downloaddb(DB2NAME, "daily.cvd", hostname, ipaddr, &signo, opt)) > 50) |
|
69 |
+ if((ret = downloaddb(DB2NAME, "daily.cvd", hostname, ipaddr, &signo, copt)) > 50) |
|
70 | 70 |
return ret; |
71 | 71 |
else if(ret == 0) |
72 | 72 |
updated = 1; |
73 | 73 |
|
74 | 74 |
if(updated) { |
75 |
- if(optl(opt, "http-proxy")) { |
|
75 |
+ if(cfgopt(copt, "HTTPProxyServer")) { |
|
76 | 76 |
mprintf("Database updated (%d signatures) from %s.\n", signo, hostname); |
77 | 77 |
logg("Database updated (%d signatures) from %s.\n", signo, hostname); |
78 | 78 |
} else { |
... | ... |
@@ -81,17 +82,17 @@ int downloadmanager(const struct optstruct *opt, const char *hostname) |
81 | 81 |
} |
82 | 82 |
|
83 | 83 |
#ifdef BUILD_CLAMD |
84 |
- if(optl(opt, "daemon-notify")) { |
|
85 |
- const char *clamav_conf = getargl(opt, "daemon-notify"); |
|
84 |
+ if((cpt = cfgopt(copt, "NotifyClamd"))) { |
|
85 |
+ const char *clamav_conf = cpt->strarg; |
|
86 | 86 |
if(!clamav_conf) |
87 |
- clamav_conf = DEFAULT_CFG; |
|
87 |
+ clamav_conf = CONFDIR"/clamav.conf"; |
|
88 | 88 |
|
89 | 89 |
notify(clamav_conf); |
90 | 90 |
} |
91 | 91 |
#endif |
92 | 92 |
|
93 |
- if(optl(opt, "on-update-execute")) |
|
94 |
- system(getargl(opt, "on-update-execute")); |
|
93 |
+ if((cpt = cfgopt(copt, "OnUpdateExecute"))) |
|
94 |
+ system(cpt->strarg); |
|
95 | 95 |
|
96 | 96 |
return 0; |
97 | 97 |
|
... | ... |
@@ -99,53 +100,46 @@ int downloadmanager(const struct optstruct *opt, const char *hostname) |
99 | 99 |
return 1; |
100 | 100 |
} |
101 | 101 |
|
102 |
-int downloaddb(const char *localname, const char *remotename, const char *hostname, char *ip, int *signo, const struct optstruct *opt) |
|
102 |
+int downloaddb(const char *localname, const char *remotename, const char *hostname, char *ip, int *signo, const struct cfgstruct *copt) |
|
103 | 103 |
{ |
104 | 104 |
struct cl_cvd *current, *remote; |
105 |
- int hostfd, nodb = 0, ret; |
|
105 |
+ struct cfgstruct *cpt; |
|
106 |
+ int hostfd, nodb = 0, ret, port = 0; |
|
106 | 107 |
char *tempname, ipaddr[16]; |
107 |
- const char *proxy, *user; |
|
108 |
+ const char *proxy = NULL, *user = NULL, *pass = NULL; |
|
108 | 109 |
|
109 | 110 |
|
110 | 111 |
if((current = cl_cvdhead(localname)) == NULL) |
111 | 112 |
nodb = 1; |
112 | 113 |
|
113 |
- if(optl(opt, "proxy-user")) |
|
114 |
- user = getargl(opt, "proxy-user"); |
|
115 |
- else |
|
116 |
- user = NULL; |
|
114 |
+ if((cpt = cfgopt(copt, "HTTPProxyUsername"))) { |
|
115 |
+ user = cpt->strarg; |
|
116 |
+ |
|
117 |
+ if((cpt = cfgopt(copt, "HTTPProxyPassword"))) { |
|
118 |
+ pass = cpt->strarg; |
|
119 |
+ } else { |
|
120 |
+ mprintf("HTTPProxyUsername required HTTPProxyPassword\n"); |
|
121 |
+ return 57; |
|
122 |
+ } |
|
123 |
+ } |
|
117 | 124 |
|
118 | 125 |
/* |
119 | 126 |
* njh@bandsman.co.uk: added proxy support. Tested using squid 2.4 |
120 | 127 |
*/ |
121 |
- if(optl(opt, "http-proxy")) { |
|
122 |
- proxy = getargl(opt, "http-proxy"); |
|
128 |
+ if((cpt = cfgopt(copt, "HTTPProxyServer"))) { |
|
129 |
+ proxy = cpt->strarg; |
|
123 | 130 |
if(strncasecmp(proxy, "http://", 7) == 0) |
124 | 131 |
proxy += 7; |
125 |
- } else if((proxy = getenv("http_proxy"))) { |
|
126 |
- char *no_proxy; |
|
127 |
- |
|
128 |
- if(strncasecmp(proxy, "http://", 7) == 0) |
|
129 |
- proxy = &proxy[7]; |
|
130 |
- |
|
131 |
- if((no_proxy = getenv("no_proxy"))) { |
|
132 |
- const char *ptr; |
|
133 |
- for(ptr = strtok(no_proxy, ","); ptr; ptr = strtok(NULL, ",")) |
|
134 |
- if(strcasecmp(ptr, hostname) == 0) { |
|
135 |
- proxy = NULL; |
|
136 |
- break; |
|
137 |
- } |
|
138 |
- } |
|
139 |
- if(proxy && strlen(proxy) == 0) |
|
140 |
- proxy = NULL; |
|
141 |
- } |
|
142 |
- if(proxy) |
|
143 | 132 |
mprintf("Connecting via %s\n", proxy); |
133 |
+ } |
|
134 |
+ |
|
135 |
+ if((cpt = cfgopt(copt, "HTTPProxyPort"))) |
|
136 |
+ port = cpt->numarg; |
|
144 | 137 |
|
145 | 138 |
if(ip[0]) |
146 |
- hostfd = wwwconnect(ip, proxy, ipaddr); /* we use ip to connect */ |
|
139 |
+ hostfd = wwwconnect(ip, proxy, port, ipaddr); /* we use ip to connect */ |
|
147 | 140 |
else |
148 |
- hostfd = wwwconnect(hostname, proxy, ipaddr); |
|
141 |
+ hostfd = wwwconnect(hostname, proxy, port, ipaddr); |
|
149 | 142 |
|
150 | 143 |
if(hostfd < 0) { |
151 | 144 |
mprintf("@Connection with %s (IP: %s) failed.\n", hostname, ipaddr); |
... | ... |
@@ -156,7 +150,7 @@ int downloaddb(const char *localname, const char *remotename, const char *hostna |
156 | 156 |
if(!ip[0]) |
157 | 157 |
strcpy(ip, ipaddr); |
158 | 158 |
|
159 |
- if(!(remote = remote_cvdhead(remotename, hostfd, hostname, proxy, user))) { |
|
159 |
+ if(!(remote = remote_cvdhead(remotename, hostfd, hostname, proxy, user, pass))) { |
|
160 | 160 |
mprintf("@Can't read %s header from %s (%s)\n", remotename, hostname, ipaddr); |
161 | 161 |
close(hostfd); |
162 | 162 |
return 52; |
... | ... |
@@ -184,7 +178,7 @@ int downloaddb(const char *localname, const char *remotename, const char *hostna |
184 | 184 |
*/ |
185 | 185 |
/* begin bug work-around */ |
186 | 186 |
close(hostfd); |
187 |
- hostfd = wwwconnect(ipaddr, proxy, NULL); /* we use ipaddr to connect |
|
187 |
+ hostfd = wwwconnect(ipaddr, proxy, port, NULL); /* we use ipaddr to connect |
|
188 | 188 |
* to the same mirror |
189 | 189 |
*/ |
190 | 190 |
|
... | ... |
@@ -199,7 +193,7 @@ int downloaddb(const char *localname, const char *remotename, const char *hostna |
199 | 199 |
*/ |
200 | 200 |
tempname = cl_gentemp("."); |
201 | 201 |
|
202 |
- if(get_database(remotename, hostfd, tempname, hostname, proxy, user)) { |
|
202 |
+ if(get_database(remotename, hostfd, tempname, hostname, proxy, user, pass)) { |
|
203 | 203 |
mprintf("@Can't download %s from %s\n", remotename, ipaddr); |
204 | 204 |
unlink(tempname); |
205 | 205 |
free(tempname); |
... | ... |
@@ -239,7 +233,7 @@ int downloaddb(const char *localname, const char *remotename, const char *hostna |
239 | 239 |
|
240 | 240 |
/* this function returns socket descriptor */ |
241 | 241 |
/* proxy support finshed by njh@bandsman.co.uk */ |
242 |
-int wwwconnect(const char *server, const char *proxy, char *ip) |
|
242 |
+int wwwconnect(const char *server, const char *proxy, int pport, char *ip) |
|
243 | 243 |
{ |
244 | 244 |
int socketfd, port; |
245 | 245 |
struct sockaddr_in name; |
... | ... |
@@ -262,13 +256,9 @@ int wwwconnect(const char *server, const char *proxy, char *ip) |
262 | 262 |
name.sin_family = AF_INET; |
263 | 263 |
|
264 | 264 |
if(proxy) { |
265 |
- proxycpy = strdup(proxy); |
|
266 |
- hostpt = proxycpy; |
|
267 |
- portpt = strchr(proxycpy, ':'); |
|
268 |
- if(portpt) { |
|
269 |
- *portpt = 0; |
|
270 |
- port = atoi(++portpt); |
|
271 |
- } else { |
|
265 |
+ hostpt = proxy; |
|
266 |
+ |
|
267 |
+ if(!(port = pport)) { |
|
272 | 268 |
#ifndef C_CYGWIN |
273 | 269 |
const struct servent *webcache = getservbyname("webcache", "TCP"); |
274 | 270 |
|
... | ... |
@@ -282,6 +272,7 @@ int wwwconnect(const char *server, const char *proxy, char *ip) |
282 | 282 |
port = 8080; |
283 | 283 |
#endif |
284 | 284 |
} |
285 |
+ |
|
285 | 286 |
} else { |
286 | 287 |
hostpt = server; |
287 | 288 |
port = 80; |
... | ... |
@@ -289,8 +280,6 @@ int wwwconnect(const char *server, const char *proxy, char *ip) |
289 | 289 |
|
290 | 290 |
if((host = gethostbyname(hostpt)) == NULL) { |
291 | 291 |
mprintf("@Can't get information about %s host.\n", hostpt); |
292 |
- if(proxycpy) |
|
293 |
- free(proxycpy); |
|
294 | 292 |
return -1; |
295 | 293 |
} |
296 | 294 |
|
... | ... |
@@ -307,21 +296,17 @@ int wwwconnect(const char *server, const char *proxy, char *ip) |
307 | 307 |
if(connect(socketfd, (struct sockaddr *) &name, sizeof(struct sockaddr_in)) == -1) { |
308 | 308 |
mprintf("@Can't connect to port %d of host %s (%s)\n", port, hostpt, ipaddr); |
309 | 309 |
close(socketfd); |
310 |
- if(proxycpy) |
|
311 |
- free(proxycpy); |
|
312 | 310 |
return -2; |
313 | 311 |
} |
314 | 312 |
|
315 |
- if(proxycpy) |
|
316 |
- free(proxycpy); |
|
317 | 313 |
return socketfd; |
318 | 314 |
} |
319 | 315 |
|
320 | 316 |
/* njh@bandsman.co.uk: added proxy support */ |
321 | 317 |
/* TODO: use a HEAD instruction to see if the file has been changed */ |
322 |
-struct cl_cvd *remote_cvdhead(const char *file, int socketfd, const char *hostname, const char *proxy, const char *user) |
|
318 |
+struct cl_cvd *remote_cvdhead(const char *file, int socketfd, const char *hostname, const char *proxy, const char *user, const char *pass) |
|
323 | 319 |
{ |
324 |
- char cmd[512], head[513], buffer[FILEBUFF], *ch, *tmp; |
|
320 |
+ char cmd[512], head[513], buffer[FILEBUFF], *ch, *tmp, *userpass; |
|
325 | 321 |
int i, j, bread, cnt; |
326 | 322 |
char *remotename = NULL, *authorization = NULL; |
327 | 323 |
struct cl_cvd *cvd; |
... | ... |
@@ -332,13 +317,16 @@ struct cl_cvd *remote_cvdhead(const char *file, int socketfd, const char *hostna |
332 | 332 |
|
333 | 333 |
if(user) { |
334 | 334 |
int len; |
335 |
- char* buf = mmalloc(strlen(user)*2+4); |
|
336 |
- len=fmt_base64(buf,user,strlen(user)); |
|
335 |
+ char* buf = mmalloc(strlen(user)*2+4); |
|
336 |
+ char *userpass = mmalloc(strlen(user) + strlen(pass) + 2); |
|
337 |
+ sprintf(userpass, "%s:%s", user, pass); |
|
338 |
+ len=fmt_base64(buf,userpass,strlen(userpass)); |
|
339 |
+ free(userpass); |
|
337 | 340 |
buf[len]='\0'; |
338 | 341 |
authorization = mmalloc(strlen(buf) + 30); |
339 | 342 |
sprintf(authorization, "Proxy-Authorization: Basic %s\r\n", buf); |
340 | 343 |
free(buf); |
341 |
- } |
|
344 |
+ } |
|
342 | 345 |
} |
343 | 346 |
|
344 | 347 |
mprintf("Reading CVD header (%s): ", file); |
... | ... |
@@ -413,11 +401,9 @@ struct cl_cvd *remote_cvdhead(const char *file, int socketfd, const char *hostna |
413 | 413 |
|
414 | 414 |
/* njh@bandsman.co.uk: added proxy support */ |
415 | 415 |
/* TODO: use a HEAD instruction to see if the file has been changed */ |
416 |
-int |
|
417 |
-get_database(const char *dbfile, int socketfd, const char *file, const char *hostname, const char *proxy, const char *user) |
|
416 |
+int get_database(const char *dbfile, int socketfd, const char *file, const char *hostname, const char *proxy, const char *user, const char *pass) |
|
418 | 417 |
{ |
419 |
- char cmd[512], buffer[FILEBUFF]; |
|
420 |
- char *ch; |
|
418 |
+ char cmd[512], buffer[FILEBUFF], *ch; |
|
421 | 419 |
int bread, fd, i, rot = 0; |
422 | 420 |
char *remotename = NULL, *authorization = NULL; |
423 | 421 |
const char *rotation = "|/-\\"; |
... | ... |
@@ -430,7 +416,10 @@ get_database(const char *dbfile, int socketfd, const char *file, const char *hos |
430 | 430 |
if(user) { |
431 | 431 |
int len; |
432 | 432 |
char* buf = mmalloc(strlen(user)*2+4); |
433 |
- len=fmt_base64(buf,user,strlen(user)); |
|
433 |
+ char *userpass = mmalloc(strlen(user) + strlen(pass) + 2); |
|
434 |
+ sprintf(userpass, "%s:%s", user, pass); |
|
435 |
+ len=fmt_base64(buf,userpass,strlen(userpass)); |
|
436 |
+ free(userpass); |
|
434 | 437 |
buf[len]='\0'; |
435 | 438 |
authorization = mmalloc(strlen(buf) + 30); |
436 | 439 |
sprintf(authorization, "Proxy-Authorization: Basic %s\r\n", buf); |
... | ... |
@@ -19,18 +19,18 @@ |
19 | 19 |
#ifndef __MANAGER_H |
20 | 20 |
#define __MANAGER_H |
21 | 21 |
|
22 |
-#include "options.h" |
|
22 |
+#include "cfgfile.h" |
|
23 | 23 |
#include "clamav.h" |
24 | 24 |
|
25 |
-int downloadmanager(const struct optstruct *opt, const char *hostname); |
|
25 |
+int downloadmanager(const struct cfgstruct *copt, const char *hostname); |
|
26 | 26 |
|
27 |
-int downloaddb(const char *localname, const char *remotename, const char *hostname, char *ip, int *signo, const struct optstruct *opt); |
|
27 |
+int downloaddb(const char *localname, const char *remotename, const char *hostname, char *ip, int *signo, const struct cfgstruct *copt); |
|
28 | 28 |
|
29 |
-int wwwconnect(const char *server, const char *proxy, char *ip); |
|
29 |
+int wwwconnect(const char *server, const char *proxy, int pport, char *ip); |
|
30 | 30 |
|
31 |
-struct cl_cvd *remote_cvdhead(const char *file, int socketfd, const char *hostname, const char *proxy, const char *user); |
|
31 |
+struct cl_cvd *remote_cvdhead(const char *file, int socketfd, const char *hostname, const char *proxy, const char *user, const char *pass); |
|
32 | 32 |
|
33 |
-int get_database(const char *dbfile, int socketfd, const char *file, const char *hostname, const char *proxy, const char *user); |
|
33 |
+int get_database(const char *dbfile, int socketfd, const char *file, const char *hostname, const char *proxy, const char *user, const char *pass); |
|
34 | 34 |
|
35 | 35 |
unsigned int fmt_base64(char* dest,const char* src,unsigned int len); |
36 | 36 |
|
... | ... |
@@ -47,7 +47,8 @@ int main(int argc, char **argv) |
47 | 47 |
{"log-verbose", 0, 0, 0}, |
48 | 48 |
{"stdout", 0, 0, 0}, |
49 | 49 |
{"daemon", 0, 0, 'd'}, |
50 |
- {"user", 1, 0, 'u'}, |
|
50 |
+ {"user", 1, 0, 'u'}, /* not used */ |
|
51 |
+ {"config-file", 1, 0, 'c'}, /* not used */ |
|
51 | 52 |
{"checks", 1, 0, 'c'}, |
52 | 53 |
{"http-proxy", 1, 0, 0}, |
53 | 54 |
{"proxy-user", 1, 0, 0}, |