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