| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: gzip.c,v 1.117 2021/06/24 07:16:49 simonb Exp $ */ | | 1 | /* $NetBSD: gzip.c,v 1.118 2022/01/22 14:00:45 christos 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.117 2021/06/24 07:16:49 simonb Exp $"); | | 34 | __RCSID("$NetBSD: gzip.c,v 1.118 2022/01/22 14:00:45 christos 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 |
| @@ -55,26 +55,27 @@ __RCSID("$NetBSD: gzip.c,v 1.117 2021/06 | | | @@ -55,26 +55,27 @@ __RCSID("$NetBSD: gzip.c,v 1.117 2021/06 |
55 | #include <unistd.h> | | 55 | #include <unistd.h> |
56 | #include <stdio.h> | | 56 | #include <stdio.h> |
57 | #include <string.h> | | 57 | #include <string.h> |
58 | #include <stdlib.h> | | 58 | #include <stdlib.h> |
59 | #include <err.h> | | 59 | #include <err.h> |
60 | #include <errno.h> | | 60 | #include <errno.h> |
61 | #include <fcntl.h> | | 61 | #include <fcntl.h> |
62 | #include <zlib.h> | | 62 | #include <zlib.h> |
63 | #include <fts.h> | | 63 | #include <fts.h> |
64 | #include <libgen.h> | | 64 | #include <libgen.h> |
65 | #include <stdarg.h> | | 65 | #include <stdarg.h> |
66 | #include <getopt.h> | | 66 | #include <getopt.h> |
67 | #include <time.h> | | 67 | #include <time.h> |
| | | 68 | #include <paths.h> |
68 | | | 69 | |
69 | #ifndef PRIdOFF | | 70 | #ifndef PRIdOFF |
70 | #define PRIdOFF PRId64 | | 71 | #define PRIdOFF PRId64 |
71 | #endif | | 72 | #endif |
72 | | | 73 | |
73 | /* what type of file are we dealing with */ | | 74 | /* what type of file are we dealing with */ |
74 | enum filetype { | | 75 | enum filetype { |
75 | FT_GZIP, | | 76 | FT_GZIP, |
76 | #ifndef NO_BZIP2_SUPPORT | | 77 | #ifndef NO_BZIP2_SUPPORT |
77 | FT_BZIP2, | | 78 | FT_BZIP2, |
78 | #endif | | 79 | #endif |
79 | #ifndef NO_COMPRESS_SUPPORT | | 80 | #ifndef NO_COMPRESS_SUPPORT |
80 | FT_Z, | | 81 | FT_Z, |
| @@ -1698,39 +1699,59 @@ file_uncompress(char *file, char *outfil | | | @@ -1698,39 +1699,59 @@ file_uncompress(char *file, char *outfil |
1698 | maybe_warnx("%s: unexpected end of file", file); | | 1699 | maybe_warnx("%s: unexpected end of file", file); |
1699 | lose: | | 1700 | lose: |
1700 | if (fd != -1) | | 1701 | if (fd != -1) |
1701 | close(fd); | | 1702 | close(fd); |
1702 | if (zfd != -1 && zfd != STDOUT_FILENO) | | 1703 | if (zfd != -1 && zfd != STDOUT_FILENO) |
1703 | close(fd); | | 1704 | close(fd); |
1704 | return -1; | | 1705 | return -1; |
1705 | } | | 1706 | } |
1706 | | | 1707 | |
1707 | #ifndef SMALL | | 1708 | #ifndef SMALL |
1708 | static void | | 1709 | static void |
1709 | check_siginfo(void) | | 1710 | check_siginfo(void) |
1710 | { | | 1711 | { |
| | | 1712 | static int ttyfd = -2; |
| | | 1713 | char buf[2048]; |
| | | 1714 | int n; |
| | | 1715 | |
1711 | if (print_info == 0) | | 1716 | if (print_info == 0) |
1712 | return; | | 1717 | return; |
1713 | if (infile) { | | 1718 | |
1714 | if (infile_total) { | | 1719 | if (!infile) |
1715 | int pcent = (int)((100.0 * infile_current) / infile_total); | | 1720 | goto out; |
1716 | | | 1721 | |
1717 | fprintf(stderr, "%s: done %llu/%llu bytes %d%%\n", | | 1722 | if (ttyfd == -2) |
1718 | infile, (unsigned long long)infile_current, | | 1723 | ttyfd = open(_PATH_TTY, O_RDWR | O_CLOEXEC); |
1719 | (unsigned long long)infile_total, pcent); | | 1724 | |
1720 | } else | | 1725 | if (ttyfd == -1) |
1721 | fprintf(stderr, "%s: done %llu bytes\n", | | 1726 | goto out; |
1722 | infile, (unsigned long long)infile_current); | | 1727 | |
| | | 1728 | if (infile_total) { |
| | | 1729 | const double pcent = (100.0 * infile_current) / infile_total; |
| | | 1730 | |
| | | 1731 | n = snprintf(buf, sizeof(buf), |
| | | 1732 | "%s: %s: done %ju/%ju bytes (%3.2f%%)\n", |
| | | 1733 | getprogname(), infile, (uintmax_t)infile_current, |
| | | 1734 | (uintmax_t)infile_total, pcent); |
| | | 1735 | } else { |
| | | 1736 | n = snprintf(buf, sizeof(buf), "%s: %s: done %ju bytes\n", |
| | | 1737 | getprogname(), infile, (uintmax_t)infile_current); |
1723 | } | | 1738 | } |
| | | 1739 | |
| | | 1740 | if (n <= 0) |
| | | 1741 | goto out; |
| | | 1742 | |
| | | 1743 | write(ttyfd, buf, (size_t)n); |
| | | 1744 | out: |
1724 | print_info = 0; | | 1745 | print_info = 0; |
1725 | } | | 1746 | } |
1726 | | | 1747 | |
1727 | static off_t | | 1748 | static off_t |
1728 | cat_fd(unsigned char * prepend, size_t count, off_t *gsizep, int fd) | | 1749 | cat_fd(unsigned char * prepend, size_t count, off_t *gsizep, int fd) |
1729 | { | | 1750 | { |
1730 | char buf[BUFLEN]; | | 1751 | char buf[BUFLEN]; |
1731 | off_t in_tot; | | 1752 | off_t in_tot; |
1732 | ssize_t w; | | 1753 | ssize_t w; |
1733 | | | 1754 | |
1734 | in_tot = count; | | 1755 | in_tot = count; |
1735 | w = write_retry(STDOUT_FILENO, prepend, count); | | 1756 | w = write_retry(STDOUT_FILENO, prepend, count); |
1736 | if (w == -1 || (size_t)w != count) { | | 1757 | if (w == -1 || (size_t)w != count) { |
| @@ -1873,42 +1894,42 @@ out: | | | @@ -1873,42 +1894,42 @@ out: |
1873 | } | | 1894 | } |
1874 | | | 1895 | |
1875 | static void | | 1896 | static void |
1876 | handle_stdout(void) | | 1897 | handle_stdout(void) |
1877 | { | | 1898 | { |
1878 | off_t gsize; | | 1899 | off_t gsize; |
1879 | #ifndef SMALL | | 1900 | #ifndef SMALL |
1880 | off_t usize; | | 1901 | off_t usize; |
1881 | struct stat sb; | | 1902 | struct stat sb; |
1882 | time_t systime; | | 1903 | time_t systime; |
1883 | uint32_t mtime; | | 1904 | uint32_t mtime; |
1884 | int ret; | | 1905 | int ret; |
1885 | | | 1906 | |
1886 | infile_set("(stdout)", 0); | | 1907 | infile_set("<stdout>", 0); |
1887 | | | 1908 | |
1888 | if (fflag == 0 && isatty(STDOUT_FILENO)) { | | 1909 | if (fflag == 0 && isatty(STDOUT_FILENO)) { |
1889 | maybe_warnx("standard output is a terminal -- ignoring"); | | 1910 | maybe_warnx("standard output is a terminal -- ignoring"); |
1890 | return; | | 1911 | return; |
1891 | } | | 1912 | } |
1892 | | | 1913 | |
1893 | /* If stdin is a file use its mtime, otherwise use current time */ | | 1914 | /* If stdin is a file use its mtime, otherwise use current time */ |
1894 | ret = fstat(STDIN_FILENO, &sb); | | 1915 | ret = fstat(STDIN_FILENO, &sb); |
1895 | if (ret < 0) { | | 1916 | if (ret < 0) { |
1896 | maybe_warn("Can't stat stdin"); | | 1917 | maybe_warn("Can't stat stdin"); |
1897 | return; | | 1918 | return; |
1898 | } | | 1919 | } |
1899 | | | 1920 | |
1900 | if (S_ISREG(sb.st_mode)) { | | 1921 | if (S_ISREG(sb.st_mode)) { |
1901 | infile_set("(stdout)", sb.st_size); | | 1922 | infile_set("<stdout>", sb.st_size); |
1902 | mtime = (uint32_t)sb.st_mtime; | | 1923 | mtime = (uint32_t)sb.st_mtime; |
1903 | } else { | | 1924 | } else { |
1904 | systime = time(NULL); | | 1925 | systime = time(NULL); |
1905 | if (systime == -1) { | | 1926 | if (systime == -1) { |
1906 | maybe_warn("time"); | | 1927 | maybe_warn("time"); |
1907 | return; | | 1928 | return; |
1908 | } | | 1929 | } |
1909 | mtime = (uint32_t)systime; | | 1930 | mtime = (uint32_t)systime; |
1910 | } | | 1931 | } |
1911 | | | 1932 | |
1912 | usize = | | 1933 | usize = |
1913 | #endif | | 1934 | #endif |
1914 | gz_compress(STDIN_FILENO, STDOUT_FILENO, &gsize, "", mtime); | | 1935 | gz_compress(STDIN_FILENO, STDOUT_FILENO, &gsize, "", mtime); |