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