--- ./regress/fread.c.orig	2022-06-13 09:00:23 +0000
+++ ./regress/fread.c	2022-06-13 09:02:45 +0000
@@ -36,12 +36,193 @@
 #include <stdio.h>
 #include <stdlib.h>
 
-#ifndef HAVE_GETOPT
-#include "getopt.h"
-#endif
-
 #include "zip.h"
 
+#include <string.h>
+
+struct option
+{
+        const char *name;
+        int                     has_arg;
+        int                *flag;
+        int                     val;
+};
+
+#define no_argument 0
+#define required_argument 1
+#define optional_argument 2
+
+#define BADCH   '?'
+#define BADARG  ':'
+#define EMSG    ""
+
+
+/*
+ * getopt_long
+ *      Parse argc/argv argument vector, with long options.
+ *
+ * This implementation does not use optreset.  Instead, we guarantee that
+ * it can be restarted on a new argv array after a previous call returned -1,
+ * if the caller resets optind to 1 before the first call of the new series.
+ * (Internally, this means we must be sure to reset "place" to EMSG before
+ * returning -1.)
+ */
+int
+getopt_long(int argc, char *const argv[],
+                        const char *optstring,
+                        const struct option *longopts, int *longindex)
+{
+        static char *place = EMSG;      /* option letter processing */
+        char       *oli;                        /* option letter list index */
+
+        if (!*place)
+        {                                                       /* update scanning pointer */
+                if (optind >= argc)
+                {
+                        place = EMSG;
+                        return -1;
+                }
+
+                place = argv[optind];
+
+                if (place[0] != '-')
+                {
+                        place = EMSG;
+                        return -1;
+                }
+
+                place++;
+
+                if (place[0] && place[0] == '-' && place[1] == '\0')
+                {                                               /* found "--" */
+                        ++optind;
+                        place = EMSG;
+                        return -1;
+                }
+
+                if (place[0] && place[0] == '-' && place[1])
+                {
+                        /* long option */
+                        size_t          namelen;
+                        int                     i;
+
+                        place++;
+
+                        namelen = strcspn(place, "=");
+                        for (i = 0; longopts[i].name != NULL; i++)
+                        {
+                                if (strlen(longopts[i].name) == namelen
+                                        && strncmp(place, longopts[i].name, namelen) == 0)
+                                {
+                                        int                     has_arg = longopts[i].has_arg;
+
+                                        if (has_arg != no_argument)
+                                        {
+                                                if (place[namelen] == '=')
+                                                        optarg = place + namelen + 1;
+                                                else if (optind < argc - 1 &&
+                                                                 has_arg == required_argument)
+                                                {
+                                                        optind++;
+                                                        optarg = argv[optind];
+                                                }
+                                                else
+                                                {
+                                                        if (optstring[0] == ':')
+                                                                return BADARG;
+
+                                                        if (opterr && has_arg == required_argument)
+                                                                fprintf(stderr,
+                                                                                "%s: option requires an argument -- %s\n",
+                                                                                argv[0], place);
+
+                                                        place = EMSG;
+                                                        optind++;
+
+                                                        if (has_arg == required_argument)
+                                                                return BADCH;
+                                                        optarg = NULL;
+                                                }
+                                        }
+                                        else
+                                        {
+                                                optarg = NULL;
+                                                if (place[namelen] != 0)
+                                                {
+                                                        /* XXX error? */
+                                                }
+                                        }
+
+                                        optind++;
+
+                                        if (longindex)
+                                                *longindex = i;
+
+                                        place = EMSG;
+
+                                        if (longopts[i].flag == NULL)
+                                                return longopts[i].val;
+                                        else
+                                        {
+                                                *longopts[i].flag = longopts[i].val;
+                                                return 0;
+                                        }
+                                }
+                        }
+
+                        if (opterr && optstring[0] != ':')
+                                fprintf(stderr,
+                                                "%s: illegal option -- %s\n", argv[0], place);
+                        place = EMSG;
+                        optind++;
+                        return BADCH;
+                }
+        }
+
+        /* short option */
+        optopt = (int) *place++;
+
+        oli = strchr(optstring, optopt);
+        if (!oli)
+        {
+                if (!*place)
+                        ++optind;
+                if (opterr && *optstring != ':')
+                        fprintf(stderr,
+                                        "%s: illegal option -- %c\n", argv[0], optopt);
+                return BADCH;
+        }
+
+        if (oli[1] != ':')
+        {                                                       /* don't need argument */
+                optarg = NULL;
+                if (!*place)
+                        ++optind;
+        }
+        else
+        {                                                       /* need an argument */
+                if (*place)                             /* no white space */
+                        optarg = place;
+                else if (argc <= ++optind)
+                {                                               /* no arg */
+                        place = EMSG;
+                        if (*optstring == ':')
+                                return BADARG;
+                        if (opterr)
+                                fprintf(stderr,
+                                                "%s: option requires an argument -- %c\n",
+                                                argv[0], optopt);
+                        return BADCH;
+                }
+                else
+                        /* white space */
+                        optarg = argv[optind];
+                place = EMSG;
+                ++optind;
+        }
+        return optopt;
+}
+
 enum when { WHEN_NEVER, WHEN_OPEN, WHEN_READ, WHEN_CLOSE };
 
 const char *when_name[] = {"no", "zip_fopen", "zip_fread", "zip_fclose"};
