git-svn: trunk@3192
Nigel Horne authored on 2007/08/29 01:01:53... | ... |
@@ -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 |