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