qt: remove leak
[metze/wireshark/wip.git] / tfshark.c
1 /* tfshark.c
2  *
3  * Text-mode variant of Fileshark, based off of TShark,
4  *
5  * Wireshark - Network traffic analyzer
6  * By Gerald Combs <gerald@wireshark.org>
7  * Copyright 1998 Gerald Combs
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License
11  * as published by the Free Software Foundation; either version 2
12  * of the License, or (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22  */
23
24 #include <config.h>
25
26 #include <stdlib.h>
27 #include <stdio.h>
28 #include <string.h>
29 #include <locale.h>
30 #include <limits.h>
31
32 #ifdef HAVE_UNISTD_H
33 #include <unistd.h>
34 #endif
35
36 #ifdef HAVE_GETOPT_H
37 #include <getopt.h>
38 #endif
39
40 #include <errno.h>
41
42 #ifdef HAVE_FCNTL_H
43 #include <fcntl.h>
44 #endif
45
46 #ifdef HAVE_SYS_STAT_H
47 # include <sys/stat.h>
48 #endif
49
50 #ifdef HAVE_LIBZ
51 #include <zlib.h>      /* to get the libz version number */
52 #endif
53
54 #ifndef HAVE_GETOPT_LONG
55 #include "wsutil/wsgetopt.h"
56 #endif
57
58 #include <glib.h>
59
60 #include <epan/exceptions.h>
61 #include <epan/epan-int.h>
62 #include <epan/epan.h>
63
64 #include <wsutil/clopts_common.h>
65 #include <wsutil/cmdarg_err.h>
66 #include <wsutil/crash_info.h>
67 #include <wsutil/filesystem.h>
68 #include <wsutil/file_util.h>
69 #include <wsutil/privileges.h>
70 #include <wsutil/report_err.h>
71 #include <wsutil/ws_diag_control.h>
72 #include <wsutil/ws_version_info.h>
73
74 #include "globals.h"
75 #include <epan/timestamp.h>
76 #include <epan/packet.h>
77 #ifdef HAVE_LUA
78 #include <epan/wslua/init_wslua.h>
79 #endif
80 #include "file.h"
81 #include "frame_tvbuff.h"
82 #include <epan/disabled_protos.h>
83 #include <epan/prefs.h>
84 #include <epan/column.h>
85 #include <epan/print.h>
86 #include <epan/addr_resolv.h>
87 #include "ui/util.h"
88 #include "register.h"
89 #include <epan/epan_dissect.h>
90 #include <epan/tap.h>
91 #include <epan/stat_tap_ui.h>
92 #include <epan/ex-opt.h>
93
94 #if defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS)
95 #include <epan/asn1.h>
96 #include <epan/dissectors/packet-kerberos.h>
97 #endif
98
99 #include <wiretap/wtap-int.h>
100 #include <wiretap/file_wrappers.h>
101
102 #ifdef _WIN32
103 #include <wsutil/unicode-utils.h>
104 #endif /* _WIN32 */
105
106 #include "log.h"
107 #include <epan/funnel.h>
108
109 #ifdef HAVE_PLUGINS
110 #include <wsutil/plugins.h>
111 #endif
112
113 /*
114  * This is the template for the decode as option; it is shared between the
115  * various functions that output the usage for this parameter.
116  */
117 static const gchar decode_as_arg_template[] = "<layer_type>==<selector>,<decode_as_protocol>";
118
119 static guint32 cum_bytes;
120 static const frame_data *ref;
121 static frame_data ref_frame;
122 static frame_data *prev_dis;
123 static frame_data prev_dis_frame;
124 static frame_data *prev_cap;
125 static frame_data prev_cap_frame;
126
127 static const char* prev_display_dissector_name = NULL;
128
129 static gboolean perform_two_pass_analysis;
130
131 /*
132  * The way the packet decode is to be written.
133  */
134 typedef enum {
135   WRITE_TEXT,   /* summary or detail text */
136   WRITE_XML,    /* PDML or PSML */
137   WRITE_FIELDS  /* User defined list of fields */
138   /* Add CSV and the like here */
139 } output_action_e;
140
141 static output_action_e output_action;
142 static gboolean do_dissection;     /* TRUE if we have to dissect each packet */
143 static gboolean print_packet_info; /* TRUE if we're to print packet information */
144 static gint print_summary = -1;    /* TRUE if we're to print packet summary information */
145 static gboolean print_details;     /* TRUE if we're to print packet details information */
146 static gboolean print_hex;         /* TRUE if we're to print hex/ascci information */
147 static gboolean line_buffered;
148 static gboolean really_quiet = FALSE;
149
150 static print_format_e print_format = PR_FMT_TEXT;
151 static print_stream_t *print_stream;
152
153 static output_fields_t* output_fields  = NULL;
154
155 /* The line separator used between packets, changeable via the -S option */
156 static const char *separator = "";
157
158 static int load_cap_file(capture_file *, int, gint64);
159 static gboolean process_packet(capture_file *cf, epan_dissect_t *edt, gint64 offset,
160     struct wtap_pkthdr *whdr, const guchar *pd, guint tap_flags);
161 static void show_print_file_io_error(int err);
162 static gboolean write_preamble(capture_file *cf);
163 static gboolean print_packet(capture_file *cf, epan_dissect_t *edt);
164 static gboolean write_finale(void);
165 static const char *cf_open_error_message(int err, gchar *err_info,
166     gboolean for_writing, int file_type);
167
168 static void open_failure_message(const char *filename, int err,
169     gboolean for_writing);
170 static void failure_message(const char *msg_format, va_list ap);
171 static void read_failure_message(const char *filename, int err);
172 static void write_failure_message(const char *filename, int err);
173 static void failure_message_cont(const char *msg_format, va_list ap);
174
175 capture_file cfile;
176
177 static GHashTable *output_only_tables = NULL;
178
179 #if 0
180 struct string_elem {
181   const char *sstr;   /* The short string */
182   const char *lstr;   /* The long string */
183 };
184
185 static gint
186 string_compare(gconstpointer a, gconstpointer b)
187 {
188   return strcmp(((const struct string_elem *)a)->sstr,
189                 ((const struct string_elem *)b)->sstr);
190 }
191
192 static void
193 string_elem_print(gpointer data, gpointer not_used _U_)
194 {
195   fprintf(stderr, "    %s - %s\n",
196           ((struct string_elem *)data)->sstr,
197           ((struct string_elem *)data)->lstr);
198 }
199 #endif
200
201 static void
202 print_usage(FILE *output)
203 {
204   fprintf(output, "\n");
205   fprintf(output, "Usage: tfshark [options] ...\n");
206   fprintf(output, "\n");
207
208   /*fprintf(output, "\n");*/
209   fprintf(output, "Input file:\n");
210   fprintf(output, "  -r <infile>              set the filename to read from (no pipes or stdin!)\n");
211
212   fprintf(output, "\n");
213   fprintf(output, "Processing:\n");
214   fprintf(output, "  -2                       perform a two-pass analysis\n");
215   fprintf(output, "  -R <read filter>         packet Read filter in Wireshark display filter syntax\n");
216   fprintf(output, "  -Y <display filter>      packet displaY filter in Wireshark display filter\n");
217   fprintf(output, "                           syntax\n");
218   fprintf(output, "  -d %s ...\n", decode_as_arg_template);
219   fprintf(output, "                           \"Decode As\", see the man page for details\n");
220   fprintf(output, "                           Example: tcp.port==8888,http\n");
221
222   /*fprintf(output, "\n");*/
223   fprintf(output, "Output:\n");
224   fprintf(output, "  -C <config profile>      start with specified configuration profile\n");
225   fprintf(output, "  -V                       add output of packet tree        (Packet Details)\n");
226   fprintf(output, "  -O <protocols>           Only show packet details of these protocols, comma\n");
227   fprintf(output, "                           separated\n");
228   fprintf(output, "  -S <separator>           the line separator to print between packets\n");
229   fprintf(output, "  -x                       add output of hex and ASCII dump (Packet Bytes)\n");
230   fprintf(output, "  -T pdml|ps|psml|text|fields\n");
231   fprintf(output, "                           format of text output (def: text)\n");
232   fprintf(output, "  -e <field>               field to print if -Tfields selected (e.g. tcp.port,\n");
233   fprintf(output, "                           _ws.col.Info)\n");
234   fprintf(output, "                           this option can be repeated to print multiple fields\n");
235   fprintf(output, "  -E<fieldsoption>=<value> set options for output when -Tfields selected:\n");
236   fprintf(output, "     header=y|n            switch headers on and off\n");
237   fprintf(output, "     separator=/t|/s|<char> select tab, space, printable character as separator\n");
238   fprintf(output, "     occurrence=f|l|a      print first, last or all occurrences of each field\n");
239   fprintf(output, "     aggregator=,|/s|<char> select comma, space, printable character as\n");
240   fprintf(output, "                           aggregator\n");
241   fprintf(output, "     quote=d|s|n           select double, single, no quotes for values\n");
242   fprintf(output, "  -t a|ad|d|dd|e|r|u|ud    output format of time stamps (def: r: rel. to first)\n");
243   fprintf(output, "  -u s|hms                 output format of seconds (def: s: seconds)\n");
244   fprintf(output, "  -l                       flush standard output after each packet\n");
245   fprintf(output, "  -q                       be more quiet on stdout (e.g. when using statistics)\n");
246   fprintf(output, "  -Q                       only log true errors to stderr (quieter than -q)\n");
247   fprintf(output, "  -X <key>:<value>         eXtension options, see the man page for details\n");
248   fprintf(output, "  -z <statistics>          various statistics, see the man page for details\n");
249
250   fprintf(output, "\n");
251   fprintf(output, "Miscellaneous:\n");
252   fprintf(output, "  -h                       display this help and exit\n");
253   fprintf(output, "  -v                       display version info and exit\n");
254   fprintf(output, "  -o <name>:<value> ...    override preference setting\n");
255   fprintf(output, "  -K <keytab>              keytab file to use for kerberos decryption\n");
256   fprintf(output, "  -G [report]              dump one of several available reports and exit\n");
257   fprintf(output, "                           default report=\"fields\"\n");
258   fprintf(output, "                           use \"-G ?\" for more help\n");
259 }
260
261 static void
262 glossary_option_help(void)
263 {
264   FILE *output;
265
266   output = stdout;
267
268   fprintf(output, "TFShark (Wireshark) %s\n", get_ws_vcs_version_info());
269
270   fprintf(output, "\n");
271   fprintf(output, "Usage: tfshark -G [report]\n");
272   fprintf(output, "\n");
273   fprintf(output, "Glossary table reports:\n");
274   fprintf(output, "  -G column-formats        dump column format codes and exit\n");
275   fprintf(output, "  -G decodes               dump \"layer type\"/\"decode as\" associations and exit\n");
276   fprintf(output, "  -G dissector-tables      dump dissector table names, types, and properties\n");
277   fprintf(output, "  -G fields                dump fields glossary and exit\n");
278   fprintf(output, "  -G ftypes                dump field type basic and descriptive names\n");
279   fprintf(output, "  -G heuristic-decodes     dump heuristic dissector tables\n");
280   fprintf(output, "  -G plugins               dump installed plugins and exit\n");
281   fprintf(output, "  -G protocols             dump protocols in registration database and exit\n");
282   fprintf(output, "  -G values                dump value, range, true/false strings and exit\n");
283   fprintf(output, "\n");
284   fprintf(output, "Preference reports:\n");
285   fprintf(output, "  -G currentprefs          dump current preferences and exit\n");
286   fprintf(output, "  -G defaultprefs          dump default preferences and exit\n");
287   fprintf(output, "\n");
288 }
289
290 /*
291  * For a dissector table, print on the stream described by output,
292  * its short name (which is what's used in the "-d" option) and its
293  * descriptive name.
294  */
295 static void
296 display_dissector_table_names(const char *table_name, const char *ui_name,
297                               gpointer output)
298 {
299   if ((prev_display_dissector_name == NULL) ||
300       (strcmp(prev_display_dissector_name, table_name) != 0)) {
301      fprintf((FILE *)output, "\t%s (%s)\n", table_name, ui_name);
302      prev_display_dissector_name = table_name;
303   }
304 }
305
306 /*
307  * For a dissector handle, print on the stream described by output,
308  * the filter name (which is what's used in the "-d" option) and the full
309  * name for the protocol that corresponds to this handle.
310  */
311 static void
312 display_dissector_names(const gchar *table _U_, gpointer handle, gpointer output)
313 {
314   int          proto_id;
315   const gchar *proto_filter_name;
316   const gchar *proto_ui_name;
317
318   proto_id = dissector_handle_get_protocol_index((dissector_handle_t)handle);
319
320   if (proto_id != -1) {
321     proto_filter_name = proto_get_protocol_filter_name(proto_id);
322     proto_ui_name =  proto_get_protocol_name(proto_id);
323     g_assert(proto_filter_name != NULL);
324     g_assert(proto_ui_name != NULL);
325
326     if ((prev_display_dissector_name == NULL) ||
327         (strcmp(prev_display_dissector_name, proto_filter_name) != 0)) {
328       fprintf((FILE *)output, "\t%s (%s)\n",
329               proto_filter_name,
330               proto_ui_name);
331        prev_display_dissector_name = proto_filter_name;
332     }
333   }
334 }
335
336 /*
337  * The protocol_name_search structure is used by find_protocol_name_func()
338  * to pass parameters and store results
339  */
340 struct protocol_name_search{
341   gchar              *searched_name;  /* Protocol filter name we are looking for */
342   dissector_handle_t  matched_handle; /* Handle for a dissector whose protocol has the specified filter name */
343   guint               nb_match;       /* How many dissectors matched searched_name */
344 };
345 typedef struct protocol_name_search *protocol_name_search_t;
346
347 /*
348  * This function parses all dissectors associated with a table to find the
349  * one whose protocol has the specified filter name.  It is called
350  * as a reference function in a call to dissector_table_foreach_handle.
351  * The name we are looking for, as well as the results, are stored in the
352  * protocol_name_search struct pointed to by user_data.
353  * If called using dissector_table_foreach_handle, we actually parse the
354  * whole list of dissectors.
355  */
356 static void
357 find_protocol_name_func(const gchar *table _U_, gpointer handle, gpointer user_data)
358
359 {
360   int                     proto_id;
361   const gchar            *protocol_filter_name;
362   protocol_name_search_t  search_info;
363
364   g_assert(handle);
365
366   search_info = (protocol_name_search_t)user_data;
367
368   proto_id = dissector_handle_get_protocol_index((dissector_handle_t)handle);
369   if (proto_id != -1) {
370     protocol_filter_name = proto_get_protocol_filter_name(proto_id);
371     g_assert(protocol_filter_name != NULL);
372     if (strcmp(protocol_filter_name, search_info->searched_name) == 0) {
373       /* Found a match */
374       if (search_info->nb_match == 0) {
375         /* Record this handle only if this is the first match */
376         search_info->matched_handle = (dissector_handle_t)handle; /* Record the handle for this matching dissector */
377       }
378       search_info->nb_match++;
379     }
380   }
381 }
382
383 /*
384  * Allow dissector key names to be sorted alphabetically
385  */
386
387 static gint
388 compare_dissector_key_name(gconstpointer dissector_a, gconstpointer dissector_b)
389 {
390   return strcmp((const char*)dissector_a, (const char*)dissector_b);
391 }
392
393 /*
394  * Print all layer type names supported.
395  * We send the output to the stream described by the handle output.
396  */
397
398 static void
399 fprint_all_layer_types(FILE *output)
400
401 {
402   prev_display_dissector_name = NULL;
403   dissector_all_tables_foreach_table(display_dissector_table_names, (gpointer)output, (GCompareFunc)compare_dissector_key_name);
404 }
405
406 /*
407  * Print all protocol names supported for a specific layer type.
408  * table_name contains the layer type name in which the search is performed.
409  * We send the output to the stream described by the handle output.
410  */
411
412 static void
413 fprint_all_protocols_for_layer_types(FILE *output, gchar *table_name)
414
415 {
416   prev_display_dissector_name = NULL;
417   dissector_table_foreach_handle(table_name,
418                                  display_dissector_names,
419                                  (gpointer)output);
420 }
421
422 /*
423  * The function below parses the command-line parameters for the decode as
424  * feature (a string pointer by cl_param).
425  * It checks the format of the command-line, searches for a matching table
426  * and dissector.  If a table/dissector match is not found, we display a
427  * summary of the available tables/dissectors (on stderr) and return FALSE.
428  * If everything is fine, we get the "Decode as" preference activated,
429  * then we return TRUE.
430  */
431 static gboolean
432 add_decode_as(const gchar *cl_param)
433 {
434   gchar                        *table_name;
435   guint32                       selector, selector2;
436   gchar                        *decoded_param;
437   gchar                        *remaining_param;
438   gchar                        *selector_str;
439   gchar                        *dissector_str;
440   dissector_handle_t            dissector_matching;
441   dissector_table_t             table_matching;
442   ftenum_t                      dissector_table_selector_type;
443   struct protocol_name_search   user_protocol_name;
444   guint64                       i;
445   char                          op;
446
447   /* The following code will allocate and copy the command-line options in a string pointed by decoded_param */
448
449   g_assert(cl_param);
450   decoded_param = g_strdup(cl_param);
451   g_assert(decoded_param);
452
453
454   /* The lines below will parse this string (modifying it) to extract all
455     necessary information.  Note that decoded_param is still needed since
456     strings are not copied - we just save pointers. */
457
458   /* This section extracts a layer type (table_name) from decoded_param */
459   table_name = decoded_param; /* Layer type string starts from beginning */
460
461   remaining_param = strchr(table_name, '=');
462   if (remaining_param == NULL) {
463     cmdarg_err("Parameter \"%s\" doesn't follow the template \"%s\"", cl_param, decode_as_arg_template);
464     /* If the argument does not follow the template, carry on anyway to check
465        if the table name is at least correct.  If remaining_param is NULL,
466        we'll exit anyway further down */
467   }
468   else {
469     *remaining_param = '\0'; /* Terminate the layer type string (table_name) where '=' was detected */
470   }
471
472   /* Remove leading and trailing spaces from the table name */
473   while ( table_name[0] == ' ' )
474     table_name++;
475   while ( table_name[strlen(table_name) - 1] == ' ' )
476     table_name[strlen(table_name) - 1] = '\0'; /* Note: if empty string, while loop will eventually exit */
477
478 /* The following part searches a table matching with the layer type specified */
479   table_matching = NULL;
480
481 /* Look for the requested table */
482   if ( !(*(table_name)) ) { /* Is the table name empty, if so, don't even search for anything, display a message */
483     cmdarg_err("No layer type specified"); /* Note, we don't exit here, but table_matching will remain NULL, so we exit below */
484   }
485   else {
486     table_matching = find_dissector_table(table_name);
487     if (!table_matching) {
488       cmdarg_err("Unknown layer type -- %s", table_name); /* Note, we don't exit here, but table_matching will remain NULL, so we exit below */
489     }
490   }
491
492   if (!table_matching) {
493     /* Display a list of supported layer types to help the user, if the
494        specified layer type was not found */
495     cmdarg_err("Valid layer types are:");
496     fprint_all_layer_types(stderr);
497   }
498   if (remaining_param == NULL || !table_matching) {
499     /* Exit if the layer type was not found, or if no '=' separator was found
500        (see above) */
501     g_free(decoded_param);
502     return FALSE;
503   }
504
505   if (*(remaining_param + 1) != '=') { /* Check for "==" and not only '=' */
506     cmdarg_err("WARNING: -d requires \"==\" instead of \"=\". Option will be treated as \"%s==%s\"", table_name, remaining_param + 1);
507   }
508   else {
509     remaining_param++; /* Move to the second '=' */
510     *remaining_param = '\0'; /* Remove the second '=' */
511   }
512   remaining_param++; /* Position after the layer type string */
513
514   /* This section extracts a selector value (selector_str) from decoded_param */
515
516   selector_str = remaining_param; /* Next part starts with the selector number */
517
518   remaining_param = strchr(selector_str, ',');
519   if (remaining_param == NULL) {
520     cmdarg_err("Parameter \"%s\" doesn't follow the template \"%s\"", cl_param, decode_as_arg_template);
521     /* If the argument does not follow the template, carry on anyway to check
522        if the selector value is at least correct.  If remaining_param is NULL,
523        we'll exit anyway further down */
524   }
525   else {
526     *remaining_param = '\0'; /* Terminate the selector number string (selector_str) where ',' was detected */
527   }
528
529   dissector_table_selector_type = get_dissector_table_selector_type(table_name);
530
531   switch (dissector_table_selector_type) {
532
533   case FT_UINT8:
534   case FT_UINT16:
535   case FT_UINT24:
536   case FT_UINT32:
537     /* The selector for this table is an unsigned number.  Parse it as such.
538        There's no need to remove leading and trailing spaces from the
539        selector number string, because sscanf will do that for us. */
540     switch (sscanf(selector_str, "%u%c%u", &selector, &op, &selector2)) {
541       case 1:
542         op = '\0';
543         break;
544       case 3:
545         if (op != ':' && op != '-') {
546             cmdarg_err("Invalid selector numeric range \"%s\"", selector_str);
547             g_free(decoded_param);
548             return FALSE;
549         }
550         if (op == ':') {
551             if ((selector2 == 0) || ((guint64)selector + selector2 - 1) > G_MAXUINT32) {
552                 cmdarg_err("Invalid selector numeric range \"%s\"", selector_str);
553                 g_free(decoded_param);
554                 return FALSE;
555             }
556         }
557         else if (selector2 < selector) {
558             /* We could swap them for the user, but maybe it's better to call
559              * this out as an error in case it's not what was intended? */
560             cmdarg_err("Invalid selector numeric range \"%s\"", selector_str);
561             g_free(decoded_param);
562             return FALSE;
563         }
564         break;
565       default:
566         cmdarg_err("Invalid selector number \"%s\"", selector_str);
567         g_free(decoded_param);
568         return FALSE;
569     }
570     break;
571
572   case FT_STRING:
573   case FT_STRINGZ:
574   case FT_UINT_STRING:
575   case FT_STRINGZPAD:
576     /* The selector for this table is a string. */
577     break;
578
579   default:
580     /* There are currently no dissector tables with any types other
581        than the ones listed above. */
582     g_assert_not_reached();
583   }
584
585   if (remaining_param == NULL) {
586     /* Exit if no ',' separator was found (see above) */
587     cmdarg_err("Valid protocols for layer type \"%s\" are:", table_name);
588     fprint_all_protocols_for_layer_types(stderr, table_name);
589     g_free(decoded_param);
590     return FALSE;
591   }
592
593   remaining_param++; /* Position after the selector number string */
594
595   /* This section extracts a protocol filter name (dissector_str) from decoded_param */
596
597   dissector_str = remaining_param; /* All the rest of the string is the dissector (decode as protocol) name */
598
599   /* Remove leading and trailing spaces from the dissector name */
600   while ( dissector_str[0] == ' ' )
601     dissector_str++;
602   while ( dissector_str[strlen(dissector_str) - 1] == ' ' )
603     dissector_str[strlen(dissector_str) - 1] = '\0'; /* Note: if empty string, while loop will eventually exit */
604
605   dissector_matching = NULL;
606
607   /* We now have a pointer to the handle for the requested table inside the variable table_matching */
608   if ( ! (*dissector_str) ) { /* Is the dissector name empty, if so, don't even search for a matching dissector and display all dissectors found for the selected table */
609     cmdarg_err("No protocol name specified"); /* Note, we don't exit here, but dissector_matching will remain NULL, so we exit below */
610   }
611   else {
612     user_protocol_name.nb_match = 0;
613     user_protocol_name.searched_name = dissector_str;
614     user_protocol_name.matched_handle = NULL;
615
616     dissector_table_foreach_handle(table_name, find_protocol_name_func, &user_protocol_name); /* Go and perform the search for this dissector in the this table's dissectors' names and shortnames */
617
618     if (user_protocol_name.nb_match != 0) {
619       dissector_matching = user_protocol_name.matched_handle;
620       if (user_protocol_name.nb_match > 1) {
621         cmdarg_err("WARNING: Protocol \"%s\" matched %u dissectors, first one will be used", dissector_str, user_protocol_name.nb_match);
622       }
623     }
624     else {
625       /* OK, check whether the problem is that there isn't any such
626          protocol, or that there is but it's not specified as a protocol
627          that's valid for that dissector table.
628          Note, we don't exit here, but dissector_matching will remain NULL,
629          so we exit below */
630       if (proto_get_id_by_filter_name(dissector_str) == -1) {
631         /* No such protocol */
632         cmdarg_err("Unknown protocol -- \"%s\"", dissector_str);
633       } else {
634         cmdarg_err("Protocol \"%s\" isn't valid for layer type \"%s\"",
635                    dissector_str, table_name);
636       }
637     }
638   }
639
640   if (!dissector_matching) {
641     cmdarg_err("Valid protocols for layer type \"%s\" are:", table_name);
642     fprint_all_protocols_for_layer_types(stderr, table_name);
643     g_free(decoded_param);
644     return FALSE;
645   }
646
647 /* This is the end of the code that parses the command-line options.
648    All information is now stored in the variables:
649    table_name
650    selector
651    dissector_matching
652    The above variables that are strings are still pointing to areas within
653    decoded_parm.  decoded_parm thus still needs to be kept allocated in
654    until we stop needing these variables
655    decoded_param will be deallocated at each exit point of this function */
656
657
658   /* We now have a pointer to the handle for the requested dissector
659      (requested protocol) inside the variable dissector_matching */
660   switch (dissector_table_selector_type) {
661
662   case FT_UINT8:
663   case FT_UINT16:
664   case FT_UINT24:
665   case FT_UINT32:
666     /* The selector for this table is an unsigned number. */
667     if (op == '\0') {
668       dissector_change_uint(table_name, selector, dissector_matching);
669     } else if (op == ':') {
670       for (i = selector; i < (guint64)selector + selector2; i++) {
671         dissector_change_uint(table_name, (guint32)i, dissector_matching);
672       }
673     } else { /* op == '-' */
674       for (i = selector; i <= selector2; i++) {
675         dissector_change_uint(table_name, (guint32)i, dissector_matching);
676       }
677     }
678     break;
679
680   case FT_STRING:
681   case FT_STRINGZ:
682   case FT_UINT_STRING:
683   case FT_STRINGZPAD:
684     /* The selector for this table is a string. */
685     dissector_change_string(table_name, selector_str, dissector_matching);
686     break;
687
688   default:
689     /* There are currently no dissector tables with any types other
690        than the ones listed above. */
691     g_assert_not_reached();
692   }
693   g_free(decoded_param); /* "Decode As" rule has been successfully added */
694   return TRUE;
695 }
696
697 static void
698 tfshark_log_handler (const gchar *log_domain, GLogLevelFlags log_level,
699     const gchar *message, gpointer user_data)
700 {
701   /* ignore log message, if log_level isn't interesting based
702      upon the console log preferences.
703      If the preferences haven't been loaded loaded yet, display the
704      message anyway.
705
706      The default console_log_level preference value is such that only
707        ERROR, CRITICAL and WARNING level messages are processed;
708        MESSAGE, INFO and DEBUG level messages are ignored.
709
710      XXX: Aug 07, 2009: Prior tshark g_log code was hardwired to process only
711            ERROR and CRITICAL level messages so the current code is a behavioral
712            change.  The current behavior is the same as in Wireshark.
713   */
714   if ((log_level & G_LOG_LEVEL_MASK & prefs.console_log_level) == 0 &&
715      prefs.console_log_level != 0) {
716     return;
717   }
718
719   g_log_default_handler(log_domain, log_level, message, user_data);
720
721 }
722
723 static void
724 print_current_user(void) {
725   gchar *cur_user, *cur_group;
726
727   if (started_with_special_privs()) {
728     cur_user = get_cur_username();
729     cur_group = get_cur_groupname();
730     fprintf(stderr, "Running as user \"%s\" and group \"%s\".",
731       cur_user, cur_group);
732     g_free(cur_user);
733     g_free(cur_group);
734     if (running_with_special_privs()) {
735       fprintf(stderr, " This could be dangerous.");
736     }
737     fprintf(stderr, "\n");
738   }
739 }
740
741 static void
742 get_tfshark_compiled_version_info(GString *str)
743 {
744   /* LIBZ */
745 #ifdef HAVE_LIBZ
746   g_string_append(str, "with libz ");
747 #ifdef ZLIB_VERSION
748   g_string_append(str, ZLIB_VERSION);
749 #else /* ZLIB_VERSION */
750   g_string_append(str, "(version unknown)");
751 #endif /* ZLIB_VERSION */
752 #else /* HAVE_LIBZ */
753   g_string_append(str, "without libz");
754 #endif /* HAVE_LIBZ */
755 }
756
757 static void
758 get_tfshark_runtime_version_info(GString *str)
759 {
760   /* zlib */
761 #if defined(HAVE_LIBZ) && !defined(_WIN32)
762   g_string_append_printf(str, ", with libz %s", zlibVersion());
763 #endif
764
765   /* stuff used by libwireshark */
766   epan_get_runtime_version_info(str);
767 }
768
769 int
770 main(int argc, char *argv[])
771 {
772   GString             *comp_info_str;
773   GString             *runtime_info_str;
774   char                *init_progfile_dir_error;
775   int                  opt;
776 DIAG_OFF(cast-qual)
777   static const struct option long_options[] = {
778     {(char *)"help", no_argument, NULL, 'h'},
779     {(char *)"version", no_argument, NULL, 'v'},
780     {0, 0, 0, 0 }
781   };
782 DIAG_ON(cast-qual)
783   gboolean             arg_error = FALSE;
784
785   char                *gpf_path, *pf_path;
786   char                *gdp_path, *dp_path;
787   int                  gpf_open_errno, gpf_read_errno;
788   int                  pf_open_errno, pf_read_errno;
789   int                  gdp_open_errno, gdp_read_errno;
790   int                  dp_open_errno, dp_read_errno;
791   int                  err;
792   volatile int         exit_status = 0;
793   gboolean             quiet = FALSE;
794   gchar               *volatile cf_name = NULL;
795   gchar               *rfilter = NULL;
796   gchar               *dfilter = NULL;
797   dfilter_t           *rfcode = NULL;
798   dfilter_t           *dfcode = NULL;
799   gchar               *err_msg;
800   e_prefs             *prefs_p;
801   int                  log_flags;
802   gchar               *output_only = NULL;
803
804 /*
805  * The leading + ensures that getopt_long() does not permute the argv[]
806  * entries.
807  *
808  * We have to make sure that the first getopt_long() preserves the content
809  * of argv[] for the subsequent getopt_long() call.
810  *
811  * We use getopt_long() in both cases to ensure that we're using a routine
812  * whose permutation behavior we can control in the same fashion on all
813  * platforms, and so that, if we ever need to process a long argument before
814  * doing further initialization, we can do so.
815  *
816  * Glibc and Solaris libc document that a leading + disables permutation
817  * of options, regardless of whether POSIXLY_CORRECT is set or not; *BSD
818  * and OS X don't document it, but do so anyway.
819  *
820  * We do *not* use a leading - because the behavior of a leading - is
821  * platform-dependent.
822  */
823 #define OPTSTRING "+2C:d:e:E:hK:lo:O:qQr:R:S:t:T:u:vVxX:Y:z:"
824
825   static const char    optstring[] = OPTSTRING;
826
827   /* Set the C-language locale to the native environment. */
828   setlocale(LC_ALL, "");
829
830   cmdarg_err_init(failure_message, failure_message_cont);
831
832 #ifdef _WIN32
833   arg_list_utf_16to8(argc, argv);
834   create_app_running_mutex();
835 #if !GLIB_CHECK_VERSION(2,31,0)
836   g_thread_init(NULL);
837 #endif
838 #endif /* _WIN32 */
839
840   /*
841    * Get credential information for later use, and drop privileges
842    * before doing anything else.
843    * Let the user know if anything happened.
844    */
845   init_process_policies();
846   relinquish_special_privs_perm();
847   print_current_user();
848
849   /*
850    * Attempt to get the pathname of the executable file.
851    */
852   init_progfile_dir_error = init_progfile_dir(argv[0], (void *)main);
853   if (init_progfile_dir_error != NULL) {
854     fprintf(stderr, "tfshark: Can't get pathname of tfshark program: %s.\n",
855             init_progfile_dir_error);
856   }
857
858   initialize_funnel_ops();
859
860   /* Get the compile-time version information string */
861   comp_info_str = get_compiled_version_info(get_tfshark_compiled_version_info,
862                                             epan_get_compiled_version_info);
863
864   /* Get the run-time version information string */
865   runtime_info_str = get_runtime_version_info(get_tfshark_runtime_version_info);
866
867   /* Add it to the information to be reported on a crash. */
868   ws_add_crash_info("TFShark (Wireshark) %s\n"
869          "\n"
870          "%s"
871          "\n"
872          "%s",
873       get_ws_vcs_version_info(), comp_info_str->str, runtime_info_str->str);
874
875   /*
876    * In order to have the -X opts assigned before the wslua machine starts
877    * we need to call getopts before epan_init() gets called.
878    *
879    * In order to handle, for example, -o options, we also need to call it
880    * *after* epan_init() gets called, so that the dissectors have had a
881    * chance to register their preferences.
882    *
883    * XXX - can we do this all with one getopt_long() call, saving the
884    * arguments we can't handle until after initializing libwireshark,
885    * and then process them after initializing libwireshark?
886    */
887   opterr = 0;
888
889   while ((opt = getopt_long(argc, argv, optstring, long_options, NULL)) != -1) {
890     switch (opt) {
891     case 'C':        /* Configuration Profile */
892       if (profile_exists (optarg, FALSE)) {
893         set_profile_name (optarg);
894       } else {
895         cmdarg_err("Configuration Profile \"%s\" does not exist", optarg);
896         return 1;
897       }
898       break;
899     case 'O':        /* Only output these protocols */
900       output_only = g_strdup(optarg);
901       /* FALLTHROUGH */
902     case 'V':        /* Verbose */
903       print_details = TRUE;
904       print_packet_info = TRUE;
905       break;
906     case 'x':        /* Print packet data in hex (and ASCII) */
907       print_hex = TRUE;
908       /*  The user asked for hex output, so let's ensure they get it,
909        *  even if they're writing to a file.
910        */
911       print_packet_info = TRUE;
912       break;
913     case 'X':
914       ex_opt_add(optarg);
915       break;
916     default:
917       break;
918     }
919   }
920
921   /*
922    * Print packet summary information is the default, unless either -V or -x
923    * were specified.  Note that this is new behavior, which
924    * allows for the possibility of printing only hex/ascii output without
925    * necessarily requiring that either the summary or details be printed too.
926    */
927   if (print_summary == -1)
928     print_summary = (print_details || print_hex) ? FALSE : TRUE;
929
930 /** Send All g_log messages to our own handler **/
931
932   log_flags =
933                     G_LOG_LEVEL_ERROR|
934                     G_LOG_LEVEL_CRITICAL|
935                     G_LOG_LEVEL_WARNING|
936                     G_LOG_LEVEL_MESSAGE|
937                     G_LOG_LEVEL_INFO|
938                     G_LOG_LEVEL_DEBUG|
939                     G_LOG_FLAG_FATAL|G_LOG_FLAG_RECURSION;
940
941   g_log_set_handler(NULL,
942                     (GLogLevelFlags)log_flags,
943                     tfshark_log_handler, NULL /* user_data */);
944   g_log_set_handler(LOG_DOMAIN_MAIN,
945                     (GLogLevelFlags)log_flags,
946                     tfshark_log_handler, NULL /* user_data */);
947
948   init_report_err(failure_message, open_failure_message, read_failure_message,
949                   write_failure_message);
950
951   timestamp_set_type(TS_RELATIVE);
952   timestamp_set_precision(TS_PREC_AUTO);
953   timestamp_set_seconds_type(TS_SECONDS_DEFAULT);
954
955   init_open_routines();
956
957 #ifdef HAVE_PLUGINS
958   /* Register all the plugin types we have. */
959   epan_register_plugin_types(); /* Types known to libwireshark */
960
961   /* Scan for plugins.  This does *not* call their registration routines;
962      that's done later. */
963   scan_plugins();
964
965 #endif
966
967   /* Register all dissectors; we must do this before checking for the
968      "-G" flag, as the "-G" flag dumps information registered by the
969      dissectors, and we must do it before we read the preferences, in
970      case any dissectors register preferences. */
971   epan_init(register_all_protocols, register_all_protocol_handoffs, NULL, NULL);
972
973   /* Register all tap listeners; we do this before we parse the arguments,
974      as the "-z" argument can specify a registered tap. */
975
976   /* we register the plugin taps before the other taps because
977      stats_tree taps plugins will be registered as tap listeners
978      by stats_tree_stat.c and need to registered before that */
979
980   /* XXX Disable tap registration for now until we can get tfshark set up with
981    * its own set of taps and the necessary registration function etc.
982 #ifdef HAVE_PLUGINS
983   register_all_plugin_tap_listeners();
984 #endif
985   register_all_tap_listeners();
986   */
987
988   /* If invoked with the "-G" flag, we dump out information based on
989      the argument to the "-G" flag; if no argument is specified,
990      for backwards compatibility we dump out a glossary of display
991      filter symbols.
992
993      XXX - we do this here, for now, to support "-G" with no arguments.
994      If none of our build or other processes uses "-G" with no arguments,
995      we can just process it with the other arguments. */
996   if (argc >= 2 && strcmp(argv[1], "-G") == 0) {
997     proto_initialize_all_prefixes();
998
999     if (argc == 2)
1000       proto_registrar_dump_fields();
1001     else {
1002       if (strcmp(argv[2], "column-formats") == 0)
1003         column_dump_column_formats();
1004       else if (strcmp(argv[2], "currentprefs") == 0) {
1005         read_prefs(&gpf_open_errno, &gpf_read_errno, &gpf_path,
1006             &pf_open_errno, &pf_read_errno, &pf_path);
1007         write_prefs(NULL);
1008       }
1009       else if (strcmp(argv[2], "decodes") == 0)
1010         dissector_dump_decodes();
1011       else if (strcmp(argv[2], "defaultprefs") == 0)
1012         write_prefs(NULL);
1013       else if (strcmp(argv[2], "dissector-tables") == 0)
1014         dissector_dump_dissector_tables();
1015       else if (strcmp(argv[2], "fields") == 0)
1016         proto_registrar_dump_fields();
1017       else if (strcmp(argv[2], "ftypes") == 0)
1018         proto_registrar_dump_ftypes();
1019       else if (strcmp(argv[2], "heuristic-decodes") == 0)
1020         dissector_dump_heur_decodes();
1021       else if (strcmp(argv[2], "plugins") == 0) {
1022 #ifdef HAVE_PLUGINS
1023         plugins_dump_all();
1024 #endif
1025 #ifdef HAVE_LUA
1026         wslua_plugins_dump_all();
1027 #endif
1028       }
1029       else if (strcmp(argv[2], "protocols") == 0)
1030         proto_registrar_dump_protocols();
1031       else if (strcmp(argv[2], "values") == 0)
1032         proto_registrar_dump_values();
1033       else if (strcmp(argv[2], "?") == 0)
1034         glossary_option_help();
1035       else if (strcmp(argv[2], "-?") == 0)
1036         glossary_option_help();
1037       else {
1038         cmdarg_err("Invalid \"%s\" option for -G flag, enter -G ? for more help.", argv[2]);
1039         return 1;
1040       }
1041     }
1042     return 0;
1043   }
1044
1045   prefs_p = read_prefs(&gpf_open_errno, &gpf_read_errno, &gpf_path,
1046                      &pf_open_errno, &pf_read_errno, &pf_path);
1047   if (gpf_path != NULL) {
1048     if (gpf_open_errno != 0) {
1049       cmdarg_err("Can't open global preferences file \"%s\": %s.",
1050               pf_path, g_strerror(gpf_open_errno));
1051     }
1052     if (gpf_read_errno != 0) {
1053       cmdarg_err("I/O error reading global preferences file \"%s\": %s.",
1054               pf_path, g_strerror(gpf_read_errno));
1055     }
1056   }
1057   if (pf_path != NULL) {
1058     if (pf_open_errno != 0) {
1059       cmdarg_err("Can't open your preferences file \"%s\": %s.", pf_path,
1060               g_strerror(pf_open_errno));
1061     }
1062     if (pf_read_errno != 0) {
1063       cmdarg_err("I/O error reading your preferences file \"%s\": %s.",
1064               pf_path, g_strerror(pf_read_errno));
1065     }
1066     g_free(pf_path);
1067     pf_path = NULL;
1068   }
1069
1070   /* Read the disabled protocols file. */
1071   read_disabled_protos_list(&gdp_path, &gdp_open_errno, &gdp_read_errno,
1072                             &dp_path, &dp_open_errno, &dp_read_errno);
1073   read_disabled_heur_dissector_list(&gdp_path, &gdp_open_errno, &gdp_read_errno,
1074                             &dp_path, &dp_open_errno, &dp_read_errno);
1075   if (gdp_path != NULL) {
1076     if (gdp_open_errno != 0) {
1077       cmdarg_err("Could not open global disabled protocols file\n\"%s\": %s.",
1078                  gdp_path, g_strerror(gdp_open_errno));
1079     }
1080     if (gdp_read_errno != 0) {
1081       cmdarg_err("I/O error reading global disabled protocols file\n\"%s\": %s.",
1082                  gdp_path, g_strerror(gdp_read_errno));
1083     }
1084     g_free(gdp_path);
1085   }
1086   if (dp_path != NULL) {
1087     if (dp_open_errno != 0) {
1088       cmdarg_err(
1089         "Could not open your disabled protocols file\n\"%s\": %s.", dp_path,
1090         g_strerror(dp_open_errno));
1091     }
1092     if (dp_read_errno != 0) {
1093       cmdarg_err(
1094         "I/O error reading your disabled protocols file\n\"%s\": %s.", dp_path,
1095         g_strerror(dp_read_errno));
1096     }
1097     g_free(dp_path);
1098   }
1099
1100   cap_file_init(&cfile);
1101
1102   /* Print format defaults to this. */
1103   print_format = PR_FMT_TEXT;
1104
1105   output_fields = output_fields_new();
1106
1107   /*
1108    * To reset the options parser, set optreset to 1 on platforms that
1109    * have optreset (documented in *BSD and OS X, apparently present but
1110    * not documented in Solaris - the Illumos repository seems to
1111    * suggest that the first Solaris getopt_long(), at least as of 2004,
1112    * was based on the NetBSD one, it had optreset) and set optind to 1,
1113    * and set optind to 0 otherwise (documented as working in the GNU
1114    * getopt_long().  Setting optind to 0 didn't originally work in the
1115    * NetBSD one, but that was added later - we don't want to depend on
1116    * it if we have optreset).
1117    *
1118    * Also reset opterr to 1, so that error messages are printed by
1119    * getopt_long().
1120    */
1121 #ifdef HAVE_OPTRESET
1122   optreset = 1;
1123   optind = 1;
1124 #else
1125   optind = 0;
1126 #endif
1127   opterr = 1;
1128
1129   /* Now get our args */
1130   while ((opt = getopt_long(argc, argv, optstring, long_options, NULL)) != -1) {
1131     switch (opt) {
1132     case '2':        /* Perform two pass analysis */
1133       perform_two_pass_analysis = TRUE;
1134       break;
1135     case 'C':
1136       /* already processed; just ignore it now */
1137       break;
1138     case 'd':        /* Decode as rule */
1139       if (!add_decode_as(optarg))
1140         return 1;
1141       break;
1142 #if defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS)
1143     case 'K':        /* Kerberos keytab file */
1144       read_keytab_file(optarg);
1145       break;
1146 #endif
1147     case 'e':
1148       /* Field entry */
1149       output_fields_add(output_fields, optarg);
1150       break;
1151     case 'E':
1152       /* Field option */
1153       if (!output_fields_set_option(output_fields, optarg)) {
1154         cmdarg_err("\"%s\" is not a valid field output option=value pair.", optarg);
1155         output_fields_list_options(stderr);
1156         return 1;
1157       }
1158       break;
1159
1160     case 'h':        /* Print help and exit */
1161       printf("TFShark (Wireshark) %s\n"
1162              "Dump and analyze network traffic.\n"
1163              "See https://www.wireshark.org for more information.\n",
1164              get_ws_vcs_version_info());
1165       print_usage(stdout);
1166       return 0;
1167       break;
1168     case 'l':        /* "Line-buffer" standard output */
1169       /* This isn't line-buffering, strictly speaking, it's just
1170          flushing the standard output after the information for
1171          each packet is printed; however, that should be good
1172          enough for all the purposes to which "-l" is put (and
1173          is probably actually better for "-V", as it does fewer
1174          writes).
1175
1176          See the comment in "process_packet()" for an explanation of
1177          why we do that, and why we don't just use "setvbuf()" to
1178          make the standard output line-buffered (short version: in
1179          Windows, "line-buffered" is the same as "fully-buffered",
1180          and the output buffer is only flushed when it fills up). */
1181       line_buffered = TRUE;
1182       break;
1183     case 'o':        /* Override preference from command line */
1184       switch (prefs_set_pref(optarg)) {
1185
1186       case PREFS_SET_OK:
1187         break;
1188
1189       case PREFS_SET_SYNTAX_ERR:
1190         cmdarg_err("Invalid -o flag \"%s\"", optarg);
1191         return 1;
1192         break;
1193
1194       case PREFS_SET_NO_SUCH_PREF:
1195       case PREFS_SET_OBSOLETE:
1196         cmdarg_err("-o flag \"%s\" specifies unknown preference", optarg);
1197         return 1;
1198         break;
1199       }
1200       break;
1201     case 'q':        /* Quiet */
1202       quiet = TRUE;
1203       break;
1204     case 'Q':        /* Really quiet */
1205       quiet = TRUE;
1206       really_quiet = TRUE;
1207       break;
1208     case 'r':        /* Read capture file x */
1209       cf_name = g_strdup(optarg);
1210       break;
1211     case 'R':        /* Read file filter */
1212       rfilter = optarg;
1213       break;
1214     case 'S':        /* Set the line Separator to be printed between packets */
1215       separator = g_strdup(optarg);
1216       break;
1217     case 't':        /* Time stamp type */
1218       if (strcmp(optarg, "r") == 0)
1219         timestamp_set_type(TS_RELATIVE);
1220       else if (strcmp(optarg, "a") == 0)
1221         timestamp_set_type(TS_ABSOLUTE);
1222       else if (strcmp(optarg, "ad") == 0)
1223         timestamp_set_type(TS_ABSOLUTE_WITH_YMD);
1224       else if (strcmp(optarg, "adoy") == 0)
1225         timestamp_set_type(TS_ABSOLUTE_WITH_YDOY);
1226       else if (strcmp(optarg, "d") == 0)
1227         timestamp_set_type(TS_DELTA);
1228       else if (strcmp(optarg, "dd") == 0)
1229         timestamp_set_type(TS_DELTA_DIS);
1230       else if (strcmp(optarg, "e") == 0)
1231         timestamp_set_type(TS_EPOCH);
1232       else if (strcmp(optarg, "u") == 0)
1233         timestamp_set_type(TS_UTC);
1234       else if (strcmp(optarg, "ud") == 0)
1235         timestamp_set_type(TS_UTC_WITH_YMD);
1236       else if (strcmp(optarg, "udoy") == 0)
1237         timestamp_set_type(TS_UTC_WITH_YDOY);
1238       else {
1239         cmdarg_err("Invalid time stamp type \"%s\"; it must be one of:", optarg);
1240         cmdarg_err_cont("\t\"a\"    for absolute\n"
1241                         "\t\"ad\"   for absolute with YYYY-MM-DD date\n"
1242                         "\t\"adoy\" for absolute with YYYY/DOY date\n"
1243                         "\t\"d\"    for delta\n"
1244                         "\t\"dd\"   for delta displayed\n"
1245                         "\t\"e\"    for epoch\n"
1246                         "\t\"r\"    for relative\n"
1247                         "\t\"u\"    for absolute UTC\n"
1248                         "\t\"ud\"   for absolute UTC with YYYY-MM-DD date\n"
1249                         "\t\"udoy\" for absolute UTC with YYYY/DOY date");
1250         return 1;
1251       }
1252       break;
1253     case 'T':        /* printing Type */
1254       if (strcmp(optarg, "text") == 0) {
1255         output_action = WRITE_TEXT;
1256         print_format = PR_FMT_TEXT;
1257       } else if (strcmp(optarg, "ps") == 0) {
1258         output_action = WRITE_TEXT;
1259         print_format = PR_FMT_PS;
1260       } else if (strcmp(optarg, "pdml") == 0) {
1261         output_action = WRITE_XML;
1262         print_details = TRUE;   /* Need details */
1263         print_summary = FALSE;  /* Don't allow summary */
1264       } else if (strcmp(optarg, "psml") == 0) {
1265         output_action = WRITE_XML;
1266         print_details = FALSE;  /* Don't allow details */
1267         print_summary = TRUE;   /* Need summary */
1268       } else if (strcmp(optarg, "fields") == 0) {
1269         output_action = WRITE_FIELDS;
1270         print_details = TRUE;   /* Need full tree info */
1271         print_summary = FALSE;  /* Don't allow summary */
1272       } else {
1273         cmdarg_err("Invalid -T parameter \"%s\"; it must be one of:", optarg);                   /* x */
1274         cmdarg_err_cont("\t\"fields\" The values of fields specified with the -e option, in a form\n"
1275                         "\t         specified by the -E option.\n"
1276                         "\t\"pdml\"   Packet Details Markup Language, an XML-based format for the\n"
1277                         "\t         details of a decoded packet. This information is equivalent to\n"
1278                         "\t         the packet details printed with the -V flag.\n"
1279                         "\t\"ps\"     PostScript for a human-readable one-line summary of each of\n"
1280                         "\t         the packets, or a multi-line view of the details of each of\n"
1281                         "\t         the packets, depending on whether the -V flag was specified.\n"
1282                         "\t\"psml\"   Packet Summary Markup Language, an XML-based format for the\n"
1283                         "\t         summary information of a decoded packet. This information is\n"
1284                         "\t         equivalent to the information shown in the one-line summary\n"
1285                         "\t         printed by default.\n"
1286                         "\t\"text\"   Text of a human-readable one-line summary of each of the\n"
1287                         "\t         packets, or a multi-line view of the details of each of the\n"
1288                         "\t         packets, depending on whether the -V flag was specified.\n"
1289                         "\t         This is the default.");
1290         return 1;
1291       }
1292       break;
1293     case 'u':        /* Seconds type */
1294       if (strcmp(optarg, "s") == 0)
1295         timestamp_set_seconds_type(TS_SECONDS_DEFAULT);
1296       else if (strcmp(optarg, "hms") == 0)
1297         timestamp_set_seconds_type(TS_SECONDS_HOUR_MIN_SEC);
1298       else {
1299         cmdarg_err("Invalid seconds type \"%s\"; it must be one of:", optarg);
1300         cmdarg_err_cont("\t\"s\"   for seconds\n"
1301                         "\t\"hms\" for hours, minutes and seconds");
1302         return 1;
1303       }
1304       break;
1305     case 'v':         /* Show version and exit */
1306     {
1307       show_version("TFShark (Wireshark)", comp_info_str, runtime_info_str);
1308       g_string_free(comp_info_str, TRUE);
1309       g_string_free(runtime_info_str, TRUE);
1310       /* We don't really have to cleanup here, but it's a convenient way to test
1311        * start-up and shut-down of the epan library without any UI-specific
1312        * cruft getting in the way. Makes the results of running
1313        * $ ./tools/valgrind-wireshark -n
1314        * much more useful. */
1315       epan_cleanup();
1316       return 0;
1317     }
1318     case 'O':        /* Only output these protocols */
1319       /* already processed; just ignore it now */
1320       break;
1321     case 'V':        /* Verbose */
1322       /* already processed; just ignore it now */
1323       break;
1324     case 'x':        /* Print packet data in hex (and ASCII) */
1325       /* already processed; just ignore it now */
1326       break;
1327     case 'X':
1328       /* already processed; just ignore it now */
1329       break;
1330     case 'Y':
1331       dfilter = optarg;
1332       break;
1333     case 'z':
1334       /* We won't call the init function for the stat this soon
1335          as it would disallow MATE's fields (which are registered
1336          by the preferences set callback) from being used as
1337          part of a tap filter.  Instead, we just add the argument
1338          to a list of stat arguments. */
1339       if (strcmp("help", optarg) == 0) {
1340         fprintf(stderr, "tfshark: The available statistics for the \"-z\" option are:\n");
1341         list_stat_cmd_args();
1342         return 0;
1343       }
1344       if (!process_stat_cmd_arg(optarg)) {
1345         cmdarg_err("Invalid -z argument \"%s\"; it must be one of:", optarg);
1346         list_stat_cmd_args();
1347         return 1;
1348       }
1349       break;
1350     default:
1351     case '?':        /* Bad flag - print usage message */
1352       print_usage(stderr);
1353       return 1;
1354       break;
1355     }
1356   }
1357
1358   /* If we specified output fields, but not the output field type... */
1359   if (WRITE_FIELDS != output_action && 0 != output_fields_num_fields(output_fields)) {
1360         cmdarg_err("Output fields were specified with \"-e\", "
1361             "but \"-Tfields\" was not specified.");
1362         return 1;
1363   } else if (WRITE_FIELDS == output_action && 0 == output_fields_num_fields(output_fields)) {
1364         cmdarg_err("\"-Tfields\" was specified, but no fields were "
1365                     "specified with \"-e\".");
1366
1367         return 1;
1368   }
1369
1370   /* If no capture filter or display filter has been specified, and there are
1371      still command-line arguments, treat them as the tokens of a capture
1372      filter (if no "-r" flag was specified) or a display filter (if a "-r"
1373      flag was specified. */
1374   if (optind < argc) {
1375     if (cf_name != NULL) {
1376       if (dfilter != NULL) {
1377         cmdarg_err("Display filters were specified both with \"-d\" "
1378             "and with additional command-line arguments.");
1379         return 1;
1380       }
1381       dfilter = get_args_as_string(argc, argv, optind);
1382     }
1383   }
1384
1385   /* if "-q" wasn't specified, we should print packet information */
1386   if (!quiet)
1387     print_packet_info = TRUE;
1388
1389   if (arg_error) {
1390     print_usage(stderr);
1391     return 1;
1392   }
1393
1394   if (print_hex) {
1395     if (output_action != WRITE_TEXT) {
1396       cmdarg_err("Raw packet hex data can only be printed as text or PostScript");
1397       return 1;
1398     }
1399   }
1400
1401   if (output_only != NULL) {
1402     char *ps;
1403
1404     if (!print_details) {
1405       cmdarg_err("-O requires -V");
1406       return 1;
1407     }
1408
1409     output_only_tables = g_hash_table_new (g_str_hash, g_str_equal);
1410     for (ps = strtok (output_only, ","); ps; ps = strtok (NULL, ",")) {
1411       g_hash_table_insert(output_only_tables, (gpointer)ps, (gpointer)ps);
1412     }
1413   }
1414
1415   if (rfilter != NULL && !perform_two_pass_analysis) {
1416     cmdarg_err("-R without -2 is deprecated. For single-pass filtering use -Y.");
1417     return 1;
1418   }
1419
1420   /* Notify all registered modules that have had any of their preferences
1421      changed either from one of the preferences file or from the command
1422      line that their preferences have changed. */
1423   prefs_apply_all();
1424
1425   /* At this point MATE will have registered its field array so we can
1426      have a tap filter with one of MATE's late-registered fields as part
1427      of the filter.  We can now process all the "-z" arguments. */
1428   start_requested_stats();
1429
1430   /* disabled protocols as per configuration file */
1431   if (gdp_path == NULL && dp_path == NULL) {
1432     set_disabled_protos_list();
1433     set_disabled_heur_dissector_list();
1434   }
1435
1436   /* Build the column format array */
1437   build_column_format_array(&cfile.cinfo, prefs_p->num_cols, TRUE);
1438
1439   if (rfilter != NULL) {
1440     if (!dfilter_compile(rfilter, &rfcode, &err_msg)) {
1441       cmdarg_err("%s", err_msg);
1442       g_free(err_msg);
1443       epan_cleanup();
1444       return 2;
1445     }
1446   }
1447   cfile.rfcode = rfcode;
1448
1449   if (dfilter != NULL) {
1450     if (!dfilter_compile(dfilter, &dfcode, &err_msg)) {
1451       cmdarg_err("%s", err_msg);
1452       g_free(err_msg);
1453       epan_cleanup();
1454       return 2;
1455     }
1456   }
1457   cfile.dfcode = dfcode;
1458
1459   if (print_packet_info) {
1460     /* If we're printing as text or PostScript, we have
1461        to create a print stream. */
1462     if (output_action == WRITE_TEXT) {
1463       switch (print_format) {
1464
1465       case PR_FMT_TEXT:
1466         print_stream = print_stream_text_stdio_new(stdout);
1467         break;
1468
1469       case PR_FMT_PS:
1470         print_stream = print_stream_ps_stdio_new(stdout);
1471         break;
1472
1473       default:
1474         g_assert_not_reached();
1475       }
1476     }
1477   }
1478
1479   /* We have to dissect each packet if:
1480
1481         we're printing information about each packet;
1482
1483         we're using a read filter on the packets;
1484
1485         we're using a display filter on the packets;
1486
1487         we're using any taps that need dissection. */
1488   do_dissection = print_packet_info || rfcode || dfcode || tap_listeners_require_dissection();
1489
1490   if (cf_name) {
1491     /*
1492      * We're reading a capture file.
1493      */
1494
1495     /* TODO: if tfshark is ever changed to give the user a choice of which
1496        open_routine reader to use, then the following needs to change. */
1497     if (cf_open(&cfile, cf_name, WTAP_TYPE_AUTO, FALSE, &err) != CF_OK) {
1498       epan_cleanup();
1499       return 2;
1500     }
1501
1502     /* Process the packets in the file */
1503     TRY {
1504       /* XXX - for now there is only 1 packet */
1505       err = load_cap_file(&cfile, 1, 0);
1506     }
1507     CATCH(OutOfMemoryError) {
1508       fprintf(stderr,
1509               "Out Of Memory!\n"
1510               "\n"
1511               "Sorry, but TFShark has to terminate now!\n"
1512               "\n"
1513               "Some infos / workarounds can be found at:\n"
1514               "https://wiki.wireshark.org/KnownBugs/OutOfMemory\n");
1515       err = ENOMEM;
1516     }
1517     ENDTRY;
1518
1519     if (err != 0) {
1520       /* We still dump out the results of taps, etc., as we might have
1521          read some packets; however, we exit with an error status. */
1522       exit_status = 2;
1523     }
1524   }
1525
1526   g_free(cf_name);
1527
1528   if (cfile.frames != NULL) {
1529     free_frame_data_sequence(cfile.frames);
1530     cfile.frames = NULL;
1531   }
1532
1533   draw_tap_listeners(TRUE);
1534   funnel_dump_all_text_windows();
1535   epan_free(cfile.epan);
1536   epan_cleanup();
1537
1538   output_fields_free(output_fields);
1539   output_fields = NULL;
1540
1541   return exit_status;
1542 }
1543
1544 static const nstime_t *
1545 tfshark_get_frame_ts(void *data, guint32 frame_num)
1546 {
1547   capture_file *cf = (capture_file *) data;
1548
1549   if (ref && ref->num == frame_num)
1550     return &ref->abs_ts;
1551
1552   if (prev_dis && prev_dis->num == frame_num)
1553     return &prev_dis->abs_ts;
1554
1555   if (prev_cap && prev_cap->num == frame_num)
1556     return &prev_cap->abs_ts;
1557
1558   if (cf->frames) {
1559      frame_data *fd = frame_data_sequence_find(cf->frames, frame_num);
1560
1561      return (fd) ? &fd->abs_ts : NULL;
1562   }
1563
1564   return NULL;
1565 }
1566
1567 static const char *
1568 no_interface_name(void *data _U_, guint32 interface_id _U_)
1569 {
1570     return "";
1571 }
1572
1573 static epan_t *
1574 tfshark_epan_new(capture_file *cf)
1575 {
1576   epan_t *epan = epan_new();
1577
1578   epan->data = cf;
1579   epan->get_frame_ts = tfshark_get_frame_ts;
1580   epan->get_interface_name = no_interface_name;
1581   epan->get_user_comment = NULL;
1582
1583   return epan;
1584 }
1585
1586 static gboolean
1587 process_packet_first_pass(capture_file *cf, epan_dissect_t *edt,
1588                gint64 offset, struct wtap_pkthdr *whdr,
1589                const guchar *pd)
1590 {
1591   frame_data     fdlocal;
1592   guint32        framenum;
1593   gboolean       passed;
1594
1595   /* The frame number of this packet is one more than the count of
1596      frames in this packet. */
1597   framenum = cf->count + 1;
1598
1599   /* If we're not running a display filter and we're not printing any
1600      packet information, we don't need to do a dissection. This means
1601      that all packets can be marked as 'passed'. */
1602   passed = TRUE;
1603
1604   frame_data_init(&fdlocal, framenum, whdr, offset, cum_bytes);
1605
1606   /* If we're going to print packet information, or we're going to
1607      run a read filter, or display filter, or we're going to process taps, set up to
1608      do a dissection and do so. */
1609   if (edt) {
1610     /* If we're running a read filter, prime the epan_dissect_t with that
1611        filter. */
1612     if (cf->rfcode)
1613       epan_dissect_prime_dfilter(edt, cf->rfcode);
1614
1615     frame_data_set_before_dissect(&fdlocal, &cf->elapsed_time,
1616                                   &ref, prev_dis);
1617     if (ref == &fdlocal) {
1618       ref_frame = fdlocal;
1619       ref = &ref_frame;
1620     }
1621
1622     epan_dissect_file_run(edt, whdr, file_tvbuff_new(&fdlocal, pd), &fdlocal, NULL);
1623
1624     /* Run the read filter if we have one. */
1625     if (cf->rfcode)
1626       passed = dfilter_apply_edt(cf->rfcode, edt);
1627   }
1628
1629   if (passed) {
1630     frame_data_set_after_dissect(&fdlocal, &cum_bytes);
1631     prev_cap = prev_dis = frame_data_sequence_add(cf->frames, &fdlocal);
1632
1633     /* If we're not doing dissection then there won't be any dependent frames.
1634      * More importantly, edt.pi.dependent_frames won't be initialized because
1635      * epan hasn't been initialized.
1636      */
1637     if (edt) {
1638       g_slist_foreach(edt->pi.dependent_frames, find_and_mark_frame_depended_upon, cf->frames);
1639     }
1640
1641     cf->count++;
1642   } else {
1643     /* if we don't add it to the frame_data_sequence, clean it up right now
1644      * to avoid leaks */
1645     frame_data_destroy(&fdlocal);
1646   }
1647
1648   if (edt)
1649     epan_dissect_reset(edt);
1650
1651   return passed;
1652 }
1653
1654 static gboolean
1655 process_packet_second_pass(capture_file *cf, epan_dissect_t *edt, frame_data *fdata,
1656                struct wtap_pkthdr *phdr, Buffer *buf,
1657                guint tap_flags)
1658 {
1659   column_info    *cinfo;
1660   gboolean        passed;
1661
1662   /* If we're not running a display filter and we're not printing any
1663      packet information, we don't need to do a dissection. This means
1664      that all packets can be marked as 'passed'. */
1665   passed = TRUE;
1666
1667   /* If we're going to print packet information, or we're going to
1668      run a read filter, or we're going to process taps, set up to
1669      do a dissection and do so. */
1670   if (edt) {
1671
1672     /* If we're running a display filter, prime the epan_dissect_t with that
1673        filter. */
1674     if (cf->dfcode)
1675       epan_dissect_prime_dfilter(edt, cf->dfcode);
1676
1677     col_custom_prime_edt(edt, &cf->cinfo);
1678
1679     /* We only need the columns if either
1680          1) some tap needs the columns
1681        or
1682          2) we're printing packet info but we're *not* verbose; in verbose
1683             mode, we print the protocol tree, not the protocol summary.
1684      */
1685     if ((tap_flags & TL_REQUIRES_COLUMNS) || (print_packet_info && print_summary))
1686       cinfo = &cf->cinfo;
1687     else
1688       cinfo = NULL;
1689
1690     frame_data_set_before_dissect(fdata, &cf->elapsed_time,
1691                                   &ref, prev_dis);
1692     if (ref == fdata) {
1693       ref_frame = *fdata;
1694       ref = &ref_frame;
1695     }
1696
1697     epan_dissect_file_run_with_taps(edt, phdr, file_tvbuff_new_buffer(fdata, buf), fdata, cinfo);
1698
1699     /* Run the read/display filter if we have one. */
1700     if (cf->dfcode)
1701       passed = dfilter_apply_edt(cf->dfcode, edt);
1702   }
1703
1704   if (passed) {
1705     frame_data_set_after_dissect(fdata, &cum_bytes);
1706     /* Process this packet. */
1707     if (print_packet_info) {
1708       /* We're printing packet information; print the information for
1709          this packet. */
1710       print_packet(cf, edt);
1711
1712       /* The ANSI C standard does not appear to *require* that a line-buffered
1713          stream be flushed to the host environment whenever a newline is
1714          written, it just says that, on such a stream, characters "are
1715          intended to be transmitted to or from the host environment as a
1716          block when a new-line character is encountered".
1717
1718          The Visual C++ 6.0 C implementation doesn't do what is intended;
1719          even if you set a stream to be line-buffered, it still doesn't
1720          flush the buffer at the end of every line.
1721
1722          So, if the "-l" flag was specified, we flush the standard output
1723          at the end of a packet.  This will do the right thing if we're
1724          printing packet summary lines, and, as we print the entire protocol
1725          tree for a single packet without waiting for anything to happen,
1726          it should be as good as line-buffered mode if we're printing
1727          protocol trees.  (The whole reason for the "-l" flag in either
1728          tcpdump or TShark is to allow the output of a live capture to
1729          be piped to a program or script and to have that script see the
1730          information for the packet as soon as it's printed, rather than
1731          having to wait until a standard I/O buffer fills up. */
1732       if (line_buffered)
1733         fflush(stdout);
1734
1735       if (ferror(stdout)) {
1736         show_print_file_io_error(errno);
1737         exit(2);
1738       }
1739     }
1740     prev_dis = fdata;
1741   }
1742   prev_cap = fdata;
1743
1744   if (edt) {
1745     epan_dissect_reset(edt);
1746   }
1747   return passed || fdata->flags.dependent_of_displayed;
1748 }
1749
1750 gboolean
1751 local_wtap_read(capture_file *cf, struct wtap_pkthdr* file_phdr _U_, int *err, gchar **err_info _U_, gint64 *data_offset _U_, guint8** data_buffer)
1752 {
1753     /* int bytes_read; */
1754     gint64 packet_size = wtap_file_size(cf->wth, err);
1755
1756     *data_buffer = (guint8*)g_malloc((gsize)packet_size);
1757     /* bytes_read =*/ file_read(*data_buffer, (unsigned int)packet_size, cf->wth->fh);
1758
1759 #if 0 /* no more filetap */
1760     if (bytes_read < 0) {
1761         *err = file_error(cf->wth->fh, err_info);
1762         if (*err == 0)
1763             *err = FTAP_ERR_SHORT_READ;
1764         return FALSE;
1765     } else if (bytes_read == 0) {
1766         /* Done with file, no error */
1767         return FALSE;
1768     }
1769
1770
1771     /* XXX - SET FRAME SIZE EQUAL TO TOTAL FILE SIZE */
1772     file_phdr->caplen = (guint32)packet_size;
1773     file_phdr->len = (guint32)packet_size;
1774
1775     /*
1776      * Set the packet encapsulation to the file's encapsulation
1777      * value; if that's not WTAP_ENCAP_PER_PACKET, it's the
1778      * right answer (and means that the read routine for this
1779      * capture file type doesn't have to set it), and if it
1780      * *is* WTAP_ENCAP_PER_PACKET, the caller needs to set it
1781      * anyway.
1782      */
1783     wth->phdr.pkt_encap = wth->file_encap;
1784
1785     if (!wth->subtype_read(wth, err, err_info, data_offset)) {
1786         /*
1787          * If we didn't get an error indication, we read
1788          * the last packet.  See if there's any deferred
1789          * error, as might, for example, occur if we're
1790          * reading a compressed file, and we got an error
1791          * reading compressed data from the file, but
1792          * got enough compressed data to decompress the
1793          * last packet of the file.
1794          */
1795         if (*err == 0)
1796             *err = file_error(wth->fh, err_info);
1797         return FALSE;    /* failure */
1798     }
1799
1800     /*
1801      * It makes no sense for the captured data length to be bigger
1802      * than the actual data length.
1803      */
1804     if (wth->phdr.caplen > wth->phdr.len)
1805         wth->phdr.caplen = wth->phdr.len;
1806
1807     /*
1808      * Make sure that it's not WTAP_ENCAP_PER_PACKET, as that
1809      * probably means the file has that encapsulation type
1810      * but the read routine didn't set this packet's
1811      * encapsulation type.
1812      */
1813     g_assert(wth->phdr.pkt_encap != WTAP_ENCAP_PER_PACKET);
1814 #endif
1815
1816     return TRUE; /* success */
1817 }
1818
1819 static int
1820 load_cap_file(capture_file *cf, int max_packet_count, gint64 max_byte_count)
1821 {
1822   guint32      framenum;
1823   int          err;
1824   gchar       *err_info = NULL;
1825   gint64       data_offset = 0;
1826   gboolean     filtering_tap_listeners;
1827   guint        tap_flags;
1828   Buffer       buf;
1829   epan_dissect_t *edt = NULL;
1830   struct wtap_pkthdr file_phdr;
1831   guint8* raw_data;
1832
1833   if (print_packet_info) {
1834     if (!write_preamble(cf)) {
1835       err = errno;
1836       show_print_file_io_error(err);
1837       goto out;
1838     }
1839   }
1840
1841   /* Do we have any tap listeners with filters? */
1842   filtering_tap_listeners = have_filtering_tap_listeners();
1843
1844   /* Get the union of the flags for all tap listeners. */
1845   tap_flags = union_of_tap_listener_flags();
1846
1847   wtap_phdr_init(&file_phdr);
1848
1849   /* XXX - TEMPORARY HACK TO ELF DISSECTOR */
1850   file_phdr.pkt_encap = 1234;
1851
1852   if (perform_two_pass_analysis) {
1853     frame_data *fdata;
1854
1855     /* Allocate a frame_data_sequence for all the frames. */
1856     cf->frames = new_frame_data_sequence();
1857
1858     if (do_dissection) {
1859        gboolean create_proto_tree = FALSE;
1860
1861       /* If we're going to be applying a filter, we'll need to
1862          create a protocol tree against which to apply the filter. */
1863       if (cf->rfcode)
1864         create_proto_tree = TRUE;
1865
1866       /* We're not going to display the protocol tree on this pass,
1867          so it's not going to be "visible". */
1868       edt = epan_dissect_new(cf->epan, create_proto_tree, FALSE);
1869     }
1870     while (local_wtap_read(cf, &file_phdr, &err, &err_info, &data_offset, &raw_data)) {
1871       if (process_packet_first_pass(cf, edt, data_offset, &file_phdr/*wtap_phdr(cf->wth)*/,
1872                          wtap_buf_ptr(cf->wth))) {
1873
1874         /* Stop reading if we have the maximum number of packets;
1875          * When the -c option has not been used, max_packet_count
1876          * starts at 0, which practically means, never stop reading.
1877          * (unless we roll over max_packet_count ?)
1878          */
1879         if ( (--max_packet_count == 0) || (max_byte_count != 0 && data_offset >= max_byte_count)) {
1880           err = 0; /* This is not an error */
1881           break;
1882         }
1883       }
1884     }
1885
1886     if (edt) {
1887       epan_dissect_free(edt);
1888       edt = NULL;
1889     }
1890
1891 #if 0
1892     /* Close the sequential I/O side, to free up memory it requires. */
1893     wtap_sequential_close(cf->wth);
1894 #endif
1895
1896     /* Allow the protocol dissectors to free up memory that they
1897      * don't need after the sequential run-through of the packets. */
1898     postseq_cleanup_all_protocols();
1899
1900     prev_dis = NULL;
1901     prev_cap = NULL;
1902     ws_buffer_init(&buf, 1500);
1903
1904     if (do_dissection) {
1905       gboolean create_proto_tree;
1906
1907       if (cf->dfcode || print_details || filtering_tap_listeners ||
1908          (tap_flags & TL_REQUIRES_PROTO_TREE) || have_custom_cols(&cf->cinfo))
1909            create_proto_tree = TRUE;
1910       else
1911            create_proto_tree = FALSE;
1912
1913       /* The protocol tree will be "visible", i.e., printed, only if we're
1914          printing packet details, which is true if we're printing stuff
1915          ("print_packet_info" is true) and we're in verbose mode
1916          ("packet_details" is true). */
1917       edt = epan_dissect_new(cf->epan, create_proto_tree, print_packet_info && print_details);
1918     }
1919
1920     for (framenum = 1; err == 0 && framenum <= cf->count; framenum++) {
1921       fdata = frame_data_sequence_find(cf->frames, framenum);
1922 #if 0
1923       if (wtap_seek_read(cf->wth, fdata->file_off,
1924           &buf, fdata->cap_len, &err, &err_info)) {
1925         process_packet_second_pass(cf, edt, fdata, &cf->phdr, &buf, tap_flags);
1926       }
1927 #else
1928         process_packet_second_pass(cf, edt, fdata, &cf->phdr, &buf, tap_flags);
1929 #endif
1930     }
1931
1932     if (edt) {
1933       epan_dissect_free(edt);
1934       edt = NULL;
1935     }
1936
1937     ws_buffer_free(&buf);
1938   }
1939   else {
1940     framenum = 0;
1941
1942     if (do_dissection) {
1943       gboolean create_proto_tree;
1944
1945       if (cf->rfcode || cf->dfcode || print_details || filtering_tap_listeners ||
1946           (tap_flags & TL_REQUIRES_PROTO_TREE) || have_custom_cols(&cf->cinfo))
1947         create_proto_tree = TRUE;
1948       else
1949         create_proto_tree = FALSE;
1950
1951       /* The protocol tree will be "visible", i.e., printed, only if we're
1952          printing packet details, which is true if we're printing stuff
1953          ("print_packet_info" is true) and we're in verbose mode
1954          ("packet_details" is true). */
1955       edt = epan_dissect_new(cf->epan, create_proto_tree, print_packet_info && print_details);
1956     }
1957
1958     while (local_wtap_read(cf, &file_phdr, &err, &err_info, &data_offset, &raw_data)) {
1959
1960       framenum++;
1961
1962       process_packet(cf, edt, data_offset, &file_phdr/*wtap_phdr(cf->wth)*/,
1963                              raw_data, tap_flags);
1964
1965         /* Stop reading if we have the maximum number of packets;
1966         * When the -c option has not been used, max_packet_count
1967         * starts at 0, which practically means, never stop reading.
1968         * (unless we roll over max_packet_count ?)
1969         */
1970         if ( (--max_packet_count == 0) || (max_byte_count != 0 && data_offset >= max_byte_count)) {
1971             err = 0; /* This is not an error */
1972             break;
1973         }
1974     }
1975
1976     if (edt) {
1977       epan_dissect_free(edt);
1978       edt = NULL;
1979     }
1980   }
1981
1982   wtap_phdr_cleanup(&file_phdr);
1983
1984   if (err != 0) {
1985     /*
1986      * Print a message noting that the read failed somewhere along the line.
1987      *
1988      * If we're printing packet data, and the standard output and error are
1989      * going to the same place, flush the standard output, so everything
1990      * buffered up is written, and then print a newline to the standard error
1991      * before printing the error message, to separate it from the packet
1992      * data.  (Alas, that only works on UN*X; st_dev is meaningless, and
1993      * the _fstat() documentation at Microsoft doesn't indicate whether
1994      * st_ino is even supported.)
1995      */
1996 #ifndef _WIN32
1997     if (print_packet_info) {
1998       ws_statb64 stat_stdout, stat_stderr;
1999
2000       if (ws_fstat64(1, &stat_stdout) == 0 && ws_fstat64(2, &stat_stderr) == 0) {
2001         if (stat_stdout.st_dev == stat_stderr.st_dev &&
2002             stat_stdout.st_ino == stat_stderr.st_ino) {
2003           fflush(stdout);
2004           fprintf(stderr, "\n");
2005         }
2006       }
2007     }
2008 #endif
2009 #if 0
2010     switch (err) {
2011
2012     case FTAP_ERR_UNSUPPORTED:
2013       cmdarg_err("The file \"%s\" contains record data that TFShark doesn't support.\n(%s)",
2014                  cf->filename, err_info);
2015       g_free(err_info);
2016       break;
2017
2018     case FTAP_ERR_UNSUPPORTED_ENCAP:
2019       cmdarg_err("The file \"%s\" has a packet with a network type that TFShark doesn't support.\n(%s)",
2020                  cf->filename, err_info);
2021       g_free(err_info);
2022       break;
2023
2024     case FTAP_ERR_CANT_READ:
2025       cmdarg_err("An attempt to read from the file \"%s\" failed for some unknown reason.",
2026                  cf->filename);
2027       break;
2028
2029     case FTAP_ERR_SHORT_READ:
2030       cmdarg_err("The file \"%s\" appears to have been cut short in the middle of a packet.",
2031                  cf->filename);
2032       break;
2033
2034     case FTAP_ERR_BAD_FILE:
2035       cmdarg_err("The file \"%s\" appears to be damaged or corrupt.\n(%s)",
2036                  cf->filename, err_info);
2037       g_free(err_info);
2038       break;
2039
2040     case FTAP_ERR_DECOMPRESS:
2041       cmdarg_err("The compressed file \"%s\" appears to be damaged or corrupt.\n"
2042                  "(%s)", cf->filename, err_info);
2043       break;
2044
2045     default:
2046       cmdarg_err("An error occurred while reading the file \"%s\": %s.",
2047                  cf->filename, ftap_strerror(err));
2048       break;
2049     }
2050 #endif
2051   } else {
2052     if (print_packet_info) {
2053       if (!write_finale()) {
2054         err = errno;
2055         show_print_file_io_error(err);
2056       }
2057     }
2058   }
2059
2060 out:
2061   wtap_close(cf->wth);
2062   cf->wth = NULL;
2063
2064   return err;
2065 }
2066
2067 static gboolean
2068 process_packet(capture_file *cf, epan_dissect_t *edt, gint64 offset,
2069                struct wtap_pkthdr *whdr, const guchar *pd, guint tap_flags)
2070 {
2071   frame_data      fdata;
2072   column_info    *cinfo;
2073   gboolean        passed;
2074
2075   /* Count this packet. */
2076   cf->count++;
2077
2078   /* If we're not running a display filter and we're not printing any
2079      packet information, we don't need to do a dissection. This means
2080      that all packets can be marked as 'passed'. */
2081   passed = TRUE;
2082
2083   frame_data_init(&fdata, cf->count, whdr, offset, cum_bytes);
2084
2085   /* If we're going to print packet information, or we're going to
2086      run a read filter, or we're going to process taps, set up to
2087      do a dissection and do so. */
2088   if (edt) {
2089     /* If we're running a filter, prime the epan_dissect_t with that
2090        filter. */
2091     if (cf->dfcode)
2092       epan_dissect_prime_dfilter(edt, cf->dfcode);
2093
2094     col_custom_prime_edt(edt, &cf->cinfo);
2095
2096     /* We only need the columns if either
2097          1) some tap needs the columns
2098        or
2099          2) we're printing packet info but we're *not* verbose; in verbose
2100             mode, we print the protocol tree, not the protocol summary.
2101        or
2102          3) there is a column mapped as an individual field */
2103     if ((tap_flags & TL_REQUIRES_COLUMNS) || (print_packet_info && print_summary) || output_fields_has_cols(output_fields))
2104       cinfo = &cf->cinfo;
2105     else
2106       cinfo = NULL;
2107
2108     frame_data_set_before_dissect(&fdata, &cf->elapsed_time,
2109                                   &ref, prev_dis);
2110     if (ref == &fdata) {
2111       ref_frame = fdata;
2112       ref = &ref_frame;
2113     }
2114
2115     epan_dissect_file_run_with_taps(edt, whdr, frame_tvbuff_new(&fdata, pd), &fdata, cinfo);
2116
2117     /* Run the filter if we have it. */
2118     if (cf->dfcode)
2119       passed = dfilter_apply_edt(cf->dfcode, edt);
2120   }
2121
2122   if (passed) {
2123     frame_data_set_after_dissect(&fdata, &cum_bytes);
2124
2125     /* Process this packet. */
2126     if (print_packet_info) {
2127       /* We're printing packet information; print the information for
2128          this packet. */
2129       print_packet(cf, edt);
2130
2131       /* The ANSI C standard does not appear to *require* that a line-buffered
2132          stream be flushed to the host environment whenever a newline is
2133          written, it just says that, on such a stream, characters "are
2134          intended to be transmitted to or from the host environment as a
2135          block when a new-line character is encountered".
2136
2137          The Visual C++ 6.0 C implementation doesn't do what is intended;
2138          even if you set a stream to be line-buffered, it still doesn't
2139          flush the buffer at the end of every line.
2140
2141          So, if the "-l" flag was specified, we flush the standard output
2142          at the end of a packet.  This will do the right thing if we're
2143          printing packet summary lines, and, as we print the entire protocol
2144          tree for a single packet without waiting for anything to happen,
2145          it should be as good as line-buffered mode if we're printing
2146          protocol trees.  (The whole reason for the "-l" flag in either
2147          tcpdump or TShark is to allow the output of a live capture to
2148          be piped to a program or script and to have that script see the
2149          information for the packet as soon as it's printed, rather than
2150          having to wait until a standard I/O buffer fills up. */
2151       if (line_buffered)
2152         fflush(stdout);
2153
2154       if (ferror(stdout)) {
2155         show_print_file_io_error(errno);
2156         exit(2);
2157       }
2158     }
2159
2160     /* this must be set after print_packet() [bug #8160] */
2161     prev_dis_frame = fdata;
2162     prev_dis = &prev_dis_frame;
2163   }
2164
2165   prev_cap_frame = fdata;
2166   prev_cap = &prev_cap_frame;
2167
2168   if (edt) {
2169     epan_dissect_reset(edt);
2170     frame_data_destroy(&fdata);
2171   }
2172   return passed;
2173 }
2174
2175 static gboolean
2176 write_preamble(capture_file *cf)
2177 {
2178   switch (output_action) {
2179
2180   case WRITE_TEXT:
2181     return print_preamble(print_stream, cf->filename, get_ws_vcs_version_info());
2182
2183   case WRITE_XML:
2184     if (print_details)
2185       write_pdml_preamble(stdout, cf->filename);
2186     else
2187       write_psml_preamble(&cf->cinfo, stdout);
2188     return !ferror(stdout);
2189
2190   case WRITE_FIELDS:
2191     write_fields_preamble(output_fields, stdout);
2192     return !ferror(stdout);
2193
2194   default:
2195     g_assert_not_reached();
2196     return FALSE;
2197   }
2198 }
2199
2200 static char *
2201 get_line_buf(size_t len)
2202 {
2203   static char   *line_bufp    = NULL;
2204   static size_t  line_buf_len = 256;
2205   size_t         new_line_buf_len;
2206
2207   for (new_line_buf_len = line_buf_len; len > new_line_buf_len;
2208        new_line_buf_len *= 2)
2209     ;
2210   if (line_bufp == NULL) {
2211     line_buf_len = new_line_buf_len;
2212     line_bufp = (char *)g_malloc(line_buf_len + 1);
2213   } else {
2214     if (new_line_buf_len > line_buf_len) {
2215       line_buf_len = new_line_buf_len;
2216       line_bufp = (char *)g_realloc(line_bufp, line_buf_len + 1);
2217     }
2218   }
2219   return line_bufp;
2220 }
2221
2222 static inline void
2223 put_string(char *dest, const char *str, size_t str_len)
2224 {
2225   memcpy(dest, str, str_len);
2226   dest[str_len] = '\0';
2227 }
2228
2229 static inline void
2230 put_spaces_string(char *dest, const char *str, size_t str_len, size_t str_with_spaces)
2231 {
2232   size_t i;
2233
2234   for (i = str_len; i < str_with_spaces; i++)
2235     *dest++ = ' ';
2236
2237   put_string(dest, str, str_len);
2238 }
2239
2240 static inline void
2241 put_string_spaces(char *dest, const char *str, size_t str_len, size_t str_with_spaces)
2242 {
2243   size_t i;
2244
2245   memcpy(dest, str, str_len);
2246   for (i = str_len; i < str_with_spaces; i++)
2247     dest[i] = ' ';
2248
2249   dest[str_with_spaces] = '\0';
2250 }
2251
2252 static gboolean
2253 print_columns(capture_file *cf)
2254 {
2255   char   *line_bufp;
2256   int     i;
2257   size_t  buf_offset;
2258   size_t  column_len;
2259   size_t  col_len;
2260   col_item_t* col_item;
2261
2262   line_bufp = get_line_buf(256);
2263   buf_offset = 0;
2264   *line_bufp = '\0';
2265   for (i = 0; i < cf->cinfo.num_cols; i++) {
2266     col_item = &cf->cinfo.columns[i];
2267     /* Skip columns not marked as visible. */
2268     if (!get_column_visible(i))
2269       continue;
2270     switch (col_item->col_fmt) {
2271     case COL_NUMBER:
2272       column_len = col_len = strlen(col_item->col_data);
2273       if (column_len < 3)
2274         column_len = 3;
2275       line_bufp = get_line_buf(buf_offset + column_len);
2276       put_spaces_string(line_bufp + buf_offset, col_item->col_data, col_len, column_len);
2277       break;
2278
2279     case COL_CLS_TIME:
2280     case COL_REL_TIME:
2281     case COL_ABS_TIME:
2282     case COL_ABS_YMD_TIME:  /* XXX - wider */
2283     case COL_ABS_YDOY_TIME: /* XXX - wider */
2284     case COL_UTC_TIME:
2285     case COL_UTC_YMD_TIME:  /* XXX - wider */
2286     case COL_UTC_YDOY_TIME: /* XXX - wider */
2287       column_len = col_len = strlen(col_item->col_data);
2288       if (column_len < 10)
2289         column_len = 10;
2290       line_bufp = get_line_buf(buf_offset + column_len);
2291       put_spaces_string(line_bufp + buf_offset, col_item->col_data, col_len, column_len);
2292       break;
2293
2294     case COL_DEF_SRC:
2295     case COL_RES_SRC:
2296     case COL_UNRES_SRC:
2297     case COL_DEF_DL_SRC:
2298     case COL_RES_DL_SRC:
2299     case COL_UNRES_DL_SRC:
2300     case COL_DEF_NET_SRC:
2301     case COL_RES_NET_SRC:
2302     case COL_UNRES_NET_SRC:
2303       column_len = col_len = strlen(col_item->col_data);
2304       if (column_len < 12)
2305         column_len = 12;
2306       line_bufp = get_line_buf(buf_offset + column_len);
2307       put_spaces_string(line_bufp + buf_offset, col_item->col_data, col_len, column_len);
2308       break;
2309
2310     case COL_DEF_DST:
2311     case COL_RES_DST:
2312     case COL_UNRES_DST:
2313     case COL_DEF_DL_DST:
2314     case COL_RES_DL_DST:
2315     case COL_UNRES_DL_DST:
2316     case COL_DEF_NET_DST:
2317     case COL_RES_NET_DST:
2318     case COL_UNRES_NET_DST:
2319       column_len = col_len = strlen(col_item->col_data);
2320       if (column_len < 12)
2321         column_len = 12;
2322       line_bufp = get_line_buf(buf_offset + column_len);
2323       put_string_spaces(line_bufp + buf_offset, col_item->col_data, col_len, column_len);
2324       break;
2325
2326     default:
2327       column_len = strlen(col_item->col_data);
2328       line_bufp = get_line_buf(buf_offset + column_len);
2329       put_string(line_bufp + buf_offset, col_item->col_data, column_len);
2330       break;
2331     }
2332     buf_offset += column_len;
2333     if (i != cf->cinfo.num_cols - 1) {
2334       /*
2335        * This isn't the last column, so we need to print a
2336        * separator between this column and the next.
2337        *
2338        * If we printed a network source and are printing a
2339        * network destination of the same type next, separate
2340        * them with " -> "; if we printed a network destination
2341        * and are printing a network source of the same type
2342        * next, separate them with " <- "; otherwise separate them
2343        * with a space.
2344        *
2345        * We add enough space to the buffer for " <- " or " -> ",
2346        * even if we're only adding " ".
2347        */
2348       line_bufp = get_line_buf(buf_offset + 4);
2349       switch (col_item->col_fmt) {
2350
2351       case COL_DEF_SRC:
2352       case COL_RES_SRC:
2353       case COL_UNRES_SRC:
2354         switch (cf->cinfo.columns[i+1].col_fmt) {
2355
2356         case COL_DEF_DST:
2357         case COL_RES_DST:
2358         case COL_UNRES_DST:
2359           put_string(line_bufp + buf_offset, " -> ", 4);
2360           buf_offset += 4;
2361           break;
2362
2363         default:
2364           put_string(line_bufp + buf_offset, " ", 1);
2365           buf_offset += 1;
2366           break;
2367         }
2368         break;
2369
2370       case COL_DEF_DL_SRC:
2371       case COL_RES_DL_SRC:
2372       case COL_UNRES_DL_SRC:
2373         switch (cf->cinfo.columns[i+1].col_fmt) {
2374
2375         case COL_DEF_DL_DST:
2376         case COL_RES_DL_DST:
2377         case COL_UNRES_DL_DST:
2378           put_string(line_bufp + buf_offset, " -> ", 4);
2379           buf_offset += 4;
2380           break;
2381
2382         default:
2383           put_string(line_bufp + buf_offset, " ", 1);
2384           buf_offset += 1;
2385           break;
2386         }
2387         break;
2388
2389       case COL_DEF_NET_SRC:
2390       case COL_RES_NET_SRC:
2391       case COL_UNRES_NET_SRC:
2392         switch (cf->cinfo.columns[i+1].col_fmt) {
2393
2394         case COL_DEF_NET_DST:
2395         case COL_RES_NET_DST:
2396         case COL_UNRES_NET_DST:
2397           put_string(line_bufp + buf_offset, " -> ", 4);
2398           buf_offset += 4;
2399           break;
2400
2401         default:
2402           put_string(line_bufp + buf_offset, " ", 1);
2403           buf_offset += 1;
2404           break;
2405         }
2406         break;
2407
2408       case COL_DEF_DST:
2409       case COL_RES_DST:
2410       case COL_UNRES_DST:
2411         switch (cf->cinfo.columns[i+1].col_fmt) {
2412
2413         case COL_DEF_SRC:
2414         case COL_RES_SRC:
2415         case COL_UNRES_SRC:
2416           put_string(line_bufp + buf_offset, " <- ", 4);
2417           buf_offset += 4;
2418           break;
2419
2420         default:
2421           put_string(line_bufp + buf_offset, " ", 1);
2422           buf_offset += 1;
2423           break;
2424         }
2425         break;
2426
2427       case COL_DEF_DL_DST:
2428       case COL_RES_DL_DST:
2429       case COL_UNRES_DL_DST:
2430         switch (cf->cinfo.columns[i+1].col_fmt) {
2431
2432         case COL_DEF_DL_SRC:
2433         case COL_RES_DL_SRC:
2434         case COL_UNRES_DL_SRC:
2435           put_string(line_bufp + buf_offset, " <- ", 4);
2436           buf_offset += 4;
2437           break;
2438
2439         default:
2440           put_string(line_bufp + buf_offset, " ", 1);
2441           buf_offset += 1;
2442           break;
2443         }
2444         break;
2445
2446       case COL_DEF_NET_DST:
2447       case COL_RES_NET_DST:
2448       case COL_UNRES_NET_DST:
2449         switch (cf->cinfo.columns[i+1].col_fmt) {
2450
2451         case COL_DEF_NET_SRC:
2452         case COL_RES_NET_SRC:
2453         case COL_UNRES_NET_SRC:
2454           put_string(line_bufp + buf_offset, " <- ", 4);
2455           buf_offset += 4;
2456           break;
2457
2458         default:
2459           put_string(line_bufp + buf_offset, " ", 1);
2460           buf_offset += 1;
2461           break;
2462         }
2463         break;
2464
2465       default:
2466         put_string(line_bufp + buf_offset, " ", 1);
2467         buf_offset += 1;
2468         break;
2469       }
2470     }
2471   }
2472   return print_line(print_stream, 0, line_bufp);
2473 }
2474
2475 static gboolean
2476 print_packet(capture_file *cf, epan_dissect_t *edt)
2477 {
2478   print_args_t print_args;
2479
2480   if (print_summary || output_fields_has_cols(output_fields)) {
2481     /* Just fill in the columns. */
2482     epan_dissect_fill_in_columns(edt, FALSE, TRUE);
2483
2484     if (print_summary) {
2485       /* Now print them. */
2486       switch (output_action) {
2487
2488       case WRITE_TEXT:
2489         if (!print_columns(cf))
2490           return FALSE;
2491         break;
2492
2493       case WRITE_XML:
2494         write_psml_columns(edt, stdout);
2495         return !ferror(stdout);
2496       case WRITE_FIELDS: /*No non-verbose "fields" format */
2497         g_assert_not_reached();
2498         break;
2499       }
2500     }
2501   }
2502   if (print_details) {
2503     /* Print the information in the protocol tree. */
2504     switch (output_action) {
2505
2506     case WRITE_TEXT:
2507       /* Only initialize the fields that are actually used in proto_tree_print.
2508        * This is particularly important for .range, as that's heap memory which
2509        * we would otherwise have to g_free().
2510       print_args.to_file = TRUE;
2511       print_args.format = print_format;
2512       print_args.print_summary = print_summary;
2513       print_args.print_formfeed = FALSE;
2514       packet_range_init(&print_args.range, &cfile);
2515       */
2516       print_args.print_hex = print_hex;
2517       print_args.print_dissections = print_details ? print_dissections_expanded : print_dissections_none;
2518
2519       if (!proto_tree_print(&print_args, edt, output_only_tables, print_stream))
2520         return FALSE;
2521       if (!print_hex) {
2522         if (!print_line(print_stream, 0, separator))
2523           return FALSE;
2524       }
2525       break;
2526
2527     case WRITE_XML:
2528       write_pdml_proto_tree(edt, stdout);
2529       printf("\n");
2530       return !ferror(stdout);
2531     case WRITE_FIELDS:
2532       write_fields_proto_tree(output_fields, edt, &cf->cinfo, stdout);
2533       printf("\n");
2534       return !ferror(stdout);
2535     }
2536   }
2537   if (print_hex) {
2538     if (print_summary || print_details) {
2539       if (!print_line(print_stream, 0, ""))
2540         return FALSE;
2541     }
2542     if (!print_hex_data(print_stream, edt))
2543       return FALSE;
2544     if (!print_line(print_stream, 0, separator))
2545       return FALSE;
2546   }
2547   return TRUE;
2548 }
2549
2550 static gboolean
2551 write_finale(void)
2552 {
2553   switch (output_action) {
2554
2555   case WRITE_TEXT:
2556     return print_finale(print_stream);
2557
2558   case WRITE_XML:
2559     if (print_details)
2560       write_pdml_finale(stdout);
2561     else
2562       write_psml_finale(stdout);
2563     return !ferror(stdout);
2564
2565   case WRITE_FIELDS:
2566     write_fields_finale(output_fields, stdout);
2567     return !ferror(stdout);
2568
2569   default:
2570     g_assert_not_reached();
2571     return FALSE;
2572   }
2573 }
2574
2575 cf_status_t
2576 cf_open(capture_file *cf, const char *fname, unsigned int type, gboolean is_tempfile, int *err)
2577 {
2578   gchar *err_info;
2579   char   err_msg[2048+1];
2580
2581   /* The open isn't implemented yet.  Fill in the information for this file. */
2582
2583   /* Create new epan session for dissection. */
2584   epan_free(cf->epan);
2585   cf->epan = tfshark_epan_new(cf);
2586
2587   cf->wth = NULL; /**** XXX - DOESN'T WORK RIGHT NOW!!!! */
2588   cf->f_datalen = 0; /* not used, but set it anyway */
2589
2590   /* Set the file name because we need it to set the follow stream filter.
2591      XXX - is that still true?  We need it for other reasons, though,
2592      in any case. */
2593   cf->filename = g_strdup(fname);
2594
2595   /* Indicate whether it's a permanent or temporary file. */
2596   cf->is_tempfile = is_tempfile;
2597
2598   /* No user changes yet. */
2599   cf->unsaved_changes = FALSE;
2600
2601   cf->cd_t      = 0; /**** XXX - DOESN'T WORK RIGHT NOW!!!! */
2602   cf->open_type = type;
2603   cf->count     = 0;
2604   cf->drops_known = FALSE;
2605   cf->drops     = 0;
2606   cf->snap      = 0; /**** XXX - DOESN'T WORK RIGHT NOW!!!! */
2607   if (cf->snap == 0) {
2608     /* Snapshot length not known. */
2609     cf->has_snap = FALSE;
2610     cf->snap = 0;
2611   } else
2612     cf->has_snap = TRUE;
2613   nstime_set_zero(&cf->elapsed_time);
2614   ref = NULL;
2615   prev_dis = NULL;
2616   prev_cap = NULL;
2617
2618   cf->state = FILE_READ_IN_PROGRESS;
2619
2620   return CF_OK;
2621
2622 /* fail: */
2623   g_snprintf(err_msg, sizeof err_msg,
2624              cf_open_error_message(*err, err_info, FALSE, cf->cd_t), fname);
2625   cmdarg_err("%s", err_msg);
2626   return CF_ERROR;
2627 }
2628
2629 static void
2630 show_print_file_io_error(int err)
2631 {
2632   switch (err) {
2633
2634   case ENOSPC:
2635     cmdarg_err("Not all the packets could be printed because there is "
2636 "no space left on the file system.");
2637     break;
2638
2639 #ifdef EDQUOT
2640   case EDQUOT:
2641     cmdarg_err("Not all the packets could be printed because you are "
2642 "too close to, or over your disk quota.");
2643   break;
2644 #endif
2645
2646   default:
2647     cmdarg_err("An error occurred while printing packets: %s.",
2648       g_strerror(err));
2649     break;
2650   }
2651 }
2652
2653 static const char *
2654 cf_open_error_message(int err, gchar *err_info _U_, gboolean for_writing,
2655                       int file_type _U_)
2656 {
2657   const char *errmsg;
2658   /* static char errmsg_errno[1024+1]; */
2659
2660 #if 0
2661   if (err < 0) {
2662     /* Wiretap error. */
2663     switch (err) {
2664
2665     case FTAP_ERR_NOT_REGULAR_FILE:
2666       errmsg = "The file \"%s\" is a \"special file\" or socket or other non-regular file.";
2667       break;
2668
2669     case FTAP_ERR_RANDOM_OPEN_PIPE:
2670       /* Seen only when opening a capture file for reading. */
2671       errmsg = "The file \"%s\" is a pipe or FIFO; TFShark can't read pipe or FIFO files in two-pass mode.";
2672       break;
2673
2674     case FTAP_ERR_FILE_UNKNOWN_FORMAT:
2675       /* Seen only when opening a capture file for reading. */
2676       errmsg = "The file \"%s\" isn't a capture file in a format TFShark understands.";
2677       break;
2678
2679     case FTAP_ERR_UNSUPPORTED:
2680       /* Seen only when opening a capture file for reading. */
2681       g_snprintf(errmsg_errno, sizeof(errmsg_errno),
2682                "The file \"%%s\" isn't a capture file in a format TFShark understands.\n"
2683                "(%s)", err_info);
2684       g_free(err_info);
2685       errmsg = errmsg_errno;
2686       break;
2687
2688     case FTAP_ERR_CANT_WRITE_TO_PIPE:
2689       /* Seen only when opening a capture file for writing. */
2690       g_snprintf(errmsg_errno, sizeof(errmsg_errno),
2691                  "The file \"%%s\" is a pipe, and \"%s\" capture files can't be "
2692                  "written to a pipe.", ftap_file_type_subtype_short_string(file_type));
2693       errmsg = errmsg_errno;
2694       break;
2695
2696     case FTAP_ERR_UNSUPPORTED_FILE_TYPE:
2697       /* Seen only when opening a capture file for writing. */
2698       errmsg = "TFShark doesn't support writing capture files in that format.";
2699       break;
2700
2701     case FTAP_ERR_UNSUPPORTED_ENCAP:
2702       if (for_writing) {
2703         g_snprintf(errmsg_errno, sizeof(errmsg_errno),
2704                    "TFShark can't save this capture as a \"%s\" file.",
2705                    ftap_file_type_subtype_short_string(file_type));
2706       } else {
2707         g_snprintf(errmsg_errno, sizeof(errmsg_errno),
2708                  "The file \"%%s\" is a capture for a network type that TFShark doesn't support.\n"
2709                  "(%s)", err_info);
2710         g_free(err_info);
2711       }
2712       errmsg = errmsg_errno;
2713       break;
2714
2715     case FTAP_ERR_ENCAP_PER_RECORD_UNSUPPORTED:
2716       if (for_writing) {
2717         g_snprintf(errmsg_errno, sizeof(errmsg_errno),
2718                    "TFShark can't save this capture as a \"%s\" file.",
2719                    ftap_file_type_subtype_short_string(file_type));
2720         errmsg = errmsg_errno;
2721       } else
2722         errmsg = "The file \"%s\" is a capture for a network type that TFShark doesn't support.";
2723       break;
2724
2725     case FTAP_ERR_BAD_FILE:
2726       /* Seen only when opening a capture file for reading. */
2727       g_snprintf(errmsg_errno, sizeof(errmsg_errno),
2728                "The file \"%%s\" appears to be damaged or corrupt.\n"
2729                "(%s)", err_info);
2730       g_free(err_info);
2731       errmsg = errmsg_errno;
2732       break;
2733
2734     case FTAP_ERR_CANT_OPEN:
2735       if (for_writing)
2736         errmsg = "The file \"%s\" could not be created for some unknown reason.";
2737       else
2738         errmsg = "The file \"%s\" could not be opened for some unknown reason.";
2739       break;
2740
2741     case FTAP_ERR_SHORT_READ:
2742       errmsg = "The file \"%s\" appears to have been cut short"
2743                " in the middle of a packet or other data.";
2744       break;
2745
2746     case FTAP_ERR_SHORT_WRITE:
2747       errmsg = "A full header couldn't be written to the file \"%s\".";
2748       break;
2749
2750     case FTAP_ERR_COMPRESSION_NOT_SUPPORTED:
2751       errmsg = "This file type cannot be written as a compressed file.";
2752       break;
2753
2754     case FTAP_ERR_DECOMPRESS:
2755       /* Seen only when opening a capture file for reading. */
2756       g_snprintf(errmsg_errno, sizeof(errmsg_errno),
2757                  "The compressed file \"%%s\" appears to be damaged or corrupt.\n"
2758                  "(%s)", err_info);
2759       g_free(err_info);
2760       errmsg = errmsg_errno;
2761       break;
2762
2763     default:
2764       g_snprintf(errmsg_errno, sizeof(errmsg_errno),
2765                  "The file \"%%s\" could not be %s: %s.",
2766                  for_writing ? "created" : "opened",
2767                  ftap_strerror(err));
2768       errmsg = errmsg_errno;
2769       break;
2770     }
2771   } else
2772 #endif
2773     errmsg = file_open_error_message(err, for_writing);
2774   return errmsg;
2775 }
2776
2777 /*
2778  * Open/create errors are reported with an console message in TFShark.
2779  */
2780 static void
2781 open_failure_message(const char *filename, int err, gboolean for_writing)
2782 {
2783   fprintf(stderr, "tfshark: ");
2784   fprintf(stderr, file_open_error_message(err, for_writing), filename);
2785   fprintf(stderr, "\n");
2786 }
2787
2788
2789 /*
2790  * General errors are reported with an console message in TFShark.
2791  */
2792 static void
2793 failure_message(const char *msg_format, va_list ap)
2794 {
2795   fprintf(stderr, "tfshark: ");
2796   vfprintf(stderr, msg_format, ap);
2797   fprintf(stderr, "\n");
2798 }
2799
2800 /*
2801  * Read errors are reported with an console message in TFShark.
2802  */
2803 static void
2804 read_failure_message(const char *filename, int err)
2805 {
2806   cmdarg_err("An error occurred while reading from the file \"%s\": %s.",
2807           filename, g_strerror(err));
2808 }
2809
2810 /*
2811  * Write errors are reported with an console message in TFShark.
2812  */
2813 static void
2814 write_failure_message(const char *filename, int err)
2815 {
2816   cmdarg_err("An error occurred while writing to the file \"%s\": %s.",
2817           filename, g_strerror(err));
2818 }
2819
2820 /*
2821  * Report additional information for an error in command-line arguments.
2822  */
2823 static void
2824 failure_message_cont(const char *msg_format, va_list ap)
2825 {
2826   vfprintf(stderr, msg_format, ap);
2827   fprintf(stderr, "\n");
2828 }
2829
2830 /*
2831  * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
2832  *
2833  * Local variables:
2834  * c-basic-offset: 2
2835  * tab-width: 8
2836  * indent-tabs-mode: nil
2837  * End:
2838  *
2839  * vi: set shiftwidth=2 tabstop=8 expandtab:
2840  * :indentSize=2:tabSize=8:noTabs=true:
2841  */