--- ./regress/tryopen.c.orig	2022-06-13 09:08:00 +0000
+++ ./regress/tryopen.c	2022-06-13 09:10:02 +0000
@@ -36,9 +36,190 @@
 #include <errno.h>
 #include <stdio.h>
 
-#ifndef HAVE_GETOPT
-#include "getopt.h"
-#endif
+#include <string.h>
+
+struct option
+{
+        const char *name;
+        int                     has_arg;
+        int                *flag;
+        int                     val;
+};
+
+#define no_argument 0
+#define required_argument 1
+#define optional_argument 2
+
+#define BADCH   '?'
+#define BADARG  ':'
+#define EMSG    ""
+
+
+/*
+ * getopt_long
+ *      Parse argc/argv argument vector, with long options.
+ *
+ * This implementation does not use optreset.  Instead, we guarantee that
+ * it can be restarted on a new argv array after a previous call returned -1,
+ * if the caller resets optind to 1 before the first call of the new series.
+ * (Internally, this means we must be sure to reset "place" to EMSG before
+ * returning -1.)
+ */
+int
+getopt_long(int argc, char *const argv[],
+                        const char *optstring,
+                        const struct option *longopts, int *longindex)
+{
+        static char *place = EMSG;      /* option letter processing */
+        char       *oli;                        /* option letter list index */
+
+        if (!*place)
+        {                                                       /* update scanning pointer */
+                if (optind >= argc)
+                {
+                        place = EMSG;
+                        return -1;
+                }
+
+                place = argv[optind];
+
+                if (place[0] != '-')
+                {
+                        place = EMSG;
+                        return -1;
+                }
+
+                place++;
+
+                if (place[0] && place[0] == '-' && place[1] == '\0')
+                {                                               /* found "--" */
+                        ++optind;
+                        place = EMSG;
+                        return -1;
+                }
+
+                if (place[0] && place[0] == '-' && place[1])
+                {
+                        /* long option */
+                        size_t          namelen;
+                        int                     i;
+
+                        place++;
+
+                        namelen = strcspn(place, "=");
+                        for (i = 0; longopts[i].name != NULL; i++)
+                        {
+                                if (strlen(longopts[i].name) == namelen
+                                        && strncmp(place, longopts[i].name, namelen) == 0)
+                                {
+                                        int                     has_arg = longopts[i].has_arg;
+
+                                        if (has_arg != no_argument)
+                                        {
+                                                if (place[namelen] == '=')
+                                                        optarg = place + namelen + 1;
+                                                else if (optind < argc - 1 &&
+                                                                 has_arg == required_argument)
+                                                {
+                                                        optind++;
+                                                        optarg = argv[optind];
+                                                }
+                                                else
+                                                {
+                                                        if (optstring[0] == ':')
+                                                                return BADARG;
+
+                                                        if (opterr && has_arg == required_argument)
+                                                                fprintf(stderr,
+                                                                                "%s: option requires an argument -- %s\n",
+                                                                                argv[0], place);
+
+                                                        place = EMSG;
+                                                        optind++;
+
+                                                        if (has_arg == required_argument)
+                                                                return BADCH;
+                                                        optarg = NULL;
+                                                }
+                                        }
+                                        else
+                                        {
+                                                optarg = NULL;
+                                                if (place[namelen] != 0)
+                                                {
+                                                        /* XXX error? */
+                                                }
+                                        }
+
+                                        optind++;
+
+                                        if (longindex)
+                                                *longindex = i;
+
+                                        place = EMSG;
+
+                                        if (longopts[i].flag == NULL)
+                                                return longopts[i].val;
+                                        else
+                                        {
+                                                *longopts[i].flag = longopts[i].val;
+                                                return 0;
+                                        }
+                                }
+                        }
+
+                        if (opterr && optstring[0] != ':')
+                                fprintf(stderr,
+                                                "%s: illegal option -- %s\n", argv[0], place);
+                        place = EMSG;
+                        optind++;
+                        return BADCH;
+                }
+        }
+
+        /* short option */
+        optopt = (int) *place++;
+
+        oli = strchr(optstring, optopt);
+        if (!oli)
+        {
+                if (!*place)
+                        ++optind;
+                if (opterr && *optstring != ':')
+                        fprintf(stderr,
+                                        "%s: illegal option -- %c\n", argv[0], optopt);
+                return BADCH;
+        }
+
+        if (oli[1] != ':')
+        {                                                       /* don't need argument */
+                optarg = NULL;
+                if (!*place)
+                        ++optind;
+        }
+        else
+        {                                                       /* need an argument */
+                if (*place)                             /* no white space */
+                        optarg = place;
+                else if (argc <= ++optind)
+                {                                               /* no arg */
+                        place = EMSG;
+                        if (*optstring == ':')
+                                return BADARG;
+                        if (opterr)
+                                fprintf(stderr,
+                                                "%s: option requires an argument -- %c\n",
+                                                argv[0], optopt);
+                        return BADCH;
+                }
+                else
+                        /* white space */
+                        optarg = argv[optind];
+                place = EMSG;
+                ++optind;
+        }
+        return optopt;
+}
 
 #include "zip.h"
 #define TRYOPEN_USAGE                  \
