As with "file_write_error_message()", so with

"file_close_error_message()" - but just use "file_write_error_message()"
for UNIX-style errors, under the assumption that a close will only fail
because a buffer-flushing write fails or because "close()" itself fails
when, for example, pushing unsynced NFS client-side writes out over the
wire.

Make several routines in "print.c" return success/failure indications.

Check for write errors when printing "Follow TCP Stream" stuff or saving
it to a file.

svn path=/trunk/; revision=9825
This commit is contained in:
Guy Harris 2004-01-24 10:53:25 +00:00
parent 7180513677
commit 65f18bb833
6 changed files with 137 additions and 75 deletions

52
file.c
View File

@ -1,7 +1,7 @@
/* file.c /* file.c
* File I/O routines * File I/O routines
* *
* $Id: file.c,v 1.346 2004/01/24 02:01:42 guy Exp $ * $Id: file.c,v 1.347 2004/01/24 10:53:24 guy Exp $
* *
* Ethereal - Network traffic analyzer * Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com> * By Gerald Combs <gerald@ethereal.com>
@ -119,7 +119,7 @@ static char *cf_open_error_message(int err, gboolean for_writing,
int file_type); int file_type);
static char *file_rename_error_message(int err); static char *file_rename_error_message(int err);
static char *cf_write_error_message(int); static char *cf_write_error_message(int);
static char *file_close_error_message(int err); static char *cf_close_error_message(int err);
static gboolean copy_binary_file(char *from_filename, char *to_filename); static gboolean copy_binary_file(char *from_filename, char *to_filename);
/* Update the progress bar this many times when reading a file. */ /* Update the progress bar this many times when reading a file. */
@ -2621,7 +2621,7 @@ cf_save(char *fname, capture_file *cf, packet_range_t *range, guint save_format)
} }
if (!wtap_dump_close(pdh, &err)) { if (!wtap_dump_close(pdh, &err)) {
simple_dialog(ESD_TYPE_WARN, NULL, file_close_error_message(err), fname); simple_dialog(ESD_TYPE_WARN, NULL, cf_close_error_message(err), fname);
goto fail; goto fail;
} }
} }
@ -2812,37 +2812,33 @@ cf_write_error_message(int err)
might not send writes to the server until the "write()" call finishes, might not send writes to the server until the "write()" call finishes,
so that the write may fail on the server but the "write()" may succeed. */ so that the write may fail on the server but the "write()" may succeed. */
static char * static char *
file_close_error_message(int err) cf_close_error_message(int err)
{ {
char *errmsg; char *errmsg;
static char errmsg_errno[1024+1]; static char errmsg_errno[1024+1];
switch (err) { if (err < 0) {
/* Wiretap error. */
switch (err) {
case WTAP_ERR_CANT_CLOSE: case WTAP_ERR_CANT_CLOSE:
errmsg = "The file \"%s\" couldn't be closed for some unknown reason."; errmsg = "The file \"%s\" couldn't be closed for some unknown reason.";
break; break;
case WTAP_ERR_SHORT_WRITE: case WTAP_ERR_SHORT_WRITE:
errmsg = "Not all the packets could be written to the file \"%s\"."; errmsg = "Not all the packets could be written to the file \"%s\".";
break; break;
case ENOSPC: default:
errmsg = "The file \"%s\" could not be saved because there is no space left on the file system."; snprintf(errmsg_errno, sizeof(errmsg_errno),
break; "An error occurred while closing the file \"%%s\": %s.",
wtap_strerror(err));
#ifdef EDQUOT errmsg = errmsg_errno;
case EDQUOT: break;
errmsg = "The file \"%s\" could not be saved because you are too close to, or over, your disk quota."; }
break; } else {
#endif /* We assume that a close error from the OS is really a write error. */
errmsg = file_write_error_message(err);
default:
snprintf(errmsg_errno, sizeof(errmsg_errno),
"An error occurred while closing the file \"%%s\": %s.",
wtap_strerror(err));
errmsg = errmsg_errno;
break;
} }
return errmsg; return errmsg;
} }
@ -2908,7 +2904,7 @@ copy_binary_file(char *from_filename, char *to_filename)
if (close(to_fd) < 0) { if (close(to_fd) < 0) {
err = errno; err = errno;
simple_dialog(ESD_TYPE_CRIT, NULL, simple_dialog(ESD_TYPE_CRIT, NULL,
file_close_error_message(err), to_filename); file_write_error_message(err), to_filename);
goto done; goto done;
} }

