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