Get rid of an unused variable.
[metze/wireshark/wip.git] / wireshark-qt.cpp
1 /* wireshark-qt.cpp
2  *
3  * Wireshark - Network traffic analyzer
4  * By Gerald Combs <gerald@wireshark.org>
5  * Copyright 1998 Gerald Combs
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20  */
21
22 #include <config.h>
23
24 #include <glib.h>
25
26 #ifdef Q_OS_UNIX
27 #include <signal.h>
28 #endif
29
30 #ifdef HAVE_LIBZ
31 #include <zlib.h>       /* to get the libz version number */
32 #endif
33
34 #ifdef HAVE_GETOPT_H
35 #include <getopt.h>
36 #endif
37
38 #ifndef HAVE_GETOPT_LONG
39 #include "wsutil/wsgetopt.h"
40 #endif
41
42 #include <wsutil/clopts_common.h>
43 #include <wsutil/cmdarg_err.h>
44 #include <wsutil/crash_info.h>
45 #include <wsutil/filesystem.h>
46 #include <wsutil/privileges.h>
47 #ifdef HAVE_PLUGINS
48 #include <wsutil/plugins.h>
49 #endif
50 #include <wsutil/report_err.h>
51 #include <wsutil/u3.h>
52 #include <wsutil/unicode-utils.h>
53 #include <wsutil/ws_diag_control.h>
54 #include <wsutil/ws_version_info.h>
55
56 #include <epan/addr_resolv.h>
57 #include <epan/ex-opt.h>
58 #include <epan/tap.h>
59 #include <epan/stat_tap_ui.h>
60 #include <epan/column.h>
61 #include <epan/disabled_protos.h>
62
63 #ifdef HAVE_KERBEROS
64 #include <epan/packet.h>
65 #include <epan/asn1.h>
66 #include <epan/dissectors/packet-kerberos.h>
67 #endif
68
69 #ifdef HAVE_PLUGINS
70 #include <codecs/codecs.h>
71 #endif
72
73 #ifdef HAVE_EXTCAP
74 #include <extcap.h>
75 #endif
76
77 /* general (not Qt specific) */
78 #include "file.h"
79 #include "epan/color_filters.h"
80 #include "log.h"
81
82 #include "epan/rtd_table.h"
83 #include "epan/srt_table.h"
84
85 #include "ui/alert_box.h"
86 #include "ui/console.h"
87 #include "ui/iface_lists.h"
88 #include "ui/language.h"
89 #include "ui/persfilepath_opt.h"
90 #include "ui/recent.h"
91 #include "ui/simple_dialog.h"
92 #include "ui/util.h"
93
94 #include "ui/qt/conversation_dialog.h"
95 #include "ui/qt/color_utils.h"
96 #include "ui/qt/coloring_rules_dialog.h"
97 #include "ui/qt/endpoint_dialog.h"
98 #include "ui/qt/main_window.h"
99 #include "ui/qt/response_time_delay_dialog.h"
100 #include "ui/qt/service_response_time_dialog.h"
101 #include "ui/qt/simple_dialog.h"
102 #include "ui/qt/simple_statistics_dialog.h"
103 #include "ui/qt/splash_overlay.h"
104 #include "ui/qt/wireshark_application.h"
105
106 #include "caputils/capture-pcap-util.h"
107
108 #ifdef _WIN32
109 #  include "caputils/capture-wpcap.h"
110 #  include "caputils/capture_wpcap_packet.h"
111 #  include <tchar.h> /* Needed for Unicode */
112 #  include <wsutil/file_util.h>
113 #  include <wsutil/os_version_info.h>
114 #endif /* _WIN32 */
115
116 #ifdef HAVE_AIRPCAP
117 #  include <caputils/airpcap.h>
118 #  include <caputils/airpcap_loader.h>
119 //#  include "airpcap_dlg.h"
120 //#  include "airpcap_gui_utils.h"
121 #endif
122
123 #include "epan/crypt/airpdcap_ws.h"
124
125 #if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0))
126 #include <QTextCodec>
127 #endif
128
129 #if defined(HAVE_LIBPCAP) || defined(HAVE_EXTCAP)
130 capture_options global_capture_opts;
131 #endif
132
133 GString *comp_info_str, *runtime_info_str;
134
135 /* update the main window */
136 void main_window_update(void)
137 {
138     WiresharkApplication::processEvents();
139 }
140
141 #ifdef HAVE_LIBPCAP
142
143 /* quit a nested main window */
144 void main_window_nested_quit(void)
145 {
146 //    if (gtk_main_level() > 0)
147     wsApp->quit();
148 }
149
150 /* quit the main window */
151 void main_window_quit(void)
152 {
153     wsApp->quit();
154 }
155
156 #endif /* HAVE_LIBPCAP */
157
158
159 // xxx copied from ../gtk/main.c
160 static void
161 print_usage(gboolean for_help_option) {
162     FILE *output;
163
164 #ifdef _WIN32
165     create_console();
166 #endif
167
168     if (for_help_option) {
169         output = stdout;
170         fprintf(output, "Wireshark %s\n"
171                 "Interactively dump and analyze network traffic.\n"
172                 "See https://www.wireshark.org for more information.\n",
173                 get_ws_vcs_version_info());
174     } else {
175         output = stderr;
176     }
177     fprintf(output, "\n");
178     fprintf(output, "Usage: wireshark [options] ... [ <infile> ]\n");
179     fprintf(output, "\n");
180
181 #ifdef HAVE_LIBPCAP
182     fprintf(output, "Capture interface:\n");
183     fprintf(output, "  -i <interface>           name or idx of interface (def: first non-loopback)\n");
184     fprintf(output, "  -f <capture filter>      packet filter in libpcap filter syntax\n");
185     fprintf(output, "  -s <snaplen>             packet snapshot length (def: 65535)\n");
186     fprintf(output, "  -p                       don't capture in promiscuous mode\n");
187     fprintf(output, "  -k                       start capturing immediately (def: do nothing)\n");
188     fprintf(output, "  -S                       update packet display when new packets are captured\n");
189     fprintf(output, "  -l                       turn on automatic scrolling while -S is in use\n");
190 #ifdef HAVE_PCAP_CREATE
191     fprintf(output, "  -I                       capture in monitor mode, if available\n");
192 #endif
193 #ifdef CAN_SET_CAPTURE_BUFFER_SIZE
194     fprintf(output, "  -B <buffer size>         size of kernel buffer (def: %dMB)\n", DEFAULT_CAPTURE_BUFFER_SIZE);
195 #endif
196     fprintf(output, "  -y <link type>           link layer type (def: first appropriate)\n");
197     fprintf(output, "  -D                       print list of interfaces and exit\n");
198     fprintf(output, "  -L                       print list of link-layer types of iface and exit\n");
199     fprintf(output, "\n");
200     fprintf(output, "Capture stop conditions:\n");
201     fprintf(output, "  -c <packet count>        stop after n packets (def: infinite)\n");
202     fprintf(output, "  -a <autostop cond.> ...  duration:NUM - stop after NUM seconds\n");
203     fprintf(output, "                           filesize:NUM - stop this file after NUM KB\n");
204     fprintf(output, "                              files:NUM - stop after NUM files\n");
205     /*fprintf(output, "\n");*/
206     fprintf(output, "Capture output:\n");
207     fprintf(output, "  -b <ringbuffer opt.> ... duration:NUM - switch to next file after NUM secs\n");
208     fprintf(output, "                           filesize:NUM - switch to next file after NUM KB\n");
209     fprintf(output, "                              files:NUM - ringbuffer: replace after NUM files\n");
210 #endif  /* HAVE_LIBPCAP */
211 #ifdef HAVE_PCAP_REMOTE
212     fprintf(output, "RPCAP options:\n");
213     fprintf(output, "  -A <user>:<password>     use RPCAP password authentication\n");
214 #endif
215     /*fprintf(output, "\n");*/
216     fprintf(output, "Input file:\n");
217     fprintf(output, "  -r <infile>              set the filename to read from (no pipes or stdin!)\n");
218
219     fprintf(output, "\n");
220     fprintf(output, "Processing:\n");
221     fprintf(output, "  -R <read filter>         packet filter in Wireshark display filter syntax\n");
222     fprintf(output, "  -n                       disable all name resolutions (def: all enabled)\n");
223     fprintf(output, "  -N <name resolve flags>  enable specific name resolution(s): \"mnNtCd\"\n");
224     fprintf(output, "  --disable-protocol <proto_name>\n");
225     fprintf(output, "                           disable dissection of proto_name\n");
226     fprintf(output, "  --enable-heuristic <short_name>\n");
227     fprintf(output, "                           enable dissection of heuristic protocol\n");
228     fprintf(output, "  --disable-heuristic <short_name>\n");
229     fprintf(output, "                           disable dissection of heuristic protocol\n");
230
231     fprintf(output, "\n");
232     fprintf(output, "User interface:\n");
233     fprintf(output, "  -C <config profile>      start with specified configuration profile\n");
234     fprintf(output, "  -Y <display filter>      start with the given display filter\n");
235     fprintf(output, "  -g <packet number>       go to specified packet number after \"-r\"\n");
236     fprintf(output, "  -J <jump filter>         jump to the first packet matching the (display)\n");
237     fprintf(output, "                           filter\n");
238     fprintf(output, "  -j                       search backwards for a matching packet after \"-J\"\n");
239     fprintf(output, "  -m <font>                set the font name used for most text\n");
240     fprintf(output, "  -t a|ad|d|dd|e|r|u|ud    output format of time stamps (def: r: rel. to first)\n");
241     fprintf(output, "  -u s|hms                 output format of seconds (def: s: seconds)\n");
242     fprintf(output, "  -X <key>:<value>         eXtension options, see man page for details\n");
243     fprintf(output, "  -z <statistics>          show various statistics, see man page for details\n");
244
245     fprintf(output, "\n");
246     fprintf(output, "Output:\n");
247     fprintf(output, "  -w <outfile|->           set the output filename (or '-' for stdout)\n");
248
249     fprintf(output, "\n");
250     fprintf(output, "Miscellaneous:\n");
251     fprintf(output, "  -h                       display this help and exit\n");
252     fprintf(output, "  -v                       display version info and exit\n");
253     fprintf(output, "  -P <key>:<path>          persconf:path - personal configuration files\n");
254     fprintf(output, "                           persdata:path - personal data files\n");
255     fprintf(output, "  -o <name>:<value> ...    override preference or recent setting\n");
256     fprintf(output, "  -K <keytab>              keytab file to use for kerberos decryption\n");
257 #ifndef _WIN32
258     fprintf(output, "  --display=DISPLAY        X display to use\n");
259 #endif
260     fprintf(output, "\nNOTE: Not all options are implemented in the Qt port.\n");
261
262 #ifdef _WIN32
263     destroy_console();
264 #endif
265 }
266
267 /*
268  * Report an error in command-line arguments.
269  * Creates a console on Windows.
270  */
271 // xxx copied from ../gtk/main.c
272 static void
273 wireshark_cmdarg_err(const char *fmt, va_list ap)
274 {
275 #ifdef _WIN32
276     create_console();
277 #endif
278     fprintf(stderr, "wireshark: ");
279     vfprintf(stderr, fmt, ap);
280     fprintf(stderr, "\n");
281 }
282
283 /*
284  * Report additional information for an error in command-line arguments.
285  * Creates a console on Windows.
286  * XXX - pop this up in a window of some sort on UNIX+X11 if the controlling
287  * terminal isn't the standard error?
288  */
289 // xxx copied from ../gtk/main.c
290 static void
291 wireshark_cmdarg_err_cont(const char *fmt, va_list ap)
292 {
293 #ifdef _WIN32
294     create_console();
295 #endif
296     vfprintf(stderr, fmt, ap);
297     fprintf(stderr, "\n");
298 }
299
300 // xxx based from ../gtk/main.c:get_gtk_compiled_info
301 static void
302 get_wireshark_qt_compiled_info(GString *str)
303 {
304     g_string_append(str, "with ");
305     g_string_append_printf(str,
306 #ifdef QT_VERSION
307                     "Qt %s", QT_VERSION_STR);
308 #else
309                     "Qt (version unknown)");
310 #endif
311
312     /* Capture libraries */
313     g_string_append(str, ", ");
314     get_compiled_caplibs_version(str);
315
316     /* LIBZ */
317     g_string_append(str, ", ");
318 #ifdef HAVE_LIBZ
319     g_string_append(str, "with libz ");
320 #ifdef ZLIB_VERSION
321     g_string_append(str, ZLIB_VERSION);
322 #else /* ZLIB_VERSION */
323     g_string_append(str, "(version unknown)");
324 #endif /* ZLIB_VERSION */
325 #else /* HAVE_LIBZ */
326     g_string_append(str, "without libz");
327 #endif /* HAVE_LIBZ */
328 }
329
330 // xxx copied from ../gtk/main.c
331 static void
332 get_gui_compiled_info(GString *str)
333 {
334     epan_get_compiled_version_info(str);
335
336     g_string_append(str, ", ");
337 #ifdef QT_MULTIMEDIA_LIB
338     g_string_append(str, "with QtMultimedia");
339 #else
340     g_string_append(str, "without QtMultimedia");
341 #endif
342
343     g_string_append(str, ", ");
344 #ifdef HAVE_AIRPCAP
345     get_compiled_airpcap_version(str);
346 #else
347     g_string_append(str, "without AirPcap");
348 #endif
349 }
350
351 // xxx copied from ../gtk/main.c
352 static void
353 get_wireshark_runtime_info(GString *str)
354 {
355 #ifdef HAVE_LIBPCAP
356     /* Capture libraries */
357     g_string_append(str, ", ");
358     get_runtime_caplibs_version(str);
359 #endif
360
361     /* zlib */
362 #if defined(HAVE_LIBZ) && !defined(_WIN32)
363     g_string_append_printf(str, ", with libz %s", zlibVersion());
364 #endif
365
366     /* stuff used by libwireshark */
367     epan_get_runtime_version_info(str);
368
369 #ifdef HAVE_AIRPCAP
370     g_string_append(str, ", ");
371     get_runtime_airpcap_version(str);
372 #endif
373
374     if(u3_active()) {
375         g_string_append(str, ", ");
376         u3_runtime_info(str);
377     }
378 }
379
380 #ifdef HAVE_LIBPCAP
381 /*  Check if there's something important to tell the user during startup.
382  *  We want to do this *after* showing the main window so that any windows
383  *  we pop up will be above the main window.
384  */
385 static void
386 check_and_warn_user_startup(const QString &cf_name)
387 {
388 #ifndef _WIN32
389     Q_UNUSED(cf_name)
390 #endif
391     gchar               *cur_user, *cur_group;
392
393     /* Tell the user not to run as root. */
394     if (running_with_special_privs() && recent.privs_warn_if_elevated) {
395         cur_user = get_cur_username();
396         cur_group = get_cur_groupname();
397         simple_message_box(ESD_TYPE_WARN, &recent.privs_warn_if_elevated,
398         "Running as user \"%s\" and group \"%s\".\n"
399         "This could be dangerous.\n\n"
400         "If you're running Wireshark this way in order to perform live capture, "
401         "you may want to be aware that there is a better way documented at\n"
402         "https://wiki.wireshark.org/CaptureSetup/CapturePrivileges", cur_user, cur_group);
403         g_free(cur_user);
404         g_free(cur_group);
405     }
406
407 #ifdef _WIN32
408     /* Warn the user if npf.sys isn't loaded. */
409     if (!get_stdin_capture() && cf_name.isEmpty() && !npf_sys_is_running() && recent.privs_warn_if_no_npf && get_windows_major_version() >= 6) {
410         simple_message_box(ESD_TYPE_WARN, &recent.privs_warn_if_no_npf, "%s",
411         "The NPF driver isn't running. You may have trouble\n"
412         "capturing or listing interfaces.");
413     }
414 #endif
415
416 }
417 #endif
418
419 #ifdef _WIN32
420 // Try to avoid library search path collisions. QCoreApplication will
421 // search QT_INSTALL_PREFIX/plugins for platform DLLs before searching
422 // the application directory. If
423 //
424 // - You have Qt version 5.x.y installed in the default location
425 //   (C:\Qt\5.x) on your machine.
426 //
427 // and
428 //
429 // - You install Wireshark that was built on a machine with Qt version
430 //   5.x.z installed in the default location.
431 //
432 // Qt5Core.dll will load qwindows.dll from your local C:\Qt\5.x\...\plugins
433 // directory. This may not be compatible with qwindows.dll from that
434 // same path on the build machine. At any rate, loading DLLs from paths
435 // you don't control is ill-advised. We work around this by removing every
436 // path except our application directory.
437
438 static inline void
439 reset_library_path(void)
440 {
441     QString app_path = QDir(get_progfile_dir()).path();
442     foreach (QString path, QCoreApplication::libraryPaths()) {
443         QCoreApplication::removeLibraryPath(path);
444     }
445     QCoreApplication::addLibraryPath(app_path);
446 }
447 #endif
448
449 /* And now our feature presentation... [ fade to music ] */
450 int main(int argc, char *argv[])
451 {
452     MainWindow *main_w;
453
454     int                  opt;
455     gboolean             arg_error = FALSE;
456     char               **ws_argv = argv;
457
458 #ifdef _WIN32
459     WSADATA              wsaData;
460 #endif  /* _WIN32 */
461
462     char                *rf_path;
463     int                  rf_open_errno;
464     char                *gdp_path, *dp_path;
465 #ifdef HAVE_LIBPCAP
466     int                  err;
467     gboolean             start_capture = FALSE;
468     gboolean             list_link_layer_types = FALSE;
469     GList               *if_list;
470     gchar               *err_str;
471     int                  status;
472 #else
473     gboolean             capture_option_specified = FALSE;
474 #ifdef _WIN32
475 #ifdef HAVE_AIRPCAP
476     gchar               *err_str;
477 #endif
478 #endif
479 #endif
480     e_prefs             *prefs_p;
481     char                 badopt;
482     guint                go_to_packet = 0;
483
484     QString              dfilter, read_filter;
485     GSList              *disable_protocol_slist = NULL;
486     GSList              *enable_heur_slist = NULL;
487     GSList              *disable_heur_slist = NULL;
488
489     cmdarg_err_init(wireshark_cmdarg_err, wireshark_cmdarg_err_cont);
490
491     // In Qt 5, C strings are treated always as UTF-8 when converted to
492     // QStrings; in Qt 4, the codec must be set to make that happen
493 #if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0))
494     // Hopefully we won't have to use QString::fromUtf8() in as many places.
495     QTextCodec *utf8codec = QTextCodec::codecForName("UTF-8");
496     QTextCodec::setCodecForCStrings(utf8codec);
497     // XXX - QObject doesn't *have* a tr method in 5.0, as far as I can see...
498     QTextCodec::setCodecForTr(utf8codec);
499 #endif
500
501     /* Set the C-language locale to the native environment. */
502     // The GTK+ UI calls this. Should we as well?
503     //setlocale(LC_ALL, "");
504 #ifdef _WIN32
505     // QCoreApplication clobbers argv. Let's have a local copy.
506     ws_argv = (char **) g_malloc(sizeof(char *) * argc);
507     for (opt = 0; opt < argc; opt++) {
508         ws_argv[opt] = argv[opt];
509     }
510     arg_list_utf_16to8(argc, ws_argv);
511     create_app_running_mutex();
512 #endif /* _WIN32 */
513
514     /*
515      * Get credential information for later use, and drop privileges
516      * before doing anything else.
517      * Let the user know if anything happened.
518      */
519     init_process_policies();
520     relinquish_special_privs_perm();
521
522     /*
523      * Attempt to get the pathname of the executable file.
524      */
525     /* init_progfile_dir_error = */ init_progfile_dir(ws_argv[0],
526         (int (*)(int, char **)) get_gui_compiled_info);
527     g_log(NULL, G_LOG_LEVEL_DEBUG, "progfile_dir: %s", get_progfile_dir());
528
529 #ifdef _WIN32
530     /* Load wpcap if possible. Do this before collecting the run-time version information */
531     load_wpcap();
532
533     /* ... and also load the packet.dll from wpcap */
534     wpcap_packet_load();
535
536 #ifdef HAVE_AIRPCAP
537     /* Load the airpcap.dll.  This must also be done before collecting
538      * run-time version information. */
539     load_airpcap();
540 #if 0
541     airpcap_dll_ret_val = load_airpcap();
542
543     switch (airpcap_dll_ret_val) {
544     case AIRPCAP_DLL_OK:
545         /* load the airpcap interfaces */
546         g_airpcap_if_list = get_airpcap_interface_list(&err, &err_str);
547
548         if (g_airpcap_if_list == NULL || g_list_length(g_airpcap_if_list) == 0){
549             if (err == CANT_GET_AIRPCAP_INTERFACE_LIST && err_str != NULL) {
550                 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", "Failed to open Airpcap Adapters.");
551                 g_free(err_str);
552             }
553             airpcap_if_active = NULL;
554
555         } else {
556
557             /* select the first ad default (THIS SHOULD BE CHANGED) */
558             airpcap_if_active = airpcap_get_default_if(airpcap_if_list);
559         }
560         break;
561     /*
562      * XXX - Maybe we need to warn the user if one of the following happens???
563      */
564     case AIRPCAP_DLL_OLD:
565         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DLL_OLD\n");
566         break;
567
568     case AIRPCAP_DLL_ERROR:
569         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DLL_ERROR\n");
570         break;
571
572     case AIRPCAP_DLL_NOT_FOUND:
573         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DDL_NOT_FOUND\n");
574         break;
575     }
576 #endif
577 #endif /* HAVE_AIRPCAP */
578 #endif /* _WIN32 */
579
580     /* Get the compile-time version information string */
581     // XXX qtshark
582     comp_info_str = get_compiled_version_info(get_wireshark_qt_compiled_info,
583                                               get_gui_compiled_info);
584
585     /* Assemble the run-time version information string */
586     // xxx qtshark
587     runtime_info_str = get_runtime_version_info(get_wireshark_runtime_info);
588
589     /*
590      * In order to have the -X opts assigned before the wslua machine starts
591      * we need to call getopt_long before epan_init() gets called.
592      *
593      * In addition, we process "console only" parameters (ones where we
594      * send output to the console and exit) here, so we don't start Qt
595      * if we're only showing command-line help or version information.
596      *
597      * XXX - this pre-scan is done before we start Qt, so we haven't
598      * run WiresharkApplication's constructor on the arguments.  That
599      * means that Qt arguments have not been removed from the argument
600      * list; those arguments begin with "-", and may be treated as
601      * errors by getopt_long().
602      *
603      * We thus ignore errors - *and* set "opterr" to 0 to suppress the
604      * error messages.
605      *
606      * XXX - is there some way to parse and remove Qt arguments without
607      * starting up the GUI, which we can call before calling this?
608      *
609      * In order to handle, for example, -o options, we also need to call it
610      * *after* epan_init() gets called, so that the dissectors have had a
611      * chance to register their preferences, so we have another getopt_long()
612      * call later.
613      *
614      * XXX - can we do this all with one getopt_long() call, saving the
615      * arguments we can't handle until after initializing libwireshark,
616      * and then process them after initializing libwireshark?
617      *
618      * Note that we don't want to initialize libwireshark until after the
619      * GUI is up, as that can take a while, and we want a window of some
620      * sort up to show progress while that's happening.
621      */
622     // XXX Should the remaining code be in WiresharkApplcation::WiresharkApplication?
623 #define OPTSTRING OPTSTRING_CAPTURE_COMMON "C:g:Hh" "jJ:kK:lm:nN:o:P:r:R:St:u:vw:X:Y:z:"
624     static const struct option long_options[] = {
625         {"help", no_argument, NULL, 'h'},
626         {"read-file", required_argument, NULL, 'r' },
627         {"read-filter", required_argument, NULL, 'R' },
628         {"display-filter", required_argument, NULL, 'Y' },
629         {"version", no_argument, NULL, 'v'},
630         LONGOPT_CAPTURE_COMMON
631         {0, 0, 0, 0 }
632     };
633     static const char optstring[] = OPTSTRING;
634
635     opterr = 0;
636
637     while ((opt = getopt_long(argc, ws_argv, optstring, long_options, NULL)) != -1) {
638         switch (opt) {
639             case 'C':        /* Configuration Profile */
640                 if (profile_exists (optarg, FALSE)) {
641                     set_profile_name (optarg);
642                 } else {
643                     cmdarg_err("Configuration Profile \"%s\" does not exist", optarg);
644                     exit(1);
645                 }
646                 break;
647             case 'D':        /* Print a list of capture devices and exit */
648 #ifdef HAVE_LIBPCAP
649                 if_list = capture_interface_list(&err, &err_str, NULL);
650                 if (if_list == NULL) {
651                     if (err == 0)
652                         cmdarg_err("There are no interfaces on which a capture can be done");
653                     else {
654                         cmdarg_err("%s", err_str);
655                         g_free(err_str);
656                     }
657                     exit(2);
658                 }
659 #ifdef _WIN32
660                 create_console();
661 #endif /* _WIN32 */
662                 capture_opts_print_interfaces(if_list);
663                 free_interface_list(if_list);
664 #ifdef _WIN32
665                 destroy_console();
666 #endif /* _WIN32 */
667                 exit(0);
668 #else /* HAVE_LIBPCAP */
669                 capture_option_specified = TRUE;
670                 arg_error = TRUE;
671 #endif /* HAVE_LIBPCAP */
672                 break;
673             case 'h':        /* Print help and exit */
674                 print_usage(TRUE);
675                 exit(0);
676                 break;
677 #ifdef _WIN32
678             case 'i':
679                 if (strcmp(optarg, "-") == 0)
680                     set_stdin_capture(TRUE);
681                 break;
682 #endif
683             case 'P':        /* Personal file directory path settings - change these before the Preferences and alike are processed */
684                 if (!persfilepath_opt(opt, optarg)) {
685                     cmdarg_err("-P flag \"%s\" failed (hint: is it quoted and existing?)", optarg);
686                     exit(2);
687                 }
688                 break;
689             case 'v':        /* Show version and exit */
690 #ifdef _WIN32
691                 create_console();
692 #endif
693                 show_version("Wireshark", comp_info_str, runtime_info_str);
694 #ifdef _WIN32
695                 destroy_console();
696 #endif
697                 exit(0);
698                 break;
699             case 'X':
700                 /*
701                  *  Extension command line options have to be processed before
702                  *  we call epan_init() as they are supposed to be used by dissectors
703                  *  or taps very early in the registration process.
704                  */
705                 ex_opt_add(optarg);
706                 break;
707             case '?':        /* Ignore errors - the "real" scan will catch them. */
708                 break;
709         }
710     }
711
712 #ifdef _WIN32
713     reset_library_path();
714 #endif
715
716     /* Create The Wireshark app */
717     WiresharkApplication ws_app(argc, argv);
718
719     /* initialize the funnel mini-api */
720     // xxx qtshark
721     //initialize_funnel_ops();
722
723     AirPDcapInitContext(&airpdcap_ctx);
724
725     QString locale;
726     QString cf_name;
727     unsigned int in_file_type = WTAP_TYPE_AUTO;
728
729     /* Add it to the information to be reported on a crash. */
730     ws_add_crash_info("Wireshark %s\n"
731            "\n"
732            "%s"
733            "\n"
734            "%s",
735         get_ws_vcs_version_info(), comp_info_str->str, runtime_info_str->str);
736
737 #ifdef _WIN32
738     /* Start windows sockets */
739     WSAStartup( MAKEWORD( 1, 1 ), &wsaData );
740 #endif  /* _WIN32 */
741
742     profile_store_persconffiles(TRUE);
743
744     /* Read the profile independent recent file.  We have to do this here so we can */
745     /* set the profile before it can be set from the command line parameter */
746     if (!recent_read_static(&rf_path, &rf_open_errno)) {
747         simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
748                       "Could not open common recent file\n\"%s\": %s.",
749                       rf_path, strerror(rf_open_errno));
750         g_free(rf_path);
751     }
752
753     /* Read the profile dependent (static part) of the recent file. */
754     /* Only the static part of it will be read, as we don't have the gui now to fill the */
755     /* recent lists which is done in the dynamic part. */
756     /* We have to do this already here, so command line parameters can overwrite these values. */
757     if (!recent_read_profile_static(&rf_path, &rf_open_errno)) {
758         simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
759                       "Could not open recent file\n\"%s\": %s.",
760                       rf_path, g_strerror(rf_open_errno));
761         g_free(rf_path);
762     }
763     wsApp->applyCustomColorsFromRecent();
764
765     // Initialize our language
766     read_language_prefs();
767     locale = QString(language);
768     wsApp->loadLanguage(locale);
769
770     g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Translator %s", locale.toStdString().c_str());
771
772     // Init the main window (and splash)
773     main_w = new(MainWindow);
774     main_w->show();
775     // We may not need a queued connection here but it would seem to make sense
776     // to force the issue.
777     main_w->connect(&ws_app, SIGNAL(openCaptureFile(QString,QString,unsigned int)),
778             main_w, SLOT(openCaptureFile(QString,QString,unsigned int)));
779
780     /* Init the "Open file" dialog directory */
781     /* (do this after the path settings are processed) */
782     if (recent.gui_fileopen_remembered_dir &&
783         test_for_directory(recent.gui_fileopen_remembered_dir) == EISDIR) {
784       wsApp->setLastOpenDir(recent.gui_fileopen_remembered_dir);
785     } else {
786       wsApp->setLastOpenDir(get_persdatafile_dir());
787     }
788
789 #ifdef Q_OS_UNIX
790     // Replicates behavior in gtk_init();
791     signal(SIGPIPE, SIG_IGN);
792 #endif
793
794     set_console_log_handler();
795
796 #ifdef HAVE_LIBPCAP
797     /* Set the initial values in the capture options. This might be overwritten
798        by preference settings and then again by the command line parameters. */
799     capture_opts_init(&global_capture_opts);
800 #endif
801
802     init_report_err(failure_alert_box, open_failure_alert_box,
803                     read_failure_alert_box, write_failure_alert_box);
804
805     init_open_routines();
806
807 #ifdef HAVE_PLUGINS
808     /* Register all the plugin types we have. */
809     epan_register_plugin_types(); /* Types known to libwireshark */
810     wtap_register_plugin_types(); /* Types known to libwiretap */
811     codec_register_plugin_types(); /* Types known to libwscodecs */
812
813     /* Scan for plugins.  This does *not* call their registration routines;
814        that's done later. */
815     scan_plugins();
816
817     /* Register all libwiretap plugin modules. */
818     register_all_wiretap_modules();
819
820     /* Register all audio codec plugins. */
821     register_all_codecs();
822 #endif
823
824     /* Register all dissectors; we must do this before checking for the
825        "-G" flag, as the "-G" flag dumps information registered by the
826        dissectors, and we must do it before we read the preferences, in
827        case any dissectors register preferences. */
828     if (!epan_init(register_all_protocols,register_all_protocol_handoffs,
829                    splash_update, NULL)) {
830         SimpleDialog::displayQueuedMessages(main_w);
831         return 2;
832     }
833
834     splash_update(RA_LISTENERS, NULL, NULL);
835
836     /* Register all tap listeners; we do this before we parse the arguments,
837        as the "-z" argument can specify a registered tap. */
838
839     /* we register the plugin taps before the other taps because
840             stats_tree taps plugins will be registered as tap listeners
841             by stats_tree_stat.c and need to registered before that */
842 #ifdef HAVE_PLUGINS
843     register_all_plugin_tap_listeners();
844 #endif
845
846 #ifdef HAVE_EXTCAP
847     extcap_register_preferences();
848 #endif
849
850     register_all_tap_listeners();
851     conversation_table_set_gui_info(init_conversation_table);
852     hostlist_table_set_gui_info(init_endpoint_table);
853     srt_table_iterate_tables(register_service_response_tables, NULL);
854     rtd_table_iterate_tables(register_response_time_delay_tables, NULL);
855     new_stat_tap_iterate_tables(register_simple_stat_tables, NULL);
856
857     if (ex_opt_count("read_format") > 0) {
858         in_file_type = open_info_name_to_type(ex_opt_get_next("read_format"));
859     }
860
861     splash_update(RA_PREFERENCES, NULL, NULL);
862
863     prefs_p = ws_app.readConfigurationFiles(&gdp_path, &dp_path, false);
864
865     /*
866      * To reset the options parser, set optreset to 1 on platforms that
867      * have optreset (documented in *BSD and OS X, apparently present but
868      * not documented in Solaris - the Illumos repository seems to
869      * suggest that the first Solaris getopt_long(), at least as of 2004,
870      * was based on the NetBSD one, it had optreset) and set optind to 1,
871      * and set optind to 0 otherwise (documented as working in the GNU
872      * getopt_long().  Setting optind to 0 didn't originally work in the
873      * NetBSD one, but that was added later - we don't want to depend on
874      * it if we have optreset).
875      *
876      * Also reset opterr to 1, so that error messages are printed by
877      * getopt_long().
878      *
879      * XXX - if we want to control all the command-line option errors, so
880      * that we can display them where we choose (e.g., in a window), we'd
881      * want to leave opterr as 0, and produce our own messages using optopt.
882      * We'd have to check the value of optopt to see if it's a valid option
883      * letter, in which case *presumably* the error is "this option requires
884      * an argument but none was specified", or not a valid option letter,
885      * in which case *presumably* the error is "this option isn't valid".
886      * Some versions of getopt() let you supply a option string beginning
887      * with ':', which means that getopt() will return ':' rather than '?'
888      * for "this option requires an argument but none was specified", but
889      * not all do.  But we're now using getopt_long() - what does it do?
890      */
891 #ifdef HAVE_OPTRESET
892     optreset = 1;
893     optind = 1;
894 #else
895     optind = 0;
896 #endif
897     opterr = 1;
898
899     /* Now get our args */
900     while ((opt = getopt_long(argc, ws_argv, optstring, long_options, NULL)) != -1) {
901         switch (opt) {
902         /*** capture option specific ***/
903         case 'a':        /* autostop criteria */
904         case 'b':        /* Ringbuffer option */
905         case 'c':        /* Capture xxx packets */
906         case 'f':        /* capture filter */
907         case 'k':        /* Start capture immediately */
908         case 'H':        /* Hide capture info dialog box */
909         case 'p':        /* Don't capture in promiscuous mode */
910         case 'i':        /* Use interface x */
911 #ifdef HAVE_PCAP_CREATE
912         case 'I':        /* Capture in monitor mode, if available */
913 #endif
914 #ifdef HAVE_PCAP_REMOTE
915         case 'A':        /* Authentication */
916 #endif
917         case 's':        /* Set the snapshot (capture) length */
918         case 'S':        /* "Sync" mode: used for following file ala tail -f */
919         case 'w':        /* Write to capture file xxx */
920         case 'y':        /* Set the pcap data link type */
921 #ifdef CAN_SET_CAPTURE_BUFFER_SIZE
922         case 'B':        /* Buffer size */
923 #endif
924 #ifdef HAVE_LIBPCAP
925             status = capture_opts_add_opt(&global_capture_opts, opt, optarg,
926                                           &start_capture);
927             if(status != 0) {
928                 exit(status);
929             }
930 #else
931             capture_option_specified = TRUE;
932             arg_error = TRUE;
933 #endif
934             break;
935 #ifdef HAVE_KERBEROS
936         case 'K':        /* Kerberos keytab file */
937             read_keytab_file(optarg);
938             break;
939 #endif
940
941         /*** all non capture option specific ***/
942         case 'C':
943             /* Configuration profile settings were already processed just ignore them this time*/
944             break;
945         case 'j':        /* Search backwards for a matching packet from filter in option J */
946             /* Not supported yet */
947             break;
948         case 'g':        /* Go to packet with the given packet number */
949             go_to_packet = get_positive_int(optarg, "go to packet");
950             break;
951         case 'J':        /* Jump to the first packet which matches the filter criteria */
952             /* Not supported yet */
953             break;
954         case 'l':        /* Automatic scrolling in live capture mode */
955 #ifdef HAVE_LIBPCAP
956             /* Not supported yet */
957 #else
958             capture_option_specified = TRUE;
959             arg_error = TRUE;
960 #endif
961             break;
962         case 'L':        /* Print list of link-layer types and exit */
963 #ifdef HAVE_LIBPCAP
964                 list_link_layer_types = TRUE;
965 #else
966                 capture_option_specified = TRUE;
967                 arg_error = TRUE;
968 #endif
969             break;
970         case 'm':        /* Fixed-width font for the display */
971             /* Not supported yet */
972             break;
973         case 'n':        /* No name resolution */
974             disable_name_resolution();
975             break;
976         case 'N':        /* Select what types of addresses/port #s to resolve */
977             badopt = string_to_name_resolve(optarg, &gbl_resolv_flags);
978             if (badopt != '\0') {
979                 cmdarg_err("-N specifies unknown resolving option '%c'; valid options are 'C', 'd', m', 'n', 'N', and 't'",
980                            badopt);
981                 exit(1);
982             }
983             break;
984         case 'o':        /* Override preference from command line */
985             switch (prefs_set_pref(optarg)) {
986                 case PREFS_SET_OK:
987                     break;
988                 case PREFS_SET_SYNTAX_ERR:
989                     cmdarg_err("Invalid -o flag \"%s\"", optarg);
990                     exit(1);
991                     break;
992                 case PREFS_SET_NO_SUCH_PREF:
993                 /* not a preference, might be a recent setting */
994                     switch (recent_set_arg(optarg)) {
995                         case PREFS_SET_OK:
996                             break;
997                         case PREFS_SET_SYNTAX_ERR:
998                             /* shouldn't happen, checked already above */
999                             cmdarg_err("Invalid -o flag \"%s\"", optarg);
1000                             exit(1);
1001                             break;
1002                         case PREFS_SET_NO_SUCH_PREF:
1003                         case PREFS_SET_OBSOLETE:
1004                             cmdarg_err("-o flag \"%s\" specifies unknown preference/recent value",
1005                                        optarg);
1006                             exit(1);
1007                             break;
1008                         default:
1009                             g_assert_not_reached();
1010                     }
1011                     break;
1012                 case PREFS_SET_OBSOLETE:
1013                     cmdarg_err("-o flag \"%s\" specifies obsolete preference",
1014                                optarg);
1015                     exit(1);
1016                     break;
1017                 default:
1018                     g_assert_not_reached();
1019             }
1020             break;
1021         case 'P':
1022             /* Path settings were already processed just ignore them this time*/
1023             break;
1024         case 'r':
1025             cf_name = optarg;
1026             break;
1027         case 'R':        /* Read file filter */
1028             read_filter = QString(optarg);
1029             break;
1030         case 't':        /* Time stamp type */
1031             if (strcmp(optarg, "r") == 0)
1032                 timestamp_set_type(TS_RELATIVE);
1033             else if (strcmp(optarg, "a") == 0)
1034                 timestamp_set_type(TS_ABSOLUTE);
1035             else if (strcmp(optarg, "ad") == 0)
1036                 timestamp_set_type(TS_ABSOLUTE_WITH_YMD);
1037             else if (strcmp(optarg, "adoy") == 0)
1038                 timestamp_set_type(TS_ABSOLUTE_WITH_YDOY);
1039             else if (strcmp(optarg, "d") == 0)
1040                 timestamp_set_type(TS_DELTA);
1041             else if (strcmp(optarg, "dd") == 0)
1042                 timestamp_set_type(TS_DELTA_DIS);
1043             else if (strcmp(optarg, "e") == 0)
1044                 timestamp_set_type(TS_EPOCH);
1045             else if (strcmp(optarg, "u") == 0)
1046                 timestamp_set_type(TS_UTC);
1047             else if (strcmp(optarg, "ud") == 0)
1048                 timestamp_set_type(TS_UTC_WITH_YMD);
1049             else if (strcmp(optarg, "udoy") == 0)
1050                 timestamp_set_type(TS_UTC_WITH_YDOY);
1051             else {
1052                 cmdarg_err("Invalid time stamp type \"%s\"", optarg);
1053                 cmdarg_err_cont(
1054 "It must be \"a\" for absolute, \"ad\" for absolute with YYYY-MM-DD date,");
1055                 cmdarg_err_cont(
1056 "\"adoy\" for absolute with YYYY/DOY date, \"d\" for delta,");
1057                 cmdarg_err_cont(
1058 "\"dd\" for delta displayed, \"e\" for epoch, \"r\" for relative,");
1059                 cmdarg_err_cont(
1060 "\"u\" for absolute UTC, \"ud\" for absolute UTC with YYYY-MM-DD date,");
1061                 cmdarg_err_cont(
1062 "or \"udoy\" for absolute UTC with YYYY/DOY date.");
1063                 exit(1);
1064             }
1065             break;
1066         case 'u':        /* Seconds type */
1067             if (strcmp(optarg, "s") == 0)
1068                 timestamp_set_seconds_type(TS_SECONDS_DEFAULT);
1069             else if (strcmp(optarg, "hms") == 0)
1070                 timestamp_set_seconds_type(TS_SECONDS_HOUR_MIN_SEC);
1071             else {
1072                 cmdarg_err("Invalid seconds type \"%s\"", optarg);
1073                 cmdarg_err_cont(
1074 "It must be \"s\" for seconds or \"hms\" for hours, minutes and seconds.");
1075                 exit(1);
1076             }
1077             break;
1078         case 'X':
1079             /* ext ops were already processed just ignore them this time*/
1080             break;
1081         case 'Y':
1082             dfilter = QString(optarg);
1083             break;
1084         case 'z':
1085             /* We won't call the init function for the stat this soon
1086              as it would disallow MATE's fields (which are registered
1087              by the preferences set callback) from being used as
1088              part of a tap filter.  Instead, we just add the argument
1089              to a list of stat arguments. */
1090             if (strcmp("help", optarg) == 0) {
1091               fprintf(stderr, "wireshark: The available statistics for the \"-z\" option are:\n");
1092               list_stat_cmd_args();
1093               exit(0);
1094             }
1095             if (!process_stat_cmd_arg(optarg)) {
1096                 cmdarg_err("Invalid -z argument.");
1097                 cmdarg_err_cont("  -z argument must be one of :");
1098                 list_stat_cmd_args();
1099                 exit(1);
1100             }
1101             break;
1102         case LONGOPT_DISABLE_PROTOCOL: /* disable dissection of protocol */
1103             disable_protocol_slist = g_slist_append(disable_protocol_slist, optarg);
1104             break;
1105         case LONGOPT_ENABLE_HEURISTIC: /* enable heuristic dissection of protocol */
1106             enable_heur_slist = g_slist_append(enable_heur_slist, optarg);
1107             break;
1108         case LONGOPT_DISABLE_HEURISTIC: /* disable heuristic dissection of protocol */
1109             disable_heur_slist = g_slist_append(disable_heur_slist, optarg);
1110             break;
1111
1112         default:
1113         case '?':        /* Bad flag - print usage message */
1114             print_usage(FALSE);
1115             exit(0);
1116             break;
1117         }
1118     }
1119
1120     if (!arg_error) {
1121         argc -= optind;
1122         ws_argv += optind;
1123         if (argc >= 1) {
1124             if (!cf_name.isEmpty()) {
1125                 /*
1126                  * Input file name specified with "-r" *and* specified as a regular
1127                  * command-line argument.
1128                  */
1129                 cmdarg_err("File name specified both with -r and regular argument");
1130                 arg_error = TRUE;
1131             } else {
1132                 /*
1133                  * Input file name not specified with "-r", and a command-line argument
1134                  * was specified; treat it as the input file name.
1135                  *
1136                  * Yes, this is different from tshark, where non-flag command-line
1137                  * arguments are a filter, but this works better on GUI desktops
1138                  * where a command can be specified to be run to open a particular
1139                  * file - yes, you could have "-r" as the last part of the command,
1140                  * but that's a bit ugly.
1141                  */
1142                 cf_name = ws_argv[0];
1143
1144             }
1145             argc--;
1146             ws_argv++;
1147         }
1148
1149         if (argc != 0) {
1150             /*
1151              * Extra command line arguments were specified; complain.
1152              */
1153             cmdarg_err("Invalid argument: %s", ws_argv[0]);
1154             arg_error = TRUE;
1155         }
1156     }
1157     if (arg_error) {
1158 #ifndef HAVE_LIBPCAP
1159         if (capture_option_specified) {
1160             cmdarg_err("This version of Wireshark was not built with support for capturing packets.");
1161         }
1162 #endif
1163         print_usage(FALSE);
1164         exit(1);
1165     }
1166
1167     /* Removed thread code:
1168      * https://code.wireshark.org/review/gitweb?p=wireshark.git;a=commit;h=9e277ae6154fd04bf6a0a34ec5655a73e5a736a3
1169      */
1170
1171     // XXX Is there a better place to set the timestamp format & precision?
1172     timestamp_set_type(recent.gui_time_format);
1173     timestamp_set_precision(recent.gui_time_precision);
1174     timestamp_set_seconds_type (recent.gui_seconds_format);
1175
1176 #ifdef HAVE_LIBPCAP
1177     fill_in_local_interfaces(main_window_update);
1178
1179     if (start_capture && list_link_layer_types) {
1180         /* Specifying *both* is bogus. */
1181         cmdarg_err("You can't specify both -L and a live capture.");
1182         exit(1);
1183     }
1184
1185     if (list_link_layer_types) {
1186         /* We're supposed to list the link-layer types for an interface;
1187            did the user also specify a capture file to be read? */
1188         if (!cf_name.isEmpty()) {
1189             /* Yes - that's bogus. */
1190             cmdarg_err("You can't specify -L and a capture file to be read.");
1191         exit(1);
1192         }
1193         /* No - did they specify a ring buffer option? */
1194         if (global_capture_opts.multi_files_on) {
1195             cmdarg_err("Ring buffer requested, but a capture isn't being done.");
1196             exit(1);
1197         }
1198     } else {
1199         /* We're supposed to do a live capture; did the user also specify
1200            a capture file to be read? */
1201         if (start_capture && !cf_name.isEmpty()) {
1202             /* Yes - that's bogus. */
1203             cmdarg_err("You can't specify both a live capture and a capture file to be read.");
1204             exit(1);
1205         }
1206
1207         /* No - was the ring buffer option specified and, if so, does it make
1208            sense? */
1209         if (global_capture_opts.multi_files_on) {
1210             /* Ring buffer works only under certain conditions:
1211              a) ring buffer does not work with temporary files;
1212              b) real_time_mode and multi_files_on are mutually exclusive -
1213              real_time_mode takes precedence;
1214              c) it makes no sense to enable the ring buffer if the maximum
1215              file size is set to "infinite". */
1216             if (global_capture_opts.save_file == NULL) {
1217                 cmdarg_err("Ring buffer requested, but capture isn't being saved to a permanent file.");
1218                 global_capture_opts.multi_files_on = FALSE;
1219             }
1220             if (!global_capture_opts.has_autostop_filesize && !global_capture_opts.has_file_duration) {
1221                 cmdarg_err("Ring buffer requested, but no maximum capture file size or duration were specified.");
1222                 /* XXX - this must be redesigned as the conditions changed */
1223             }
1224         }
1225     }
1226
1227     if (start_capture || list_link_layer_types) {
1228         /* We're supposed to do a live capture or get a list of link-layer
1229            types for a live capture device; if the user didn't specify an
1230            interface to use, pick a default. */
1231         status = capture_opts_default_iface_if_necessary(&global_capture_opts,
1232         ((prefs_p->capture_device) && (*prefs_p->capture_device != '\0')) ? get_if_name(prefs_p->capture_device) : NULL);
1233         if (status != 0) {
1234             exit(status);
1235         }
1236     }
1237
1238     if (list_link_layer_types) {
1239         /* Get the list of link-layer types for the capture devices. */
1240         if_capabilities_t *caps;
1241         guint i;
1242         interface_t device;
1243         for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
1244
1245             device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
1246             if (device.selected) {
1247 #if defined(HAVE_PCAP_CREATE)
1248                 caps = capture_get_if_capabilities(device.name, device.monitor_mode_supported, NULL, &err_str, main_window_update);
1249 #else
1250                 caps = capture_get_if_capabilities(device.name, FALSE, NULL, &err_str,main_window_update);
1251 #endif
1252                 if (caps == NULL) {
1253                     cmdarg_err("%s", err_str);
1254                     g_free(err_str);
1255                     exit(2);
1256                 }
1257             if (caps->data_link_types == NULL) {
1258                 cmdarg_err("The capture device \"%s\" has no data link types.", device.name);
1259                 exit(2);
1260             }
1261 #ifdef _WIN32
1262             create_console();
1263 #endif /* _WIN32 */
1264 #if defined(HAVE_PCAP_CREATE)
1265             capture_opts_print_if_capabilities(caps, device.name, device.monitor_mode_supported);
1266 #else
1267             capture_opts_print_if_capabilities(caps, device.name, FALSE);
1268 #endif
1269 #ifdef _WIN32
1270             destroy_console();
1271 #endif /* _WIN32 */
1272             free_if_capabilities(caps);
1273             }
1274         }
1275         exit(0);
1276     }
1277
1278     capture_opts_trim_snaplen(&global_capture_opts, MIN_PACKET_SIZE);
1279     capture_opts_trim_ring_num_files(&global_capture_opts);
1280 #endif /* HAVE_LIBPCAP */
1281
1282     /* Notify all registered modules that have had any of their preferences
1283        changed either from one of the preferences file or from the command
1284        line that their preferences have changed. */
1285     prefs_apply_all();
1286     wsApp->emitAppSignal(WiresharkApplication::PreferencesChanged);
1287
1288 #ifdef HAVE_LIBPCAP
1289     if ((global_capture_opts.num_selected == 0) &&
1290             (prefs.capture_device != NULL)) {
1291         guint i;
1292         interface_t device;
1293         for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
1294             device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
1295             if (!device.hidden && strcmp(device.display_name, prefs.capture_device) == 0) {
1296                 device.selected = TRUE;
1297                 global_capture_opts.num_selected++;
1298                 global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, i);
1299                 g_array_insert_val(global_capture_opts.all_ifaces, i, device);
1300                 break;
1301             }
1302         }
1303     }
1304 #endif
1305
1306     /* disabled protocols as per configuration file */
1307     if (gdp_path == NULL && dp_path == NULL) {
1308         set_disabled_protos_list();
1309         set_disabled_heur_dissector_list();
1310     }
1311
1312     if(disable_protocol_slist) {
1313         GSList *proto_disable;
1314         for (proto_disable = disable_protocol_slist; proto_disable != NULL; proto_disable = g_slist_next(proto_disable))
1315         {
1316             proto_disable_proto_by_name((char*)proto_disable->data);
1317         }
1318     }
1319
1320     if(enable_heur_slist) {
1321         GSList *heur_enable;
1322         for (heur_enable = enable_heur_slist; heur_enable != NULL; heur_enable = g_slist_next(heur_enable))
1323         {
1324             proto_enable_heuristic_by_name((char*)heur_enable->data, TRUE);
1325         }
1326     }
1327
1328     if(disable_heur_slist) {
1329         GSList *heur_disable;
1330         for (heur_disable = disable_heur_slist; heur_disable != NULL; heur_disable = g_slist_next(heur_disable))
1331         {
1332             proto_enable_heuristic_by_name((char*)heur_disable->data, FALSE);
1333         }
1334     }
1335
1336     build_column_format_array(&CaptureFile::globalCapFile()->cinfo, prefs_p->num_cols, TRUE);
1337     wsApp->emitAppSignal(WiresharkApplication::ColumnsChanged); // We read "recent" widths above.
1338     wsApp->emitAppSignal(WiresharkApplication::RecentFilesRead); // Must be emitted after PreferencesChanged.
1339
1340     wsApp->setMonospaceFont(prefs.gui_qt_font_name);
1341
1342     /* For update of WindowTitle (When use gui.window_title preference) */
1343     main_w->setWSWindowTitle();
1344 ////////
1345
1346     /* Read the dynamic part of the recent file, as we have the gui now ready for
1347        it. */
1348     if (!recent_read_dynamic(&rf_path, &rf_open_errno)) {
1349         simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
1350                       "Could not open recent file\n\"%s\": %s.",
1351                       rf_path, g_strerror(rf_open_errno));
1352         g_free(rf_path);
1353     }
1354
1355     packet_list_enable_color(recent.packet_list_colorize);
1356
1357     g_log(NULL, G_LOG_LEVEL_DEBUG, "FIX: fetch recent color settings");
1358     packet_list_enable_color(TRUE);
1359
1360 ////////
1361
1362
1363 ////////
1364     gchar* err_msg = NULL;
1365     if (!color_filters_init(&err_msg, color_filter_add_cb)) {
1366         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", err_msg);
1367         g_free(err_msg);
1368     }
1369
1370 ////////
1371
1372 #ifdef HAVE_LIBPCAP
1373     /* if the user didn't supply a capture filter, use the one to filter out remote connections like SSH */
1374     if (!start_capture && !global_capture_opts.default_options.cfilter) {
1375         global_capture_opts.default_options.cfilter = g_strdup(get_conn_cfilter());
1376     }
1377 #else /* HAVE_LIBPCAP */
1378     ////////
1379 #endif /* HAVE_LIBPCAP */
1380
1381     wsApp->allSystemsGo();
1382     g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_INFO, "Wireshark is up and ready to go");
1383     SimpleDialog::displayQueuedMessages(main_w);
1384
1385     /* User could specify filename, or display filter, or both */
1386     if (!dfilter.isEmpty())
1387         main_w->filterPackets(dfilter, false);
1388     if (!cf_name.isEmpty()) {
1389         if (main_w->openCaptureFile(cf_name, read_filter, in_file_type)) {
1390
1391             /* Open stat windows; we do so after creating the main window,
1392                to avoid Qt warnings, and after successfully opening the
1393                capture file, so we know we have something to compute stats
1394                on, and after registering all dissectors, so that MATE will
1395                have registered its field array and we can have a tap filter
1396                with one of MATE's late-registered fields as part of the
1397                filter. */
1398             start_requested_stats();
1399
1400             if(go_to_packet != 0) {
1401                 /* Jump to the specified frame number, kept for backward
1402                    compatibility. */
1403                 cf_goto_frame(CaptureFile::globalCapFile(), go_to_packet);
1404             }
1405         }
1406     }
1407 #ifdef HAVE_LIBPCAP
1408     else {
1409         if (start_capture) {
1410             if (global_capture_opts.save_file != NULL) {
1411                 /* Save the directory name for future file dialogs. */
1412                 /* (get_dirname overwrites filename) */
1413                 gchar *s = get_dirname(g_strdup(global_capture_opts.save_file));
1414                 set_last_open_dir(s);
1415                 g_free(s);
1416             }
1417             /* "-k" was specified; start a capture. */
1418 //            show_main_window(FALSE);
1419             check_and_warn_user_startup(cf_name);
1420
1421             /* If no user interfaces were specified on the command line,
1422                copy the list of selected interfaces to the set of interfaces
1423                to use for this capture. */
1424             if (global_capture_opts.ifaces->len == 0)
1425                 collect_ifaces(&global_capture_opts);
1426             CaptureFile::globalCapFile()->window = main_w;
1427             if (capture_start(&global_capture_opts, main_w->captureSession(), main_w->captureInfoData(), main_window_update)) {
1428                 /* The capture started.  Open stat windows; we do so after creating
1429                    the main window, to avoid GTK warnings, and after successfully
1430                    opening the capture file, so we know we have something to compute
1431                    stats on, and after registering all dissectors, so that MATE will
1432                    have registered its field array and we can have a tap filter with
1433                    one of MATE's late-registered fields as part of the filter. */
1434                 start_requested_stats();
1435             }
1436         }
1437     /* if the user didn't supply a capture filter, use the one to filter out remote connections like SSH */
1438         if (!start_capture && !global_capture_opts.default_options.cfilter) {
1439             global_capture_opts.default_options.cfilter = g_strdup(get_conn_cfilter());
1440         }
1441     }
1442 #endif /* HAVE_LIBPCAP */
1443
1444     return wsApp->exec();
1445 }
1446
1447 /*
1448  * Editor modelines
1449  *
1450  * Local Variables:
1451  * c-basic-offset: 4
1452  * tab-width: 8
1453  * indent-tabs-mode: nil
1454  * End:
1455  *
1456  * ex: set shiftwidth=4 tabstop=8 expandtab:
1457  * :indentSize=4:tabSize=8:noTabs=true:
1458  */