Browse code

Support for freshclam.conf

git-svn: trunk@166

Tomasz Kojm authored on 2003/12/29 14:31:52
Showing 19 changed files
... ...
@@ -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},