Blame wireshark-0011-getopt_long.patch

Peter Hatina dc6ff5
diff --git a/ConfigureChecks.cmake b/ConfigureChecks.cmake
Peter Hatina dc6ff5
index 918a628..dfdad33 100644
Peter Hatina dc6ff5
--- a/ConfigureChecks.cmake
Peter Hatina dc6ff5
+++ b/ConfigureChecks.cmake
Peter Hatina dc6ff5
@@ -81,7 +81,14 @@ check_function_exists("dladdr"           HAVE_DLADDR)
Peter Hatina dc6ff5
 cmake_pop_check_state()
Peter Hatina dc6ff5
 
Peter Hatina dc6ff5
 check_function_exists("gethostbyname2"   HAVE_GETHOSTBYNAME2)
Peter Hatina dc6ff5
-check_function_exists("getopt"           HAVE_GETOPT)
Peter Hatina dc6ff5
+check_function_exists("getopt_long"      HAVE_GETOPT_LONG)
Peter Hatina dc6ff5
+if(HAVE_GETOPT_LONG)
Peter Hatina dc6ff5
+    if(HAVE_GETOPT_H)
Peter Hatina dc6ff5
+        check_symbol_exists("optreset" "getopt.h" HAVE_OPTRESET)
Peter Hatina dc6ff5
+    else()
Peter Hatina dc6ff5
+        check_symbol_exists("optreset"            HAVE_OPTRESET)
Peter Hatina dc6ff5
+    endif()
Peter Hatina dc6ff5
+endif()
Peter Hatina dc6ff5
 check_function_exists("getprotobynumber" HAVE_GETPROTOBYNUMBER)
Peter Hatina dc6ff5
 check_function_exists("inet_ntop"        HAVE_INET_NTOP_PROTO)
Peter Hatina dc6ff5
 check_function_exists("issetugid"        HAVE_ISSETUGID)
Peter Hatina dc6ff5
diff --git a/capinfos.c b/capinfos.c
Peter Hatina dc6ff5
index c4daebc..523a303 100644
Peter Hatina dc6ff5
--- a/capinfos.c
Peter Hatina dc6ff5
+++ b/capinfos.c
Peter Hatina dc6ff5
@@ -90,7 +90,7 @@
Peter Hatina dc6ff5
 #include <wsutil/file_util.h>
Peter Hatina dc6ff5
 #endif
Peter Hatina dc6ff5
 
Peter Hatina dc6ff5
-#ifndef HAVE_GETOPT
Peter Hatina dc6ff5
+#ifndef HAVE_GETOPT_LONG
Peter Hatina dc6ff5
 #include "wsutil/wsgetopt.h"
Peter Hatina dc6ff5
 #endif
Peter Hatina dc6ff5
 
