UI: Free up the -m flag.
[metze/wireshark/wip.git] / ui / commandline.c
1 /* commandline.c
2  * Common command line handling between GUIs
3  *
4  * Wireshark - Network traffic analyzer
5  * By Gerald Combs <gerald@wireshark.org>
6  * Copyright 1998 Gerald Combs
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; either version 2
11  * of the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21  */
22
23 #include "config.h"
24
25 #include <glib.h>
26
27 #include <string.h>
28 #include <stdio.h>
29 #include <stdlib.h>
30
31 #ifdef HAVE_GETOPT_H
32 #include <getopt.h>
33 #endif
34
35 #ifndef HAVE_GETOPT_LONG
36 #include "wsutil/wsgetopt.h"
37 #endif
38
39 #include <ws_version_info.h>
40
41 #include <wsutil/clopts_common.h>
42 #include <wsutil/cmdarg_err.h>
43 #include <wsutil/filesystem.h>
44
45 #include <epan/ex-opt.h>
46 #include <epan/addr_resolv.h>
47 #include <epan/packet.h>
48 #include <epan/proto.h>
49 #include <epan/prefs.h>
50 #include <epan/prefs-int.h>
51 #include <epan/timestamp.h>
52 #include <epan/stat_tap_ui.h>
53
54 #include "capture_opts.h"
55 #include "persfilepath_opt.h"
56 #include "preference_utils.h"
57 #include "console.h"
58 #include "recent.h"
59 #include "decode_as_utils.h"
60
61 #if defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS)
62 #include <epan/asn1.h>
63 #include <epan/dissectors/packet-kerberos.h>
64 #endif
65
66 #include "../file.h"
67
68 #include "ui/commandline.h"
69
70 commandline_param_info_t global_commandline_info;
71
72 #if defined(HAVE_LIBPCAP) || defined(HAVE_EXTCAP)
73 capture_options global_capture_opts;
74 #endif
75
76 void
77 commandline_print_usage(gboolean for_help_option) {
78     FILE *output;
79
80 #ifdef _WIN32
81     create_console();
82 #endif
83
84     if (for_help_option) {
85         output = stdout;
86         fprintf(output, "Wireshark %s\n"
87             "Interactively dump and analyze network traffic.\n"
88             "See https://www.wireshark.org for more information.\n",
89             get_ws_vcs_version_info());
90     } else {
91         output = stderr;
92     }
93     fprintf(output, "\n");
94     fprintf(output, "Usage: wireshark [options] ... [ <infile> ]\n");
95     fprintf(output, "\n");
96
97 #ifdef HAVE_LIBPCAP
98     fprintf(output, "Capture interface:\n");
99     fprintf(output, "  -i <interface>           name or idx of interface (def: first non-loopback)\n");
100     fprintf(output, "  -f <capture filter>      packet filter in libpcap filter syntax\n");
101     fprintf(output, "  -s <snaplen>             packet snapshot length (def: 65535)\n");
102     fprintf(output, "  -p                       don't capture in promiscuous mode\n");
103     fprintf(output, "  -k                       start capturing immediately (def: do nothing)\n");
104     fprintf(output, "  -S                       update packet display when new packets are captured\n");
105     fprintf(output, "  -l                       turn on automatic scrolling while -S is in use\n");
106 #ifdef HAVE_PCAP_CREATE
107     fprintf(output, "  -I                       capture in monitor mode, if available\n");
108 #endif
109 #ifdef CAN_SET_CAPTURE_BUFFER_SIZE
110     fprintf(output, "  -B <buffer size>         size of kernel buffer (def: %dMB)\n", DEFAULT_CAPTURE_BUFFER_SIZE);
111 #endif
112     fprintf(output, "  -y <link type>           link layer type (def: first appropriate)\n");
113     fprintf(output, "  -D                       print list of interfaces and exit\n");
114     fprintf(output, "  -L                       print list of link-layer types of iface and exit\n");
115     fprintf(output, "\n");
116     fprintf(output, "Capture stop conditions:\n");
117     fprintf(output, "  -c <packet count>        stop after n packets (def: infinite)\n");
118     fprintf(output, "  -a <autostop cond.> ...  duration:NUM - stop after NUM seconds\n");
119     fprintf(output, "                           filesize:NUM - stop this file after NUM KB\n");
120     fprintf(output, "                              files:NUM - stop after NUM files\n");
121     /*fprintf(output, "\n");*/
122     fprintf(output, "Capture output:\n");
123     fprintf(output, "  -b <ringbuffer opt.> ... duration:NUM - switch to next file after NUM secs\n");
124     fprintf(output, "                           filesize:NUM - switch to next file after NUM KB\n");
125     fprintf(output, "                              files:NUM - ringbuffer: replace after NUM files\n");
126 #endif  /* HAVE_LIBPCAP */
127 #ifdef HAVE_PCAP_REMOTE
128     fprintf(output, "RPCAP options:\n");
129     fprintf(output, "  -A <user>:<password>     use RPCAP password authentication\n");
130 #endif
131     /*fprintf(output, "\n");*/
132     fprintf(output, "Input file:\n");
133     fprintf(output, "  -r <infile>              set the filename to read from (no pipes or stdin!)\n");
134
135     fprintf(output, "\n");
136     fprintf(output, "Processing:\n");
137     fprintf(output, "  -R <read filter>         packet filter in Wireshark display filter syntax\n");
138     fprintf(output, "  -n                       disable all name resolutions (def: all enabled)\n");
139     fprintf(output, "  -N <name resolve flags>  enable specific name resolution(s): \"mnNtd\"\n");
140     fprintf(output, "  -d %s ...\n", DECODE_AS_ARG_TEMPLATE);
141     fprintf(output, "                           \"Decode As\", see the man page for details\n");
142     fprintf(output, "                           Example: tcp.port==8888,http\n");
143     fprintf(output, "  --disable-protocol <proto_name>\n");
144     fprintf(output, "                           disable dissection of proto_name\n");
145     fprintf(output, "  --enable-heuristic <short_name>\n");
146     fprintf(output, "                           enable dissection of heuristic protocol\n");
147     fprintf(output, "  --disable-heuristic <short_name>\n");
148     fprintf(output, "                           disable dissection of heuristic protocol\n");
149
150     fprintf(output, "\n");
151     fprintf(output, "User interface:\n");
152     fprintf(output, "  -C <config profile>      start with specified configuration profile\n");
153     fprintf(output, "  -Y <display filter>      start with the given display filter\n");
154     fprintf(output, "  -g <packet number>       go to specified packet number after \"-r\"\n");
155     fprintf(output, "  -J <jump filter>         jump to the first packet matching the (display)\n");
156     fprintf(output, "                           filter\n");
157     fprintf(output, "  -j                       search backwards for a matching packet after \"-J\"\n");
158     fprintf(output, "  -m <font>                set the font name used for most text\n");
159     fprintf(output, "  -t a|ad|d|dd|e|r|u|ud    output format of time stamps (def: r: rel. to first)\n");
160     fprintf(output, "  -u s|hms                 output format of seconds (def: s: seconds)\n");
161     fprintf(output, "  -X <key>:<value>         eXtension options, see man page for details\n");
162     fprintf(output, "  -z <statistics>          show various statistics, see man page for details\n");
163
164     fprintf(output, "\n");
165     fprintf(output, "Output:\n");
166     fprintf(output, "  -w <outfile|->           set the output filename (or '-' for stdout)\n");
167
168     fprintf(output, "\n");
169     fprintf(output, "Miscellaneous:\n");
170     fprintf(output, "  -h                       display this help and exit\n");
171     fprintf(output, "  -v                       display version info and exit\n");
172     fprintf(output, "  -P <key>:<path>          persconf:path - personal configuration files\n");
173     fprintf(output, "                           persdata:path - personal data files\n");
174     fprintf(output, "  -o <name>:<value> ...    override preference or recent setting\n");
175     fprintf(output, "  -K <keytab>              keytab file to use for kerberos decryption\n");
176 #ifndef _WIN32
177     fprintf(output, "  --display=DISPLAY        X display to use\n");
178 #endif
179
180 #ifdef _WIN32
181     destroy_console();
182 #endif
183 }
184
185 #define OPTSTRING OPTSTRING_CAPTURE_COMMON "C:d:g:Hh" "jJ:kK:lm:nN:o:P:r:R:St:u:vw:X:Y:z:"
186 static const struct option long_options[] = {
187         {"help", no_argument, NULL, 'h'},
188         {"read-file", required_argument, NULL, 'r' },
189         {"read-filter", required_argument, NULL, 'R' },
190         {"display-filter", required_argument, NULL, 'Y' },
191         {"version", no_argument, NULL, 'v'},
192         LONGOPT_CAPTURE_COMMON
193         {0, 0, 0, 0 }
194     };
195 static const char optstring[] = OPTSTRING;
196
197 #ifndef HAVE_LIBPCAP
198 static void print_no_capture_support_error(void)
199 {
200     cmdarg_err("This version of Wireshark was not built with support for capturing packets.");
201 }
202 #endif
203
204 void commandline_early_options(int argc, char *argv[],
205     GString *comp_info_str, GString *runtime_info_str)
206 {
207     int opt;
208 #ifdef HAVE_LIBPCAP
209     int err;
210     GList *if_list;
211     gchar *err_str;
212 #else
213     gboolean capture_option_specified;
214 #endif
215
216     /*
217      * In order to have the -X opts assigned before the wslua machine starts
218      * we need to call getopt_long before epan_init() gets called.
219      *
220      * In addition, we process "console only" parameters (ones where we
221      * send output to the console and exit) here, so we don't start GUI
222      * if we're only showing command-line help or version information.
223      *
224      * XXX - this pre-scan is done before we start GUI, so we haven't
225      * run "GUI init function" on the arguments.  That means that GUI-specific
226      * arguments have not been removed from the argument list; those arguments
227      * begin with "--", and will be treated as an error by getopt_long().
228      *
229      * We thus ignore errors - *and* set "opterr" to 0 to suppress the
230      * error messages.
231      *
232      * XXX - should we, instead, first call gtk_parse_args(), without
233      * calling gtk_init(), and then call this?
234      *
235      * In order to handle, for example, -o options, we also need to call it
236      * *after* epan_init() gets called, so that the dissectors have had a
237      * chance to register their preferences, so we have another getopt_long()
238      * call later.
239      *
240      * XXX - can we do this all with one getopt_long() call, saving the
241      * arguments we can't handle until after initializing libwireshark,
242      * and then process them after initializing libwireshark?
243      *
244      * Note that we don't want to initialize libwireshark until after the
245      * GUI is up, as that can take a while, and we want a window of some
246      * sort up to show progress while that's happening.
247      */
248     opterr = 0;
249
250 #ifndef HAVE_LIBPCAP
251     capture_option_specified = FALSE;
252 #endif
253     while ((opt = getopt_long(argc, argv, optstring, long_options, NULL)) != -1) {
254         switch (opt) {
255             case 'C':        /* Configuration Profile */
256                 if (profile_exists (optarg, FALSE)) {
257                     set_profile_name (optarg);
258                 } else {
259                     cmdarg_err("Configuration Profile \"%s\" does not exist", optarg);
260                     exit(1);
261                 }
262                 break;
263             case 'D':        /* Print a list of capture devices and exit */
264 #ifdef HAVE_LIBPCAP
265                 if_list = capture_interface_list(&err, &err_str, NULL);
266                 if (if_list == NULL) {
267                     if (err == 0)
268                         cmdarg_err("There are no interfaces on which a capture can be done");
269                     else {
270                         cmdarg_err("%s", err_str);
271                         g_free(err_str);
272                     }
273                     exit(2);
274                 }
275 #ifdef _WIN32
276                 create_console();
277 #endif /* _WIN32 */
278                 capture_opts_print_interfaces(if_list);
279                 free_interface_list(if_list);
280 #ifdef _WIN32
281                 destroy_console();
282 #endif /* _WIN32 */
283                 exit(0);
284 #else /* HAVE_LIBPCAP */
285                 capture_option_specified = TRUE;
286 #endif /* HAVE_LIBPCAP */
287                 break;
288             case 'h':        /* Print help and exit */
289                 commandline_print_usage(TRUE);
290                 exit(0);
291                 break;
292 #ifdef _WIN32
293             case 'i':
294                 if (strcmp(optarg, "-") == 0)
295                     set_stdin_capture(TRUE);
296                 break;
297 #endif
298             case 'P':        /* Personal file directory path settings - change these before the Preferences and alike are processed */
299                 if (!persfilepath_opt(opt, optarg)) {
300                     cmdarg_err("-P flag \"%s\" failed (hint: is it quoted and existing?)", optarg);
301                     exit(2);
302                 }
303                 break;
304             case 'v':        /* Show version and exit */
305 #ifdef _WIN32
306                 create_console();
307 #endif
308                 show_version("Wireshark", comp_info_str, runtime_info_str);
309 #ifdef _WIN32
310                 destroy_console();
311 #endif
312                 exit(0);
313                 break;
314             case 'X':
315                 /*
316                  *  Extension command line options have to be processed before
317                  *  we call epan_init() as they are supposed to be used by dissectors
318                  *  or taps very early in the registration process.
319                  */
320                 ex_opt_add(optarg);
321                 break;
322             case '?':        /* Ignore errors - the "real" scan will catch them. */
323                 break;
324         }
325     }
326
327 #ifndef HAVE_LIBPCAP
328     if (capture_option_specified) {
329         print_no_capture_support_error();
330         commandline_print_usage(FALSE);
331         exit(1);
332     }
333 #endif
334 }
335
336 void commandline_other_options(int argc, char *argv[], gboolean opt_reset)
337 {
338     int opt;
339     gboolean arg_error = FALSE;
340 #ifdef HAVE_LIBPCAP
341     int status;
342 #else
343     gboolean capture_option_specified;
344 #endif
345     char badopt;
346
347     /*
348      * To reset the options parser, set optreset to 1 on platforms that
349      * have optreset (documented in *BSD and OS X, apparently present but
350      * not documented in Solaris - the Illumos repository seems to
351      * suggest that the first Solaris getopt_long(), at least as of 2004,
352      * was based on the NetBSD one, it had optreset) and set optind to 1,
353      * and set optind to 0 otherwise (documented as working in the GNU
354      * getopt_long().  Setting optind to 0 didn't originally work in the
355      * NetBSD one, but that was added later - we don't want to depend on
356      * it if we have optreset).
357      *
358      * Also reset opterr to 1, so that error messages are printed by
359      * getopt_long().
360      *
361      * XXX - if we want to control all the command-line option errors, so
362      * that we can display them where we choose (e.g., in a window), we'd
363      * want to leave opterr as 0, and produce our own messages using optopt.
364      * We'd have to check the value of optopt to see if it's a valid option
365      * letter, in which case *presumably* the error is "this option requires
366      * an argument but none was specified", or not a valid option letter,
367      * in which case *presumably* the error is "this option isn't valid".
368      * Some versions of getopt() let you supply a option string beginning
369      * with ':', which means that getopt() will return ':' rather than '?'
370      * for "this option requires an argument but none was specified", but
371      * not all do.  But we're now using getopt_long() - what does it do?
372      */
373     if (opt_reset) {
374 #ifdef HAVE_OPTRESET
375         optreset = 1;
376         optind = 1;
377 #else
378         optind = 0;
379 #endif
380         opterr = 1;
381     }
382
383     /* Initialize with default values */
384     global_commandline_info.jump_backwards = SD_FORWARD;
385     global_commandline_info.go_to_packet = 0;
386     global_commandline_info.jfilter = NULL;
387     global_commandline_info.cf_name = NULL;
388     global_commandline_info.rfilter = NULL;
389     global_commandline_info.dfilter = NULL;
390     global_commandline_info.time_format = TS_NOT_SET;
391 #ifdef HAVE_LIBPCAP
392     global_commandline_info.start_capture = FALSE;
393     global_commandline_info.list_link_layer_types = FALSE;
394     global_commandline_info.quit_after_cap = getenv("WIRESHARK_QUIT_AFTER_CAPTURE") ? TRUE : FALSE;
395 #endif
396     global_commandline_info.disable_protocol_slist = NULL;
397     global_commandline_info.enable_heur_slist = NULL;
398     global_commandline_info.disable_heur_slist = NULL;
399
400     while ((opt = getopt_long(argc, argv, optstring, long_options, NULL)) != -1) {
401         switch (opt) {
402             /*** capture option specific ***/
403             case 'a':        /* autostop criteria */
404             case 'b':        /* Ringbuffer option */
405             case 'c':        /* Capture xxx packets */
406             case 'f':        /* capture filter */
407             case 'k':        /* Start capture immediately */
408             case 'H':        /* Hide capture info dialog box */
409             case 'p':        /* Don't capture in promiscuous mode */
410             case 'i':        /* Use interface x */
411 #ifdef HAVE_PCAP_CREATE
412             case 'I':        /* Capture in monitor mode, if available */
413 #endif
414 #ifdef HAVE_PCAP_REMOTE
415             case 'A':        /* Authentication */
416 #endif
417             case 's':        /* Set the snapshot (capture) length */
418             case 'S':        /* "Sync" mode: used for following file ala tail -f */
419             case 'w':        /* Write to capture file xxx */
420             case 'y':        /* Set the pcap data link type */
421 #ifdef CAN_SET_CAPTURE_BUFFER_SIZE
422             case 'B':        /* Buffer size */
423 #endif
424 #ifdef HAVE_LIBPCAP
425                 status = capture_opts_add_opt(&global_capture_opts, opt, optarg,
426                                               &global_commandline_info.start_capture);
427                 if(status != 0) {
428                     exit(status);
429                 }
430 #else
431                 capture_option_specified = TRUE;
432                 arg_error = TRUE;
433 #endif
434                 break;
435
436 #if defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS)
437             case 'K':        /* Kerberos keytab file */
438                 read_keytab_file(optarg);
439                 break;
440 #endif
441
442             /*** all non capture option specific ***/
443             case 'C':
444                 /* Configuration profile settings were already processed just ignore them this time*/
445                 break;
446             case 'd':        /* Decode as rule */
447                 if (!decode_as_command_option(optarg))
448                     exit(1);
449                 break;
450             case 'j':        /* Search backwards for a matching packet from filter in option J */
451                 global_commandline_info.jump_backwards = SD_BACKWARD;
452                 break;
453             case 'g':        /* Go to packet with the given packet number */
454                 global_commandline_info.go_to_packet = get_nonzero_guint32(optarg, "go to packet");
455                 break;
456             case 'J':        /* Jump to the first packet which matches the filter criteria */
457                 global_commandline_info.jfilter = optarg;
458                 break;
459             case 'l':        /* Automatic scrolling in live capture mode */
460 #ifdef HAVE_LIBPCAP
461                 auto_scroll_live = TRUE;
462 #else
463                 capture_option_specified = TRUE;
464                 arg_error = TRUE;
465 #endif
466                 break;
467             case 'L':        /* Print list of link-layer types and exit */
468 #ifdef HAVE_LIBPCAP
469                 global_commandline_info.list_link_layer_types = TRUE;
470 #else
471                 capture_option_specified = TRUE;
472                 arg_error = TRUE;
473 #endif
474                 break;
475             case 'n':        /* No name resolution */
476                 disable_name_resolution();
477                 break;
478             case 'N':        /* Select what types of addresses/port #s to resolve */
479                 badopt = string_to_name_resolve(optarg, &gbl_resolv_flags);
480                 if (badopt != '\0') {
481                     cmdarg_err("-N specifies unknown resolving option '%c'; valid options are 'd', m', 'n', 'N', and 't'",
482                                badopt);
483                     exit(1);
484                 }
485                 break;
486             case 'o':        /* Override preference from command line */
487                 switch (prefs_set_pref(optarg)) {
488                     case PREFS_SET_OK:
489                         break;
490                     case PREFS_SET_SYNTAX_ERR:
491                         cmdarg_err("Invalid -o flag \"%s\"", optarg);
492                         exit(1);
493                         break;
494                     case PREFS_SET_NO_SUCH_PREF:
495                     /* not a preference, might be a recent setting */
496                         switch (recent_set_arg(optarg)) {
497                             case PREFS_SET_OK:
498                                 break;
499                             case PREFS_SET_SYNTAX_ERR:
500                                 /* shouldn't happen, checked already above */
501                                 cmdarg_err("Invalid -o flag \"%s\"", optarg);
502                                 exit(1);
503                                 break;
504                             case PREFS_SET_NO_SUCH_PREF:
505                             case PREFS_SET_OBSOLETE:
506                                 cmdarg_err("-o flag \"%s\" specifies unknown preference/recent value",
507                                            optarg);
508                                 exit(1);
509                                 break;
510                             default:
511                                 g_assert_not_reached();
512                         }
513                         break;
514                     case PREFS_SET_OBSOLETE:
515                         cmdarg_err("-o flag \"%s\" specifies obsolete preference",
516                                    optarg);
517                         exit(1);
518                         break;
519                     default:
520                         g_assert_not_reached();
521                 }
522                 break;
523             case 'P':
524                 /* Path settings were already processed just ignore them this time*/
525                 break;
526             case 'r':        /* Read capture file xxx */
527                 /* We may set "last_open_dir" to "cf_name", and if we change
528                  "last_open_dir" later, we free the old value, so we have to
529                  set "cf_name" to something that's been allocated. */
530                 global_commandline_info.cf_name = g_strdup(optarg);
531                 break;
532             case 'R':        /* Read file filter */
533                 global_commandline_info.rfilter = optarg;
534                 break;
535             case 't':        /* Time stamp type */
536                 if (strcmp(optarg, "r") == 0)
537                     global_commandline_info.time_format = TS_RELATIVE;
538                 else if (strcmp(optarg, "a") == 0)
539                     global_commandline_info.time_format = TS_ABSOLUTE;
540                 else if (strcmp(optarg, "ad") == 0)
541                     global_commandline_info.time_format = TS_ABSOLUTE_WITH_YMD;
542                 else if (strcmp(optarg, "adoy") == 0)
543                     global_commandline_info.time_format = TS_ABSOLUTE_WITH_YDOY;
544                 else if (strcmp(optarg, "d") == 0)
545                     global_commandline_info.time_format = TS_DELTA;
546                 else if (strcmp(optarg, "dd") == 0)
547                     global_commandline_info.time_format = TS_DELTA_DIS;
548                 else if (strcmp(optarg, "e") == 0)
549                     global_commandline_info.time_format = TS_EPOCH;
550                 else if (strcmp(optarg, "u") == 0)
551                     global_commandline_info.time_format = TS_UTC;
552                 else if (strcmp(optarg, "ud") == 0)
553                     global_commandline_info.time_format = TS_UTC_WITH_YMD;
554                 else if (strcmp(optarg, "udoy") == 0)
555                     global_commandline_info.time_format = TS_UTC_WITH_YDOY;
556                 else {
557                     cmdarg_err("Invalid time stamp type \"%s\"", optarg);
558                     cmdarg_err_cont("It must be \"a\" for absolute, \"ad\" for absolute with YYYY-MM-DD date,");
559                     cmdarg_err_cont("\"adoy\" for absolute with YYYY/DOY date, \"d\" for delta,");
560                     cmdarg_err_cont("\"dd\" for delta displayed, \"e\" for epoch, \"r\" for relative,");
561                     cmdarg_err_cont("\"u\" for absolute UTC, \"ud\" for absolute UTC with YYYY-MM-DD date,");
562                     cmdarg_err_cont("or \"udoy\" for absolute UTC with YYYY/DOY date.");
563                     exit(1);
564                 }
565                 break;
566             case 'u':        /* Seconds type */
567                 if (strcmp(optarg, "s") == 0)
568                     timestamp_set_seconds_type(TS_SECONDS_DEFAULT);
569                 else if (strcmp(optarg, "hms") == 0)
570                     timestamp_set_seconds_type(TS_SECONDS_HOUR_MIN_SEC);
571                 else {
572                     cmdarg_err("Invalid seconds type \"%s\"", optarg);
573                     cmdarg_err_cont("It must be \"s\" for seconds or \"hms\" for hours, minutes and seconds.");
574                     exit(1);
575                 }
576                 break;
577             case 'X':
578                 /* ext ops were already processed just ignore them this time*/
579                 break;
580             case 'Y':
581                 global_commandline_info.dfilter = optarg;
582                 break;
583             case 'z':
584                 /* We won't call the init function for the stat this soon
585                  as it would disallow MATE's fields (which are registered
586                  by the preferences set callback) from being used as
587                  part of a tap filter.  Instead, we just add the argument
588                  to a list of stat arguments. */
589                 if (strcmp("help", optarg) == 0) {
590                   fprintf(stderr, "wireshark: The available statistics for the \"-z\" option are:\n");
591                   list_stat_cmd_args();
592                   exit(0);
593                 }
594                 if (!process_stat_cmd_arg(optarg)) {
595                     cmdarg_err("Invalid -z argument.");
596                     cmdarg_err_cont("  -z argument must be one of :");
597                     list_stat_cmd_args();
598                     exit(1);
599                 }
600                 break;
601             case LONGOPT_DISABLE_PROTOCOL: /* disable dissection of protocol */
602                 global_commandline_info.disable_protocol_slist = g_slist_append(global_commandline_info.disable_protocol_slist, optarg);
603                 break;
604             case LONGOPT_ENABLE_HEURISTIC: /* enable heuristic dissection of protocol */
605                 global_commandline_info.enable_heur_slist = g_slist_append(global_commandline_info.enable_heur_slist, optarg);
606                 break;
607             case LONGOPT_DISABLE_HEURISTIC: /* disable heuristic dissection of protocol */
608                 global_commandline_info.disable_heur_slist = g_slist_append(global_commandline_info.disable_heur_slist, optarg);
609                 break;
610             default:
611             case '?':        /* Bad flag - print usage message */
612                 arg_error = TRUE;
613                 break;
614             }
615     }
616
617     if (!arg_error) {
618         argc -= optind;
619         argv += optind;
620         if (argc >= 1) {
621             if (global_commandline_info.cf_name != NULL) {
622                 /*
623                  * Input file name specified with "-r" *and* specified as a regular
624                  * command-line argument.
625                  */
626                 cmdarg_err("File name specified both with -r and regular argument");
627                 arg_error = TRUE;
628             } else {
629                 /*
630                  * Input file name not specified with "-r", and a command-line argument
631                  * was specified; treat it as the input file name.
632                  *
633                  * Yes, this is different from tshark, where non-flag command-line
634                  * arguments are a filter, but this works better on GUI desktops
635                  * where a command can be specified to be run to open a particular
636                  * file - yes, you could have "-r" as the last part of the command,
637                  * but that's a bit ugly.
638                  */
639 #ifndef HAVE_GTKOSXAPPLICATION
640                 /*
641                  * For GTK+ Mac Integration, file name passed as free argument passed
642                  * through grag-and-drop and opened twice sometimes causing crashes.
643                  * Subject to report to GTK+ MAC.
644                  */
645                 global_commandline_info.cf_name = g_strdup(argv[0]);
646 #endif
647             }
648             argc--;
649             argv++;
650         }
651
652         if (argc != 0) {
653             /*
654              * Extra command line arguments were specified; complain.
655              */
656             cmdarg_err("Invalid argument: %s", argv[0]);
657             arg_error = TRUE;
658         }
659     }
660
661     if (arg_error) {
662 #ifndef HAVE_LIBPCAP
663         if (capture_option_specified) {
664             print_no_capture_support_error();
665         }
666 #endif
667         commandline_print_usage(FALSE);
668         exit(1);
669     }
670
671 #ifdef HAVE_LIBPCAP
672     if (global_commandline_info.start_capture && global_commandline_info.list_link_layer_types) {
673         /* Specifying *both* is bogus. */
674         cmdarg_err("You can't specify both -L and a live capture.");
675         exit(1);
676     }
677
678     if (global_commandline_info.list_link_layer_types) {
679         /* We're supposed to list the link-layer types for an interface;
680            did the user also specify a capture file to be read? */
681         if (global_commandline_info.cf_name) {
682             /* Yes - that's bogus. */
683             cmdarg_err("You can't specify -L and a capture file to be read.");
684             exit(1);
685         }
686         /* No - did they specify a ring buffer option? */
687         if (global_capture_opts.multi_files_on) {
688             cmdarg_err("Ring buffer requested, but a capture isn't being done.");
689             exit(1);
690         }
691     } else {
692         /* We're supposed to do a live capture; did the user also specify
693            a capture file to be read? */
694         if (global_commandline_info.start_capture && global_commandline_info.cf_name) {
695             /* Yes - that's bogus. */
696             cmdarg_err("You can't specify both a live capture and a capture file to be read.");
697             exit(1);
698         }
699
700         /* No - was the ring buffer option specified and, if so, does it make
701            sense? */
702         if (global_capture_opts.multi_files_on) {
703             /* Ring buffer works only under certain conditions:
704              a) ring buffer does not work with temporary files;
705              b) real_time_mode and multi_files_on are mutually exclusive -
706              real_time_mode takes precedence;
707              c) it makes no sense to enable the ring buffer if the maximum
708              file size is set to "infinite". */
709             if (global_capture_opts.save_file == NULL) {
710                 cmdarg_err("Ring buffer requested, but capture isn't being saved to a permanent file.");
711                 global_capture_opts.multi_files_on = FALSE;
712             }
713             if (!global_capture_opts.has_autostop_filesize && !global_capture_opts.has_file_duration) {
714                 cmdarg_err("Ring buffer requested, but no maximum capture file size or duration were specified.");
715                 /* XXX - this must be redesigned as the conditions changed */
716             }
717         }
718     }
719 #endif
720 }
721
722 /*
723  * Editor modelines
724  *
725  * Local Variables:
726  * c-basic-offset: 4
727  * tab-width: 8
728  * indent-tabs-mode: nil
729  * End:
730  *
731  * ex: set shiftwidth=4 tabstop=8 expandtab:
732  * :indentSize=4:tabSize=8:noTabs=true:
733  */