Skip to content

Commit 27ca511

Browse files
committed
unzip: use libarchive-style getopt() implementation
1 parent a8578c0 commit 27ca511

8 files changed

Lines changed: 348 additions & 45 deletions

File tree

CMakeLists.txt

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -696,7 +696,6 @@ int main(void) { return EXT2_IOC_GETFLAGS; }" HAVE_WORKING_EXT2_IOC_GETFLAGS)
696696

697697
LA_CHECK_INCLUDE_FILE("fcntl.h" HAVE_FCNTL_H)
698698
LA_CHECK_INCLUDE_FILE("fnmatch.h" HAVE_FNMATCH_H)
699-
LA_CHECK_INCLUDE_FILE("getopt.h" HAVE_GETOPT_H)
700699
LA_CHECK_INCLUDE_FILE("grp.h" HAVE_GRP_H)
701700
LA_CHECK_INCLUDE_FILE("inttypes.h" HAVE_INTTYPES_H)
702701
LA_CHECK_INCLUDE_FILE("io.h" HAVE_IO_H)
@@ -1489,10 +1488,6 @@ CHECK_C_SOURCE_COMPILES(
14891488
"#include <fcntl.h>\n#include <unistd.h>\nint main() {char buf[10]; return readlinkat(AT_FDCWD, \"\", buf, 0);}"
14901489
HAVE_READLINKAT)
14911490

1492-
# Check for getopt uses optreset to reset
1493-
CHECK_SYMBOL_EXISTS(optreset "getopt.h" HAVE_GETOPT_OPTRESET)
1494-
1495-
14961491
# To verify major(), we need to both include the header
14971492
# of interest and verify that the result can be linked.
14981493
# CHECK_FUNCTION_EXISTS doesn't accept a header argument,

Makefile.am

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1451,7 +1451,9 @@ bsdcat_test_EXTRA_DIST= \
14511451

14521452
bsdunzip_SOURCES= \
14531453
unzip/bsdunzip.c \
1454+
unzip/bsdunzip.h \
14541455
unzip/bsdunzip_platform.h \
1456+
unzip/cmdline.c \
14551457
unzip/la_getline.c \
14561458
unzip/la_queue.h
14571459

@@ -1489,7 +1491,7 @@ bsdunzip_programs=
14891491
endif
14901492

14911493
#
1492-
# bsdcat_test
1494+
# bsdunzip_test
14931495
#
14941496

14951497
bsdunzip_test_SOURCES= \

build/cmake/config.h.in

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -648,12 +648,6 @@ typedef uint64_t uintmax_t;
648648
/* Define to 1 if you have the `getline' function. */
649649
#cmakedefine HAVE_GETLINE 1
650650

651-
/* Define to 1 if you have the <getopt.h> header file. */
652-
#cmakedefine HAVE_GETOPT_H 1
653-
654-
/* Define to 1 if platform uses `optreset` to reset `getopt` */
655-
#cmakedefine HAVE_GETOPT_OPTRESET 1
656-
657651
/* Define to 1 if you have the `getpid' function. */
658652
#cmakedefine HAVE_GETPID 1
659653

configure.ac

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,7 @@ AC_HEADER_DIRENT
329329
AC_HEADER_SYS_WAIT
330330
AC_CHECK_HEADERS([acl/libacl.h attr/xattr.h])
331331
AC_CHECK_HEADERS([copyfile.h ctype.h])
332-
AC_CHECK_HEADERS([errno.h ext2fs/ext2_fs.h fcntl.h fnmatch.h getopt.h grp.h])
332+
AC_CHECK_HEADERS([errno.h ext2fs/ext2_fs.h fcntl.h fnmatch.h grp.h])
333333

334334
AC_CACHE_CHECK([whether EXT2_IOC_GETFLAGS is usable],
335335
[ac_cv_have_decl_EXT2_IOC_GETFLAGS],
@@ -837,11 +837,6 @@ AC_CHECK_MEMBER(struct dirent.d_namlen,,,
837837
#endif
838838
])
839839

