--- ./src/google-authenticator.c.orig	2026-04-12 18:48:00.000000000 -0500
+++ ./src/google-authenticator.c	2026-04-12 18:48:00.000000000 -0500
@@ -22,7 +22,6 @@
 #include <dlfcn.h>
 #include <errno.h>
 #include <fcntl.h>
-#include <getopt.h>
 #include <pwd.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -34,6 +33,311 @@
 #include "base32.h"
 #include "hmac.h"
 #include "sha1.h"
+
+ #include <stdarg.h>
+ #include <stdio.h>
+ #include <string.h>
+#include "vasprintf.h"
+
+ /*
+  * vasprintf(3)
+  * 20020809 entropy@tappedin.com
+  * public domain.  no warranty.  use at your own risk.  have a nice day.
+  */
+ 
+ #include <stdarg.h>
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
+ #include <unistd.h>
+ 
+ #if HAVE_PATHS_H
+#include <paths.h>
+ #endif /* HAVE_PATHS_H */
+ 
+ 
+ #if defined(HAVE__VSNPRINTF) && !defined(HAVE_VSNPRINTF)
+ #undef HAVE_VSNPRINTF
+ #undef vsnprintf
+#define HAVE_VSNPRINTF 1
+ #define vsnprintf _vsnprintf
+#endif
+ 
+ #ifndef _PATH_DEVNULL
+#define _PATH_DEVNULL "/dev/null"
+ #endif
+ 
+ #define CHUNKSIZE 512
+ int
+ vasprintf(char **ret, const char *fmt, va_list ap)
+ {
+ #if HAVE_VSNPRINTF
+ 	int chunks;
+ 	size_t buflen;
+ 	char *buf;
+ 	int len;
+ 
+ 	chunks = ((strlen(fmt) + 1) / CHUNKSIZE) + 1;
+ 	buflen = chunks * CHUNKSIZE;
+ 	for (;;) {
+ 		if ((buf = malloc(buflen)) == NULL) {
+ 			*ret = NULL;
+ 			return -1;
+ 		}
+ 		len = vsnprintf(buf, buflen, fmt, ap);
+ 		if (len >= 0 && (size_t) len < (buflen - 1)) {
+ 			break;
+ 		}
+ 		free(buf);
+ 		buflen = (++chunks) * CHUNKSIZE;
+ 		/* 
+ 		 * len >= 0 are required for vsnprintf implementation that 
+ 		 * return -1 of buffer insufficient
+ 		 */
+ 		if (len >= 0 && (size_t) len >= buflen) {
+ 			buflen = len + 1;
+ 		}
+ 	}
+ 	*ret = buf;
+ 	return len;
+ #else /* HAVE_VSNPRINTF */
+ #ifdef _REENTRANT
+ 	FILE *fp;
+ #else /* !_REENTRANT */
+ 	static FILE *fp = NULL;
+ #endif /* !_REENTRANT */
+ 	int len;
+ 	char *buf;
+ 
+ 	*ret = NULL;
+ 
+ #ifdef _REENTRANT
+ 
+ # ifdef WIN32
+ #  error Win32 do not have /dev/null, should use vsnprintf version
+ # endif
+ 
+ 	if ((fp = fopen(_PATH_DEVNULL, "w")) == NULL)
+ 		return -1;
+ #else /* !_REENTRANT */
+ 	if ((fp == NULL) && ((fp = fopen(_PATH_DEVNULL, "w")) == NULL))
+	return -1;
+ #endif /* !_REENTRANT */
+ 
+ 	len = vfprintf(fp, fmt, ap);
+ 
+ #ifdef _REENTRANT
+ 	if (fclose(fp) != 0)
+ 		return -1;
+ #endif /* _REENTRANT */
+ 
+ 	if (len < 0)
+ 		return len;
+ 	if ((buf = malloc(len + 1)) == NULL)
+ 		return -1;
+ 	if (vsprintf(buf, fmt, ap) != len)
+ 		return -1;
+ 	*ret = buf;
+ 	return len;
+ #endif /* HAVE_VSNPRINTF */
+ }
+
+ int
+ asprintf(char **ret, const char *fmt, ...)
+ {
+ 	int len;
+ 	va_list ap;
+ 
+ 	va_start(ap, fmt);
+ 	len = vasprintf(ret, fmt, ap);
+ 	va_end(ap);
+ 	return len;
+ }
+
+#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;
+}
 
 #define SECRET                    "/.google_authenticator"
 #define SECRET_BITS               160         // Must be divisible by eight
--- /dev/null	2026-04-12 18:48:00.000000000 -0500
+++ ./src/vasprintf.h	2026-04-12 18:48:00.000000000 -0500
@@ -0,0 +1,30 @@
+ #ifndef _vasprintf_h_
+ #define _vasprintf_h_
+ 
+ #include <stdarg.h>
+
+ #ifdef __cplusplus
+ extern "C"
+ {
+ #endif
+ 
+ #if defined(HAVE__VSNPRINTF) && !defined(HAVE_VSNPRINTF)
+ #undef vsnprintf
+ #define vsnprintf _vsnprintf
+ #elif !HAVE_VSNPRINTF
+ int vsnprintf(char *ret, size_t max, const char *fmt, va_list ap);
+ #endif /* !HAVE_VSNPRINTF */
+ 
+ #if !HAVE_ASPRINTF
+ int asprintf(char **ret, const char *fmt, ...);
+ #endif /* !HAVE_ASPRINTF */
+ 
+ #if !HAVE_VASPRINTF
+ int vasprintf(char **ret, const char *fmt, va_list ap);
+ #endif /* !HAVE_VASPRINTF */
+ 
+ #ifdef __cplusplus
+ }
+ #endif
+ 
+ #endif