View File

@ -1,6 +1,6 @@
/* follow_dlg.c /* follow_dlg.c
* *
* $Id: follow_dlg.c,v 1.35 2004/01/24 02:01:44 guy Exp $ * $Id: follow_dlg.c,v 1.36 2004/01/24 10:53:25 guy Exp $
* *
* Ethereal - Network traffic analyzer * Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com> * By Gerald Combs <gerald@ethereal.com>
@ -496,7 +496,7 @@ follow_charset_toggle_cb(GtkWidget * w _U_, gpointer data)
#define FLT_BUF_SIZE 1024 #define FLT_BUF_SIZE 1024
static void static void
follow_read_stream(follow_info_t *follow_info, follow_read_stream(follow_info_t *follow_info,
void (*print_line) (char *, int, gboolean, void *), gboolean (*print_line) (char *, int, gboolean, void *),
void *arg) void *arg)
{ {
tcp_stream_chunk sc; tcp_stream_chunk sc;
@ -550,13 +550,15 @@ follow_read_stream(follow_info_t *follow_info,
case SHOW_EBCDIC: case SHOW_EBCDIC:
/* If our native arch is ASCII, call: */ /* If our native arch is ASCII, call: */
EBCDIC_to_ASCII(buffer, nchars); EBCDIC_to_ASCII(buffer, nchars);
(*print_line) (buffer, nchars, is_server, arg); if (!(*print_line) (buffer, nchars, is_server, arg))
goto fail;
break; break;
case SHOW_ASCII: case SHOW_ASCII:
/* If our native arch is EBCDIC, call: /* If our native arch is EBCDIC, call:
* ASCII_TO_EBCDIC(buffer, nchars); * ASCII_TO_EBCDIC(buffer, nchars);
*/ */
(*print_line) (buffer, nchars, is_server, arg); if (!(*print_line) (buffer, nchars, is_server, arg))
goto fail;
break; break;
case SHOW_HEXDUMP: case SHOW_HEXDUMP:
current_pos = 0; current_pos = 0;
@ -613,14 +615,16 @@ follow_read_stream(follow_info_t *follow_info,
(*global_pos) += i; (*global_pos) += i;
hexbuf[cur++] = '\n'; hexbuf[cur++] = '\n';
hexbuf[cur] = 0; hexbuf[cur] = 0;
(*print_line) (hexbuf, strlen(hexbuf), is_server, arg); if (!(*print_line) (hexbuf, strlen(hexbuf), is_server, arg))
goto fail;
} }
break; break;
case SHOW_CARRAY: case SHOW_CARRAY:
current_pos = 0; current_pos = 0;
sprintf(initbuf, "char peer%d_%d[] = {\n", is_server ? 1 : 0, sprintf(initbuf, "char peer%d_%d[] = {\n", is_server ? 1 : 0,
is_server ? server_packet_count++ : client_packet_count++); is_server ? server_packet_count++ : client_packet_count++);
(*print_line) (initbuf, strlen(initbuf), is_server, arg); if (!(*print_line) (initbuf, strlen(initbuf), is_server, arg))
goto fail;
while (current_pos < nchars) { while (current_pos < nchars) {
gchar hexbuf[256]; gchar hexbuf[256];
gchar hexchars[] = "0123456789abcdef"; gchar hexchars[] = "0123456789abcdef";
@ -655,7 +659,8 @@ follow_read_stream(follow_info_t *follow_info,
(*global_pos) += i; (*global_pos) += i;
hexbuf[cur++] = '\n'; hexbuf[cur++] = '\n';
hexbuf[cur] = 0; hexbuf[cur] = 0;
(*print_line) (hexbuf, strlen(hexbuf), is_server, arg); if (!(*print_line) (hexbuf, strlen(hexbuf), is_server, arg))
goto fail;
} }
break; break;
} }
@ -667,6 +672,7 @@ follow_read_stream(follow_info_t *follow_info,
"Error reading temporary file %s: %s", follow_info->data_out_filename, "Error reading temporary file %s: %s", follow_info->data_out_filename,
strerror(errno)); strerror(errno));
} }
fail:
fclose(data_out_file); fclose(data_out_file);
data_out_file = NULL; data_out_file = NULL;
} else { } else {
@ -685,12 +691,29 @@ follow_read_stream(follow_info_t *follow_info,
* *
* For now, we support only text printing. * For now, we support only text printing.
*/ */
static void typedef struct {
gboolean to_file;
const char *filename;
FILE *fh;
} print_text_args_t;
static gboolean
follow_print_text(char *buffer, int nchars, gboolean is_server _U_, void *arg) follow_print_text(char *buffer, int nchars, gboolean is_server _U_, void *arg)
{ {
FILE *fh = arg; print_text_args_t *print_args = arg;
fwrite(buffer, nchars, 1, fh); if (fwrite(buffer, nchars, 1, print_args->fh) != 1) {
if (print_args->to_file) {
simple_dialog(ESD_TYPE_CRIT, NULL,
file_write_error_message(errno), print_args->filename);
} else {
simple_dialog(ESD_TYPE_CRIT, NULL,
"Error writing to print command: %s",
strerror(errno));
}
return FALSE;
}
return TRUE;
} }
static void static void
@ -720,6 +743,7 @@ follow_print_stream(GtkWidget * w _U_, gpointer data)
gboolean to_file; gboolean to_file;
char *print_dest; char *print_dest;
follow_info_t *follow_info = data; follow_info_t *follow_info = data;
print_text_args_t args;
switch (prefs.pr_dest) { switch (prefs.pr_dest) {
case PR_DEST_CMD: case PR_DEST_CMD:
@ -740,27 +764,58 @@ follow_print_stream(GtkWidget * w _U_, gpointer data)
fh = open_print_dest(to_file, print_dest); fh = open_print_dest(to_file, print_dest);
if (fh == NULL) { if (fh == NULL) {
switch (to_file) { if (to_file) {
case FALSE:
simple_dialog(ESD_TYPE_WARN, NULL,
"Couldn't run print command %s.", prefs.pr_cmd);
break;
case TRUE:
simple_dialog(ESD_TYPE_WARN, NULL, simple_dialog(ESD_TYPE_WARN, NULL,
file_write_error_message(errno), prefs.pr_file); file_write_error_message(errno), prefs.pr_file);
break; } else {
simple_dialog(ESD_TYPE_WARN, NULL,
"Couldn't run print command %s.", prefs.pr_cmd);
} }
return; return;
} }
print_preamble(fh, PR_FMT_TEXT); if (!print_preamble(fh, PR_FMT_TEXT)) {
follow_read_stream(follow_info, follow_print_text, fh); if (to_file) {
print_finale(fh, PR_FMT_TEXT); simple_dialog(ESD_TYPE_WARN, NULL,
close_print_dest(to_file, fh); file_write_error_message(errno), prefs.pr_file);
} else {
simple_dialog(ESD_TYPE_WARN, NULL,
"Error writing to print command: %s",
strerror(errno));
}
/* XXX - cancel printing? */
close_print_dest(to_file, fh);
return;
}
args.to_file = to_file;
args.filename = prefs.pr_file;
args.fh = fh;
follow_read_stream(follow_info, follow_print_text, &args);
if (!print_finale(fh, PR_FMT_TEXT)) {
if (to_file) {
simple_dialog(ESD_TYPE_WARN, NULL,
file_write_error_message(errno), prefs.pr_file);
} else {
simple_dialog(ESD_TYPE_WARN, NULL,
"Error writing to print command: %s",
strerror(errno));
}
/* XXX - cancel printing? */
close_print_dest(to_file, fh);
return;
}
if (!close_print_dest(to_file, fh)) {
if (to_file) {
simple_dialog(ESD_TYPE_WARN, NULL,
file_write_error_message(errno), prefs.pr_file);
} else {
simple_dialog(ESD_TYPE_WARN, NULL,
"Error closing print destination.");
}
}
} }
static void static gboolean
follow_add_to_gtk_text(char *buffer, int nchars, gboolean is_server, follow_add_to_gtk_text(char *buffer, int nchars, gboolean is_server,
void *arg) void *arg)
{ {
@ -810,6 +865,7 @@ follow_add_to_gtk_text(char *buffer, int nchars, gboolean is_server,
NULL); NULL);
g_free(convbuf); g_free(convbuf);
#endif #endif
return TRUE;
} }
static void static void
@ -901,6 +957,7 @@ follow_save_as_ok_cb(GtkWidget * w _U_, GtkFileSelection * fs)
follow_info_t *follow_info; follow_info_t *follow_info;
FILE *fh; FILE *fh;
gchar *dirname; gchar *dirname;
print_text_args_t args;
to_name = g_strdup(gtk_file_selection_get_filename(GTK_FILE_SELECTION(fs))); to_name = g_strdup(gtk_file_selection_get_filename(GTK_FILE_SELECTION(fs)));
@ -928,8 +985,14 @@ follow_save_as_ok_cb(GtkWidget * w _U_, GtkFileSelection * fs)
follow_info = OBJECT_GET_DATA(fs, E_FOLLOW_INFO_KEY); follow_info = OBJECT_GET_DATA(fs, E_FOLLOW_INFO_KEY);
gtk_widget_destroy(GTK_WIDGET(fs)); gtk_widget_destroy(GTK_WIDGET(fs));
follow_read_stream(follow_info, follow_print_text, fh); args.to_file = TRUE;
fclose(fh); args.filename = to_name;
args.fh = fh;
follow_read_stream(follow_info, follow_print_text, &args);
if (fclose(fh) == EOF) {
simple_dialog(ESD_TYPE_WARN, NULL,
file_write_error_message(errno), to_name);
}
/* Save the directory name for future file dialogs. */ /* Save the directory name for future file dialogs. */
dirname = get_dirname(to_name); /* Overwrites to_name */ dirname = get_dirname(to_name); /* Overwrites to_name */

24
print.c
View File

@ -1,7 +1,7 @@
/* print.c /* print.c
* Routines for printing packet analysis trees. * Routines for printing packet analysis trees.
* *
* $Id: print.c,v 1.69 2004/01/09 18:49:31 sharpe Exp $ * $Id: print.c,v 1.70 2004/01/24 10:53:24 guy Exp $
* *
* Gilbert Ramirez <gram@alumni.rice.edu> * Gilbert Ramirez <gram@alumni.rice.edu>
* *
@ -78,13 +78,13 @@ FILE *open_print_dest(int to_file, const char *dest)
return fh; return fh;
} }
void close_print_dest(int to_file, FILE *fh) gboolean close_print_dest(int to_file, FILE *fh)
{ {
/* Close the file or command */ /* Close the file or command */
if (to_file) if (to_file)
fclose(fh); return (fclose(fh) == 0);
else else
pclose(fh); return (pclose(fh) == 0);
} }
@ -650,27 +650,31 @@ void ps_clean_string(unsigned char *out, const unsigned char *in,
} }
/* Some formats need stuff at the beginning of the output */ /* Some formats need stuff at the beginning of the output */
void gboolean
print_preamble(FILE *fh, gint format) print_preamble(FILE *fh, gint format)
{ {
if (format == PR_FMT_PS) if (format == PR_FMT_PS)
print_ps_preamble(fh); return !print_ps_preamble(fh);
else if (format == PR_FMT_PDML) { else if (format == PR_FMT_PDML) {
fputs("<?xml version=\"1.0\"?>\n", fh); fputs("<?xml version=\"1.0\"?>\n", fh);
fputs("<pdml version=\"" PDML_VERSION "\" ", fh); fputs("<pdml version=\"" PDML_VERSION "\" ", fh);
fprintf(fh, "creator=\"%s/%s\">\n", PACKAGE, VERSION); fprintf(fh, "creator=\"%s/%s\">\n", PACKAGE, VERSION);
} return !ferror(fh);
} else
return TRUE;
} }
/* Some formats need stuff at the end of the output */ /* Some formats need stuff at the end of the output */
void gboolean
print_finale(FILE *fh, gint format) print_finale(FILE *fh, gint format)
{ {
if (format == PR_FMT_PS) if (format == PR_FMT_PS)
print_ps_finale(fh); return !print_ps_finale(fh);
else if (format == PR_FMT_PDML) { else if (format == PR_FMT_PDML) {
fputs("</pdml>\n", fh); fputs("</pdml>\n", fh);
} return !ferror(fh);
} else
return TRUE;
} }
void void

