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