From 18f922b46ea4a679f2ac208ca447e0cf14b8fd67 Mon Sep 17 00:00:00 2001 From: Guy Harris Date: Sat, 12 Jun 1999 09:10:20 +0000 Subject: Improve the alert boxes put up for file open/read/write errors. (Some influence came from http://developer.apple.com/techpubs/mac/HIGuidelines/HIGuidelines-232.html which has a section on dialog box and alert box messages. However, we're largely dealing with technoids, not with The Rest Of Us, so I didn't go as far as one perhaps should.) Unfortunately, it looks like it's a bit more work to arrange that, if you give a bad file name to the "-r" flag, the dialog box pop up only *after* the main window pops up - it has the annoying habit of popping up *before* the main window pops up, and sometimes getting *obscured* by it, when I do that. The removal of the dialog box stuff from "load_cap_file()" was intended to facilitate that work. (It might also be nice if, when an open from the "File/Open" menu item fails, we keep the file selection box open, and give the user a chance to correct typos, choose another file name, etc.) svn path=/trunk/; revision=310 --- capture.c | 29 +++++++--- ethereal.c | 42 +++++++++++--- file.c | 192 +++++++++++++++++++++++++++++++++++++++++++++++++++++++------ file.h | 24 +++++++- util.c | 71 +---------------------- util.h | 8 +-- 6 files changed, 254 insertions(+), 112 deletions(-) diff --git a/capture.c b/capture.c index 73c226b663..58af109b1c 100644 --- a/capture.c +++ b/capture.c @@ -1,7 +1,7 @@ /* capture.c * Routines for packet capture windows * - * $Id: capture.c,v 1.25 1999/06/11 15:30:34 gram Exp $ + * $Id: capture.c,v 1.26 1999/06/12 09:10:19 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs @@ -368,6 +368,7 @@ capture_prep_ok_cb(GtkWidget *w, gpointer data) { int fork_child; char ssnap[24]; char scount[24]; /* need a constant for len of numbers */ + int err; sprintf(ssnap,"%d",cf.snap); /* in liu of itoa */ sprintf(scount,"%d",cf.count); @@ -412,8 +413,13 @@ capture_prep_ok_cb(GtkWidget *w, gpointer data) { if (kill(fork_child, 0) == -1 && errno == ESRCH) break; } - if (sigusr2_received) - tail_cap_file(cf.save_file, &cf); + if (sigusr2_received) { + err = tail_cap_file(cf.save_file, &cf); + if (err != 0) { + simple_dialog(ESD_TYPE_WARN, NULL, + file_open_error_message(err, FALSE), cf.save_file); + } + } sigusr2_received = FALSE; } } @@ -441,6 +447,7 @@ capture(void) { loop_data ld; bpf_u_int32 netnum, netmask; time_t upd_time, cur_time; + int err; ld.go = TRUE; ld.counts.total = 0; @@ -586,13 +593,19 @@ capture(void) { gtk_exit(0); } - if (cf.save_file) load_cap_file(cf.save_file, &cf); + if (cf.save_file) { + err = load_cap_file(cf.save_file, &cf); + if (err != 0) { + simple_dialog(ESD_TYPE_WARN, NULL, + file_open_error_message(err, FALSE), cf.save_file); + } + } #ifdef USE_ITEM - set_menu_sensitivity("/File/Save", TRUE); - set_menu_sensitivity("/File/Save as", FALSE); + set_menu_sensitivity("/File/Save", TRUE); + set_menu_sensitivity("/File/Save as", FALSE); #else - set_menu_sensitivity("
/File/Save", TRUE); - set_menu_sensitivity("
/File/Save as", FALSE); + set_menu_sensitivity("
/File/Save", TRUE); + set_menu_sensitivity("
/File/Save as", FALSE); #endif } diff --git a/ethereal.c b/ethereal.c index db13a53acf..ca0d282da7 100644 --- a/ethereal.c +++ b/ethereal.c @@ -1,6 +1,6 @@ /* ethereal.c * - * $Id: ethereal.c,v 1.37 1999/06/12 07:04:34 guy Exp $ + * $Id: ethereal.c,v 1.38 1999/06/12 09:10:20 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs @@ -155,6 +155,10 @@ file_sel_ok_cb(GtkWidget *w, GtkFileSelection *fs) { * cf_name, leaving only the path to the directory. */ if ((err = load_cap_file(cf_name, &cf)) == 0) chdir(cf_name); + else { + simple_dialog(ESD_TYPE_WARN, NULL, file_open_error_message(err, FALSE), + cf_name); + } g_free(cf_name); #ifdef USE_ITEM set_menu_sensitivity("/File/Save", FALSE); @@ -179,6 +183,7 @@ follow_stream_cb( GtkWidget *w, gpointer data ) { char filename1[128]; GtkWidget *streamwindow, *box, *text, *vscrollbar, *table; GtkWidget *filter_te = NULL; + int err; if (w) filter_te = gtk_object_get_data(GTK_OBJECT(w), E_DFILTER_TE_KEY); @@ -204,7 +209,11 @@ follow_stream_cb( GtkWidget *w, gpointer data ) { fprintf( stderr, "Could not open tmp file %s\n", filename1 ); } reset_tcp_reassembly(); - load_cap_file( cf.filename, &cf ); + err = load_cap_file( cf.filename, &cf ); + if (err != 0) { + simple_dialog(ESD_TYPE_WARN, NULL, file_open_error_message(err, FALSE), + cf.filename); + } /* the data_out_file should now be full of the streams information */ fclose( data_out_file ); /* the filename1 file now has all the text that was in the session */ @@ -357,6 +366,7 @@ file_save_as_cmd_cb(GtkWidget *w, gpointer data) { static void file_save_ok_cb(GtkWidget *w, GtkFileSelection *fs) { gchar *cf_name; + int err; cf_name = g_strdup(gtk_file_selection_get_filename(GTK_FILE_SELECTION(fs))); gtk_widget_hide(GTK_WIDGET (fs)); @@ -367,7 +377,11 @@ file_save_ok_cb(GtkWidget *w, GtkFileSelection *fs) { g_free(cf.save_file); cf.save_file = g_strdup(cf_name); cf.user_saved = 1; - load_cap_file(cf_name, &cf); + err = load_cap_file(cf_name, &cf); + if (err != 0) { + simple_dialog(ESD_TYPE_WARN, NULL, + file_open_error_message(err, FALSE), cf_name); + } #ifdef USE_ITEM set_menu_sensitivity("/File/Save", FALSE); @@ -381,6 +395,7 @@ file_save_ok_cb(GtkWidget *w, GtkFileSelection *fs) { static void file_save_as_ok_cb(GtkWidget *w, GtkFileSelection *fs) { gchar *cf_name; + int err; cf_name = g_strdup(gtk_file_selection_get_filename(GTK_FILE_SELECTION(fs))); gtk_widget_hide(GTK_WIDGET (fs)); @@ -391,7 +406,11 @@ file_save_as_ok_cb(GtkWidget *w, GtkFileSelection *fs) { g_free(cf.save_file); cf.save_file = g_strdup(cf_name); cf.user_saved = 1; - load_cap_file(cf_name, &cf); + err = load_cap_file(cf_name, &cf); + if (err != 0) { + simple_dialog(ESD_TYPE_WARN, NULL, + file_open_error_message(err, FALSE), cf_name); + } #ifdef USE_ITEM set_menu_sensitivity("/File/Save", FALSE); @@ -407,12 +426,17 @@ void file_reload_cmd_cb(GtkWidget *w, gpointer data) { /*GtkWidget *filter_te = gtk_object_get_data(GTK_OBJECT(w), E_DFILTER_TE_KEY);*/ GtkWidget *filter_te; + int err; filter_te = gtk_object_get_data(GTK_OBJECT(w), E_DFILTER_TE_KEY); if (cf.dfilter) g_free(cf.dfilter); cf.dfilter = g_strdup(gtk_entry_get_text(GTK_ENTRY(filter_te))); - load_cap_file(cf.filename, &cf); + err = load_cap_file(cf.filename, &cf); + if (err != 0) { + simple_dialog(ESD_TYPE_WARN, NULL, file_open_error_message(err, FALSE), + cf.filename); + } } /* Print a packet */ @@ -495,7 +519,7 @@ void blank_packetinfo() { pi.destport = 0; } -/* Things to do when the OK button is pressed */ +/* Things to do when the main window is realized */ void main_realize_cb(GtkWidget *w, gpointer data) { gchar *cf_name = (gchar *) data; @@ -503,6 +527,10 @@ main_realize_cb(GtkWidget *w, gpointer data) { if (cf_name) { err = load_cap_file(cf_name, &cf); + if (err != 0) { + simple_dialog(ESD_TYPE_WARN, NULL, file_open_error_message(err, FALSE), + cf_name); + } cf_name[0] = '\0'; #ifdef USE_ITEM set_menu_sensitivity("/File/Save as", TRUE); @@ -529,7 +557,7 @@ ethereal_proto_init(void) { } -void +static void print_usage(void) { fprintf(stderr, "This is GNU %s %s, compiled with %s\n", PACKAGE, diff --git a/file.c b/file.c index 87f56166ea..e41599e518 100644 --- a/file.c +++ b/file.c @@ -1,7 +1,7 @@ /* file.c * File I/O routines * - * $Id: file.c,v 1.25 1999/05/11 20:07:47 gram Exp $ + * $Id: file.c,v 1.26 1999/06/12 09:10:19 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs @@ -96,14 +96,10 @@ open_cap_file(char *fname, capture_file *cf) { struct stat cf_stat; /* First, make sure the file is valid */ - if (stat(fname, &cf_stat)) { - simple_dialog(ESD_TYPE_WARN, NULL, "File does not exist."); - return 1; - } - if (! S_ISREG(cf_stat.st_mode) && ! S_ISFIFO(cf_stat.st_mode)) { - simple_dialog(ESD_TYPE_WARN, NULL, "The file you have chosen is invalid."); - return 1; - } + if (stat(fname, &cf_stat)) + return (errno); + if (! S_ISREG(cf_stat.st_mode) && ! S_ISFIFO(cf_stat.st_mode)) + return (OPEN_CAP_FILE_NOT_REGULAR); /* Next, try to open the file */ cf->fh = fopen(fname, "r"); @@ -156,8 +152,10 @@ open_cap_file(char *fname, capture_file *cf) { if (cf->wth == NULL) { #endif - simple_dialog(ESD_TYPE_WARN, NULL, "Could not open file."); - return 1; + /* XXX - we assume that, because we were able to open it above, + this must have failed because it's not a capture file in + a format we can read. */ + return (OPEN_CAP_FILE_UNKNOWN_FORMAT); } #ifndef WITH_WIRETAP @@ -184,14 +182,11 @@ open_cap_file(char *fname, capture_file *cf) { cf->snap = pcap_snapshot(cf->pfh); cf->lnk_t = pcap_datalink(cf->pfh); } else if (ntohl(magic[0]) == SNOOP_MAGIC_1 && ntohl(magic[1]) == SNOOP_MAGIC_2) { - simple_dialog(ESD_TYPE_WARN, NULL, "The snoop format is not yet supported."); - return 1; + return (OPEN_CAP_FILE_UNKNOWN_FORMAT); } - if (cf->cd_t == CD_UNKNOWN) { - simple_dialog(ESD_TYPE_WARN, NULL, "Can't determine file type."); - return 1; - } + if (cf->cd_t == CD_UNKNOWN) + return (OPEN_CAP_FILE_UNKNOWN_FORMAT); #else if (cf->dfilter) { if (wtap_offline_filter(cf->wth, cf->dfilter) < 0) { @@ -204,7 +199,7 @@ open_cap_file(char *fname, capture_file *cf) { cf->snap = wtap_snapshot_length(cf->wth); #endif - return 0; + return (0); } /* Reset everything to a pristine state */ @@ -250,7 +245,7 @@ load_cap_file(char *fname, capture_file *cf) { close_cap_file(cf, info_bar, file_ctx); - /* Initialize protocol-speficic variables */ + /* Initialize protocol-specific variables */ ncp_init_protocol(); if ((name_ptr = (gchar *) strrchr(fname, '/')) == NULL) @@ -562,3 +557,162 @@ pcap_dispatch_cb(u_char *user, const struct pcap_pkthdr *phdr, cf->plist = cf->plist->next; } + +/* Tries to mv a file. If unsuccessful, tries to cp the file. + * Returns 0 on failure to do either, 1 on success of either + */ +int +file_mv(char *from, char *to) +{ + +#define COPY_BUFFER_SIZE 8192 + + int retval; + + /* try a hard link */ + retval = link(from, to); + + /* or try a copy */ + if (retval < 0) { + retval = file_cp(from, to); + if (!retval) { + return 0; + } + } + + unlink(from); + return 1; +} + +/* Copies a file. + * Returns 0 on failure to do either, 1 on success of either + */ +int +file_cp(char *from, char *to) +{ + +#define COPY_BUFFER_SIZE 8192 + + int from_fd, to_fd, nread, nwritten; + char *buffer; + gint dialogue_button = ESD_BTN_OK; + + buffer = g_malloc(COPY_BUFFER_SIZE); + + from_fd = open(from, O_RDONLY); + if (from_fd < 0) { + simple_dialog(ESD_TYPE_WARN, &dialogue_button, + file_open_error_message(errno, TRUE), from); + return 0; + } + + to_fd = creat(to, 0644); + if (to_fd < 0) { + simple_dialog(ESD_TYPE_WARN, &dialogue_button, + file_open_error_message(errno, TRUE), to); + close(from_fd); + return 0; + } + + while( (nread = read(from_fd, buffer, COPY_BUFFER_SIZE)) > 0) { + nwritten = write(to_fd, buffer, nread); + if (nwritten < nread) { + if (nwritten < 0) { + simple_dialog(ESD_TYPE_WARN, &dialogue_button, + file_write_error_message(errno), to); + } else { + simple_dialog(ESD_TYPE_WARN, &dialogue_button, +"The file \"%s\" could not be saved: tried writing %d, wrote %d.\n", + to, nread, nwritten); + } + close(from_fd); + close(to_fd); + return 0; + } + } + if (nread < 0) { + simple_dialog(ESD_TYPE_WARN, &dialogue_button, + file_read_error_message(errno), from); + close(from_fd); + close(to_fd); + return 0; + } + close(from_fd); + close(to_fd); + + return 1; +} + +char * +file_open_error_message(int err, int for_writing) +{ + char *errmsg; + static char errmsg_errno[1024+1]; + + switch (err) { + + case OPEN_CAP_FILE_NOT_REGULAR: + errmsg = "The file \"%s\" is invalid."; + break; + + case OPEN_CAP_FILE_UNKNOWN_FORMAT: + errmsg = "The file \"%s\" is not a capture file in a format Ethereal understands."; + break; + + case ENOENT: + if (for_writing) + errmsg = "The path to the file \"%s\" does not exist."; + else + errmsg = "The file \"%s\" does not exist."; + break; + + case EACCES: + if (for_writing) + errmsg = "You do not have permission to create or write to the file \"%s\"."; + else + errmsg = "You do not have permission to open the file \"%s\"."; + break; + + default: + sprintf(errmsg_errno, "The file \"%%s\" could not be opened: %s.", strerror(err)); + errmsg = errmsg_errno; + break; + } + return errmsg; +} + +char * +file_read_error_message(int err) +{ + static char errmsg_errno[1024+1]; + + sprintf(errmsg_errno, "An error occurred while reading from the file \"%%s\": %s.", strerror(err)); + return errmsg_errno; +} + +char * +file_write_error_message(int err) +{ + char *errmsg; + static char errmsg_errno[1024+1]; + + switch (err) { + + case ENOSPC: + errmsg = "The file \"%s\" could not be saved because there is no space left on the file system."; + break; + +#ifdef EDQUOT + case EDQUOT: + errmsg = "The file \"%s\" could not be saved because you are too close to, or over, your disk quota."; + break; +#endif + + default: + sprintf(errmsg_errno, "An error occurred while writing to the file \"%%s\": %s.", strerror(err)); + errmsg = errmsg_errno; + break; + } + return errmsg; +} + diff --git a/file.h b/file.h index 3480347c3d..0b96caa3e0 100644 --- a/file.h +++ b/file.h @@ -1,7 +1,7 @@ /* file.h * Definitions for file structures and routines * - * $Id: file.h,v 1.13 1999/05/11 18:51:10 deniel Exp $ + * $Id: file.h,v 1.14 1999/06/12 09:10:19 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs @@ -118,10 +118,32 @@ typedef struct _snoop_frame_hdr { } snoop_frame_hdr; #endif +/* + * "open_cap_file()" can return: + * + * 0 on success; + * + * a positive "errno" value on an open failure; + * + * a negative number, indicating the type of error, on other failures. + */ +#define OPEN_CAP_FILE_NOT_REGULAR -1 /* not a plain file */ +#define OPEN_CAP_FILE_UNKNOWN_FORMAT -2 /* not a capture file in a known format */ + int open_cap_file(char *, capture_file *); void close_cap_file(capture_file *, void *, guint); int load_cap_file(char *, capture_file *); int tail_cap_file(char *, capture_file *); /* size_t read_frame_header(capture_file *); */ +/* Moves or copies a file. Returns 0 on failure, 1 on success */ +int file_mv(char *from, char *to); + +/* Copies a file. Returns 0 on failure, 1 on success */ +int file_cp(char *from, char *to); + +char *file_open_error_message(int, int); +char *file_read_error_message(int); +char *file_write_error_message(int); + #endif /* file.h */ diff --git a/util.c b/util.c index 4c8277db3c..7a84868b08 100644 --- a/util.c +++ b/util.c @@ -1,7 +1,7 @@ /* util.c * Utility routines * - * $Id: util.c,v 1.14 1999/04/06 16:24:49 gram Exp $ + * $Id: util.c,v 1.15 1999/06/12 09:10:18 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs @@ -174,72 +174,3 @@ simple_dialog_cancel_cb(GtkWidget *w, gpointer win) { *btn_mask = ESD_BTN_CANCEL; gtk_widget_destroy(GTK_WIDGET(win)); } - -/* Tries to mv a file. If unsuccessful, tries to cp the file. - * Returns 0 on failure to do either, 1 on success of either - */ -int -file_mv(char *from, char *to) -{ - -#define COPY_BUFFER_SIZE 8192 - - int retval; - - /* try a hard link */ - retval = link(from, to); - - /* or try a copy */ - if (retval < 0) { - retval = file_cp(from, to); - if (!retval) { - return 0; - } - } - - unlink(from); - return 1; -} - -/* Copies a file. - * Returns 0 on failure to do either, 1 on success of either - */ -int -file_cp(char *from, char *to) -{ - -#define COPY_BUFFER_SIZE 8192 - - int from_fd, to_fd, nread; - char *buffer; - gint dialogue_button = ESD_BTN_OK; - - buffer = g_malloc(COPY_BUFFER_SIZE); - - from_fd = open(from, O_RDONLY); - if (from_fd < 0) { - simple_dialog(ESD_TYPE_WARN, &dialogue_button, - "Cannot open from-file for copying."); - return 0; - } - - to_fd = creat(to, 0644); - if (to_fd < 0) { - simple_dialog(ESD_TYPE_WARN, &dialogue_button, - "Cannot open to-file for copying."); - close(from_fd); - return 0; - } - - while( (nread = read(from_fd, buffer, COPY_BUFFER_SIZE)) > 0) { - if (write(to_fd, buffer, nread) < nread) { - close(from_fd); - close(to_fd); - return 0; - } - } - close(from_fd); - close(to_fd); - - return 1; -} diff --git a/util.h b/util.h index 69dffb8266..88f1ab9d44 100644 --- a/util.h +++ b/util.h @@ -1,7 +1,7 @@ /* util.h * Utility definitions * - * $Id: util.h,v 1.9 1999/04/06 16:24:50 gram Exp $ + * $Id: util.h,v 1.10 1999/06/12 09:10:20 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs @@ -46,12 +46,6 @@ void simple_dialog(gint, gint *, gchar *, ...) void simple_dialog(gint, gint *, gchar *, ...); #endif -/* Moves or copies a file. Returns 0 on failure, 1 on success */ -int file_mv(char *from, char *to); - -/* Copies a file. Returns 0 on failure, 1 on success */ -int file_cp(char *from, char *to); - #ifdef __cplusplus } #endif /* __cplusplus */ -- cgit v1.2.3