summaryrefslogtreecommitdiff
path: root/usr.bin/compress
diff options
context:
space:
mode:
authorTodd C. Miller <millert@cvs.openbsd.org>2016-04-28 14:21:25 +0000
committerTodd C. Miller <millert@cvs.openbsd.org>2016-04-28 14:21:25 +0000
commitadc2de426ae23e1ae6dffc2ae80c3e8485d2b857 (patch)
treea61d0091b12b4e95ccc686b8c4b9d72ec4079e7e /usr.bin/compress
parenta58a3c8bb37719a9d05fb6c7f4b11e10f3f54b20 (diff)
Account for multiple streams in "gzip -l" output. This fixes "gzip
-l" output when used on package files. OK espie@ deraadt@
Diffstat (limited to 'usr.bin/compress')
-rw-r--r--usr.bin/compress/gzopen.c35
1 files changed, 24 insertions, 11 deletions
diff --git a/usr.bin/compress/gzopen.c b/usr.bin/compress/gzopen.c
index 5837ee7a611..b761d8760db 100644
--- a/usr.bin/compress/gzopen.c
+++ b/usr.bin/compress/gzopen.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: gzopen.c,v 1.29 2015/08/20 22:32:41 deraadt Exp $ */
+/* $OpenBSD: gzopen.c,v 1.30 2016/04/28 14:21:24 millert Exp $ */
/*
* Copyright (c) 1997 Michael Shalayeff
@@ -83,14 +83,15 @@
typedef
struct gz_stream {
int z_fd; /* .gz file */
- z_stream z_stream; /* libz stream */
int z_eof; /* set if end of input file */
+ z_stream z_stream; /* libz stream */
u_char z_buf[Z_BUFSIZE]; /* i/o buffer */
+ char z_mode; /* 'w' or 'r' */
u_int32_t z_time; /* timestamp (mtime) */
- u_int32_t z_hlen; /* length of the gz header */
u_int32_t z_crc; /* crc32 of uncompressed data */
- char z_mode; /* 'w' or 'r' */
-
+ u_int32_t z_hlen; /* length of the gz header */
+ u_int64_t z_total_in; /* # bytes in */
+ u_int64_t z_total_out; /* # bytes out */
} gz_stream;
static const u_char gz_magic[2] = {0x1f, 0x8b}; /* gzip magic header */
@@ -128,6 +129,8 @@ gz_open(int fd, const char *mode, char *name, int bits,
s->z_eof = 0;
s->z_time = 0;
s->z_hlen = 0;
+ s->z_total_in = 0;
+ s->z_total_out = 0;
s->z_crc = crc32(0L, Z_NULL, 0);
s->z_mode = mode[0];
@@ -206,8 +209,8 @@ gz_close(void *cookie, struct z_info *info, const char *name, struct stat *sb)
info->mtime = s->z_time;
info->crc = s->z_crc;
info->hlen = s->z_hlen;
- info->total_in = (off_t)s->z_stream.total_in;
- info->total_out = (off_t)s->z_stream.total_out;
+ info->total_in = s->z_total_in;
+ info->total_out = s->z_total_out;
}
setfile(name, s->z_fd, sb);
@@ -336,7 +339,7 @@ get_header(gz_stream *s, char *name, int gotmagic)
(void)get_byte(s);
(void)get_byte(s);
- s->z_hlen = 10; /* magic, method, flags, time, xflags, OS code */
+ s->z_hlen += 10; /* magic, method, flags, time, xflags, OS code */
if ((flags & EXTRA_FIELD) != 0) { /* skip the extra field */
len = (uInt)get_byte(s);
len += ((uInt)get_byte(s))<<8;
@@ -438,11 +441,11 @@ gz_read(void *cookie, char *buf, int len)
if (error == Z_DATA_ERROR) {
errno = EINVAL;
- return -1;
+ goto bad;
}
if (error == Z_BUF_ERROR) {
errno = EIO;
- return -1;
+ goto bad;
}
if (error == Z_STREAM_END) {
/* Check CRC and original size */
@@ -452,13 +455,18 @@ gz_read(void *cookie, char *buf, int len)
if (get_int32(s) != s->z_crc) {
errno = EINVAL;
- return -1;
+ goto bad;
}
if (get_int32(s) != (u_int32_t)s->z_stream.total_out) {
errno = EIO;
return -1;
}
s->z_hlen += 2 * sizeof(int32_t);
+
+ /* Add byte counts from the finished stream. */
+ s->z_total_in += s->z_stream.total_in;
+ s->z_total_out += s->z_stream.total_out;
+
/* Check for the existence of an appended file. */
if (get_header(s, NULL, 0) != 0) {
s->z_eof = 1;
@@ -474,6 +482,11 @@ gz_read(void *cookie, char *buf, int len)
len -= s->z_stream.avail_out;
return (len);
+bad:
+ /* Add byte counts from the finished stream. */
+ s->z_total_in += s->z_stream.total_in;
+ s->z_total_out += s->z_stream.total_out;
+ return (-1);
}
int