Browse code

MailFollowURLS: improved debugging

git-svn: trunk@3192

Nigel Horne authored on 2007/08/29 01:01:53
Showing 2 changed files
... ...
@@ -1,3 +1,12 @@
1
+Tue Aug 28 16:08:13 BST 2007 (njh)
2
+----------------------------------
3
+  * libclamav/mbox.c:	MailFollowURLS: improved debugging
4
+
5
+Mon Aug 27 23:10:26 BST 2007 (njh)
6
+----------------------------------
7
+  * libclamav/blob.[ch]:	Bug 637
8
+  * libclamav/mbox.c:		Minor code tidy
9
+
1 10
 Tue Aug 21 21:43:56 CEST 2007 (tk)
2 11
 ----------------------------------
3 12
   * libclamav/others.c: bump f-level
... ...
@@ -249,11 +249,21 @@ struct arg {
249 249
 	char *filename;
250 250
 	int	depth;
251 251
 };
252
+#define	URL_TIMEOUT	5	/* Allow 5 seconds to connect */
252 253
 #ifdef	CL_THREAD_SAFE
253 254
 static	void	*getURL(void *a);
254 255
 #else
255 256
 static	void	*getURL(struct arg *arg);
256 257
 #endif
258
+static	long	nonblock_fcntl(int sock);
259
+static	void	restore_fcntl(int sock, long fcntl_flags);
260
+static	int	nonblock_connect(const char *url, int sock, const struct sockaddr *addr, socklen_t addrlen, int secs);
261
+static	int	connect_error(const char *url, int sock);
262
+static	int	my_r_gethostbyname(const char *hostname, struct hostent *hp, char *buf, size_t len);
263
+
264
+#define NONBLOCK_SELECT_MAX_FAILURES	3
265
+#define NONBLOCK_MAX_BOGUS_LOOPS	10
266
+
257 267
 #endif
258 268
 
259 269
 /* Maximum line length according to RFC821 */
... ...
@@ -3554,7 +3564,7 @@ rfc2047(const char *in)
3554 3554
 		if(*in == '\0')
3555 3555
 			break;
3556 3556
 		encoding = *++in;
3557
-		encoding = tolower(encoding);
3557
+		encoding = (char)tolower(encoding);
3558 3558
 
3559 3559
 		if((encoding != 'q') && (encoding != 'b')) {
3560 3560
 			cli_warnmsg("Unsupported RFC2047 encoding type '%c' - if you believe this file contains a virus, submit it to www.clamav.net\n", encoding);
... ...
@@ -4022,34 +4032,6 @@ do_checkURLs(const char *dir, tag_arguments_t *hrefs)
4022 4022
  * Includes some of the freshclam hacks by Everton da Silva Marques
4023 4023
  * everton.marques@gmail.com>
4024 4024
  */
4025
-#ifndef timercmp
4026
-# define timercmp(a, b, cmp)	  \
4027
-  (((a)->tv_sec == (b)->tv_sec) ?	\
4028
-   ((a)->tv_usec cmp (b)->tv_usec) :  \
4029
-   ((a)->tv_sec cmp (b)->tv_sec))
4030
-#endif /* timercmp */
4031
-
4032
-#ifndef timersub
4033
-# define timersub(a, b, result)	 \
4034
-  do {				\
4035
-	(result)->tv_sec = (a)->tv_sec - (b)->tv_sec;	\
4036
-	(result)->tv_usec = (a)->tv_usec - (b)->tv_usec;  \
4037
-	if ((result)->tv_usec < 0) {			\
4038
-		--(result)->tv_sec;			 \
4039
-		(result)->tv_usec += 1000000;		 \
4040
-	}						 \
4041
-  } while (0)
4042
-#endif /* timersub */
4043
-
4044
-static	long	nonblock_fcntl(int sock);
4045
-static	void	restore_fcntl(int sock, long fcntl_flags);
4046
-static	int	nonblock_connect(int sock, const struct sockaddr *addr, socklen_t addrlen, int secs);
4047
-static	int	connect_error(int sock);
4048
-static	int	my_r_gethostbyname(const char *hostname, struct hostent *hp, char *buf, size_t len);
4049
-
4050
-#define NONBLOCK_SELECT_MAX_FAILURES	3
4051
-#define NONBLOCK_MAX_BOGUS_LOOPS	10
4052
-
4053 4025
 /*
4054 4026
  * Simple implementation of a subset of RFC1945 (HTTP/1.0)
4055 4027
  * TODO: HTTP/1.1 (RFC2068)
... ...
@@ -4221,7 +4203,7 @@ getURL(struct arg *arg)
4221 4221
 		return NULL;
4222 4222
 	}
4223 4223
 	flags = nonblock_fcntl(sd);
4224
-	if(nonblock_connect(sd, (struct sockaddr *)&server, sizeof(struct sockaddr_in), 5) < 0) {
4224
+	if(nonblock_connect(url, sd, (struct sockaddr *)&server, sizeof(struct sockaddr_in), URL_TIMEOUT) < 0) {
4225 4225
 		closesocket(sd);
4226 4226
 		fclose(fp);
4227 4227
 		return NULL;
... ...
@@ -4458,57 +4440,60 @@ restore_fcntl(int sock, long fcntl_flags)
4458 4458
 }
4459 4459
 
4460 4460
 static int
4461
-nonblock_connect(int sock, const struct sockaddr *addr, socklen_t addrlen, int secs)
4461
+nonblock_connect(const char *url, int sock, const struct sockaddr *addr, socklen_t addrlen, int secs)
4462 4462
 {
4463 4463
 	int select_failures;	/* Max. of unexpected select() failures */
4464 4464
 	int bogus_loops;	/* Max. of useless loops */
4465 4465
 	struct timeval timeout;	/* When we should time out */
4466 4466
 	int numfd;		/* Highest fdset fd plus 1 */
4467 4467
 
4468
-	/* Launch (possibly) non-blocking connect() request */
4469
-	if(connect(sock, addr, addrlen)) {
4470
-		int e = errno;
4468
+	/* Calculate into 'timeout' when we should time out */
4469
+	gettimeofday(&timeout, 0);
4471 4470
 
4472
-		cli_dbgmsg("nonblock_connect: connect(): fd=%d errno=%d: %s\n",
4473
-			sock, e, strerror(e));
4474
-		switch (e) {
4471
+	if(connect(sock, addr, addrlen))
4472
+		switch(errno) {
4475 4473
 			case EALREADY:
4476 4474
 			case EINPROGRESS:
4475
+				cli_dbgmsg("%s: connect: %s\n", url, strerror(errno));
4477 4476
 				break; /* wait for connection */
4478 4477
 			case EISCONN:
4479 4478
 				return 0; /* connected */
4480 4479
 			default:
4481
-				cli_warnmsg("nonblock_connect: connect(): fd=%d errno=%d: %s\n",
4482
-					sock, e, strerror(e));
4480
+				cli_warnmsg("%s: connect: %s\n", url, strerror(errno));
4483 4481
 				return -1; /* failed */
4484 4482
 		}
4485
-	} else
4486
-		return connect_error(sock);
4487
-
4488
-	/* Calculate into 'timeout' when we should time out */
4489
-	gettimeofday(&timeout, 0);
4490
-	timeout.tv_sec += secs;
4483
+	else
4484
+		return connect_error(url, sock);
4491 4485
 
4492 4486
 	numfd = sock + 1; /* Highest fdset fd plus 1 */
4493 4487
 	select_failures = NONBLOCK_SELECT_MAX_FAILURES;
4494 4488
 	bogus_loops = NONBLOCK_MAX_BOGUS_LOOPS;
4489
+	timeout.tv_sec += secs;
4495 4490
 
4496 4491
 	for (;;) {
4492
+		int n, t;
4497 4493
 		fd_set fds;
4498
-		struct timeval now;
4499
-		struct timeval waittime;
4500
-		int n;
4494
+		struct timeval now, waittime;
4501 4495
 
4502 4496
 		/* Force timeout if we ran out of time */
4503 4497
 		gettimeofday(&now, 0);
4504
-		if (timercmp(&now, &timeout, >)) {
4505
-			cli_warnmsg("connect timing out (%d secs)\n",
4506
-				secs);
4507
-			break; /* failed */
4498
+		t = (now.tv_sec == timeout.tv_sec) ?
4499
+			(now.tv_usec > timeout.tv_usec) :
4500
+			(now.tv_sec > timeout.tv_sec);
4501
+
4502
+		if(t) {
4503
+			cli_warnmsg("%s: connect timeout (%d secs)\n",
4504
+				url, secs);
4505
+			break;
4508 4506
 		}
4509 4507
 
4510
-		/* Calculate into 'waittime' how long to wait */
4511
-		timersub(&timeout, &now, &waittime); /* wait = timeout - now */
4508
+		/* Calculate how long to wait */
4509
+		waittime.tv_sec = timeout.tv_sec - now.tv_sec;
4510
+		waittime.tv_usec = timeout.tv_usec - now.tv_usec;
4511
+		if(waittime.tv_usec < 0) {
4512
+			waittime.tv_sec--;
4513
+			waittime.tv_usec += 1000000;
4514
+		}
4512 4515
 
4513 4516
 		/* Init fds with 'sock' as the only fd */
4514 4517
 		FD_ZERO(&fds);
... ...
@@ -4516,21 +4501,22 @@ nonblock_connect(int sock, const struct sockaddr *addr, socklen_t addrlen, int s
4516 4516
 
4517 4517
 		n = select(numfd, 0, &fds, 0, &waittime);
4518 4518
 		if(n < 0) {
4519
-			cli_warnmsg("nonblock_connect: select() failure %d: errno=%d: %s\n",
4520
-				select_failures, errno, strerror(errno));
4521
-			if (--select_failures >= 0)
4519
+			cli_warnmsg("%s: select attempt %d %s\n",
4520
+				url, select_failures, strerror(errno));
4521
+			if(--select_failures >= 0)
4522 4522
 				continue; /* keep waiting */
4523 4523
 			break; /* failed */
4524 4524
 		}
4525 4525
 
4526
-		cli_dbgmsg("nonblock_connect: select = %d\n", n);
4526
+		cli_dbgmsg("%s: select = %d\n", url, n);
4527 4527
 
4528 4528
 		if(n)
4529
-			return connect_error(sock);
4529
+			return connect_error(url, sock);
4530 4530
 
4531
-		/* Select returned, but there is no work to do... */
4531
+		/* timeout */
4532 4532
 		if(--bogus_loops < 0) {
4533
-			cli_warnmsg("nonblock_connect: giving up due to excessive bogus loops\n");
4533
+			cli_warnmsg("%s: giving up due to excessive bogus loops\n",
4534
+				url);
4534 4535
 			break; /* failed */
4535 4536
 		}
4536 4537
 
... ...
@@ -4540,23 +4526,21 @@ nonblock_connect(int sock, const struct sockaddr *addr, socklen_t addrlen, int s
4540 4540
 }
4541 4541
 
4542 4542
 static int
4543
-connect_error(int sock)
4543
+connect_error(const char *url, int sock)
4544 4544
 {
4545 4545
 #ifdef	SO_ERROR
4546 4546
 	int optval;
4547
-	socklen_t optlen;
4547
+	socklen_t optlen = sizeof(optval);
4548 4548
 
4549
-	optlen = sizeof(optval);
4550 4549
 	getsockopt(sock, SOL_SOCKET, SO_ERROR, &optval, &optlen);
4551 4550
 
4552
-	if(optval)
4553
-		cli_warnmsg("connect_error: getsockopt(SO_ERROR): fd=%d error=%d: %s\n",
4554
-			sock, optval, strerror(optval));
4551
+	if(optval) {
4552
+		cli_warnmsg("%s: %s\n", url, strerror(optval));
4553
+		return -1;
4554
+	}
4555
+#endif
4555 4556
 
4556
-	return optval ? -1 : 0;
4557
-#else
4558 4557
 	return 0;
4559
-#endif
4560 4558
 }
4561 4559
 
4562 4560
 #endif