diff options
-rw-r--r-- | file.c | 69 | ||||
-rw-r--r-- | file.h | 33 | ||||
-rw-r--r-- | ui/gtk/capture_file_dlg.c | 139 | ||||
-rw-r--r-- | ui/gtk/main.c | 15 | ||||
-rw-r--r-- | ui/gtk/main_statusbar.c | 50 |
5 files changed, 223 insertions, 83 deletions
@@ -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 @@ -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(); |