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 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
* By Gerald Combs <gerald@ethereal.com>
@ -119,7 +119,7 @@ static char *cf_open_error_message(int err, gboolean for_writing,
int file_type);
static char *file_rename_error_message(int err);
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);
/* 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)) {
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;
}
}
@ -2812,37 +2812,33 @@ cf_write_error_message(int err)
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. */
static char *
file_close_error_message(int err)
cf_close_error_message(int err)
{
char *errmsg;
static char errmsg_errno[1024+1];
switch (err) {
if (err < 0) {
/* Wiretap error. */
switch (err) {
case WTAP_ERR_CANT_CLOSE:
errmsg = "The file \"%s\" couldn't be closed for some unknown reason.";
break;
case WTAP_ERR_CANT_CLOSE:
errmsg = "The file \"%s\" couldn't be closed for some unknown reason.";
break;
case WTAP_ERR_SHORT_WRITE:
errmsg = "Not all the packets could be written to the file \"%s\".";
break;
case WTAP_ERR_SHORT_WRITE:
errmsg = "Not all the packets could be written to the file \"%s\".";
break;
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:
snprintf(errmsg_errno, sizeof(errmsg_errno),
"An error occurred while closing the file \"%%s\": %s.",
wtap_strerror(err));
errmsg = errmsg_errno;
break;
default:
snprintf(errmsg_errno, sizeof(errmsg_errno),
"An error occurred while closing the file \"%%s\": %s.",
wtap_strerror(err));
errmsg = errmsg_errno;
break;
}
} else {
/* We assume that a close error from the OS is really a write error. */
errmsg = file_write_error_message(err);
}
return errmsg;
}
@ -2908,7 +2904,7 @@ copy_binary_file(char *from_filename, char *to_filename)
if (close(to_fd) < 0) {
err = errno;
simple_dialog(ESD_TYPE_CRIT, NULL,
file_close_error_message(err), to_filename);
file_write_error_message(err), to_filename);
goto done;
}

View File