View File

@ -1,7 +1,7 @@
/* print.h /* print.h
* Definitions for printing packet analysis trees. * Definitions for printing packet analysis trees.
* *
* $Id: print.h,v 1.34 2004/01/09 18:10:40 ulfl Exp $ * $Id: print.h,v 1.35 2004/01/24 10:53:24 guy Exp $
* *
* Gilbert Ramirez <gram@alumni.rice.edu> * Gilbert Ramirez <gram@alumni.rice.edu>
* *
@ -65,9 +65,9 @@ typedef struct {
/* Functions in print.h */ /* Functions in print.h */
FILE *open_print_dest(int to_file, const char *dest); FILE *open_print_dest(int to_file, const char *dest);
void close_print_dest(int to_file, FILE *fh); gboolean close_print_dest(int to_file, FILE *fh);
void print_preamble(FILE *fh, gint format); gboolean print_preamble(FILE *fh, gint format);
void print_finale(FILE *fh, gint format); gboolean print_finale(FILE *fh, gint format);
void proto_tree_print(print_args_t *print_args, epan_dissect_t *edt, void proto_tree_print(print_args_t *print_args, epan_dissect_t *edt,
FILE *fh); FILE *fh);
void print_hex_data(FILE *fh, gint format, epan_dissect_t *edt); void print_hex_data(FILE *fh, gint format, epan_dissect_t *edt);