840-
AC_CHECK_DECL([optreset],
841-
[AC_DEFINE(HAVE_GETOPT_OPTRESET, 1, [Platform uses optreset to reset getopt])],
842-
[],
843-
[#include <getopt.h>])
844-
845840
# Check for Extended Attributes support
846841
AC_ARG_ENABLE([xattr],
847842
AS_HELP_STRING([--disable-xattr],

unzip/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@ IF(ENABLE_UNZIP)
77

88
SET(bsdunzip_SOURCES
99
bsdunzip.c
10+
bsdunzip.h
1011
bsdunzip_platform.h
12+
cmdline.c
1113
la_getline.c
1214
la_queue.h
1315
../libarchive_fe/err.c

unzip/bsdunzip.c

Lines changed: 29 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,6 @@
5959
#ifdef HAVE_FNMATCH_H
6060
#include <fnmatch.h>
6161
#endif
62-
#ifdef HAVE_GETOPT_H
63-
#include <getopt.h>
64-
#endif
6562
#ifdef HAVE_STDARG_H
6663
#include <stdarg.h>
6764
#endif
@@ -82,8 +79,7 @@
8279
#endif
8380
#endif
8481

85-
#include <archive.h>
86-
#include <archive_entry.h>
82+
#include "bsdunzip.h"
8783
#include "passphrase.h"
8884
#include "err.h"
8985

@@ -93,13 +89,13 @@ static int C_opt; /* match case-insensitively */
9389
static int c_opt; /* extract to stdout */
9490
static const char *d_arg; /* directory */
9591
static int f_opt; /* update existing files only */
96-
static char *O_arg; /* encoding */
92+
static const char *O_arg; /* encoding */
9793
static int j_opt; /* junk directories */
9894
static int L_opt; /* lowercase names */
9995
static int n_opt; /* never overwrite */
10096
static int o_opt; /* always overwrite */
10197
static int p_opt; /* extract to stdout, quiet */
102-
static char *P_arg; /* passphrase */
98+
static const char *P_arg; /* passphrase */
10399
static int q_opt; /* quiet */
104100
static int t_opt; /* test */
105101
static int u_opt; /* update */
@@ -117,6 +113,8 @@ static int zipinfo_mode;
117113
/* running on tty? */
118114
static int tty;
119115

116+
int bsdunzip_optind;
117+
120118
/* convenience macro */
121119
/* XXX should differentiate between ARCHIVE_{WARN,FAIL,RETRY} */
122120
#define ac(call) \
@@ -1105,25 +1103,18 @@ version(void)
11051103
static int
11061104
getopts(int argc, char *argv[])
11071105
{
1106+
struct bsdunzip *bsdunzip, bsdunzip_storage;
11081107
int opt;
1108+
bsdunzip_optind = 1;
11091109

1110-
static struct option longopts[] = {
1111-
{ "version", no_argument, &version_opt, 1 },
1112-
{ 0, 0, 0, 0}
1113-
};
1110+
bsdunzip = &bsdunzip_storage;
1111+
memset(bsdunzip, 0, sizeof(*bsdunzip));
11141112

1115-
optind = 1;
1116-
#ifdef HAVE_GETOPT_OPTRESET
1117-
optreset = 1;
1118-
#endif
1119-
while ((opt = getopt_long(argc, argv,
1120-
"aCcd:fI:jLlnO:opP:qtuvx:yZ1", longopts, NULL)) != -1) {
1113+
bsdunzip->argv = argv;
1114+
bsdunzip->argc = argc;
1115+
1116+
while ((opt = bsdunzip_getopt(bsdunzip)) != -1) {
11211117
switch (opt) {
1122-
case 0:
1123-
break;
1124-
case '1':
1125-
Z1_opt = 1;
1126-
break;
11271118
case 'a':
11281119
a_opt = 1;
11291120
break;
@@ -1134,14 +1125,14 @@ getopts(int argc, char *argv[])
11341125
c_opt = 1;
11351126
break;
11361127
case 'd':
1137-
d_arg = optarg;
1128+
d_arg = bsdunzip->argument;
11381129
break;
11391130
case 'f':
11401131
f_opt = 1;
11411132
break;
11421133
case 'I':
11431134
case 'O':
1144-
O_arg = optarg;
1135+
O_arg = bsdunzip->argument;
11451136
break;
11461137
case 'j':
11471138
j_opt = 1;
@@ -1164,7 +1155,7 @@ getopts(int argc, char *argv[])
11641155
p_opt = 1;
11651156
break;
11661157
case 'P':
1167-
P_arg = optarg;
1158+
P_arg = bsdunzip->argument;
11681159
break;
11691160
case 'q':
11701161
q_opt = 1;
@@ -1179,19 +1170,30 @@ getopts(int argc, char *argv[])
11791170
v_opt = 2;
11801171
break;
11811172
case 'x':
1182-
add_pattern(&exclude, optarg);
1173+
add_pattern(&exclude, bsdunzip->argument);
11831174
break;
11841175
case 'y':
11851176
y_str = " ";
11861177
break;
11871178
case 'Z':
11881179
zipinfo_mode = 1;
1180+
if (bsdunzip->argument != NULL &&
1181+
strcmp(bsdunzip->argument, "1") == 0) {
1182+
Z1_opt = 1;
1183+
}
1184+
break;
1185+
case OPTION_VERSION:
1186+
version_opt = 1;
1187+
break;
1188+
case OPTION_NONE:
11891189
break;
11901190
default:
11911191
usage();
11921192
}
1193+
if (opt == OPTION_NONE)
1194+
break;
11931195
}
1194-
return (optind);
1196+
return (bsdunzip_optind);
11951197
}
11961198

11971199
int

unzip/bsdunzip.h

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/*-
2+
* Copyright (c) 2023, Martin Matuska
3+
* All rights reserved.
4+
*
5+
* Redistribution and use in source and binary forms, with or without
6+
* modification, are permitted provided that the following conditions
7+
* are met:
8+
* 1. Redistributions of source code must retain the above copyright
9+
* notice, this list of conditions and the following disclaimer.
10+
* 2. Redistributions in binary form must reproduce the above copyright
11+
* notice, this list of conditions and the following disclaimer in the
12+
* documentation and/or other materials provided with the distribution.
13+
*
14+
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
15+
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16+
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17+
* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
18+
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19+
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20+
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21+
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23+
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24+
*/
25+
26+
#ifndef BSDUNZIP_H_INCLUDED
27+
#define BSDUNZIP_H_INCLUDED
28+
29+
#if defined(PLATFORM_CONFIG_H)
30+
/* Use hand-built config.h in environments that need it. */
31+
#include PLATFORM_CONFIG_H
32+
#else
33+
/* Not having a config.h of some sort is a serious problem. */
34+
#include "config.h"
35+
#endif
36+
37+
#include <archive.h>
38+
#include <archive_entry.h>
39+
40+
struct bsdunzip {
41+
/* Option parser state */
42+
int getopt_state;
43+
char *getopt_word;
44+
45+
/* Miscellaneous state information */
46+
int argc;
47+
char **argv;
48+
const char *argument;
49+
};
50+
51+
struct bsdunzip_getopt_ret {
52+
int index;
53+
int opt;
54+
};
55+
56+
enum {
57+
OPTION_NONE,
58+
OPTION_VERSION
59+
};
60+
61+
int bsdunzip_getopt(struct bsdunzip *);
62+
63+
#endif

0 commit comments

Comments
 (0)