git: a227908571da - main - unzip: add -O/-I encoding support

From: Warner Losh <imp_at_FreeBSD.org>
Date: Tue, 27 Jun 2023 17:00:21 UTC
The branch main has been updated by imp:

URL: https://cgit.FreeBSD.org/src/commit/?id=a227908571da056f66abb7263f965331303bf02f

commit a227908571da056f66abb7263f965331303bf02f
Author:     Mingye Wang <arthur200126@gmail.com>
AuthorDate: 2023-06-27 16:54:12 +0000
Commit:     Warner Losh <imp@FreeBSD.org>
CommitDate: 2023-06-27 16:55:26 +0000

    unzip: add -O/-I encoding support
    
    These are for compatibility with the info-zip version of unzip.
    
    PR: 271657
    Reviewed by: imp
    Pull Request: https://github.com/freebsd/freebsd-src/pull/752
---
 usr.bin/unzip/unzip.1 |  6 +++++-
 usr.bin/unzip/unzip.c | 11 +++++++++--
 2 files changed, 14 insertions(+), 3 deletions(-)

diff --git a/usr.bin/unzip/unzip.1 b/usr.bin/unzip/unzip.1
index 82e2c3a60ea0..436f1a928ce9 100644
--- a/usr.bin/unzip/unzip.1
+++ b/usr.bin/unzip/unzip.1
@@ -25,7 +25,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd January 2, 2023
+.Dd June 27, 2023
 .Dt UNZIP 1
 .Os
 .Sh NAME
@@ -34,6 +34,7 @@
 .Sh SYNOPSIS
 .Nm
 .Op Fl aCcfjLlnopqtuvy
+.Op { Fl O | Fl I No } Ar encoding
 .Op Fl d Ar dir
 .Op Fl x Ar pattern
 .Op Fl P Ar password
@@ -62,6 +63,9 @@ Update existing.
 Extract only files from the zipfile if a file with the same name
 already exists on disk and is older than the former.
 Otherwise, the file is silently skipped.
+.It Fl I Ar encoding
+.It Fl O Ar encoding
+Convert filenames from the specified encoding.
 .It Fl j
 Ignore directories stored in the zipfile; instead, extract all files
 directly into the extraction directory.
diff --git a/usr.bin/unzip/unzip.c b/usr.bin/unzip/unzip.c
index 578eaca9d772..1200aa53e7e3 100644
--- a/usr.bin/unzip/unzip.c
+++ b/usr.bin/unzip/unzip.c
@@ -59,6 +59,7 @@ static int		 C_opt;		/* match case-insensitively */
 static int		 c_opt;		/* extract to stdout */
 static const char	*d_arg;		/* directory */
 static int		 f_opt;		/* update existing files only */
+static char		*O_arg;		/* encoding */
 static int		 j_opt;		/* junk directories */
 static int		 L_opt;		/* lowercase names */
 static int		 n_opt;		/* never overwrite */
@@ -917,6 +918,9 @@ unzip(const char *fn)
 
 	ac(archive_read_support_format_zip(a));
 
+	if (O_arg)
+		ac(archive_read_set_format_option(a, "zip", "hdrcharset", O_arg));
+
 	if (P_arg)
 		archive_read_add_passphrase(a, P_arg);
 	else
@@ -999,7 +1003,7 @@ usage(void)
 {
 
 	fprintf(stderr,
-"Usage: unzip [-aCcfjLlnopqtuvyZ1] [-d dir] [-x pattern] [-P password] zipfile\n"
+"Usage: unzip [-aCcfjLlnopqtuvyZ1] [{-O|-I} encoding] [-d dir] [-x pattern] [-P password] zipfile\n"
 "             [member ...]\n");
 	exit(EXIT_FAILURE);
 }
@@ -1010,7 +1014,7 @@ getopts(int argc, char *argv[])
 	int opt;
 
 	optreset = optind = 1;
-	while ((opt = getopt(argc, argv, "aCcd:fjLlnopP:qtuvx:yZ1")) != -1)
+	while ((opt = getopt(argc, argv, "aCcd:fI:jLlnO:opP:qtuvx:yZ1")) != -1)
 		switch (opt) {
 		case '1':
 			Z1_opt = 1;
@@ -1030,6 +1034,9 @@ getopts(int argc, char *argv[])
 		case 'f':
 			f_opt = 1;
 			break;
+		case 'I':
+		case 'O':
+			O_arg = optarg;
 		case 'j':
 			j_opt = 1;
 			break;