Peter Hatina dc6ff5
diff --git a/capture_opts.h b/capture_opts.h
Peter Hatina dc6ff5
index 704242f..e67a027 100644
Peter Hatina dc6ff5
--- a/capture_opts.h
Peter Hatina dc6ff5
+++ b/capture_opts.h
Peter Hatina dc6ff5
@@ -50,6 +50,39 @@ extern "C" {
Peter Hatina dc6ff5
 #define LONGOPT_NUM_CAP_COMMENT 2
Peter Hatina dc6ff5
 
Peter Hatina dc6ff5
 
Peter Hatina dc6ff5
+#if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
Peter Hatina dc6ff5
+#define LONGOPT_BUFFER_SIZE \
Peter Hatina dc6ff5
+    {(char *)"buffer-size", required_argument, NULL, 'B'},
Peter Hatina dc6ff5
+#define OPTSTRING_B "B:"
Peter Hatina dc6ff5
+#else
Peter Hatina dc6ff5
+#define LONGOPT_BUFFER_SIZE
Peter Hatina dc6ff5
+#define OPTSTRING_B ""
Peter Hatina dc6ff5
+#endif
Peter Hatina dc6ff5
+
Peter Hatina dc6ff5
+#ifdef HAVE_PCAP_CREATE
Peter Hatina dc6ff5
+#define LONGOPT_MONITOR_MODE {(char *)"monitor-mode", no_argument, NULL, 'I'},
Peter Hatina dc6ff5
+#define OPTSTRING_I "I"
Peter Hatina dc6ff5
+#else
Peter Hatina dc6ff5
+#define LONGOPT_MONITOR_MODE
Peter Hatina dc6ff5
+#define OPTSTRING_I ""
Peter Hatina dc6ff5
+#endif
Peter Hatina dc6ff5
+
Peter Hatina dc6ff5
+#define LONGOPT_CAPTURE_COMMON \
Peter Hatina dc6ff5
+    {(char *)"capture-comment",      required_argument, NULL, LONGOPT_NUM_CAP_COMMENT}, \
Peter Hatina dc6ff5
+    {(char *)"autostop",             required_argument, NULL, 'a'}, \
Peter Hatina dc6ff5
+    {(char *)"ring-buffer",          required_argument, NULL, 'b'}, \
Peter Hatina dc6ff5
+    LONGOPT_BUFFER_SIZE \
Peter Hatina dc6ff5
+    {(char *)"list-interfaces",      no_argument,       NULL, 'D'}, \
Peter Hatina dc6ff5
+    {(char *)"interface",            required_argument, NULL, 'i'}, \
Peter Hatina dc6ff5
+    LONGOPT_MONITOR_MODE \
Peter Hatina dc6ff5
+    {(char *)"list-data-link-types", no_argument,       NULL, 'L'}, \
Peter Hatina dc6ff5
+    {(char *)"no-promiscuous-mode",  no_argument,       NULL, 'p'}, \
Peter Hatina dc6ff5
+    {(char *)"snapshot-length",      required_argument, NULL, 's'}, \
Peter Hatina dc6ff5
+    {(char *)"linktype",             required_argument, NULL, 'y'},
Peter Hatina dc6ff5
+
Peter Hatina dc6ff5
+#define OPTSTRING_CAPTURE_COMMON \
Peter Hatina dc6ff5
+    "a:" OPTSTRING_A "b:" OPTSTRING_B "c:Df:i:" OPTSTRING_I "Lps:y:"
Peter Hatina dc6ff5
+
Peter Hatina dc6ff5
 #ifdef HAVE_PCAP_REMOTE
Peter Hatina dc6ff5
 /* Type of capture source */
Peter Hatina dc6ff5
 typedef enum {
Peter Hatina dc6ff5
diff --git a/cmakeconfig.h.in b/cmakeconfig.h.in
Peter Hatina dc6ff5
index a809e77..f1a5d44 100644
Peter Hatina dc6ff5
--- a/cmakeconfig.h.in
Peter Hatina dc6ff5
+++ b/cmakeconfig.h.in
Peter Hatina dc6ff5
@@ -63,8 +63,8 @@
Peter Hatina dc6ff5
 /* Define to 1 if you have the `gethostbyname2' function. */
Peter Hatina dc6ff5
 #cmakedefine HAVE_GETHOSTBYNAME2 1
Peter Hatina dc6ff5
 
Peter Hatina dc6ff5
-/* Define to 1 if you have the getopt function. */
Peter Hatina dc6ff5
-#cmakedefine HAVE_GETOPT 1
Peter Hatina dc6ff5
+/* Define to 1 if you have the getopt_long function. */
Peter Hatina dc6ff5
+#cmakedefine HAVE_GETOPT_LONG 1
Peter Hatina dc6ff5
 
Peter Hatina dc6ff5
 /* Define to 1 if you have the <getopt.h> header file. */
Peter Hatina dc6ff5
 #cmakedefine HAVE_GETOPT_H 1
Peter Hatina dc6ff5
@@ -234,6 +234,9 @@
Peter Hatina dc6ff5
 /* Define if python devel package available */
Peter Hatina dc6ff5
 #cmakedefine HAVE_PYTHON 1
Peter Hatina dc6ff5
 
Peter Hatina dc6ff5
+/* Define to 1 if you have the optreset variable */
Peter Hatina dc6ff5
+#cmakedefine HAVE_OPTRESET 1
Peter Hatina dc6ff5
+
Peter Hatina dc6ff5
 /* Define to 1 to enable remote capturing feature in WinPcap library */
Peter Hatina dc6ff5
 #cmakedefine HAVE_REMOTE 1
Peter Hatina dc6ff5
 
Peter Hatina dc6ff5
diff --git a/configure.ac b/configure.ac
Peter Hatina dc6ff5
index 6bcdcab..4ecdab6 100644
Peter Hatina dc6ff5
--- a/configure.ac
Peter Hatina dc6ff5
+++ b/configure.ac
Peter Hatina dc6ff5
@@ -2553,9 +2553,28 @@ AC_C_BIGENDIAN
Peter Hatina dc6ff5
 AC_PROG_GCC_TRADITIONAL
Peter Hatina dc6ff5
 
Peter Hatina dc6ff5
 GETOPT_LO=""
Peter Hatina dc6ff5
-AC_CHECK_FUNC(getopt,
Peter Hatina dc6ff5
+AC_CHECK_FUNC(getopt_long,
Peter Hatina dc6ff5
   [GETOPT_LO=""
Peter Hatina dc6ff5
-   AC_DEFINE(HAVE_GETOPT, 1, [Define to 1 if you have the getopt function.])
Peter Hatina dc6ff5
+   AC_DEFINE(HAVE_GETOPT_LONG, 1, [Define to 1 if you have the getopt_long function.])
Peter Hatina dc6ff5
+
Peter Hatina dc6ff5
+   #
Peter Hatina dc6ff5
+   # Do we have optreset?
Peter Hatina dc6ff5
+   #
Peter Hatina dc6ff5
+   AC_MSG_CHECKING(whether optreset is defined)
Peter Hatina dc6ff5
+   AC_TRY_LINK([],
Peter Hatina dc6ff5
+     [
Peter Hatina dc6ff5
+       extern int optreset;
Peter Hatina dc6ff5
+
Peter Hatina dc6ff5
+       return optreset;
Peter Hatina dc6ff5
+     ],
Peter Hatina dc6ff5
+     ac_cv_pcap_debug_defined=yes,
Peter Hatina dc6ff5
+     ac_cv_pcap_debug_defined=no)
Peter Hatina dc6ff5
+   if test "$ac_cv_pcap_debug_defined" = yes ; then
Peter Hatina dc6ff5
+     AC_MSG_RESULT(yes)
Peter Hatina dc6ff5
+     AC_DEFINE(HAVE_OPTRESET, 1, [Define to 1 if you have the optreset variable])
Peter Hatina dc6ff5
+   else
Peter Hatina dc6ff5
+     AC_MSG_RESULT(no)
Peter Hatina dc6ff5
+   fi 
Peter Hatina dc6ff5
   ],
Peter Hatina dc6ff5
   GETOPT_LO="wsgetopt.lo"
Peter Hatina dc6ff5
 )
Peter Hatina dc6ff5
diff --git a/dumpcap.c b/dumpcap.c
Peter Hatina dc6ff5
index 2ceed86..329c1d3 100644
Peter Hatina dc6ff5
--- a/dumpcap.c
Peter Hatina dc6ff5
+++ b/dumpcap.c
Peter Hatina dc6ff5
@@ -69,7 +69,7 @@
Peter Hatina dc6ff5
 
Peter Hatina dc6ff5
 #include <wsutil/crash_info.h>
Peter Hatina dc6ff5
 
Peter Hatina dc6ff5
-#ifndef HAVE_GETOPT
Peter Hatina dc6ff5
+#ifndef HAVE_GETOPT_LONG
Peter Hatina dc6ff5
 #include "wsutil/wsgetopt.h"
Peter Hatina dc6ff5
 #endif
Peter Hatina dc6ff5
 
Peter Hatina dc6ff5
diff --git a/editcap.c b/editcap.c
Peter Hatina dc6ff5
index 9197e62..a081238 100644
Peter Hatina dc6ff5
--- a/editcap.c
Peter Hatina dc6ff5
+++ b/editcap.c
Peter Hatina dc6ff5
@@ -56,7 +56,7 @@
Peter Hatina dc6ff5
 
Peter Hatina dc6ff5
 #include "wtap.h"
Peter Hatina dc6ff5
 
Peter Hatina dc6ff5
-#ifndef HAVE_GETOPT
Peter Hatina dc6ff5
+#ifndef HAVE_GETOPT_LONG
Peter Hatina dc6ff5
 #include "wsutil/wsgetopt.h"
Peter Hatina dc6ff5
 #endif
Peter Hatina dc6ff5
 
Peter Hatina dc6ff5
diff --git a/mergecap.c b/mergecap.c
Peter Hatina dc6ff5
index a9c1ef9..14092eb 100644
Peter Hatina dc6ff5
--- a/mergecap.c
Peter Hatina dc6ff5
+++ b/mergecap.c
Peter Hatina dc6ff5
@@ -41,7 +41,7 @@
Peter Hatina dc6ff5
 #include <string.h>
Peter Hatina dc6ff5
 #include "wtap.h"
Peter Hatina dc6ff5
 
Peter Hatina dc6ff5
-#ifndef HAVE_GETOPT
Peter Hatina dc6ff5
+#ifndef HAVE_GETOPT_LONG
Peter Hatina dc6ff5
 #include <wsutil/wsgetopt.h>
Peter Hatina dc6ff5
 #endif
Peter Hatina dc6ff5
 
Peter Hatina dc6ff5
diff --git a/randpkt.c b/randpkt.c
Peter Hatina dc6ff5
index 5393fa9..726f11e 100644
Peter Hatina dc6ff5
--- a/randpkt.c
Peter Hatina dc6ff5
+++ b/randpkt.c
Peter Hatina dc6ff5
@@ -27,7 +27,7 @@
Peter Hatina dc6ff5
 #include <unistd.h>
Peter Hatina dc6ff5
 #endif
Peter Hatina dc6ff5
 
Peter Hatina dc6ff5
-#ifndef HAVE_GETOPT
Peter Hatina dc6ff5
+#ifndef HAVE_GETOPT_LONG
Peter Hatina dc6ff5
 #include "wsutil/wsgetopt.h"
Peter Hatina dc6ff5
 #endif
Peter Hatina dc6ff5
 
Peter Hatina dc6ff5
diff --git a/rawshark.c b/rawshark.c
Peter Hatina dc6ff5
index b4eccb8..d672bde 100644
Peter Hatina dc6ff5
--- a/rawshark.c
Peter Hatina dc6ff5
+++ b/rawshark.c
Peter Hatina dc6ff5
@@ -56,7 +56,7 @@
Peter Hatina dc6ff5
 # include <sys/stat.h>
Peter Hatina dc6ff5
 #endif
Peter Hatina dc6ff5
 
Peter Hatina dc6ff5
-#ifndef HAVE_GETOPT
Peter Hatina dc6ff5
+#ifndef HAVE_GETOPT_LONG
Peter Hatina dc6ff5
 #include "wsutil/wsgetopt.h"
Peter Hatina dc6ff5
 #endif
Peter Hatina dc6ff5
 
Peter Hatina dc6ff5
diff --git a/reordercap.c b/reordercap.c
Peter Hatina dc6ff5
index ce563be..8589230 100644
Peter Hatina dc6ff5
--- a/reordercap.c
Peter Hatina dc6ff5
+++ b/reordercap.c
Peter Hatina dc6ff5
@@ -34,7 +34,7 @@
Peter Hatina dc6ff5
 
Peter Hatina dc6ff5
 #include "wtap.h"
Peter Hatina dc6ff5
 
Peter Hatina dc6ff5
-#ifndef HAVE_GETOPT
Peter Hatina dc6ff5
+#ifndef HAVE_GETOPT_LONG
Peter Hatina dc6ff5
 #include "wsutil/wsgetopt.h"
Peter Hatina dc6ff5
 #endif
Peter Hatina dc6ff5
 
Peter Hatina dc6ff5
diff --git a/text2pcap.c b/text2pcap.c
Peter Hatina dc6ff5
index ae47e4d..c07d5d2 100644
Peter Hatina dc6ff5
--- a/text2pcap.c
Peter Hatina dc6ff5
+++ b/text2pcap.c
Peter Hatina dc6ff5
@@ -122,7 +122,7 @@
Peter Hatina dc6ff5
 #include <errno.h>
Peter Hatina dc6ff5
 #include <assert.h>
Peter Hatina dc6ff5
 
Peter Hatina dc6ff5
-#ifndef HAVE_GETOPT
Peter Hatina dc6ff5
+#ifndef HAVE_GETOPT_LONG
Peter Hatina dc6ff5
 #include "wsutil/wsgetopt.h"
Peter Hatina dc6ff5
 #endif
Peter Hatina dc6ff5
 
Peter Hatina dc6ff5
diff --git a/tfshark.c b/tfshark.c
Peter Hatina dc6ff5
index e623504..2a54d39 100644
Peter Hatina dc6ff5
--- a/tfshark.c
Peter Hatina dc6ff5
+++ b/tfshark.c
Peter Hatina dc6ff5
@@ -50,7 +50,7 @@
Peter Hatina dc6ff5
 # include <sys/stat.h>
Peter Hatina dc6ff5
 #endif
Peter Hatina dc6ff5
 
Peter Hatina dc6ff5
-#ifndef HAVE_GETOPT
Peter Hatina dc6ff5
+#ifndef HAVE_GETOPT_LONG
Peter Hatina dc6ff5
 #include "wsutil/wsgetopt.h"
Peter Hatina dc6ff5
 #endif
Peter Hatina dc6ff5
 
Peter Hatina dc6ff5
@@ -780,13 +780,28 @@ main(int argc, char *argv[])
Peter Hatina dc6ff5
   dfilter_t           *dfcode = NULL;
Peter Hatina dc6ff5
   e_prefs             *prefs_p;
Peter Hatina dc6ff5
   int                  log_flags;
Peter Hatina dc6ff5
-  int                  optind_initial;
Peter Hatina dc6ff5
   gchar               *output_only = NULL;
Peter Hatina dc6ff5
 
Peter Hatina dc6ff5
-/* the leading - ensures that getopt() does not permute the argv[] entries
Peter Hatina dc6ff5
-   we have to make sure that the first getopt() preserves the content of argv[]
Peter Hatina dc6ff5
-   for the subsequent getopt_long() call */
Peter Hatina dc6ff5
-#define OPTSTRING "-2C:d:e:E:hK:lo:O:qQr:R:S:t:T:u:vVxX:Y:z:"
Peter Hatina dc6ff5
+/*
Peter Hatina dc6ff5
+ * The leading + ensures that getopt_long() does not permute the argv[]
Peter Hatina dc6ff5
+ * entries.
Peter Hatina dc6ff5
+ *
Peter Hatina dc6ff5
+ * We have to make sure that the first getopt_long() preserves the content
Peter Hatina dc6ff5
+ * of argv[] for the subsequent getopt_long() call.
Peter Hatina dc6ff5
+ *
Peter Hatina dc6ff5
+ * We use getopt_long() in both cases to ensure that we're using a routine
Peter Hatina dc6ff5
+ * whose permutation behavior we can control in the same fashion on all
Peter Hatina dc6ff5
+ * platforms, and so that, if we ever need to process a long argument before
Peter Hatina dc6ff5
+ * doing further initialization, we can do so.
Peter Hatina dc6ff5
+ *
Peter Hatina dc6ff5
+ * Glibc and Solaris libc document that a leading + disables permutation
Peter Hatina dc6ff5
+ * of options, regardless of whether POSIXLY_CORRECT is set or not; *BSD
Peter Hatina dc6ff5
+ * and OS X don't document it, but do so anyway.
Peter Hatina dc6ff5
+ *
Peter Hatina dc6ff5
+ * We do *not* use a leading - because the behavior of a leading - is
Peter Hatina dc6ff5
+ * platform-dependent.
Peter Hatina dc6ff5
+ */
Peter Hatina dc6ff5
+#define OPTSTRING "+2C:d:e:E:hK:lo:O:qQr:R:S:t:T:u:vVxX:Y:z:"
Peter Hatina dc6ff5
 
Peter Hatina dc6ff5
   static const char    optstring[] = OPTSTRING;
Peter Hatina dc6ff5
 
Peter Hatina dc6ff5
@@ -831,11 +846,18 @@ main(int argc, char *argv[])
Peter Hatina dc6ff5
   /*
Peter Hatina dc6ff5
    * In order to have the -X opts assigned before the wslua machine starts
Peter Hatina dc6ff5
    * we need to call getopts before epan_init() gets called.
Peter Hatina dc6ff5
+   *
Peter Hatina dc6ff5
+   * In order to handle, for example, -o options, we also need to call it
Peter Hatina dc6ff5
+   * *after* epan_init() gets called, so that the dissectors have had a
Peter Hatina dc6ff5
+   * chance to register their preferences.
Peter Hatina dc6ff5
+   *
Peter Hatina dc6ff5
+   * XXX - can we do this all with one getopt_long() call, saving the
Peter Hatina dc6ff5
+   * arguments we can't handle until after initializing libwireshark,
Peter Hatina dc6ff5
+   * and then process them after initializing libwireshark?
Peter Hatina dc6ff5
    */
Peter Hatina dc6ff5
   opterr = 0;
Peter Hatina dc6ff5
-  optind_initial = optind;
Peter Hatina dc6ff5
 
Peter Hatina dc6ff5
-  while ((opt = getopt(argc, argv, optstring)) != -1) {
Peter Hatina dc6ff5
+  while ((opt = getopt_long(argc, argv, optstring, long_options, NULL)) != -1) {
Peter Hatina dc6ff5
     switch (opt) {
Peter Hatina dc6ff5
     case 'C':        /* Configuration Profile */
Peter Hatina dc6ff5
       if (profile_exists (optarg, FALSE)) {
Peter Hatina dc6ff5
@@ -876,11 +898,6 @@ main(int argc, char *argv[])
Peter Hatina dc6ff5
   if (print_summary == -1)
Peter Hatina dc6ff5
     print_summary = (print_details || print_hex) ? FALSE : TRUE;
Peter Hatina dc6ff5
 
Peter Hatina dc6ff5
-  optind = optind_initial;
Peter Hatina dc6ff5
-  opterr = 1;
Peter Hatina dc6ff5
-
Peter Hatina dc6ff5
-
Peter Hatina dc6ff5
-
Peter Hatina dc6ff5
 /** Send All g_log messages to our own handler **/
Peter Hatina dc6ff5
 
Peter Hatina dc6ff5
   log_flags =
Peter Hatina dc6ff5
@@ -1063,6 +1080,28 @@ main(int argc, char *argv[])
Peter Hatina dc6ff5
 
Peter Hatina dc6ff5
   output_fields = output_fields_new();
Peter Hatina dc6ff5
 
Peter Hatina dc6ff5
+  /*
Peter Hatina dc6ff5
+   * To reset the options parser, set optreset to 1 on platforms that
Peter Hatina dc6ff5
+   * have optreset (documented in *BSD and OS X, apparently present but
Peter Hatina dc6ff5
+   * not documented in Solaris - the Illumos repository seems to
Peter Hatina dc6ff5
+   * suggest that the first Solaris getopt_long(), at least as of 2004,
Peter Hatina dc6ff5
+   * was based on the NetBSD one, it had optreset) and set optind to 1,
Peter Hatina dc6ff5
+   * and set optind to 0 otherwise (documented as working in the GNU
Peter Hatina dc6ff5
+   * getopt_long().  Setting optind to 0 didn't originally work in the
Peter Hatina dc6ff5
+   * NetBSD one, but that was added later - we don't want to depend on
Peter Hatina dc6ff5
+   * it if we have optreset).
Peter Hatina dc6ff5
+   *
Peter Hatina dc6ff5
+   * Also reset opterr to 1, so that error messages are printed by
Peter Hatina dc6ff5
+   * getopt_long().
Peter Hatina dc6ff5
+   */
Peter Hatina dc6ff5
+#ifdef HAVE_OPTRESET
Peter Hatina dc6ff5
+  optreset = 1;
Peter Hatina dc6ff5
+  optind = 1;
Peter Hatina dc6ff5
+#else
Peter Hatina dc6ff5
+  optind = 0;
Peter Hatina dc6ff5
+#endif
Peter Hatina dc6ff5
+  opterr = 1;
Peter Hatina dc6ff5
+
Peter Hatina dc6ff5
   /* Now get our args */
Peter Hatina dc6ff5
   while ((opt = getopt(argc, argv, optstring)) != -1) {
Peter Hatina dc6ff5
     switch (opt) {
Peter Hatina dc6ff5
@@ -1070,7 +1109,7 @@ main(int argc, char *argv[])
Peter Hatina dc6ff5
       perform_two_pass_analysis = TRUE;
Peter Hatina dc6ff5
       break;
Peter Hatina dc6ff5
     case 'C':
Peter Hatina dc6ff5
-      /* Configuration profile settings were already processed just ignore them this time*/
Peter Hatina dc6ff5
+      /* already processed; just ignore it now */
Peter Hatina dc6ff5
       break;
Peter Hatina dc6ff5
     case 'd':        /* Decode as rule */
Peter Hatina dc6ff5
       if (!add_decode_as(optarg))
Peter Hatina dc6ff5
@@ -1258,6 +1297,7 @@ main(int argc, char *argv[])
Peter Hatina dc6ff5
       /* already processed; just ignore it now */
Peter Hatina dc6ff5
       break;
Peter Hatina dc6ff5
     case 'X':
Peter Hatina dc6ff5
+      /* already processed; just ignore it now */
Peter Hatina dc6ff5
       break;
Peter Hatina dc6ff5
     case 'Y':
Peter Hatina dc6ff5
       dfilter = optarg;
Peter Hatina dc6ff5
diff --git a/tshark.c b/tshark.c
Peter Hatina dc6ff5
index 8de15c6..fcaffcb 100644
Peter Hatina dc6ff5
--- a/tshark.c
Peter Hatina dc6ff5
+++ b/tshark.c
Peter Hatina dc6ff5
@@ -51,7 +51,7 @@
Peter Hatina dc6ff5
 # include <sys/stat.h>
Peter Hatina dc6ff5
 #endif
Peter Hatina dc6ff5
 
Peter Hatina dc6ff5
-#ifndef HAVE_GETOPT
Peter Hatina dc6ff5
+#ifndef HAVE_GETOPT_LONG
Peter Hatina dc6ff5
 #include "wsutil/wsgetopt.h"
Peter Hatina dc6ff5
 #endif
Peter Hatina dc6ff5
 
Peter Hatina dc6ff5
@@ -973,7 +973,6 @@ main(int argc, char *argv[])
Peter Hatina dc6ff5
   e_prefs             *prefs_p;
Peter Hatina dc6ff5
   char                 badopt;
Peter Hatina dc6ff5
   int                  log_flags;
Peter Hatina dc6ff5
-  int                  optind_initial;
Peter Hatina dc6ff5
   gchar               *output_only = NULL;
Peter Hatina dc6ff5
 
Peter Hatina dc6ff5
 #ifdef HAVE_PCAP_REMOTE
Peter Hatina dc6ff5
@@ -997,10 +996,22 @@ main(int argc, char *argv[])
Peter Hatina dc6ff5
 #define OPTSTRING_I ""
Peter Hatina dc6ff5
 #endif
Peter Hatina dc6ff5
 
Peter Hatina dc6ff5
-/* the leading - ensures that getopt() does not permute the argv[] entries
Peter Hatina dc6ff5
-   we have to make sure that the first getopt() preserves the content of argv[]
Peter Hatina dc6ff5
-   for the subsequent getopt_long() call */
Peter Hatina dc6ff5
-#define OPTSTRING "-2a:" OPTSTRING_A "b:" OPTSTRING_B "c:C:d:De:E:f:F:gG:hH:i:" OPTSTRING_I "K:lLnN:o:O:pPqQr:R:s:S:t:T:u:vVw:W:xX:y:Y:z:"
Peter Hatina dc6ff5
+/*
Peter Hatina dc6ff5
+ * The leading + ensures that getopt_long() does not permute the argv[] entries.
Peter Hatina dc6ff5
+ *
Peter Hatina dc6ff5
+ * We have to make sure that the first getopt_long() preserves the content
Peter Hatina dc6ff5
+ * of argv[] for the subsequent getopt_long() call.
Peter Hatina dc6ff5
+ *
Peter Hatina dc6ff5
+ * We use getopt_long() in both cases to ensure that we're using a routine
Peter Hatina dc6ff5
+ * whose permutation behavior we can control in the same fashion on all
Peter Hatina dc6ff5
+ * platforms, and so that, if we ever need to process a long argument before
Peter Hatina dc6ff5
+ * doing further initialization, we can do so.
Peter Hatina dc6ff5
+ *
Peter Hatina dc6ff5
+ * Glibc and Solaris libc document that a leading + disables permutation
Peter Hatina dc6ff5
+ * of options, regardless of whether POSIXLY_CORRECT is set or not; *BSD
Peter Hatina dc6ff5
+ * and OS X don't document it, but do so anyway.
Peter Hatina dc6ff5
+ */
Peter Hatina dc6ff5
+#define OPTSTRING "+2a:" OPTSTRING_A "b:" OPTSTRING_B "c:C:d:De:E:f:F:gG:hH:i:" OPTSTRING_I "K:lLnN:o:O:pPqQr:R:s:S:t:T:u:vVw:W:xX:y:Y:z:"
Peter Hatina dc6ff5
 
Peter Hatina dc6ff5
   static const char    optstring[] = OPTSTRING;
Peter Hatina dc6ff5
 
Peter Hatina dc6ff5
@@ -1044,12 +1055,19 @@ main(int argc, char *argv[])
Peter Hatina dc6ff5
 
Peter Hatina dc6ff5
   /*
Peter Hatina dc6ff5
    * In order to have the -X opts assigned before the wslua machine starts
Peter Hatina dc6ff5
-   * we need to call getopts before epan_init() gets called.
Peter Hatina dc6ff5
+   * we need to call getopt_long before epan_init() gets called.
Peter Hatina dc6ff5
+   *
Peter Hatina dc6ff5
+   * In order to handle, for example, -o options, we also need to call it
Peter Hatina dc6ff5
+   * *after* epan_init() gets called, so that the dissectors have had a
Peter Hatina dc6ff5
+   * chance to register their preferences.
Peter Hatina dc6ff5
+   *
Peter Hatina dc6ff5
+   * XXX - can we do this all with one getopt_long() call, saving the
Peter Hatina dc6ff5
+   * arguments we can't handle until after initializing libwireshark,
Peter Hatina dc6ff5
+   * and then process them after initializing libwireshark?
Peter Hatina dc6ff5
    */
Peter Hatina dc6ff5
   opterr = 0;
Peter Hatina dc6ff5
-  optind_initial = optind;
Peter Hatina dc6ff5
 
Peter Hatina dc6ff5
-  while ((opt = getopt(argc, argv, optstring)) != -1) {
Peter Hatina dc6ff5
+  while ((opt = getopt_long(argc, argv, optstring, long_options, NULL)) != -1) {
Peter Hatina dc6ff5
     switch (opt) {
Peter Hatina dc6ff5
     case 'C':        /* Configuration Profile */
Peter Hatina dc6ff5
       if (profile_exists (optarg, FALSE)) {
Peter Hatina dc6ff5
@@ -1094,11 +1112,6 @@ main(int argc, char *argv[])
Peter Hatina dc6ff5
   if (print_summary == -1)
Peter Hatina dc6ff5
     print_summary = (print_details || print_hex) ? FALSE : TRUE;
Peter Hatina dc6ff5
 
Peter Hatina dc6ff5
-  optind = optind_initial;
Peter Hatina dc6ff5
-  opterr = 1;
Peter Hatina dc6ff5
-
Peter Hatina dc6ff5
-
Peter Hatina dc6ff5
-
Peter Hatina dc6ff5
 /** Send All g_log messages to our own handler **/
Peter Hatina dc6ff5
 
Peter Hatina dc6ff5
   log_flags =
Peter Hatina dc6ff5
@@ -1292,6 +1305,28 @@ main(int argc, char *argv[])
Peter Hatina dc6ff5
 
Peter Hatina dc6ff5
   output_fields = output_fields_new();
Peter Hatina dc6ff5
 
Peter Hatina dc6ff5
+  /*
Peter Hatina dc6ff5
+   * To reset the options parser, set optreset to 1 on platforms that
Peter Hatina dc6ff5
+   * have optreset (documented in *BSD and OS X, apparently present but
Peter Hatina dc6ff5
+   * not documented in Solaris - the Illumos repository seems to
Peter Hatina dc6ff5
+   * suggest that the first Solaris getopt_long(), at least as of 2004,
Peter Hatina dc6ff5
+   * was based on the NetBSD one, it had optreset) and set optind to 1,
Peter Hatina dc6ff5
+   * and set optind to 0 otherwise (documented as working in the GNU
Peter Hatina dc6ff5
+   * getopt_long().  Setting optind to 0 didn't originally work in the
Peter Hatina dc6ff5
+   * NetBSD one, but that was added later - we don't want to depend on
Peter Hatina dc6ff5
+   * it if we have optreset).
Peter Hatina dc6ff5
+   *
Peter Hatina dc6ff5
+   * Also reset opterr to 1, so that error messages are printed by
Peter Hatina dc6ff5
+   * getopt_long().
Peter Hatina dc6ff5
+   */
Peter Hatina dc6ff5
+#ifdef HAVE_OPTRESET
Peter Hatina dc6ff5
+  optreset = 1;
Peter Hatina dc6ff5
+  optind = 1;
Peter Hatina dc6ff5
+#else
Peter Hatina dc6ff5
+  optind = 0;
Peter Hatina dc6ff5
+#endif
Peter Hatina dc6ff5
+  opterr = 1;
Peter Hatina dc6ff5
+
Peter Hatina dc6ff5
   /* Now get our args */
Peter Hatina dc6ff5
   while ((opt = getopt_long(argc, argv, optstring, long_options, NULL)) != -1) {
Peter Hatina dc6ff5
     switch (opt) {
Peter Hatina dc6ff5
@@ -1337,7 +1372,7 @@ main(int argc, char *argv[])
Peter Hatina dc6ff5
 #endif
Peter Hatina dc6ff5
       break;
Peter Hatina dc6ff5
     case 'C':
Peter Hatina dc6ff5
-      /* Configuration profile settings were already processed just ignore them this time*/
Peter Hatina dc6ff5
+      /* already processed; just ignore it now */
Peter Hatina dc6ff5
       break;
Peter Hatina dc6ff5
     case 'd':        /* Decode as rule */
Peter Hatina dc6ff5
       if (!add_decode_as(optarg))
Peter Hatina dc6ff5
@@ -1608,6 +1643,7 @@ main(int argc, char *argv[])
Peter Hatina dc6ff5
       /* already processed; just ignore it now */
Peter Hatina dc6ff5
       break;
Peter Hatina dc6ff5
     case 'X':
Peter Hatina dc6ff5
+      /* already processed; just ignore it now */
Peter Hatina dc6ff5
       break;
Peter Hatina dc6ff5
     case 'Y':
Peter Hatina dc6ff5
       dfilter = optarg;
Peter Hatina dc6ff5
diff --git a/ui/gtk/main.c b/ui/gtk/main.c
Peter Hatina dc6ff5
index f0edc8e..b28d992 100644
Peter Hatina dc6ff5
--- a/ui/gtk/main.c
Peter Hatina dc6ff5
+++ b/ui/gtk/main.c
Peter Hatina dc6ff5
@@ -41,7 +41,11 @@
Peter Hatina dc6ff5
 #include <unistd.h>
Peter Hatina dc6ff5
 #endif
Peter Hatina dc6ff5
 
Peter Hatina dc6ff5
-#ifndef HAVE_GETOPT
Peter Hatina dc6ff5
+#ifdef HAVE_GETOPT_H
Peter Hatina dc6ff5
+#  include <getopt.h>
Peter Hatina dc6ff5
+#endif
Peter Hatina dc6ff5
+
Peter Hatina dc6ff5
+#ifndef HAVE_GETOPT_LONG
Peter Hatina dc6ff5
 #include "wsutil/wsgetopt.h"
Peter Hatina dc6ff5
 #endif
Peter Hatina dc6ff5
 
Peter Hatina dc6ff5
@@ -2150,7 +2154,6 @@ main(int argc, char *argv[])
Peter Hatina dc6ff5
     guint                go_to_packet = 0;
Peter Hatina dc6ff5
     search_direction     jump_backwards = SD_FORWARD;
Peter Hatina dc6ff5
     dfilter_t           *jump_to_filter = NULL;
Peter Hatina dc6ff5
-    int                  optind_initial;
Peter Hatina dc6ff5
     unsigned int         in_file_type = WTAP_TYPE_AUTO;
Peter Hatina dc6ff5
 #ifdef HAVE_GTKOSXAPPLICATION
Peter Hatina dc6ff5
     GtkosxApplication   *theApp;
Peter Hatina dc6ff5
@@ -2178,6 +2181,16 @@ main(int argc, char *argv[])
Peter Hatina dc6ff5
 
Peter Hatina dc6ff5
 #define OPTSTRING "a:" OPTSTRING_A "b:" OPTSTRING_B "c:C:Df:g:Hhi:" OPTSTRING_I "jJ:kK:lLm:nN:o:P:pr:R:Ss:t:u:vw:X:y:Y:z:"
Peter Hatina dc6ff5
 
Peter Hatina dc6ff5
+    static const struct option long_options[] = {
Peter Hatina dc6ff5
+        {(char *)"help", no_argument, NULL, 'h'},
Peter Hatina dc6ff5
+        {(char *)"read-file", required_argument, NULL, 'r' },
Peter Hatina dc6ff5
+        {(char *)"read-filter", required_argument, NULL, 'R' },
Peter Hatina dc6ff5
+        {(char *)"display-filter", required_argument, NULL, 'Y' },
Peter Hatina dc6ff5
+        {(char *)"version", no_argument, NULL, 'v'},
Peter Hatina dc6ff5
+        LONGOPT_CAPTURE_COMMON
Peter Hatina dc6ff5
+        {0, 0, 0, 0 }
Peter Hatina dc6ff5
+    };
Peter Hatina dc6ff5
+
Peter Hatina dc6ff5
     static const char optstring[] = OPTSTRING;
Peter Hatina dc6ff5
 
Peter Hatina dc6ff5
 
Peter Hatina dc6ff5
@@ -2288,20 +2301,41 @@ main(int argc, char *argv[])
Peter Hatina dc6ff5
                       rf_path, g_strerror(rf_open_errno));
Peter Hatina dc6ff5
     }
Peter Hatina dc6ff5
 
Peter Hatina dc6ff5
-    /* "pre-scan" the command line parameters, if we have "console only"
Peter Hatina dc6ff5
-       parameters.  We do this so we don't start GTK+ if we're only showing
Peter Hatina dc6ff5
-       command-line help or version information.
Peter Hatina dc6ff5
+    /*
Peter Hatina dc6ff5
+     * In order to have the -X opts assigned before the wslua machine starts
Peter Hatina dc6ff5
+     * we need to call getopt_long before epan_init() gets called.
Peter Hatina dc6ff5
+
Peter Hatina dc6ff5
+     * In addition, we process "console only" parameters (ones where we
Peter Hatina dc6ff5
+     * send output to the console and exit) here, so we don't start GTK+
Peter Hatina dc6ff5
+     * if we're only showing command-line help or version information.
Peter Hatina dc6ff5
 
Peter Hatina dc6ff5
-       XXX - this pre-scan is done before we start GTK+, so we haven't
Peter Hatina dc6ff5
-       run gtk_init() on the arguments.  That means that GTK+ arguments
Peter Hatina dc6ff5
-       have not been removed from the argument list; those arguments
Peter Hatina dc6ff5
-       begin with "--", and will be treated as an error by getopt().
Peter Hatina dc6ff5
+     * XXX - this pre-scan is done before we start GTK+, so we haven't
Peter Hatina dc6ff5
+     * run gtk_init() on the arguments.  That means that GTK+ arguments
Peter Hatina dc6ff5
+     * have not been removed from the argument list; those arguments
Peter Hatina dc6ff5
+     * begin with "--", and will be treated as an error by getopt_long().
Peter Hatina dc6ff5
 
Peter Hatina dc6ff5
-       We thus ignore errors - *and* set "opterr" to 0 to suppress the
Peter Hatina dc6ff5
-       error messages. */
Peter Hatina dc6ff5
+     * We thus ignore errors - *and* set "opterr" to 0 to suppress the
Peter Hatina dc6ff5
+     * error messages.
Peter Hatina dc6ff5
+
Peter Hatina dc6ff5
+     * XXX - should we, instead, first call gtk_parse_args(), without
Peter Hatina dc6ff5
+     * calling gtk_init(), and then call this?
Peter Hatina dc6ff5
+
Peter Hatina dc6ff5
+     * In order to handle, for example, -o options, we also need to call it
Peter Hatina dc6ff5
+     * *after* epan_init() gets called, so that the dissectors have had a
Peter Hatina dc6ff5
+     * chance to register their preferences, so we have another getopt_long()
Peter Hatina dc6ff5
+     * call later.
Peter Hatina dc6ff5
+
Peter Hatina dc6ff5
+     * XXX - can we do this all with one getopt_long() call, saving the
Peter Hatina dc6ff5
+     * arguments we can't handle until after initializing libwireshark,
Peter Hatina dc6ff5
+     * and then process them after initializing libwireshark?
Peter Hatina dc6ff5
+
Peter Hatina dc6ff5
+     * Note that we don't want to initialize libwireshark until after the
Peter Hatina dc6ff5
+     * GUI is up, as that can take a while, and we want a window of some
Peter Hatina dc6ff5
+     * sort up to show progress while that's happening.
Peter Hatina dc6ff5
+     */
Peter Hatina dc6ff5
     opterr = 0;
Peter Hatina dc6ff5
-    optind_initial = optind;
Peter Hatina dc6ff5
-    while ((opt = getopt(argc, argv, optstring)) != -1) {
Peter Hatina dc6ff5
+
Peter Hatina dc6ff5
+    while ((opt = getopt_long(argc, argv, optstring, long_options, NULL)) != -1) {
Peter Hatina dc6ff5
         switch (opt) {
Peter Hatina dc6ff5
             case 'C':        /* Configuration Profile */
Peter Hatina dc6ff5
                 if (profile_exists (optarg, FALSE)) {
Peter Hatina dc6ff5
@@ -2402,42 +2436,6 @@ main(int argc, char *argv[])
Peter Hatina dc6ff5
         set_last_open_dir(get_persdatafile_dir());
Peter Hatina dc6ff5
     }
Peter Hatina dc6ff5
 
Peter Hatina dc6ff5
-    /* Set getopt index back to initial value, so it will start with the
Peter Hatina dc6ff5
-       first command line parameter again.  Also reset opterr to 1, so that
Peter Hatina dc6ff5
-       error messages are printed by getopt().
Peter Hatina dc6ff5
-
Peter Hatina dc6ff5
-       XXX - this seems to work on most platforms, but time will tell.
Peter Hatina dc6ff5
-       The Single UNIX Specification says "The getopt() function need
Peter Hatina dc6ff5
-       not be reentrant", so this isn't guaranteed to work.  The Mac
Peter Hatina dc6ff5
-       OS X 10.4[.x] getopt() man page says
Peter Hatina dc6ff5
-
Peter Hatina dc6ff5
-         In order to use getopt() to evaluate multiple sets of arguments, or to
Peter Hatina dc6ff5
-         evaluate a single set of arguments multiple times, the variable optreset
Peter Hatina dc6ff5
-         must be set to 1 before the second and each additional set of calls to
Peter Hatina dc6ff5
-         getopt(), and the variable optind must be reinitialized.
Peter Hatina dc6ff5
-
Peter Hatina dc6ff5
-           ...
Peter Hatina dc6ff5
-
Peter Hatina dc6ff5
-         The optreset variable was added to make it possible to call the getopt()
Peter Hatina dc6ff5
-         function multiple times.  This is an extension to the IEEE Std 1003.2
Peter Hatina dc6ff5
-         (``POSIX.2'') specification.
Peter Hatina dc6ff5
-
Peter Hatina dc6ff5
-       which I think comes from one of the other BSDs.
Peter Hatina dc6ff5
-
Peter Hatina dc6ff5
-       XXX - if we want to control all the command-line option errors, so
Peter Hatina dc6ff5
-       that we can display them where we choose (e.g., in a window), we'd
Peter Hatina dc6ff5
-       want to leave opterr as 0, and produce our own messages using optopt.
Peter Hatina dc6ff5
-       We'd have to check the value of optopt to see if it's a valid option
Peter Hatina dc6ff5
-       letter, in which case *presumably* the error is "this option requires
Peter Hatina dc6ff5
-       an argument but none was specified", or not a valid option letter,
Peter Hatina dc6ff5
-       in which case *presumably* the error is "this option isn't valid".
Peter Hatina dc6ff5
-       Some versions of getopt() let you supply a option string beginning
Peter Hatina dc6ff5
-       with ':', which means that getopt() will return ':' rather than '?'
Peter Hatina dc6ff5
-       for "this option requires an argument but none was specified", but
Peter Hatina dc6ff5
-       not all do. */
Peter Hatina dc6ff5
-    optind = optind_initial;
Peter Hatina dc6ff5
-    opterr = 1;
Peter Hatina dc6ff5
-
Peter Hatina dc6ff5
 #if !GLIB_CHECK_VERSION(2,31,0)
Peter Hatina dc6ff5
     g_thread_init(NULL);
Peter Hatina dc6ff5
 #endif
Peter Hatina dc6ff5
@@ -2587,8 +2585,42 @@ main(int argc, char *argv[])
Peter Hatina dc6ff5
 /*#ifdef HAVE_LIBPCAP
Peter Hatina dc6ff5
     fill_in_local_interfaces();
Peter Hatina dc6ff5
 #endif*/
Peter Hatina dc6ff5
+    /*
Peter Hatina dc6ff5
+     * To reset the options parser, set optreset to 1 on platforms that
Peter Hatina dc6ff5
+     * have optreset (documented in *BSD and OS X, apparently present but
Peter Hatina dc6ff5
+     * not documented in Solaris - the Illumos repository seems to
Peter Hatina dc6ff5
+     * suggest that the first Solaris getopt_long(), at least as of 2004,
Peter Hatina dc6ff5
+     * was based on the NetBSD one, it had optreset) and set optind to 1,
Peter Hatina dc6ff5
+     * and set optind to 0 otherwise (documented as working in the GNU
Peter Hatina dc6ff5
+     * getopt_long().  Setting optind to 0 didn't originally work in the
Peter Hatina dc6ff5
+     * NetBSD one, but that was added later - we don't want to depend on
Peter Hatina dc6ff5
+     * it if we have optreset).
Peter Hatina dc6ff5
+     *
Peter Hatina dc6ff5
+     * Also reset opterr to 1, so that error messages are printed by
Peter Hatina dc6ff5
+     * getopt_long().
Peter Hatina dc6ff5
+     *
Peter Hatina dc6ff5
+     * XXX - if we want to control all the command-line option errors, so
Peter Hatina dc6ff5
+     * that we can display them where we choose (e.g., in a window), we'd
Peter Hatina dc6ff5
+     * want to leave opterr as 0, and produce our own messages using optopt.
Peter Hatina dc6ff5
+     * We'd have to check the value of optopt to see if it's a valid option
Peter Hatina dc6ff5
+     * letter, in which case *presumably* the error is "this option requires
Peter Hatina dc6ff5
+     * an argument but none was specified", or not a valid option letter,
Peter Hatina dc6ff5
+     * in which case *presumably* the error is "this option isn't valid".
Peter Hatina dc6ff5
+     * Some versions of getopt() let you supply a option string beginning
Peter Hatina dc6ff5
+     * with ':', which means that getopt() will return ':' rather than '?'
Peter Hatina dc6ff5
+     * for "this option requires an argument but none was specified", but
Peter Hatina dc6ff5
+     * not all do.  But we're now using getopt_long() - what does it do?
Peter Hatina dc6ff5
+     */
Peter Hatina dc6ff5
+#ifdef HAVE_OPTRESET
Peter Hatina dc6ff5
+    optreset = 1;
Peter Hatina dc6ff5
+    optind = 1;
Peter Hatina dc6ff5
+#else
Peter Hatina dc6ff5
+    optind = 0;
Peter Hatina dc6ff5
+#endif
Peter Hatina dc6ff5
+    opterr = 1;
Peter Hatina dc6ff5
+
Peter Hatina dc6ff5
     /* Now get our args */
Peter Hatina dc6ff5
-    while ((opt = getopt(argc, argv, optstring)) != -1) {
Peter Hatina dc6ff5
+    while ((opt = getopt_long(argc, argv, optstring, long_options, NULL)) != -1) {
Peter Hatina dc6ff5
         switch (opt) {
Peter Hatina dc6ff5
             /*** capture option specific ***/
Peter Hatina dc6ff5
             case 'a':        /* autostop criteria */