10
ps.h
View File

@ -1,15 +1,14 @@
/* ps.h /* ps.h
* Definitions for generating PostScript(R) packet output. * Definitions for generating PostScript(R) packet output.
* *
* $Id: ps.h,v 1.6 2004/01/24 10:53:24 guy Exp $
* *
* $Id: ps.h,v 1.5 2002/08/28 21:00:41 jmayer Exp $
* Gilbert Ramirez <gram@alumni.rice.edu> * Gilbert Ramirez <gram@alumni.rice.edu>
* *
* Ethereal - Network traffic analyzer * Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org> * By Gerald Combs <gerald@ethereal.com>
* Copyright 1998 Gerald Combs * Copyright 1998 Gerald Combs
* *
*
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2 * as published by the Free Software Foundation; either version 2
@ -30,8 +29,7 @@
/* Functions in ps.c; automatically generated by rdps */ /* Functions in ps.c; automatically generated by rdps */
void print_ps_preamble(FILE *); int print_ps_preamble(FILE *);
void print_ps_hex(FILE *); int print_ps_finale(FILE *);
void print_ps_finale(FILE *);
#endif /* ps.h */ #endif /* ps.h */

5
rdps.c
View File

@ -1,6 +1,6 @@
/* rdps.c /* rdps.c
* *
* $Id: rdps.c,v 1.6 2004/01/23 00:43:15 jmayer Exp $ * $Id: rdps.c,v 1.7 2004/01/24 10:53:25 guy Exp $
* Ethereal - Network traffic analyzer * Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com> * By Gerald Combs <gerald@ethereal.com>
* Copyright 1998 Gerald Combs * Copyright 1998 Gerald Combs
@ -127,7 +127,7 @@ int main(int argc, char **argv)
void start_code(FILE *fd, char *func) void start_code(FILE *fd, char *func)
{ {
fprintf(fd, "/* Created by rdps.c. Do not edit! */\n"); fprintf(fd, "/* Created by rdps.c. Do not edit! */\n");
fprintf(fd, "void print_ps_%s(FILE *fd) {\n", func); fprintf(fd, "int print_ps_%s(FILE *fd) {\n", func);
} }
void write_code(FILE *fd, char *string) void write_code(FILE *fd, char *string)
@ -139,6 +139,7 @@ void write_code(FILE *fd, char *string)
void end_code(FILE *fd) void end_code(FILE *fd)
{ {
fprintf(fd, "\treturn ferror(fd);\n");
fprintf(fd, "}\n\n\n"); fprintf(fd, "}\n\n\n");
} }