/* file.c
* File I/O routines
*
- * $Id$
- *
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
* Copyright 1998 Gerald Combs
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
-#include "config.h"
-
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
+#include <config.h>
#include <time.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
-#include <signal.h>
-
-#ifdef HAVE_FCNTL_H
-#include <fcntl.h>
-#endif
#include <wsutil/tempfile.h>
#include <wsutil/file_util.h>
#include <wsutil/filesystem.h>
+#include <wsutil/ws_version_info.h>
#include <wiretap/merge.h>
#include <epan/dfilter/dfilter.h>
#include <epan/epan_dissect.h>
#include <epan/tap.h>
-#include <epan/dissectors/packet-data.h>
#include <epan/dissectors/packet-ber.h>
#include <epan/timestamp.h>
#include <epan/dfilter/dfilter-macro.h>
#include "ui/progress_dlg.h"
#include "ui/ui_util.h"
-#include "version_info.h"
-
/* Needed for addrinfo */
#ifdef HAVE_SYS_TYPES_H
# include <sys/types.h>
#endif
#ifdef HAVE_LIBPCAP
-gboolean auto_scroll_live;
+gboolean auto_scroll_live; /* GTK+ only? */
#endif
-static void cf_reset_state(capture_file *cf);
-
static int read_packet(capture_file *cf, dfilter_t *dfcode, epan_dissect_t *edt,
column_info *cinfo, gint64 offset);
}
void
-cf_callback_remove(cf_callback_t func)
+cf_callback_remove(cf_callback_t func, gpointer user_data)
{
cf_callback_data_t *cb;
GList *cb_item = cf_callbacks;
while (cb_item != NULL) {
cb = (cf_callback_data_t *)cb_item->data;
- if (cb->cb_fct == func) {
+ if (cb->cb_fct == func && cb->user_data == user_data) {
cf_callbacks = g_list_remove(cf_callbacks, cb);
g_free(cb);
return;
cf_timestamp_auto_precision(capture_file *cf)
{
int i;
- int prec = timestamp_get_precision();
-
/* don't try to get the file's precision if none is opened */
if (cf->state == FILE_CLOSED) {
return;
}
- /* if we are in auto mode, set precision of current file */
- if (prec == TS_PREC_AUTO ||
- prec == TS_PREC_AUTO_SEC ||
- prec == TS_PREC_AUTO_DSEC ||
- prec == TS_PREC_AUTO_CSEC ||
- prec == TS_PREC_AUTO_MSEC ||
- prec == TS_PREC_AUTO_USEC ||
- prec == TS_PREC_AUTO_NSEC)
- {
- switch(wtap_file_tsprecision(cf->wth)) {
- case(WTAP_FILE_TSPREC_SEC):
- timestamp_set_precision(TS_PREC_AUTO_SEC);
- break;
- case(WTAP_FILE_TSPREC_DSEC):
- timestamp_set_precision(TS_PREC_AUTO_DSEC);
- break;
- case(WTAP_FILE_TSPREC_CSEC):
- timestamp_set_precision(TS_PREC_AUTO_CSEC);
- break;
- case(WTAP_FILE_TSPREC_MSEC):
- timestamp_set_precision(TS_PREC_AUTO_MSEC);
- break;
- case(WTAP_FILE_TSPREC_USEC):
- timestamp_set_precision(TS_PREC_AUTO_USEC);
- break;
- case(WTAP_FILE_TSPREC_NSEC):
- timestamp_set_precision(TS_PREC_AUTO_NSEC);
- break;
- default:
- g_assert_not_reached();
- }
- }
/* Set the column widths of those columns that show the time in
"command-line-specified" format. */
for (i = 0; i < cf->cinfo.num_cols; i++) {
}
cf_status_t
-cf_open(capture_file *cf, const char *fname, gboolean is_tempfile, int *err)
+cf_open(capture_file *cf, const char *fname, unsigned int type, gboolean is_tempfile, int *err)
{
wtap *wth;
gchar *err_info;
- wth = wtap_open_offline(fname, err, &err_info, TRUE);
+ wth = wtap_open_offline(fname, type, err, &err_info, TRUE);
if (wth == NULL)
goto fail;
and fill in the information for this file. */
cf_close(cf);
+ /* Initialize the packet header. */
+ wtap_phdr_init(&cf->phdr);
+
/* XXX - we really want to initialize this after we've read all
the packets, so we know how much we'll ultimately need. */
- buffer_init(&cf->buf, 1500);
+ ws_buffer_init(&cf->buf, 1500);
/* Create new epan session for dissection.
* (The old one was freed in cf_close().)
cf->computed_elapsed = 0;
cf->cd_t = wtap_file_type_subtype(cf->wth);
+ cf->open_type = type;
cf->linktypes = g_array_sized_new(FALSE, FALSE, (guint) sizeof(int), 1);
cf->count = 0;
cf->packet_comment_count = 0;
g_array_append_val(cf->linktypes, encap);
}
-/*
- * Reset the state for the currently closed file, but don't do the
- * UI callbacks; this is for use in "cf_open()", where we don't
- * want the UI to go from "file open" to "file closed" back to
- * "file open", we want it to go from "old file open" to "new file
- * open and being read".
- *
- * XXX - currently, cf_open() calls cf_close(), rather than
- * cf_reset_state().
- */
-static void
-cf_reset_state(capture_file *cf)
+/* Reset everything to a pristine state */
+void
+cf_close(capture_file *cf)
{
+ cf->stop_flag = FALSE;
+ if (cf->state == FILE_CLOSED)
+ return; /* Nothing to do */
+
/* Die if we're in the middle of reading a file. */
g_assert(cf->state != FILE_READ_IN_PROGRESS);
+ cf_callback_invoke(cf_cb_file_closing, cf);
+
+ /* close things, if not already closed before */
+ color_filters_cleanup();
+
if (cf->wth) {
wtap_close(cf->wth);
cf->wth = NULL;
/* ...which means we have no changes to that file to save. */
cf->unsaved_changes = FALSE;
+ /* no open_routine type */
+ cf->open_type = WTAP_TYPE_AUTO;
+
+ /* Clean up the packet header. */
+ wtap_phdr_cleanup(&cf->phdr);
+
/* Free up the packet buffer. */
- buffer_free(&cf->buf);
+ ws_buffer_free(&cf->buf);
dfilter_free(cf->rfcode);
cf->rfcode = NULL;
cf->finfo_selected = NULL;
/* No frame link-layer types, either. */
- g_array_free(cf->linktypes, TRUE);
- cf->linktypes = NULL;
+ if (cf->linktypes != NULL) {
+ g_array_free(cf->linktypes, TRUE);
+ cf->linktypes = NULL;
+ }
/* Clear the packet list. */
packet_list_freeze();
reset_tap_listeners();
+ epan_free(cf->epan);
+ cf->epan = NULL;
+
/* We have no file open. */
cf->state = FILE_CLOSED;
-}
-
-/* Reset everything to a pristine state */
-void
-cf_close(capture_file *cf)
-{
- if (cf->state != FILE_CLOSED) {
- cf_callback_invoke(cf_cb_file_closing, cf);
-
- /* close things, if not already closed before */
- color_filters_cleanup();
- cf_reset_state(cf);
- epan_free(cf->epan);
- cf->epan = NULL;
- cf_callback_invoke(cf_cb_file_closed, cf);
- }
+ cf_callback_invoke(cf_cb_file_closed, cf);
}
static float
gchar *err_info;
gchar *name_ptr;
progdlg_t *progbar = NULL;
- gboolean stop_flag;
GTimeVal start_time;
epan_dissect_t edt;
dfilter_t *dfcode;
* We assume this will not fail since cf->dfilter is only set in
* cf_filter IFF the filter was valid.
*/
- compiled = dfilter_compile(cf->dfilter, &dfcode);
+ compiled = dfilter_compile(cf->dfilter, &dfcode, NULL);
g_assert(!cf->dfilter || (compiled && dfcode));
/* Get the union of the flags for all tap listeners. */
/* The packet list window will be empty until the file is completly loaded */
packet_list_freeze();
- stop_flag = FALSE;
+ cf->stop_flag = FALSE;
g_get_current_time(&start_time);
epan_dissect_init(&edt, cf->epan, create_proto_tree, FALSE);
progbar_val = calc_progbar_val(cf, size, file_pos, status_str, sizeof(status_str));
if (reloading)
progbar = delayed_create_progress_dlg(cf->window, "Reloading", name_ptr,
- TRUE, &stop_flag, &start_time, progbar_val);
+ TRUE, &cf->stop_flag, &start_time, progbar_val);
else
progbar = delayed_create_progress_dlg(cf->window, "Loading", name_ptr,
- TRUE, &stop_flag, &start_time, progbar_val);
+ TRUE, &cf->stop_flag, &start_time, progbar_val);
}
/* Update the progress bar, but do it only N_PROGBAR_UPDATES times;
}
}
- if (stop_flag) {
+ if (cf->stop_flag) {
/* Well, the user decided to abort the read. He/She will be warned and
it might be enough for him/her to work with the already loaded
packets.
}
CATCH(OutOfMemoryError) {
simple_message_box(ESD_TYPE_ERROR, NULL,
- "Some infos / workarounds can be found at:\n"
- "http://wiki.wireshark.org/KnownBugs/OutOfMemory",
- "Sorry, but Wireshark has run out of memory and has to terminate now!");
+ "More information and workarounds can be found at\n"
+ "https://wiki.wireshark.org/KnownBugs/OutOfMemory",
+ "Sorry, but Wireshark has run out of memory and has to terminate now.");
#if 0
/* Could we close the current capture and free up memory from that? */
#else
packet_list_select_first_row();
}
- if (stop_flag) {
+ if (cf->stop_flag) {
simple_message_box(ESD_TYPE_WARN, NULL,
"The remaining packets in the file were discarded.\n"
"\n"
"As a lot of packets from the original file will be missing,\n"
"remember to be careful when saving the current content to a file.\n",
- "File loading was cancelled!");
+ "File loading was cancelled.");
return CF_READ_ERROR;
}
case WTAP_ERR_UNSUPPORTED:
simple_error_message_box(
"The capture file contains record data that Wireshark doesn't support.\n(%s)",
- err_info);
- g_free(err_info);
- break;
-
- case WTAP_ERR_UNSUPPORTED_ENCAP:
- simple_error_message_box(
- "The capture file has a packet with a network type that Wireshark doesn't support.\n(%s)",
- err_info);
+ err_info != NULL ? err_info : "no information supplied");
g_free(err_info);
break;
- case WTAP_ERR_CANT_READ:
- simple_error_message_box(
- "An attempt to read from the capture file failed for"
- " some unknown reason.");
- break;
-
case WTAP_ERR_SHORT_READ:
simple_error_message_box(
"The capture file appears to have been cut short"
case WTAP_ERR_BAD_FILE:
simple_error_message_box(
"The capture file appears to be damaged or corrupt.\n(%s)",
- err_info);
+ err_info != NULL ? err_info : "no information supplied");
g_free(err_info);
break;
case WTAP_ERR_DECOMPRESS:
simple_error_message_box(
- "The compressed capture file appears to be damaged or corrupt.\n"
- "(%s)", err_info);
+ "The compressed capture file appears to be damaged or corrupt.\n(%s)",
+ err_info != NULL ? err_info : "no information supplied");
g_free(err_info);
break;
cf_continue_tail(capture_file *cf, volatile int to_read, int *err)
{
gchar *err_info;
- int newly_displayed_packets = 0;
+ volatile int newly_displayed_packets = 0;
dfilter_t *dfcode;
- epan_dissect_t edt;
- gboolean create_proto_tree;
+ epan_dissect_t edt;
+ gboolean create_proto_tree;
guint tap_flags;
gboolean compiled;
* We assume this will not fail since cf->dfilter is only set in
* cf_filter IFF the filter was valid.
*/
- compiled = dfilter_compile(cf->dfilter, &dfcode);
+ compiled = dfilter_compile(cf->dfilter, &dfcode, NULL);
g_assert(!cf->dfilter || (compiled && dfcode));
/* Get the union of the flags for all tap listeners. */
}
CATCH(OutOfMemoryError) {
simple_message_box(ESD_TYPE_ERROR, NULL,
- "Some infos / workarounds can be found at:\n"
- "http://wiki.wireshark.org/KnownBugs/OutOfMemory",
- "Sorry, but Wireshark has run out of memory and has to terminate now!");
+ "More information and workarounds can be found at\n"
+ "https://wiki.wireshark.org/KnownBugs/OutOfMemory",
+ "Sorry, but Wireshark has run out of memory and has to terminate now.");
#if 0
/* Could we close the current capture and free up memory from that? */
return CF_READ_ABORTED;
} else if (*err != 0) {
/* We got an error reading the capture file.
XXX - pop up a dialog box instead? */
- g_warning("Error \"%s\" while reading: \"%s\" (\"%s\")",
- wtap_strerror(*err), err_info, cf->filename);
- g_free(err_info);
-
+ if (err_info != NULL) {
+ g_warning("Error \"%s\" while reading \"%s\" (\"%s\")",
+ wtap_strerror(*err), cf->filename, err_info);
+ g_free(err_info);
+ } else {
+ g_warning("Error \"%s\" while reading \"%s\"",
+ wtap_strerror(*err), cf->filename);
+ }
return CF_READ_ERROR;
} else
return CF_READ_OK;
* We assume this will not fail since cf->dfilter is only set in
* cf_filter IFF the filter was valid.
*/
- compiled = dfilter_compile(cf->dfilter, &dfcode);
+ compiled = dfilter_compile(cf->dfilter, &dfcode, NULL);
g_assert(!cf->dfilter || (compiled && dfcode));
/* Get the union of the flags for all tap listeners. */
if (*err != 0) {
/* We got an error reading the capture file.
XXX - pop up a dialog box? */
-
- g_warning("Error \"%s\" while reading: \"%s\" (\"%s\")",
- wtap_strerror(*err), err_info, cf->filename);
- g_free(err_info);
+ if (err_info != NULL) {
+ g_warning("Error \"%s\" while reading \"%s\" (\"%s\")",
+ wtap_strerror(*err), cf->filename, err_info);
+ g_free(err_info);
+ } else {
+ g_warning("Error \"%s\" while reading \"%s\"",
+ wtap_strerror(*err), cf->filename);
+ }
return CF_READ_ERROR;
} else {
return CF_READ_OK;
return cf->count;
}
-/* XXX - use a macro instead? */
-void
-cf_set_packet_count(capture_file *cf, int packet_count)
-{
- cf->count = packet_count;
-}
-
/* XXX - use a macro instead? */
gboolean
cf_is_tempfile(capture_file *cf)
}
/* Dissect the frame. */
- epan_dissect_run_with_taps(edt, phdr, frame_tvbuff_new(fdata, buf), fdata, cinfo);
+ epan_dissect_run_with_taps(edt, cf->cd_t, phdr, frame_tvbuff_new(fdata, buf), fdata, cinfo);
/* If we don't have a display filter, set "passed_dfilter" to 1. */
if (dfcode != NULL) {
epan_dissect_init(&rf_edt, cf->epan, TRUE, FALSE);
epan_dissect_prime_dfilter(&rf_edt, cf->rfcode);
- epan_dissect_run(&rf_edt, phdr, frame_tvbuff_new(&fdlocal, buf), &fdlocal, NULL);
+ epan_dissect_run(&rf_edt, cf->cd_t, phdr, frame_tvbuff_new(&fdlocal, buf), &fdlocal, NULL);
passed = dfilter_apply_edt(cf->rfcode, &rf_edt);
epan_dissect_cleanup(&rf_edt);
}
return row;
}
-cf_status_t
-cf_merge_files(char **out_filenamep, int in_file_count,
- char *const *in_filenames, int file_type, gboolean do_append)
-{
- merge_in_file_t *in_files, *in_file;
- char *out_filename;
- char *tmpname;
- int out_fd;
- wtap_dumper *pdh;
- int open_err, read_err, write_err, close_err;
- gchar *err_info;
- int err_fileno;
- int i;
- gboolean got_read_error = FALSE, got_write_error = FALSE;
- gint64 data_offset;
- progdlg_t *progbar = NULL;
- gboolean stop_flag;
- gint64 f_len, file_pos;
- float progbar_val;
- GTimeVal start_time;
- gchar status_str[100];
+
+typedef struct _callback_data_t {
+ gint64 f_len;
gint64 progbar_nextstep;
gint64 progbar_quantum;
- gchar *display_basename;
- int selected_frame_type;
- gboolean fake_interface_ids = FALSE;
-
- /* open the input files */
- if (!merge_open_in_files(in_file_count, in_filenames, &in_files,
- &open_err, &err_info, &err_fileno)) {
- g_free(in_files);
- cf_open_failure_alert_box(in_filenames[err_fileno], open_err, err_info,
- FALSE, 0);
- return CF_ERROR;
- }
-
- if (*out_filenamep != NULL) {
- out_filename = *out_filenamep;
- out_fd = ws_open(out_filename, O_CREAT|O_TRUNC|O_BINARY, 0600);
- if (out_fd == -1)
- open_err = errno;
- } else {
- out_fd = create_tempfile(&tmpname, "wireshark");
- if (out_fd == -1)
- open_err = errno;
- out_filename = g_strdup(tmpname);
- *out_filenamep = out_filename;
- }
- if (out_fd == -1) {
- err_info = NULL;
- merge_close_in_files(in_file_count, in_files);
- g_free(in_files);
- cf_open_failure_alert_box(out_filename, open_err, NULL, TRUE, file_type);
- return CF_ERROR;
- }
-
- selected_frame_type = merge_select_frame_type(in_file_count, in_files);
-
- /* If we are trying to merge a number of libpcap files with different encapsulation types
- * change the output file type to pcapng and create SHB and IDB:s for the new file use the
- * interface index stored in in_files per file to change the phdr before writing the datablock.
- * XXX should it be an option to convert to pcapng?
- *
- * We need something similar when merging pcapng files possibly with an option to say
- * the same interface(s) used in all in files. SHBs comments should be merged together.
- */
- if ((selected_frame_type == WTAP_ENCAP_PER_PACKET)&&(file_type == WTAP_FILE_TYPE_SUBTYPE_PCAP)) {
- /* Write output in pcapng format */
- wtapng_section_t *shb_hdr;
- wtapng_iface_descriptions_t *idb_inf, *idb_inf_merge_file;
- wtapng_if_descr_t int_data, *file_int_data;
- GString *comment_gstr;
-
- fake_interface_ids = TRUE;
- /* Create SHB info */
- shb_hdr = wtap_file_get_shb_info(in_files[0].wth);
- comment_gstr = g_string_new("");
- g_string_append_printf(comment_gstr, "%s \n",shb_hdr->opt_comment);
- g_string_append_printf(comment_gstr, "File created by merging: \n");
- file_type = WTAP_FILE_TYPE_SUBTYPE_PCAPNG;
-
- for (i = 0; i < in_file_count; i++) {
- g_string_append_printf(comment_gstr, "File%d: %s \n",i+1,in_files[i].filename);
- }
- shb_hdr->section_length = -1;
- /* options */
- shb_hdr->opt_comment = g_string_free(comment_gstr, FALSE); /* NULL if not available */
- shb_hdr->shb_hardware = NULL; /* NULL if not available, UTF-8 string containing the */
- /* description of the hardware used to create this section. */
- shb_hdr->shb_os = NULL; /* NULL if not available, UTF-8 string containing the name */
- /* of the operating system used to create this section. */
- shb_hdr->shb_user_appl = "Wireshark"; /* NULL if not available, UTF-8 string containing the name */
- /* of the application used to create this section. */
-
- /* create fake IDB info */
- idb_inf = g_new(wtapng_iface_descriptions_t,1);
- idb_inf->number_of_interfaces = in_file_count; /* TODO make this the number of DIFFERENT encapsulation types
- * check that snaplength is the same too?
- */
- idb_inf->interface_data = g_array_new(FALSE, FALSE, sizeof(wtapng_if_descr_t));
-
- for (i = 0; i < in_file_count; i++) {
- idb_inf_merge_file = wtap_file_get_idb_info(in_files[i].wth);
- /* read the interface data from the in file to our combined interfca data */
- file_int_data = &g_array_index (idb_inf_merge_file->interface_data, wtapng_if_descr_t, 0);
- int_data.wtap_encap = file_int_data->wtap_encap;
- int_data.time_units_per_second = file_int_data->time_units_per_second;
- int_data.link_type = file_int_data->link_type;
- int_data.snap_len = file_int_data->snap_len;
- int_data.if_name = g_strdup(file_int_data->if_name);
- int_data.opt_comment = NULL;
- int_data.if_description = NULL;
- int_data.if_speed = 0;
- int_data.if_tsresol = 6;
- int_data.if_filter_str = NULL;
- int_data.bpf_filter_len = 0;
- int_data.if_filter_bpf_bytes = NULL;
- int_data.if_os = NULL;
- int_data.if_fcslen = -1;
- int_data.num_stat_entries = 0; /* Number of ISB:s */
- int_data.interface_statistics = NULL;
-
- g_array_append_val(idb_inf->interface_data, int_data);
- g_free(idb_inf_merge_file);
-
- /* Set fake interface Id in per file data */
- in_files[i].interface_id = i;
- }
+ GTimeVal start_time;
+ progdlg_t *progbar;
+ gboolean stop_flag;
+} callback_data_t;
- pdh = wtap_dump_fdopen_ng(out_fd, file_type,
- selected_frame_type,
- merge_max_snapshot_length(in_file_count, in_files),
- FALSE /* compressed */, shb_hdr, idb_inf /* wtapng_iface_descriptions_t *idb_inf */, &open_err);
- if (pdh == NULL) {
- ws_close(out_fd);
- merge_close_in_files(in_file_count, in_files);
- g_free(in_files);
- cf_open_failure_alert_box(out_filename, open_err, err_info, TRUE,
- file_type);
- return CF_ERROR;
- }
+static gboolean
+merge_callback(merge_event event, int num _U_,
+ const merge_in_file_t in_files[], const guint in_file_count,
+ void *data)
+{
+ guint i;
+ callback_data_t *cb_data = (callback_data_t*) data;
- } else {
+ g_assert(cb_data != NULL);
- pdh = wtap_dump_fdopen(out_fd, file_type,
- selected_frame_type,
- merge_max_snapshot_length(in_file_count, in_files),
- FALSE /* compressed */, &open_err);
- if (pdh == NULL) {
- ws_close(out_fd);
- merge_close_in_files(in_file_count, in_files);
- g_free(in_files);
- cf_open_failure_alert_box(out_filename, open_err, err_info, TRUE,
- file_type);
- return CF_ERROR;
- }
- }
+ switch (event) {
- /* Get the sum of the sizes of all the files. */
- f_len = 0;
- for (i = 0; i < in_file_count; i++)
- f_len += in_files[i].size;
+ case MERGE_EVENT_INPUT_FILES_OPENED:
+ /* do nothing */
+ break;
- /* Update the progress bar when it gets to this value. */
- progbar_nextstep = 0;
- /* When we reach the value that triggers a progress bar update,
- bump that value by this amount. */
- progbar_quantum = f_len/N_PROGBAR_UPDATES;
- /* Progress so far. */
- progbar_val = 0.0f;
+ case MERGE_EVENT_FRAME_TYPE_SELECTED:
+ /* do nothing */
+ break;
- stop_flag = FALSE;
- g_get_current_time(&start_time);
+ case MERGE_EVENT_READY_TO_MERGE:
+ /* Get the sum of the sizes of all the files. */
+ for (i = 0; i < in_file_count; i++)
+ cb_data->f_len += in_files[i].size;
- /* do the merge (or append) */
- for (;;) {
- if (do_append)
- in_file = merge_append_read_packet(in_file_count, in_files, &read_err,
- &err_info);
- else
- in_file = merge_read_packet(in_file_count, in_files, &read_err,
- &err_info);
- if (in_file == NULL) {
- /* EOF */
- break;
- }
+ /* When we reach the value that triggers a progress bar update,
+ bump that value by this amount. */
+ cb_data->progbar_quantum = cb_data->f_len / N_PROGBAR_UPDATES;
- if (read_err != 0) {
- /* I/O error reading from in_file */
- got_read_error = TRUE;
+ g_get_current_time(&cb_data->start_time);
break;
- }
-
- /* Get the sum of the data offsets in all of the files. */
- data_offset = 0;
- for (i = 0; i < in_file_count; i++)
- data_offset += in_files[i].data_offset;
- /* Create the progress bar if necessary.
- We check on every iteration of the loop, so that it takes no
- longer than the standard time to create it (otherwise, for a
- large file, we might take considerably longer than that standard
- time in order to get to the next progress bar step). */
- if (progbar == NULL) {
- progbar = delayed_create_progress_dlg(NULL, "Merging", "files",
- FALSE, &stop_flag, &start_time, progbar_val);
- }
+ case MERGE_EVENT_PACKET_WAS_READ:
+ {
+ gint64 data_offset = 0;
- /* Update the progress bar, but do it only N_PROGBAR_UPDATES times;
- when we update it, we have to run the GTK+ main loop to get it
- to repaint what's pending, and doing so may involve an "ioctl()"
- to see if there's any pending input from an X server, and doing
- that for every packet can be costly, especially on a big file. */
- if (data_offset >= progbar_nextstep) {
- /* Get the sum of the seek positions in all of the files. */
- file_pos = 0;
+ /* Get the sum of the data offsets in all of the files. */
+ data_offset = 0;
for (i = 0; i < in_file_count; i++)
- file_pos += wtap_read_so_far(in_files[i].wth);
- progbar_val = (gfloat) file_pos / (gfloat) f_len;
- if (progbar_val > 1.0f) {
- /* Some file probably grew while we were reading it.
- That "shouldn't happen", so we'll just clip the progress
- value at 1.0. */
- progbar_val = 1.0f;
- }
- if (progbar != NULL) {
- g_snprintf(status_str, sizeof(status_str),
- "%" G_GINT64_MODIFIER "dKB of %" G_GINT64_MODIFIER "dKB",
- file_pos / 1024, f_len / 1024);
- update_progress_dlg(progbar, progbar_val, status_str);
+ data_offset += in_files[i].data_offset;
+
+ /* Create the progress bar if necessary.
+ We check on every iteration of the loop, so that it takes no
+ longer than the standard time to create it (otherwise, for a
+ large file, we might take considerably longer than that standard
+ time in order to get to the next progress bar step). */
+ if (cb_data->progbar == NULL) {
+ cb_data->progbar = delayed_create_progress_dlg(NULL, "Merging", "files",
+ FALSE, &cb_data->stop_flag, &cb_data->start_time, 0.0f);
}
- progbar_nextstep += progbar_quantum;
- }
- if (stop_flag) {
- /* Well, the user decided to abort the merge. */
- break;
- }
+ /* Update the progress bar, but do it only N_PROGBAR_UPDATES times;
+ when we update it, we have to run the GTK+ main loop to get it
+ to repaint what's pending, and doing so may involve an "ioctl()"
+ to see if there's any pending input from an X server, and doing
+ that for every packet can be costly, especially on a big file. */
+ if (data_offset >= cb_data->progbar_nextstep) {
+ float progbar_val;
+ gint64 file_pos = 0;
+ /* Get the sum of the seek positions in all of the files. */
+ for (i = 0; i < in_file_count; i++)
+ file_pos += wtap_read_so_far(in_files[i].wth);
+
+ progbar_val = (gfloat) file_pos / (gfloat) cb_data->f_len;
+ if (progbar_val > 1.0f) {
+ /* Some file probably grew while we were reading it.
+ That "shouldn't happen", so we'll just clip the progress
+ value at 1.0. */
+ progbar_val = 1.0f;
+ }
- /* If we have WTAP_ENCAP_PER_PACKET and the infiles are of type
- * WTAP_FILE_TYPE_SUBTYPE_PCAP, we need to set the interface id
- * in the paket header = the interface index we used in the IDBs
- * interface description for this file(encapsulation type).
- */
- if (fake_interface_ids) {
- struct wtap_pkthdr *phdr;
+ if (cb_data->progbar != NULL) {
+ gchar status_str[100];
+ g_snprintf(status_str, sizeof(status_str),
+ "%" G_GINT64_MODIFIER "dKB of %" G_GINT64_MODIFIER "dKB",
+ file_pos / 1024, cb_data->f_len / 1024);
+ update_progress_dlg(cb_data->progbar, progbar_val, status_str);
+ }
+ cb_data->progbar_nextstep += cb_data->progbar_quantum;
+ }
+ }
+ break;
- phdr = wtap_phdr(in_file->wth);
- phdr->interface_id = in_file->interface_id;
- phdr->presence_flags = phdr->presence_flags | WTAP_HAS_INTERFACE_ID;
- }
- if (!wtap_dump(pdh, wtap_phdr(in_file->wth),
- wtap_buf_ptr(in_file->wth), &write_err)) {
- got_write_error = TRUE;
+ case MERGE_EVENT_DONE:
+ /* We're done merging the files; destroy the progress bar if it was created. */
+ if (cb_data->progbar != NULL)
+ destroy_progress_dlg(cb_data->progbar);
break;
- }
}
- /* We're done merging the files; destroy the progress bar if it was created. */
- if (progbar != NULL)
- destroy_progress_dlg(progbar);
+ return cb_data->stop_flag;
+}
+
+
+
+cf_status_t
+cf_merge_files(char **out_filenamep, int in_file_count,
+ char *const *in_filenames, int file_type, gboolean do_append)
+{
+ char *out_filename;
+ char *tmpname;
+ int out_fd;
+ int err = 0;
+ gchar *err_info = NULL;
+ int err_fileno;
+ merge_result status;
+ merge_progress_callback_t cb;
+
- merge_close_in_files(in_file_count, in_files);
- if (!got_write_error) {
- if (!wtap_dump_close(pdh, &write_err))
- got_write_error = TRUE;
+ if (*out_filenamep != NULL) {
+ out_filename = *out_filenamep;
+ out_fd = ws_open(out_filename, O_CREAT|O_TRUNC|O_BINARY, 0600);
+ if (out_fd == -1)
+ err = errno;
} else {
- /*
- * We already got a write error; no need to report another
- * write error on close.
- *
- * Don't overwrite the earlier write error.
- */
- (void)wtap_dump_close(pdh, &close_err);
+ out_fd = create_tempfile(&tmpname, "wireshark");
+ if (out_fd == -1)
+ err = errno;
+ out_filename = g_strdup(tmpname);
+ *out_filenamep = out_filename;
+ }
+ if (out_fd == -1) {
+ cf_open_failure_alert_box(out_filename, err, NULL, TRUE, file_type);
+ return CF_ERROR;
}
- if (got_read_error) {
- /*
- * Find the file on which we got the error, and report the error.
- */
- for (i = 0; i < in_file_count; i++) {
- if (in_files[i].state == GOT_ERROR) {
- /* Put up a message box noting that a read failed somewhere along
- the line. */
- display_basename = g_filename_display_basename(in_files[i].filename);
- switch (read_err) {
-
- case WTAP_ERR_UNSUPPORTED_ENCAP:
- simple_error_message_box(
- "The capture file %s has a packet with a network type that Wireshark doesn't support.\n(%s)",
- display_basename, err_info);
- g_free(err_info);
- break;
-
- case WTAP_ERR_CANT_READ:
- simple_error_message_box(
- "An attempt to read from the capture file %s failed for"
- " some unknown reason.", display_basename);
- break;
+ /* prepare our callback routine */
+ cb.callback_func = merge_callback;
+ cb.data = g_malloc0(sizeof(callback_data_t));
- case WTAP_ERR_SHORT_READ:
- simple_error_message_box(
- "The capture file %s appears to have been cut short"
- " in the middle of a packet.", display_basename);
- break;
+ /* merge the files */
+ status = merge_files(out_fd, out_filename, file_type,
+ (const char *const *) in_filenames, in_file_count,
+ do_append, IDB_MERGE_MODE_ALL_SAME, 0 /* snaplen */,
+ "Wireshark", &cb, &err, &err_info, &err_fileno);
- case WTAP_ERR_BAD_FILE:
- simple_error_message_box(
- "The capture file %s appears to be damaged or corrupt.\n(%s)",
- display_basename, err_info);
- g_free(err_info);
- break;
+ g_free(cb.data);
- case WTAP_ERR_DECOMPRESS:
- simple_error_message_box(
- "The compressed capture file %s appears to be damaged or corrupt.\n"
- "(%s)", display_basename, err_info);
- g_free(err_info);
- break;
+ switch (status) {
+ case MERGE_OK:
+ break;
- default:
- simple_error_message_box(
- "An error occurred while reading the"
- " capture file %s: %s.",
- display_basename, wtap_strerror(read_err));
- break;
- }
- g_free(display_basename);
- }
- }
- }
+ case MERGE_USER_ABORTED:
+ /* this isn't really an error, though we will return CF_ERROR later */
+ break;
- if (got_write_error) {
- /* Put up an alert box for the write error. */
- if (write_err < 0) {
- /* Wiretap error. */
- switch (write_err) {
+ case MERGE_ERR_CANT_OPEN_INFILE:
+ cf_open_failure_alert_box(in_filenames[err_fileno], err, err_info,
+ FALSE, 0);
+ ws_close(out_fd);
+ break;
- case WTAP_ERR_UNSUPPORTED_ENCAP:
- /*
- * This is a problem with the particular frame we're writing;
- * note that, and give the frame number.
- */
- display_basename = g_filename_display_basename(in_file->filename);
- simple_error_message_box(
- "Frame %u of \"%s\" has a network type that can't be saved in a \"%s\" file.",
- in_file->packet_num, display_basename,
- wtap_file_type_subtype_string(file_type));
- g_free(display_basename);
- break;
+ case MERGE_ERR_CANT_OPEN_OUTFILE:
+ cf_open_failure_alert_box(out_filename, err, err_info, TRUE,
+ file_type);
+ ws_close(out_fd);
+ break;
- default:
- display_basename = g_filename_display_basename(out_filename);
- simple_error_message_box(
- "An error occurred while writing to the file \"%s\": %s.",
- out_filename, wtap_strerror(write_err));
- g_free(display_basename);
- break;
- }
- } else {
- /* OS error. */
- write_failure_alert_box(out_filename, write_err);
- }
+ case MERGE_ERR_CANT_READ_INFILE: /* fall through */
+ case MERGE_ERR_BAD_PHDR_INTERFACE_ID:
+ case MERGE_ERR_CANT_WRITE_OUTFILE:
+ case MERGE_ERR_CANT_CLOSE_OUTFILE:
+ default:
+ simple_error_message_box("%s", err_info ? err_info : "unknown error");
+ break;
}
- if (got_read_error || got_write_error || stop_flag) {
+ g_free(err_info);
+ /* for general case, no need to close out_fd: file handle associated to this file
+ descriptor was already closed by the call to wtap_dump_close() in merge_files() */
+
+ if (status != MERGE_OK) {
/* Callers aren't expected to treat an error or an explicit abort
differently - we put up error dialogs ourselves, so they don't
have to. */
const char *filter_new = dftext ? dftext : "";
const char *filter_old = cf->dfilter ? cf->dfilter : "";
dfilter_t *dfcode;
+ gchar *err_msg;
GTimeVal start_time;
/* if new filter equals old one, do nothing unless told to do so */
* and try to compile it.
*/
dftext = g_strdup(dftext);
- if (!dfilter_compile(dftext, &dfcode)) {
+ if (!dfilter_compile(dftext, &dfcode, &err_msg)) {
/* The attempt failed; report an error. */
simple_message_box(ESD_TYPE_ERROR, NULL,
"See the help for a description of the display filter syntax.",
"\"%s\" isn't a valid display filter: %s",
- dftext, dfilter_error_msg);
+ dftext, err_msg);
+ g_free(err_msg);
g_free(dftext);
return CF_ERROR;
}
/* Now rescan the packet list, applying the new filter, but not
throwing away information constructed on a previous pass. */
- if (dftext == NULL) {
- rescan_packets(cf, "Resetting", "Filter", FALSE);
- } else {
- rescan_packets(cf, "Filtering", dftext, FALSE);
+ if (cf->state != FILE_CLOSED) {
+ if (dftext == NULL) {
+ rescan_packets(cf, "Resetting", "Filter", FALSE);
+ } else {
+ rescan_packets(cf, "Filtering", dftext, FALSE);
+ }
}
/* Cleanup and release all dfilter resources */
}
gboolean
-cf_read_frame_r(capture_file *cf, const frame_data *fdata,
- struct wtap_pkthdr *phdr, Buffer *buf)
+cf_read_record_r(capture_file *cf, const frame_data *fdata,
+ struct wtap_pkthdr *phdr, Buffer *buf)
{
int err;
gchar *err_info;
const modified_frame_data *frame = (const modified_frame_data *) g_tree_lookup(cf->edited_frames, GINT_TO_POINTER(fdata->num));
if (!frame) {
- simple_error_message_box("fdata->file_off == -1, but can't find modified frame!");
+ simple_error_message_box("fdata->file_off == -1, but can't find modified frame.");
return FALSE;
}
*phdr = frame->phdr;
- buffer_assure_space(buf, frame->phdr.caplen);
- memcpy(buffer_start_ptr(buf), frame->pd, frame->phdr.caplen);
+ ws_buffer_assure_space(buf, frame->phdr.caplen);
+ memcpy(ws_buffer_start_ptr(buf), frame->pd, frame->phdr.caplen);
return TRUE;
}
#endif
display_basename = g_filename_display_basename(cf->filename);
switch (err) {
- case WTAP_ERR_UNSUPPORTED_ENCAP:
- simple_error_message_box("The file \"%s\" has a packet with a network type that Wireshark doesn't support.\n(%s)",
- display_basename, err_info);
- g_free(err_info);
- break;
-
case WTAP_ERR_BAD_FILE:
simple_error_message_box("An error occurred while reading from the file \"%s\": %s.\n(%s)",
- display_basename, wtap_strerror(err), err_info);
+ display_basename, wtap_strerror(err),
+ err_info != NULL ? err_info : "no information supplied");
g_free(err_info);
break;
}
gboolean
-cf_read_frame(capture_file *cf, frame_data *fdata)
+cf_read_record(capture_file *cf, frame_data *fdata)
{
- return cf_read_frame_r(cf, fdata, &cf->phdr, &cf->buf);
+ return cf_read_record_r(cf, fdata, &cf->phdr, &cf->buf);
}
/* Rescan the list of packets, reconstructing the CList.
guint32 framenum;
frame_data *fdata;
progdlg_t *progbar = NULL;
- gboolean stop_flag;
int count;
frame_data *selected_frame, *preceding_frame, *following_frame, *prev_frame;
int selected_frame_num, preceding_frame_num, following_frame_num, prev_frame_num;
* We assume this will not fail since cf->dfilter is only set in
* cf_filter IFF the filter was valid.
*/
- compiled = dfilter_compile(cf->dfilter, &dfcode);
+ compiled = dfilter_compile(cf->dfilter, &dfcode, NULL);
g_assert(!cf->dfilter || (compiled && dfcode));
/* Get the union of the flags for all tap listeners. */
/* 'reset' dissection session */
epan_free(cf->epan);
cf->epan = ws_epan_new(cf);
+ cf->cinfo.epan = cf->epan;
/* We need to redissect the packets so we have to discard our old
* packet list store. */
cf->prev_cap = NULL;
cf->cum_bytes = 0;
+ cf_callback_invoke(cf_cb_file_rescan_started, cf);
+
/* Update the progress bar when it gets to this value. */
progbar_nextstep = 0;
/* When we reach the value that triggers a progress bar update,
/* Progress so far. */
progbar_val = 0.0f;
- stop_flag = FALSE;
+ cf->stop_flag = FALSE;
g_get_current_time(&start_time);
/* no previous row yet */
time in order to get to the next progress bar step). */
if (progbar == NULL)
progbar = delayed_create_progress_dlg(cf->window, action, action_item, TRUE,
- &stop_flag, &start_time,
+ &cf->stop_flag,
+ &start_time,
progbar_val);
/* Update the progress bar, but do it only N_PROGBAR_UPDATES times;
progbar_nextstep += progbar_quantum;
}
- if (stop_flag) {
+ if (cf->stop_flag) {
/* Well, the user decided to abort the filtering. Just stop.
XXX - go back to the previous filter? Users probably just
/* Frame dependencies from the previous dissection/filtering are no longer valid. */
fdata->flags.dependent_of_displayed = 0;
- if (!cf_read_frame(cf, fdata))
+ if (!cf_read_record(cf, fdata))
break; /* error reading the frame */
/* If the previous frame is displayed, and we haven't yet seen the
add_packet_to_packet_list(fdata, cf, &edt, dfcode,
cinfo, &cf->phdr,
- buffer_start_ptr(&cf->buf),
+ ws_buffer_start_ptr(&cf->buf),
add_to_packet_list);
/* If this frame is displayed, and this is the first frame we've
packet_list_thaw();
+ cf_callback_invoke(cf_cb_file_rescan_finished, cf);
+
if (selected_frame_num == -1) {
/* The selected frame didn't pass the filter. */
if (selected_frame == NULL) {
so we can't select it. */
simple_message_box(ESD_TYPE_INFO, NULL,
"The capture file is probably not fully dissected.",
- "End of capture exceeded!");
+ "End of capture exceeded.");
}
}
}
if ( (fdata->flags.passed_dfilter) || (fdata->flags.ref_time) ) {
/* This frame either passed the display filter list or is marked as
a time reference frame. All time reference frames are displayed
- even if they dont pass the display filter */
+ even if they don't pass the display filter */
if (fdata->flags.ref_time) {
/* if this was a TIME REF frame we should reset the cum_bytes field */
cf->cum_bytes = fdata->pkt_len;
} psp_return_t;
static psp_return_t
-process_specified_packets(capture_file *cf, packet_range_t *range,
+process_specified_records(capture_file *cf, packet_range_t *range,
const char *string1, const char *string2, gboolean terminate_is_stop,
gboolean (*callback)(capture_file *, frame_data *,
struct wtap_pkthdr *, const guint8 *, void *),
progdlg_t *progbar = NULL;
int progbar_count;
float progbar_val;
- gboolean progbar_stop_flag;
GTimeVal progbar_start_time;
gchar progbar_status_str[100];
int progbar_nextstep;
range_process_e process_this;
struct wtap_pkthdr phdr;
- memset(&phdr, 0, sizeof(struct wtap_pkthdr));
- buffer_init(&buf, 1500);
+ wtap_phdr_init(&phdr);
+ ws_buffer_init(&buf, 1500);
/* Update the progress bar when it gets to this value. */
progbar_nextstep = 0;
/* Progress so far. */
progbar_val = 0.0f;
- progbar_stop_flag = FALSE;
+ cf->stop_flag = FALSE;
g_get_current_time(&progbar_start_time);
if (range != NULL)
if (progbar == NULL)
progbar = delayed_create_progress_dlg(cf->window, string1, string2,
terminate_is_stop,
- &progbar_stop_flag,
+ &cf->stop_flag,
&progbar_start_time,
progbar_val);
progbar_nextstep += progbar_quantum;
}
- if (progbar_stop_flag) {
+ if (cf->stop_flag) {
/* Well, the user decided to abort the operation. Just stop,
and arrange to return PSP_STOPPED to our caller, so they know
it was stopped explicitly. */
}
/* Get the packet */
- if (!cf_read_frame_r(cf, fdata, &phdr, &buf)) {
+ if (!cf_read_record_r(cf, fdata, &phdr, &buf)) {
/* Attempt to get the packet failed. */
ret = PSP_FAILED;
break;
}
/* Process the packet */
- if (!callback(cf, fdata, &phdr, buffer_start_ptr(&buf), callback_args)) {
+ if (!callback(cf, fdata, &phdr, ws_buffer_start_ptr(&buf), callback_args)) {
/* Callback failed. We assume it reported the error appropriately. */
ret = PSP_FAILED;
break;
if (progbar != NULL)
destroy_progress_dlg(progbar);
- buffer_free(&buf);
+ wtap_phdr_cleanup(&phdr);
+ ws_buffer_free(&buf);
return ret;
}
} retap_callback_args_t;
static gboolean
-retap_packet(capture_file *cf _U_, frame_data *fdata,
+retap_packet(capture_file *cf, frame_data *fdata,
struct wtap_pkthdr *phdr, const guint8 *pd,
void *argsp)
{
retap_callback_args_t *args = (retap_callback_args_t *)argsp;
- epan_dissect_run_with_taps(&args->edt, phdr, frame_tvbuff_new(fdata, pd), fdata, args->cinfo);
+ epan_dissect_run_with_taps(&args->edt, cf->cd_t, phdr, frame_tvbuff_new(fdata, pd), fdata, args->cinfo);
epan_dissect_reset(&args->edt);
return TRUE;
guint tap_flags;
psp_return_t ret;
+ /* Presumably the user closed the capture file. */
+ if (cf == NULL) {
+ return CF_READ_ABORTED;
+ }
+
+ cf_callback_invoke(cf_cb_file_retap_started, cf);
+
/* Do we have any tap listeners with filters? */
filtering_tap_listeners = have_filtering_tap_listeners();
packet_range_init(&range, cf);
packet_range_process_init(&range);
- ret = process_specified_packets(cf, &range, "Recalculating statistics on",
+ ret = process_specified_records(cf, &range, "Recalculating statistics on",
"all packets", TRUE, retap_packet,
&callback_args);
epan_dissect_cleanup(&callback_args.edt);
+ cf_callback_invoke(cf_cb_file_retap_finished, cf);
+
switch (ret) {
case PSP_FINISHED:
/* Completed successfully. */
int cp_off;
char bookmark_name[9+10+1]; /* "__frameNNNNNNNNNN__\0" */
char bookmark_title[6+10+1]; /* "Frame NNNNNNNNNN__\0" */
+ col_item_t* col_item;
/* Fill in the column information if we're printing the summary
information. */
if (args->print_args->print_summary) {
col_custom_prime_edt(&args->edt, &cf->cinfo);
- epan_dissect_run(&args->edt, phdr, frame_tvbuff_new(fdata, pd), fdata, &cf->cinfo);
+ epan_dissect_run(&args->edt, cf->cd_t, phdr, frame_tvbuff_new(fdata, pd), fdata, &cf->cinfo);
epan_dissect_fill_in_columns(&args->edt, FALSE, TRUE);
} else
- epan_dissect_run(&args->edt, phdr, frame_tvbuff_new(fdata, pd), fdata, NULL);
+ epan_dissect_run(&args->edt, cf->cd_t, phdr, frame_tvbuff_new(fdata, pd), fdata, NULL);
if (args->print_formfeed) {
if (!new_page(args->print_args->stream))
cp = &args->line_buf[0];
line_len = 0;
for (i = 0; i < args->num_visible_cols; i++) {
+ col_item = &cf->cinfo.columns[args->visible_cols[i]];
/* Find the length of the string for this column. */
- column_len = (int) strlen(cf->cinfo.col_data[args->visible_cols[i]]);
+ column_len = (int) strlen(col_item->col_data);
if (args->col_widths[i] > column_len)
column_len = args->col_widths[i];
}
/* Right-justify the packet number column. */
- if (cf->cinfo.col_fmt[args->visible_cols[i]] == COL_NUMBER)
- g_snprintf(cp, column_len+1, "%*s", args->col_widths[i], cf->cinfo.col_data[args->visible_cols[i]]);
+ if (col_item->col_fmt == COL_NUMBER)
+ g_snprintf(cp, column_len+1, "%*s", args->col_widths[i], col_item->col_data);
else
- g_snprintf(cp, column_len+1, "%-*s", args->col_widths[i], cf->cinfo.col_data[args->visible_cols[i]]);
+ g_snprintf(cp, column_len+1, "%-*s", args->col_widths[i], col_item->col_data);
cp += column_len;
if (i != args->num_visible_cols - 1)
*cp++ = ' ';
}
/* Print the information in that tree. */
- if (!proto_tree_print(args->print_args, &args->edt, args->print_args->stream))
+ if (!proto_tree_print(args->print_args, &args->edt, NULL, args->print_args->stream))
goto fail;
/* Print a blank line if we print anything after this (aka more than one packet). */
callback_args.num_visible_cols = 0;
callback_args.visible_cols = NULL;
- if (!print_preamble(print_args->stream, cf->filename, wireshark_svnversion)) {
+ if (!print_preamble(print_args->stream, cf->filename, get_ws_vcs_version_info())) {
destroy_print_stream(print_args->stream);
return CF_PRINT_WRITE_ERROR;
}
if (i == last_visible_col)
callback_args.col_widths[visible_col_count] = 0;
else {
- callback_args.col_widths[visible_col_count] = (gint) strlen(cf->cinfo.col_title[i]);
+ callback_args.col_widths[visible_col_count] = (gint) strlen(cf->cinfo.columns[i].col_title);
data_width = get_column_char_width(get_column_format(i));
if (data_width > callback_args.col_widths[visible_col_count])
callback_args.col_widths[visible_col_count] = data_width;
}
/* Find the length of the string for this column. */
- column_len = (int) strlen(cf->cinfo.col_title[i]);
+ column_len = (int) strlen(cf->cinfo.columns[i].col_title);
if (callback_args.col_widths[i] > column_len)
column_len = callback_args.col_widths[visible_col_count];
/* Right-justify the packet number column. */
/* if (cf->cinfo.col_fmt[i] == COL_NUMBER)
- g_snprintf(cp, column_len+1, "%*s", callback_args.col_widths[visible_col_count], cf->cinfo.col_title[i]);
+ g_snprintf(cp, column_len+1, "%*s", callback_args.col_widths[visible_col_count], cf->cinfo.columns[i].col_title);
else*/
- g_snprintf(cp, column_len+1, "%-*s", callback_args.col_widths[visible_col_count], cf->cinfo.col_title[i]);
+ g_snprintf(cp, column_len+1, "%-*s", callback_args.col_widths[visible_col_count], cf->cinfo.columns[i].col_title);
cp += column_len;
if (i != cf->cinfo.num_cols - 1)
*cp++ = ' ';
/* Iterate through the list of packets, printing the packets we were
told to print. */
- ret = process_specified_packets(cf, &print_args->range, "Printing",
+ ret = process_specified_records(cf, &print_args->range, "Printing",
"selected packets", TRUE, print_packet,
&callback_args);
epan_dissect_cleanup(&callback_args.edt);
} write_packet_callback_args_t;
static gboolean
-write_pdml_packet(capture_file *cf _U_, frame_data *fdata,
+write_pdml_packet(capture_file *cf, frame_data *fdata,
struct wtap_pkthdr *phdr, const guint8 *pd,
void *argsp)
{
write_packet_callback_args_t *args = (write_packet_callback_args_t *)argsp;
/* Create the protocol tree, but don't fill in the column information. */
- epan_dissect_run(&args->edt, phdr, frame_tvbuff_new(fdata, pd), fdata, NULL);
+ epan_dissect_run(&args->edt, cf->cd_t, phdr, frame_tvbuff_new(fdata, pd), fdata, NULL);
/* Write out the information in that tree. */
- proto_tree_write_pdml(&args->edt, args->fh);
+ write_pdml_proto_tree(&args->edt, args->fh);
epan_dissect_reset(&args->edt);
/* Iterate through the list of packets, printing the packets we were
told to print. */
- ret = process_specified_packets(cf, &print_args->range, "Writing PDML",
+ ret = process_specified_records(cf, &print_args->range, "Writing PDML",
"selected packets", TRUE,
write_pdml_packet, &callback_args);
{
write_packet_callback_args_t *args = (write_packet_callback_args_t *)argsp;
+ /* Fill in the column information */
col_custom_prime_edt(&args->edt, &cf->cinfo);
- epan_dissect_run(&args->edt, phdr, frame_tvbuff_new(fdata, pd), fdata, &cf->cinfo);
+ epan_dissect_run(&args->edt, cf->cd_t, phdr, frame_tvbuff_new(fdata, pd), fdata, &cf->cinfo);
epan_dissect_fill_in_columns(&args->edt, FALSE, TRUE);
- /* Write out the information in that tree. */
- proto_tree_write_psml(&args->edt, args->fh);
+ /* Write out the column information. */
+ write_psml_columns(&args->edt, args->fh);
epan_dissect_reset(&args->edt);
if (fh == NULL)
return CF_PRINT_OPEN_ERROR; /* attempt to open destination failed */
- write_psml_preamble(fh);
+ write_psml_preamble(&cf->cinfo, fh);
if (ferror(fh)) {
fclose(fh);
return CF_PRINT_WRITE_ERROR;
/* Iterate through the list of packets, printing the packets we were
told to print. */
- ret = process_specified_packets(cf, &print_args->range, "Writing PSML",
+ ret = process_specified_records(cf, &print_args->range, "Writing PSML",
"selected packets", TRUE,
write_psml_packet, &callback_args);
/* Fill in the column information */
col_custom_prime_edt(&args->edt, &cf->cinfo);
- epan_dissect_run(&args->edt, phdr, frame_tvbuff_new(fdata, pd), fdata, &cf->cinfo);
+ epan_dissect_run(&args->edt, cf->cd_t, phdr, frame_tvbuff_new(fdata, pd), fdata, &cf->cinfo);
epan_dissect_fill_in_columns(&args->edt, FALSE, TRUE);
- /* Write out the information in that tree. */
- proto_tree_write_csv(&args->edt, args->fh);
+ /* Write out the column information. */
+ write_csv_columns(&args->edt, args->fh);
epan_dissect_reset(&args->edt);
if (fh == NULL)
return CF_PRINT_OPEN_ERROR; /* attempt to open destination failed */
- write_csv_preamble(fh);
+ write_csv_column_titles(&cf->cinfo, fh);
if (ferror(fh)) {
fclose(fh);
return CF_PRINT_WRITE_ERROR;
/* Iterate through the list of packets, printing the packets we were
told to print. */
- ret = process_specified_packets(cf, &print_args->range, "Writing CSV",
+ ret = process_specified_records(cf, &print_args->range, "Writing CSV",
"selected packets", TRUE,
write_csv_packet, &callback_args);
return CF_PRINT_WRITE_ERROR;
}
- write_csv_finale(fh);
- if (ferror(fh)) {
- fclose(fh);
- return CF_PRINT_WRITE_ERROR;
- }
-
/* XXX - check for an error */
fclose(fh);
}
static gboolean
-write_carrays_packet(capture_file *cf _U_, frame_data *fdata,
+carrays_write_packet(capture_file *cf, frame_data *fdata,
struct wtap_pkthdr *phdr,
const guint8 *pd, void *argsp)
{
write_packet_callback_args_t *args = (write_packet_callback_args_t *)argsp;
- epan_dissect_run(&args->edt, phdr, frame_tvbuff_new(fdata, pd), fdata, NULL);
- proto_tree_write_carrays(fdata->num, args->fh, &args->edt);
+ epan_dissect_run(&args->edt, cf->cd_t, phdr, frame_tvbuff_new(fdata, pd), fdata, NULL);
+ write_carrays_hex_data(fdata->num, args->fh, &args->edt);
epan_dissect_reset(&args->edt);
return !ferror(args->fh);
if (fh == NULL)
return CF_PRINT_OPEN_ERROR; /* attempt to open destination failed */
- write_carrays_preamble(fh);
-
if (ferror(fh)) {
fclose(fh);
return CF_PRINT_WRITE_ERROR;
/* Iterate through the list of packets, printing the packets we were
told to print. */
- ret = process_specified_packets(cf, &print_args->range,
+ ret = process_specified_records(cf, &print_args->range,
"Writing C Arrays",
"selected packets", TRUE,
- write_carrays_packet, &callback_args);
+ carrays_write_packet, &callback_args);
epan_dissect_cleanup(&callback_args.edt);
return CF_PRINT_WRITE_ERROR;
}
- write_carrays_finale(fh);
-
- if (ferror(fh)) {
- fclose(fh);
- return CF_PRINT_WRITE_ERROR;
- }
-
fclose(fh);
return CF_PRINT_OK;
}
epan_dissect_t edt;
/* Load the frame's data. */
- if (!cf_read_frame(cf, fdata)) {
+ if (!cf_read_record(cf, fdata)) {
/* Attempt to get the packet failed. */
return MR_ERROR;
}
/* Construct the protocol tree, including the displayed text */
epan_dissect_init(&edt, cf->epan, TRUE, TRUE);
/* We don't need the column information */
- epan_dissect_run(&edt, &cf->phdr, frame_tvbuff_new_buffer(fdata, &cf->buf), fdata, NULL);
+ epan_dissect_run(&edt, cf->cd_t, &cf->phdr, frame_tvbuff_new_buffer(fdata, &cf->buf), fdata, NULL);
/* Iterate through all the nodes, seeing if they have text that matches. */
mdata->cf = cf;
for (i = 0; i < label_len; i++) {
c_char = label_ptr[i];
if (cf->case_type)
- c_char = toupper(c_char);
+ c_char = g_ascii_toupper(c_char);
if (c_char == string[c_match]) {
c_match++;
if (c_match == string_len) {
size_t c_match = 0;
/* Load the frame's data. */
- if (!cf_read_frame(cf, fdata)) {
+ if (!cf_read_record(cf, fdata)) {
/* Attempt to get the packet failed. */
return MR_ERROR;
}
/* Don't bother constructing the protocol tree */
epan_dissect_init(&edt, cf->epan, FALSE, FALSE);
/* Get the column information */
- epan_dissect_run(&edt, &cf->phdr, frame_tvbuff_new_buffer(fdata, &cf->buf), fdata,
+ epan_dissect_run(&edt, cf->cd_t, &cf->phdr, frame_tvbuff_new_buffer(fdata, &cf->buf), fdata,
&cf->cinfo);
/* Find the Info column */
for (colx = 0; colx < cf->cinfo.num_cols; colx++) {
- if (cf->cinfo.fmt_matx[colx][COL_INFO]) {
+ if (cf->cinfo.columns[colx].fmt_matx[COL_INFO]) {
/* Found it. See if we match. */
- info_column = edt.pi.cinfo->col_data[colx];
+ info_column = edt.pi.cinfo->columns[colx].col_data;
info_column_len = strlen(info_column);
for (i = 0; i < info_column_len; i++) {
c_char = info_column[i];
if (cf->case_type)
- c_char = toupper(c_char);
+ c_char = g_ascii_toupper(c_char);
if (c_char == string[c_match]) {
c_match++;
if (c_match == string_len) {
size_t c_match = 0;
/* Load the frame's data. */
- if (!cf_read_frame(cf, fdata)) {
+ if (!cf_read_record(cf, fdata)) {
/* Attempt to get the packet failed. */
return MR_ERROR;
}
result = MR_NOTMATCHED;
buf_len = fdata->cap_len;
- pd = buffer_start_ptr(&cf->buf);
+ pd = ws_buffer_start_ptr(&cf->buf);
i = 0;
while (i < buf_len) {
c_char = pd[i];
if (cf->case_type)
- c_char = toupper(c_char);
+ c_char = g_ascii_toupper(c_char);
if (c_char != '\0') {
if (c_char == ascii_text[c_match]) {
c_match += 1;
size_t c_match = 0;
/* Load the frame's data. */
- if (!cf_read_frame(cf, fdata)) {
+ if (!cf_read_record(cf, fdata)) {
/* Attempt to get the packet failed. */
return MR_ERROR;
}
result = MR_NOTMATCHED;
buf_len = fdata->cap_len;
- pd = buffer_start_ptr(&cf->buf);
+ pd = ws_buffer_start_ptr(&cf->buf);
i = 0;
while (i < buf_len) {
c_char = pd[i];
if (cf->case_type)
- c_char = toupper(c_char);
+ c_char = g_ascii_toupper(c_char);
if (c_char == ascii_text[c_match]) {
c_match += 1;
if (c_match == textlen) {
size_t c_match = 0;
/* Load the frame's data. */
- if (!cf_read_frame(cf, fdata)) {
+ if (!cf_read_record(cf, fdata)) {
/* Attempt to get the packet failed. */
return MR_ERROR;
}
result = MR_NOTMATCHED;
buf_len = fdata->cap_len;
- pd = buffer_start_ptr(&cf->buf);
+ pd = ws_buffer_start_ptr(&cf->buf);
i = 0;
while (i < buf_len) {
c_char = pd[i];
if (cf->case_type)
- c_char = toupper(c_char);
+ c_char = g_ascii_toupper(c_char);
if (c_char == ascii_text[c_match]) {
c_match += 1;
if (c_match == textlen) {
size_t c_match = 0;
/* Load the frame's data. */
- if (!cf_read_frame(cf, fdata)) {
+ if (!cf_read_record(cf, fdata)) {
/* Attempt to get the packet failed. */
return MR_ERROR;
}
result = MR_NOTMATCHED;
buf_len = fdata->cap_len;
- pd = buffer_start_ptr(&cf->buf);
+ pd = ws_buffer_start_ptr(&cf->buf);
i = 0;
while (i < buf_len) {
if (pd[i] == binary_data[c_match]) {
dfilter_t *sfcode;
gboolean result;
- if (!dfilter_compile(filter, &sfcode)) {
+ if (!dfilter_compile(filter, &sfcode, NULL)) {
/*
* XXX - this shouldn't happen, as the filter string is machine
* generated
match_result result;
/* Load the frame's data. */
- if (!cf_read_frame(cf, fdata)) {
+ if (!cf_read_record(cf, fdata)) {
/* Attempt to get the packet failed. */
return MR_ERROR;
}
epan_dissect_init(&edt, cf->epan, TRUE, FALSE);
epan_dissect_prime_dfilter(&edt, sfcode);
- epan_dissect_run(&edt, &cf->phdr, frame_tvbuff_new_buffer(fdata, &cf->buf), fdata, NULL);
+ epan_dissect_run(&edt, cf->cd_t, &cf->phdr, frame_tvbuff_new_buffer(fdata, &cf->buf), fdata, NULL);
result = dfilter_apply_edt(sfcode, &edt) ? MR_MATCHED : MR_NOTMATCHED;
epan_dissect_cleanup(&edt);
return result;
frame_data *fdata;
frame_data *new_fd = NULL;
progdlg_t *progbar = NULL;
- gboolean stop_flag;
int count;
gboolean found;
float progbar_val;
/* Progress so far. */
progbar_val = 0.0f;
- stop_flag = FALSE;
+ cf->stop_flag = FALSE;
g_get_current_time(&start_time);
title = cf->sfilter?cf->sfilter:"";
time in order to get to the next progress bar step). */
if (progbar == NULL)
progbar = delayed_create_progress_dlg(cf->window, "Searching", title,
- FALSE, &stop_flag, &start_time, progbar_val);
+ FALSE, &cf->stop_flag, &start_time, progbar_val);
/* Update the progress bar, but do it only N_PROGBAR_UPDATES times;
when we update it, we have to run the GTK+ main loop to get it
progbar_nextstep += progbar_quantum;
}
- if (stop_flag) {
+ if (cf->stop_flag) {
/* Well, the user decided to abort the search. Go back to the
frame where we started. */
new_fd = start_fd;
so we can't select it. */
simple_message_box(ESD_TYPE_INFO, NULL,
"The capture file is probably not fully dissected.",
- "End of capture exceeded!");
+ "End of capture exceeded.");
return FALSE;
}
return TRUE; /* success */
so we can't select it. */
simple_message_box(ESD_TYPE_INFO, NULL,
"The capture file is probably not fully dissected.",
- "End of capture exceeded!");
+ "End of capture exceeded.");
return FALSE;
}
return TRUE; /* we got to that packet */
}
/* Get the data in that frame. */
- if (!cf_read_frame (cf, fdata)) {
+ if (!cf_read_record (cf, fdata)) {
return;
}
cf->edt = epan_dissect_new(cf->epan, TRUE, TRUE);
tap_build_interesting(cf->edt);
- epan_dissect_run(cf->edt, &cf->phdr, frame_tvbuff_new_buffer(cf->current_frame, &cf->buf),
+ epan_dissect_run(cf->edt, cf->cd_t, &cf->phdr, frame_tvbuff_new_buffer(cf->current_frame, &cf->buf),
cf->current_frame, NULL);
dfilter_macro_build_ftv_cache(cf->edt->tree);
const gchar *
cf_read_shb_comment(capture_file *cf)
{
- wtapng_section_t *shb_inf;
- const gchar *temp_str;
-
/* Get info from SHB */
- shb_inf = wtap_file_get_shb_info(cf->wth);
- if (shb_inf == NULL)
- return NULL;
- temp_str = shb_inf->opt_comment;
- g_free(shb_inf);
-
- return temp_str;
-
+ return wtap_file_get_shb_comment(cf->wth);
}
void
cf_update_capture_comment(capture_file *cf, gchar *comment)
{
- wtapng_section_t *shb_inf;
+ const gchar *shb_comment;
/* Get info from SHB */
- shb_inf = wtap_file_get_shb_info(cf->wth);
+ shb_comment = wtap_file_get_shb_comment(cf->wth);
/* See if the comment has changed or not */
- if (shb_inf && shb_inf->opt_comment) {
- if (strcmp(shb_inf->opt_comment, comment) == 0) {
+ if (shb_comment) {
+ if (strcmp(shb_comment, comment) == 0) {
g_free(comment);
- g_free(shb_inf);
return;
}
}
- g_free(shb_inf);
-
/* The comment has changed, let's update it */
wtap_write_shb_comment(cf->wth, comment);
/* Mark the file as having unsaved changes */
char *
cf_get_comment(capture_file *cf, const frame_data *fd)
{
+ char *comment;
+
/* fetch user comment */
if (fd->flags.has_user_comment)
return g_strdup(cf_get_user_packet_comment(cf, fd));
struct wtap_pkthdr phdr; /* Packet header */
Buffer buf; /* Packet data */
- phdr.opt_comment = NULL;
+ wtap_phdr_init(&phdr);
+ ws_buffer_init(&buf, 1500);
- buffer_init(&buf, 1500);
- if (!cf_read_frame_r(cf, fd, &phdr, &buf))
+ if (!cf_read_record_r(cf, fd, &phdr, &buf))
{ /* XXX, what we can do here? */ }
- buffer_free(&buf);
- return phdr.opt_comment;
+ comment = phdr.opt_comment;
+ wtap_phdr_cleanup(&phdr);
+ ws_buffer_free(&buf);
+ return comment;
}
return NULL;
}
return comment_types;
}
+#ifdef WANT_PACKET_EDITOR
+static gint
+g_direct_compare_func(gconstpointer a, gconstpointer b, gpointer user_data _U_)
+{
+ if (a > b)
+ return 1;
+ else if (a < b)
+ return -1;
+ else
+ return 0;
+}
+
+static void
+modified_frame_data_free(gpointer data)
+{
+ modified_frame_data *mfd = (modified_frame_data *)data;
+
+ g_free(mfd->pd);
+ g_free(mfd);
+}
+
+/*
+ * Give a frame new, edited data.
+ */
+void
+cf_set_frame_edited(capture_file *cf, frame_data *fd,
+ struct wtap_pkthdr *phdr, guint8 *pd)
+{
+ modified_frame_data *mfd = (modified_frame_data *)g_malloc(sizeof(modified_frame_data));
+
+ mfd->phdr = *phdr;
+ mfd->pd = pd;
+
+ if (cf->edited_frames == NULL)
+ cf->edited_frames = g_tree_new_full(g_direct_compare_func, NULL, NULL,
+ modified_frame_data_free);
+ g_tree_insert(cf->edited_frames, GINT_TO_POINTER(fd->num), mfd);
+ fd->file_off = -1;
+
+ /* Mark the file as having unsaved changes */
+ cf->unsaved_changes = TRUE;
+}
+#endif
+
typedef struct {
wtap_dumper *pdh;
const char *fname;
* up a message box for the failure.
*/
static gboolean
-save_packet(capture_file *cf _U_, frame_data *fdata,
+save_record(capture_file *cf, frame_data *fdata,
struct wtap_pkthdr *phdr, const guint8 *pd,
void *argsp)
{
save_callback_args_t *args = (save_callback_args_t *)argsp;
struct wtap_pkthdr hdr;
int err;
+ gchar *err_info;
gchar *display_basename;
const char *pkt_comment;
For WTAP_HAS_PACK_FLAGS, we currently don't save the FCS length
from the packet flags. */
+ hdr.rec_type = phdr->rec_type;
hdr.presence_flags = 0;
if (fdata->flags.has_ts)
hdr.presence_flags |= WTAP_HAS_TS;
hdr.presence_flags |= WTAP_HAS_PACK_FLAGS;
hdr.ts.secs = fdata->abs_ts.secs;
hdr.ts.nsecs = fdata->abs_ts.nsecs;
- hdr.caplen = fdata->cap_len;
- hdr.len = fdata->pkt_len;
+ hdr.caplen = phdr->caplen;
+ hdr.len = phdr->len;
hdr.pkt_encap = fdata->lnk_t;
/* pcapng */
hdr.interface_id = phdr->interface_id; /* identifier of the interface. */
hdr.pack_flags = /* XXX - 0 for now (any value for "we don't have it"?) */
#endif
/* and save the packet */
- if (!wtap_dump(args->pdh, &hdr, pd, &err)) {
+ if (!wtap_dump(args->pdh, &hdr, pd, &err, &err_info)) {
if (err < 0) {
/* Wiretap error. */
switch (err) {
- case WTAP_ERR_UNSUPPORTED_ENCAP:
+ case WTAP_ERR_UNWRITABLE_ENCAP:
/*
- * This is a problem with the particular frame we're writing;
- * note that, and give the frame number.
+ * This is a problem with the particular frame we're writing and
+ * the file type and subtype we're writing; note that, and report
+ * the frame number and file type/subtype.
*/
simple_error_message_box(
"Frame %u has a network type that can't be saved in a \"%s\" file.",
fdata->num, wtap_file_type_subtype_string(args->file_type));
break;
+ case WTAP_ERR_PACKET_TOO_LARGE:
+ /*
+ * This is a problem with the particular frame we're writing and
+ * the file type and subtype we're writing; note that, and report
+ * the frame number and file type/subtype.
+ */
+ simple_error_message_box(
+ "Frame %u is larger than Wireshark supports in a \"%s\" file.",
+ fdata->num, wtap_file_type_subtype_string(args->file_type));
+ break;
+
+ case WTAP_ERR_UNWRITABLE_REC_TYPE:
+ /*
+ * This is a problem with the particular record we're writing and
+ * the file type and subtype we're writing; note that, and report
+ * the record number and file type/subtype.
+ */
+ simple_error_message_box(
+ "Record %u has a record type that can't be saved in a \"%s\" file.",
+ fdata->num, wtap_file_type_subtype_string(args->file_type));
+ break;
+
+ case WTAP_ERR_UNWRITABLE_REC_DATA:
+ /*
+ * This is a problem with the particular frame we're writing and
+ * the file type and subtype we're writing; note that, and report
+ * the frame number and file type/subtype.
+ */
+ simple_error_message_box(
+ "Record %u has data that can't be saved in a \"%s\" file.\n(%s)",
+ fdata->num, wtap_file_type_subtype_string(args->file_type),
+ err_info != NULL ? err_info : "no information supplied");
+ g_free(err_info);
+ break;
+
default:
display_basename = g_filename_display_basename(args->fname);
simple_error_message_box(
* If this is a temporary file, or a file with unsaved changes, it
* has unsaved data.
*/
- return cf->is_tempfile || cf->unsaved_changes;
+ return (cf->is_tempfile && cf->count>0) || cf->unsaved_changes;
}
/*
gchar *err_info;
gchar *name_ptr;
gint64 data_offset;
- gint64 file_pos;
progdlg_t *progbar = NULL;
- gboolean stop_flag;
gint64 size;
float progbar_val;
GTimeVal start_time;
wtap_close(cf->wth);
/* Open the new file. */
- cf->wth = wtap_open_offline(fname, err, &err_info, TRUE);
+ /* XXX: this will go through all open_routines for a matching one. But right
+ now rescan_file() is only used when a file is being saved to a different
+ format than the original, and the user is not given a choice of which
+ reader to use (only which format to save it in), so doing this makes
+ sense for now. */
+ cf->wth = wtap_open_offline(fname, WTAP_TYPE_AUTO, err, &err_info, TRUE);
if (cf->wth == NULL) {
cf_open_failure_alert_box(fname, *err, err_info, FALSE, 0);
return CF_READ_ERROR;
}else
progbar_quantum = 0;
- stop_flag = FALSE;
+ cf->stop_flag = FALSE;
g_get_current_time(&start_time);
framenum = 0;
fdata->file_off = data_offset;
if (size >= 0) {
count++;
- file_pos = wtap_read_so_far(cf->wth);
+ cf->f_datalen = wtap_read_so_far(cf->wth);
/* Create the progress bar if necessary.
* Check whether it should be created or not every MIN_NUMBER_OF_PACKET
*/
if ((progbar == NULL) && !(count % MIN_NUMBER_OF_PACKET)) {
- progbar_val = calc_progbar_val(cf, size, file_pos, status_str, sizeof(status_str));
+ progbar_val = calc_progbar_val(cf, size, cf->f_datalen, status_str, sizeof(status_str));
progbar = delayed_create_progress_dlg(cf->window, "Rescanning", name_ptr,
- TRUE, &stop_flag, &start_time, progbar_val);
+ TRUE, &cf->stop_flag, &start_time, progbar_val);
}
/* Update the progress bar, but do it only N_PROGBAR_UPDATES times;
to repaint what's pending, and doing so may involve an "ioctl()"
to see if there's any pending input from an X server, and doing
that for every packet can be costly, especially on a big file. */
- if (file_pos >= progbar_nextstep) {
+ if (cf->f_datalen >= progbar_nextstep) {
if (progbar != NULL) {
- progbar_val = calc_progbar_val(cf, size, file_pos, status_str, sizeof(status_str));
+ progbar_val = calc_progbar_val(cf, size, cf->f_datalen, status_str, sizeof(status_str));
/* update the packet bar content on the first run or frequently on very large files */
#ifdef HAVE_LIBPCAP
if (progbar_quantum > 500000 || displayed_once == 0) {
}
}
- if (stop_flag) {
+ if (cf->stop_flag) {
/* Well, the user decided to abort the rescan. Sadly, as this
isn't a reread, recovering is difficult, so we'll just
close the current capture. */
cf_callback_invoke(cf_cb_file_rescan_finished, cf);
- if (stop_flag) {
+ if (cf->stop_flag) {
/* Our caller will give up at this point. */
return CF_READ_ABORTED;
}
case WTAP_ERR_UNSUPPORTED:
simple_error_message_box(
"The capture file contains record data that Wireshark doesn't support.\n(%s)",
- err_info);
+ err_info != NULL ? err_info : "no information supplied");
g_free(err_info);
break;
- case WTAP_ERR_UNSUPPORTED_ENCAP:
- simple_error_message_box(
- "The capture file has a packet with a network type that Wireshark doesn't support.\n(%s)",
- err_info);
- g_free(err_info);
- break;
-
- case WTAP_ERR_CANT_READ:
- simple_error_message_box(
- "An attempt to read from the capture file failed for"
- " some unknown reason.");
- break;
-
case WTAP_ERR_SHORT_READ:
simple_error_message_box(
"The capture file appears to have been cut short"
case WTAP_ERR_BAD_FILE:
simple_error_message_box(
"The capture file appears to be damaged or corrupt.\n(%s)",
- err_info);
+ err_info != NULL ? err_info : "no information supplied");
g_free(err_info);
break;
case WTAP_ERR_DECOMPRESS:
simple_error_message_box(
"The compressed capture file appears to be damaged or corrupt.\n"
- "(%s)", err_info);
+ "(%s)",
+ err_info != NULL ? err_info : "no information supplied");
g_free(err_info);
break;
}
cf_write_status_t
-cf_save_packets(capture_file *cf, const char *fname, guint save_format,
+cf_save_records(capture_file *cf, const char *fname, guint save_format,
gboolean compressed, gboolean discard_comments,
gboolean dont_reopen)
{
or moving the capture file, we have to do it by writing the packets
out in Wiretap. */
- wtapng_section_t *shb_hdr = NULL;
+ wtapng_section_t *shb_hdr = NULL;
wtapng_iface_descriptions_t *idb_inf = NULL;
+ wtapng_name_res_t *nrb_hdr = NULL;
int encap;
- shb_hdr = wtap_file_get_shb_info(cf->wth);
+ /* XXX: what free's this shb_hdr? */
+ shb_hdr = wtap_file_get_shb_for_new_file(cf->wth);
idb_inf = wtap_file_get_idb_info(cf->wth);
+ nrb_hdr = wtap_file_get_nrb_for_new_file(cf->wth);
/* Determine what file encapsulation type we should use. */
encap = wtap_dump_file_encap_type(cf->linktypes);
from which we're reading the packets that we're writing!) */
fname_new = g_strdup_printf("%s~", fname);
pdh = wtap_dump_open_ng(fname_new, save_format, encap, cf->snap,
- compressed, shb_hdr, idb_inf, &err);
+ compressed, shb_hdr, idb_inf, nrb_hdr, &err);
} else {
pdh = wtap_dump_open_ng(fname, save_format, encap, cf->snap,
- compressed, shb_hdr, idb_inf, &err);
+ compressed, shb_hdr, idb_inf, nrb_hdr, &err);
}
g_free(idb_inf);
idb_inf = NULL;
callback_args.pdh = pdh;
callback_args.fname = fname;
callback_args.file_type = save_format;
- switch (process_specified_packets(cf, NULL, "Saving", "packets",
- TRUE, save_packet, &callback_args)) {
+ switch (process_specified_records(cf, NULL, "Saving", "packets",
+ TRUE, save_record, &callback_args)) {
case PSP_FINISHED:
/* Completed successfully. */
the wtap structure, the filename, and the "is temporary"
status applies to the new file; just update that. */
wtap_close(cf->wth);
- cf->wth = wtap_open_offline(fname, &err, &err_info, TRUE);
+ /* Although we're just "copying" and then opening the copy, it will
+ try all open_routine readers to open the copy, so we need to
+ reset the cfile's open_type. */
+ cf->open_type = WTAP_TYPE_AUTO;
+ cf->wth = wtap_open_offline(fname, WTAP_TYPE_AUTO, &err, &err_info, TRUE);
if (cf->wth == NULL) {
cf_open_failure_alert_box(fname, err, err_info, FALSE, 0);
cf_close(cf);
...as long as, for gzipped files, the process of writing
out the file *also* generates the information needed to
support fast random access to the compressed file. */
+ /* rescan_file will cause us to try all open_routines, so
+ reset cfile's open_type */
+ cf->open_type = WTAP_TYPE_AUTO;
if (rescan_file(cf, fname, FALSE, &err) != CF_READ_OK) {
/* The rescan failed; just close the file. Either
a dialog was popped up for the failure, so the
int err;
wtap_dumper *pdh;
save_callback_args_t callback_args;
- wtapng_section_t *shb_hdr;
- wtapng_iface_descriptions_t *idb_inf;
+ wtapng_section_t *shb_hdr = NULL;
+ wtapng_iface_descriptions_t *idb_inf = NULL;
+ wtapng_name_res_t *nrb_hdr = NULL;
int encap;
cf_callback_invoke(cf_cb_file_export_specified_packets_started, (gpointer)fname);
written, don't special-case the operation - read each packet
and then write it out if it's one of the specified ones. */
- shb_hdr = wtap_file_get_shb_info(cf->wth);
+ /* XXX: what free's this shb_hdr? */
+ shb_hdr = wtap_file_get_shb_for_new_file(cf->wth);
idb_inf = wtap_file_get_idb_info(cf->wth);
+ nrb_hdr = wtap_file_get_nrb_for_new_file(cf->wth);
/* Determine what file encapsulation type we should use. */
encap = wtap_dump_file_encap_type(cf->linktypes);
from which we're reading the packets that we're writing!) */
fname_new = g_strdup_printf("%s~", fname);
pdh = wtap_dump_open_ng(fname_new, save_format, encap, cf->snap,
- compressed, shb_hdr, idb_inf, &err);
+ compressed, shb_hdr, idb_inf, nrb_hdr, &err);
} else {
pdh = wtap_dump_open_ng(fname, save_format, encap, cf->snap,
- compressed, shb_hdr, idb_inf, &err);
+ compressed, shb_hdr, idb_inf, nrb_hdr, &err);
}
g_free(idb_inf);
idb_inf = NULL;
told to process.
XXX - we've already called "packet_range_process_init(range)", but
- "process_specified_packets()" will do it again. Fortunately,
+ "process_specified_records()" will do it again. Fortunately,
that's harmless in this case, as we haven't done anything to
"range" since we initialized it. */
callback_args.pdh = pdh;
callback_args.fname = fname;
callback_args.file_type = save_format;
- switch (process_specified_packets(cf, range, "Writing", "specified packets",
- TRUE, save_packet, &callback_args)) {
+ switch (process_specified_records(cf, range, "Writing", "specified records",
+ TRUE, save_record, &callback_args)) {
case PSP_FINISHED:
/* Completed successfully. */
case WTAP_ERR_UNSUPPORTED:
/* Seen only when opening a capture file for reading. */
simple_error_message_box(
- "The file \"%s\" isn't a capture file in a format Wireshark understands.\n"
+ "The file \"%s\" contains record data that Wireshark doesn't support.\n"
"(%s)",
- display_basename, err_info);
+ display_basename,
+ err_info != NULL ? err_info : "no information supplied");
g_free(err_info);
break;
display_basename, wtap_file_type_subtype_string(file_type));
break;
- case WTAP_ERR_UNSUPPORTED_FILE_TYPE:
+ case WTAP_ERR_UNWRITABLE_FILE_TYPE:
/* Seen only when opening a capture file for writing. */
simple_error_message_box(
"Wireshark doesn't support writing capture files in that format.");
break;
- case WTAP_ERR_UNSUPPORTED_ENCAP:
- if (for_writing) {
- simple_error_message_box("Wireshark can't save this capture in that format.");
- } else {
- simple_error_message_box(
- "The file \"%s\" is a capture for a network type that Wireshark doesn't support.\n"
- "(%s)",
- display_basename, err_info);
- g_free(err_info);
- }
+ case WTAP_ERR_UNWRITABLE_ENCAP:
+ /* Seen only when opening a capture file for writing. */
+ simple_error_message_box("Wireshark can't save this capture in that format.");
break;
case WTAP_ERR_ENCAP_PER_PACKET_UNSUPPORTED:
simple_error_message_box(
"The file \"%s\" appears to be damaged or corrupt.\n"
"(%s)",
- display_basename, err_info);
+ display_basename,
+ err_info != NULL ? err_info : "no information supplied");
g_free(err_info);
break;
case WTAP_ERR_DECOMPRESS:
simple_error_message_box(
"The compressed file \"%s\" appears to be damaged or corrupt.\n"
- "(%s)", display_basename, err_info);
+ "(%s)", display_basename,
+ err_info != NULL ? err_info : "no information supplied");
g_free(err_info);
break;
filename = g_strdup(cf->filename);
is_tempfile = cf->is_tempfile;
cf->is_tempfile = FALSE;
- if (cf_open(cf, filename, is_tempfile, &err) == CF_OK) {
+ if (cf_open(cf, filename, cf->open_type, is_tempfile, &err) == CF_OK) {
switch (cf_read(cf, TRUE)) {
case CF_READ_OK: