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