aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--file.c69
-rw-r--r--file.h33
-rw-r--r--ui/gtk/capture_file_dlg.c139
-rw-r--r--ui/gtk/main.c15
-rw-r--r--ui/gtk/main_statusbar.c50
5 files changed, 223 insertions, 83 deletions
diff --git a/file.c b/file.c
index 6646e3abc8..325a21a189 100644
--- a/file.c
+++ b/file.c
@@ -2087,7 +2087,8 @@ process_specified_packets(capture_file *cf, packet_range_t *range,
progbar_stop_flag = FALSE;
g_get_current_time(&progbar_start_time);
- packet_range_process_init(range);
+ if (range != NULL)
+ packet_range_process_init(range);
/* Iterate through all the packets, printing the packets that
were selected by the current display filter. */
@@ -2137,14 +2138,16 @@ process_specified_packets(capture_file *cf, packet_range_t *range,
progbar_count++;
- /* do we have to process this packet? */
- process_this = packet_range_process_packet(range, fdata);
- if (process_this == range_process_next) {
+ if (range != NULL) {
+ /* do we have to process this packet? */
+ process_this = packet_range_process_packet(range, fdata);
+ if (process_this == range_process_next) {
/* this packet uninteresting, continue with next one */
continue;
- } else if (process_this == range_processing_finished) {
+ } else if (process_this == range_processing_finished) {
/* all interesting packets processed, stop the loop */
break;
+ }
}
/* Get the packet */
@@ -3817,7 +3820,7 @@ cf_can_save_as(capture_file *cf)
return FALSE;
}
-cf_status_t
+cf_write_status_t
cf_save_packets(capture_file *cf, const char *fname, guint save_format,
gboolean compressed, gboolean dont_reopen)
{
@@ -3825,7 +3828,6 @@ cf_save_packets(capture_file *cf, const char *fname, guint save_format,
int err;
gboolean do_copy;
wtap_dumper *pdh;
- packet_range_t range;
save_callback_args_t callback_args;
cf_callback_invoke(cf_cb_file_save_started, (gpointer)fname);
@@ -3943,15 +3945,11 @@ cf_save_packets(capture_file *cf, const char *fname, guint save_format,
/* Add address resolution */
wtap_dump_set_addrinfo_list(pdh, get_addrinfo_list());
- /* Create a packet range that's set to the default "save everything"
- state. */
- packet_range_init(&range);
-
/* Iterate through the list of packets, processing all the packets. */
callback_args.pdh = pdh;
callback_args.fname = fname;
callback_args.file_type = save_format;
- switch (process_specified_packets(cf, &range, "Saving", "selected packets",
+ switch (process_specified_packets(cf, NULL, "Saving", "packets",
TRUE, save_packet, &callback_args)) {
case PSP_FINISHED:
@@ -3960,11 +3958,20 @@ cf_save_packets(capture_file *cf, const char *fname, guint save_format,
case PSP_STOPPED:
/* The user decided to abort the saving.
- XXX - remove the output file? */
- break;
+ If we're writing to a temporary file, remove it.
+ XXX - should we do so even if we're not writing to a
+ temporary file? */
+ wtap_dump_close(pdh, &err);
+ if (fname_new != NULL)
+ ws_unlink(fname_new);
+ cf_callback_invoke(cf_cb_file_save_stopped, NULL);
+ return CF_WRITE_ABORTED;
case PSP_FAILED:
- /* Error while saving. */
+ /* Error while saving.
+ If we're writing to a temporary file, remove it. */
+ if (fname_new != NULL)
+ ws_unlink(fname_new);
wtap_dump_close(pdh, &err);
goto fail;
}
@@ -4043,7 +4050,7 @@ cf_save_packets(capture_file *cf, const char *fname, guint save_format,
}
}
}
- return CF_OK;
+ return CF_WRITE_OK;
fail:
if (fname_new != NULL) {
@@ -4057,10 +4064,10 @@ fail:
g_free(fname_new);
}
cf_callback_invoke(cf_cb_file_save_failed, NULL);
- return CF_ERROR;
+ return CF_WRITE_ERROR;
}
-cf_status_t
+cf_write_status_t
cf_export_specified_packets(capture_file *cf, const char *fname,
packet_range_t *range, guint save_format,
gboolean compressed)
@@ -4072,7 +4079,7 @@ cf_export_specified_packets(capture_file *cf, const char *fname,
wtapng_section_t *shb_hdr = NULL;
wtapng_iface_descriptions_t *idb_inf = NULL;
- cf_callback_invoke(cf_cb_file_save_started, (gpointer)fname);
+ cf_callback_invoke(cf_cb_file_export_specified_packets_started, (gpointer)fname);
packet_range_process_init(range);
@@ -4128,12 +4135,22 @@ cf_export_specified_packets(capture_file *cf, const char *fname,
break;
case PSP_STOPPED:
- /* The user decided to abort the writing.
- XXX - remove the output file? */
+ /* The user decided to abort the saving.
+ If we're writing to a temporary file, remove it.
+ XXX - should we do so even if we're not writing to a
+ temporary file? */
+ wtap_dump_close(pdh, &err);
+ if (fname_new != NULL)
+ ws_unlink(fname_new);
+ cf_callback_invoke(cf_cb_file_export_specified_packets_stopped, NULL);
+ return CF_WRITE_ABORTED;
break;
case PSP_FAILED:
- /* Error while writing. */
+ /* Error while saving.
+ If we're writing to a temporary file, remove it. */
+ if (fname_new != NULL)
+ ws_unlink(fname_new);
wtap_dump_close(pdh, &err);
goto fail;
}
@@ -4155,8 +4172,8 @@ cf_export_specified_packets(capture_file *cf, const char *fname,
}
}
- cf_callback_invoke(cf_cb_file_save_finished, NULL);
- return CF_OK;
+ cf_callback_invoke(cf_cb_file_export_specified_packets_finished, NULL);
+ return CF_WRITE_OK;
fail:
if (fname_new != NULL) {
@@ -4169,8 +4186,8 @@ fail:
ws_unlink(fname_new);
g_free(fname_new);
}
- cf_callback_invoke(cf_cb_file_save_failed, NULL);
- return CF_ERROR;
+ cf_callback_invoke(cf_cb_file_export_specified_packets_failed, NULL);
+ return CF_WRITE_ERROR;
}
static void
diff --git a/file.h b/file.h
index e3b9acff0e..b40a642d91 100644
--- a/file.h
+++ b/file.h
@@ -51,6 +51,13 @@ typedef enum {
CF_READ_ABORTED /**< operation aborted by user */
} cf_read_status_t;
+/** Return values from functions that write out packets. */
+typedef enum {
+ CF_WRITE_OK, /**< operation succeeded */
+ CF_WRITE_ERROR, /**< operation got an error (function may provide err with details) */
+ CF_WRITE_ABORTED, /**< operation aborted by user */
+} cf_write_status_t;
+
/** Return values from functions that print sets of packets. */
typedef enum {
CF_PRINT_OK, /**< print operation succeeded */
@@ -70,7 +77,12 @@ typedef enum {
cf_cb_field_unselected,
cf_cb_file_save_started,
cf_cb_file_save_finished,
- cf_cb_file_save_failed
+ cf_cb_file_save_failed,
+ cf_cb_file_save_stopped,
+ cf_cb_file_export_specified_packets_started,
+ cf_cb_file_export_specified_packets_finished,
+ cf_cb_file_export_specified_packets_failed,
+ cf_cb_file_export_specified_packets_stopped
} cf_cbs;
typedef void (*cf_callback_t) (gint event, gpointer data, gpointer user_data);
@@ -208,11 +220,11 @@ gboolean cf_can_save_as(capture_file *cf);
* @param compressed whether to gzip compress the file
* @param dont_reopen TRUE if it shouldn't reopen and make that file the
* current capture file
- * @return one of cf_status_t
+ * @return one of cf_write_status_t
*/
-cf_status_t cf_save_packets(capture_file * cf, const char *fname,
- guint save_format, gboolean compressed,
- gboolean dont_reopen);
+cf_write_status_t cf_save_packets(capture_file * cf, const char *fname,
+ guint save_format, gboolean compressed,
+ gboolean dont_reopen);
/**
* Export some or all packets from a capture file to a new file. If there's
@@ -226,12 +238,13 @@ cf_status_t cf_save_packets(capture_file * cf, const char *fname,
* @param range the range of packets to write
* @param save_format the format of the file to write (libpcap, ...)
* @param compressed whether to gzip compress the file
- * @return one of cf_status_t
+ * @return one of cf_write_status_t
*/
-cf_status_t cf_export_specified_packets(capture_file *cf, const char *fname,
- packet_range_t *range,
- guint save_format,
- gboolean compressed);
+cf_write_status_t cf_export_specified_packets(capture_file *cf,
+ const char *fname,
+ packet_range_t *range,
+ guint save_format,
+ gboolean compressed);
/**
* Get a displayable name of the capture file.
diff --git a/ui/gtk/capture_file_dlg.c b/ui/gtk/capture_file_dlg.c
index 0ab1ae7dea..6392412c56 100644
--- a/ui/gtk/capture_file_dlg.c
+++ b/ui/gtk/capture_file_dlg.c
@@ -78,9 +78,9 @@
static void do_file_save(capture_file *cf, gboolean dont_reopen);
static void do_file_save_as(capture_file *cf);
-static void file_save_as_cb(GtkWidget *fs);
+static cf_write_status_t file_save_as_cb(GtkWidget *fs);
static void file_select_file_type_cb(GtkWidget *w, gpointer data);
-static void file_export_specified_packets_cb(GtkWidget *fs, packet_range_t *range);
+static cf_write_status_t file_export_specified_packets_cb(GtkWidget *fs, packet_range_t *range);
static void set_file_type_list(GtkWidget *combo_box, capture_file *cf);
#define E_FILE_TYPE_COMBO_BOX_KEY "file_type_combo_box"
@@ -1312,10 +1312,22 @@ do_file_save_as(capture_file *cf)
continue;
}
- /* save file */
+ /* Attempt to save the file */
g_free(cf_name);
- file_save_as_cb(file_save_as_w);
- return;
+ switch (file_save_as_cb(file_save_as_w)) {
+
+ case CF_WRITE_OK:
+ /* The save succeeded; we're done. */
+ return;
+
+ case CF_WRITE_ERROR:
+ /* The save failed; let the user try again */
+ continue;
+
+ case CF_WRITE_ABORTED:
+ /* The user aborted the save; just return. */
+ return;
+ }
}
#endif /* _WIN32 */
}
@@ -1328,8 +1340,9 @@ file_save_as_cmd_cb(GtkWidget *w _U_, gpointer data _U_)
/* all tests ok, we only have to save the file */
/* (and probably continue with a pending operation) */
-static void
-file_save_as_cb(GtkWidget *fs) {
+static cf_write_status_t
+file_save_as_cb(GtkWidget *fs)
+{
GtkWidget *ft_combo_box;
GtkWidget *compressed_cb;
gchar *cf_name;
@@ -1337,6 +1350,7 @@ file_save_as_cb(GtkWidget *fs) {
gpointer ptr;
int file_type;
gboolean compressed;
+ cf_write_status_t status;
/* Hide the file chooser while doing the save. */
gtk_widget_hide(fs);
@@ -1353,26 +1367,34 @@ file_save_as_cb(GtkWidget *fs) {
compressed = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(compressed_cb));
/* Write out all the packets to the file with the specified name. */
- if (cf_save_packets(&cfile, cf_name, file_type, compressed, FALSE) != CF_OK) {
- /* The write failed; don't dismiss the open dialog box,
- just leave it around so that the user can, after they
- dismiss the alert box popped up for the error, try again. */
- g_free(cf_name);
- /* XXX - as we cannot start a new event loop (using gtk_dialog_run()),
- * as this will prevent the user from closing the now existing error
- * message, simply close the dialog (this is the best we can do here). */
+ status = cf_save_packets(&cfile, cf_name, file_type, compressed, FALSE);
+ switch (status) {
+
+ case CF_WRITE_OK:
+ /* The write succeeded; get rid of the file selection box. */
+ /* cf_save_packets() might already closed our dialog! */
window_destroy(fs);
- return;
- }
- /* The write succeeded; get rid of the file selection box. */
- /* cf_save_packets() might already closed our dialog! */
- window_destroy(fs);
+ /* Save the directory name for future file dialogs. */
+ dirname = get_dirname(cf_name); /* Overwrites cf_name */
+ set_last_open_dir(dirname);
+ break;
+
+ case CF_WRITE_ERROR:
+ /* The write failed.
+ just leave the file selection box around so that the user can,
+ after they dismiss the alert box popped up for the error, try
+ again. */
+ break;
- /* Save the directory name for future file dialogs. */
- dirname = get_dirname(cf_name); /* Overwrites cf_name */
- set_last_open_dir(dirname);
+ case CF_WRITE_ABORTED:
+ /* The write was aborted; just get rid of the file selection
+ box and return. */
+ window_destroy(fs);
+ break;
+ }
g_free(cf_name);
+ return status;
}
void
@@ -1514,18 +1536,32 @@ file_export_specified_packets_cmd_cb(GtkWidget *widget _U_, gpointer data _U_)
continue;
}
- /* export packets */
+ /* attempt to export the packets */
g_free(cf_name);
- file_export_specified_packets_cb(file_export_specified_packets_w, &range);
- return;
+ switch (file_export_specified_packets_cb(file_export_specified_packets_w,
+ &range)) {
+
+ case CF_WRITE_OK:
+ /* The save succeeded; we're done. */
+ return;
+
+ case CF_WRITE_ERROR:
+ /* The save failed; let the user try again */
+ continue;
+
+ case CF_WRITE_ABORTED:
+ /* The user aborted the save; just return. */
+ return;
+ }
}
#endif /* _WIN32 */
}
/* all tests ok, we only have to write out the packets */
/* (and probably continue with a pending operation) */
-static void
-file_export_specified_packets_cb(GtkWidget *fs, packet_range_t *range) {
+static cf_write_status_t
+file_export_specified_packets_cb(GtkWidget *fs, packet_range_t *range)
+{
GtkWidget *ft_combo_box;
GtkWidget *compressed_cb;
gchar *cf_name;
@@ -1533,6 +1569,7 @@ file_export_specified_packets_cb(GtkWidget *fs, packet_range_t *range) {
gpointer ptr;
int file_type;
gboolean compressed;
+ cf_write_status_t status;
/* Hide the file chooser while we're doing the export. */
gtk_widget_hide(fs);
@@ -1549,29 +1586,37 @@ file_export_specified_packets_cb(GtkWidget *fs, packet_range_t *range) {
compressed = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(compressed_cb));
/* Write out the specified packets to the file with the specified name. */
- if (cf_export_specified_packets(&cfile, cf_name, range, file_type,
- compressed) != CF_OK) {
- /* The write failed; don't dismiss the open dialog box,
- just leave it around so that the user can, after they
- dismiss the alert box popped up for the error, try again. */
- g_free(cf_name);
- /* XXX - as we cannot start a new event loop (using gtk_dialog_run()),
- * as this will prevent the user from closing the now existing error
- * message, simply close the dialog (this is the best we can do here). */
+ status = cf_export_specified_packets(&cfile, cf_name, range, file_type,
+ compressed);
+ switch (status) {
+
+ case CF_WRITE_OK:
+ /* The write succeeded; get rid of the file selection box. */
+ /* cf_export_specified_packets() might already closed our dialog! */
window_destroy(GTK_WIDGET(fs));
- return;
- }
- /* The write succeeded; get rid of the file selection box. */
- /* cf_export_specified_packets() might already closed our dialog! */
- window_destroy(GTK_WIDGET(fs));
+ /* Save the directory name for future file dialogs.
+ XXX - should there be separate ones for "Save As" and
+ "Export Specified Packets"? */
+ dirname = get_dirname(cf_name); /* Overwrites cf_name */
+ set_last_open_dir(dirname);
+ break;
- /* Save the directory name for future file dialogs.
- XXX - should there be separate ones for "Save As" and
- "Export Specified Packets"? */
- dirname = get_dirname(cf_name); /* Overwrites cf_name */
- set_last_open_dir(dirname);
+ case CF_WRITE_ERROR:
+ /* The write failed.
+ just leave the file selection box around so that the user can,
+ after they dismiss the alert box popped up for the error, try
+ again. */
+ break;
+
+ case CF_WRITE_ABORTED:
+ /* The write was aborted; just get rid of the file selection
+ box and return. */
+ window_destroy(fs);
+ break;
+ }
g_free(cf_name);
+ return status;
}
/* Reload a file using the current read and display filters */
diff --git a/ui/gtk/main.c b/ui/gtk/main.c
index e40b91eb39..2c38529ab1 100644
--- a/ui/gtk/main.c
+++ b/ui/gtk/main.c
@@ -1765,6 +1765,21 @@ main_cf_callback(gint event, gpointer data, gpointer user_data _U_)
case(cf_cb_file_save_failed):
g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Save failed");
break;
+ case(cf_cb_file_save_stopped):
+ g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Save stopped");
+ break;
+ case(cf_cb_file_export_specified_packets_started):
+ g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Export specified packets started");
+ break;
+ case(cf_cb_file_export_specified_packets_finished):
+ g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Export specified packets finished");
+ break;
+ case(cf_cb_file_export_specified_packets_failed):
+ g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Export specified packets failed");
+ break;
+ case(cf_cb_file_export_specified_packets_stopped):
+ g_log(LOG_DOMAIN_MAIN, G_LOG_LEVEL_DEBUG, "Callback: Export specified packets stopped");
+ break;
default:
g_warning("main_cf_callback: event %u unknown", event);
g_assert_not_reached();
diff --git a/ui/gtk/main_statusbar.c b/ui/gtk/main_statusbar.c
index 937aaf8581..1d3ffbc6e9 100644
--- a/ui/gtk/main_statusbar.c
+++ b/ui/gtk/main_statusbar.c
@@ -943,6 +943,41 @@ statusbar_cf_file_save_failed_cb(gpointer data _U_)
statusbar_pop_file_msg();
}
+static void
+statusbar_cf_file_save_stopped_cb(gpointer data _U_)
+{
+ /* Pop the "Saving:" message off the status bar. */
+ statusbar_pop_file_msg();
+}
+
+static void
+statusbar_cf_file_export_specified_packets_started_cb(gchar *filename)
+{
+ statusbar_pop_file_msg();
+ statusbar_push_file_msg(" Exporting to: %s...", g_filename_display_basename(filename));
+}
+
+static void
+statusbar_cf_file_export_specified_packets_finished_cb(gpointer data _U_)
+{
+ /* Pop the "Exporting to:" message off the status bar. */
+ statusbar_pop_file_msg();
+}
+
+static void
+statusbar_cf_file_export_specified_packets_failed_cb(gpointer data _U_)
+{
+ /* Pop the "Exporting to:" message off the status bar. */
+ statusbar_pop_file_msg();
+}
+
+static void
+statusbar_cf_file_export_specified_packets_stopped_cb(gpointer data _U_)
+{
+ /* Pop the "Saving:" message off the status bar. */
+ statusbar_pop_file_msg();
+}
+
void
@@ -983,6 +1018,21 @@ statusbar_cf_callback(gint event, gpointer data, gpointer user_data _U_)
case(cf_cb_file_save_failed):
statusbar_cf_file_save_failed_cb(data);
break;
+ case(cf_cb_file_save_stopped):
+ statusbar_cf_file_save_stopped_cb(data);
+ break;
+ case(cf_cb_file_export_specified_packets_started):
+ statusbar_cf_file_export_specified_packets_started_cb(data);
+ break;
+ case(cf_cb_file_export_specified_packets_finished):
+ statusbar_cf_file_export_specified_packets_finished_cb(data);
+ break;
+ case(cf_cb_file_export_specified_packets_failed):
+ statusbar_cf_file_export_specified_packets_failed_cb(data);
+ break;
+ case(cf_cb_file_export_specified_packets_stopped):
+ statusbar_cf_file_export_specified_packets_stopped_cb(data);
+ break;
default:
g_warning("statusbar_cf_callback: event %u unknown", event);
g_assert_not_reached();