git-svn: trunk@3729
aCaB authored on 2008/03/21 06:02:17... | ... |
@@ -1,3 +1,8 @@ |
1 |
+Thu Mar 20 21:06:30 CET 2008 (acab) |
|
2 |
+----------------------------------- |
|
3 |
+ * libclamav/blob.[ch]: Fix for "bad file descriptor" under win32, properly |
|
4 |
+ generate tempfiles, huge cleanup |
|
5 |
+ |
|
1 | 6 |
Thu Mar 20 20:55:37 CET 2008 (acab) |
2 | 7 |
----------------------------------- |
3 | 8 |
* libclamav: Remove fsync()'s. Win32 ports should greatly benefit from it |
... | ... |
@@ -494,8 +494,7 @@ fileblobDestroy(fileblob *fb) |
494 | 494 |
void |
495 | 495 |
fileblobSetFilename(fileblob *fb, const char *dir, const char *filename) |
496 | 496 |
{ |
497 |
- int fd; |
|
498 |
- char fullname[NAME_MAX + 1]; |
|
497 |
+ char *fullname; |
|
499 | 498 |
|
500 | 499 |
if(fb->b.name) |
501 | 500 |
return; |
... | ... |
@@ -512,78 +511,17 @@ fileblobSetFilename(fileblob *fb, const char *dir, const char *filename) |
512 | 512 |
filename = blobGetFilename(&fb->b); |
513 | 513 |
|
514 | 514 |
assert(filename != NULL); |
515 |
+ |
|
516 |
+ if (cli_gentempfd(dir, &fullname, &fb->fd)!=CL_SUCCESS) return; |
|
515 | 517 |
|
516 |
-#ifdef C_QNX6 |
|
517 |
- /* |
|
518 |
- * QNX6 support from mikep@kaluga.org to fix bug where mkstemp |
|
519 |
- * can return ETOOLONG even when the file name isn't too long |
|
520 |
- */ |
|
521 |
- snprintf(fullname, sizeof(fullname), "%s/clamavtmpXXXXXXXXXXXXX", dir); |
|
522 |
-#elif defined(C_WINDOWS) |
|
523 |
- sprintf_s(fullname, sizeof(fullname) - 1, "%s\\%.*sXXXXXX", dir, |
|
524 |
- (int)(sizeof(fullname) - 9 - strlen(dir)), filename); |
|
525 |
-#else |
|
526 |
- sprintf(fullname, "%s/%.*sXXXXXX", dir, |
|
527 |
- (int)(sizeof(fullname) - 9 - strlen(dir)), filename); |
|
528 |
-#endif |
|
529 |
- |
|
530 |
-#if defined(C_LINUX) || defined(C_BSD) || defined(HAVE_MKSTEMP) || defined(C_SOLARIS) || defined(C_CYGWIN) || defined(C_QNX6) |
|
531 |
- cli_dbgmsg("fileblobSetFilename: mkstemp(%s)\n", fullname); |
|
532 |
- /* |
|
533 |
- * On older Cygwin, mkstemp opened in O_TEXT mode, rather than |
|
534 |
- * O_BINARY. I understand this is now fixed, but I don't know in |
|
535 |
- * what version |
|
536 |
- * See http://cygwin.com/ml/cygwin-patches/2006-q2/msg00014.html |
|
537 |
- */ |
|
538 |
- fd = mkstemp(fullname); |
|
539 |
- if((fd < 0) && (errno == EINVAL)) { |
|
540 |
- /* |
|
541 |
- * This happens with some Linux flavours when (mis)handling |
|
542 |
- * filenames with foreign characters |
|
543 |
- */ |
|
544 |
- snprintf(fullname, sizeof(fullname), "%s/clamavtmpXXXXXXXXXXXXX", dir); |
|
545 |
- cli_dbgmsg("fileblobSetFilename: retry as mkstemp(%s)\n", fullname); |
|
546 |
- fd = mkstemp(fullname); |
|
547 |
- } |
|
548 |
-#elif defined(C_WINDOWS) |
|
549 |
- cli_dbgmsg("fileblobSetFilename: _mktemp_s(%s)\n", fullname); |
|
550 |
- if(_mktemp_s(fullname, strlen(fullname) + 1) != 0) { |
|
551 |
- char *name; |
|
552 |
- |
|
553 |
- /* _mktemp_s only allows 26 files */ |
|
554 |
- cli_dbgmsg("fileblobSetFilename: _mktemp_s(%s) failed: %s\n", fullname, strerror(errno)); |
|
555 |
- name = cli_gentemp(dir); |
|
556 |
- if(name == NULL) |
|
557 |
- return; |
|
558 |
- fd = open(name, O_WRONLY|O_CREAT|O_EXCL|O_TRUNC|O_BINARY, 0600); |
|
559 |
- if(fd >= 0) |
|
560 |
- strncpy(fullname, name, sizeof(fullname) - 1); |
|
561 |
- free(name); |
|
562 |
- } else |
|
563 |
- fd = open(fullname, O_WRONLY|O_CREAT|O_EXCL|O_TRUNC|O_BINARY, 0600); |
|
564 |
-#else |
|
565 |
- cli_dbgmsg("fileblobSetFilename: mktemp(%s)\n", fullname); |
|
566 |
- (void)mktemp(fullname); |
|
567 |
- fd = open(fullname, O_WRONLY|O_CREAT|O_EXCL|O_TRUNC|O_BINARY, 0600); |
|
568 |
-#endif |
|
569 |
- |
|
570 |
- if(fd < 0) { |
|
571 |
- cli_errmsg("Can't create temporary file %s: %s\n", fullname, strerror(errno)); |
|
572 |
- cli_dbgmsg("%lu %lu\n", (unsigned long)sizeof(fullname), |
|
573 |
- (unsigned long)strlen(fullname)); |
|
574 |
- return; |
|
575 |
- } |
|
518 |
+ cli_dbgmsg("fileblobSetFilename: file %s saved to %s\n", filename, fullname); |
|
576 | 519 |
|
577 |
- cli_dbgmsg("Creating %s\n", fullname); |
|
578 |
- |
|
579 |
- fb->fp = fdopen(fd, "wb"); |
|
520 |
+ fb->fp = fdopen(fb->fd, "wb"); |
|
580 | 521 |
|
581 | 522 |
if(fb->fp == NULL) { |
582 |
- cli_errmsg("Can't create file %s: %s\n", fullname, strerror(errno)); |
|
583 |
- cli_dbgmsg("%lu %lu\n", (unsigned long)sizeof(fullname), |
|
584 |
- (unsigned long)strlen(fullname)); |
|
585 |
- close(fd); |
|
586 |
- |
|
523 |
+ cli_errmsg("fileblobSetFilename: fdopen failed (%s)\n", strerror(errno)); |
|
524 |
+ close(fb->fd); |
|
525 |
+ free(fullname); |
|
587 | 526 |
return; |
588 | 527 |
} |
589 | 528 |
if(fb->b.data) |
... | ... |
@@ -593,13 +531,7 @@ fileblobSetFilename(fileblob *fb, const char *dir, const char *filename) |
593 | 593 |
fb->b.len = fb->b.size = 0; |
594 | 594 |
fb->isNotEmpty = 1; |
595 | 595 |
} |
596 |
- |
|
597 |
- /* |
|
598 |
- * If this strdup fails, then if the file is empty it won't be removed |
|
599 |
- * until later. Since this is only a trivial issue, there is no need |
|
600 |
- * to error if it fails to allocate |
|
601 |
- */ |
|
602 |
- fb->fullname = cli_strdup(fullname); |
|
596 |
+ fb->fullname = fullname; |
|
603 | 597 |
} |
604 | 598 |
|
605 | 599 |
int |
... | ... |
@@ -669,14 +601,12 @@ fileblobSetCTX(fileblob *fb, cli_ctx *ctx) |
669 | 669 |
int |
670 | 670 |
fileblobScan(const fileblob *fb) |
671 | 671 |
{ |
672 |
-#ifndef C_WINDOWS |
|
673 |
- int rc, fd; |
|
672 |
+ int rc; |
|
674 | 673 |
cli_file_t ftype; |
675 |
-#endif |
|
676 | 674 |
|
677 | 675 |
if(fb->isInfected) |
678 | 676 |
return CL_VIRUS; |
679 |
- if(fb->fullname == NULL) { |
|
677 |
+ if(fb->fp == NULL || fb->fullname == NULL) { |
|
680 | 678 |
/* shouldn't happen, scan called before fileblobSetFilename */ |
681 | 679 |
cli_warnmsg("fileblobScan, fullname == NULL\n"); |
682 | 680 |
return CL_ENULLARG; /* there is no CL_UNKNOWN */ |
... | ... |
@@ -686,49 +616,26 @@ fileblobScan(const fileblob *fb) |
686 | 686 |
cli_dbgmsg("fileblobScan, ctx == NULL\n"); |
687 | 687 |
return CL_CLEAN; /* there is no CL_UNKNOWN */ |
688 | 688 |
} |
689 |
-#ifndef C_WINDOWS |
|
690 |
- /* |
|
691 |
- * FIXME: On Windows, cli_readn gives "bad file descriptor" when called |
|
692 |
- * by cli_check_mydoom_log from the call to cli_magic_scandesc here |
|
693 |
- * which implies that the file descriptor is getting closed somewhere, |
|
694 |
- * but I can't see where. |
|
695 |
- * One possible fix would be to duplicate cli_scanfile here. |
|
696 |
- */ |
|
697 |
- fflush(fb->fp); |
|
698 |
- fd = dup(fileno(fb->fp)); |
|
699 |
- if(fd == -1) { |
|
700 |
- cli_warnmsg("%s: dup failed\n", fb->fullname); |
|
701 |
- return CL_CLEAN; |
|
702 |
- } |
|
703 |
- /* cli_scanfile is static :-( */ |
|
704 |
- /*if(cli_scanfile(fb->fullname, fb->ctx) == CL_VIRUS) { |
|
705 |
- cli_dbgmsg("%s is infected\n", fb->fullname); |
|
706 |
- return CL_VIRUS; |
|
707 |
- }*/ |
|
708 | 689 |
|
709 |
- rc = cli_magic_scandesc(fd, fb->ctx); |
|
690 |
+ fflush(fb->fp); |
|
691 |
+ lseek(fb->fd, 0, SEEK_SET); |
|
692 |
+ rc = cli_magic_scandesc(fb->fd, fb->ctx); |
|
710 | 693 |
|
711 | 694 |
if(rc == CL_CLEAN) { |
712 |
- lseek(fd, 0, SEEK_SET); |
|
713 |
- ftype = cli_filetype2(fd, fb->ctx->engine); |
|
695 |
+ lseek(fb->fd, 0, SEEK_SET); |
|
696 |
+ ftype = cli_filetype2(fb->fd, fb->ctx->engine); |
|
714 | 697 |
if(ftype >= CL_TYPE_TEXT_ASCII && ftype <= CL_TYPE_TEXT_UTF16BE) { |
715 |
- lseek(fd, 0, SEEK_SET); |
|
716 |
- rc = cli_scandesc(fd, fb->ctx, CL_TYPE_MAIL, 0, NULL, AC_SCAN_VIR); |
|
698 |
+ lseek(fb->fd, 0, SEEK_SET); |
|
699 |
+ rc = cli_scandesc(fb->fd, fb->ctx, CL_TYPE_MAIL, 0, NULL, AC_SCAN_VIR); |
|
717 | 700 |
} |
718 | 701 |
} |
719 | 702 |
|
720 |
- close(fd); |
|
721 |
- |
|
722 | 703 |
if(rc == CL_VIRUS) { |
723 | 704 |
cli_dbgmsg("%s is infected\n", fb->fullname); |
724 | 705 |
return CL_VIRUS; |
725 | 706 |
} |
726 | 707 |
cli_dbgmsg("%s is clean\n", fb->fullname); |
727 | 708 |
return CL_BREAK; |
728 |
-#else /*C_WINDOWS*/ |
|
729 |
- /* Ensure that the file is saved and scanned */ |
|
730 |
- return CL_CLEAN; /* there is no CL_UNKNOWN :-( */ |
|
731 |
-#endif /*C_WINDOWS*/ |
|
732 | 709 |
} |
733 | 710 |
|
734 | 711 |
/* |