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