From d209115ba38e1f5082ecdf702782da0f09a727d2 Mon Sep 17 00:00:00 2001 From: Guy Harris Date: Fri, 16 Apr 2004 23:17:13 +0000 Subject: [PATCH] Add a "report_failure()" routine to allow dissectors to report arbitrary errors to the user. Use that, rather than "g_warning()", in the Diameter dissector to report errors reading the dictionary. Make the format argument to "simple_dialog()" a "const" pointer. Fix up the read-error message in Tethereal to end with a newline. If a simple dialog is requested before the main window or the capture-control window is popped up, queue it up and pop the queued messages up once the main or capture-control window is displayed. svn path=/trunk/; revision=10616 --- alert_box.c | 13 +++- alert_box.h | 7 ++- epan/epan.c | 24 +++++++- epan/epan.h | 3 +- epan/report_err.h | 7 ++- gtk/main.c | 10 +++- gtk/simple_dialog.c | 114 +++++++++++++++++++++++++++--------- packet-diameter.c | 35 ++++++----- plugins/Xass-list | 3 +- plugins/Xplugin_api.c | 1 + plugins/Xplugin_api.h | 1 + plugins/Xplugin_api_decls.h | 1 + plugins/Xplugin_table.h | 1 + plugins/plugin_api_list.c | 5 +- simple_dialog.h | 20 ++++++- tethereal.c | 26 +++++--- 16 files changed, 202 insertions(+), 69 deletions(-) diff --git a/alert_box.c b/alert_box.c index 2bb611fa83..3dca87a893 100644 --- a/alert_box.c +++ b/alert_box.c @@ -2,7 +2,7 @@ * Routines to put up various "standard" alert boxes used in multiple * places * - * $Id: alert_box.c,v 1.5 2004/03/23 21:19:55 guy Exp $ + * $Id: alert_box.c,v 1.6 2004/04/16 23:16:28 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs @@ -38,6 +38,15 @@ #include "simple_dialog.h" +/* + * Alert box for general errors. + */ +void +failure_alert_box(const char *msg_format, va_list ap) +{ + vsimple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, msg_format, ap); +} + /* * Alert box for a failed attempt to open or create a file. * "err" is assumed to be a UNIX-style errno; "for_writing" is TRUE if @@ -65,7 +74,7 @@ void read_failure_alert_box(const char *filename, int err) { simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, - "An error occurred while reading from the file \"%s\": %s.", + "An error occurred while reading from the file \"%s\": %s.", filename, strerror(err)); } diff --git a/alert_box.h b/alert_box.h index 807f1106f0..fbe4b1c463 100644 --- a/alert_box.h +++ b/alert_box.h @@ -2,7 +2,7 @@ * Routines to put up various "standard" alert boxes used in multiple * places * - * $Id: alert_box.h,v 1.4 2004/03/23 21:19:55 guy Exp $ + * $Id: alert_box.h,v 1.5 2004/04/16 23:16:28 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs @@ -30,6 +30,11 @@ extern "C" { #endif /* __cplusplus */ +/* + * Alert box for general errors. + */ +extern void failure_alert_box(const char *msg_format, va_list ap); + /* * Alert box for a failed attempt to open or create a file. * "err" is assumed to be a UNIX-style errno; "for_writing" is TRUE if diff --git a/epan/epan.c b/epan/epan.c index b1fc6adc91..68e425d120 100644 --- a/epan/epan.c +++ b/epan/epan.c @@ -1,6 +1,6 @@ /* epan.h * - * $Id: epan.c,v 1.24 2004/03/23 21:19:56 guy Exp $ + * $Id: epan.c,v 1.25 2004/04/16 23:16:28 guy Exp $ * * Ethereal Protocol Analyzer Library */ @@ -22,6 +22,7 @@ #include "../tap.h" #include "resolv.h" +static void (*report_failure_func)(const char *, va_list); static void (*report_open_failure_func)(const char *, int, gboolean); static void (*report_read_failure_func)(const char *, int); @@ -49,9 +50,11 @@ static void (*report_read_failure_func)(const char *, int); void epan_init(const char *plugin_dir, void (*register_all_protocols)(void), void (*register_all_handoffs)(void), + void (*report_failure)(const char *, va_list), void (*report_open_failure)(const char *, int, gboolean), void (*report_read_failure)(const char *, int)) { + report_failure_func = report_failure; report_open_failure_func = report_open_failure; report_read_failure_func = report_read_failure; except_init(); @@ -90,7 +93,23 @@ epan_circuit_init(void) } /* - * Report an error when trying to open a file. + * Report a general error. + */ +void +report_failure(const char *msg_format, ...) +{ + va_list ap; + + va_start(ap, msg_format); + (*report_failure_func)(msg_format, ap); + va_end(ap); +} + +/* + * Report an error when trying to open or create a file. + * "err" is assumed to be an error code from Wiretap; positive values are + * UNIX-style errnos, so this can be used for open failures not from + * Wiretap as long as the failue code is just an errno. */ void report_open_failure(const char *filename, int err, @@ -101,6 +120,7 @@ report_open_failure(const char *filename, int err, /* * Report an error when trying to read a file. + * "err" is assumed to be a UNIX-style errno. */ void report_read_failure(const char *filename, int err) diff --git a/epan/epan.h b/epan/epan.h index 3493a7f5a2..829baa4e47 100644 --- a/epan/epan.h +++ b/epan/epan.h @@ -1,6 +1,6 @@ /* epan.h * - * $Id: epan.h,v 1.16 2004/03/23 21:19:56 guy Exp $ + * $Id: epan.h,v 1.17 2004/04/16 23:16:28 guy Exp $ * * Ethereal Protocol Analyzer Library * @@ -34,6 +34,7 @@ typedef struct _epan_dissect_t epan_dissect_t; void epan_init(const char * plugindir, void (*register_all_protocols)(void), void (*register_all_handoffs)(void), + void (*report_failure)(const char *, va_list), void (*report_open_failure)(const char *, int, gboolean), void (*report_read_failure)(const char *, int)); void epan_cleanup(void); diff --git a/epan/report_err.h b/epan/report_err.h index ef116eb046..d2659ac1f5 100644 --- a/epan/report_err.h +++ b/epan/report_err.h @@ -2,7 +2,7 @@ * Declarations of routines for dissectors to use to report errors to * the user (e.g., problems with preference settings) * - * $Id: report_err.h,v 1.1 2004/03/23 21:19:56 guy Exp $ + * $Id: report_err.h,v 1.2 2004/04/16 23:16:28 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs @@ -41,6 +41,11 @@ extern void report_open_failure(const char *filename, int err, */ extern void report_read_failure(const char *filename, int err); +/* + * Report a general error. + */ +extern void report_failure(const char *msg_format, ...); + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/gtk/main.c b/gtk/main.c index c94f096a0c..276fb3bee2 100644 --- a/gtk/main.c +++ b/gtk/main.c @@ -1,6 +1,6 @@ /* main.c * - * $Id: main.c,v 1.422 2004/04/06 19:02:18 ulfl Exp $ + * $Id: main.c,v 1.423 2004/04/16 23:16:29 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs @@ -1940,7 +1940,7 @@ main(int argc, char *argv[]) dissectors, and we must do it before we read the preferences, in case any dissectors register preferences. */ epan_init(PLUGIN_DIR,register_all_protocols,register_all_protocol_handoffs, - open_failure_alert_box, read_failure_alert_box); + failure_alert_box,open_failure_alert_box,read_failure_alert_box); /* Register all tap listeners; we do this before we parse the arguments, as the "-z" argument can specify a registered tap. */ @@ -2694,6 +2694,9 @@ main(int argc, char *argv[]) we were told to. */ create_main_window(pl_size, tv_size, bv_size, prefs); + /* Pop up any queued-up alert boxes. */ + display_queued_messages(); + /* Read the recent file, as we have the gui now ready for it. */ read_recent(&rf_path, &rf_open_errno); @@ -2808,6 +2811,9 @@ main(int argc, char *argv[]) } #endif + /* Pop up any queued-up alert boxes. */ + display_queued_messages(); + /* If the global preferences file exists but we failed to open it or had an error reading it, pop up an alert box; we defer that until now, so that the alert box is more likely to come up on top of diff --git a/gtk/simple_dialog.c b/gtk/simple_dialog.c index a742f80b95..5e39d49a1d 100644 --- a/gtk/simple_dialog.c +++ b/gtk/simple_dialog.c @@ -1,7 +1,7 @@ /* simple_dialog.c * Simple message dialog box routines. * - * $Id: simple_dialog.c,v 1.30 2004/03/13 15:30:08 ulfl Exp $ + * $Id: simple_dialog.c,v 1.31 2004/04/16 23:16:29 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs @@ -45,35 +45,26 @@ static void simple_dialog_cancel_cb(GtkWidget *, gpointer); #define CALLBACK_BTN_KEY "ESD_Callback_Btn" #define CALLBACK_DATA_KEY "ESD_Callback_Data" -/* Simple dialog function - Displays a dialog box with the supplied message - * text. - * - * Args: - * type : One of ESD_TYPE_*. - * btn_mask : The value passed in determines which buttons are displayed. - * msg_format : Sprintf-style format of the text displayed in the dialog. - * ... : Argument list for msg_format - * - * - * XXX - if we haven't yet put up the main window, we should just - * queue up the message, etc., and wait until the main window pops up - * (or until we figure out that we're in a capture child and aren't - * going to pop up a main window) and pop up the alert boxes then, so - * that even stuff popped up before we put up the main window (such - * as file-open or file-read errors from dissectors' init routines) - * shows up on top. +/* + * Queue for messages requested before we have a main window. */ +typedef struct { + gint type; + gint btn_mask; + char *message; +} queued_message_t; + +static GSList *message_queue; -gpointer -simple_dialog(gint type, gint btn_mask, gchar *msg_format, ...) { +static GtkWidget * +display_simple_dialog(gint type, gint btn_mask, char *message) +{ GtkWidget *win, *main_vb, *top_hb, *type_pm, *msg_label, *bbox, *ok_bt, *bt; GdkPixmap *pixmap; GdkBitmap *mask; GtkStyle *style; GdkColormap *cmap; - va_list ap; - gchar message[2048]; gchar **icon; /* Main window */ @@ -156,11 +147,6 @@ simple_dialog(gint type, gint btn_mask, gchar *msg_format, ...) { gtk_container_add(GTK_CONTAINER(top_hb), type_pm); gtk_widget_show(type_pm); - /* Load our vararg list into the message string */ - va_start(ap, msg_format); - g_vsnprintf(message, sizeof(message), msg_format, ap); - va_end(ap); - msg_label = gtk_label_new(message); #if GTK_MAJOR_VERSION >= 2 @@ -240,6 +226,78 @@ simple_dialog(gint type, gint btn_mask, gchar *msg_format, ...) { return win; } +void +display_queued_messages(void) +{ + queued_message_t *queued_message; + + while (message_queue != NULL) { + queued_message = message_queue->data; + message_queue = g_slist_remove(message_queue, queued_message); + + display_simple_dialog(queued_message->type, queued_message->btn_mask, + queued_message->message); + + g_free(queued_message->message); + g_free(queued_message); + } +} + +/* Simple dialog function - Displays a dialog box with the supplied message + * text. + * + * Args: + * type : One of ESD_TYPE_*. + * btn_mask : The value passed in determines which buttons are displayed. + * msg_format : Sprintf-style format of the text displayed in the dialog. + * ... : Argument list for msg_format + */ + +gpointer +vsimple_dialog(gint type, gint btn_mask, const gchar *msg_format, va_list ap) +{ + gchar *message; + queued_message_t *queued_message; + GtkWidget *win; + + /* Format the message. */ + message = g_strdup_vprintf(msg_format, ap); + + /* If we don't yet have a main window, queue up the message for later + display. */ + if (top_level == NULL) { + queued_message = g_malloc(sizeof (queued_message_t)); + queued_message->type = type; + queued_message->btn_mask = btn_mask; + queued_message->message = message; + message_queue = g_slist_append(message_queue, queued_message); + return NULL; + } + + /* + * Do we have any queued up messages? If so, pop them up. + */ + display_queued_messages(); + + win = display_simple_dialog(type, btn_mask, message); + + g_free(message); + + return win; +} + +gpointer +simple_dialog(gint type, gint btn_mask, const gchar *msg_format, ...) +{ + va_list ap; + gpointer ret; + + va_start(ap, msg_format); + ret = vsimple_dialog(type, btn_mask, msg_format, ap); + va_end(ap); + return ret; +} + static void simple_dialog_cancel_cb(GtkWidget *w, gpointer win) { gint button = GPOINTER_TO_INT( OBJECT_GET_DATA(w, CALLBACK_BTN_KEY)); @@ -268,5 +326,3 @@ char * simple_dialog_primary_end(void) { return PRIMARY_TEXT_END; } - - diff --git a/packet-diameter.c b/packet-diameter.c index 18c36d81ed..8a77c824d8 100644 --- a/packet-diameter.c +++ b/packet-diameter.c @@ -1,7 +1,7 @@ /* packet-diameter.c * Routines for Diameter packet disassembly * - * $Id: packet-diameter.c,v 1.65 2004/03/23 21:19:55 guy Exp $ + * $Id: packet-diameter.c,v 1.66 2004/04/16 23:16:28 guy Exp $ * * Copyright (c) 2001 by David Frascone * @@ -322,7 +322,7 @@ xmlParseFilePush( char *filename, int checkValid) { /* Check valid */ if (!valid) { - g_warning( "Error! Invalid xml in %s! Failed DTD check!", + report_failure( "Error! Invalid xml in %s! Failed DTD check!", filename); return NULL; } @@ -411,7 +411,7 @@ xmlParseAVP(xmlNodePtr cur) valueCode = XmlStub.xmlGetProp(cur, "code"); if (!valueName || !valueCode) { - g_warning( "Error, bad value on avp %s", name); + report_failure( "Error, bad value on avp %s", name); return (-1); } @@ -440,11 +440,11 @@ xmlParseAVP(xmlNodePtr cur) } if (TypeValues[i].strptr == NULL) { - g_warning( "Invalid Type field in dictionary! avp %s (%s)", name, type); + report_failure( "Invalid Type field in dictionary! avp %s (%s)", name, type); return (-1); } } else if (!vEntry) { - g_warning("Missing type/enum field in dictionary avpName=%s", + report_failure("Missing type/enum field in dictionary avpName=%s", name); return (-1); } @@ -486,7 +486,7 @@ addCommand(int code, char *name, char *vendorId) entry = (CommandCode *) g_malloc(sizeof (CommandCode)); if (entry == NULL) { - g_warning("Unable to allocate memory"); + report_failure("Unable to allocate memory"); return (-1); } @@ -523,7 +523,7 @@ xmlParseCommand(xmlNodePtr cur) name = XmlStub.xmlGetProp(cur, "name"); code = XmlStub.xmlGetProp(cur, "code"); if (!name || !code) { - g_warning("Invalid command. Name or code missing!"); + report_failure("Invalid command. Name or code missing!"); return -1; } vendorIdString = XmlStub.xmlGetProp(cur, "vendor-id"); @@ -542,14 +542,14 @@ dictionaryAddApplication(char *name, int id) ApplicationId *entry; if (!name || (id < 0) || (id == 0 && !allow_zero_as_app_id)) { - g_warning( "Diameter Error: Invalid application (name=%p, id=%d)", + report_failure( "Diameter Error: Invalid application (name=%p, id=%d)", name, id); return (-1); } /* Sanity Checks */ entry = g_malloc(sizeof(ApplicationId)); if (!entry) { - g_warning( "Unable to allocate memory"); + report_failure( "Unable to allocate memory"); return (-1); } @@ -600,7 +600,7 @@ xmlParseVendor(xmlNodePtr cur) code = XmlStub.xmlGetProp(cur, "code"); if (!id || !name || !code) { - g_warning( "Invalid vendor section. vendor-id, name, and code must be specified"); + report_failure( "Invalid vendor section. vendor-id, name, and code must be specified"); return -1; } @@ -623,7 +623,7 @@ xmlDictionaryParseSegment(xmlNodePtr cur, int base) if (!name || !id) { /* ERROR!!! */ - g_warning("Diameter: Invalid application!: name=\"%s\", id=\"%s\"", + report_failure("Diameter: Invalid application!: name=\"%s\", id=\"%s\"", name?name:"NULL", id?id:"NULL"); return -1; } @@ -657,7 +657,7 @@ xmlDictionaryParseSegment(xmlNodePtr cur, int base) /* WORK -- parse in valid types . . . */ } else { /* IF we got here, we're an error */ - g_warning("Error! expecting an avp or a typedefn (got \"%s\")", + report_failure("Error! expecting an avp or a typedefn (got \"%s\")", cur->name); return (-1); } @@ -686,7 +686,7 @@ xmlDictionaryParse(xmlNodePtr cur) } else if (strcasecmp(cur->name, "comment") == 0) { /* Ignore text */ } else { - g_warning( "Diameter: XML Expecting a base or an application (got \"%s\")", + report_failure( "Diameter: XML Expecting a base or an application (got \"%s\")", cur->name); return (-1); } @@ -715,7 +715,7 @@ loadXMLDictionary(void) /* Check for invalid xml */ if (doc == NULL) { - g_warning("Diameter: Unable to parse xmldictionary %s", + report_failure("Diameter: Unable to parse xmldictionary %s", gbl_diameterDictionary); return -1; } @@ -725,13 +725,13 @@ loadXMLDictionary(void) */ cur = XmlStub.xmlDocGetRootElement(doc); if (cur == NULL) { - g_warning("Diameter: Error: \"%s\": empty document", + report_failure("Diameter: Error: \"%s\": empty document", gbl_diameterDictionary); XmlStub.xmlFreeDoc(doc); return -1; } if (XmlStub.xmlStrcmp(cur->name, (const xmlChar *) "dictionary")) { - g_warning("Diameter: Error: \"%s\": document of the wrong type, root node != dictionary", + report_failure("Diameter: Error: \"%s\": document of the wrong type, root node != dictionary", gbl_diameterDictionary); XmlStub.xmlFreeDoc(doc); return -1; @@ -801,7 +801,7 @@ initializeDictionary(void) if (loadLibXML() || (loadXMLDictionary() != 0)) { /* Something failed. Use the static dictionary */ - g_warning("Diameter: Using static dictionary! (Unable to use XML)"); + report_failure("Diameter: Using static dictionary! (Unable to use XML)"); initializeDictionaryDefaults(); } } /* initializeDictionary */ @@ -1949,4 +1949,3 @@ proto_register_diameter(void) prefs_register_obsolete_preference(diameter_module, "udp.port"); prefs_register_obsolete_preference(diameter_module, "command_in_header"); } /* proto_register_diameter */ - diff --git a/plugins/Xass-list b/plugins/Xass-list index 2ce7c2135b..fac836700d 100644 --- a/plugins/Xass-list +++ b/plugins/Xass-list @@ -80,4 +80,5 @@ dissect_ber_sequence, dissect_ber_sequence_of, dissect_ber_set_of, dissect_ber_octet_string, dissect_ber_bitstring, dissect_ber_restricted_string, dissect_ber_object_identifier, get_ber_identifier, get_ber_length, proto_item_get_subtree, proto_tree_get_parent, proto_item_get_parent, -proto_item_get_parent_nth, get_ber_last_created_item, +proto_item_get_parent_nth, get_ber_last_created_item, report_failure, + diff --git a/plugins/Xplugin_api.c b/plugins/Xplugin_api.c index b34b3aa2ca..d3226071b4 100644 --- a/plugins/Xplugin_api.c +++ b/plugins/Xplugin_api.c @@ -273,3 +273,4 @@ p_proto_tree_get_parent = pat->p_proto_tree_get_parent; p_proto_item_get_parent = pat->p_proto_item_get_parent; p_proto_item_get_parent_nth = pat->p_proto_item_get_parent_nth; p_get_ber_last_created_item = pat->p_get_ber_last_created_item; +p_report_failure = pat->p_report_failure; diff --git a/plugins/Xplugin_api.h b/plugins/Xplugin_api.h index 1cb990247a..ed3e3347a6 100644 --- a/plugins/Xplugin_api.h +++ b/plugins/Xplugin_api.h @@ -273,3 +273,4 @@ #define proto_item_get_parent (*p_proto_item_get_parent) #define proto_item_get_parent_nth (*p_proto_item_get_parent_nth) #define get_ber_last_created_item (*p_get_ber_last_created_item) +#define report_failure (*p_report_failure) diff --git a/plugins/Xplugin_api_decls.h b/plugins/Xplugin_api_decls.h index 7473bfc15c..b684430a83 100644 --- a/plugins/Xplugin_api_decls.h +++ b/plugins/Xplugin_api_decls.h @@ -273,3 +273,4 @@ addr_proto_tree_get_parent p_proto_tree_get_parent; addr_proto_item_get_parent p_proto_item_get_parent; addr_proto_item_get_parent_nth p_proto_item_get_parent_nth; addr_get_ber_last_created_item p_get_ber_last_created_item; +addr_report_failure p_report_failure; diff --git a/plugins/Xplugin_table.h b/plugins/Xplugin_table.h index 9c5d45f858..64ed5a0d50 100644 --- a/plugins/Xplugin_table.h +++ b/plugins/Xplugin_table.h @@ -273,3 +273,4 @@ typedef proto_item *(*addr_proto_tree_get_parent) (proto_tree *); typedef proto_item *(*addr_proto_item_get_parent) (proto_item *); typedef proto_item *(*addr_proto_item_get_parent_nth) (proto_item *, int); typedef proto_item *(*addr_get_ber_last_created_item) (void); +typedef void (*addr_report_failure) (const char *, ...); diff --git a/plugins/plugin_api_list.c b/plugins/plugin_api_list.c index 5ba305759d..2b47dbd7a0 100644 --- a/plugins/plugin_api_list.c +++ b/plugins/plugin_api_list.c @@ -1,7 +1,7 @@ /* plugin_api_list.c * Used to generate various included files for plugin API * - * $Id: plugin_api_list.c,v 1.33 2004/03/25 23:55:21 guy Exp $ + * $Id: plugin_api_list.c,v 1.34 2004/04/16 23:16:29 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs @@ -434,3 +434,6 @@ proto_item* proto_tree_get_parent(proto_tree *tree); proto_item* proto_item_get_parent(proto_item *ti); proto_item* proto_item_get_parent_nth(proto_item *ti, int gen); proto_item *get_ber_last_created_item(void); + +void report_failure(const char *msg_format, ...); + diff --git a/simple_dialog.h b/simple_dialog.h index e729aab654..44df274c57 100644 --- a/simple_dialog.h +++ b/simple_dialog.h @@ -2,7 +2,7 @@ * Definitions for alert box routines with toolkit-independent APIs but * toolkit-dependent implementations. * - * $Id: simple_dialog.h,v 1.11 2004/02/12 22:24:27 guy Exp $ + * $Id: simple_dialog.h,v 1.12 2004/04/16 23:16:28 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs @@ -60,10 +60,16 @@ extern "C" { /* show a simple dialog */ #if __GNUC__ >= 2 -extern gpointer simple_dialog(gint type, gint btn_mask, gchar *msg_format, ...) +extern gpointer simple_dialog(gint type, gint btn_mask, + const gchar *msg_format, ...) __attribute__((format (printf, 3, 4))); +extern gpointer vsimple_dialog(gint type, gint btn_mask, + const gchar *msg_format, va_list ap); #else -extern gpointer simple_dialog(gint type, gint btn_mask, gchar *msg_format, ...); +extern gpointer simple_dialog(gint type, gint btn_mask, + const gchar *msg_format, ...); +extern gpointer vsimple_dialog(gint type, gint btn_mask, + const gchar *msg_format, va_list ap); #endif /* callback function type */ @@ -75,6 +81,14 @@ extern void simple_dialog_set_cb(gpointer dialog, simple_dialog_cb_t callback_fc extern char *simple_dialog_primary_start(void); extern char *simple_dialog_primary_end(void); +/* + * If a routine is called to display a dialog before there are any windows + * open, information to use to display the dialog is queued up. This + * routine should be called once there are windows open, so that the queued + * up dialogs are displayed on top of those windows. + */ +extern void display_queued_messages(void); + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/tethereal.c b/tethereal.c index 1efad85f36..32f1dc36c5 100644 --- a/tethereal.c +++ b/tethereal.c @@ -1,6 +1,6 @@ /* tethereal.c * - * $Id: tethereal.c,v 1.234 2004/04/16 18:17:47 ulfl Exp $ + * $Id: tethereal.c,v 1.235 2004/04/16 23:16:28 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs @@ -187,6 +187,7 @@ static int pipe_dispatch(int, loop_data *, struct pcap_hdr *, \ static void open_failure_message(const char *filename, int err, gboolean for_writing); +static void failure_message(const char *msg_format, va_list ap); static void read_failure_message(const char *filename, int err); capture_file cfile; @@ -840,7 +841,7 @@ main(int argc, char *argv[]) dissectors, and we must do it before we read the preferences, in case any dissectors register preferences. */ epan_init(PLUGIN_DIR,register_all_protocols,register_all_protocol_handoffs, - open_failure_message, read_failure_message); + failure_message,open_failure_message,read_failure_message); /* Register all tap listeners; we do this before we parse the arguments, as the "-z" argument can specify a registered tap. */ @@ -2977,11 +2978,9 @@ cf_open_error_message(int err, gchar *err_info, gboolean for_writing, static void open_failure_message(const char *filename, int err, gboolean for_writing) { - char *errmsg; - - errmsg = g_strdup_printf(file_open_error_message(err, for_writing), filename); - fprintf(stderr, "tethereal: %s\n", errmsg); - g_free(errmsg); + fprintf(stderr, "tethereal: "); + fprintf(stderr, file_open_error_message(err, for_writing), filename); + fprintf(stderr, "\n"); } int @@ -3329,12 +3328,23 @@ pipe_dispatch(int fd, loop_data *ld, struct pcap_hdr *hdr, #endif /* _WIN32 */ #endif /* HAVE_LIBPCAP */ +/* + * General errors are reported with an console message in Tethereal. + */ +static void +failure_message(const char *msg_format, va_list ap) +{ + fprintf(stderr, "tethereal: "); + vfprintf(stderr, msg_format, ap); + fprintf(stderr, "\n"); +} + /* * Read errors are reported with an console message in Tethereal. */ static void read_failure_message(const char *filename, int err) { - fprintf(stderr, "tethereal: An error occurred while reading from the file \"%s\": %s.", + fprintf(stderr, "tethereal: An error occurred while reading from the file \"%s\": %s.\n", filename, strerror(err)); }