@ -1,6 +1,6 @@
/* 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
* By Gerald Combs <gerald@ethereal.com>
@ -496,7 +496,7 @@ follow_charset_toggle_cb(GtkWidget * w _U_, gpointer data)
#define FLT_BUF_SIZE 1024
static void
follow_read_stream(follow_info_t *follow_info,
void (*print_line) (char *, int, gboolean, void *),
gboolean (*print_line) (char *, int, gboolean, void *),
void *arg)
{
tcp_stream_chunk sc;
@ -550,13 +550,15 @@ follow_read_stream(follow_info_t *follow_info,
case SHOW_EBCDIC:
/* If our native arch is ASCII, call: */
EBCDIC_to_ASCII(buffer, nchars);
(*print_line) (buffer, nchars, is_server, arg);
if (!(*print_line) (buffer, nchars, is_server, arg))
goto fail;
break;
case SHOW_ASCII:
/* If our native arch is EBCDIC, call:
* ASCII_TO_EBCDIC(buffer, nchars);
*/
(*print_line) (buffer, nchars, is_server, arg);
if (!(*print_line) (buffer, nchars, is_server, arg))
goto fail;
break;
case SHOW_HEXDUMP:
current_pos = 0;
@ -613,14 +615,16 @@ follow_read_stream(follow_info_t *follow_info,
(*global_pos) += i;
hexbuf[cur++] = '\n';
hexbuf[cur] = 0;
(*print_line) (hexbuf, strlen(hexbuf), is_server, arg);
if (!(*print_line) (hexbuf, strlen(hexbuf), is_server, arg))
goto fail;
}
break;
case SHOW_CARRAY:
current_pos = 0;
sprintf(initbuf, "char peer%d_%d[] = {\n", is_server ? 1 : 0,
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) {
gchar hexbuf[256];
gchar hexchars[] = "0123456789abcdef";
@ -655,7 +659,8 @@ follow_read_stream(follow_info_t *follow_info,
(*global_pos) += i;
hexbuf[cur++] = '\n';
hexbuf[cur] = 0;
(*print_line) (hexbuf, strlen(hexbuf), is_server, arg);
if (!(*print_line) (hexbuf, strlen(hexbuf), is_server, arg))
goto fail;
}
break;
}
@ -667,6 +672,7 @@ follow_read_stream(follow_info_t *follow_info,
"Error reading temporary file %s: %s", follow_info->data_out_filename,
strerror(errno));
}
fail:
fclose(data_out_file);
data_out_file = NULL;
} else {
@ -685,12 +691,29 @@ follow_read_stream(follow_info_t *follow_info,
*
* 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)
{
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
@ -720,6 +743,7 @@ follow_print_stream(GtkWidget * w _U_, gpointer data)
gboolean to_file;
char *print_dest;
follow_info_t *follow_info = data;
print_text_args_t args;
switch (prefs.pr_dest) {
case PR_DEST_CMD:
@ -740,27 +764,58 @@ follow_print_stream(GtkWidget * w _U_, gpointer data)
fh = open_print_dest(to_file, print_dest);
if (fh == NULL) {
switch (to_file) {
case FALSE:
simple_dialog(ESD_TYPE_WARN, NULL,
"Couldn't run print command %s.", prefs.pr_cmd);
break;
case TRUE:
if (to_file) {
simple_dialog(ESD_TYPE_WARN, NULL,
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;
}
print_preamble(fh, PR_FMT_TEXT);
follow_read_stream(follow_info, follow_print_text, fh);
print_finale(fh, PR_FMT_TEXT);
close_print_dest(to_file, fh);
if (!print_preamble(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;
}
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,
void *arg)
{
@ -810,6 +865,7 @@ follow_add_to_gtk_text(char *buffer, int nchars, gboolean is_server,
NULL);
g_free(convbuf);
#endif
return TRUE;
}
static void
@ -901,6 +957,7 @@ follow_save_as_ok_cb(GtkWidget * w _U_, GtkFileSelection * fs)
follow_info_t *follow_info;
FILE *fh;
gchar *dirname;
print_text_args_t args;
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);
gtk_widget_destroy(GTK_WIDGET(fs));
follow_read_stream(follow_info, follow_print_text, fh);
fclose(fh);
args.to_file = TRUE;
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. */
dirname = get_dirname(to_name); /* Overwrites to_name */

24
print.c
View File

@ -1,7 +1,7 @@
/* print.c
* 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>
*
@ -78,13 +78,13 @@ FILE *open_print_dest(int to_file, const char *dest)
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 */
if (to_file)
fclose(fh);
return (fclose(fh) == 0);
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 */
void
gboolean
print_preamble(FILE *fh, gint format)
{
if (format == PR_FMT_PS)
print_ps_preamble(fh);
return !print_ps_preamble(fh);
else if (format == PR_FMT_PDML) {
fputs("<?xml version=\"1.0\"?>\n", fh);
fputs("<pdml version=\"" PDML_VERSION "\" ", fh);
fprintf(fh, "creator=\"%s/%s\">\n", PACKAGE, VERSION);
}
return !ferror(fh);
} else
return TRUE;
}
/* Some formats need stuff at the end of the output */
void
gboolean
print_finale(FILE *fh, gint format)
{
if (format == PR_FMT_PS)
print_ps_finale(fh);
return !print_ps_finale(fh);
else if (format == PR_FMT_PDML) {
fputs("</pdml>\n", fh);
}
return !ferror(fh);
} else
return TRUE;
}
void

View File

@ -1,7 +1,7 @@
/* print.h
* 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>
*
@ -65,9 +65,9 @@ typedef struct {
/* Functions in print.h */
FILE *open_print_dest(int to_file, const char *dest);
void close_print_dest(int to_file, FILE *fh);
void print_preamble(FILE *fh, gint format);
void print_finale(FILE *fh, gint format);
gboolean close_print_dest(int to_file, FILE *fh);
gboolean print_preamble(FILE *fh, gint format);
gboolean print_finale(FILE *fh, gint format);
void proto_tree_print(print_args_t *print_args, epan_dissect_t *edt,
FILE *fh);
void print_hex_data(FILE *fh, gint format, epan_dissect_t *edt);

10
ps.h
View File

@ -1,15 +1,14 @@
/* ps.h
* 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>
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
* By Gerald Combs <gerald@ethereal.com>
* Copyright 1998 Gerald Combs
*
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
@ -30,8 +29,7 @@
/* Functions in ps.c; automatically generated by rdps */
void print_ps_preamble(FILE *);
void print_ps_hex(FILE *);
void print_ps_finale(FILE *);
int print_ps_preamble(FILE *);
int print_ps_finale(FILE *);
#endif /* ps.h */

5
rdps.c
View File

@ -1,6 +1,6 @@
/* 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
* By Gerald Combs <gerald@ethereal.com>
* Copyright 1998 Gerald Combs
@ -127,7 +127,7 @@ int main(int argc, char **argv)
void start_code(FILE *fd, char *func)
{
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)
@ -139,6 +139,7 @@ void write_code(FILE *fd, char *string)
void end_code(FILE *fd)
{
fprintf(fd, "\treturn ferror(fd);\n");
fprintf(fd, "}\n\n\n");
}