git-svn: trunk@3191
Nigel Horne authored on 2007/08/28 08:05:16... | ... |
@@ -216,7 +216,7 @@ blobAddData(blob *b, const unsigned char *data, size_t len) |
216 | 216 |
|
217 | 217 |
b->size = len * 4; |
218 | 218 |
b->data = cli_malloc(b->size); |
219 |
- } else if(b->size < b->len + len) { |
|
219 |
+ } else if(b->size < b->len + (off_t)len) { |
|
220 | 220 |
unsigned char *p = cli_realloc(b->data, b->size + (len * 4)); |
221 | 221 |
|
222 | 222 |
if(p == NULL) |
... | ... |
@@ -379,10 +379,13 @@ fileblobDestroy(fileblob *fb) |
379 | 379 |
|
380 | 380 |
if(fb->b.name && fb->fp) { |
381 | 381 |
fclose(fb->fp); |
382 |
- cli_dbgmsg("fileblobDestroy: %s\n", fb->b.name); |
|
383 |
- if(!fb->isNotEmpty) { |
|
384 |
- cli_dbgmsg("fileblobDestroy: not saving empty file\n"); |
|
385 |
- unlink(fb->b.name); |
|
382 |
+ if(fb->fullname) { |
|
383 |
+ cli_dbgmsg("fileblobDestroy: %s\n", fb->fullname); |
|
384 |
+ if(!fb->isNotEmpty) { |
|
385 |
+ cli_dbgmsg("fileblobDestroy: not saving empty file\n"); |
|
386 |
+ if(unlink(fb->fullname) < 0) |
|
387 |
+ cli_warnmsg("fileblobDestroy: Can't delete empty files %s\n", fb->fullname); |
|
388 |
+ } |
|
386 | 389 |
} |
387 | 390 |
free(fb->b.name); |
388 | 391 |
|
... | ... |
@@ -396,6 +399,8 @@ fileblobDestroy(fileblob *fb) |
396 | 396 |
cli_errmsg("fileblobDestroy: file not saved (%lu bytes): report to http://bugs.clamav.net\n", |
397 | 397 |
(unsigned long)fb->b.len); |
398 | 398 |
} |
399 |
+ if(fb->fullname) |
|
400 |
+ free(fb->fullname); |
|
399 | 401 |
#ifdef CL_DEBUG |
400 | 402 |
fb->b.magic = INVALIDCLASS; |
401 | 403 |
#endif |
... | ... |
@@ -461,6 +466,8 @@ fileblobSetFilename(fileblob *fb, const char *dir, const char *filename) |
461 | 461 |
if(name == NULL) |
462 | 462 |
return; |
463 | 463 |
fd = open(name, O_WRONLY|O_CREAT|O_EXCL|O_TRUNC|O_BINARY, 0600); |
464 |
+ if(fd >= 0) |
|
465 |
+ strncpy(fullname, name, sizeof(fullname) - 1); |
|
464 | 466 |
free(name); |
465 | 467 |
} else |
466 | 468 |
fd = open(fullname, O_WRONLY|O_CREAT|O_EXCL|O_TRUNC|O_BINARY, 0600); |
... | ... |
@@ -494,7 +501,15 @@ fileblobSetFilename(fileblob *fb, const char *dir, const char *filename) |
494 | 494 |
free(fb->b.data); |
495 | 495 |
fb->b.data = NULL; |
496 | 496 |
fb->b.len = fb->b.size = 0; |
497 |
+ fb->isNotEmpty = 1; |
|
497 | 498 |
} |
499 |
+ |
|
500 |
+ /* |
|
501 |
+ * If this strdup fails, then if the file is empty it won't be removed |
|
502 |
+ * until later. Since this is only a trivial issue, there is no need |
|
503 |
+ * to error if it fails to allocate |
|
504 |
+ */ |
|
505 |
+ fb->fullname = cli_strdup(fullname); |
|
498 | 506 |
} |
499 | 507 |
|
500 | 508 |
int |
... | ... |
@@ -46,11 +46,15 @@ int blobcmp(const blob *b1, const blob *b2); |
46 | 46 |
int blobGrow(blob *b, size_t len); |
47 | 47 |
|
48 | 48 |
/* |
49 |
- * Like a blob, but associated with a file |
|
49 |
+ * Like a blob, but associated with a file stored in the temporary directory |
|
50 | 50 |
*/ |
51 | 51 |
typedef struct fileblob { |
52 | 52 |
FILE *fp; |
53 |
- blob b; |
|
53 |
+ blob b; /* |
|
54 |
+ * b.name is the name of the attachment as stored in the |
|
55 |
+ * email, not the full path name of the temporary file |
|
56 |
+ */ |
|
57 |
+ char *fullname; /* full pathname of the file */ |
|
54 | 58 |
unsigned int isNotEmpty : 1; |
55 | 59 |
unsigned int isInfected : 1; |
56 | 60 |
unsigned long bytes_scanned; |
... | ... |
@@ -4084,7 +4084,8 @@ getURL(struct arg *arg) |
4084 | 4084 |
static int tcp; |
4085 | 4085 |
int doingsite, firstpacket; |
4086 | 4086 |
char *ptr; |
4087 |
- int flags, via_proxy; |
|
4087 |
+ long flags; |
|
4088 |
+ int via_proxy; |
|
4088 | 4089 |
const char *proxy; |
4089 | 4090 |
char buf[BUFSIZ + 1], site[BUFSIZ], fout[NAME_MAX + 1]; |
4090 | 4091 |
|
... | ... |
@@ -4140,7 +4141,8 @@ getURL(struct arg *arg) |
4140 | 4140 |
|
4141 | 4141 |
if(via_proxy) { |
4142 | 4142 |
if(strncasecmp(proxy, "http://", 7) != 0) { |
4143 |
- cli_warnmsg("Unsupported proxy protocol\n"); |
|
4143 |
+ cli_warnmsg("Unsupported proxy protocol (proxy = %s)\n", |
|
4144 |
+ proxy); |
|
4144 | 4145 |
fclose(fp); |
4145 | 4146 |
return NULL; |
4146 | 4147 |
} |
... | ... |
@@ -4224,8 +4226,8 @@ getURL(struct arg *arg) |
4224 | 4224 |
fclose(fp); |
4225 | 4225 |
return NULL; |
4226 | 4226 |
} |
4227 |
- |
|
4228 | 4227 |
restore_fcntl(sd, flags); |
4228 |
+ |
|
4229 | 4229 |
/* |
4230 | 4230 |
* TODO: consider HTTP/1.1 |
4231 | 4231 |
*/ |
... | ... |
@@ -4428,19 +4430,18 @@ static long |
4428 | 4428 |
nonblock_fcntl(int sock) |
4429 | 4429 |
{ |
4430 | 4430 |
#ifdef F_GETFL |
4431 |
- long fcntl_flags; /* Save fcntl() flags */ |
|
4431 |
+ int fcntl_flags = fcntl(sock, F_GETFL, 0); /* Save fcntl() flags */ |
|
4432 | 4432 |
|
4433 |
- fcntl_flags = fcntl(sock, F_GETFL, 0); |
|
4434 | 4433 |
if(fcntl_flags < 0) |
4435 | 4434 |
cli_warnmsg("nonblock_fcntl: saving: fcntl(%d, F_GETFL): errno=%d: %s\n", |
4436 | 4435 |
sock, errno, strerror(errno)); |
4437 |
- else if(fcntl(sock, F_SETFL, fcntl_flags | O_NONBLOCK)) |
|
4436 |
+ else if(fcntl(sock, F_SETFL, (long)fcntl_flags | O_NONBLOCK) < 0) |
|
4438 | 4437 |
cli_warnmsg("nonblock_fcntl: fcntl(%d, F_SETFL, O_NONBLOCK): errno=%d: %s\n", |
4439 | 4438 |
sock, errno, strerror(errno)); |
4440 | 4439 |
|
4441 |
- return fcntl_flags; |
|
4440 |
+ return (long)fcntl_flags; |
|
4442 | 4441 |
#else |
4443 |
- return 0L; |
|
4442 |
+ return -1L; |
|
4444 | 4443 |
#endif |
4445 | 4444 |
} |
4446 | 4445 |
|
... | ... |
@@ -4448,7 +4449,7 @@ static void |
4448 | 4448 |
restore_fcntl(int sock, long fcntl_flags) |
4449 | 4449 |
{ |
4450 | 4450 |
#ifdef F_SETFL |
4451 |
- if(fcntl_flags != -1) |
|
4451 |
+ if(fcntl_flags != -1L) |
|
4452 | 4452 |
if(fcntl(sock, F_SETFL, fcntl_flags)) { |
4453 | 4453 |
cli_warnmsg("restore_fcntl: restoring: fcntl(%d, F_SETFL): errno=%d: %s\n", |
4454 | 4454 |
sock, errno, strerror(errno)); |
... | ... |
@@ -4459,20 +4460,15 @@ restore_fcntl(int sock, long fcntl_flags) |
4459 | 4459 |
static int |
4460 | 4460 |
nonblock_connect(int sock, const struct sockaddr *addr, socklen_t addrlen, int secs) |
4461 | 4461 |
{ |
4462 |
- /* Max. of unexpected select() failures */ |
|
4463 |
- int select_failures = NONBLOCK_SELECT_MAX_FAILURES; |
|
4464 |
- /* Max. of useless loops */ |
|
4465 |
- int bogus_loops = NONBLOCK_MAX_BOGUS_LOOPS; |
|
4462 |
+ int select_failures; /* Max. of unexpected select() failures */ |
|
4463 |
+ int bogus_loops; /* Max. of useless loops */ |
|
4466 | 4464 |
struct timeval timeout; /* When we should time out */ |
4467 | 4465 |
int numfd; /* Highest fdset fd plus 1 */ |
4468 | 4466 |
|
4469 |
- /* Calculate into 'timeout' when we should time out */ |
|
4470 |
- gettimeofday(&timeout, 0); |
|
4471 |
- timeout.tv_sec += secs; |
|
4472 |
- |
|
4473 | 4467 |
/* Launch (possibly) non-blocking connect() request */ |
4474 | 4468 |
if(connect(sock, addr, addrlen)) { |
4475 | 4469 |
int e = errno; |
4470 |
+ |
|
4476 | 4471 |
cli_dbgmsg("nonblock_connect: connect(): fd=%d errno=%d: %s\n", |
4477 | 4472 |
sock, e, strerror(e)); |
4478 | 4473 |
switch (e) { |
... | ... |
@@ -4489,7 +4485,13 @@ nonblock_connect(int sock, const struct sockaddr *addr, socklen_t addrlen, int s |
4489 | 4489 |
} else |
4490 | 4490 |
return connect_error(sock); |
4491 | 4491 |
|
4492 |
+ /* Calculate into 'timeout' when we should time out */ |
|
4493 |
+ gettimeofday(&timeout, 0); |
|
4494 |
+ timeout.tv_sec += secs; |
|
4495 |
+ |
|
4492 | 4496 |
numfd = sock + 1; /* Highest fdset fd plus 1 */ |
4497 |
+ select_failures = NONBLOCK_SELECT_MAX_FAILURES; |
|
4498 |
+ bogus_loops = NONBLOCK_MAX_BOGUS_LOOPS; |
|
4493 | 4499 |
|
4494 | 4500 |
for (;;) { |
4495 | 4501 |
fd_set fds; |
... | ... |
@@ -4513,7 +4515,7 @@ nonblock_connect(int sock, const struct sockaddr *addr, socklen_t addrlen, int s |
4513 | 4513 |
FD_SET(sock, &fds); |
4514 | 4514 |
|
4515 | 4515 |
n = select(numfd, 0, &fds, 0, &waittime); |
4516 |
- if (n < 0) { |
|
4516 |
+ if(n < 0) { |
|
4517 | 4517 |
cli_warnmsg("nonblock_connect: select() failure %d: errno=%d: %s\n", |
4518 | 4518 |
select_failures, errno, strerror(errno)); |
4519 | 4519 |
if (--select_failures >= 0) |
... | ... |
@@ -4527,7 +4529,7 @@ nonblock_connect(int sock, const struct sockaddr *addr, socklen_t addrlen, int s |
4527 | 4527 |
return connect_error(sock); |
4528 | 4528 |
|
4529 | 4529 |
/* Select returned, but there is no work to do... */ |
4530 |
- if (--bogus_loops < 0) { |
|
4530 |
+ if(--bogus_loops < 0) { |
|
4531 | 4531 |
cli_warnmsg("nonblock_connect: giving up due to excessive bogus loops\n"); |
4532 | 4532 |
break; /* failed */ |
4533 | 4533 |
} |