aboutsummaryrefslogtreecommitdiffstats
path: root/tshark.c
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2014-12-26 14:37:31 -0800
committerGuy Harris <guy@alum.mit.edu>2014-12-26 22:39:46 +0000
commitc2c9a09880a6c2aad7529f9e133f53cfe7aba7ec (patch)
tree8f7b37c08f0f635ae25a8de45d65de3af20ccd1c /tshark.c
parent2c6d2bb1e56055f53531468be83075c4f12cdcb2 (diff)
Use getopt_long() for the first pass through the argument list.
That way: 1) we don't have to worry about the system getopt() and our getopt_long(), on platforms that have getopt() but not getopt_long() (Solaris prior to Solaris 10, HP-UX, AIX), not working well together; 2) if necessary, we can handle long options in the first pass. Switch to using getopt_long() for the *second* pass for the GTK+ version of Wireshark. Use the documented mechanism for resetting the argument parser for the glibc version of getopt_long(); use the mostly-undocumented-but-at-least- they-documented-optreset mechanism for the *BSD version. (We should look into doing only one pass, saving away arguments that can't fully be processed in the first pass for further processing after initializing libwireshark.) Change-Id: Ide5069f1c7c66a5d04acc712551eb201080ce02f Reviewed-on: https://code.wireshark.org/review/6063 Reviewed-by: Guy Harris <guy@alum.mit.edu>
Diffstat (limited to 'tshark.c')
-rw-r--r--tshark.c61
1 files changed, 48 insertions, 13 deletions
diff --git a/tshark.c b/tshark.c
index c6cfb3061b..523e2a245b 100644
--- a/tshark.c
+++ b/tshark.c
@@ -992,12 +992,22 @@ main(int argc, char *argv[])
e_prefs *prefs_p;
char badopt;
int log_flags;
- int optind_initial;
gchar *output_only = NULL;
-/* the leading - ensures that getopt() does not permute the argv[] entries
- we have to make sure that the first getopt() preserves the content of argv[]
- for the subsequent getopt_long() call */
+/*
+ * The leading - ensures that getopt_long() does not permute the argv[] entries.
+ *
+ * We have to make sure that the first getopt_long() preserves the content
+ * of argv[] for the subsequent getopt_long() call.
+ *
+ * We use getopt_long() in both cases to ensure that we're using a routine
+ * whose permutation behavior we can control in the same fashion on all
+ * platforms, and so that, if we ever need to process a long argument before
+ * doing further initialization, we can do so.
+ *
+ * XXX - the behavior of a leading - is platform-dependent, so we shouldn't
+ * use it.
+ */
#define OPTSTRING "-2" OPTSTRING_CAPTURE_COMMON "C:d:e:E:F:gG:hH:" "K:lnN:o:O:PqQr:R:S:t:T:u:vVw:W:xX:Y:z:"
static const char optstring[] = OPTSTRING;
@@ -1062,12 +1072,19 @@ main(int argc, char *argv[])
/*
* In order to have the -X opts assigned before the wslua machine starts
- * we need to call getopts before epan_init() gets called.
+ * we need to call getopt_long before epan_init() gets called.
+ *
+ * In order to handle, for example, -o options, we also need to call it
+ * *after* epan_init() gets called, so that the dissectors have had a
+ * chance to register their preferences.
+ *
+ * XXX - can we do this all with one getopt_long() call, saving the
+ * arguments we can't handle until after initializing libwireshark,
+ * and then process them after initializing libwireshark?
*/
opterr = 0;
- optind_initial = optind;
- while ((opt = getopt(argc, argv, optstring)) != -1) {
+ while ((opt = getopt_long(argc, argv, optstring, long_options, NULL)) != -1) {
switch (opt) {
case 'C': /* Configuration Profile */
if (profile_exists (optarg, FALSE)) {
@@ -1112,11 +1129,6 @@ main(int argc, char *argv[])
if (print_summary == -1)
print_summary = (print_details || print_hex) ? FALSE : TRUE;
- optind = optind_initial;
- opterr = 1;
-
-
-
/** Send All g_log messages to our own handler **/
log_flags =
@@ -1310,6 +1322,28 @@ main(int argc, char *argv[])
output_fields = output_fields_new();
+ /*
+ * To reset the options parser, set optreset to 1 on platforms that
+ * have optreset (documented in *BSD and OS X, apparently present but
+ * not documented in Solaris - the Illumos repository seems to
+ * suggest that the first Solaris getopt_long(), at least as of 2004,
+ * was based on the NetBSD one, it had optreset) and set optind to 1,
+ * and set optind to 0 otherwise (documented as working in the GNU
+ * getopt_long(). Setting optind to 0 didn't originally work in the
+ * NetBSD one, but that was added later - we don't want to depend on
+ * it if we have optreset).
+ *
+ * Also reset opterr to 1, so that error messages are printed by
+ * getopt_long().
+ */
+#ifdef HAVE_OPTRESET
+ optreset = 1;
+ optind = 1;
+#else
+ optind = 0;
+#endif
+ opterr = 1;
+
/* Now get our args */
while ((opt = getopt_long(argc, argv, optstring, long_options, NULL)) != -1) {
switch (opt) {
@@ -1355,7 +1389,7 @@ main(int argc, char *argv[])
#endif
break;
case 'C':
- /* Configuration profile settings were already processed just ignore them this time*/
+ /* already processed; just ignore it now */
break;
case 'd': /* Decode as rule */
if (!add_decode_as(optarg))
@@ -1625,6 +1659,7 @@ main(int argc, char *argv[])
/* already processed; just ignore it now */
break;
case 'X':
+ /* already processed; just ignore it now */
break;
case 'Y':
dfilter = optarg;