Update to WinSparkle 0.5.3.
[metze/wireshark/wip.git] / tfshark.c
1 /* tfshark.c
2  *
3  * Text-mode variant of Fileshark, based off of TShark,
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 <stdlib.h>
27 #include <stdio.h>
28 #include <string.h>
29 #include <locale.h>
30 #include <limits.h>
31
32 #ifdef HAVE_GETOPT_H
33 #include <getopt.h>
34 #endif
35
36 #include <errno.h>
37
38 #ifndef HAVE_GETOPT_LONG
39 #include "wsutil/wsgetopt.h"
40 #endif
41
42 #include <glib.h>
43
44 #include <epan/exceptions.h>
45 #include <epan/epan-int.h>
46 #include <epan/epan.h>
47
48 #include <wsutil/clopts_common.h>
49 #include <wsutil/cmdarg_err.h>
50 #include <wsutil/crash_info.h>
51 #include <wsutil/filesystem.h>
52 #include <wsutil/file_util.h>
53 #include <wsutil/privileges.h>
54 #include <wsutil/report_err.h>
55 #include <ws_version_info.h>
56
57 #include "globals.h"
58 #include <epan/timestamp.h>
59 #include <epan/packet.h>
60 #ifdef HAVE_LUA
61 #include <epan/wslua/init_wslua.h>
62 #endif
63 #include "file.h"
64 #include "frame_tvbuff.h"
65 #include <epan/disabled_protos.h>
66 #include <epan/prefs.h>
67 #include <epan/column.h>
68 #include <epan/print.h>
69 #include <epan/addr_resolv.h>
70 #include "ui/util.h"
71 #include "ui/decode_as_utils.h"
72 #include "ui/dissect_opts.h"
73 #include "register.h"
74 #include <epan/epan_dissect.h>
75 #include <epan/tap.h>
76 #include <epan/stat_tap_ui.h>
77 #include <epan/ex-opt.h>
78
79 #ifdef HAVE_EXTCAP
80 #include "extcap.h"
81 #endif
82
83 #include <wiretap/wtap-int.h>
84 #include <wiretap/file_wrappers.h>
85
86 #ifdef _WIN32
87 #include <wsutil/unicode-utils.h>
88 #endif /* _WIN32 */
89
90 #include "log.h"
91 #include <epan/funnel.h>
92
93 #ifdef HAVE_PLUGINS
94 #include <wsutil/plugins.h>
95 #endif
96
97 static guint32 cum_bytes;
98 static const frame_data *ref;
99 static frame_data ref_frame;
100 static frame_data *prev_dis;
101 static frame_data prev_dis_frame;
102 static frame_data *prev_cap;
103 static frame_data prev_cap_frame;
104
105 static gboolean perform_two_pass_analysis;
106
107 /*
108  * The way the packet decode is to be written.
109  */
110 typedef enum {
111   WRITE_TEXT,   /* summary or detail text */
112   WRITE_XML,    /* PDML or PSML */
113   WRITE_FIELDS  /* User defined list of fields */
114   /* Add CSV and the like here */
115 } output_action_e;
116
117 static output_action_e output_action;
118 static gboolean do_dissection;     /* TRUE if we have to dissect each packet */
119 static gboolean print_packet_info; /* TRUE if we're to print packet information */
120 static gint print_summary = -1;    /* TRUE if we're to print packet summary information */
121 static gboolean print_details;     /* TRUE if we're to print packet details information */
122 static gboolean print_hex;         /* TRUE if we're to print hex/ascci information */
123 static gboolean line_buffered;
124 static gboolean really_quiet = FALSE;
125
126 static print_format_e print_format = PR_FMT_TEXT;
127 static print_stream_t *print_stream;
128
129 static output_fields_t* output_fields  = NULL;
130
131 /* The line separator used between packets, changeable via the -S option */
132 static const char *separator = "";
133
134 static int load_cap_file(capture_file *, int, gint64);
135 static gboolean process_packet(capture_file *cf, epan_dissect_t *edt, gint64 offset,
136     struct wtap_pkthdr *whdr, const guchar *pd, guint tap_flags);
137 static void show_print_file_io_error(int err);
138 static gboolean write_preamble(capture_file *cf);
139 static gboolean print_packet(capture_file *cf, epan_dissect_t *edt);
140 static gboolean write_finale(void);
141 static const char *cf_open_error_message(int err, gchar *err_info,
142     gboolean for_writing, int file_type);
143
144 static void open_failure_message(const char *filename, int err,
145     gboolean for_writing);
146 static void failure_message(const char *msg_format, va_list ap);
147 static void read_failure_message(const char *filename, int err);
148 static void write_failure_message(const char *filename, int err);
149 static void failure_message_cont(const char *msg_format, va_list ap);
150
151 capture_file cfile;
152
153 static GHashTable *output_only_tables = NULL;
154
155 #if 0
156 struct string_elem {
157   const char *sstr;   /* The short string */
158   const char *lstr;   /* The long string */
159 };
160
161 static gint
162 string_compare(gconstpointer a, gconstpointer b)
163 {
164   return strcmp(((const struct string_elem *)a)->sstr,
165                 ((const struct string_elem *)b)->sstr);
166 }
167
168 static void
169 string_elem_print(gpointer data, gpointer not_used _U_)
170 {
171   fprintf(stderr, "    %s - %s\n",
172           ((struct string_elem *)data)->sstr,
173           ((struct string_elem *)data)->lstr);
174 }
175 #endif
176
177 static void
178 print_usage(FILE *output)
179 {
180   fprintf(output, "\n");
181   fprintf(output, "Usage: tfshark [options] ...\n");
182   fprintf(output, "\n");
183
184   /*fprintf(output, "\n");*/
185   fprintf(output, "Input file:\n");
186   fprintf(output, "  -r <infile>              set the filename to read from (no pipes or stdin!)\n");
187
188   fprintf(output, "\n");
189   fprintf(output, "Processing:\n");
190   fprintf(output, "  -2                       perform a two-pass analysis\n");
191   fprintf(output, "  -R <read filter>         packet Read filter in Wireshark display filter syntax\n");
192   fprintf(output, "  -Y <display filter>      packet displaY filter in Wireshark display filter\n");
193   fprintf(output, "                           syntax\n");
194   fprintf(output, "  -d %s ...\n", DECODE_AS_ARG_TEMPLATE);
195   fprintf(output, "                           \"Decode As\", see the man page for details\n");
196   fprintf(output, "                           Example: tcp.port==8888,http\n");
197
198   /*fprintf(output, "\n");*/
199   fprintf(output, "Output:\n");
200   fprintf(output, "  -C <config profile>      start with specified configuration profile\n");
201   fprintf(output, "  -V                       add output of packet tree        (Packet Details)\n");
202   fprintf(output, "  -O <protocols>           Only show packet details of these protocols, comma\n");
203   fprintf(output, "                           separated\n");
204   fprintf(output, "  -S <separator>           the line separator to print between packets\n");
205   fprintf(output, "  -x                       add output of hex and ASCII dump (Packet Bytes)\n");
206   fprintf(output, "  -T pdml|ps|psml|text|fields\n");
207   fprintf(output, "                           format of text output (def: text)\n");
208   fprintf(output, "  -e <field>               field to print if -Tfields selected (e.g. tcp.port,\n");
209   fprintf(output, "                           _ws.col.Info)\n");
210   fprintf(output, "                           this option can be repeated to print multiple fields\n");
211   fprintf(output, "  -E<fieldsoption>=<value> set options for output when -Tfields selected:\n");
212   fprintf(output, "     header=y|n            switch headers on and off\n");
213   fprintf(output, "     separator=/t|/s|<char> select tab, space, printable character as separator\n");
214   fprintf(output, "     occurrence=f|l|a      print first, last or all occurrences of each field\n");
215   fprintf(output, "     aggregator=,|/s|<char> select comma, space, printable character as\n");
216   fprintf(output, "                           aggregator\n");
217   fprintf(output, "     quote=d|s|n           select double, single, no quotes for values\n");
218   fprintf(output, "  -t a|ad|d|dd|e|r|u|ud    output format of time stamps (def: r: rel. to first)\n");
219   fprintf(output, "  -u s|hms                 output format of seconds (def: s: seconds)\n");
220   fprintf(output, "  -l                       flush standard output after each packet\n");
221   fprintf(output, "  -q                       be more quiet on stdout (e.g. when using statistics)\n");
222   fprintf(output, "  -Q                       only log true errors to stderr (quieter than -q)\n");
223   fprintf(output, "  -X <key>:<value>         eXtension options, see the man page for details\n");
224   fprintf(output, "  -z <statistics>          various statistics, see the man page for details\n");
225
226   fprintf(output, "\n");
227   fprintf(output, "Miscellaneous:\n");
228   fprintf(output, "  -h                       display this help and exit\n");
229   fprintf(output, "  -v                       display version info and exit\n");
230   fprintf(output, "  -o <name>:<value> ...    override preference setting\n");
231   fprintf(output, "  -K <keytab>              keytab file to use for kerberos decryption\n");
232   fprintf(output, "  -G [report]              dump one of several available reports and exit\n");
233   fprintf(output, "                           default report=\"fields\"\n");
234   fprintf(output, "                           use \"-G ?\" for more help\n");
235 }
236
237 static void
238 glossary_option_help(void)
239 {
240   FILE *output;
241
242   output = stdout;
243
244   fprintf(output, "TFShark (Wireshark) %s\n", get_ws_vcs_version_info());
245
246   fprintf(output, "\n");
247   fprintf(output, "Usage: tfshark -G [report]\n");
248   fprintf(output, "\n");
249   fprintf(output, "Glossary table reports:\n");
250   fprintf(output, "  -G column-formats        dump column format codes and exit\n");
251   fprintf(output, "  -G decodes               dump \"layer type\"/\"decode as\" associations and exit\n");
252   fprintf(output, "  -G dissector-tables      dump dissector table names, types, and properties\n");
253   fprintf(output, "  -G fields                dump fields glossary and exit\n");
254   fprintf(output, "  -G ftypes                dump field type basic and descriptive names\n");
255   fprintf(output, "  -G heuristic-decodes     dump heuristic dissector tables\n");
256   fprintf(output, "  -G plugins               dump installed plugins and exit\n");
257   fprintf(output, "  -G protocols             dump protocols in registration database and exit\n");
258   fprintf(output, "  -G values                dump value, range, true/false strings and exit\n");
259   fprintf(output, "\n");
260   fprintf(output, "Preference reports:\n");
261   fprintf(output, "  -G currentprefs          dump current preferences and exit\n");
262   fprintf(output, "  -G defaultprefs          dump default preferences and exit\n");
263   fprintf(output, "\n");
264 }
265
266 static void
267 tfshark_log_handler (const gchar *log_domain, GLogLevelFlags log_level,
268     const gchar *message, gpointer user_data)
269 {
270   /* ignore log message, if log_level isn't interesting based
271      upon the console log preferences.
272      If the preferences haven't been loaded loaded yet, display the
273      message anyway.
274
275      The default console_log_level preference value is such that only
276        ERROR, CRITICAL and WARNING level messages are processed;
277        MESSAGE, INFO and DEBUG level messages are ignored.
278
279      XXX: Aug 07, 2009: Prior tshark g_log code was hardwired to process only
280            ERROR and CRITICAL level messages so the current code is a behavioral
281            change.  The current behavior is the same as in Wireshark.
282   */
283   if ((log_level & G_LOG_LEVEL_MASK & prefs.console_log_level) == 0 &&
284      prefs.console_log_level != 0) {
285     return;
286   }
287
288   g_log_default_handler(log_domain, log_level, message, user_data);
289
290 }
291
292 static void
293 print_current_user(void) {
294   gchar *cur_user, *cur_group;
295
296   if (started_with_special_privs()) {
297     cur_user = get_cur_username();
298     cur_group = get_cur_groupname();
299     fprintf(stderr, "Running as user \"%s\" and group \"%s\".",
300       cur_user, cur_group);
301     g_free(cur_user);
302     g_free(cur_group);
303     if (running_with_special_privs()) {
304       fprintf(stderr, " This could be dangerous.");
305     }
306     fprintf(stderr, "\n");
307   }
308 }
309
310 static void
311 get_tfshark_runtime_version_info(GString *str)
312 {
313   /* stuff used by libwireshark */
314   epan_get_runtime_version_info(str);
315 }
316
317 int
318 main(int argc, char *argv[])
319 {
320   GString             *comp_info_str;
321   GString             *runtime_info_str;
322   char                *init_progfile_dir_error;
323   int                  opt;
324   static const struct option long_options[] = {
325     {"help", no_argument, NULL, 'h'},
326     {"version", no_argument, NULL, 'v'},
327     {0, 0, 0, 0 }
328   };
329   gboolean             arg_error = FALSE;
330
331   char                *gpf_path, *pf_path;
332   char                *gdp_path, *dp_path;
333   int                  gpf_open_errno, gpf_read_errno;
334   int                  pf_open_errno, pf_read_errno;
335   int                  gdp_open_errno, gdp_read_errno;
336   int                  dp_open_errno, dp_read_errno;
337   int                  err;
338   volatile int         exit_status = 0;
339   gboolean             quiet = FALSE;
340   gchar               *volatile cf_name = NULL;
341   gchar               *rfilter = NULL;
342   gchar               *dfilter = NULL;
343   dfilter_t           *rfcode = NULL;
344   dfilter_t           *dfcode = NULL;
345   gchar               *err_msg;
346   e_prefs             *prefs_p;
347   int                  log_flags;
348   gchar               *output_only = NULL;
349
350 /*
351  * The leading + ensures that getopt_long() does not permute the argv[]
352  * entries.
353  *
354  * We have to make sure that the first getopt_long() preserves the content
355  * of argv[] for the subsequent getopt_long() call.
356  *
357  * We use getopt_long() in both cases to ensure that we're using a routine
358  * whose permutation behavior we can control in the same fashion on all
359  * platforms, and so that, if we ever need to process a long argument before
360  * doing further initialization, we can do so.
361  *
362  * Glibc and Solaris libc document that a leading + disables permutation
363  * of options, regardless of whether POSIXLY_CORRECT is set or not; *BSD
364  * and OS X don't document it, but do so anyway.
365  *
366  * We do *not* use a leading - because the behavior of a leading - is
367  * platform-dependent.
368  */
369 #define OPTSTRING "+2C:d:e:E:hK:lo:O:qQr:R:S:t:T:u:vVxX:Y:z:"
370
371   static const char    optstring[] = OPTSTRING;
372
373   /* Set the C-language locale to the native environment. */
374   setlocale(LC_ALL, "");
375
376   cmdarg_err_init(failure_message, failure_message_cont);
377
378 #ifdef _WIN32
379   arg_list_utf_16to8(argc, argv);
380   create_app_running_mutex();
381 #if !GLIB_CHECK_VERSION(2,31,0)
382   g_thread_init(NULL);
383 #endif
384 #endif /* _WIN32 */
385
386   /*
387    * Get credential information for later use, and drop privileges
388    * before doing anything else.
389    * Let the user know if anything happened.
390    */
391   init_process_policies();
392   relinquish_special_privs_perm();
393   print_current_user();
394
395   /*
396    * Attempt to get the pathname of the directory containing the
397    * executable file.
398    */
399   init_progfile_dir_error = init_progfile_dir(argv[0], main);
400   if (init_progfile_dir_error != NULL) {
401     fprintf(stderr,
402             "tfshark: Can't get pathname of directory containing the tfshark program: %s.\n",
403             init_progfile_dir_error);
404     g_free(init_progfile_dir_error);
405   }
406
407   initialize_funnel_ops();
408
409   /* Get the compile-time version information string */
410   comp_info_str = get_compiled_version_info(NULL, epan_get_compiled_version_info);
411
412   /* Get the run-time version information string */
413   runtime_info_str = get_runtime_version_info(get_tfshark_runtime_version_info);
414
415   /* Add it to the information to be reported on a crash. */
416   ws_add_crash_info("TFShark (Wireshark) %s\n"
417          "\n"
418          "%s"
419          "\n"
420          "%s",
421       get_ws_vcs_version_info(), comp_info_str->str, runtime_info_str->str);
422   g_string_free(comp_info_str, TRUE);
423   g_string_free(runtime_info_str, TRUE);
424
425   /*
426    * In order to have the -X opts assigned before the wslua machine starts
427    * we need to call getopts before epan_init() gets called.
428    *
429    * In order to handle, for example, -o options, we also need to call it
430    * *after* epan_init() gets called, so that the dissectors have had a
431    * chance to register their preferences.
432    *
433    * XXX - can we do this all with one getopt_long() call, saving the
434    * arguments we can't handle until after initializing libwireshark,
435    * and then process them after initializing libwireshark?
436    */
437   opterr = 0;
438
439   while ((opt = getopt_long(argc, argv, optstring, long_options, NULL)) != -1) {
440     switch (opt) {
441     case 'C':        /* Configuration Profile */
442       if (profile_exists (optarg, FALSE)) {
443         set_profile_name (optarg);
444       } else {
445         cmdarg_err("Configuration Profile \"%s\" does not exist", optarg);
446         return 1;
447       }
448       break;
449     case 'O':        /* Only output these protocols */
450       output_only = g_strdup(optarg);
451       /* FALLTHROUGH */
452     case 'V':        /* Verbose */
453       print_details = TRUE;
454       print_packet_info = TRUE;
455       break;
456     case 'x':        /* Print packet data in hex (and ASCII) */
457       print_hex = TRUE;
458       /*  The user asked for hex output, so let's ensure they get it,
459        *  even if they're writing to a file.
460        */
461       print_packet_info = TRUE;
462       break;
463     case 'X':
464       ex_opt_add(optarg);
465       break;
466     default:
467       break;
468     }
469   }
470
471   /*
472    * Print packet summary information is the default, unless either -V or -x
473    * were specified.  Note that this is new behavior, which
474    * allows for the possibility of printing only hex/ascii output without
475    * necessarily requiring that either the summary or details be printed too.
476    */
477   if (print_summary == -1)
478     print_summary = (print_details || print_hex) ? FALSE : TRUE;
479
480 /** Send All g_log messages to our own handler **/
481
482   log_flags =
483                     G_LOG_LEVEL_ERROR|
484                     G_LOG_LEVEL_CRITICAL|
485                     G_LOG_LEVEL_WARNING|
486                     G_LOG_LEVEL_MESSAGE|
487                     G_LOG_LEVEL_INFO|
488                     G_LOG_LEVEL_DEBUG|
489                     G_LOG_FLAG_FATAL|G_LOG_FLAG_RECURSION;
490
491   g_log_set_handler(NULL,
492                     (GLogLevelFlags)log_flags,
493                     tfshark_log_handler, NULL /* user_data */);
494   g_log_set_handler(LOG_DOMAIN_MAIN,
495                     (GLogLevelFlags)log_flags,
496                     tfshark_log_handler, NULL /* user_data */);
497
498   init_report_err(failure_message, open_failure_message, read_failure_message,
499                   write_failure_message);
500
501   timestamp_set_type(TS_RELATIVE);
502   timestamp_set_precision(TS_PREC_AUTO);
503   timestamp_set_seconds_type(TS_SECONDS_DEFAULT);
504
505   wtap_init();
506
507 #ifdef HAVE_PLUGINS
508   /* Register all the plugin types we have. */
509   epan_register_plugin_types(); /* Types known to libwireshark */
510
511   /* Scan for plugins.  This does *not* call their registration routines;
512      that's done later. */
513   scan_plugins(REPORT_LOAD_FAILURE);
514
515 #endif
516
517   /* Register all dissectors; we must do this before checking for the
518      "-G" flag, as the "-G" flag dumps information registered by the
519      dissectors, and we must do it before we read the preferences, in
520      case any dissectors register preferences. */
521   if (!epan_init(register_all_protocols, register_all_protocol_handoffs, NULL,
522                  NULL))
523     return 2;
524
525   /* Register all tap listeners; we do this before we parse the arguments,
526      as the "-z" argument can specify a registered tap. */
527
528   /* we register the plugin taps before the other taps because
529      stats_tree taps plugins will be registered as tap listeners
530      by stats_tree_stat.c and need to registered before that */
531
532   /* XXX Disable tap registration for now until we can get tfshark set up with
533    * its own set of taps and the necessary registration function etc.
534 #ifdef HAVE_PLUGINS
535   register_all_plugin_tap_listeners();
536 #endif
537   register_all_tap_listeners();
538   */
539
540   /* If invoked with the "-G" flag, we dump out information based on
541      the argument to the "-G" flag; if no argument is specified,
542      for backwards compatibility we dump out a glossary of display
543      filter symbols.
544
545      XXX - we do this here, for now, to support "-G" with no arguments.
546      If none of our build or other processes uses "-G" with no arguments,
547      we can just process it with the other arguments. */
548   if (argc >= 2 && strcmp(argv[1], "-G") == 0) {
549     proto_initialize_all_prefixes();
550
551     if (argc == 2)
552       proto_registrar_dump_fields();
553     else {
554       if (strcmp(argv[2], "column-formats") == 0)
555         column_dump_column_formats();
556       else if (strcmp(argv[2], "currentprefs") == 0) {
557         read_prefs(&gpf_open_errno, &gpf_read_errno, &gpf_path,
558             &pf_open_errno, &pf_read_errno, &pf_path);
559         write_prefs(NULL);
560       }
561       else if (strcmp(argv[2], "decodes") == 0)
562         dissector_dump_decodes();
563       else if (strcmp(argv[2], "defaultprefs") == 0)
564         write_prefs(NULL);
565       else if (strcmp(argv[2], "dissector-tables") == 0)
566         dissector_dump_dissector_tables();
567       else if (strcmp(argv[2], "fields") == 0)
568         proto_registrar_dump_fields();
569       else if (strcmp(argv[2], "ftypes") == 0)
570         proto_registrar_dump_ftypes();
571       else if (strcmp(argv[2], "heuristic-decodes") == 0)
572         dissector_dump_heur_decodes();
573       else if (strcmp(argv[2], "plugins") == 0) {
574 #ifdef HAVE_PLUGINS
575         plugins_dump_all();
576 #endif
577 #ifdef HAVE_LUA
578         wslua_plugins_dump_all();
579 #endif
580       }
581       else if (strcmp(argv[2], "protocols") == 0)
582         proto_registrar_dump_protocols();
583       else if (strcmp(argv[2], "values") == 0)
584         proto_registrar_dump_values();
585       else if (strcmp(argv[2], "?") == 0)
586         glossary_option_help();
587       else if (strcmp(argv[2], "-?") == 0)
588         glossary_option_help();
589       else {
590         cmdarg_err("Invalid \"%s\" option for -G flag, enter -G ? for more help.", argv[2]);
591         return 1;
592       }
593     }
594     return 0;
595   }
596
597   prefs_p = read_prefs(&gpf_open_errno, &gpf_read_errno, &gpf_path,
598                      &pf_open_errno, &pf_read_errno, &pf_path);
599   if (gpf_path != NULL) {
600     if (gpf_open_errno != 0) {
601       cmdarg_err("Can't open global preferences file \"%s\": %s.",
602               pf_path, g_strerror(gpf_open_errno));
603     }
604     if (gpf_read_errno != 0) {
605       cmdarg_err("I/O error reading global preferences file \"%s\": %s.",
606               pf_path, g_strerror(gpf_read_errno));
607     }
608   }
609   if (pf_path != NULL) {
610     if (pf_open_errno != 0) {
611       cmdarg_err("Can't open your preferences file \"%s\": %s.", pf_path,
612               g_strerror(pf_open_errno));
613     }
614     if (pf_read_errno != 0) {
615       cmdarg_err("I/O error reading your preferences file \"%s\": %s.",
616               pf_path, g_strerror(pf_read_errno));
617     }
618     g_free(pf_path);
619     pf_path = NULL;
620   }
621
622   /* Read the disabled protocols file. */
623   read_disabled_protos_list(&gdp_path, &gdp_open_errno, &gdp_read_errno,
624                             &dp_path, &dp_open_errno, &dp_read_errno);
625   read_disabled_heur_dissector_list(&gdp_path, &gdp_open_errno, &gdp_read_errno,
626                             &dp_path, &dp_open_errno, &dp_read_errno);
627   if (gdp_path != NULL) {
628     if (gdp_open_errno != 0) {
629       cmdarg_err("Could not open global disabled protocols file\n\"%s\": %s.",
630                  gdp_path, g_strerror(gdp_open_errno));
631     }
632     if (gdp_read_errno != 0) {
633       cmdarg_err("I/O error reading global disabled protocols file\n\"%s\": %s.",
634                  gdp_path, g_strerror(gdp_read_errno));
635     }
636     g_free(gdp_path);
637   }
638   if (dp_path != NULL) {
639     if (dp_open_errno != 0) {
640       cmdarg_err(
641         "Could not open your disabled protocols file\n\"%s\": %s.", dp_path,
642         g_strerror(dp_open_errno));
643     }
644     if (dp_read_errno != 0) {
645       cmdarg_err(
646         "I/O error reading your disabled protocols file\n\"%s\": %s.", dp_path,
647         g_strerror(dp_read_errno));
648     }
649     g_free(dp_path);
650   }
651
652   cap_file_init(&cfile);
653
654   /* Print format defaults to this. */
655   print_format = PR_FMT_TEXT;
656
657   output_fields = output_fields_new();
658
659   /*
660    * To reset the options parser, set optreset to 1 on platforms that
661    * have optreset (documented in *BSD and OS X, apparently present but
662    * not documented in Solaris - the Illumos repository seems to
663    * suggest that the first Solaris getopt_long(), at least as of 2004,
664    * was based on the NetBSD one, it had optreset) and set optind to 1,
665    * and set optind to 0 otherwise (documented as working in the GNU
666    * getopt_long().  Setting optind to 0 didn't originally work in the
667    * NetBSD one, but that was added later - we don't want to depend on
668    * it if we have optreset).
669    *
670    * Also reset opterr to 1, so that error messages are printed by
671    * getopt_long().
672    */
673 #ifdef HAVE_OPTRESET
674   optreset = 1;
675   optind = 1;
676 #else
677   optind = 0;
678 #endif
679   opterr = 1;
680
681   /* Now get our args */
682   while ((opt = getopt_long(argc, argv, optstring, long_options, NULL)) != -1) {
683     switch (opt) {
684     case '2':        /* Perform two pass analysis */
685       perform_two_pass_analysis = TRUE;
686       break;
687     case 'C':
688       /* already processed; just ignore it now */
689       break;
690     case 'e':
691       /* Field entry */
692       output_fields_add(output_fields, optarg);
693       break;
694     case 'E':
695       /* Field option */
696       if (!output_fields_set_option(output_fields, optarg)) {
697         cmdarg_err("\"%s\" is not a valid field output option=value pair.", optarg);
698         output_fields_list_options(stderr);
699         return 1;
700       }
701       break;
702
703     case 'h':        /* Print help and exit */
704       printf("TFShark (Wireshark) %s\n"
705              "Dump and analyze network traffic.\n"
706              "See https://www.wireshark.org for more information.\n",
707              get_ws_vcs_version_info());
708       print_usage(stdout);
709       return 0;
710       break;
711     case 'l':        /* "Line-buffer" standard output */
712       /* This isn't line-buffering, strictly speaking, it's just
713          flushing the standard output after the information for
714          each packet is printed; however, that should be good
715          enough for all the purposes to which "-l" is put (and
716          is probably actually better for "-V", as it does fewer
717          writes).
718
719          See the comment in "process_packet()" for an explanation of
720          why we do that, and why we don't just use "setvbuf()" to
721          make the standard output line-buffered (short version: in
722          Windows, "line-buffered" is the same as "fully-buffered",
723          and the output buffer is only flushed when it fills up). */
724       line_buffered = TRUE;
725       break;
726     case 'o':        /* Override preference from command line */
727       switch (prefs_set_pref(optarg)) {
728
729       case PREFS_SET_OK:
730         break;
731
732       case PREFS_SET_SYNTAX_ERR:
733         cmdarg_err("Invalid -o flag \"%s\"", optarg);
734         return 1;
735         break;
736
737       case PREFS_SET_NO_SUCH_PREF:
738       case PREFS_SET_OBSOLETE:
739         cmdarg_err("-o flag \"%s\" specifies unknown preference", optarg);
740         return 1;
741         break;
742       }
743       break;
744     case 'q':        /* Quiet */
745       quiet = TRUE;
746       break;
747     case 'Q':        /* Really quiet */
748       quiet = TRUE;
749       really_quiet = TRUE;
750       break;
751     case 'r':        /* Read capture file x */
752       cf_name = g_strdup(optarg);
753       break;
754     case 'R':        /* Read file filter */
755       rfilter = optarg;
756       break;
757     case 'S':        /* Set the line Separator to be printed between packets */
758       separator = g_strdup(optarg);
759       break;
760     case 'T':        /* printing Type */
761       if (strcmp(optarg, "text") == 0) {
762         output_action = WRITE_TEXT;
763         print_format = PR_FMT_TEXT;
764       } else if (strcmp(optarg, "ps") == 0) {
765         output_action = WRITE_TEXT;
766         print_format = PR_FMT_PS;
767       } else if (strcmp(optarg, "pdml") == 0) {
768         output_action = WRITE_XML;
769         print_details = TRUE;   /* Need details */
770         print_summary = FALSE;  /* Don't allow summary */
771       } else if (strcmp(optarg, "psml") == 0) {
772         output_action = WRITE_XML;
773         print_details = FALSE;  /* Don't allow details */
774         print_summary = TRUE;   /* Need summary */
775       } else if (strcmp(optarg, "fields") == 0) {
776         output_action = WRITE_FIELDS;
777         print_details = TRUE;   /* Need full tree info */
778         print_summary = FALSE;  /* Don't allow summary */
779       } else {
780         cmdarg_err("Invalid -T parameter \"%s\"; it must be one of:", optarg);                   /* x */
781         cmdarg_err_cont("\t\"fields\" The values of fields specified with the -e option, in a form\n"
782                         "\t         specified by the -E option.\n"
783                         "\t\"pdml\"   Packet Details Markup Language, an XML-based format for the\n"
784                         "\t         details of a decoded packet. This information is equivalent to\n"
785                         "\t         the packet details printed with the -V flag.\n"
786                         "\t\"ps\"     PostScript for a human-readable one-line summary of each of\n"
787                         "\t         the packets, or a multi-line view of the details of each of\n"
788                         "\t         the packets, depending on whether the -V flag was specified.\n"
789                         "\t\"psml\"   Packet Summary Markup Language, an XML-based format for the\n"
790                         "\t         summary information of a decoded packet. This information is\n"
791                         "\t         equivalent to the information shown in the one-line summary\n"
792                         "\t         printed by default.\n"
793                         "\t\"text\"   Text of a human-readable one-line summary of each of the\n"
794                         "\t         packets, or a multi-line view of the details of each of the\n"
795                         "\t         packets, depending on whether the -V flag was specified.\n"
796                         "\t         This is the default.");
797         return 1;
798       }
799       break;
800     case 'v':         /* Show version and exit */
801       comp_info_str = get_compiled_version_info(NULL, epan_get_compiled_version_info);
802       runtime_info_str = get_runtime_version_info(get_tfshark_runtime_version_info);
803       show_version("TFShark (Wireshark)", comp_info_str, runtime_info_str);
804       g_string_free(comp_info_str, TRUE);
805       g_string_free(runtime_info_str, TRUE);
806       /* We don't really have to cleanup here, but it's a convenient way to test
807        * start-up and shut-down of the epan library without any UI-specific
808        * cruft getting in the way. Makes the results of running
809        * $ ./tools/valgrind-wireshark -n
810        * much more useful. */
811       epan_cleanup();
812 #ifdef HAVE_EXTCAP
813       extcap_cleanup();
814 #endif
815       return 0;
816     case 'O':        /* Only output these protocols */
817       /* already processed; just ignore it now */
818       break;
819     case 'V':        /* Verbose */
820       /* already processed; just ignore it now */
821       break;
822     case 'x':        /* Print packet data in hex (and ASCII) */
823       /* already processed; just ignore it now */
824       break;
825     case 'X':
826       /* already processed; just ignore it now */
827       break;
828     case 'Y':
829       dfilter = optarg;
830       break;
831     case 'z':
832       /* We won't call the init function for the stat this soon
833          as it would disallow MATE's fields (which are registered
834          by the preferences set callback) from being used as
835          part of a tap filter.  Instead, we just add the argument
836          to a list of stat arguments. */
837       if (strcmp("help", optarg) == 0) {
838         fprintf(stderr, "tfshark: The available statistics for the \"-z\" option are:\n");
839         list_stat_cmd_args();
840         return 0;
841       }
842       if (!process_stat_cmd_arg(optarg)) {
843         cmdarg_err("Invalid -z argument \"%s\"; it must be one of:", optarg);
844         list_stat_cmd_args();
845         return 1;
846       }
847       break;
848     case 'd':        /* Decode as rule */
849     case 'K':        /* Kerberos keytab file */
850     case 't':        /* Time stamp type */
851     case 'u':        /* Seconds type */
852       if (!dissect_opts_handle_opt(opt, optarg))
853           return 1;
854       break;
855     default:
856     case '?':        /* Bad flag - print usage message */
857       print_usage(stderr);
858       return 1;
859       break;
860     }
861   }
862
863   /* If we specified output fields, but not the output field type... */
864   if (WRITE_FIELDS != output_action && 0 != output_fields_num_fields(output_fields)) {
865         cmdarg_err("Output fields were specified with \"-e\", "
866             "but \"-Tfields\" was not specified.");
867         return 1;
868   } else if (WRITE_FIELDS == output_action && 0 == output_fields_num_fields(output_fields)) {
869         cmdarg_err("\"-Tfields\" was specified, but no fields were "
870                     "specified with \"-e\".");
871
872         return 1;
873   }
874
875   /* If no capture filter or display filter has been specified, and there are
876      still command-line arguments, treat them as the tokens of a capture
877      filter (if no "-r" flag was specified) or a display filter (if a "-r"
878      flag was specified. */
879   if (optind < argc) {
880     if (cf_name != NULL) {
881       if (dfilter != NULL) {
882         cmdarg_err("Display filters were specified both with \"-d\" "
883             "and with additional command-line arguments.");
884         return 1;
885       }
886       dfilter = get_args_as_string(argc, argv, optind);
887     }
888   }
889
890   /* if "-q" wasn't specified, we should print packet information */
891   if (!quiet)
892     print_packet_info = TRUE;
893
894   if (arg_error) {
895     print_usage(stderr);
896     return 1;
897   }
898
899   if (print_hex) {
900     if (output_action != WRITE_TEXT) {
901       cmdarg_err("Raw packet hex data can only be printed as text or PostScript");
902       return 1;
903     }
904   }
905
906   if (output_only != NULL) {
907     char *ps;
908
909     if (!print_details) {
910       cmdarg_err("-O requires -V");
911       return 1;
912     }
913
914     output_only_tables = g_hash_table_new (g_str_hash, g_str_equal);
915     for (ps = strtok (output_only, ","); ps; ps = strtok (NULL, ",")) {
916       g_hash_table_insert(output_only_tables, (gpointer)ps, (gpointer)ps);
917     }
918   }
919
920   if (rfilter != NULL && !perform_two_pass_analysis) {
921     cmdarg_err("-R without -2 is deprecated. For single-pass filtering use -Y.");
922     return 1;
923   }
924
925   /* Notify all registered modules that have had any of their preferences
926      changed either from one of the preferences file or from the command
927      line that their preferences have changed. */
928   prefs_apply_all();
929
930   /* At this point MATE will have registered its field array so we can
931      have a tap filter with one of MATE's late-registered fields as part
932      of the filter.  We can now process all the "-z" arguments. */
933   start_requested_stats();
934
935   /* disabled protocols as per configuration file */
936   if (gdp_path == NULL && dp_path == NULL) {
937     set_disabled_protos_list();
938     set_disabled_heur_dissector_list();
939   }
940
941   /* Build the column format array */
942   build_column_format_array(&cfile.cinfo, prefs_p->num_cols, TRUE);
943
944   if (rfilter != NULL) {
945     if (!dfilter_compile(rfilter, &rfcode, &err_msg)) {
946       cmdarg_err("%s", err_msg);
947       g_free(err_msg);
948       epan_cleanup();
949 #ifdef HAVE_EXTCAP
950       extcap_cleanup();
951 #endif
952       return 2;
953     }
954   }
955   cfile.rfcode = rfcode;
956
957   if (dfilter != NULL) {
958     if (!dfilter_compile(dfilter, &dfcode, &err_msg)) {
959       cmdarg_err("%s", err_msg);
960       g_free(err_msg);
961       epan_cleanup();
962 #ifdef HAVE_EXTCAP
963       extcap_cleanup();
964 #endif
965       return 2;
966     }
967   }
968   cfile.dfcode = dfcode;
969
970   if (print_packet_info) {
971     /* If we're printing as text or PostScript, we have
972        to create a print stream. */
973     if (output_action == WRITE_TEXT) {
974       switch (print_format) {
975
976       case PR_FMT_TEXT:
977         print_stream = print_stream_text_stdio_new(stdout);
978         break;
979
980       case PR_FMT_PS:
981         print_stream = print_stream_ps_stdio_new(stdout);
982         break;
983
984       default:
985         g_assert_not_reached();
986       }
987     }
988   }
989
990   /* We have to dissect each packet if:
991
992         we're printing information about each packet;
993
994         we're using a read filter on the packets;
995
996         we're using a display filter on the packets;
997
998         we're using any taps that need dissection. */
999   do_dissection = print_packet_info || rfcode || dfcode || tap_listeners_require_dissection();
1000
1001   if (cf_name) {
1002     /*
1003      * We're reading a capture file.
1004      */
1005
1006     /* TODO: if tfshark is ever changed to give the user a choice of which
1007        open_routine reader to use, then the following needs to change. */
1008     if (cf_open(&cfile, cf_name, WTAP_TYPE_AUTO, FALSE, &err) != CF_OK) {
1009       epan_cleanup();
1010 #ifdef HAVE_EXTCAP
1011       extcap_cleanup();
1012 #endif
1013       return 2;
1014     }
1015
1016     /* Process the packets in the file */
1017     TRY {
1018       /* XXX - for now there is only 1 packet */
1019       err = load_cap_file(&cfile, 1, 0);
1020     }
1021     CATCH(OutOfMemoryError) {
1022       fprintf(stderr,
1023               "Out Of Memory!\n"
1024               "\n"
1025               "Sorry, but TFShark has to terminate now!\n"
1026               "\n"
1027               "Some infos / workarounds can be found at:\n"
1028               "https://wiki.wireshark.org/KnownBugs/OutOfMemory\n");
1029       err = ENOMEM;
1030     }
1031     ENDTRY;
1032
1033     if (err != 0) {
1034       /* We still dump out the results of taps, etc., as we might have
1035          read some packets; however, we exit with an error status. */
1036       exit_status = 2;
1037     }
1038   }
1039
1040   g_free(cf_name);
1041
1042   if (cfile.frames != NULL) {
1043     free_frame_data_sequence(cfile.frames);
1044     cfile.frames = NULL;
1045   }
1046
1047   draw_tap_listeners(TRUE);
1048   funnel_dump_all_text_windows();
1049   epan_free(cfile.epan);
1050   epan_cleanup();
1051 #ifdef HAVE_EXTCAP
1052   extcap_cleanup();
1053 #endif
1054
1055   output_fields_free(output_fields);
1056   output_fields = NULL;
1057
1058   return exit_status;
1059 }
1060
1061 static const nstime_t *
1062 tfshark_get_frame_ts(void *data, guint32 frame_num)
1063 {
1064   capture_file *cf = (capture_file *) data;
1065
1066   if (ref && ref->num == frame_num)
1067     return &ref->abs_ts;
1068
1069   if (prev_dis && prev_dis->num == frame_num)
1070     return &prev_dis->abs_ts;
1071
1072   if (prev_cap && prev_cap->num == frame_num)
1073     return &prev_cap->abs_ts;
1074
1075   if (cf->frames) {
1076      frame_data *fd = frame_data_sequence_find(cf->frames, frame_num);
1077
1078      return (fd) ? &fd->abs_ts : NULL;
1079   }
1080
1081   return NULL;
1082 }
1083
1084 static const char *
1085 no_interface_name(void *data _U_, guint32 interface_id _U_)
1086 {
1087     return "";
1088 }
1089
1090 static epan_t *
1091 tfshark_epan_new(capture_file *cf)
1092 {
1093   epan_t *epan = epan_new();
1094
1095   epan->data = cf;
1096   epan->get_frame_ts = tfshark_get_frame_ts;
1097   epan->get_interface_name = no_interface_name;
1098   epan->get_user_comment = NULL;
1099
1100   return epan;
1101 }
1102
1103 static gboolean
1104 process_packet_first_pass(capture_file *cf, epan_dissect_t *edt,
1105                gint64 offset, struct wtap_pkthdr *whdr,
1106                const guchar *pd)
1107 {
1108   frame_data     fdlocal;
1109   guint32        framenum;
1110   gboolean       passed;
1111
1112   /* The frame number of this packet is one more than the count of
1113      frames in this packet. */
1114   framenum = cf->count + 1;
1115
1116   /* If we're not running a display filter and we're not printing any
1117      packet information, we don't need to do a dissection. This means
1118      that all packets can be marked as 'passed'. */
1119   passed = TRUE;
1120
1121   frame_data_init(&fdlocal, framenum, whdr, offset, cum_bytes);
1122
1123   /* If we're going to print packet information, or we're going to
1124      run a read filter, or display filter, or we're going to process taps, set up to
1125      do a dissection and do so. */
1126   if (edt) {
1127     /* If we're running a read filter, prime the epan_dissect_t with that
1128        filter. */
1129     if (cf->rfcode)
1130       epan_dissect_prime_dfilter(edt, cf->rfcode);
1131
1132     frame_data_set_before_dissect(&fdlocal, &cf->elapsed_time,
1133                                   &ref, prev_dis);
1134     if (ref == &fdlocal) {
1135       ref_frame = fdlocal;
1136       ref = &ref_frame;
1137     }
1138
1139     epan_dissect_file_run(edt, whdr, file_tvbuff_new(&fdlocal, pd), &fdlocal, NULL);
1140
1141     /* Run the read filter if we have one. */
1142     if (cf->rfcode)
1143       passed = dfilter_apply_edt(cf->rfcode, edt);
1144   }
1145
1146   if (passed) {
1147     frame_data_set_after_dissect(&fdlocal, &cum_bytes);
1148     prev_cap = prev_dis = frame_data_sequence_add(cf->frames, &fdlocal);
1149
1150     /* If we're not doing dissection then there won't be any dependent frames.
1151      * More importantly, edt.pi.dependent_frames won't be initialized because
1152      * epan hasn't been initialized.
1153      */
1154     if (edt) {
1155       g_slist_foreach(edt->pi.dependent_frames, find_and_mark_frame_depended_upon, cf->frames);
1156     }
1157
1158     cf->count++;
1159   } else {
1160     /* if we don't add it to the frame_data_sequence, clean it up right now
1161      * to avoid leaks */
1162     frame_data_destroy(&fdlocal);
1163   }
1164
1165   if (edt)
1166     epan_dissect_reset(edt);
1167
1168   return passed;
1169 }
1170
1171 static gboolean
1172 process_packet_second_pass(capture_file *cf, epan_dissect_t *edt, frame_data *fdata,
1173                struct wtap_pkthdr *phdr, Buffer *buf,
1174                guint tap_flags)
1175 {
1176   column_info    *cinfo;
1177   gboolean        passed;
1178
1179   /* If we're not running a display filter and we're not printing any
1180      packet information, we don't need to do a dissection. This means
1181      that all packets can be marked as 'passed'. */
1182   passed = TRUE;
1183
1184   /* If we're going to print packet information, or we're going to
1185      run a read filter, or we're going to process taps, set up to
1186      do a dissection and do so. */
1187   if (edt) {
1188
1189     /* If we're running a display filter, prime the epan_dissect_t with that
1190        filter. */
1191     if (cf->dfcode)
1192       epan_dissect_prime_dfilter(edt, cf->dfcode);
1193
1194     col_custom_prime_edt(edt, &cf->cinfo);
1195
1196     /* We only need the columns if either
1197          1) some tap needs the columns
1198        or
1199          2) we're printing packet info but we're *not* verbose; in verbose
1200             mode, we print the protocol tree, not the protocol summary.
1201      */
1202     if ((tap_flags & TL_REQUIRES_COLUMNS) || (print_packet_info && print_summary))
1203       cinfo = &cf->cinfo;
1204     else
1205       cinfo = NULL;
1206
1207     frame_data_set_before_dissect(fdata, &cf->elapsed_time,
1208                                   &ref, prev_dis);
1209     if (ref == fdata) {
1210       ref_frame = *fdata;
1211       ref = &ref_frame;
1212     }
1213
1214     epan_dissect_file_run_with_taps(edt, phdr, file_tvbuff_new_buffer(fdata, buf), fdata, cinfo);
1215
1216     /* Run the read/display filter if we have one. */
1217     if (cf->dfcode)
1218       passed = dfilter_apply_edt(cf->dfcode, edt);
1219   }
1220
1221   if (passed) {
1222     frame_data_set_after_dissect(fdata, &cum_bytes);
1223     /* Process this packet. */
1224     if (print_packet_info) {
1225       /* We're printing packet information; print the information for
1226          this packet. */
1227       print_packet(cf, edt);
1228
1229       /* The ANSI C standard does not appear to *require* that a line-buffered
1230          stream be flushed to the host environment whenever a newline is
1231          written, it just says that, on such a stream, characters "are
1232          intended to be transmitted to or from the host environment as a
1233          block when a new-line character is encountered".
1234
1235          The Visual C++ 6.0 C implementation doesn't do what is intended;
1236          even if you set a stream to be line-buffered, it still doesn't
1237          flush the buffer at the end of every line.
1238
1239          So, if the "-l" flag was specified, we flush the standard output
1240          at the end of a packet.  This will do the right thing if we're
1241          printing packet summary lines, and, as we print the entire protocol
1242          tree for a single packet without waiting for anything to happen,
1243          it should be as good as line-buffered mode if we're printing
1244          protocol trees.  (The whole reason for the "-l" flag in either
1245          tcpdump or TShark is to allow the output of a live capture to
1246          be piped to a program or script and to have that script see the
1247          information for the packet as soon as it's printed, rather than
1248          having to wait until a standard I/O buffer fills up. */
1249       if (line_buffered)
1250         fflush(stdout);
1251
1252       if (ferror(stdout)) {
1253         show_print_file_io_error(errno);
1254         exit(2);
1255       }
1256     }
1257     prev_dis = fdata;
1258   }
1259   prev_cap = fdata;
1260
1261   if (edt) {
1262     epan_dissect_reset(edt);
1263   }
1264   return passed || fdata->flags.dependent_of_displayed;
1265 }
1266
1267 static gboolean
1268 local_wtap_read(capture_file *cf, struct wtap_pkthdr* file_phdr _U_, int *err, gchar **err_info _U_, gint64 *data_offset _U_, guint8** data_buffer)
1269 {
1270     /* int bytes_read; */
1271     gint64 packet_size = wtap_file_size(cf->wth, err);
1272
1273     *data_buffer = (guint8*)g_malloc((gsize)packet_size);
1274     /* bytes_read =*/ file_read(*data_buffer, (unsigned int)packet_size, cf->wth->fh);
1275
1276 #if 0 /* no more filetap */
1277     if (bytes_read < 0) {
1278         *err = file_error(cf->wth->fh, err_info);
1279         if (*err == 0)
1280             *err = FTAP_ERR_SHORT_READ;
1281         return FALSE;
1282     } else if (bytes_read == 0) {
1283         /* Done with file, no error */
1284         return FALSE;
1285     }
1286
1287
1288     /* XXX - SET FRAME SIZE EQUAL TO TOTAL FILE SIZE */
1289     file_phdr->caplen = (guint32)packet_size;
1290     file_phdr->len = (guint32)packet_size;
1291
1292     /*
1293      * Set the packet encapsulation to the file's encapsulation
1294      * value; if that's not WTAP_ENCAP_PER_PACKET, it's the
1295      * right answer (and means that the read routine for this
1296      * capture file type doesn't have to set it), and if it
1297      * *is* WTAP_ENCAP_PER_PACKET, the caller needs to set it
1298      * anyway.
1299      */
1300     wth->phdr.pkt_encap = wth->file_encap;
1301
1302     if (!wth->subtype_read(wth, err, err_info, data_offset)) {
1303         /*
1304          * If we didn't get an error indication, we read
1305          * the last packet.  See if there's any deferred
1306          * error, as might, for example, occur if we're
1307          * reading a compressed file, and we got an error
1308          * reading compressed data from the file, but
1309          * got enough compressed data to decompress the
1310          * last packet of the file.
1311          */
1312         if (*err == 0)
1313             *err = file_error(wth->fh, err_info);
1314         return FALSE;    /* failure */
1315     }
1316
1317     /*
1318      * It makes no sense for the captured data length to be bigger
1319      * than the actual data length.
1320      */
1321     if (wth->phdr.caplen > wth->phdr.len)
1322         wth->phdr.caplen = wth->phdr.len;
1323
1324     /*
1325      * Make sure that it's not WTAP_ENCAP_PER_PACKET, as that
1326      * probably means the file has that encapsulation type
1327      * but the read routine didn't set this packet's
1328      * encapsulation type.
1329      */
1330     g_assert(wth->phdr.pkt_encap != WTAP_ENCAP_PER_PACKET);
1331 #endif
1332
1333     return TRUE; /* success */
1334 }
1335
1336 static int
1337 load_cap_file(capture_file *cf, int max_packet_count, gint64 max_byte_count)
1338 {
1339   guint32      framenum;
1340   int          err;
1341   gchar       *err_info = NULL;
1342   gint64       data_offset = 0;
1343   gboolean     filtering_tap_listeners;
1344   guint        tap_flags;
1345   Buffer       buf;
1346   epan_dissect_t *edt = NULL;
1347   struct wtap_pkthdr file_phdr;
1348   guint8* raw_data;
1349
1350   if (print_packet_info) {
1351     if (!write_preamble(cf)) {
1352       err = errno;
1353       show_print_file_io_error(err);
1354       goto out;
1355     }
1356   }
1357
1358   /* Do we have any tap listeners with filters? */
1359   filtering_tap_listeners = have_filtering_tap_listeners();
1360
1361   /* Get the union of the flags for all tap listeners. */
1362   tap_flags = union_of_tap_listener_flags();
1363
1364   wtap_phdr_init(&file_phdr);
1365
1366   /* XXX - TEMPORARY HACK TO ELF DISSECTOR */
1367   file_phdr.pkt_encap = 1234;
1368
1369   if (perform_two_pass_analysis) {
1370     frame_data *fdata;
1371
1372     /* Allocate a frame_data_sequence for all the frames. */
1373     cf->frames = new_frame_data_sequence();
1374
1375     if (do_dissection) {
1376        gboolean create_proto_tree = FALSE;
1377
1378       /* If we're going to be applying a filter, we'll need to
1379          create a protocol tree against which to apply the filter. */
1380       if (cf->rfcode)
1381         create_proto_tree = TRUE;
1382
1383       /* We're not going to display the protocol tree on this pass,
1384          so it's not going to be "visible". */
1385       edt = epan_dissect_new(cf->epan, create_proto_tree, FALSE);
1386     }
1387     while (local_wtap_read(cf, &file_phdr, &err, &err_info, &data_offset, &raw_data)) {
1388       if (process_packet_first_pass(cf, edt, data_offset, &file_phdr/*wtap_phdr(cf->wth)*/,
1389                          wtap_buf_ptr(cf->wth))) {
1390
1391         /* Stop reading if we have the maximum number of packets;
1392          * When the -c option has not been used, max_packet_count
1393          * starts at 0, which practically means, never stop reading.
1394          * (unless we roll over max_packet_count ?)
1395          */
1396         if ( (--max_packet_count == 0) || (max_byte_count != 0 && data_offset >= max_byte_count)) {
1397           err = 0; /* This is not an error */
1398           break;
1399         }
1400       }
1401     }
1402
1403     if (edt) {
1404       epan_dissect_free(edt);
1405       edt = NULL;
1406     }
1407
1408 #if 0
1409     /* Close the sequential I/O side, to free up memory it requires. */
1410     wtap_sequential_close(cf->wth);
1411 #endif
1412
1413     /* Allow the protocol dissectors to free up memory that they
1414      * don't need after the sequential run-through of the packets. */
1415     postseq_cleanup_all_protocols();
1416
1417     prev_dis = NULL;
1418     prev_cap = NULL;
1419     ws_buffer_init(&buf, 1500);
1420
1421     if (do_dissection) {
1422       gboolean create_proto_tree;
1423
1424       if (cf->dfcode || print_details || filtering_tap_listeners ||
1425          (tap_flags & TL_REQUIRES_PROTO_TREE) || have_custom_cols(&cf->cinfo))
1426            create_proto_tree = TRUE;
1427       else
1428            create_proto_tree = FALSE;
1429
1430       /* The protocol tree will be "visible", i.e., printed, only if we're
1431          printing packet details, which is true if we're printing stuff
1432          ("print_packet_info" is true) and we're in verbose mode
1433          ("packet_details" is true). */
1434       edt = epan_dissect_new(cf->epan, create_proto_tree, print_packet_info && print_details);
1435     }
1436
1437     for (framenum = 1; err == 0 && framenum <= cf->count; framenum++) {
1438       fdata = frame_data_sequence_find(cf->frames, framenum);
1439 #if 0
1440       if (wtap_seek_read(cf->wth, fdata->file_off,
1441           &buf, fdata->cap_len, &err, &err_info)) {
1442         process_packet_second_pass(cf, edt, fdata, &cf->phdr, &buf, tap_flags);
1443       }
1444 #else
1445         process_packet_second_pass(cf, edt, fdata, &cf->phdr, &buf, tap_flags);
1446 #endif
1447     }
1448
1449     if (edt) {
1450       epan_dissect_free(edt);
1451       edt = NULL;
1452     }
1453
1454     ws_buffer_free(&buf);
1455   }
1456   else {
1457     framenum = 0;
1458
1459     if (do_dissection) {
1460       gboolean create_proto_tree;
1461
1462       if (cf->rfcode || cf->dfcode || print_details || filtering_tap_listeners ||
1463           (tap_flags & TL_REQUIRES_PROTO_TREE) || have_custom_cols(&cf->cinfo))
1464         create_proto_tree = TRUE;
1465       else
1466         create_proto_tree = FALSE;
1467
1468       /* The protocol tree will be "visible", i.e., printed, only if we're
1469          printing packet details, which is true if we're printing stuff
1470          ("print_packet_info" is true) and we're in verbose mode
1471          ("packet_details" is true). */
1472       edt = epan_dissect_new(cf->epan, create_proto_tree, print_packet_info && print_details);
1473     }
1474
1475     while (local_wtap_read(cf, &file_phdr, &err, &err_info, &data_offset, &raw_data)) {
1476
1477       framenum++;
1478
1479       process_packet(cf, edt, data_offset, &file_phdr/*wtap_phdr(cf->wth)*/,
1480                              raw_data, tap_flags);
1481
1482         /* Stop reading if we have the maximum number of packets;
1483         * When the -c option has not been used, max_packet_count
1484         * starts at 0, which practically means, never stop reading.
1485         * (unless we roll over max_packet_count ?)
1486         */
1487         if ( (--max_packet_count == 0) || (max_byte_count != 0 && data_offset >= max_byte_count)) {
1488             err = 0; /* This is not an error */
1489             break;
1490         }
1491     }
1492
1493     if (edt) {
1494       epan_dissect_free(edt);
1495       edt = NULL;
1496     }
1497   }
1498
1499   wtap_phdr_cleanup(&file_phdr);
1500
1501   if (err != 0) {
1502     /*
1503      * Print a message noting that the read failed somewhere along the line.
1504      *
1505      * If we're printing packet data, and the standard output and error are
1506      * going to the same place, flush the standard output, so everything
1507      * buffered up is written, and then print a newline to the standard error
1508      * before printing the error message, to separate it from the packet
1509      * data.  (Alas, that only works on UN*X; st_dev is meaningless, and
1510      * the _fstat() documentation at Microsoft doesn't indicate whether
1511      * st_ino is even supported.)
1512      */
1513 #ifndef _WIN32
1514     if (print_packet_info) {
1515       ws_statb64 stat_stdout, stat_stderr;
1516
1517       if (ws_fstat64(1, &stat_stdout) == 0 && ws_fstat64(2, &stat_stderr) == 0) {
1518         if (stat_stdout.st_dev == stat_stderr.st_dev &&
1519             stat_stdout.st_ino == stat_stderr.st_ino) {
1520           fflush(stdout);
1521           fprintf(stderr, "\n");
1522         }
1523       }
1524     }
1525 #endif
1526 #if 0
1527     switch (err) {
1528
1529     case FTAP_ERR_UNSUPPORTED:
1530       cmdarg_err("The file \"%s\" contains record data that TFShark doesn't support.\n(%s)",
1531                  cf->filename, err_info);
1532       g_free(err_info);
1533       break;
1534
1535     case FTAP_ERR_UNSUPPORTED_ENCAP:
1536       cmdarg_err("The file \"%s\" has a packet with a network type that TFShark doesn't support.\n(%s)",
1537                  cf->filename, err_info);
1538       g_free(err_info);
1539       break;
1540
1541     case FTAP_ERR_CANT_READ:
1542       cmdarg_err("An attempt to read from the file \"%s\" failed for some unknown reason.",
1543                  cf->filename);
1544       break;
1545
1546     case FTAP_ERR_SHORT_READ:
1547       cmdarg_err("The file \"%s\" appears to have been cut short in the middle of a packet.",
1548                  cf->filename);
1549       break;
1550
1551     case FTAP_ERR_BAD_FILE:
1552       cmdarg_err("The file \"%s\" appears to be damaged or corrupt.\n(%s)",
1553                  cf->filename, err_info);
1554       g_free(err_info);
1555       break;
1556
1557     case FTAP_ERR_DECOMPRESS:
1558       cmdarg_err("The compressed file \"%s\" appears to be damaged or corrupt.\n"
1559                  "(%s)", cf->filename, err_info);
1560       break;
1561
1562     default:
1563       cmdarg_err("An error occurred while reading the file \"%s\": %s.",
1564                  cf->filename, ftap_strerror(err));
1565       break;
1566     }
1567 #endif
1568   } else {
1569     if (print_packet_info) {
1570       if (!write_finale()) {
1571         err = errno;
1572         show_print_file_io_error(err);
1573       }
1574     }
1575   }
1576
1577 out:
1578   wtap_close(cf->wth);
1579   cf->wth = NULL;
1580
1581   return err;
1582 }
1583
1584 static gboolean
1585 process_packet(capture_file *cf, epan_dissect_t *edt, gint64 offset,
1586                struct wtap_pkthdr *whdr, const guchar *pd, guint tap_flags)
1587 {
1588   frame_data      fdata;
1589   column_info    *cinfo;
1590   gboolean        passed;
1591
1592   /* Count this packet. */
1593   cf->count++;
1594
1595   /* If we're not running a display filter and we're not printing any
1596      packet information, we don't need to do a dissection. This means
1597      that all packets can be marked as 'passed'. */
1598   passed = TRUE;
1599
1600   frame_data_init(&fdata, cf->count, whdr, offset, cum_bytes);
1601
1602   /* If we're going to print packet information, or we're going to
1603      run a read filter, or we're going to process taps, set up to
1604      do a dissection and do so. */
1605   if (edt) {
1606     /* If we're running a filter, prime the epan_dissect_t with that
1607        filter. */
1608     if (cf->dfcode)
1609       epan_dissect_prime_dfilter(edt, cf->dfcode);
1610
1611     col_custom_prime_edt(edt, &cf->cinfo);
1612
1613     /* We only need the columns if either
1614          1) some tap needs the columns
1615        or
1616          2) we're printing packet info but we're *not* verbose; in verbose
1617             mode, we print the protocol tree, not the protocol summary.
1618        or
1619          3) there is a column mapped as an individual field */
1620     if ((tap_flags & TL_REQUIRES_COLUMNS) || (print_packet_info && print_summary) || output_fields_has_cols(output_fields))
1621       cinfo = &cf->cinfo;
1622     else
1623       cinfo = NULL;
1624
1625     frame_data_set_before_dissect(&fdata, &cf->elapsed_time,
1626                                   &ref, prev_dis);
1627     if (ref == &fdata) {
1628       ref_frame = fdata;
1629       ref = &ref_frame;
1630     }
1631
1632     epan_dissect_file_run_with_taps(edt, whdr, frame_tvbuff_new(&fdata, pd), &fdata, cinfo);
1633
1634     /* Run the filter if we have it. */
1635     if (cf->dfcode)
1636       passed = dfilter_apply_edt(cf->dfcode, edt);
1637   }
1638
1639   if (passed) {
1640     frame_data_set_after_dissect(&fdata, &cum_bytes);
1641
1642     /* Process this packet. */
1643     if (print_packet_info) {
1644       /* We're printing packet information; print the information for
1645          this packet. */
1646       print_packet(cf, edt);
1647
1648       /* The ANSI C standard does not appear to *require* that a line-buffered
1649          stream be flushed to the host environment whenever a newline is
1650          written, it just says that, on such a stream, characters "are
1651          intended to be transmitted to or from the host environment as a
1652          block when a new-line character is encountered".
1653
1654          The Visual C++ 6.0 C implementation doesn't do what is intended;
1655          even if you set a stream to be line-buffered, it still doesn't
1656          flush the buffer at the end of every line.
1657
1658          So, if the "-l" flag was specified, we flush the standard output
1659          at the end of a packet.  This will do the right thing if we're
1660          printing packet summary lines, and, as we print the entire protocol
1661          tree for a single packet without waiting for anything to happen,
1662          it should be as good as line-buffered mode if we're printing
1663          protocol trees.  (The whole reason for the "-l" flag in either
1664          tcpdump or TShark is to allow the output of a live capture to
1665          be piped to a program or script and to have that script see the
1666          information for the packet as soon as it's printed, rather than
1667          having to wait until a standard I/O buffer fills up. */
1668       if (line_buffered)
1669         fflush(stdout);
1670
1671       if (ferror(stdout)) {
1672         show_print_file_io_error(errno);
1673         exit(2);
1674       }
1675     }
1676
1677     /* this must be set after print_packet() [bug #8160] */
1678     prev_dis_frame = fdata;
1679     prev_dis = &prev_dis_frame;
1680   }
1681
1682   prev_cap_frame = fdata;
1683   prev_cap = &prev_cap_frame;
1684
1685   if (edt) {
1686     epan_dissect_reset(edt);
1687     frame_data_destroy(&fdata);
1688   }
1689   return passed;
1690 }
1691
1692 static gboolean
1693 write_preamble(capture_file *cf)
1694 {
1695   switch (output_action) {
1696
1697   case WRITE_TEXT:
1698     return print_preamble(print_stream, cf->filename, get_ws_vcs_version_info());
1699
1700   case WRITE_XML:
1701     if (print_details)
1702       write_pdml_preamble(stdout, cf->filename);
1703     else
1704       write_psml_preamble(&cf->cinfo, stdout);
1705     return !ferror(stdout);
1706
1707   case WRITE_FIELDS:
1708     write_fields_preamble(output_fields, stdout);
1709     return !ferror(stdout);
1710
1711   default:
1712     g_assert_not_reached();
1713     return FALSE;
1714   }
1715 }
1716
1717 static char *
1718 get_line_buf(size_t len)
1719 {
1720   static char   *line_bufp    = NULL;
1721   static size_t  line_buf_len = 256;
1722   size_t         new_line_buf_len;
1723
1724   for (new_line_buf_len = line_buf_len; len > new_line_buf_len;
1725        new_line_buf_len *= 2)
1726     ;
1727   if (line_bufp == NULL) {
1728     line_buf_len = new_line_buf_len;
1729     line_bufp = (char *)g_malloc(line_buf_len + 1);
1730   } else {
1731     if (new_line_buf_len > line_buf_len) {
1732       line_buf_len = new_line_buf_len;
1733       line_bufp = (char *)g_realloc(line_bufp, line_buf_len + 1);
1734     }
1735   }
1736   return line_bufp;
1737 }
1738
1739 static inline void
1740 put_string(char *dest, const char *str, size_t str_len)
1741 {
1742   memcpy(dest, str, str_len);
1743   dest[str_len] = '\0';
1744 }
1745
1746 static inline void
1747 put_spaces_string(char *dest, const char *str, size_t str_len, size_t str_with_spaces)
1748 {
1749   size_t i;
1750
1751   for (i = str_len; i < str_with_spaces; i++)
1752     *dest++ = ' ';
1753
1754   put_string(dest, str, str_len);
1755 }
1756
1757 static inline void
1758 put_string_spaces(char *dest, const char *str, size_t str_len, size_t str_with_spaces)
1759 {
1760   size_t i;
1761
1762   memcpy(dest, str, str_len);
1763   for (i = str_len; i < str_with_spaces; i++)
1764     dest[i] = ' ';
1765
1766   dest[str_with_spaces] = '\0';
1767 }
1768
1769 static gboolean
1770 print_columns(capture_file *cf)
1771 {
1772   char   *line_bufp;
1773   int     i;
1774   size_t  buf_offset;
1775   size_t  column_len;
1776   size_t  col_len;
1777   col_item_t* col_item;
1778
1779   line_bufp = get_line_buf(256);
1780   buf_offset = 0;
1781   *line_bufp = '\0';
1782   for (i = 0; i < cf->cinfo.num_cols; i++) {
1783     col_item = &cf->cinfo.columns[i];
1784     /* Skip columns not marked as visible. */
1785     if (!get_column_visible(i))
1786       continue;
1787     switch (col_item->col_fmt) {
1788     case COL_NUMBER:
1789       column_len = col_len = strlen(col_item->col_data);
1790       if (column_len < 3)
1791         column_len = 3;
1792       line_bufp = get_line_buf(buf_offset + column_len);
1793       put_spaces_string(line_bufp + buf_offset, col_item->col_data, col_len, column_len);
1794       break;
1795
1796     case COL_CLS_TIME:
1797     case COL_REL_TIME:
1798     case COL_ABS_TIME:
1799     case COL_ABS_YMD_TIME:  /* XXX - wider */
1800     case COL_ABS_YDOY_TIME: /* XXX - wider */
1801     case COL_UTC_TIME:
1802     case COL_UTC_YMD_TIME:  /* XXX - wider */
1803     case COL_UTC_YDOY_TIME: /* XXX - wider */
1804       column_len = col_len = strlen(col_item->col_data);
1805       if (column_len < 10)
1806         column_len = 10;
1807       line_bufp = get_line_buf(buf_offset + column_len);
1808       put_spaces_string(line_bufp + buf_offset, col_item->col_data, col_len, column_len);
1809       break;
1810
1811     case COL_DEF_SRC:
1812     case COL_RES_SRC:
1813     case COL_UNRES_SRC:
1814     case COL_DEF_DL_SRC:
1815     case COL_RES_DL_SRC:
1816     case COL_UNRES_DL_SRC:
1817     case COL_DEF_NET_SRC:
1818     case COL_RES_NET_SRC:
1819     case COL_UNRES_NET_SRC:
1820       column_len = col_len = strlen(col_item->col_data);
1821       if (column_len < 12)
1822         column_len = 12;
1823       line_bufp = get_line_buf(buf_offset + column_len);
1824       put_spaces_string(line_bufp + buf_offset, col_item->col_data, col_len, column_len);
1825       break;
1826
1827     case COL_DEF_DST:
1828     case COL_RES_DST:
1829     case COL_UNRES_DST:
1830     case COL_DEF_DL_DST:
1831     case COL_RES_DL_DST:
1832     case COL_UNRES_DL_DST:
1833     case COL_DEF_NET_DST:
1834     case COL_RES_NET_DST:
1835     case COL_UNRES_NET_DST:
1836       column_len = col_len = strlen(col_item->col_data);
1837       if (column_len < 12)
1838         column_len = 12;
1839       line_bufp = get_line_buf(buf_offset + column_len);
1840       put_string_spaces(line_bufp + buf_offset, col_item->col_data, col_len, column_len);
1841       break;
1842
1843     default:
1844       column_len = strlen(col_item->col_data);
1845       line_bufp = get_line_buf(buf_offset + column_len);
1846       put_string(line_bufp + buf_offset, col_item->col_data, column_len);
1847       break;
1848     }
1849     buf_offset += column_len;
1850     if (i != cf->cinfo.num_cols - 1) {
1851       /*
1852        * This isn't the last column, so we need to print a
1853        * separator between this column and the next.
1854        *
1855        * If we printed a network source and are printing a
1856        * network destination of the same type next, separate
1857        * them with " -> "; if we printed a network destination
1858        * and are printing a network source of the same type
1859        * next, separate them with " <- "; otherwise separate them
1860        * with a space.
1861        *
1862        * We add enough space to the buffer for " <- " or " -> ",
1863        * even if we're only adding " ".
1864        */
1865       line_bufp = get_line_buf(buf_offset + 4);
1866       switch (col_item->col_fmt) {
1867
1868       case COL_DEF_SRC:
1869       case COL_RES_SRC:
1870       case COL_UNRES_SRC:
1871         switch (cf->cinfo.columns[i+1].col_fmt) {
1872
1873         case COL_DEF_DST:
1874         case COL_RES_DST:
1875         case COL_UNRES_DST:
1876           put_string(line_bufp + buf_offset, " -> ", 4);
1877           buf_offset += 4;
1878           break;
1879
1880         default:
1881           put_string(line_bufp + buf_offset, " ", 1);
1882           buf_offset += 1;
1883           break;
1884         }
1885         break;
1886
1887       case COL_DEF_DL_SRC:
1888       case COL_RES_DL_SRC:
1889       case COL_UNRES_DL_SRC:
1890         switch (cf->cinfo.columns[i+1].col_fmt) {
1891
1892         case COL_DEF_DL_DST:
1893         case COL_RES_DL_DST:
1894         case COL_UNRES_DL_DST:
1895           put_string(line_bufp + buf_offset, " -> ", 4);
1896           buf_offset += 4;
1897           break;
1898
1899         default:
1900           put_string(line_bufp + buf_offset, " ", 1);
1901           buf_offset += 1;
1902           break;
1903         }
1904         break;
1905
1906       case COL_DEF_NET_SRC:
1907       case COL_RES_NET_SRC:
1908       case COL_UNRES_NET_SRC:
1909         switch (cf->cinfo.columns[i+1].col_fmt) {
1910
1911         case COL_DEF_NET_DST:
1912         case COL_RES_NET_DST:
1913         case COL_UNRES_NET_DST:
1914           put_string(line_bufp + buf_offset, " -> ", 4);
1915           buf_offset += 4;
1916           break;
1917
1918         default:
1919           put_string(line_bufp + buf_offset, " ", 1);
1920           buf_offset += 1;
1921           break;
1922         }
1923         break;
1924
1925       case COL_DEF_DST:
1926       case COL_RES_DST:
1927       case COL_UNRES_DST:
1928         switch (cf->cinfo.columns[i+1].col_fmt) {
1929
1930         case COL_DEF_SRC:
1931         case COL_RES_SRC:
1932         case COL_UNRES_SRC:
1933           put_string(line_bufp + buf_offset, " <- ", 4);
1934           buf_offset += 4;
1935           break;
1936
1937         default:
1938           put_string(line_bufp + buf_offset, " ", 1);
1939           buf_offset += 1;
1940           break;
1941         }
1942         break;
1943
1944       case COL_DEF_DL_DST:
1945       case COL_RES_DL_DST:
1946       case COL_UNRES_DL_DST:
1947         switch (cf->cinfo.columns[i+1].col_fmt) {
1948
1949         case COL_DEF_DL_SRC:
1950         case COL_RES_DL_SRC:
1951         case COL_UNRES_DL_SRC:
1952           put_string(line_bufp + buf_offset, " <- ", 4);
1953           buf_offset += 4;
1954           break;
1955
1956         default:
1957           put_string(line_bufp + buf_offset, " ", 1);
1958           buf_offset += 1;
1959           break;
1960         }
1961         break;
1962
1963       case COL_DEF_NET_DST:
1964       case COL_RES_NET_DST:
1965       case COL_UNRES_NET_DST:
1966         switch (cf->cinfo.columns[i+1].col_fmt) {
1967
1968         case COL_DEF_NET_SRC:
1969         case COL_RES_NET_SRC:
1970         case COL_UNRES_NET_SRC:
1971           put_string(line_bufp + buf_offset, " <- ", 4);
1972           buf_offset += 4;
1973           break;
1974
1975         default:
1976           put_string(line_bufp + buf_offset, " ", 1);
1977           buf_offset += 1;
1978           break;
1979         }
1980         break;
1981
1982       default:
1983         put_string(line_bufp + buf_offset, " ", 1);
1984         buf_offset += 1;
1985         break;
1986       }
1987     }
1988   }
1989   return print_line(print_stream, 0, line_bufp);
1990 }
1991
1992 static gboolean
1993 print_packet(capture_file *cf, epan_dissect_t *edt)
1994 {
1995   print_args_t print_args;
1996
1997   if (print_summary || output_fields_has_cols(output_fields)) {
1998     /* Just fill in the columns. */
1999     epan_dissect_fill_in_columns(edt, FALSE, TRUE);
2000
2001     if (print_summary) {
2002       /* Now print them. */
2003       switch (output_action) {
2004
2005       case WRITE_TEXT:
2006         if (!print_columns(cf))
2007           return FALSE;
2008         break;
2009
2010       case WRITE_XML:
2011         write_psml_columns(edt, stdout);
2012         return !ferror(stdout);
2013       case WRITE_FIELDS: /*No non-verbose "fields" format */
2014         g_assert_not_reached();
2015         break;
2016       }
2017     }
2018   }
2019   if (print_details) {
2020     /* Print the information in the protocol tree. */
2021     switch (output_action) {
2022
2023     case WRITE_TEXT:
2024       /* Only initialize the fields that are actually used in proto_tree_print.
2025        * This is particularly important for .range, as that's heap memory which
2026        * we would otherwise have to g_free().
2027       print_args.to_file = TRUE;
2028       print_args.format = print_format;
2029       print_args.print_summary = print_summary;
2030       print_args.print_formfeed = FALSE;
2031       packet_range_init(&print_args.range, &cfile);
2032       */
2033       print_args.print_hex = print_hex;
2034       print_args.print_dissections = print_details ? print_dissections_expanded : print_dissections_none;
2035
2036       if (!proto_tree_print(&print_args, edt, output_only_tables, print_stream))
2037         return FALSE;
2038       if (!print_hex) {
2039         if (!print_line(print_stream, 0, separator))
2040           return FALSE;
2041       }
2042       break;
2043
2044     case WRITE_XML:
2045       write_pdml_proto_tree(NULL, NULL, edt, stdout);
2046       printf("\n");
2047       return !ferror(stdout);
2048     case WRITE_FIELDS:
2049       write_fields_proto_tree(output_fields, edt, &cf->cinfo, stdout);
2050       printf("\n");
2051       return !ferror(stdout);
2052     }
2053   }
2054   if (print_hex) {
2055     if (print_summary || print_details) {
2056       if (!print_line(print_stream, 0, ""))
2057         return FALSE;
2058     }
2059     if (!print_hex_data(print_stream, edt))
2060       return FALSE;
2061     if (!print_line(print_stream, 0, separator))
2062       return FALSE;
2063   }
2064   return TRUE;
2065 }
2066
2067 static gboolean
2068 write_finale(void)
2069 {
2070   switch (output_action) {
2071
2072   case WRITE_TEXT:
2073     return print_finale(print_stream);
2074
2075   case WRITE_XML:
2076     if (print_details)
2077       write_pdml_finale(stdout);
2078     else
2079       write_psml_finale(stdout);
2080     return !ferror(stdout);
2081
2082   case WRITE_FIELDS:
2083     write_fields_finale(output_fields, stdout);
2084     return !ferror(stdout);
2085
2086   default:
2087     g_assert_not_reached();
2088     return FALSE;
2089   }
2090 }
2091
2092 cf_status_t
2093 cf_open(capture_file *cf, const char *fname, unsigned int type, gboolean is_tempfile, int *err)
2094 {
2095   gchar *err_info;
2096   char   err_msg[2048+1];
2097
2098   /* The open isn't implemented yet.  Fill in the information for this file. */
2099
2100   /* Create new epan session for dissection. */
2101   epan_free(cf->epan);
2102   cf->epan = tfshark_epan_new(cf);
2103
2104   cf->wth = NULL; /**** XXX - DOESN'T WORK RIGHT NOW!!!! */
2105   cf->f_datalen = 0; /* not used, but set it anyway */
2106
2107   /* Set the file name because we need it to set the follow stream filter.
2108      XXX - is that still true?  We need it for other reasons, though,
2109      in any case. */
2110   cf->filename = g_strdup(fname);
2111
2112   /* Indicate whether it's a permanent or temporary file. */
2113   cf->is_tempfile = is_tempfile;
2114
2115   /* No user changes yet. */
2116   cf->unsaved_changes = FALSE;
2117
2118   cf->cd_t      = 0; /**** XXX - DOESN'T WORK RIGHT NOW!!!! */
2119   cf->open_type = type;
2120   cf->count     = 0;
2121   cf->drops_known = FALSE;
2122   cf->drops     = 0;
2123   cf->snap      = 0; /**** XXX - DOESN'T WORK RIGHT NOW!!!! */
2124   if (cf->snap == 0) {
2125     /* Snapshot length not known. */
2126     cf->has_snap = FALSE;
2127     cf->snap = 0;
2128   } else
2129     cf->has_snap = TRUE;
2130   nstime_set_zero(&cf->elapsed_time);
2131   ref = NULL;
2132   prev_dis = NULL;
2133   prev_cap = NULL;
2134
2135   cf->state = FILE_READ_IN_PROGRESS;
2136
2137   return CF_OK;
2138
2139 /* fail: */
2140   g_snprintf(err_msg, sizeof err_msg,
2141              cf_open_error_message(*err, err_info, FALSE, cf->cd_t), fname);
2142   cmdarg_err("%s", err_msg);
2143   return CF_ERROR;
2144 }
2145
2146 static void
2147 show_print_file_io_error(int err)
2148 {
2149   switch (err) {
2150
2151   case ENOSPC:
2152     cmdarg_err("Not all the packets could be printed because there is "
2153 "no space left on the file system.");
2154     break;
2155
2156 #ifdef EDQUOT
2157   case EDQUOT:
2158     cmdarg_err("Not all the packets could be printed because you are "
2159 "too close to, or over your disk quota.");
2160   break;
2161 #endif
2162
2163   default:
2164     cmdarg_err("An error occurred while printing packets: %s.",
2165       g_strerror(err));
2166     break;
2167   }
2168 }
2169
2170 static const char *
2171 cf_open_error_message(int err, gchar *err_info _U_, gboolean for_writing,
2172                       int file_type _U_)
2173 {
2174   const char *errmsg;
2175   /* static char errmsg_errno[1024+1]; */
2176
2177 #if 0
2178   if (err < 0) {
2179     /* Wiretap error. */
2180     switch (err) {
2181
2182     case FTAP_ERR_NOT_REGULAR_FILE:
2183       errmsg = "The file \"%s\" is a \"special file\" or socket or other non-regular file.";
2184       break;
2185
2186     case FTAP_ERR_RANDOM_OPEN_PIPE:
2187       /* Seen only when opening a capture file for reading. */
2188       errmsg = "The file \"%s\" is a pipe or FIFO; TFShark can't read pipe or FIFO files in two-pass mode.";
2189       break;
2190
2191     case FTAP_ERR_FILE_UNKNOWN_FORMAT:
2192       /* Seen only when opening a capture file for reading. */
2193       errmsg = "The file \"%s\" isn't a capture file in a format TFShark understands.";
2194       break;
2195
2196     case FTAP_ERR_UNSUPPORTED:
2197       /* Seen only when opening a capture file for reading. */
2198       g_snprintf(errmsg_errno, sizeof(errmsg_errno),
2199                "The file \"%%s\" isn't a capture file in a format TFShark understands.\n"
2200                "(%s)", err_info);
2201       g_free(err_info);
2202       errmsg = errmsg_errno;
2203       break;
2204
2205     case FTAP_ERR_CANT_WRITE_TO_PIPE:
2206       /* Seen only when opening a capture file for writing. */
2207       g_snprintf(errmsg_errno, sizeof(errmsg_errno),
2208                  "The file \"%%s\" is a pipe, and \"%s\" capture files can't be "
2209                  "written to a pipe.", ftap_file_type_subtype_short_string(file_type));
2210       errmsg = errmsg_errno;
2211       break;
2212
2213     case FTAP_ERR_UNSUPPORTED_FILE_TYPE:
2214       /* Seen only when opening a capture file for writing. */
2215       errmsg = "TFShark doesn't support writing capture files in that format.";
2216       break;
2217
2218     case FTAP_ERR_UNSUPPORTED_ENCAP:
2219       if (for_writing) {
2220         g_snprintf(errmsg_errno, sizeof(errmsg_errno),
2221                    "TFShark can't save this capture as a \"%s\" file.",
2222                    ftap_file_type_subtype_short_string(file_type));
2223       } else {
2224         g_snprintf(errmsg_errno, sizeof(errmsg_errno),
2225                  "The file \"%%s\" is a capture for a network type that TFShark doesn't support.\n"
2226                  "(%s)", err_info);
2227         g_free(err_info);
2228       }
2229       errmsg = errmsg_errno;
2230       break;
2231
2232     case FTAP_ERR_ENCAP_PER_RECORD_UNSUPPORTED:
2233       if (for_writing) {
2234         g_snprintf(errmsg_errno, sizeof(errmsg_errno),
2235                    "TFShark can't save this capture as a \"%s\" file.",
2236                    ftap_file_type_subtype_short_string(file_type));
2237         errmsg = errmsg_errno;
2238       } else
2239         errmsg = "The file \"%s\" is a capture for a network type that TFShark doesn't support.";
2240       break;
2241
2242     case FTAP_ERR_BAD_FILE:
2243       /* Seen only when opening a capture file for reading. */
2244       g_snprintf(errmsg_errno, sizeof(errmsg_errno),
2245                "The file \"%%s\" appears to be damaged or corrupt.\n"
2246                "(%s)", err_info);
2247       g_free(err_info);
2248       errmsg = errmsg_errno;
2249       break;
2250
2251     case FTAP_ERR_CANT_OPEN:
2252       if (for_writing)
2253         errmsg = "The file \"%s\" could not be created for some unknown reason.";
2254       else
2255         errmsg = "The file \"%s\" could not be opened for some unknown reason.";
2256       break;
2257
2258     case FTAP_ERR_SHORT_READ:
2259       errmsg = "The file \"%s\" appears to have been cut short"
2260                " in the middle of a packet or other data.";
2261       break;
2262
2263     case FTAP_ERR_SHORT_WRITE:
2264       errmsg = "A full header couldn't be written to the file \"%s\".";
2265       break;
2266
2267     case FTAP_ERR_COMPRESSION_NOT_SUPPORTED:
2268       errmsg = "This file type cannot be written as a compressed file.";
2269       break;
2270
2271     case FTAP_ERR_DECOMPRESS:
2272       /* Seen only when opening a capture file for reading. */
2273       g_snprintf(errmsg_errno, sizeof(errmsg_errno),
2274                  "The compressed file \"%%s\" appears to be damaged or corrupt.\n"
2275                  "(%s)", err_info);
2276       g_free(err_info);
2277       errmsg = errmsg_errno;
2278       break;
2279
2280     default:
2281       g_snprintf(errmsg_errno, sizeof(errmsg_errno),
2282                  "The file \"%%s\" could not be %s: %s.",
2283                  for_writing ? "created" : "opened",
2284                  ftap_strerror(err));
2285       errmsg = errmsg_errno;
2286       break;
2287     }
2288   } else
2289 #endif
2290     errmsg = file_open_error_message(err, for_writing);
2291   return errmsg;
2292 }
2293
2294 /*
2295  * Open/create errors are reported with an console message in TFShark.
2296  */
2297 static void
2298 open_failure_message(const char *filename, int err, gboolean for_writing)
2299 {
2300   fprintf(stderr, "tfshark: ");
2301   fprintf(stderr, file_open_error_message(err, for_writing), filename);
2302   fprintf(stderr, "\n");
2303 }
2304
2305
2306 /*
2307  * General errors are reported with an console message in TFShark.
2308  */
2309 static void
2310 failure_message(const char *msg_format, va_list ap)
2311 {
2312   fprintf(stderr, "tfshark: ");
2313   vfprintf(stderr, msg_format, ap);
2314   fprintf(stderr, "\n");
2315 }
2316
2317 /*
2318  * Read errors are reported with an console message in TFShark.
2319  */
2320 static void
2321 read_failure_message(const char *filename, int err)
2322 {
2323   cmdarg_err("An error occurred while reading from the file \"%s\": %s.",
2324           filename, g_strerror(err));
2325 }
2326
2327 /*
2328  * Write errors are reported with an console message in TFShark.
2329  */
2330 static void
2331 write_failure_message(const char *filename, int err)
2332 {
2333   cmdarg_err("An error occurred while writing to the file \"%s\": %s.",
2334           filename, g_strerror(err));
2335 }
2336
2337 /*
2338  * Report additional information for an error in command-line arguments.
2339  */
2340 static void
2341 failure_message_cont(const char *msg_format, va_list ap)
2342 {
2343   vfprintf(stderr, msg_format, ap);
2344   fprintf(stderr, "\n");
2345 }
2346
2347 /*
2348  * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
2349  *
2350  * Local variables:
2351  * c-basic-offset: 2
2352  * tab-width: 8
2353  * indent-tabs-mode: nil
2354  * End:
2355  *
2356  * vi: set shiftwidth=2 tabstop=8 expandtab:
2357  * :indentSize=2:tabSize=8:noTabs=true:
2358  */