Package: analog Version: 2:6.0-17~lenny1 Severity: normal Tags: patch
Multi-stream bz2 files are created if you concatenate two "normal" bz2 files. Analog's current code stops at the end of the first stream. This happens without error, and simply shows up as an unexplained failure to read to the end of the log file. The attached patch checks if the end-of-stream is also the end-of-file, and if not, it opens the next stream and continues on. A workaround is to use UNCOMPRESS *.bz2 "bzcat" in your configuration file, thus overriding the built-in bzip code. -- System Information: Debian Release: 5.0 APT prefers stable APT policy: (500, 'stable') Architecture: i386 (i686) Kernel: Linux 2.6.26-1-686 (SMP w/2 CPU cores) Locale: LANG=en_IE.UTF-8, LC_CTYPE=en_IE.UTF-8 (charmap=UTF-8) Shell: /bin/sh linked to /bin/bash Versions of packages analog depends on: ii debconf [debconf-2.0] 1.5.24 Debian configuration management sy ii libbz2-1.0 1.0.5-1 high-quality block-sorting file co ii libc6 2.7-18 GNU C Library: Shared libraries ii libgd2-xpm 2.0.36~rc1~dfsg-3 GD Graphics Library version 2 ii libjpeg62 6b-14 The Independent JPEG Group's JPEG ii libpcre3 7.6-2.1 Perl 5 Compatible Regular Expressi ii libpng12-0 1.2.27-2+lenny2 PNG library - runtime ii perl 5.10.0-19 Larry Wall's Practical Extraction ii zlib1g 1:1.2.3.3.dfsg-12 compression library - runtime analog recommends no packages. Versions of packages analog suggests: ii apache2 2.2.9-10+lenny2 Apache HTTP Server metapackage ii apache2-mpm-prefork [htt 2.2.9-10+lenny2 Apache HTTP Server - traditional n pn rmagic <none> (no description available) -- debconf information excluded
--- input.c.old 2004-12-19 13:51:30.000000000 +0000 +++ input.c 2009-04-02 10:07:38.000000000 +0100 @@ -377,6 +377,9 @@ choice getmoredata(Logfile *lf, char *start, size_t length) { #ifndef LINE_PARSER int bze; + void* unusedPtr; + char* unusedData; + int unusedCount; #endif int n; @@ -397,9 +400,53 @@ n = 0; /* unzReadCurrentFile() returns -1 on error */ break; case LF_BZ2: - n = BZ2_bzRead(&bze, (BZFILE *)(lf->file2), (void *)start, length); - if (bze != BZ_OK && bze != BZ_STREAM_END) - n = 0; /* return value from BZ2_bzRead() undefined on error */ + n = 0; + // Multiple BZ2 streams may occur in a single file. If we reach the end of + // a stream before we have enough bytes, open the next stream and go again + while (n < length) { + n = n + BZ2_bzRead(&bze, (BZFILE *)(lf->file2), (void *)start + n, length - n); + + if (bze != BZ_OK && bze != BZ_STREAM_END) { + n = 0; /* return value from BZ2_bzRead() undefined on error */ + break; + } + + if (bze == BZ_STREAM_END) { + // Is this really the end of the file, or is there another stream? + // Check for "unused" data (see the bzip docs for what this is) + BZ2_bzReadGetUnused(&bze, (BZFILE *)(lf->file2), &unusedPtr, &unusedCount); + if (bze != BZ_OK) { + n = 0; // Something's wrong, give up + break; + } + + if (unusedCount == 0 && feof((FILE *)(lf->file))) { + break; // Real end-of-file + } + + // Put the unused data somewhere safe for a moment + unusedData = malloc(unusedCount); + memcpy(unusedData, unusedPtr, unusedCount); + + // Close the old stream + BZ2_bzReadClose(&bze, (BZFILE *)(lf->file2)); + if (bze != BZ_OK) { + n = 0; // Something's wrong, give up + break; + } + + // Open the new stream + lf->file2 = (void *)BZ2_bzReadOpen(&bze, (FILE *)(lf->file), + 0, 0, unusedData, unusedCount); + if (bze != BZ_OK || (BZFILE *)(lf->file2)==NULL) { + n = 0; // Something's wrong, give up + break; + } + + // Unused data is copied immediately by bzReadOpen + free(unusedData); + } + } break; #endif default: