Browse code

merge backport fixes for 0.88.6

git-svn-id: file:///var/lib/svn/clamav-devel/branches/0.88-stable@2804 77e5149b-7576-45b1-b177-96237e5ba77b

Sven Strickroth authored on 2007/02/18 23:49:35
Showing 23 changed files
... ...
@@ -1,3 +1,14 @@
1
+Sun Nov  5 17:08:22 CET 2006
2
+-----------------------------
3
+  * Bugfixes:
4
+    - freshclam: apply timeout patch from Everton da Silva Marques
5
+      <everton*lab.ipaccess.diveo.net.br> (new options: ConnectTimeout and
6
+      ReceiveTimeout)
7
+    - clamd: change stack size at the right place (closes bug#103)
8
+      Patch from Jonathan Chen <jon+clamav*spock.org>
9
+    - libclamav/petite.c: sanity check the number of rebuilt sections (speeds
10
+      up handling of malformed files)
11
+
1 12
 Sun Oct 15 20:10:31 CEST 2006
2 13
 -----------------------------
3 14
   * Bugfixes:
... ...
@@ -1,8 +1,11 @@
1
-0.88.5
1
+0.88.6
2 2
 ------
3 3
 
4
-This version fixes a crash in the CHM unpacker and a heap overflow in the
5
-function rebuilding PE files after unpacking.
4
+Changes in this release include better handling of network problems in
5
+freshclam and other minor bugfixes.
6
+
7
+The ClamAV developers encourage all users to give a try to the latest
8
+beta version of 0.90!
6 9
 
7 10
 --
8 11
 The ClamAV team (http://www.clamav.net/team.html)
... ...
@@ -2,6 +2,19 @@ Note: This README/NEWS file refers to the source tarball. Some things described
2 2
 here may not be available in binary packages.
3 3
 --
4 4
 
5
+0.88.6
6
+------
7
+
8
+Changes in this release include better handling of network problems in
9
+freshclam and other minor bugfixes.
10
+
11
+The ClamAV developers encourage all users to give a try to the latest
12
+beta version of 0.90!
13
+
14
+--
15
+The ClamAV team (http://www.clamav.net/team.html)
16
+
17
+
5 18
 0.88.5
6 19
 ------
7 20
 
... ...
@@ -230,7 +230,6 @@ int acceptloop_th(int socketd, struct cl_node *root, const struct cfgstruct *cop
230 230
 	struct sigaction sigact;
231 231
 	mode_t old_umask;
232 232
 	struct cl_limits limits;
233
-	pthread_attr_t thattr;
234 233
 	sigset_t sigset;
235 234
 	client_conn_t *client_conn;
236 235
 	struct cfgstruct *cpt;
... ...
@@ -417,9 +416,6 @@ int acceptloop_th(int socketd, struct cl_node *root, const struct cfgstruct *cop
417 417
 	logg("Self checking every %d seconds.\n", selfchk);
418 418
     }
419 419
 
420
-    pthread_attr_init(&thattr);
421
-    pthread_attr_setdetachstate(&thattr, PTHREAD_CREATE_DETACHED);
422
-
423 420
     if(cfgopt(copt, "ClamukoScanOnLine") || cfgopt(copt, "ClamukoScanOnAccess"))
424 421
 #ifdef CLAMUKO
425 422
     {
... ...
@@ -467,18 +463,6 @@ int acceptloop_th(int socketd, struct cl_node *root, const struct cfgstruct *cop
467 467
 	sigaction(SIGSEGV, &sigact, NULL);
468 468
     }
469 469
 
470
-#if defined(C_BIGSTACK) || defined(C_BSD)
471
-    /*
472
-     * njh@bandsman.co.uk:
473
-     * libclamav/scanners.c uses a *huge* buffer
474
-     * (128K not BUFSIZ from stdio.h).
475
-     * We need to allow for that.
476
-     */
477
-    pthread_attr_getstacksize(&thattr, &stacksize);
478
-    cli_dbgmsg("set stacksize to %u\n", stacksize + SCANBUFF + 64 * 1024);
479
-    pthread_attr_setstacksize(&thattr, stacksize + SCANBUFF + 64 * 1024);
480
-#endif
481
-
482 470
     pthread_mutex_init(&exit_mutex, NULL);
483 471
     pthread_mutex_init(&reload_mutex, NULL);
484 472
 
... ...
@@ -121,6 +121,9 @@ void thrmgr_destroy(threadpool_t *threadpool)
121 121
 threadpool_t *thrmgr_new(int max_threads, int idle_timeout, void (*handler)(void *))
122 122
 {
123 123
 	threadpool_t *threadpool;
124
+#if defined(C_BIGSTACK) || defined(C_BSD)
125
+	size_t stacksize;
126
+#endif
124 127
 	
125 128
 	if (max_threads <= 0) {
126 129
 		return NULL;
... ...
@@ -154,6 +157,15 @@ threadpool_t *thrmgr_new(int max_threads, int idle_timeout, void (*handler)(void
154 154
 		free(threadpool);
155 155
 		return NULL;
156 156
 	}
157
+
158
+#if defined(C_BIGSTACK) || defined(C_BSD)
159
+	pthread_attr_getstacksize(&(threadpool->pool_attr), &stacksize);
160
+	stacksize = stacksize + 64 * 1024;
161
+	if (stacksize < 1048576) stacksize = 1048576; /* at least 1MB please */
162
+	logg("Set stack size to %u\n", stacksize);
163
+	pthread_attr_setstacksize(&(threadpool->pool_attr), stacksize);
164
+#endif
165
+
157 166
 	threadpool->state = POOL_VALID;
158 167
 
159 168
 	return threadpool;
... ...
@@ -2562,7 +2562,7 @@ fi
2562 2562
 
2563 2563
 # Define the identity of the package.
2564 2564
  PACKAGE=clamav
2565
- VERSION="0.88.5"
2565
+ VERSION="0.88.6"
2566 2566
 
2567 2567
 
2568 2568
 cat >>confdefs.h <<_ACEOF
... ...
@@ -2712,7 +2712,7 @@ ac_config_headers="$ac_config_headers clamav-config.h"
2712 2712
 
2713 2713
 
2714 2714
 LC_CURRENT=1
2715
-LC_REVISION=17
2715
+LC_REVISION=18
2716 2716
 LC_AGE=0
2717 2717
 LIBCLAMAV_VERSION="$LC_CURRENT":"$LC_REVISION":"$LC_AGE"
2718 2718
 
... ...
@@ -18,11 +18,11 @@ dnl   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 18
 
19 19
 AC_INIT(clamscan/clamscan.c)
20 20
 AC_CREATE_TARGET_H(target.h)
21
-AM_INIT_AUTOMAKE(clamav, "0.88.5")
21
+AM_INIT_AUTOMAKE(clamav, "0.88.6")
22 22
 AM_CONFIG_HEADER(clamav-config.h)
23 23
 
24 24
 LC_CURRENT=1
25
-LC_REVISION=17
25
+LC_REVISION=18
26 26
 LC_AGE=0
27 27
 LIBCLAMAV_VERSION="$LC_CURRENT":"$LC_REVISION":"$LC_AGE"
28 28
 AC_SUBST(LIBCLAMAV_VERSION)
29 29
Binary files a/docs/clamdoc.pdf and b/docs/clamdoc.pdf differ
... ...
@@ -70,7 +70,7 @@
70 70
     \vspace{3cm}
71 71
     \begin{flushright}
72 72
 	\rule[-1ex]{8cm}{3pt}\\
73
-	\huge Clam AntiVirus 0.88.3\\
73
+	\huge Clam AntiVirus 0.88.6\\
74 74
 	\huge \emph{User Manual}\\
75 75
     \end{flushright}
76 76
 
... ...
@@ -123,7 +123,7 @@
123 123
 	\item{POSIX compliant, portable}
124 124
 	\item{Fast scanning}
125 125
 	\item{Supports on-access scanning (Linux and FreeBSD only)}
126
-	\item{Detects over 35000 viruses, worms, and trojans, including
126
+	\item{Detects over 75.000 viruses, worms, and trojans, including
127 127
 	      Microsoft Office and MacOffice macro viruses}
128 128
 	\item{Scans within archives and compressed files (also protects
129 129
 	      against archive bombs), built-in support includes:
... ...
@@ -2092,8 +2092,6 @@ level required:MD5 checksum:digital signature:builder name:build time (sec)
2092 2092
 				 &		  &	& \email{<ed*hp.uab.edu>}\\ \hline
2093 2093
 	\url{clamav.inoc.net} & 64.246.134.133 & USA & Robert Blayzor\\
2094 2094
 			      &		       &     & \email{<noc*inoc.net>}\\ \hline
2095
-	\url{clamav.devolution.com} & 206.58.251.131 & California, & Scott Call\\
2096
-				    &		     &		   & \email{<scall*atgi.net>}\\ \hline
2097 2095
 	\url{clamavdb.hostlink.com.hk} & 210.245.160.22 & Hong Kong & Alex Fong\\
2098 2096
 				       &		&	    & \email{<alexfkl*hostlink.com.hk>}\\ \hline
2099 2097
 	\url{clamav.clearfield.com} & 65.110.48.11 & USA & Jean-Francois Pirus\\
... ...
@@ -2202,8 +2200,6 @@ level required:MD5 checksum:digital signature:builder name:build time (sec)
2202 2202
 				   &		   &	 & \email{<scollins*liquidweb.com>}\\ \hline
2203 2203
 	\url{clamav.xs4all.nl} & 194.109.6.74 & Netherlands & Eric Veldhuyzen\\
2204 2204
 			       &	      &		    & \email{<ericv*xs4all.net>}\\ \hline
2205
-        \url{clamav.pinna.cx} & 69.57.154.46 & Texas, & Nicola Pinna\\
2206
-			      &		     & USA    &	\email{<pinna*pinna.cx>}\\ \hline
2207 2205
 	\url{switch.clamav.net} & 130.59.10.35 & Switzerland & Thomas Lenggenhager\\
2208 2206
 				&	       &	     & \email{<lenggenhager*switch.ch>}\\ \hline
2209 2207
 	\url{clamav.public-internet.co.uk} & 195.85.245.20 & London, & Tom Beard\\
... ...
@@ -2277,6 +2273,26 @@ level required:MD5 checksum:digital signature:builder name:build time (sec)
2277 2277
 			      &		     &	       & \email{<b.kopp*maoke.de>}\\ \hline
2278 2278
 	\url{4most1.clamav.ialfa.net} & 58.221.253.171 & People's Republic & Alfa Shen\\
2279 2279
 				      &		       & of China	   & \email{<alfa*ialfa.net>}\\ \hline
2280
+	\url{clamav.hostway.co.kr} & 211.239.150.206 & Korea & Hoon Kim\\
2281
+				   &		     &	     & \email{<hkim*hostway.co.kr>}\\ \hline
2282
+	\url{clamav.doubleukay.com} & 202.71.97.92 & Malaysia & Woon Wai Keen\\
2283
+				    &		   &	      & \email{<doubleukay*doubleukay.com>}\\ \hline
2284
+	\url{clamav.archidiecezja.katowice.pl} & 212.106.154.2 & Poland & Artur Klimek\\
2285
+					       &	       &	& \email{<artk*archidiecezja.katowice.pl>}\\ \hline
2286
+	\url{clamav.dcux.com} & 61.129.102.109 & Shanghai, & Chun Xin Lee\\
2287
+			      &		       & China	   & \email{<chunxin*osslab.org>}\\ \hline
2288
+	\url{clamav.mirror.racksense.com} & 194.145.196.13 & United Kingdom & Paul Civati\\
2289
+					  &		   &		    & \email{<mirror*racksense.com>}\\ \hline
2290
+	\url{linkfirew.uncg.edu} & 152.13.144.243 & US & Vijay Sarvepalli\\
2291
+				 &		  &    & \email{<vssarvepat*uncg.edu>}\\ \hline
2292
+	\url{db.ezhik.org.ru} & 217.147.29.149 & Russia & Syrnikov Alexei\\
2293
+			      &		       &	& \email{<san*ezhik.org.ru>}\\ \hline
2294
+	\url{clamav.codefrog.dk} & 82.103.132.91 & Denmark & Lasse Brandt\\
2295
+				 &		 &	   & \email{<lasse*codefrog.dk>}\\ \hline
2296
+	\url{clamav.lmta.lt} & 193.219.48.134 & Lithuania & Rimas Kudelis\\
2297
+			     &		      &		  & \email{<clamavdb*lmta.lt>}\\ \hline
2298
+	\url{clamav.teleservice.net} & 85.30.129.18 & Sweden & Philip Olsson\\
2299
+				     &		    &	     & \email{<philip*teleservice.net>}\\ \hline
2280 2300
     \end{tabular}}
2281 2301
     \end{center}
2282 2302
 
... ...
@@ -2545,11 +2561,14 @@ level required:MD5 checksum:digital signature:builder name:build time (sec)
2545 2545
     \begin{itemize}
2546 2546
 	\item ActiveIntra.net Inc. (\url{http://www.activeintra.net/})
2547 2547
 	\item Advance Healthcare Group (\url{http://www.ahgl.com.au/})
2548
+	\item Allied Quotes (\url{http://www.AlliedQuotes.com /})
2548 2549
 	\item American Computer \& Electronic Services Corp. (\url{http://www.acesnw.com/})
2549 2550
 	\item Steve Anderson
2550 2551
 	\item Anonymous donor from Colorado, US
2552
+	\item Arudius (\url{http://arudius.sourceforge.net/})
2551 2553
 	\item Peter Ashman
2552 2554
 	\item Atlas College (\url{http://www.atlascollege.nl/})
2555
+	\item Australian Payday Cash Loans (\url{http://www.cashdoctors.com.au/})
2553 2556
 	\item AWD Online (\url{http://www.awdonline.com/})
2554 2557
 	\item BackupAssist Backup Software (\url{http://www.backupassist.com/})
2555 2558
 	\item Dave Baker
... ...
@@ -2557,9 +2576,11 @@ level required:MD5 checksum:digital signature:builder name:build time (sec)
2557 2557
 	\item Aaron Begley
2558 2558
 	\item Craig H. Block
2559 2559
 	\item Norman E. Brake, Jr.
2560
+	\item Josh Burstyn
2560 2561
 	\item By Design (\url{http://www.by-design.net/})
2561 2562
 	\item Canadian Web Hosting (\url{http://www.canadianwebhosting.com/})
2562 2563
 	\item cedarcreeksoftware.com (\url{http://www.cedarcreeksoftware.com/})
2564
+	\item Ricardo Cerqueira
2563 2565
 	\item Thanos Chatziathanassiou
2564 2566
 	\item Cheahch from Singapore
2565 2567
 	\item Conexim Australia - business web hosting (\url{http://www.conexim.com.au})
... ...
@@ -2593,11 +2614,13 @@ level required:MD5 checksum:digital signature:builder name:build time (sec)
2593 2593
 	\item GBC Internet Service Center GmbH (\url{http://www.gbc.net/})
2594 2594
 	\item GCS Tech (\url{http://www.gcstech.net/})
2595 2595
 	\item GHRS (\url{http://www.ghrshotels.com/})
2596
+	\item Lyle Giese
2596 2597
 	\item Todd Goodman
2597 2598
 	\item Bill Gradwohl (\url{http://www.ycc.com/})
2598 2599
 	\item Grain-of-Salt Consulting
2599 2600
 	\item Terje Gravvold
2600 2601
 	\item Hart Computer (\url{http://www.hart.co.jp/})
2602
+	\item Pen Helm
2601 2603
 	\item Hosting Metro LLC (\url{http://www.hostingmetro.com/})
2602 2604
 	\item IDEAL Software GmbH (\url{http://www.IdealSoftware.com/})
2603 2605
 	\item Industry Standard Computers (\url{http://www.ISCnetwork.com/})
... ...
@@ -2616,6 +2639,7 @@ level required:MD5 checksum:digital signature:builder name:build time (sec)
2616 2616
 	\item Michel Machado (\url{http://oss.digirati.com.br/})
2617 2617
 	\item Olivier Marechal
2618 2618
 	\item Matthew McKenzie
2619
+	\item Durval Menezes (\url{http://www.durval.com.br/})
2619 2620
 	\item Micro Logic Systems (\url{http://www.mls.nc/})
2620 2621
 	\item Midcoast Internet Solutions
2621 2622
 	\item Mimecast (\url{http://www.mimecast.com/})
... ...
@@ -2694,7 +2718,7 @@ level required:MD5 checksum:digital signature:builder name:build time (sec)
2694 2694
 	Role: virus database maintainer, coder
2695 2695
 
2696 2696
 	\item Boguslaw Brandys \email{<bbrandys*clamav.net>}, Poland\\
2697
-	Role: Win32 development
2697
+	Role: temporarily inactive
2698 2698
 
2699 2699
 	\item Mike Cathey \email{<mike*clamav.net>}, USA\\
2700 2700
 	Role: co-sysadmin
... ...
@@ -2718,24 +2742,27 @@ level required:MD5 checksum:digital signature:builder name:build time (sec)
2718 2718
 	Role: virus database maintainer
2719 2719
 
2720 2720
 	\item Tomasz Kojm \email{<tkojm*clamav.net>}, Poland\\
2721
-	Role: project leader, coder, virus database maintainer
2721
+	Role: project leader, coder
2722 2722
 
2723 2723
 	\item Thomas Lamy \email{<tlamy*clamav.net>}, Germany\\
2724
-	Role: random hacker
2724
+	Role: inactive
2725 2725
 
2726 2726
 	\item Thomas Madsen \email{<tmadsen*clamav.net>}, Denmark\\
2727
-	Role: virus submission management
2727
+	Role: inactive
2728 2728
 
2729 2729
 	\item Denis De Messemacker \email{<ddm*clamav.net>}, Belgium\\
2730 2730
 	Role: inactive
2731 2731
 
2732 2732
 	\item Tomasz Papszun \email{<tomek*clamav.net>}, Poland\\
2733
-	Role: virus database maintainer
2733
+	Role: various help
2734 2734
 
2735 2735
 	\item Sven Strickroth \email{<sven*clamav.net>}, Germany\\
2736
-	Role: virus database maintainer
2736
+	Role: virus database maintainer, virus submission management
2737
+
2738
+	\item Edvin Torok \email{<edwin*clamav.net>}, Romania\\
2739
+	Role: coder
2737 2740
 
2738 2741
 	\item Trog \email{<trog*clamav.net>}, United Kingdom\\
2739
-	Role: coder, virus database maintainer
2742
+	Role: coder
2740 2743
     \end{itemize}
2741 2744
 \end{document}
... ...
@@ -59,7 +59,7 @@ original version by:  Nikos Drakos, CBLU, University of Leeds
59 59
 <BR>
60 60
 <BR>
61 61
     <DIV ALIGN="RIGHT">
62
-<BR>	<FONT SIZE="+3">Clam AntiVirus 0.88.5
62
+<BR>	<FONT SIZE="+3">Clam AntiVirus 0.88.6
63 63
 <BR>	<FONT SIZE="+3"><I>User Manual</I>
64 64
 <BR>    
65 65
 </FONT></FONT></DIV>
... ...
@@ -67,7 +67,7 @@ Features</A>
67 67
 </LI>
68 68
 <LI>Supports on-access scanning (Linux and FreeBSD only)
69 69
 </LI>
70
-<LI>Detects over 70.000 viruses, worms, and trojans, including
70
+<LI>Detects over 75.000 viruses, worms, and trojans, including
71 71
 	      Microsoft Office and MacOffice macro viruses
72 72
 </LI>
73 73
 <LI>Scans within archives and compressed files (also protects
... ...
@@ -107,3 +107,11 @@ DatabaseMirror database.clamav.net
107 107
 # Enable debug messages in libclamav.
108 108
 # Default: disabled
109 109
 #Debug
110
+
111
+# Timeout in seconds when connecting to the database server.
112
+# Default: 30
113
+#ConnectTimeout 60
114
+
115
+# Timeout in seconds when reading from the database server.
116
+# Default: 30
117
+#ReceiveTimeout 60
... ...
@@ -41,7 +41,9 @@ freshclam_SOURCES = \
41 41
     dns.c \
42 42
     dns.h \
43 43
     execute.c \
44
-    execute.h
44
+    execute.h \
45
+    nonblock.c \
46
+    nonblock.h
45 47
 
46 48
 DEFS = @DEFS@ -DCL_NOTHREADS
47 49
 INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/shared -I$(top_srcdir)/libclamav
... ...
@@ -72,7 +72,8 @@ PROGRAMS = $(bin_PROGRAMS)
72 72
 am_freshclam_OBJECTS = output.$(OBJEXT) cfgparser.$(OBJEXT) \
73 73
 	getopt.$(OBJEXT) memory.$(OBJEXT) misc.$(OBJEXT) \
74 74
 	freshclam.$(OBJEXT) options.$(OBJEXT) manager.$(OBJEXT) \
75
-	notify.$(OBJEXT) dns.$(OBJEXT) execute.$(OBJEXT)
75
+	notify.$(OBJEXT) dns.$(OBJEXT) execute.$(OBJEXT) \
76
+	nonblock.$(OBJEXT)
76 77
 freshclam_OBJECTS = $(am_freshclam_OBJECTS)
77 78
 freshclam_LDADD = $(LDADD)
78 79
 DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
... ...
@@ -228,7 +229,9 @@ freshclam_SOURCES = \
228 228
     dns.c \
229 229
     dns.h \
230 230
     execute.c \
231
-    execute.h
231
+    execute.h \
232
+    nonblock.c \
233
+    nonblock.h
232 234
 
233 235
 INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/shared -I$(top_srcdir)/libclamav
234 236
 all: all-am
... ...
@@ -310,6 +313,7 @@ distclean-compile:
310 310
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/manager.Po@am__quote@
311 311
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/memory.Po@am__quote@
312 312
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/misc.Po@am__quote@
313
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nonblock.Po@am__quote@
313 314
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/notify.Po@am__quote@
314 315
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/options.Po@am__quote@
315 316
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/output.Po@am__quote@
... ...
@@ -39,3 +39,6 @@
39 39
 #define CL_DEFAULT_CHECKS 12
40 40
 #define CL_DEFAULT_MAXATTEMPTS 3
41 41
 #define CL_MAX_CHILDREN 5
42
+#define CL_DEFAULT_CONNECTTIMEOUT 30
43
+#define CL_DEFAULT_RECVTIMEOUT 30
44
+
... ...
@@ -51,7 +51,7 @@
51 51
 #include "../libclamav/str.h" /* cli_strtok */
52 52
 #include "dns.h"
53 53
 #include "execute.h"
54
-
54
+#include "nonblock.h"
55 55
 
56 56
 int downloadmanager(const struct cfgstruct *copt, const struct optstruct *opt, const char *hostname)
57 57
 {
... ...
@@ -267,7 +267,19 @@ int downloaddb(const char *localname, const char *remotename, const char *hostna
267 267
 	char  *tempname, ipaddr[16], *pt;
268 268
 	const char *proxy = NULL, *user = NULL, *pass = NULL;
269 269
 	int flevel = cl_retflevel();
270
+	int ctimeout; /* connect timeout in seconds */
271
+	int rtimeout; /* recv timeout in seconds */
272
+
273
+
274
+    if((cpt = cfgopt(copt, "ConnectTimeout")))
275
+	ctimeout = cpt->numarg;
276
+    else
277
+	ctimeout = CL_DEFAULT_CONNECTTIMEOUT;
270 278
 
279
+    if((cpt = cfgopt(copt, "ReceiveTimeout")))
280
+	rtimeout = cpt->numarg;
281
+    else
282
+	rtimeout = CL_DEFAULT_RECVTIMEOUT;
271 283
 
272 284
     if((current = cl_cvdhead(localname)) == NULL)
273 285
 	nodb = 1;
... ...
@@ -327,10 +339,11 @@ int downloaddb(const char *localname, const char *remotename, const char *hostna
327 327
     memset(ipaddr, 0, sizeof(ipaddr));
328 328
 
329 329
     if(!nodb && dbver == -1) {
330
+
330 331
 	if(ip[0]) /* use ip to connect */
331
-	    hostfd = wwwconnect(ip, proxy, port, ipaddr, localip);
332
+	    hostfd = wwwconnect(ip, proxy, port, ipaddr, localip, ctimeout);
332 333
 	else
333
-	    hostfd = wwwconnect(hostname, proxy, port, ipaddr, localip);
334
+	    hostfd = wwwconnect(hostname, proxy, port, ipaddr, localip, ctimeout);
334 335
 
335 336
 	if(hostfd < 0) {
336 337
             mprintf("@No servers could be reached. Giving up\n");
... ...
@@ -345,7 +358,7 @@ int downloaddb(const char *localname, const char *remotename, const char *hostna
345 345
 	if(!ip[0])
346 346
 	    strcpy(ip, ipaddr);
347 347
 
348
-	remote = remote_cvdhead(remotename, hostfd, hostname, proxy, user, pass, &ims);
348
+	remote = remote_cvdhead(remotename, hostfd, hostname, proxy, user, pass, &ims, rtimeout);
349 349
 
350 350
 	if(!nodb && !ims) {
351 351
 	    mprintf("%s is up to date (version: %d, sigs: %d, f-level: %d, builder: %s)\n", localname, current->version, current->sigs, current->fl, current->builder);
... ...
@@ -393,9 +406,9 @@ int downloaddb(const char *localname, const char *remotename, const char *hostna
393 393
 
394 394
     if(ipaddr[0]) {
395 395
 	/* use ipaddr in order to connect to the same mirror */
396
-	hostfd = wwwconnect(ipaddr, proxy, port, NULL, localip);
396
+	hostfd = wwwconnect(ipaddr, proxy, port, NULL, localip, ctimeout);
397 397
     } else {
398
-	hostfd = wwwconnect(hostname, proxy, port, ipaddr, localip);
398
+	hostfd = wwwconnect(hostname, proxy, port, ipaddr, localip, ctimeout);
399 399
 	if(!ip[0])
400 400
 	    strcpy(ip, ipaddr);
401 401
     }
... ...
@@ -414,7 +427,7 @@ int downloaddb(const char *localname, const char *remotename, const char *hostna
414 414
     tempname = cli_gentemp(".");
415 415
 
416 416
     mprintf("*Retrieving http://%s/%s\n", hostname, remotename);
417
-    if((ret = get_database(remotename, hostfd, tempname, hostname, proxy, user, pass))) {
417
+    if((ret = get_database(remotename, hostfd, tempname, hostname, proxy, user, pass, rtimeout))) {
418 418
         mprintf("@Can't download %s from %s (IP: %s)\n", remotename, hostname, ipaddr);
419 419
         unlink(tempname);
420 420
         free(tempname);
... ...
@@ -483,7 +496,7 @@ int downloaddb(const char *localname, const char *remotename, const char *hostna
483 483
 
484 484
 /* this function returns socket descriptor */
485 485
 /* proxy support finshed by njh@bandsman.co.uk */
486
-int wwwconnect(const char *server, const char *proxy, int pport, char *ip, char *localip)
486
+int wwwconnect(const char *server, const char *proxy, int pport, char *ip, char *localip, int ctimeout)
487 487
 {
488 488
 	int socketfd = -1, port, i;
489 489
 	struct sockaddr_in name;
... ...
@@ -615,7 +628,7 @@ int wwwconnect(const char *server, const char *proxy, int pport, char *ip, char
615 615
 	name.sin_addr = *((struct in_addr *) host->h_addr_list[i]);
616 616
 	name.sin_port = htons(port);
617 617
 
618
-	if(connect(socketfd, (struct sockaddr *) &name, sizeof(struct sockaddr_in)) == -1) {
618
+	if(wait_connect(socketfd, (struct sockaddr *) &name, sizeof(struct sockaddr_in), ctimeout) == -1) {
619 619
 	    mprintf("Can't connect to port %d of host %s (IP: %s)\n", port, hostpt, ipaddr);
620 620
 	    continue;
621 621
 	} else {
... ...
@@ -635,7 +648,7 @@ int Rfc2822DateTime(char *buf, time_t mtime)
635 635
     return strftime(buf, 36, "%a, %d %b %Y %X GMT", time);
636 636
 }
637 637
 
638
-struct cl_cvd *remote_cvdhead(const char *file, int socketfd, const char *hostname, const char *proxy, const char *user, const char *pass, int *ims)
638
+struct cl_cvd *remote_cvdhead(const char *file, int socketfd, const char *hostname, const char *proxy, const char *user, const char *pass, int *ims, int rtimeout)
639 639
 {
640 640
 	char cmd[512], head[513], buffer[FILEBUFF], *ch, *tmp;
641 641
 	int i, j, bread, cnt;
... ...
@@ -698,7 +711,7 @@ struct cl_cvd *remote_cvdhead(const char *file, int socketfd, const char *hostna
698 698
 
699 699
     tmp = buffer;
700 700
     cnt = FILEBUFF;
701
-    while ((bread = recv(socketfd, tmp, cnt, 0)) > 0) {
701
+    while ((bread = wait_recv(socketfd, tmp, cnt, 0, rtimeout)) > 0) {
702 702
 	tmp+=bread;
703 703
 	cnt-=bread;
704 704
 	if (cnt <= 0) break;
... ...
@@ -759,7 +772,7 @@ struct cl_cvd *remote_cvdhead(const char *file, int socketfd, const char *hostna
759 759
     return cvd;
760 760
 }
761 761
 
762
-int get_database(const char *dbfile, int socketfd, const char *file, const char *hostname, const char *proxy, const char *user, const char *pass)
762
+int get_database(const char *dbfile, int socketfd, const char *file, const char *hostname, const char *proxy, const char *user, const char *pass, int rtimeout)
763 763
 {
764 764
 	char cmd[512], buffer[FILEBUFF], *ch;
765 765
 	int bread, fd, i, rot = 0;
... ...
@@ -829,7 +842,7 @@ int get_database(const char *dbfile, int socketfd, const char *file, const char
829 829
     while (1) {
830 830
       /* recv one byte at a time, until we reach \r\n\r\n */
831 831
 
832
-      if((i >= sizeof(buffer) - 1) || recv(socketfd, buffer + i, 1, 0) == -1) {
832
+      if((i >= sizeof(buffer) - 1) || wait_recv(socketfd, buffer + i, 1, 0, rtimeout) == -1) {
833 833
         mprintf("@Error while reading database from %s\n", hostname);
834 834
         close(fd);
835 835
         unlink(file);
... ...
@@ -857,7 +870,7 @@ int get_database(const char *dbfile, int socketfd, const char *file, const char
857 857
 
858 858
     /* receive body and write it to disk */
859 859
 
860
-    while((bread = read(socketfd, buffer, FILEBUFF)) > 0) {
860
+    while((bread = wait_recv(socketfd, buffer, FILEBUFF, 0, rtimeout)) > 0) {
861 861
 	write(fd, buffer, bread);
862 862
 	mprintf("Downloading %s [%c]\r", dbfile, rotation[rot]);
863 863
 	fflush(stdout);
... ...
@@ -26,11 +26,11 @@ int downloadmanager(const struct cfgstruct *copt, const struct optstruct *opt, c
26 26
 
27 27
 int downloaddb(const char *localname, const char *remotename, const char *hostname, char *ip, int *signo, const struct cfgstruct *copt, const char *dnsreply, char *localip, int outdated);
28 28
 
29
-int wwwconnect(const char *server, const char *proxy, int pport, char *remoteip, char *localip);
29
+int wwwconnect(const char *server, const char *proxy, int pport, char *remoteip, char *localip, int timeout);
30 30
 
31
-struct cl_cvd *remote_cvdhead(const char *file, int socketfd, const char *hostname, const char *proxy, const char *user, const char *pass, int *ims);
31
+struct cl_cvd *remote_cvdhead(const char *file, int socketfd, const char *hostname, const char *proxy, const char *user, const char *pass, int *ims, int rtimeout);
32 32
 
33
-int get_database(const char *dbfile, int socketfd, const char *file, const char *hostname, const char *proxy, const char *user, const char *pass);
33
+int get_database(const char *dbfile, int socketfd, const char *file, const char *hostname, const char *proxy, const char *user, const char *pass, int rtimeout);
34 34
 
35 35
 unsigned int fmt_base64(char* dest,const char* src,unsigned int len);
36 36
 
37 37
new file mode 100644
... ...
@@ -0,0 +1,307 @@
0
+/*
1
+ *  Copyright 2006 Everton da Silva Marques <everton.marques@gmail.com>
2
+ *
3
+ *  This program is free software; you can redistribute it and/or modify
4
+ *  it under the terms of the GNU General Public License as published by
5
+ *  the Free Software Foundation; either version 2 of the License, or
6
+ *  (at your option) any later version.
7
+ *
8
+ *  This program is distributed in the hope that it will be useful,
9
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
+ *  GNU General Public License for more details.
12
+ *
13
+ *  You should have received a copy of the GNU General Public License
14
+ *  along with this program; if not, write to the Free Software
15
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
16
+ */
17
+
18
+#if HAVE_CONFIG_H
19
+#include "clamav-config.h"
20
+#endif
21
+
22
+#include "nonblock.h"
23
+
24
+#include <stdio.h>
25
+#include <stdlib.h>
26
+#include <unistd.h>
27
+#include <string.h>
28
+#include <ctype.h>
29
+#include <netinet/in.h>
30
+#include <netdb.h>
31
+#include <sys/types.h>
32
+#include <sys/socket.h>
33
+#include <sys/time.h>
34
+#include <time.h>
35
+#include <fcntl.h>
36
+#include <sys/stat.h>
37
+#include <clamav.h>
38
+#include <errno.h>
39
+
40
+#include "shared/output.h"
41
+
42
+#ifdef SO_ERROR
43
+
44
+#ifndef timercmp
45
+# define timercmp(a, b, cmp)          \
46
+  (((a)->tv_sec == (b)->tv_sec) ?     \
47
+   ((a)->tv_usec cmp (b)->tv_usec) :  \
48
+   ((a)->tv_sec cmp (b)->tv_sec))
49
+#endif /* timercmp */
50
+
51
+#ifndef timersub
52
+# define timersub(a, b, result)                       \
53
+  do {                                                \
54
+    (result)->tv_sec = (a)->tv_sec - (b)->tv_sec;     \
55
+    (result)->tv_usec = (a)->tv_usec - (b)->tv_usec;  \
56
+    if ((result)->tv_usec < 0) {                      \
57
+      --(result)->tv_sec;                             \
58
+      (result)->tv_usec += 1000000;                   \
59
+    }                                                 \
60
+  } while (0)
61
+#endif /* timersub */
62
+
63
+#define NONBLOCK_SELECT_MAX_FAILURES 3
64
+#define NONBLOCK_MAX_BOGUS_LOOPS     10
65
+#undef  NONBLOCK_DEBUG
66
+
67
+static int connect_error(int sock)
68
+{
69
+	int optval;
70
+	int optlen;
71
+
72
+	optlen = sizeof(optval);
73
+	getsockopt(sock, SOL_SOCKET, SO_ERROR, &optval, &optlen);
74
+
75
+	if (optval) {
76
+		logg("connect_error: getsockopt(SO_ERROR): fd=%d error=%d: %s\n",
77
+		     sock, optval, strerror(optval));
78
+	}
79
+
80
+	return optval ? -1 : 0;
81
+}
82
+
83
+static int nonblock_connect(int sock, const struct sockaddr *addr, socklen_t addrlen, int secs)
84
+{
85
+	/* Max. of unexpected select() failures */
86
+	int select_failures = NONBLOCK_SELECT_MAX_FAILURES;
87
+	/* Max. of useless loops */
88
+	int bogus_loops = NONBLOCK_MAX_BOGUS_LOOPS;
89
+	struct timeval timeout;  /* When we should time out */
90
+	int numfd;               /* Highest fdset fd plus 1 */
91
+
92
+	/* Calculate into 'timeout' when we should time out */
93
+	gettimeofday(&timeout, 0);
94
+	timeout.tv_sec += secs;
95
+
96
+	/* Launch (possibly) non-blocking connect() request */
97
+	if (connect(sock, addr, addrlen)) {
98
+		int e = errno;
99
+#ifdef NONBLOCK_DEBUG
100
+		logg("DEBUG nonblock_connect: connect(): fd=%d errno=%d: %s\n",
101
+		     sock, e, strerror(e));
102
+#endif
103
+		switch (e) {
104
+		case EALREADY:
105
+		case EINPROGRESS:
106
+			break; /* wait for connection */
107
+		case EISCONN:
108
+			return 0; /* connected */
109
+		default:
110
+			logg("nonblock_connect: connect(): fd=%d errno=%d: %s\n",
111
+			     sock, e, strerror(e));
112
+			return -1; /* failed */
113
+		}
114
+	}
115
+	else {
116
+		return connect_error(sock);
117
+	}
118
+
119
+	numfd = sock + 1; /* Highest fdset fd plus 1 */
120
+
121
+	for (;;) {
122
+		fd_set fds;
123
+		struct timeval now;
124
+		struct timeval wait;
125
+		int n;
126
+
127
+		/* Force timeout if we ran out of time */
128
+		gettimeofday(&now, 0);
129
+		if (timercmp(&now, &timeout, >)) {
130
+			logg("nonblock_connect: connect timing out (%d secs)\n",
131
+			     secs);
132
+			break; /* failed */
133
+		}
134
+
135
+		/* Calculate into 'wait' how long to wait */
136
+		timersub(&timeout, &now, &wait); /* wait = timeout - now */
137
+
138
+		/* Init fds with 'sock' as the only fd */
139
+		FD_ZERO(&fds);
140
+		FD_SET(sock, &fds);
141
+
142
+		n = select(numfd, 0, &fds, 0, &wait);
143
+		if (n < 0) {
144
+			logg("nonblock_connect: select() failure %d: errno=%d: %s\n",
145
+			     select_failures, errno, strerror(errno));
146
+			if (--select_failures >= 0)
147
+				continue; /* keep waiting */
148
+			break; /* failed */
149
+		}
150
+
151
+#ifdef NONBLOCK_DEBUG
152
+		logg("DEBUG nonblock_connect: select = %d\n", n);
153
+#endif
154
+
155
+		if (n) {
156
+			return connect_error(sock);
157
+		}
158
+
159
+		/* Select returned, but there is no work to do... */
160
+		if (--bogus_loops < 0) {
161
+			logg("nonblock_connect: giving up due to excessive bogus loops\n");
162
+			break; /* failed */
163
+		}
164
+
165
+	} /* for loop: keep waiting */
166
+
167
+	return -1; /* failed */
168
+}
169
+
170
+static ssize_t nonblock_recv(int sock, void *buf, size_t len, int flags, int secs)
171
+{
172
+	/* Max. of unexpected select() failures */
173
+	int select_failures = NONBLOCK_SELECT_MAX_FAILURES;
174
+	/* Max. of useless loops */
175
+	int bogus_loops = NONBLOCK_MAX_BOGUS_LOOPS;
176
+	struct timeval timeout;  /* When we should time out */
177
+	int numfd;               /* Highest fdset fd plus 1 */
178
+
179
+	/* Calculate into 'timeout' when we should time out */
180
+	gettimeofday(&timeout, 0);
181
+	timeout.tv_sec += secs;
182
+
183
+	numfd = sock + 1; /* Highest fdset fd plus 1 */
184
+
185
+	for (;;) {
186
+		fd_set fds;
187
+		struct timeval now;
188
+		struct timeval wait;
189
+		int n;
190
+
191
+		/* Force timeout if we ran out of time */
192
+		gettimeofday(&now, 0);
193
+		if (timercmp(&now, &timeout, >)) {
194
+			logg("nonblock_recv: recv timing out (%d secs)\n", secs);
195
+			break; /* failed */
196
+		}
197
+
198
+		/* Calculate into 'wait' how long to wait */
199
+		timersub(&timeout, &now, &wait); /* wait = timeout - now */
200
+
201
+		/* Init fds with 'sock' as the only fd */
202
+		FD_ZERO(&fds);
203
+		FD_SET(sock, &fds);
204
+
205
+		n = select(numfd, &fds, 0, 0, &wait);
206
+		if (n < 0) {
207
+			logg("nonblock_recv: select() failure %d: errno=%d: %s\n",
208
+			     select_failures, errno, strerror(errno));
209
+			if (--select_failures >= 0)
210
+				continue; /* keep waiting */
211
+			break; /* failed */
212
+		}
213
+
214
+		if (n) {
215
+			return recv(sock, buf, len, flags);
216
+		}
217
+
218
+		/* Select returned, but there is no work to do... */
219
+		if (--bogus_loops < 0) {
220
+			logg("nonblock_recv: giving up due to excessive bogus loops\n");
221
+			break; /* failed */
222
+		}
223
+
224
+	} /* for loop: keep waiting */
225
+
226
+	return -1; /* failed */
227
+}
228
+
229
+static long nonblock_fcntl(int sock)
230
+{
231
+	long fcntl_flags; /* Save fcntl() flags */
232
+
233
+	fcntl_flags = fcntl(sock, F_GETFL, 0);
234
+	if (fcntl_flags == -1) {
235
+		logg("nonblock_fcntl: saving: fcntl(%d, F_GETFL): errno=%d: %s\n",
236
+		     sock, errno, strerror(errno));
237
+	}
238
+	else if (fcntl(sock, F_SETFL, fcntl_flags | O_NONBLOCK)) {
239
+		logg("nonblock_fcntl: fcntl(%d, F_SETFL, O_NONBLOCK): errno=%d: %s\n",
240
+		     sock, errno, strerror(errno));
241
+	}
242
+
243
+	return fcntl_flags;
244
+}
245
+
246
+static void restore_fcntl(int sock, long fcntl_flags)
247
+{
248
+	if (fcntl_flags != -1) {
249
+		if (fcntl(sock, F_SETFL, fcntl_flags)) {
250
+			logg("restore_fcntl: restoring: fcntl(%d, F_SETFL): errno=%d: %s\n",
251
+			     sock, errno, strerror(errno));
252
+		}
253
+	}
254
+}
255
+
256
+/*
257
+	wait_connect(): wrapper for connect(), with explicit 'secs' timeout
258
+*/
259
+int wait_connect(int sock, const struct sockaddr *addr, socklen_t addrlen, int secs)
260
+{
261
+	long fcntl_flags; /* Save fcntl() flags */
262
+	int ret;
263
+
264
+	/* Temporarily set socket to non-blocking mode */
265
+	fcntl_flags = nonblock_fcntl(sock);
266
+
267
+	ret = nonblock_connect(sock, addr, addrlen, secs);
268
+
269
+	/* Restore socket's default blocking mode */
270
+	restore_fcntl(sock, fcntl_flags);
271
+
272
+	return ret;
273
+}
274
+
275
+/*
276
+	wait_recv(): wrapper for recv(), with explicit 'secs' timeout
277
+*/
278
+ssize_t wait_recv(int sock, void *buf, size_t len, int flags, int secs)
279
+{
280
+	long fcntl_flags; /* Save fcntl() flags */
281
+	int ret;
282
+
283
+	/* Temporarily set socket to non-blocking mode */
284
+	fcntl_flags = nonblock_fcntl(sock);
285
+
286
+	ret = nonblock_recv(sock, buf, len, flags, secs);
287
+
288
+	/* Restore socket's default blocking mode */
289
+	restore_fcntl(sock, fcntl_flags);
290
+
291
+	return ret;
292
+}
293
+
294
+#else /* !SO_ERROR */
295
+
296
+int wait_connect(int sock, const struct sockaddr *addr, socklen_t addrlen, int secs)
297
+{
298
+    return connect(sock, addr, addrlen);
299
+}
300
+
301
+ssize_t wait_recv(int sock, void *buf, size_t len, int flags, int secs)
302
+{
303
+    return recv(sock, buf, len, flags);
304
+}
305
+
306
+#endif /* SO_ERROR */
0 307
new file mode 100644
... ...
@@ -0,0 +1,39 @@
0
+/*
1
+ *  Copyright 2006 Everton da Silva Marques <everton.marques@gmail.com>
2
+ *
3
+ *  This program is free software; you can redistribute it and/or modify
4
+ *  it under the terms of the GNU General Public License as published by
5
+ *  the Free Software Foundation; either version 2 of the License, or
6
+ *  (at your option) any later version.
7
+ *
8
+ *  This program is distributed in the hope that it will be useful,
9
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
+ *  GNU General Public License for more details.
12
+ *
13
+ *  You should have received a copy of the GNU General Public License
14
+ *  along with this program; if not, write to the Free Software
15
+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
16
+ */
17
+
18
+#ifndef __NONBLOCK_H
19
+#define __NONBLOCK_H
20
+
21
+#if HAVE_CONFIG_H
22
+#include "clamav-config.h"
23
+#endif
24
+
25
+#include <sys/types.h>
26
+#include <sys/socket.h>
27
+
28
+/*
29
+	wait_connect(): wrapper for connect(), with explicit 'secs' timeout
30
+*/
31
+int wait_connect(int sock, const struct sockaddr *addr, socklen_t addrlen, int secs);
32
+
33
+/*
34
+        wait_recv(): wrapper for recv(), with explicit 'secs' timeout
35
+*/
36
+ssize_t wait_recv(int sock, void *buf, size_t len, int flags, int secs);
37
+
38
+#endif /* NONBLOCK_H */
... ...
@@ -72,7 +72,7 @@ pthread_mutex_t cli_gentemp_mutex = PTHREAD_MUTEX_INITIALIZER;
72 72
 #define	O_BINARY	0
73 73
 #endif
74 74
 
75
-#define CL_FLEVEL 9 /* don't touch it */
75
+#define CL_FLEVEL 10 /* don't touch it */
76 76
 
77 77
 short cli_debug_flag = 0, cli_leavetemps_flag = 0;
78 78
 
... ...
@@ -288,6 +288,12 @@ int petite_inflate2x_1to9(char *buf, uint32_t minrva, uint32_t bufsz, struct pe_
288 288
       thisrva=cli_readint32(packed+8); /* RVA of the original section */
289 289
       packed += 0x10;
290 290
 
291
+      if ( j >= 99 ) {
292
+	cli_dbgmsg("Petite: maximum number of sections exceeded, giving up.\n");
293
+	free(usects);
294
+	return -1;
295
+      }
296
+
291 297
       /* Alloc 1 more struct */
292 298
       if ( ! (tmpsct = realloc(usects, sizeof(struct SECTION) * (j+1))) ) {
293 299
 	if (usects)
... ...
@@ -557,7 +557,7 @@ static int cli_loadndb(FILE *fd, struct cl_node **root, unsigned int *signo, uns
557 557
 	    }
558 558
 
559 559
 	    if(atoi(pt) > cl_retflevel()) {
560
-		cli_warnmsg("Signature for %s requires new ClamAV version. Please update!\n", virname);
560
+		cli_dbgmsg("Signature for %s not loaded (required f-level: %u)\n", virname, cl_retflevel());
561 561
 		sigs--;
562 562
 		free(virname);
563 563
 		free(pt);
... ...
@@ -115,6 +115,8 @@ struct cfgstruct *parsecfg(const char *cfgfile, int messages)
115 115
 	    {"OnErrorExecute", OPT_FULLSTR}, /* freshclam */
116 116
 	    {"OnOutdatedExecute", OPT_FULLSTR}, /* freshclam */
117 117
 	    {"LocalIPAddress", OPT_STR}, /* freshclam */
118
+	    {"ConnectTimeout", OPT_NUM}, /* freshclam */
119
+	    {"ReceiveTimeout", OPT_NUM}, /* freshclam */
118 120
 	    {0, 0},
119 121
 	};
120 122