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