--- ./regress/hole.c.orig	2022-06-14 23:41:44 +0000
+++ ./regress/hole.c	2022-06-14 23:43:49 +0000
@@ -36,9 +36,191 @@
 #include <stdio.h>
 #include <stdlib.h>
 
-#ifndef HAVE_GETOPT
-#include "getopt.h"
-#endif
+#include <string.h>
+
+struct option
+{
+        const char *name;
+        int                     has_arg;
+        int                *flag;
+        int                     val;
+};
+
+#define no_argument 0
+#define required_argument 1
+#define optional_argument 2
+
+#define BADCH   '?'
+#define BADARG  ':'
+#define EMSG    ""
+
+
+/*
+ * getopt_long
+ *      Parse argc/argv argument vector, with long options.
+ *
+ * This implementation does not use optreset.  Instead, we guarantee that
+ * it can be restarted on a new argv array after a previous call returned -1,
+ * if the caller resets optind to 1 before the first call of the new series.
+ * (Internally, this means we must be sure to reset "place" to EMSG before
+ * returning -1.)
+ */
+int
+getopt_long(int argc, char *const argv[],
+                        const char *optstring,
+                        const struct option *longopts, int *longindex)
+{
+        static char *place = EMSG;      /* option letter processing */
+        char       *oli;                        /* option letter list index */
+
+        if (!*place)
+        {                                                       /* update scanning pointer */
+                if (optind >= argc)
+                {
+                        place = EMSG;
+                        return -1;
+                }
+
+                place = argv[optind];
+
+                if (place[0] != '-')
+                {
+                        place = EMSG;
+                        return -1;
+                }
+
+                place++;
+
+                if (place[0] && place[0] == '-' && place[1] == '\0')
+                {                                               /* found "--" */
+                        ++optind;
+                        place = EMSG;
+                        return -1;
+                }
+
+                if (place[0] && place[0] == '-' && place[1])
+                {
+                        /* long option */
+                        size_t          namelen;
+                        int                     i;
+
+                        place++;
+
+                        namelen = strcspn(place, "=");
+                        for (i = 0; longopts[i].name != NULL; i++)
+                        {
+                                if (strlen(longopts[i].name) == namelen
+                                        && strncmp(place, longopts[i].name, namelen) == 0)
+                                {
+                                        int                     has_arg = longopts[i].has_arg;
+
+                                        if (has_arg != no_argument)
+                                        {
+                                                if (place[namelen] == '=')
+                                                        optarg = place + namelen + 1;
+                                                else if (optind < argc - 1 &&
+                                                                 has_arg == required_argument)
+                                                {
+                                                        optind++;
+                                                        optarg = argv[optind];
+                                                }
+                                                else
+                                                {
+                                                        if (optstring[0] == ':')
+                                                                return BADARG;
+
+                                                        if (opterr && has_arg == required_argument)
+                                                                fprintf(stderr,
+                                                                                "%s: option requires an argument -- %s\n",
+                                                                                argv[0], place);
+
+                                                        place = EMSG;
+                                                        optind++;
+
+                                                        if (has_arg == required_argument)
+                                                                return BADCH;
+                                                        optarg = NULL;
+                                                }
+                                        }
+                                        else
+                                        {
+                                                optarg = NULL;
+                                                if (place[namelen] != 0)
+                                                {
+                                                        /* XXX error? */
+                                                }
+                                        }
+
+                                        optind++;
+
+                                        if (longindex)
+                                                *longindex = i;
+
+                                        place = EMSG;
+
+                                        if (longopts[i].flag == NULL)
+                                                return longopts[i].val;
+                                        else
+                                        {
+                                                *longopts[i].flag = longopts[i].val;
+                                                return 0;
+                                        }
+                                }
+                        }
+
+                        if (opterr && optstring[0] != ':')
+                                fprintf(stderr,
+                                                "%s: illegal option -- %s\n", argv[0], place);
+                        place = EMSG;
+                        optind++;
+                        return BADCH;
+                }
+        }
+
+        /* short option */
+        optopt = (int) *place++;
+
+        oli = strchr(optstring, optopt);
+        if (!oli)
+        {
+                if (!*place)
+                        ++optind;
+                if (opterr && *optstring != ':')
+                        fprintf(stderr,
+                                        "%s: illegal option -- %c\n", argv[0], optopt);
+                return BADCH;
+        }
+
+        if (oli[1] != ':')
+        {                                                       /* don't need argument */
+                optarg = NULL;
+                if (!*place)
+                        ++optind;
+        }
+        else
+        {                                                       /* need an argument */
+                if (*place)                             /* no white space */
+                        optarg = place;
+                else if (argc <= ++optind)
+                {                                               /* no arg */
+                        place = EMSG;
+                        if (*optstring == ':')
+                                return BADARG;
+                        if (opterr)
+                                fprintf(stderr,
+                                                "%s: option requires an argument -- %c\n",
+                                                argv[0], optopt);
+                        return BADCH;
+                }
+                else
+                        /* white space */
+                        optarg = argv[optind];
+                place = EMSG;
+                ++optind;
+        }
+        return optopt;
+}
+
 
 #include "zip.h"
 
