| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: gzip.c,v 1.118 2022/01/22 14:00:45 christos Exp $ */ | | 1 | /* $NetBSD: gzip.c,v 1.119 2023/06/10 04:45:25 simonb Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * Copyright (c) 1997, 1998, 2003, 2004, 2006, 2008, 2009, 2010, 2011, 2015, 2017 | | 4 | * Copyright (c) 1997, 1998, 2003, 2004, 2006, 2008, 2009, 2010, 2011, 2015, 2017 |
5 | * Matthew R. Green | | 5 | * Matthew R. Green |
6 | * All rights reserved. | | 6 | * All rights reserved. |
7 | * | | 7 | * |
8 | * Redistribution and use in source and binary forms, with or without | | 8 | * Redistribution and use in source and binary forms, with or without |
9 | * modification, are permitted provided that the following conditions | | 9 | * modification, are permitted provided that the following conditions |
10 | * are met: | | 10 | * are met: |
11 | * 1. Redistributions of source code must retain the above copyright | | 11 | * 1. Redistributions of source code must retain the above copyright |
12 | * notice, this list of conditions and the following disclaimer. | | 12 | * notice, this list of conditions and the following disclaimer. |
13 | * 2. Redistributions in binary form must reproduce the above copyright | | 13 | * 2. Redistributions in binary form must reproduce the above copyright |
14 | * notice, this list of conditions and the following disclaimer in the | | 14 | * notice, this list of conditions and the following disclaimer in the |
| @@ -21,27 +21,27 @@ | | | @@ -21,27 +21,27 @@ |
21 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, | | 21 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
22 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | | 22 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
23 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED | | 23 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
24 | * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | | 24 | * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
25 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | | 25 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
26 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | | 26 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
27 | * SUCH DAMAGE. | | 27 | * SUCH DAMAGE. |
28 | */ | | 28 | */ |
29 | | | 29 | |
30 | #include <sys/cdefs.h> | | 30 | #include <sys/cdefs.h> |
31 | #ifndef lint | | 31 | #ifndef lint |
32 | __COPYRIGHT("@(#) Copyright (c) 1997, 1998, 2003, 2004, 2006, 2008,\ | | 32 | __COPYRIGHT("@(#) Copyright (c) 1997, 1998, 2003, 2004, 2006, 2008,\ |
33 | 2009, 2010, 2011, 2015, 2017 Matthew R. Green. All rights reserved."); | | 33 | 2009, 2010, 2011, 2015, 2017 Matthew R. Green. All rights reserved."); |
34 | __RCSID("$NetBSD: gzip.c,v 1.118 2022/01/22 14:00:45 christos Exp $"); | | 34 | __RCSID("$NetBSD: gzip.c,v 1.119 2023/06/10 04:45:25 simonb Exp $"); |
35 | #endif /* not lint */ | | 35 | #endif /* not lint */ |
36 | | | 36 | |
37 | /* | | 37 | /* |
38 | * gzip.c -- GPL free gzip using zlib. | | 38 | * gzip.c -- GPL free gzip using zlib. |
39 | * | | 39 | * |
40 | * RFC 1950 covers the zlib format | | 40 | * RFC 1950 covers the zlib format |
41 | * RFC 1951 covers the deflate format | | 41 | * RFC 1951 covers the deflate format |
42 | * RFC 1952 covers the gzip format | | 42 | * RFC 1952 covers the gzip format |
43 | * | | 43 | * |
44 | * TODO: | | 44 | * TODO: |
45 | * - use mmap where possible | | 45 | * - use mmap where possible |
46 | * - handle some signals better (remove outfile?) | | 46 | * - handle some signals better (remove outfile?) |
47 | * - make bzip2/compress -v/-t/-l support work as well as possible | | 47 | * - make bzip2/compress -v/-t/-l support work as well as possible |
| @@ -1390,27 +1390,27 @@ file_compress(char *file, char *outfile, | | | @@ -1390,27 +1390,27 @@ file_compress(char *file, char *outfile, |
1390 | maybe_warnx("leaving original %s", file); | | 1390 | maybe_warnx("leaving original %s", file); |
1391 | unlink(outfile); | | 1391 | unlink(outfile); |
1392 | return size; | | 1392 | return size; |
1393 | #endif | | 1393 | #endif |
1394 | } | | 1394 | } |
1395 | | | 1395 | |
1396 | /* uncompress the given file and remove the original */ | | 1396 | /* uncompress the given file and remove the original */ |
1397 | static off_t | | 1397 | static off_t |
1398 | file_uncompress(char *file, char *outfile, size_t outsize) | | 1398 | file_uncompress(char *file, char *outfile, size_t outsize) |
1399 | { | | 1399 | { |
1400 | struct stat isb, osb; | | 1400 | struct stat isb, osb; |
1401 | off_t size; | | 1401 | off_t size; |
1402 | ssize_t rbytes; | | 1402 | ssize_t rbytes; |
1403 | unsigned char header1[4]; | | 1403 | unsigned char fourbytes[4]; |
1404 | enum filetype method; | | 1404 | enum filetype method; |
1405 | int fd, ofd, zfd = -1; | | 1405 | int fd, ofd, zfd = -1; |
1406 | size_t in_size; | | 1406 | size_t in_size; |
1407 | #ifndef SMALL | | 1407 | #ifndef SMALL |
1408 | ssize_t rv; | | 1408 | ssize_t rv; |
1409 | time_t timestamp = 0; | | 1409 | time_t timestamp = 0; |
1410 | char name[PATH_MAX + 1]; | | 1410 | char name[PATH_MAX + 1]; |
1411 | #endif | | 1411 | #endif |
1412 | | | 1412 | |
1413 | /* gather the old name info */ | | 1413 | /* gather the old name info */ |
1414 | | | 1414 | |
1415 | fd = open(file, O_RDONLY); | | 1415 | fd = open(file, O_RDONLY); |
1416 | if (fd < 0) { | | 1416 | if (fd < 0) { |
| @@ -1424,66 +1424,66 @@ file_uncompress(char *file, char *outfil | | | @@ -1424,66 +1424,66 @@ file_uncompress(char *file, char *outfil |
1424 | } | | 1424 | } |
1425 | if (S_ISREG(isb.st_mode)) | | 1425 | if (S_ISREG(isb.st_mode)) |
1426 | in_size = isb.st_size; | | 1426 | in_size = isb.st_size; |
1427 | else | | 1427 | else |
1428 | in_size = 0; | | 1428 | in_size = 0; |
1429 | infile_set(file, in_size); | | 1429 | infile_set(file, in_size); |
1430 | | | 1430 | |
1431 | strlcpy(outfile, file, outsize); | | 1431 | strlcpy(outfile, file, outsize); |
1432 | if (check_suffix(outfile, 1) == NULL && !(cflag || lflag)) { | | 1432 | if (check_suffix(outfile, 1) == NULL && !(cflag || lflag)) { |
1433 | maybe_warnx("%s: unknown suffix -- ignored", file); | | 1433 | maybe_warnx("%s: unknown suffix -- ignored", file); |
1434 | goto lose; | | 1434 | goto lose; |
1435 | } | | 1435 | } |
1436 | | | 1436 | |
1437 | rbytes = read(fd, header1, sizeof header1); | | 1437 | rbytes = read(fd, fourbytes, sizeof fourbytes); |
1438 | if (rbytes != sizeof header1) { | | 1438 | if (rbytes != sizeof fourbytes) { |
1439 | /* we don't want to fail here. */ | | 1439 | /* we don't want to fail here. */ |
1440 | #ifndef SMALL | | 1440 | #ifndef SMALL |
1441 | if (fflag) | | 1441 | if (fflag) |
1442 | goto lose; | | 1442 | goto lose; |
1443 | #endif | | 1443 | #endif |
1444 | if (rbytes == -1) | | 1444 | if (rbytes == -1) |
1445 | maybe_warn("can't read %s", file); | | 1445 | maybe_warn("can't read %s", file); |
1446 | else | | 1446 | else |
1447 | goto unexpected_EOF; | | 1447 | goto unexpected_EOF; |
1448 | goto lose; | | 1448 | goto lose; |
1449 | } | | 1449 | } |
1450 | infile_newdata(rbytes); | | 1450 | infile_newdata(rbytes); |
1451 | | | 1451 | |
1452 | method = file_gettype(header1); | | 1452 | method = file_gettype(fourbytes); |
1453 | #ifndef SMALL | | 1453 | #ifndef SMALL |
1454 | if (fflag == 0 && method == FT_UNKNOWN) { | | 1454 | if (fflag == 0 && method == FT_UNKNOWN) { |
1455 | maybe_warnx("%s: not in gzip format", file); | | 1455 | maybe_warnx("%s: not in gzip format", file); |
1456 | goto lose; | | 1456 | goto lose; |
1457 | } | | 1457 | } |
1458 | | | 1458 | |
1459 | #endif | | 1459 | #endif |
1460 | | | 1460 | |
1461 | #ifndef SMALL | | 1461 | #ifndef SMALL |
1462 | if (method == FT_GZIP && Nflag) { | | 1462 | if (method == FT_GZIP && Nflag) { |
1463 | unsigned char ts[4]; /* timestamp */ | | 1463 | unsigned char ts[4]; /* timestamp */ |
1464 | | | 1464 | |
1465 | rv = pread(fd, ts, sizeof ts, GZIP_TIMESTAMP); | | 1465 | rv = pread(fd, ts, sizeof ts, GZIP_TIMESTAMP); |
1466 | if (rv >= 0 && rv < (ssize_t)(sizeof ts)) | | 1466 | if (rv >= 0 && rv < (ssize_t)(sizeof ts)) |
1467 | goto unexpected_EOF; | | 1467 | goto unexpected_EOF; |
1468 | if (rv == -1) { | | 1468 | if (rv == -1) { |
1469 | if (!fflag) | | 1469 | if (!fflag) |
1470 | maybe_warn("can't read %s", file); | | 1470 | maybe_warn("can't read %s", file); |
1471 | goto lose; | | 1471 | goto lose; |
1472 | } | | 1472 | } |
1473 | infile_newdata(rv); | | 1473 | infile_newdata(rv); |
1474 | timestamp = ts[3] << 24 | ts[2] << 16 | ts[1] << 8 | ts[0]; | | 1474 | timestamp = ts[3] << 24 | ts[2] << 16 | ts[1] << 8 | ts[0]; |
1475 | | | 1475 | |
1476 | if (header1[3] & ORIG_NAME) { | | 1476 | if (fourbytes[3] & ORIG_NAME) { |
1477 | rbytes = pread(fd, name, sizeof(name) - 1, GZIP_ORIGNAME); | | 1477 | rbytes = pread(fd, name, sizeof(name) - 1, GZIP_ORIGNAME); |
1478 | if (rbytes < 0) { | | 1478 | if (rbytes < 0) { |
1479 | maybe_warn("can't read %s", file); | | 1479 | maybe_warn("can't read %s", file); |
1480 | goto lose; | | 1480 | goto lose; |
1481 | } | | 1481 | } |
1482 | if (name[0] != '\0') { | | 1482 | if (name[0] != '\0') { |
1483 | char *dp, *nf; | | 1483 | char *dp, *nf; |
1484 | | | 1484 | |
1485 | /* Make sure that name is NUL-terminated */ | | 1485 | /* Make sure that name is NUL-terminated */ |
1486 | name[rbytes] = '\0'; | | 1486 | name[rbytes] = '\0'; |
1487 | | | 1487 | |
1488 | /* strip saved directory name */ | | 1488 | /* strip saved directory name */ |
1489 | nf = strrchr(name, '/'); | | 1489 | nf = strrchr(name, '/'); |
| @@ -1777,27 +1777,27 @@ cat_fd(unsigned char * prepend, size_t c | | | @@ -1777,27 +1777,27 @@ cat_fd(unsigned char * prepend, size_t c |
1777 | in_tot += rv; | | 1777 | in_tot += rv; |
1778 | } | | 1778 | } |
1779 | | | 1779 | |
1780 | if (gsizep) | | 1780 | if (gsizep) |
1781 | *gsizep = in_tot; | | 1781 | *gsizep = in_tot; |
1782 | return (in_tot); | | 1782 | return (in_tot); |
1783 | } | | 1783 | } |
1784 | #endif | | 1784 | #endif |
1785 | | | 1785 | |
1786 | static void | | 1786 | static void |
1787 | handle_stdin(void) | | 1787 | handle_stdin(void) |
1788 | { | | 1788 | { |
1789 | struct stat isb; | | 1789 | struct stat isb; |
1790 | unsigned char header1[4]; | | 1790 | unsigned char fourbytes[4]; |
1791 | size_t in_size; | | 1791 | size_t in_size; |
1792 | off_t usize, gsize; | | 1792 | off_t usize, gsize; |
1793 | enum filetype method; | | 1793 | enum filetype method; |
1794 | ssize_t bytes_read; | | 1794 | ssize_t bytes_read; |
1795 | #ifndef NO_COMPRESS_SUPPORT | | 1795 | #ifndef NO_COMPRESS_SUPPORT |
1796 | FILE *in; | | 1796 | FILE *in; |
1797 | #endif | | 1797 | #endif |
1798 | | | 1798 | |
1799 | #ifndef SMALL | | 1799 | #ifndef SMALL |
1800 | if (fflag == 0 && lflag == 0 && isatty(STDIN_FILENO)) { | | 1800 | if (fflag == 0 && lflag == 0 && isatty(STDIN_FILENO)) { |
1801 | maybe_warnx("standard input is a terminal -- ignoring"); | | 1801 | maybe_warnx("standard input is a terminal -- ignoring"); |
1802 | goto out; | | 1802 | goto out; |
1803 | } | | 1803 | } |
| @@ -1808,84 +1808,84 @@ handle_stdin(void) | | | @@ -1808,84 +1808,84 @@ handle_stdin(void) |
1808 | goto out; | | 1808 | goto out; |
1809 | } | | 1809 | } |
1810 | if (S_ISREG(isb.st_mode)) | | 1810 | if (S_ISREG(isb.st_mode)) |
1811 | in_size = isb.st_size; | | 1811 | in_size = isb.st_size; |
1812 | else | | 1812 | else |
1813 | in_size = 0; | | 1813 | in_size = 0; |
1814 | infile_set("(stdin)", in_size); | | 1814 | infile_set("(stdin)", in_size); |
1815 | | | 1815 | |
1816 | if (lflag) { | | 1816 | if (lflag) { |
1817 | print_list(STDIN_FILENO, in_size, infile, isb.st_mtime); | | 1817 | print_list(STDIN_FILENO, in_size, infile, isb.st_mtime); |
1818 | goto out; | | 1818 | goto out; |
1819 | } | | 1819 | } |
1820 | | | 1820 | |
1821 | bytes_read = read_retry(STDIN_FILENO, header1, sizeof header1); | | 1821 | bytes_read = read_retry(STDIN_FILENO, fourbytes, sizeof fourbytes); |
1822 | if (bytes_read == -1) { | | 1822 | if (bytes_read == -1) { |
1823 | maybe_warn("can't read stdin"); | | 1823 | maybe_warn("can't read stdin"); |
1824 | goto out; | | 1824 | goto out; |
1825 | } else if (bytes_read != sizeof(header1)) { | | 1825 | } else if (bytes_read != sizeof(fourbytes)) { |
1826 | maybe_warnx("(stdin): unexpected end of file"); | | 1826 | maybe_warnx("(stdin): unexpected end of file"); |
1827 | goto out; | | 1827 | goto out; |
1828 | } | | 1828 | } |
1829 | | | 1829 | |
1830 | method = file_gettype(header1); | | 1830 | method = file_gettype(fourbytes); |
1831 | switch (method) { | | 1831 | switch (method) { |
1832 | default: | | 1832 | default: |
1833 | #ifndef SMALL | | 1833 | #ifndef SMALL |
1834 | if (fflag == 0) { | | 1834 | if (fflag == 0) { |
1835 | maybe_warnx("unknown compression format"); | | 1835 | maybe_warnx("unknown compression format"); |
1836 | goto out; | | 1836 | goto out; |
1837 | } | | 1837 | } |
1838 | usize = cat_fd(header1, sizeof header1, &gsize, STDIN_FILENO); | | 1838 | usize = cat_fd(fourbytes, sizeof fourbytes, &gsize, STDIN_FILENO); |
1839 | break; | | 1839 | break; |
1840 | #endif | | 1840 | #endif |
1841 | case FT_GZIP: | | 1841 | case FT_GZIP: |
1842 | usize = gz_uncompress(STDIN_FILENO, STDOUT_FILENO, | | 1842 | usize = gz_uncompress(STDIN_FILENO, STDOUT_FILENO, |
1843 | (char *)header1, sizeof header1, &gsize, "(stdin)"); | | 1843 | (char *)fourbytes, sizeof fourbytes, &gsize, "(stdin)"); |
1844 | break; | | 1844 | break; |
1845 | #ifndef NO_BZIP2_SUPPORT | | 1845 | #ifndef NO_BZIP2_SUPPORT |
1846 | case FT_BZIP2: | | 1846 | case FT_BZIP2: |
1847 | usize = unbzip2(STDIN_FILENO, STDOUT_FILENO, | | 1847 | usize = unbzip2(STDIN_FILENO, STDOUT_FILENO, |
1848 | (char *)header1, sizeof header1, &gsize); | | 1848 | (char *)fourbytes, sizeof fourbytes, &gsize); |
1849 | break; | | 1849 | break; |
1850 | #endif | | 1850 | #endif |
1851 | #ifndef NO_COMPRESS_SUPPORT | | 1851 | #ifndef NO_COMPRESS_SUPPORT |
1852 | case FT_Z: | | 1852 | case FT_Z: |
1853 | if ((in = zdopen(STDIN_FILENO)) == NULL) { | | 1853 | if ((in = zdopen(STDIN_FILENO)) == NULL) { |
1854 | maybe_warnx("zopen of stdin"); | | 1854 | maybe_warnx("zopen of stdin"); |
1855 | goto out; | | 1855 | goto out; |
1856 | } | | 1856 | } |
1857 | | | 1857 | |
1858 | usize = zuncompress(in, stdout, (char *)header1, | | 1858 | usize = zuncompress(in, stdout, (char *)fourbytes, |
1859 | sizeof header1, &gsize); | | 1859 | sizeof fourbytes, &gsize); |
1860 | fclose(in); | | 1860 | fclose(in); |
1861 | break; | | 1861 | break; |
1862 | #endif | | 1862 | #endif |
1863 | #ifndef NO_PACK_SUPPORT | | 1863 | #ifndef NO_PACK_SUPPORT |
1864 | case FT_PACK: | | 1864 | case FT_PACK: |
1865 | usize = unpack(STDIN_FILENO, STDOUT_FILENO, | | 1865 | usize = unpack(STDIN_FILENO, STDOUT_FILENO, |
1866 | (char *)header1, sizeof header1, &gsize); | | 1866 | (char *)fourbytes, sizeof fourbytes, &gsize); |
1867 | break; | | 1867 | break; |
1868 | #endif | | 1868 | #endif |
1869 | #ifndef NO_XZ_SUPPORT | | 1869 | #ifndef NO_XZ_SUPPORT |
1870 | case FT_XZ: | | 1870 | case FT_XZ: |
1871 | usize = unxz(STDIN_FILENO, STDOUT_FILENO, | | 1871 | usize = unxz(STDIN_FILENO, STDOUT_FILENO, |
1872 | (char *)header1, sizeof header1, &gsize); | | 1872 | (char *)fourbytes, sizeof fourbytes, &gsize); |
1873 | break; | | 1873 | break; |
1874 | #endif | | 1874 | #endif |
1875 | #ifndef NO_LZ_SUPPORT | | 1875 | #ifndef NO_LZ_SUPPORT |
1876 | case FT_LZ: | | 1876 | case FT_LZ: |
1877 | usize = unlz(STDIN_FILENO, STDOUT_FILENO, | | 1877 | usize = unlz(STDIN_FILENO, STDOUT_FILENO, |
1878 | (char *)header1, sizeof header1, &gsize); | | 1878 | (char *)fourbytes, sizeof fourbytes, &gsize); |
1879 | break; | | 1879 | break; |
1880 | #endif | | 1880 | #endif |
1881 | } | | 1881 | } |
1882 | | | 1882 | |
1883 | #ifndef SMALL | | 1883 | #ifndef SMALL |
1884 | if (vflag && !tflag && usize != -1 && gsize != -1) | | 1884 | if (vflag && !tflag && usize != -1 && gsize != -1) |
1885 | print_verbage(NULL, NULL, usize, gsize); | | 1885 | print_verbage(NULL, NULL, usize, gsize); |
1886 | if (vflag && tflag) | | 1886 | if (vflag && tflag) |
1887 | print_test("(stdin)", usize != -1); | | 1887 | print_test("(stdin)", usize != -1); |
1888 | #else | | 1888 | #else |
1889 | (void)&usize; | | 1889 | (void)&usize; |
1890 | #endif | | 1890 | #endif |
1891 | | | 1891 | |