From ddf6a8acf2bb398d8aa4072700c4bf915d498d73 Mon Sep 17 00:00:00 2001 From: Guy Harris Date: Thu, 7 Aug 2003 00:41:28 +0000 Subject: [PATCH] From Michael Lum: add the ability to have a preferences file containing a list of disabled protocols, and to save that list from the Edit > Protocols dialog box. Add checks for read errors in "read_prefs()". Clean up white space. svn path=/trunk/; revision=8144 --- AUTHORS | 4 + Makefile.am | 6 +- Makefile.nmake | 3 +- disabled_protos.c | 350 ++++++++++++++++++++++++++++++++++++++ disabled_protos.h | 59 +++++++ doc/ethereal.pod.template | 3 +- gtk/main.c | 186 ++++++++++++-------- gtk/proto_dlg.c | 52 +++++- prefs.c | 39 ++++- prefs.h | 10 +- tethereal.c | 55 +++++- 11 files changed, 671 insertions(+), 96 deletions(-) create mode 100644 disabled_protos.c create mode 100644 disabled_protos.h diff --git a/AUTHORS b/AUTHORS index c5d277d0f1..d33bb1555d 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1769,6 +1769,10 @@ Oleg Terletsky { LWRES support } +Michael Lum { + Support for saving list of disabled protocols +} + And assorted fixes and enhancements by the people listed above and by: Pavel Roskin diff --git a/Makefile.am b/Makefile.am index ee820f2129..2917f8c00e 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,7 +1,7 @@ # Makefile.am # Automake file for Ethereal # -# $Id: Makefile.am,v 1.606 2003/08/05 05:09:35 guy Exp $ +# $Id: Makefile.am,v 1.607 2003/08/07 00:41:26 guy Exp $ # # Ethereal - Network traffic analyzer # By Gerald Combs @@ -713,7 +713,8 @@ ETHEREAL_COMMON_SRC = \ crypt-md5.h \ crypt-rc4.c \ crypt-rc4.h \ - packet-dcerpc-nt.c \ + disabled_protos.c \ + disabled_protos.h \ etypes.h \ file.h \ follow.c \ @@ -730,6 +731,7 @@ ETHEREAL_COMMON_SRC = \ llcsaps.h \ nlpid.h \ oui.h \ + packet-dcerpc-nt.c \ pcap-util.c \ pcap-util.h \ ppptypes.h \ diff --git a/Makefile.nmake b/Makefile.nmake index 858694eb7e..5fd45dbde4 100644 --- a/Makefile.nmake +++ b/Makefile.nmake @@ -1,7 +1,7 @@ ## Makefile for building ethereal.exe with Microsoft C and nmake ## Use: $(MAKE) /$(MAKEFLAGS) -f makefile.nmake # -# $Id: Makefile.nmake,v 1.321 2003/08/01 09:16:47 sahlberg Exp $ +# $Id: Makefile.nmake,v 1.322 2003/08/07 00:41:26 guy Exp $ include config.nmake include @@ -403,6 +403,7 @@ ETHEREAL_COMMON_OBJECTS = \ crypt-md4.obj \ crypt-md5.obj \ crypt-rc4.obj \ + disabled_protos.obj \ follow.obj \ g711.obj \ getopt.obj \ diff --git a/disabled_protos.c b/disabled_protos.c new file mode 100644 index 0000000000..45b35e9ba7 --- /dev/null +++ b/disabled_protos.c @@ -0,0 +1,350 @@ +/* disabled_protos.c + * Code for reading and writing the disabled protocols file. + * + * $Id: disabled_protos.c,v 1.1 2003/08/07 00:41:26 guy Exp $ + * + * Ethereal - Network traffic analyzer + * By Gerald Combs + * 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 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include +#include + +#ifdef HAVE_UNISTD_H +#include +#endif + +#include + +#include +#include + +#include "disabled_protos.h" + +#define PROTOCOLS_FILE_NAME "disabled_protos" + +/* + * List of disabled protocols + */ +static GList *disabled_protos = NULL; + +#define INIT_BUF_SIZE 128 + +/* + * Read in a list of disabled protocols. + * + * On success, "*pref_path_return" is set to NULL. + * On error, "*pref_path_return" is set to point to the pathname of + * the file we tried to read - it should be freed by our caller - + * and "*open_errno_return" is set to the error if an open failed + * or "*read_errno_return" is set to the error if a read failed. + */ + +void +read_disabled_protos_list(char **pref_path_return, int *open_errno_return, + int *read_errno_return) +{ + char *ff_path, *ff_name; + FILE *ff; + GList **flp; + GList *fl_ent; + protocol_def *prot; + int c; + char *prot_name; + int prot_name_len; + int prot_name_index; + int line = 1; + + *pref_path_return = NULL; /* assume no error */ + + ff_name = PROTOCOLS_FILE_NAME; + flp = &disabled_protos; + + /* To do: generalize this */ + ff_path = get_persconffile_path(ff_name, FALSE); + if ((ff = fopen(ff_path, "r")) == NULL) { + /* + * Did that fail because we the file didn't exist? + */ + if (errno != ENOENT) { + /* + * No. Just give up. + */ + *pref_path_return = ff_path; + *open_errno_return = errno; + *read_errno_return = 0; + return; + } + + /* + * Yes. See if there's a "protocols" file; if so, read it. + */ + g_free(ff_path); + ff_path = get_persconffile_path(PROTOCOLS_FILE_NAME, FALSE); + if ((ff = fopen(ff_path, "r")) == NULL) { + /* + * Well, that didn't work, either. Just give up. + * Return an error if the file existed but we couldn't open it. + */ + if (errno != ENOENT) { + *pref_path_return = ff_path; + *open_errno_return = errno; + *read_errno_return = 0; + } + return; + } + } + + /* If we already have a list of protocols, discard it. */ + if (*flp != NULL) { + fl_ent = g_list_first(*flp); + while (fl_ent != NULL) { + prot = (protocol_def *) fl_ent->data; + g_free(prot->name); + g_free(prot); + fl_ent = fl_ent->next; + } + g_list_free(*flp); + *flp = NULL; + } + + /* Allocate the protocol name buffer. */ + prot_name_len = INIT_BUF_SIZE; + prot_name = g_malloc(prot_name_len + 1); + + for (line = 1; ; line++) { + /* Lines in a disabled protocol file contain the "filter name" of + a protocol to be disabled. */ + + /* Skip over leading white space, if any. */ + while ((c = getc(ff)) != EOF && isspace(c)) { + if (c == '\n') { + /* Blank line. */ + continue; + } + } + + if (c == EOF) { + if (ferror(ff)) + goto error; /* I/O error */ + else + break; /* Nothing more to read */ + } + ungetc(c, ff); /* Unread the non-white-space character. */ + + /* Get the name of the protocol. */ + prot_name_index = 0; + for (;;) { + c = getc(ff); + if (c == EOF) + break; /* End of file, or I/O error */ + if (isspace(c)) + break; /* Trailing white space, or end of line. */ + if (c == '#') + break; /* Start of comment, running to end of line. */ + /* Add this character to the protocol name string. */ + if (prot_name_index >= prot_name_len) { + /* protocol name buffer isn't long enough; double its length. */ + prot_name_len *= 2; + prot_name = g_realloc(prot_name, prot_name_len + 1); + } + prot_name[prot_name_index] = c; + prot_name_index++; + } + + if (isspace(c) && c != '\n') { + /* Skip over trailing white space. */ + while ((c = getc(ff)) != EOF && c != '\n' && isspace(c)) + ; + if (c != EOF && c != '\n') { + /* Non-white-space after the protocol name; warn about it, + in case we come up with a reason to use it. */ + g_warning("'%s' line %d has extra stuff after the protocol name.", + ff_path, line); + + /* Skip to end of line. */ + while ((c = getc(ff)) != EOF && c != '\n') + ; + } + } else if (c == '#') { + /* Comment - skip to end of line. */ + while ((c = getc(ff)) != EOF && c != '\n') + ; + } + + if (c == EOF) { + if (ferror(ff)) + goto error; /* I/O error */ + else { + /* EOF, not error; no newline seen before EOF */ + g_warning("'%s' line %d doesn't have a newline.", ff_path, + line); + } + break; /* nothing more to read */ + } + + /* Null-terminate the protocol name. */ + if (prot_name_index >= prot_name_len) { + /* protocol name buffer isn't long enough; double its length. */ + prot_name_len *= 2; + prot_name = g_realloc(prot_name, prot_name_len + 1); + } + prot_name[prot_name_index] = '\0'; + + /* Add the new protocol to the list of disabled protocols */ + prot = (protocol_def *) g_malloc(sizeof(protocol_def)); + prot->name = g_strdup(prot_name); + *flp = g_list_append(*flp, prot); + } + g_free(ff_path); + fclose(ff); + g_free(prot_name); + return; + +error: + *pref_path_return = ff_path; + *open_errno_return = 0; + *read_errno_return = errno; + fclose(ff); +} + +/* + * Disable protocols as per the stored configuration + */ +void +set_disabled_protos_list(void) +{ + gint i; + GList *fl_ent; + protocol_def *prot; + + /* + * assume all protocols are enabled by default + */ + if (disabled_protos == NULL) + return; /* nothing to disable */ + + fl_ent = g_list_first(disabled_protos); + + while (fl_ent != NULL) { + prot = (protocol_def *) fl_ent->data; + i = proto_get_id_by_filter_name(prot->name); + if (i == -1) { + /* XXX - complain here? */ + } else { + if (proto_can_disable_protocol(i)) + proto_set_decoding(i, FALSE); + } + + fl_ent = fl_ent->next; + } +} + +/* + * Write out a list of disabled protocols. + * + * On success, "*pref_path_return" is set to NULL. + * On error, "*pref_path_return" is set to point to the pathname of + * the file we tried to read - it should be freed by our caller - + * and "*errno_return" is set to the error. + */ +void +save_disabled_protos_list(char **pref_path_return, int *errno_return) +{ + gchar *ff_path, *ff_path_new, *ff_name; + FILE *ff; + gint i; + void *cookie; + + *pref_path_return = NULL; /* assume no error */ + + ff_name = PROTOCOLS_FILE_NAME; + + ff_path = get_persconffile_path(ff_name, TRUE); + + /* Write to "XXX.new", and rename if that succeeds. + That means we don't trash the file if we fail to write it out + completely. */ + ff_path_new = (gchar *) g_malloc(strlen(ff_path) + 5); + sprintf(ff_path_new, "%s.new", ff_path); + + if ((ff = fopen(ff_path_new, "w")) == NULL) { + *pref_path_return = ff_path; + *errno_return = errno; + g_free(ff_path_new); + return; + } + + /* Iterate over all the protocols */ + + for (i = proto_get_first_protocol(&cookie); i != -1; + i = proto_get_next_protocol(&cookie)) { + + if (!proto_can_disable_protocol(i)) { + continue; + } + + if (proto_is_protocol_enabled(i)) { + continue; + } + + /* Write out the protocol name. */ + fprintf(ff, "%s\n", proto_get_protocol_filter_name(i)); + } + + if (fclose(ff) == EOF) { + *pref_path_return = ff_path; + *errno_return = errno; + unlink(ff_path_new); + g_free(ff_path_new); + return; + } + +#ifdef WIN32 + /* ANSI C doesn't say whether "rename()" removes the target if it + exists; the Win32 call to rename files doesn't do so, which I + infer is the reason why the MSVC++ "rename()" doesn't do so. + We must therefore remove the target file first, on Windows. */ + if (remove(ff_path) < 0 && errno != ENOENT) { + /* It failed for some reason other than "it's not there"; if + it's not there, we don't need to remove it, so we just + drive on. */ + *pref_path_return = ff_path; + *errno_return = errno; + unlink(ff_path_new); + g_free(ff_path_new); + return; + } +#endif + + if (rename(ff_path_new, ff_path) < 0) { + *pref_path_return = ff_path; + *errno_return = errno; + unlink(ff_path_new); + g_free(ff_path_new); + return; + } + g_free(ff_path_new); + g_free(ff_path); +} diff --git a/disabled_protos.h b/disabled_protos.h new file mode 100644 index 0000000000..867f32f9af --- /dev/null +++ b/disabled_protos.h @@ -0,0 +1,59 @@ +/* disabled_protos.h + * Declarations of routines for reading and writing the disabled protocols file. + * + * $Id: disabled_protos.h,v 1.1 2003/08/07 00:41:26 guy Exp $ + * + * Ethereal - Network traffic analyzer + * By Gerald Combs + * 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 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +/* + * Item in a list of disabled protocols. + */ +typedef struct { + char *name; /* protocol name */ +} protocol_def; + +/* + * Read in a list of disabled protocols. + * + * On success, "*pref_path_return" is set to NULL. + * On error, "*pref_path_return" is set to point to the pathname of + * the file we tried to read - it should be freed by our caller - + * and "*open_errno_return" is set to the error if we couldn't open the file + * or "*read_errno_return" is set to the error if we got an error reading + * the file. + */ +void read_disabled_protos_list(char **pref_path_return, int *open_errno_return, + int *read_errno_return); + +/* + * Disable protocols as per the stored configuration + */ +void set_disabled_protos_list(void); + +/* + * Write out a list of disabled protocols. + * + * On success, "*pref_path_return" is set to NULL. + * On error, "*pref_path_return" is set to point to the pathname of + * the file we tried to read - it should be freed by our caller - + * and "*errno_return" is set to the error. + */ +void save_disabled_protos_list(char **pref_path_return, int *errno_return); diff --git a/doc/ethereal.pod.template b/doc/ethereal.pod.template index 5554f37c0d..63f2a67af2 100644 --- a/doc/ethereal.pod.template +++ b/doc/ethereal.pod.template @@ -1862,7 +1862,8 @@ B. Christoph Wiest Xuan Zhang Thierry Martin - Oleg Terletsky { + Oleg Terletsky + Michael Lum Pavel Roskin Georgi Guninski Jason Copenhaver diff --git a/gtk/main.c b/gtk/main.c index 093f4277f9..bfc9accd73 100644 --- a/gtk/main.c +++ b/gtk/main.c @@ -1,6 +1,6 @@ /* main.c * - * $Id: main.c,v 1.303 2003/07/25 04:11:51 gram Exp $ + * $Id: main.c,v 1.304 2003/08/07 00:41:28 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs @@ -84,6 +84,7 @@ #include "summary.h" #include "file.h" #include "filters.h" +#include "disabled_protos.h" #include "prefs.h" #include "menu.h" #include "../menu.h" @@ -1445,9 +1446,12 @@ main(int argc, char *argv[]) WSADATA wsaData; #endif /* WIN32 */ - char *gpf_path, *cf_path, *df_path; - char *pf_path; - int gpf_open_errno, pf_open_errno, cf_open_errno, df_open_errno; + char *gpf_path, *pf_path; + char *cf_path, *df_path, *dp_path; + int gpf_open_errno, gpf_read_errno; + int pf_open_errno, pf_read_errno; + int cf_open_errno, df_open_errno; + int dp_open_errno, dp_read_errno; int err; #ifdef HAVE_LIBPCAP gboolean start_capture = FALSE; @@ -1601,7 +1605,8 @@ main(int argc, char *argv[]) gtk_init (&argc, &argv); /* Read the preference files. */ - prefs = read_prefs(&gpf_open_errno, &gpf_path, &pf_open_errno, &pf_path); + prefs = read_prefs(&gpf_open_errno, &gpf_read_errno, &gpf_path, + &pf_open_errno, &pf_read_errno, &pf_path); #ifdef HAVE_LIBPCAP capture_opts.has_snaplen = FALSE; @@ -1646,6 +1651,9 @@ main(int argc, char *argv[]) /* Read the display filter file. */ read_filter_list(DFILTER_LIST, &df_path, &df_open_errno); + /* Read the disabled protocols file. */ + read_disabled_protos_list(&dp_path, &dp_open_errno, &dp_read_errno); + init_cap_file(&cfile); #ifdef WIN32 @@ -1977,6 +1985,11 @@ main(int argc, char *argv[]) line that their preferences have changed. */ prefs_apply_all(); + /* disabled protocols as per configuration file */ + if (dp_path == NULL) { + set_disabled_protos_list(); + } + #ifndef HAVE_LIBPCAP if (capture_option_specified) fprintf(stderr, "This version of Ethereal was not built with support for capturing packets.\n"); @@ -2215,24 +2228,40 @@ main(int argc, char *argv[]) } #endif - /* If the global preferences file exists but we failed to open 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 the main window. */ + /* 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 + the main window. */ if (gpf_path != NULL) { + if (gpf_open_errno != 0) { simple_dialog(ESD_TYPE_WARN, NULL, "Could not open global preferences file\n\"%s\": %s.", gpf_path, strerror(gpf_open_errno)); + } + if (gpf_read_errno != 0) { + simple_dialog(ESD_TYPE_WARN, NULL, + "I/O error reading global preferences file\n\"%s\": %s.", gpf_path, + strerror(gpf_read_errno)); + } } - /* If the user's preferences file exists but we failed to open 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 the main window. */ + /* If the user's 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 + the main window. */ if (pf_path != NULL) { + if (pf_open_errno != 0) { simple_dialog(ESD_TYPE_WARN, NULL, "Could not open your preferences file\n\"%s\": %s.", pf_path, strerror(pf_open_errno)); - g_free(pf_path); - pf_path = NULL; + } + if (pf_read_errno != 0) { + simple_dialog(ESD_TYPE_WARN, NULL, + "I/O error reading your preferences file\n\"%s\": %s.", pf_path, + strerror(pf_read_errno)); + } + g_free(pf_path); + pf_path = NULL; } /* If the user's capture filter file exists but we failed to open it, @@ -2255,6 +2284,24 @@ main(int argc, char *argv[]) g_free(df_path); } + /* If the user's disabled protocols 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 the main + window. */ + if (dp_path != NULL) { + if (dp_open_errno != 0) { + simple_dialog(ESD_TYPE_WARN, NULL, + "Could not open your disabled protocols file\n\"%s\": %s.", dp_path, + strerror(dp_open_errno)); + } + if (dp_read_errno != 0) { + simple_dialog(ESD_TYPE_WARN, NULL, + "I/O error reading your disabled protocols file\n\"%s\": %s.", dp_path, + strerror(dp_read_errno)); + } + g_free(dp_path); + } + #ifdef HAVE_LIBPCAP if (capture_child) { /* This is the child process for a sync mode or fork mode capture, @@ -2289,68 +2336,69 @@ main(int argc, char *argv[]) gtk_main(); - /* Try to save our geometry. GTK+ provides two routines to get a - window's position relative to the X root window. If I understand the - documentation correctly, gdk_window_get_deskrelative_origin applies - mainly to Enlightenment and gdk_window_get_root_origin applies for - all other WMs. + /* Try to save our geometry. GTK+ provides two routines to get a + window's position relative to the X root window. If I understand the + documentation correctly, gdk_window_get_deskrelative_origin applies + mainly to Enlightenment and gdk_window_get_root_origin applies for + all other WMs. - The code below tries both routines, and picks the one that returns - the upper-left-most coordinates. + The code below tries both routines, and picks the one that returns + the upper-left-most coordinates. - More info at: + More info at: - http://mail.gnome.org/archives/gtk-devel-list/2001-March/msg00289.html - http://www.gtk.org/faq/#AEN600 */ + http://mail.gnome.org/archives/gtk-devel-list/2001-March/msg00289.html + http://www.gtk.org/faq/#AEN600 */ - /* Re-read our saved preferences. */ - /* XXX - Move all of this into a separate function? */ - prefs = read_prefs(&gpf_open_errno, &gpf_path, &pf_open_errno, &pf_path); + /* Re-read our saved preferences. */ + /* XXX - Move all of this into a separate function? */ + prefs = read_prefs(&gpf_open_errno, &gpf_read_errno, &gpf_path, + &pf_open_errno, &pf_read_errno, &pf_path); - if (pf_path == NULL) { - if (prefs->gui_geometry_save_position) { - if (top_level->window != NULL) { - gdk_window_get_root_origin(top_level->window, &root_x, &root_y); - if (gdk_window_get_deskrelative_origin(top_level->window, - &desk_x, &desk_y)) { - if (desk_x <= root_x && desk_y <= root_y) { - root_x = desk_x; - root_y = desk_y; - } - } - } - if (prefs->gui_geometry_main_x != root_x) { - prefs->gui_geometry_main_x = root_x; - prefs_write_needed = TRUE; - } - if (prefs->gui_geometry_main_y != root_y) { - prefs->gui_geometry_main_y = root_y; - prefs_write_needed = TRUE; - } - } - - if (prefs->gui_geometry_save_size) { - if (top_level->window != NULL) { - /* XXX - Is this the "approved" method? */ - gdk_window_get_size(top_level->window, &top_width, &top_height); - } - if (prefs->gui_geometry_main_width != top_width) { - prefs->gui_geometry_main_width = top_width; - prefs_write_needed = TRUE; - } - if (prefs->gui_geometry_main_height != top_height) { - prefs->gui_geometry_main_height = top_height; - prefs_write_needed = TRUE; - } - } - - if (prefs_write_needed) { - write_prefs(&pf_path); - } - } else { - /* Ignore errors silently */ - g_free(pf_path); + if (pf_path == NULL) { + if (prefs->gui_geometry_save_position) { + if (top_level->window != NULL) { + gdk_window_get_root_origin(top_level->window, &root_x, &root_y); + if (gdk_window_get_deskrelative_origin(top_level->window, + &desk_x, &desk_y)) { + if (desk_x <= root_x && desk_y <= root_y) { + root_x = desk_x; + root_y = desk_y; + } } + } + if (prefs->gui_geometry_main_x != root_x) { + prefs->gui_geometry_main_x = root_x; + prefs_write_needed = TRUE; + } + if (prefs->gui_geometry_main_y != root_y) { + prefs->gui_geometry_main_y = root_y; + prefs_write_needed = TRUE; + } + } + + if (prefs->gui_geometry_save_size) { + if (top_level->window != NULL) { + /* XXX - Is this the "approved" method? */ + gdk_window_get_size(top_level->window, &top_width, &top_height); + } + if (prefs->gui_geometry_main_width != top_width) { + prefs->gui_geometry_main_width = top_width; + prefs_write_needed = TRUE; + } + if (prefs->gui_geometry_main_height != top_height) { + prefs->gui_geometry_main_height = top_height; + prefs_write_needed = TRUE; + } + } + + if (prefs_write_needed) { + write_prefs(&pf_path); + } + } else { + /* Ignore errors silently */ + g_free(pf_path); + } epan_cleanup(); g_free(rc_file); diff --git a/gtk/proto_dlg.c b/gtk/proto_dlg.c index c71e165310..1477bb0c2e 100644 --- a/gtk/proto_dlg.c +++ b/gtk/proto_dlg.c @@ -1,6 +1,6 @@ /* proto_dlg.c * - * $Id: proto_dlg.c,v 1.25 2003/01/26 19:35:31 deniel Exp $ + * $Id: proto_dlg.c,v 1.26 2003/08/07 00:41:28 guy Exp $ * * Laurent Deniel * @@ -38,11 +38,15 @@ #include "ui_util.h" #include "dlg_utils.h" #include "proto_dlg.h" +#include "simple_dialog.h" #include "compat_macros.h" +#include "disabled_protos.h" +#include static gboolean proto_delete_cb(GtkWidget *, gpointer); static void proto_ok_cb(GtkWidget *, gpointer); static void proto_apply_cb(GtkWidget *, gpointer); +static void proto_save_cb(GtkWidget *, gpointer); static void proto_cancel_cb(GtkWidget *, gpointer); static void proto_destroy_cb(GtkWidget *, gpointer); @@ -243,6 +247,16 @@ proto_cb(GtkWidget *w _U_, gpointer data _U_) gtk_box_pack_start(GTK_BOX (bbox), button, TRUE, TRUE, 0); gtk_widget_show(button); +#if GTK_MAJOR_VERSION < 2 + button = gtk_button_new_with_label ("Save"); +#else + button = gtk_button_new_from_stock(GTK_STOCK_SAVE); +#endif + SIGNAL_CONNECT(button, "clicked", proto_save_cb, proto_w); + GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT); + gtk_box_pack_start(GTK_BOX (bbox), button, TRUE, TRUE, 0); + gtk_widget_show(button); + #if GTK_MAJOR_VERSION < 2 button = gtk_button_new_with_label ("Cancel"); #else @@ -432,6 +446,42 @@ proto_apply_cb(GtkWidget *apply_bt _U_, gpointer parent_w) redissect_packets(&cfile); } +static void +proto_save_cb(GtkWidget *save_bt _U_, gpointer parent_w) +{ + gboolean must_redissect = FALSE; + char *pf_dir_path; + char *pf_path; + int pf_save_errno; + + /* Create the directory that holds personal configuration files, if + necessary. */ + if (create_persconffile_dir(&pf_dir_path) == -1) { + simple_dialog(ESD_TYPE_WARN, NULL, + "Can't create directory\n\"%s\"\nfor disabled protocols file: %s.", pf_dir_path, + strerror(errno)); + g_free(pf_dir_path); + } else { + /* + * make disabled/enabled protocol settings current + */ + must_redissect = set_proto_selection(GTK_WIDGET(parent_w)); + + save_disabled_protos_list(&pf_path, &pf_save_errno); + if (pf_path != NULL) { + simple_dialog(ESD_TYPE_WARN, NULL, + "Could not save to your disabled protocols file\n\"%s\": %s.", + pf_path, strerror(pf_save_errno)); + g_free(pf_path); + } + } + + if (must_redissect) { + /* Redissect all the packets, and re-evaluate the display filter. */ + redissect_packets(&cfile); + } +} + static void proto_cancel_cb(GtkWidget *cancel_bt _U_, gpointer parent_w) { diff --git a/prefs.c b/prefs.c index a93468b67c..b9b7edafd1 100644 --- a/prefs.c +++ b/prefs.c @@ -1,7 +1,7 @@ /* prefs.c * Routines for handling preferences * - * $Id: prefs.c,v 1.103 2003/08/04 17:32:46 guy Exp $ + * $Id: prefs.c,v 1.104 2003/08/07 00:41:26 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs @@ -847,7 +847,7 @@ print.file: /a/very/long/path/ #define DEF_NUM_COLS 6 -static void read_prefs_file(const char *pf_path, FILE *pf); +static int read_prefs_file(const char *pf_path, FILE *pf); /* Read the preferences file, fill in "prefs", and return a pointer to it. @@ -861,10 +861,12 @@ static void read_prefs_file(const char *pf_path, FILE *pf); and a pointer to the path of the file into "*pf_path_return", and return NULL. */ e_prefs * -read_prefs(int *gpf_errno_return, char **gpf_path_return, - int *pf_errno_return, char **pf_path_return) +read_prefs(int *gpf_errno_return, int *gpf_read_errno_return, + char **gpf_path_return, int *pf_errno_return, + int *pf_read_errno_return, char **pf_path_return) { int i; + int err; char *pf_path; FILE *pf; fmt_data *cfmt; @@ -994,7 +996,14 @@ read_prefs(int *gpf_errno_return, char **gpf_path_return, *gpf_path_return = NULL; if ((pf = fopen(gpf_path, "r")) != NULL) { /* We succeeded in opening it; read it. */ - read_prefs_file(gpf_path, pf); + err = read_prefs_file(gpf_path, pf); + if (err != 0) { + /* We had an error reading the file; return the errno and the + pathname, so our caller can report the error. */ + *gpf_errno_return = 0; + *gpf_read_errno_return = err; + *gpf_path_return = gpf_path; + } fclose(pf); } else { /* We failed to open it. If we failed for some reason other than @@ -1002,6 +1011,7 @@ read_prefs(int *gpf_errno_return, char **gpf_path_return, caller can report the error. */ if (errno != ENOENT) { *gpf_errno_return = errno; + *gpf_read_errno_return = 0; *gpf_path_return = gpf_path; } } @@ -1013,16 +1023,23 @@ read_prefs(int *gpf_errno_return, char **gpf_path_return, *pf_path_return = NULL; if ((pf = fopen(pf_path, "r")) != NULL) { /* We succeeded in opening it; read it. */ - read_prefs_file(pf_path, pf); + err = read_prefs_file(pf_path, pf); + if (err != 0) { + /* We had an error reading the file; return the errno and the + pathname, so our caller can report the error. */ + *pf_errno_return = 0; + *pf_read_errno_return = err; + *pf_path_return = pf_path; + } else + g_free(pf_path); fclose(pf); - g_free(pf_path); - pf_path = NULL; } else { /* We failed to open it. If we failed for some reason other than "it doesn't exist", return the errno and the pathname, so our caller can report the error. */ if (errno != ENOENT) { *pf_errno_return = errno; + *pf_read_errno_return = 0; *pf_path_return = pf_path; } } @@ -1030,7 +1047,7 @@ read_prefs(int *gpf_errno_return, char **gpf_path_return, return &prefs; } -static void +static int read_prefs_file(const char *pf_path, FILE *pf) { enum { START, IN_VAR, PRE_VAL, IN_VAL, IN_SKIP }; @@ -1161,6 +1178,10 @@ read_prefs_file(const char *pf_path, FILE *pf) g_warning ("%s line %d: Incomplete preference", pf_path, pline); } } + if (ferror(pf)) + return errno; + else + return 0; } /* diff --git a/prefs.h b/prefs.h index cbb1cbb64f..0902fde1df 100644 --- a/prefs.h +++ b/prefs.h @@ -1,7 +1,7 @@ /* prefs.h * Definitions for preference handling routines * - * $Id: prefs.h,v 1.43 2003/07/22 03:14:28 gerald Exp $ + * $Id: prefs.h,v 1.44 2003/08/07 00:41:26 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs @@ -226,14 +226,16 @@ extern void prefs_register_modules(void); If we got an error (other than "it doesn't exist") trying to read the global preferences file, stuff the errno into "*gpf_errno_return" - and a pointer to the path of the file into "*gpf_path_return", and + on an open error and into "*gpf_read_errno_return" on a read error, + stuff a pointer to the path of the file into "*gpf_path_return", and return NULL. If we got an error (other than "it doesn't exist") trying to read the user's preferences file, stuff the errno into "*pf_errno_return" - and a pointer to the path of the file into "*pf_path_return", and + on an open error and into "*pf_read_errno_return" on a read error, + stuff a pointer to the path of the file into "*pf_path_return", and return NULL. */ -extern e_prefs *read_prefs(int *, char **, int *, char **); +extern e_prefs *read_prefs(int *, int *, char **, int *, int *, char **); /* Write out "prefs" to the user's preferences file, and return 0. diff --git a/tethereal.c b/tethereal.c index 0c200a76a7..c6dfa7a4e0 100644 --- a/tethereal.c +++ b/tethereal.c @@ -1,6 +1,6 @@ /* tethereal.c * - * $Id: tethereal.c,v 1.190 2003/07/25 04:11:50 gram Exp $ + * $Id: tethereal.c,v 1.191 2003/08/07 00:41:27 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs @@ -76,6 +76,7 @@ #include #include #include "file.h" +#include "disabled_protos.h" #include "prefs.h" #include "column.h" #include "print.h" @@ -748,9 +749,11 @@ main(int argc, char *argv[]) WSADATA wsaData; #endif /* _WIN32 */ - char *gpf_path; - char *pf_path; - int gpf_open_errno, pf_open_errno; + char *gpf_path, *pf_path; + char *dp_path; + int gpf_open_errno, gpf_read_errno; + int pf_open_errno, pf_read_errno; + int dp_open_errno, dp_read_errno; int err; #ifdef HAVE_LIBPCAP gboolean capture_filter_specified = FALSE; @@ -810,14 +813,27 @@ main(int argc, char *argv[]) /* Set the C-language locale to the native environment. */ setlocale(LC_ALL, ""); - prefs = read_prefs(&gpf_open_errno, &gpf_path, &pf_open_errno, &pf_path); + prefs = read_prefs(&gpf_open_errno, &gpf_read_errno, &gpf_path, + &pf_open_errno, &pf_read_errno, &pf_path); if (gpf_path != NULL) { - fprintf(stderr, "Can't open global preferences file \"%s\": %s.\n", pf_path, - strerror(gpf_open_errno)); + if (gpf_open_errno != 0) { + fprintf(stderr, "Can't open global preferences file \"%s\": %s.\n", + pf_path, strerror(gpf_open_errno)); + } + if (gpf_read_errno != 0) { + fprintf(stderr, "I/O error reading global preferences file \"%s\": %s.\n", + pf_path, strerror(gpf_read_errno)); + } } if (pf_path != NULL) { - fprintf(stderr, "Can't open your preferences file \"%s\": %s.\n", pf_path, - strerror(pf_open_errno)); + if (pf_open_errno != 0) { + fprintf(stderr, "Can't open your preferences file \"%s\": %s.\n", pf_path, + strerror(pf_open_errno)); + } + if (pf_read_errno != 0) { + fprintf(stderr, "I/O error reading your preferences file \"%s\": %s.\n", + pf_path, strerror(pf_read_errno)); + } g_free(pf_path); pf_path = NULL; } @@ -825,6 +841,22 @@ main(int argc, char *argv[]) /* Set the name resolution code's flags from the preferences. */ g_resolv_flags = prefs->name_resolve; + /* Read the disabled protocols file. */ + read_disabled_protos_list(&dp_path, &dp_open_errno, &dp_read_errno); + if (dp_path != NULL) { + if (dp_open_errno != 0) { + fprintf(stderr, + "Could not open your disabled protocols file\n\"%s\": %s.\n", dp_path, + strerror(dp_open_errno)); + } + if (dp_read_errno != 0) { + fprintf(stderr, + "I/O error reading your disabled protocols file\n\"%s\": %s.\n", dp_path, + strerror(dp_read_errno)); + } + g_free(dp_path); + } + #ifdef _WIN32 /* Load Wpcap, if possible */ load_wpcap(); @@ -1175,6 +1207,11 @@ main(int argc, char *argv[]) line that their preferences have changed. */ prefs_apply_all(); + /* disabled protocols as per configuration file */ + if (dp_path == NULL) { + set_disabled_protos_list(); + } + #ifndef HAVE_LIBPCAP if (capture_option_specified) fprintf(stderr, "This version of Tethereal was not built with support for capturing packets.\n");