Replace "svn" with "git" all over the place.
[metze/wireshark/wip.git] / ui / qt / main.cpp
1 /* main.cpp
2  *
3  * $Id$
4  *
5  * Wireshark - Network traffic analyzer
6  * By Gerald Combs <gerald@wireshark.org>
7  * Copyright 1998 Gerald Combs
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License
11  * as published by the Free Software Foundation; either version 2
12  * of the License, or (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22  */
23
24 #include "config.h"
25
26 #include "wireshark_application.h"
27 #include "main_window.h"
28
29 #include <ctype.h>
30 #include "globals.h"
31
32 #include <glib.h>
33
34 #ifndef HAVE_GETOPT
35 #  include "wsutil/wsgetopt.h"
36 #else
37 #  include <getopt.h>
38 #endif
39
40 #include <wsutil/crash_info.h>
41 #include <wsutil/filesystem.h>
42 #include <wsutil/file_util.h>
43 #include <wsutil/privileges.h>
44 #ifdef HAVE_PLUGINS
45 #include <wsutil/plugins.h>
46 #endif
47 #include <wsutil/report_err.h>
48 #include <wsutil/u3.h>
49
50 #include <wiretap/merge.h>
51
52 #include <epan/epan.h>
53 #include <epan/epan_dissect.h>
54 #include <epan/timestamp.h>
55 #include <epan/packet.h>
56 #include <epan/dfilter/dfilter.h>
57 #include <epan/strutil.h>
58 #include <epan/addr_resolv.h>
59 #include <epan/emem.h>
60 #include <epan/ex-opt.h>
61 #include <epan/funnel.h>
62 #include <epan/expert.h>
63 #include <epan/frequency-utils.h>
64 #include <epan/prefs.h>
65 #include <epan/prefs-int.h>
66 #include <epan/tap.h>
67 #include <epan/stat_cmd_args.h>
68 #include <epan/uat.h>
69 #include <epan/column.h>
70 #include <epan/disabled_protos.h>
71 #include <epan/print.h>
72
73 #ifdef HAVE_PLUGINS
74 #include <codecs/codecs.h>
75 #endif
76
77 /* general (not Qt specific) */
78 #include "file.h"
79 #include "summary.h"
80 #include "color.h"
81 #include "color_filters.h"
82 #include "register.h"
83 #include "ringbuffer.h"
84 #include "ui/util.h"
85 #include "clopts_common.h"
86 #include "cmdarg_err.h"
87 #include "version_info.h"
88 #include "log.h"
89
90 #include "ui/alert_box.h"
91 #include "ui/capture_globals.h"
92 #include "ui/iface_lists.h"
93 #include "ui/main_statusbar.h"
94 #include "ui/persfilepath_opt.h"
95 #include "ui/recent.h"
96 #include "ui/simple_dialog.h"
97 #include "ui/ui_util.h"
98
99 #ifdef HAVE_LIBPCAP
100 #  include "capture_ui_utils.h"
101 #  include "capture-pcap-util.h"
102 #  include "capture_ifinfo.h"
103 #  include "capture.h"
104 #  include "capture_sync.h"
105 #endif
106
107 #ifdef _WIN32
108 #  include "capture-wpcap.h"
109 #  include "capture_wpcap_packet.h"
110 #  include <tchar.h> /* Needed for Unicode */
111 #  include <wsutil/unicode-utils.h>
112 #  include <commctrl.h>
113 #  include <shellapi.h>
114 #  include <conio.h>
115 #  include "ui/win32/console_win32.h"
116 #endif /* _WIN32 */
117
118 #ifdef HAVE_AIRPCAP
119 #  include <airpcap.h>
120 #  include "airpcap_loader.h"
121 //#  include "airpcap_dlg.h"
122 //#  include "airpcap_gui_utils.h"
123 #endif
124
125 #include <epan/crypt/airpdcap_ws.h>
126
127 #include <QDebug>
128 #include <QDateTime>
129 #if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0))
130 #include <QTextCodec>
131 #endif
132 #include <qtranslator.h>
133 #include <qlocale.h>
134 #include <qlibraryinfo.h>
135
136 #ifdef HAVE_LIBPCAP
137 capture_options global_capture_opts;
138 capture_session global_capture_session;
139 #endif
140
141 capture_file cfile;
142
143 #ifdef HAVE_AIRPCAP
144 int    airpcap_dll_ret_val = -1;
145 #endif
146
147 GString *comp_info_str, *runtime_info_str;
148
149 //static gboolean have_capture_file = FALSE; /* XXX - is there an equivalent in cfile? */
150
151 static void console_log_handler(const char *log_domain,
152     GLogLevelFlags log_level, const char *message, gpointer user_data);
153
154
155 #ifdef HAVE_LIBPCAP
156 extern capture_options global_capture_opts;
157
158 static void
159 main_capture_callback(gint event, capture_session *cap_session, gpointer user_data )
160 {
161     Q_UNUSED(user_data);
162     wsApp->captureCallback(event, cap_session);
163 }
164 #endif // HAVE_LIBPCAP
165
166 static void
167 main_cf_callback(gint event, gpointer data, gpointer user_data )
168 {
169     Q_UNUSED(user_data);
170     wsApp->captureFileCallback(event, data);
171 }
172
173 /* update the main window */
174 void main_window_update(void)
175 {
176     WiresharkApplication::processEvents();
177 }
178
179 #ifdef HAVE_LIBPCAP
180
181 /* quit a nested main window */
182 void main_window_nested_quit(void)
183 {
184 //    if (gtk_main_level() > 0)
185     wsApp->quit();
186 }
187
188 /* quit the main window */
189 void main_window_quit(void)
190 {
191     wsApp->quit();
192 }
193
194 #endif /* HAVE_LIBPCAP */
195
196
197 // xxx copied from ../gtk/main.c
198 static void
199 print_usage(gboolean print_ver) {
200     FILE *output;
201
202 #ifdef _WIN32
203     create_console();
204 #endif
205
206     if (print_ver) {
207         output = stdout;
208         fprintf(output, "Wireshark " VERSION "%s\n"
209                 "Interactively dump and analyze network traffic.\n"
210                 "See http://www.wireshark.org for more information.\n"
211                 "\n"
212                 "%s",
213                 wireshark_gitversion, get_copyright_info());
214     } else {
215         output = stderr;
216     }
217     fprintf(output, "\n");
218     fprintf(output, "Usage: wireshark [options] ... [ <infile> ]\n");
219     fprintf(output, "\n");
220
221 #ifdef HAVE_LIBPCAP
222     fprintf(output, "Capture interface:\n");
223     fprintf(output, "  -i <interface>           name or idx of interface (def: first non-loopback)\n");
224     fprintf(output, "  -f <capture filter>      packet filter in libpcap filter syntax\n");
225     fprintf(output, "  -s <snaplen>             packet snapshot length (def: 65535)\n");
226     fprintf(output, "  -p                       don't capture in promiscuous mode\n");
227     fprintf(output, "  -k                       start capturing immediately (def: do nothing)\n");
228     fprintf(output, "  -Q                       quit Wireshark after capturing\n");
229     fprintf(output, "  -S                       update packet display when new packets are captured\n");
230     fprintf(output, "  -l                       turn on automatic scrolling while -S is in use\n");
231 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
232     fprintf(output, "  -B <buffer size>         size of kernel buffer (def: %dMB)\n", DEFAULT_CAPTURE_BUFFER_SIZE);
233 #endif
234     fprintf(output, "  -y <link type>           link layer type (def: first appropriate)\n");
235     fprintf(output, "  -D                       print list of interfaces and exit\n");
236     fprintf(output, "  -L                       print list of link-layer types of iface and exit\n");
237     fprintf(output, "\n");
238     fprintf(output, "Capture stop conditions:\n");
239     fprintf(output, "  -c <packet count>        stop after n packets (def: infinite)\n");
240     fprintf(output, "  -a <autostop cond.> ...  duration:NUM - stop after NUM seconds\n");
241     fprintf(output, "                           filesize:NUM - stop this file after NUM KB\n");
242     fprintf(output, "                              files:NUM - stop after NUM files\n");
243     /*fprintf(output, "\n");*/
244     fprintf(output, "Capture output:\n");
245     fprintf(output, "  -b <ringbuffer opt.> ... duration:NUM - switch to next file after NUM secs\n");
246     fprintf(output, "                           filesize:NUM - switch to next file after NUM KB\n");
247     fprintf(output, "                              files:NUM - ringbuffer: replace after NUM files\n");
248 #endif  /* HAVE_LIBPCAP */
249
250     /*fprintf(output, "\n");*/
251     fprintf(output, "Input file:\n");
252     fprintf(output, "  -r <infile>              set the filename to read from (no pipes or stdin!)\n");
253
254     fprintf(output, "\n");
255     fprintf(output, "Processing:\n");
256     fprintf(output, "  -R <read filter>         packet filter in Wireshark display filter syntax\n");
257     fprintf(output, "  -n                       disable all name resolutions (def: all enabled)\n");
258     fprintf(output, "  -N <name resolve flags>  enable specific name resolution(s): \"mntC\"\n");
259
260     fprintf(output, "\n");
261     fprintf(output, "User interface:\n");
262     fprintf(output, "  -C <config profile>      start with specified configuration profile\n");
263     fprintf(output, "  -g <packet number>       go to specified packet number after \"-r\"\n");
264     fprintf(output, "  -J <jump filter>         jump to the first packet matching the (display)\n");
265     fprintf(output, "                           filter\n");
266     fprintf(output, "  -j                       search backwards for a matching packet after \"-J\"\n");
267     fprintf(output, "  -m <font>                set the font name used for most text\n");
268     fprintf(output, "  -t ad|a|r|d|dd|e         output format of time stamps (def: r: rel. to first)\n");
269     fprintf(output, "  -u s|hms                 output format of seconds (def: s: seconds)\n");
270     fprintf(output, "  -X <key>:<value>         eXtension options, see man page for details\n");
271     fprintf(output, "  -z <statistics>          show various statistics, see man page for details\n");
272
273     fprintf(output, "\n");
274     fprintf(output, "Output:\n");
275     fprintf(output, "  -w <outfile|->           set the output filename (or '-' for stdout)\n");
276
277     fprintf(output, "\n");
278     fprintf(output, "Miscellaneous:\n");
279     fprintf(output, "  -h                       display this help and exit\n");
280     fprintf(output, "  -v                       display version info and exit\n");
281     fprintf(output, "  -P <key>:<path>          persconf:path - personal configuration files\n");
282     fprintf(output, "                           persdata:path - personal data files\n");
283     fprintf(output, "  -o <name>:<value> ...    override preference or recent setting\n");
284     fprintf(output, "  -K <keytab>              keytab file to use for kerberos decryption\n");
285 #ifndef _WIN32
286     fprintf(output, "  --display=DISPLAY        X display to use\n");
287 #endif
288
289 #ifdef _WIN32
290     destroy_console();
291 #endif
292 }
293
294 // xxx copied from ../gtk/main.c
295 static void
296 show_version(void)
297 {
298     printf(PACKAGE " " VERSION "%s\n"
299            "\n"
300            "%s"
301            "\n"
302            "%s"
303            "\n"
304            "%s",
305            wireshark_gitversion, get_copyright_info(), comp_info_str->str,
306            runtime_info_str->str);
307 }
308
309 /*
310  * Report an error in command-line arguments.
311  * Creates a console on Windows.
312  */
313 // xxx copied from ../gtk/main.c
314 void
315 cmdarg_err(const char *fmt, ...)
316 {
317     va_list ap;
318
319 #ifdef _WIN32
320     create_console();
321 #endif
322     fprintf(stderr, "wireshark: ");
323     va_start(ap, fmt);
324     vfprintf(stderr, fmt, ap);
325     va_end(ap);
326     fprintf(stderr, "\n");
327 }
328
329 /*
330  * Report additional information for an error in command-line arguments.
331  * Creates a console on Windows.
332  * XXX - pop this up in a window of some sort on UNIX+X11 if the controlling
333  * terminal isn't the standard error?
334  */
335 // xxx copied from ../gtk/main.c
336 void
337 cmdarg_err_cont(const char *fmt, ...)
338 {
339     va_list ap;
340
341 #ifdef _WIN32
342     create_console();
343 #endif
344     va_start(ap, fmt);
345     vfprintf(stderr, fmt, ap);
346     fprintf(stderr, "\n");
347     va_end(ap);
348 }
349
350 static void
351 console_log_handler(const char *log_domain, GLogLevelFlags log_level,
352                     const char *message, gpointer user_data)
353 {
354     Q_UNUSED(user_data);
355     QString level;
356     QString hmsz = QDateTime::currentDateTime().toString("hh:mm:ss.zzz");
357
358 // xxx qtshark: We want all of the messages for now.
359 //    /* ignore log message, if log_level isn't interesting based
360 //     upon the console log preferences.
361 //     If the preferences haven't been loaded loaded yet, display the
362 //     message anyway.
363
364 //     The default console_log_level preference value is such that only
365 //       ERROR, CRITICAL and WARNING level messages are processed;
366 //       MESSAGE, INFO and DEBUG level messages are ignored.  */
367 //    if((log_level & G_LOG_LEVEL_MASK & prefs.console_log_level) == 0 &&
368 //       prefs.console_log_level != 0) {
369 //        return;
370
371         switch(log_level & G_LOG_LEVEL_MASK) {
372         case G_LOG_LEVEL_ERROR:
373             level = "Err ";
374             break;
375         case G_LOG_LEVEL_CRITICAL:
376             level = "Crit";
377             break;
378         case G_LOG_LEVEL_WARNING:
379             level = "Warn";
380             break;
381         case G_LOG_LEVEL_MESSAGE:
382             level = "Msg ";
383             break;
384         case G_LOG_LEVEL_INFO:
385             level = "Info";
386             break;
387         case G_LOG_LEVEL_DEBUG:
388             level = "Dbg ";
389             break;
390         default:
391             qDebug("%s unknown log_level %u", hmsz.toUtf8().constData(), log_level);
392             g_assert_not_reached();
393         }
394
395         qDebug("%s %s %s %s", hmsz.toUtf8().constData(), log_domain, level.toUtf8().constData(), message);
396     }
397
398 // xxx based from ../gtk/main.c:get_gtk_compiled_info
399 static void
400 get_qt_compiled_info(GString *str)
401 {
402     g_string_append(str, "with ");
403     g_string_append_printf(str,
404 #ifdef QT_VERSION
405                     "Qt %s ", QT_VERSION_STR);
406 #else
407                     "Qt (version unknown) ");
408 #endif
409 }
410
411 // xxx copied from ../gtk/main.c
412 static void
413 get_gui_compiled_info(GString *str)
414 {
415     epan_get_compiled_version_info(str);
416
417     g_string_append(str, ", ");
418     g_string_append(str, "without PortAudio");
419
420   g_string_append(str, ", ");
421 #ifdef HAVE_AIRPCAP
422     get_compiled_airpcap_version(str);
423 #else
424     g_string_append(str, "without AirPcap");
425 #endif
426 }
427
428 // xxx copied from ../gtk/main.c
429 static void
430 get_gui_runtime_info(GString *str)
431 {
432     epan_get_runtime_version_info(str);
433
434 #ifdef HAVE_AIRPCAP
435     g_string_append(str, ", ");
436     get_runtime_airpcap_version(str);
437 #endif
438
439
440     if(u3_active()) {
441         g_string_append(str, ", ");
442         u3_runtime_info(str);
443     }
444
445 }
446
447 /* And now our feature presentation... [ fade to music ] */
448 int main(int argc, char *argv[])
449 {
450     WiresharkApplication ws_app(argc, argv);
451     MainWindow *main_w;
452
453     int                  opt;
454     gboolean             arg_error = FALSE;
455
456 #ifdef _WIN32
457     WSADATA            wsaData;
458 #endif  /* _WIN32 */
459
460     char                *rf_path;
461     int                  rf_open_errno;
462     char                *gdp_path, *dp_path;
463 #ifdef HAVE_LIBPCAP
464     int                  err;
465     gboolean             start_capture = FALSE;
466 //    gboolean             list_link_layer_types = FALSE;
467     GList               *if_list;
468     gchar               *err_str;
469 #else
470     gboolean             capture_option_specified = FALSE;
471 #ifdef _WIN32
472 #ifdef HAVE_AIRPCAP
473     gchar               *err_str;
474 #endif
475 #endif
476 #endif
477     e_prefs             *prefs_p;
478     GLogLevelFlags       log_flags;
479
480 #ifdef _WIN32
481     create_app_running_mutex();
482 #endif
483
484     QString locale;
485     QString *cf_name = NULL;
486
487     // In Qt 5, C strings are treated always as UTF-8 when converted to
488     // QStrings; in Qt 4, the codec must be set to make that happen
489 #if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0))
490     // Hopefully we won't have to use QString::fromUtf8() in as many places.
491     QTextCodec *utf8codec = QTextCodec::codecForName("UTF-8");
492     QTextCodec::setCodecForCStrings(utf8codec);
493     // XXX - QObject doesn't *have* a tr method in 5.0, as far as I can see...
494     QTextCodec::setCodecForTr(utf8codec);
495 #endif
496
497     // Init the main window (and splash)
498     main_w = new(MainWindow);
499     main_w->show();
500     // We may not need a queued connection here but it would seem to make sense
501     // to force the issue.
502     main_w->connect(&ws_app, SIGNAL(openCaptureFile(QString&)),
503             main_w, SLOT(openCaptureFile(QString&)));
504
505     // XXX Should the remaining code be in WiresharkApplcation::WiresharkApplication?
506 #ifdef HAVE_LIBPCAP
507 #if defined(_WIN32) || defined(HAVE_PCAP_CREATE)
508 #define OPTSTRING_B "B:"
509 #else
510 #define OPTSTRING_B ""
511 #endif  /* _WIN32 or HAVE_PCAP_CREATE */
512 #else /* HAVE_LIBPCAP */
513 #define OPTSTRING_B ""
514 #endif  /* HAVE_LIBPCAP */
515
516 #ifdef HAVE_PCAP_CREATE
517 #define OPTSTRING_I "I"
518 #else
519 #define OPTSTRING_I ""
520 #endif
521
522 #define OPTSTRING "a:b:" OPTSTRING_B "c:C:Df:g:Hhi:" OPTSTRING_I "jJ:kK:lLm:nN:o:P:pQr:R:Ss:t:u:vw:X:y:z:"
523
524     struct option     long_options[] = {
525         {(char *)"read-file", required_argument, NULL, (int)'r' },
526         {0, 0, 0, 0 }
527     };
528
529     static const char optstring[] = OPTSTRING;
530
531     /* Assemble the compile-time version information string */
532     comp_info_str = g_string_new("Compiled ");
533
534     // xxx qtshark
535     get_compiled_version_info(comp_info_str, get_qt_compiled_info, get_gui_compiled_info);
536
537     /* Assemble the run-time version information string */
538     runtime_info_str = g_string_new("Running ");
539     // xxx qtshark
540     get_runtime_version_info(runtime_info_str, get_gui_runtime_info);
541
542     ws_add_crash_info(PACKAGE " " VERSION "%s\n"
543            "\n"
544            "%s"
545            "\n"
546            "%s",
547         wireshark_gitversion, comp_info_str->str, runtime_info_str->str);
548
549     /*
550      * Get credential information for later use, and drop privileges
551      * before doing anything else.
552      * Let the user know if anything happened.
553      */
554     init_process_policies();
555     relinquish_special_privs_perm();
556
557     /*
558      * Attempt to get the pathname of the executable file.
559      */
560     /* init_progfile_dir_error = */ init_progfile_dir(QCoreApplication::applicationFilePath().toUtf8().constData(), NULL);
561     g_log(NULL, G_LOG_LEVEL_DEBUG, "progfile_dir: %s", get_progfile_dir());
562
563     /* initialize the funnel mini-api */
564     // xxx qtshark
565     //initialize_funnel_ops();
566
567     AirPDcapInitContext(&airpdcap_ctx);
568
569 // xxx qtshark
570 #ifdef _WIN32
571     /* Load wpcap if possible. Do this before collecting the run-time version information */
572     load_wpcap();
573
574     /* ... and also load the packet.dll from wpcap */
575     wpcap_packet_load();
576
577 #ifdef HAVE_AIRPCAP
578     /* Load the airpcap.dll.  This must also be done before collecting
579      * run-time version information. */
580     airpcap_dll_ret_val = load_airpcap();
581
582     switch (airpcap_dll_ret_val) {
583     case AIRPCAP_DLL_OK:
584         /* load the airpcap interfaces */
585         airpcap_if_list = get_airpcap_interface_list(&err, &err_str);
586
587         if (airpcap_if_list == NULL || g_list_length(airpcap_if_list) == 0){
588             if (err == CANT_GET_AIRPCAP_INTERFACE_LIST && err_str != NULL) {
589                 simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", "Failed to open Airpcap Adapters!");
590                 g_free(err_str);
591             }
592             airpcap_if_active = NULL;
593
594         } else {
595
596             /* select the first ad default (THIS SHOULD BE CHANGED) */
597             airpcap_if_active = airpcap_get_default_if(airpcap_if_list);
598         }
599         break;
600 #if 0
601     /*
602      * XXX - Maybe we need to warn the user if one of the following happens???
603      */
604     case AIRPCAP_DLL_OLD:
605         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DLL_OLD\n");
606         break;
607
608     case AIRPCAP_DLL_ERROR:
609         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DLL_ERROR\n");
610         break;
611
612     case AIRPCAP_DLL_NOT_FOUND:
613         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s","AIRPCAP_DDL_NOT_FOUND\n");
614         break;
615 #endif
616     }
617 #endif /* HAVE_AIRPCAP */
618
619     /* Start windows sockets */
620     WSAStartup( MAKEWORD( 1, 1 ), &wsaData );
621 #endif  /* _WIN32 */
622
623     profile_store_persconffiles (TRUE);
624
625     /* Read the profile independent recent file.  We have to do this here so we can */
626     /* set the profile before it can be set from the command line parameterts */
627     recent_read_static(&rf_path, &rf_open_errno);
628     if (rf_path != NULL && rf_open_errno != 0) {
629         simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
630                       "Could not open common recent file\n\"%s\": %s.",
631                       rf_path, strerror(rf_open_errno));
632     }
633     wsApp->emitAppSignal(WiresharkApplication::StaticRecentFilesRead);
634
635     while ((opt = getopt_long(argc, argv, optstring, long_options, NULL)) != -1) {
636         switch (opt) {
637         case 'C':        /* Configuration Profile */
638             if (profile_exists (optarg, FALSE)) {
639                 set_profile_name (optarg);
640             } else {
641                 cmdarg_err("Configuration Profile \"%s\" does not exist", optarg);
642                 exit(1);
643             }
644             break;
645         case 'D':        /* Print a list of capture devices and exit */
646 #ifdef HAVE_LIBPCAP
647             if_list = capture_interface_list(&err, &err_str, main_window_update);
648             if (if_list == NULL) {
649                 switch (err) {
650                 case CANT_GET_INTERFACE_LIST:
651                     cmdarg_err("%s", err_str);
652                     g_free(err_str);
653                     break;
654
655                 case NO_INTERFACES_FOUND:
656                     cmdarg_err("There are no interfaces on which a capture can be done");
657                     break;
658                 }
659                 exit(2);
660             }
661 #ifdef _WIN32
662             create_console();
663 #endif /* _WIN32 */
664             capture_opts_print_interfaces(if_list);
665             free_interface_list(if_list);
666 #ifdef _WIN32
667             destroy_console();
668 #endif /* _WIN32 */
669             exit(0);
670 #else /* HAVE_LIBPCAP */
671             capture_option_specified = TRUE;
672             arg_error = TRUE;
673 #endif /* HAVE_LIBPCAP */
674             break;
675         case 'h':        /* Print help and exit */
676             print_usage(TRUE);
677             exit(0);
678             break;
679 #ifdef _WIN32
680         case 'i':
681             if (strcmp(optarg, "-") == 0)
682                 set_stdin_capture(TRUE);
683             break;
684 #endif
685         case 'P':        /* Personal file directory path settings - change these before the Preferences and alike are processed */
686             if (!persfilepath_opt(opt, optarg)) {
687                 cmdarg_err("-P flag \"%s\" failed (hint: is it quoted and existing?)", optarg);
688                 exit(2);
689             }
690             break;
691         case 'v':        /* Show version and exit */
692 #ifdef _WIN32
693             create_console();
694 #endif
695             show_version();
696 #ifdef _WIN32
697             destroy_console();
698 #endif
699             exit(0);
700             break;
701         case 'r':
702             cf_name = new QString(optarg);
703             break;
704         case 'X':
705             /*
706              *  Extension command line options have to be processed before
707              *  we call epan_init() as they are supposed to be used by dissectors
708              *  or taps very early in the registration process.
709              */
710             ex_opt_add(optarg);
711             break;
712         case '?':
713             print_usage(TRUE);
714             exit(0);
715             break;
716         }
717     }
718
719     if (!arg_error) {
720         argc -= optind;
721         argv += optind;
722         if (argc >= 1) {
723             if (cf_name != NULL) {
724                 /*
725                  * Input file name specified with "-r" *and* specified as a regular
726                  * command-line argument.
727                  */
728                 cmdarg_err("File name specified both with -r and regular argument");
729                 arg_error = TRUE;
730             } else {
731                 /*
732                  * Input file name not specified with "-r", and a command-line argument
733                  * was specified; treat it as the input file name.
734                  *
735                  * Yes, this is different from tshark, where non-flag command-line
736                  * arguments are a filter, but this works better on GUI desktops
737                  * where a command can be specified to be run to open a particular
738                  * file - yes, you could have "-r" as the last part of the command,
739                  * but that's a bit ugly.
740                  */
741                 cf_name = new QString(g_strdup(argv[0]));
742
743             }
744             argc--;
745             argv++;
746         }
747
748         if (argc != 0) {
749             /*
750              * Extra command line arguments were specified; complain.
751              */
752             cmdarg_err("Invalid argument: %s", argv[0]);
753             arg_error = TRUE;
754         }
755     }
756     if (arg_error) {
757 #ifndef HAVE_LIBPCAP
758         if (capture_option_specified) {
759             cmdarg_err("This version of Wireshark was not built with support for capturing packets.");
760         }
761 #endif
762         print_usage(FALSE);
763         exit(1);
764     }
765
766     /* Init the "Open file" dialog directory */
767     /* (do this after the path settings are processed) */
768
769     /* Read the profile dependent (static part) of the recent file. */
770     /* Only the static part of it will be read, as we don't have the gui now to fill the */
771     /* recent lists which is done in the dynamic part. */
772     /* We have to do this already here, so command line parameters can overwrite these values. */
773     recent_read_profile_static(&rf_path, &rf_open_errno);
774     if (rf_path != NULL && rf_open_errno != 0) {
775       simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
776             "Could not open recent file\n\"%s\": %s.",
777             rf_path, g_strerror(rf_open_errno));
778     }
779
780     if (recent.gui_fileopen_remembered_dir &&
781         test_for_directory(recent.gui_fileopen_remembered_dir) == EISDIR) {
782       wsApp->setLastOpenDir(recent.gui_fileopen_remembered_dir);
783     } else {
784       wsApp->setLastOpenDir(get_persdatafile_dir());
785     }
786
787 #ifdef HAVE_LIBPCAP
788     capture_callback_add(main_capture_callback, NULL);
789 #endif
790     cf_callback_add(main_cf_callback, NULL);
791
792     /* Arrange that if we have no console window, and a GLib message logging
793        routine is called to log a message, we pop up a console window.
794
795        We do that by inserting our own handler for all messages logged
796        to the default domain; that handler pops up a console if necessary,
797        and then calls the default handler. */
798
799     /* We might want to have component specific log levels later ... */
800
801     log_flags = (GLogLevelFlags) (
802             G_LOG_LEVEL_ERROR|
803             G_LOG_LEVEL_CRITICAL|
804             G_LOG_LEVEL_WARNING|
805             G_LOG_LEVEL_MESSAGE|
806             G_LOG_LEVEL_INFO|
807             G_LOG_LEVEL_DEBUG|
808             G_LOG_FLAG_FATAL|G_LOG_FLAG_RECURSION );
809
810     g_log_set_handler(NULL,
811                       log_flags,
812                       console_log_handler, NULL /* user_data */);
813     g_log_set_handler(LOG_DOMAIN_MAIN,
814                       log_flags,
815                       console_log_handler, NULL /* user_data */);
816
817 #ifdef HAVE_LIBPCAP
818     g_log_set_handler(LOG_DOMAIN_CAPTURE,
819                       log_flags,
820                       console_log_handler, NULL /* user_data */);
821     g_log_set_handler(LOG_DOMAIN_CAPTURE_CHILD,
822                       log_flags,
823                       console_log_handler, NULL /* user_data */);
824
825     /* Set the initial values in the capture options. This might be overwritten
826        by preference settings and then again by the command line parameters. */
827     capture_opts_init(&global_capture_opts);
828
829     capture_session_init(&global_capture_session, (void *)&cfile);
830 #endif
831
832     init_report_err(failure_alert_box, open_failure_alert_box,
833                     read_failure_alert_box, write_failure_alert_box);
834
835 #ifdef HAVE_PLUGINS
836     /* Register all the plugin types we have. */
837     epan_register_plugin_types(); /* Types known to libwireshark */
838     wtap_register_plugin_types(); /* Types known to libwiretap */
839     codec_register_plugin_types(); /* Types known to libcodec */
840
841     /* Scan for plugins.  This does *not* call their registration routines;
842        that's done later. */
843     scan_plugins();
844
845     /* Register all libwiretap plugin modules. */
846     register_all_wiretap_modules();
847
848     /* Register all audio codec plugins. */
849     register_all_codecs();
850 #endif
851
852     /* Register all dissectors; we must do this before checking for the
853        "-G" flag, as the "-G" flag dumps information registered by the
854        dissectors, and we must do it before we read the preferences, in
855        case any dissectors register preferences. */
856     epan_init(register_all_protocols,register_all_protocol_handoffs,
857               splash_update, NULL);
858
859     splash_update(RA_LISTENERS, NULL, NULL);
860
861     /* Register all tap listeners; we do this before we parse the arguments,
862        as the "-z" argument can specify a registered tap. */
863
864     /* we register the plugin taps before the other taps because
865             stats_tree taps plugins will be registered as tap listeners
866             by stats_tree_stat.c and need to registered before that */
867
868     g_log(NULL, G_LOG_LEVEL_DEBUG, "plugin_dir: %s", get_plugin_dir());
869 #ifdef HAVE_PLUGINS
870     register_all_plugin_tap_listeners();
871 #endif
872
873     register_all_tap_listeners();
874
875     splash_update(RA_PREFERENCES, NULL, NULL);
876     prefs_p = ws_app.readConfigurationFiles (&gdp_path, &dp_path);
877
878     // Initialize our language
879
880     /*TODO: Enhance... may be get the locale from the enum gui_qt_language */
881     switch(prefs_p->gui_qt_language){
882         case 1: /* English */
883         locale = "en";
884         break;
885         case 2: /* French */
886         locale = "fr";
887         break;
888         case 3: /* German */
889         locale = "de";
890         break;
891         case 4: /* Chinese */
892         locale = "zh_CN";
893         break;
894         default: /* Auto-Detect */
895         locale = QLocale::system().name();
896         break;
897     }
898     g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Translator %s", locale.toStdString().c_str());
899     QTranslator translator;
900     translator.load(QString(":/i18n/qtshark_") + locale);
901     wsApp->installTranslator(&translator);
902
903     QTranslator qtTranslator;
904     qtTranslator.load("qt_" + locale, QLibraryInfo::location(QLibraryInfo::TranslationsPath));
905     wsApp->installTranslator(&qtTranslator);
906
907     /* Removed thread code:
908      * https://code.wireshark.org/review/gitweb?p=wireshark.git;a=commit;h=9e277ae6154fd04bf6a0a34ec5655a73e5a736a3
909      */
910
911     g_log(NULL, G_LOG_LEVEL_DEBUG, "FIX: timestamp types should be set elsewhere");
912     timestamp_set_type(TS_RELATIVE);
913     timestamp_set_precision(TS_PREC_AUTO_USEC);
914     timestamp_set_seconds_type(TS_SECONDS_DEFAULT);
915
916 #ifdef HAVE_LIBPCAP
917     fill_in_local_interfaces(main_window_update);
918
919     capture_opts_trim_snaplen(&global_capture_opts, MIN_PACKET_SIZE);
920     capture_opts_trim_ring_num_files(&global_capture_opts);
921 #endif /* HAVE_LIBPCAP */
922
923     /* Notify all registered modules that have had any of their preferences
924        changed either from one of the preferences file or from the command
925        line that their preferences have changed. */
926     prefs_apply_all();
927     wsApp->emitAppSignal(WiresharkApplication::PreferencesChanged);
928
929 #ifdef HAVE_LIBPCAP
930     if ((global_capture_opts.num_selected == 0) &&
931             (prefs.capture_device != NULL)) {
932         guint i;
933         interface_t device;
934         for (i = 0; i < global_capture_opts.all_ifaces->len; i++) {
935             device = g_array_index(global_capture_opts.all_ifaces, interface_t, i);
936             if (!device.hidden && strcmp(device.display_name, prefs.capture_device) == 0) {
937                 device.selected = TRUE;
938                 global_capture_opts.num_selected++;
939                 global_capture_opts.all_ifaces = g_array_remove_index(global_capture_opts.all_ifaces, i);
940                 g_array_insert_val(global_capture_opts.all_ifaces, i, device);
941                 break;
942             }
943         }
944     }
945 #endif
946
947     /* disabled protocols as per configuration file */
948     if (gdp_path == NULL && dp_path == NULL) {
949         set_disabled_protos_list();
950     }
951
952     build_column_format_array(&cfile.cinfo, prefs_p->num_cols, TRUE);
953
954     wsApp->setMonospaceFont(prefs.gui_qt_font_name);
955
956 ////////
957
958     /* Read the dynamic part of the recent file, as we have the gui now ready for
959        it. */
960     recent_read_dynamic(&rf_path, &rf_open_errno);
961     if (rf_path != NULL && rf_open_errno != 0) {
962         simple_dialog(ESD_TYPE_WARN, ESD_BTN_OK,
963                       "Could not open recent file\n\"%s\": %s.",
964                       rf_path, g_strerror(rf_open_errno));
965     }
966
967     color_filters_enable(recent.packet_list_colorize);
968
969     g_log(NULL, G_LOG_LEVEL_DEBUG, "FIX: fetch recent color settings");
970     color_filters_enable(TRUE);
971
972 ////////
973
974
975 ////////
976     color_filters_init();
977
978 ////////
979
980 #ifdef HAVE_LIBPCAP
981     /* if the user didn't supply a capture filter, use the one to filter out remote connections like SSH */
982     if (!start_capture && !global_capture_opts.default_options.cfilter) {
983         global_capture_opts.default_options.cfilter = g_strdup(get_conn_cfilter());
984     }
985 #else /* HAVE_LIBPCAP */
986     ////////
987 #endif /* HAVE_LIBPCAP */
988
989 //    w->setEnabled(true);
990     wsApp->allSystemsGo();
991     g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_INFO, "Wireshark is up and ready to go");
992
993     if (cf_name != NULL) {
994         main_w->openCaptureFile(*cf_name);
995     }
996
997     g_main_loop_new(NULL, FALSE);
998     return wsApp->exec();
999 }
1000
1001 /*
1002  * Editor modelines
1003  *
1004  * Local Variables:
1005  * c-basic-offset: 4
1006  * tab-width: 8
1007  * indent-tabs-mode: nil
1008  * End:
1009  *
1010  * ex: set shiftwidth=4 tabstop=8 expandtab:
1011  * :indentSize=4:tabSize=8:noTabs=true:
1012  */