Ethereal-dev: [Ethereal-dev] Check-in Request - colorfilters enhancement

Note: This archive is from the project's previous web site, ethereal.com. This list is no longer active.

From: Richard Urwin <richard@xxxxxxxxxxxxxxx>
Date: Sun, 11 May 2003 02:40:20 +0100
Here is the first phase of the enhancement of color filters:

If no colorfilters file is found in the user's personal configuration, 
Ethereal will try to read the system-wide colorfilters file from the 
DATADIRectory, (eg /usr/local/share/ethereal.)

Editing the color filters will result in the display of the system-wide 
default filters, which will then be saved to the user's file when the SAVE 
button is pressed. So the user can add filters to the default set, or remove 
filters from it.

A REVERT button is provided to delete the user's file. The colouration then 
reverts to the system-wide defaults.

The system-wide colorfilters file must be copied to the Data Directory by 
hand.

Also fixed:
  gtk/color_filters.c:read_filters did not close the file handle.

Not fixed:
  The CANCEL button should probably be labeled CLOSE, as it does not undo any 
changes that have been made.

This patch has been built and tested on Linux (MDK9.1) GTK 1
It has not been built or tested on:
a) Windows
b) GTK2

With these provisos, please check in the enclosed patch.

I also enclose a colorfilters file suitable for use as a system-wide defaults 
file.

Phase 2 will add the ability to export some or all filters to the system-wide 
defaults file, or any other file, and to import from any file.

-- 
Richard Urwin
diff -Bur --ignore-matching-lines=: --exclude='*.o' --exclude='*.dtd' --exclude='*.xml' --exclude=configure --exclude='ascend-grammar.[ch]' --exclude='ascend-scanner.[ch]' ethereal-0.9.12/epan/filesystem.c ethereal/epan/filesystem.c
--- ethereal-0.9.12/epan/filesystem.c	2003-03-29 23:26:49.000000000 +0000
+++ ethereal/epan/filesystem.c	2003-05-09 00:00:08.000000000 +0100
@@ -601,3 +601,28 @@
 
 	return path;
 }
+
+/*
+ * Construct the path name of a global configuration file, given the
+ * file name.
+ *
+ */
+char *
+get_datafile_path(const char *filename)
+{
+	char *path;
+
+	path = (gchar *) g_malloc(strlen(get_datafile_dir()) +
+	    strlen(filename) + 2);
+	sprintf(path, "%s" G_DIR_SEPARATOR_S "%s", get_datafile_dir(),
+	    filename);
+
+	return path;
+}
+
+/* Delete a file */
+gboolean
+deletefile (const char *path)
+{
+	return unlink(path) == 0;
+}
diff -Bur --ignore-matching-lines=: --exclude='*.o' --exclude='*.dtd' --exclude='*.xml' --exclude=configure --exclude='ascend-grammar.[ch]' --exclude='ascend-scanner.[ch]' ethereal-0.9.12/epan/filesystem.h ethereal/epan/filesystem.h
--- ethereal-0.9.12/epan/filesystem.h	2002-08-29 01:40:07.000000000 +0100
+++ ethereal/epan/filesystem.h	2003-05-11 01:20:15.000000000 +0100
@@ -77,6 +77,12 @@
 const char *get_datafile_dir(void);
 
 /*
+ * Construct the path name of a global configuration file, given the
+ * file name.
+*/
+char *get_datafile_path(const char *filename);
+
+/*
  * Get the directory in which files that, at least on UNIX, are
  * system files (such as "/etc/ethers") are stored; on Windows,
  * there's no "/etc" directory, so we get them from the Ethereal
@@ -105,4 +111,6 @@
  */
 char *get_persconffile_path(const char *filename, gboolean for_writing);
 
+/* Delete a file */
+gboolean deletefile (const char *path);
 #endif /* FILESYSTEM_H */
diff -Bur --ignore-matching-lines=: --exclude='*.o' --exclude='*.dtd' --exclude='*.xml' --exclude=configure --exclude='ascend-grammar.[ch]' --exclude='ascend-scanner.[ch]' ethereal-0.9.12/gtk/color_dlg.c ethereal/gtk/color_dlg.c
--- ethereal-0.9.12/gtk/color_dlg.c	2003-02-20 03:15:46.000000000 +0000
+++ ethereal/gtk/color_dlg.c	2003-05-11 01:54:44.000000000 +0100
@@ -66,6 +66,8 @@
 static void color_ok_cb(GtkButton *button, gpointer user_data);
 static void color_cancel_cb(GtkWidget *widget, gpointer user_data);
 static void color_apply_cb(GtkButton *button, gpointer user_data);
+static void color_revert_cb(GtkWidget *button, gpointer user_data);
+
 
 static void edit_color_filter_dialog_new(GtkWidget *color_filters,
                                          GtkWidget **colorize_filter_name,
@@ -152,6 +154,7 @@
   GtkWidget *color_ok;
   GtkWidget *color_apply;
   GtkWidget *color_save;
+  GtkWidget *color_revert;
   GtkWidget *color_cancel;
 
 #if GTK_MAJOR_VERSION >= 2
@@ -385,6 +388,17 @@
   gtk_tooltips_set_tip(tooltips, color_save, ("Save all filters to disk"), NULL);
 
 #if GTK_MAJOR_VERSION < 2
+  color_revert = gtk_button_new_with_label (("Revert"));
+#else
+  color_revert = gtk_button_new_from_stock(GTK_STOCK_REVERT_TO_SAVED);
+#endif
+  gtk_widget_ref(color_revert);
+  OBJECT_SET_DATA_FULL(color_win, "color_revert", color_revert, gtk_widget_unref);
+  gtk_widget_show(color_revert);
+  gtk_box_pack_start(GTK_BOX (button_ok_hbox), color_revert, FALSE, FALSE, 5);
+  gtk_tooltips_set_tip(tooltips, color_revert, ("Delete filter file and revert to system-wide default filter set"), NULL);
+
+#if GTK_MAJOR_VERSION < 2
   color_cancel = gtk_button_new_with_label (("Cancel"));
 #else
   color_cancel = gtk_button_new_from_stock(GTK_STOCK_CANCEL);
@@ -419,6 +433,8 @@
   OBJECT_SET_DATA(color_delete, COLOR_FILTERS_CL, color_filters);
   SIGNAL_CONNECT(color_delete, "clicked", color_delete_cb, NULL);
   SIGNAL_CONNECT(color_save, "clicked", color_save_cb, NULL);
+  SIGNAL_CONNECT(color_revert, "clicked", color_revert_cb, NULL);
+  OBJECT_SET_DATA(color_revert, COLOR_FILTERS_CL, color_filters);
   SIGNAL_CONNECT(color_ok, "clicked", color_ok_cb, NULL);
   SIGNAL_CONNECT(color_apply, "clicked", color_apply_cb, NULL);
   SIGNAL_CONNECT(color_cancel, "clicked", color_cancel_cb, NULL);
@@ -770,77 +786,83 @@
 
 /* Delete a color from the list. */
 static void
-color_delete_cb(GtkWidget *widget, gpointer user_data _U_)
+color_delete(gint row, GtkWidget  *color_filters)
 {
-    GtkWidget        *color_filters;
-    color_filter_t   *colorf;
+    color_filter_t *colorf;
+    
 #if GTK_MAJOR_VERSION >= 2
     GtkTreeModel     *model;
     GtkTreeIter       iter;
-    gint              row;
+    gint              rowsel;
     GtkTreeSelection *sel;
 
-    if(row_selected != -1) {
-        /* The "selection changed" callback is called when the row is
-         * removed, so we must remember the selected row. */
-        row = row_selected;
-        color_filters = (GtkWidget *)OBJECT_GET_DATA(widget, COLOR_FILTERS_CL);
-        model = gtk_tree_view_get_model(GTK_TREE_VIEW(color_filters));
-        gtk_tree_model_iter_nth_child(model, &iter, NULL, row);
-        gtk_tree_model_get(model, &iter, 4, &colorf, -1);
-
-        /* Remove this color filter from the CList displaying the
-           color filters. */
-        gtk_list_store_remove(GTK_LIST_STORE(model), &iter);
-        num_of_filters--;
-
-        /* Destroy any "Edit color filter" dialog boxes editing it. */
-        if (colorf->edit_dialog != NULL)
-            gtk_widget_destroy(colorf->edit_dialog);
-
-        /* Remove the color filter from the list of color filters. */
-        delete_color_filter(colorf);
-
-        /* If we grab the focus after updating the selection, the first
-         * row is always selected, so we do it before */
-        gtk_widget_grab_focus(color_filters);
-        /* Update the selection */
-        if (row <= (num_of_filters-1)) {
-            sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(color_filters));
-            gtk_tree_model_iter_nth_child(model, &iter, NULL, row);
-            gtk_tree_selection_select_iter(sel, &iter);
-        }
-        else if (num_of_filters > 0) {
-            sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(color_filters));
-            gtk_tree_model_iter_nth_child(model, &iter, NULL, num_of_filters-1);
-            gtk_tree_selection_select_iter(sel, &iter);
-        }
+    
+    /* The "selection changed" callback is called when the row is
+    * removed, so we must remember the selected row. */
+   model = gtk_tree_view_get_model(GTK_TREE_VIEW(color_filters));
+    gtk_tree_model_iter_nth_child(model, &iter, NULL, row);
+    gtk_tree_model_get(model, &iter, 4, &colorf, -1);
+    
+    /* Remove this color filter from the CList displaying the
+    color filters. */
+    gtk_list_store_remove(GTK_LIST_STORE(model), &iter);
+    num_of_filters--;
+    
+    /* Destroy any "Edit color filter" dialog boxes editing it. */
+    if (colorf->edit_dialog != NULL)
+    gtk_widget_destroy(colorf->edit_dialog);
+    
+    /* Remove the color filter from the list of color filters. */
+    delete_color_filter(colorf);
+    
+    /* If we grab the focus after updating the selection, the first
+    * row is always selected, so we do it before */
+    gtk_widget_grab_focus(color_filters);
+    /* Update the selection */
+    if (row_selected <= (num_of_filters-1)) {
+        sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(color_filters));
+        gtk_tree_model_iter_nth_child(model, &iter, NULL, row_selected);
+        gtk_tree_selection_select_iter(sel, &iter);
+    }
+    else if (num_of_filters > 0) {
+        sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(color_filters));
+        gtk_tree_model_iter_nth_child(model, &iter, NULL, num_of_filters-1);
+        gtk_tree_selection_select_iter(sel, &iter);
     }
 #else
-    if(row_selected != -1){
-        color_filters = (GtkWidget *)OBJECT_GET_DATA(widget, COLOR_FILTERS_CL);
-        colorf = gtk_clist_get_row_data(GTK_CLIST(color_filters), row_selected);
+   colorf = gtk_clist_get_row_data(GTK_CLIST(color_filters), row);
 
-        /* Remove this color filter from the CList displaying the
-           color filters. */
-        gtk_clist_remove(GTK_CLIST(color_filters), row_selected);
-        num_of_filters--;
-
-        /* Destroy any "Edit color filter" dialog boxes editing it. */
-        if (colorf->edit_dialog != NULL)
-            gtk_widget_destroy(colorf->edit_dialog);
-
-        /* Remove the color filter from the list of color filters. */
-        delete_color_filter(colorf);
-
-        /* Select the previous row, if there is one. */
-        if (row_selected > 0) {
-            row_selected--;
-            gtk_clist_select_row(GTK_CLIST(color_filters), row_selected, 0);
-        }
+    /* Remove this color filter from the CList displaying the
+       color filters. */
+    gtk_clist_remove(GTK_CLIST(color_filters), row);
+    num_of_filters--;
+
+    /* Destroy any "Edit color filter" dialog boxes editing it. */
+    if (colorf->edit_dialog != NULL)
+        gtk_widget_destroy(colorf->edit_dialog);
+
+    /* Remove the color filter from the list of color filters. */
+    delete_color_filter(colorf);
+
+    /* Select the previous row, if there is one. */
+    if (row <= row_selected && row_selected > 0) {
+        row_selected--;
+        gtk_clist_select_row(GTK_CLIST(color_filters), row_selected, 0);
     }
 #endif
 }
+/* Delete the selected color from the list.*/
+static void
+color_delete_cb(GtkWidget *widget, gpointer user_data _U_)
+{
+    GtkWidget  *color_filters;
+    
+    if(row_selected != -1)
+    {
+        color_filters = (GtkWidget *)OBJECT_GET_DATA(widget, COLOR_FILTERS_CL);
+        color_delete (row_selected, color_filters);
+    }
+}
 
 /* Save color filters to the color filter file. */
 static void
@@ -852,6 +874,31 @@
 
 }
 
+/* Remove all user defined color filters and revert to the global file. */
+static void
+color_revert_cb(GtkWidget *widget, gpointer user_data _U_)
+{
+    GtkWidget * color_filters;
+    
+    color_filters = (GtkWidget *)OBJECT_GET_DATA(widget, COLOR_FILTERS_CL);
+    
+    while (num_of_filters > 0)
+    {
+        color_delete (num_of_filters-1, color_filters);
+    }
+
+    if (!revert_filters())
+        simple_dialog(ESD_TYPE_CRIT, NULL, "Could not delete filter file: %s",
+            strerror(errno));
+
+    /* colorize list */
+    colorize_packets(&cfile);
+
+    /* Destroy the dialog box. */
+    gtk_widget_destroy(colorize_win);
+
+}
+
 /* Exit dialog and apply new list of color filters to the capture. */
 static void
 color_ok_cb(GtkButton *button _U_, gpointer user_data _U_)
diff -Bur --ignore-matching-lines=: --exclude='*.o' --exclude='*.dtd' --exclude='*.xml' --exclude=configure --exclude='ascend-grammar.[ch]' --exclude='ascend-scanner.[ch]' ethereal-0.9.12/gtk/color_filters.c ethereal/gtk/color_filters.c
--- ethereal-0.9.12/gtk/color_filters.c	2003-01-08 01:59:42.000000000 +0000
+++ ethereal/gtk/color_filters.c	2003-05-11 02:12:17.000000000 +0100
@@ -45,14 +45,48 @@
 #include "gtkglobals.h"
 
 static gboolean read_filters(void);
+static gboolean read_global_filters(void);
 
 GSList *filter_list;
 
-/* Initialize the filter structures (reading from file) */
+/* delete the specified filter */
+void
+delete_color_filter(color_filter_t *colorf)
+{
+	if (colorf->filter_name != NULL)
+		g_free(colorf->filter_name);
+	if (colorf->filter_text != NULL)
+		g_free(colorf->filter_text);
+	if (colorf->c_colorfilter != NULL)
+		dfilter_free(colorf->c_colorfilter);
+	filter_list = g_slist_remove(filter_list, colorf);
+	g_free(colorf);
+}
+
+/* delete the specified filter as an iterator*/
+static void
+delete_color_filter_it(gpointer filter_arg, gpointer ignored _U_)
+{
+	color_filter_t *colorf = filter_arg;
+	
+	delete_color_filter(colorf);
+}
+
+/* delete all the filters */
+
+static void
+delete_all_color_filters (void)
+{
+        g_slist_foreach(filter_list, delete_color_filter_it, NULL);
+}
+
+/* Initialize the filter structures (reading from file) for general running, including app startup */
 void
 colfilter_init(void)
 {
-	read_filters();
+	delete_all_color_filters();
+	if (!read_filters())
+		read_global_filters();
 }
 
 /* Create a new filter */
@@ -75,19 +109,6 @@
         return colorf;
 }
 
-/* delete the specified filter */
-void
-delete_color_filter(color_filter_t *colorf)
-{
-	if (colorf->filter_name != NULL)
-		g_free(colorf->filter_name);
-	if (colorf->filter_text != NULL)
-		g_free(colorf->filter_text);
-	if (colorf->c_colorfilter != NULL)
-		dfilter_free(colorf->c_colorfilter);
-	filter_list = g_slist_remove(filter_list, colorf);
-	g_free(colorf);
-}
 
 static void
 prime_edt(gpointer data, gpointer user_data)
@@ -108,9 +129,9 @@
 }
 
 
-/* read filters from the file */
+/* read filters from the given file */
 static gboolean
-read_filters(void)
+read_filters_file(gpointer file_arg)
 {
 	/* TODO: Lots more syntax checking on the file */
 	/* I hate these fixed length names! TODO: make more dynamic */
@@ -121,23 +142,8 @@
 	guint16 fg_r, fg_g, fg_b, bg_r, bg_g, bg_b;
 	GdkColor fg_color, bg_color;
 	color_filter_t *colorf;
-	gchar *path;
-	FILE *f;
 	dfilter_t *temp_dfilter;
-
-	/* decide what file to open (from dfilter code) */
-	path = get_persconffile_path("colorfilters", FALSE);
-	if ((f = fopen(path, "r")) == NULL) {
-		if (errno != ENOENT) {
-			simple_dialog(ESD_TYPE_CRIT, NULL,
-			    "Could not open filter file\n\"%s\": %s.", path,
-			    strerror(errno));
-		}
-		g_free((gchar *)path);
-		return FALSE;
-	}
-	g_free((gchar *)path);
-	path = NULL;
+	FILE *f = file_arg;
 
 	do {
 		if (fgets(buf,sizeof buf, f) == NULL)
@@ -193,8 +199,61 @@
 			gdkcolor_to_color_t(&colorf->fg_color, &fg_color);
 		}    /* if sscanf */
 	} while(!feof(f));
+	fclose(f);
 	return TRUE;
 }
+/* read filters from the user's filter file */
+static gboolean
+read_filters(void)
+{
+	/* TODO: Lots more syntax checking on the file */
+	/* I hate these fixed length names! TODO: make more dynamic */
+	/* XXX - buffer overflow possibility here
+	 * sscanf blocks max size of name and filter_exp; buf is used for
+	 * reading only */
+	gchar *path;
+	FILE *f;
+
+	/* decide what file to open (from dfilter code) */
+	path = get_persconffile_path("colorfilters", FALSE);
+	if ((f = fopen(path, "r")) == NULL) {
+		if (errno != ENOENT) {
+			simple_dialog(ESD_TYPE_CRIT, NULL,
+			    "Could not open filter file\n\"%s\": %s.", path,
+			    strerror(errno));
+		}
+		g_free((gchar *)path);
+		return FALSE;
+	}
+	g_free((gchar *)path);
+	path = NULL;
+
+	return read_filters_file(f);
+}
+
+/* read filters from the filter file */
+static gboolean
+read_global_filters(void)
+{
+	gchar *path;
+	FILE *f;
+
+	/* decide what file to open (from dfilter code) */
+	path = get_datafile_path("colorfilters");
+	if ((f = fopen(path, "r")) == NULL) {
+		if (errno != ENOENT) {
+			simple_dialog(ESD_TYPE_CRIT, NULL,
+			    "Could not open global filter file\n\"%s\": %s.", path,
+			    strerror(errno));
+		}
+		g_free((gchar *)path);
+		return FALSE;
+	}
+	g_free((gchar *)path);
+	path = NULL;
+
+	return read_filters_file(f);
+}
 
 static void
 write_filter(gpointer filter_arg, gpointer file_arg)
@@ -213,7 +272,17 @@
 	    colorf->fg_color.blue);
 }
 
-/* save filters in filter file */
+/* save filters in a filter file */
+gboolean
+write_filters_file(FILE *f)
+{
+	fprintf(f,"# DO NOT EDIT THIS FILE!  It was created by Ethereal\n");
+        g_slist_foreach(filter_list, write_filter, f);
+	return TRUE;
+}
+
+/* save filters in users filter file */
+
 gboolean
 write_filters(void)
 {
@@ -238,8 +307,53 @@
 		    path, strerror(errno));
 		return FALSE;
 	}
-        fprintf(f,"# DO NOT EDIT THIS FILE!  It was created by Ethereal\n");
-        g_slist_foreach(filter_list, write_filter, f);
+	write_filters_file(f);
+	fclose(f);
+	return TRUE;
+}
+
+/* delete users filter file and reload global filters*/
+
+gboolean
+revert_filters(void)
+{
+	gchar *pf_dir_path;
+	const gchar *path;
+
+	/* 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 color files: %s.",
+		    pf_dir_path, strerror(errno));
+		g_free(pf_dir_path);
+		return FALSE;
+	}
+
+	path = get_persconffile_path("colorfilters", TRUE);
+	if (!deletefile(path))
+		return FALSE;
+
+	/* Reload the (global) filters - Note: this does not update the dialog. */
+	colfilter_init();
+        return TRUE;
+}
+
+
+/* save filters in some other filter file */
+
+gboolean
+write_other_filters(gchar *path)
+{
+	FILE *f;
+
+	if ((f = fopen(path, "w+")) == NULL) {
+		simple_dialog(ESD_TYPE_CRIT, NULL,
+		    "Could not open\n%s\nfor writing: %s.",
+		    path, strerror(errno));
+		return FALSE;
+	}
+	write_filters_file(f);
 	fclose(f);
 	return TRUE;
 }
diff -Bur --ignore-matching-lines=: --exclude='*.o' --exclude='*.dtd' --exclude='*.xml' --exclude=configure --exclude='ascend-grammar.[ch]' --exclude='ascend-scanner.[ch]' ethereal-0.9.12/gtk/color_filters.h ethereal/gtk/color_filters.h
--- ethereal-0.9.12/gtk/color_filters.h	2003-01-08 01:59:42.000000000 +0000
+++ ethereal/gtk/color_filters.h	2003-05-08 23:14:41.000000000 +0100
@@ -34,8 +34,9 @@
 void colfilter_init(void);
 
 gboolean write_filters(void);
+gboolean revert_filters(void);
 
 color_filter_t *new_color_filter(gchar *name, gchar *filter_string);
 void delete_color_filter(color_filter_t *colorf);
-
+gboolean write_other_filters(gchar *path);
 #endif
Sun May 11 02:22:30 BST 2003 Comparison between ethereal-0.9.12 and ethereal
Changes to:
ethereal/epan/filesystem.c
ethereal/epan/filesystem.h
ethereal/gtk/color_dlg.c
ethereal/gtk/color_filters.c
ethereal/gtk/color_filters.h
New Files:
NONE
See 'colorfilters.patch' for details
# DO NOT EDIT THIS FILE!  It was created by Ethereal
@Bad TCP@tcp.checksum_bad@[58981,65534,65534][65535,0,0]
@Bad UDP Broadcast@udp.checksum_bad and eth.dst == FF:FF:FF:FF:FF:FF@[39321,65534,52428][65535,0,0]
@Bad UDP@udp.checksum_bad@[58980,65533,62258][64045,1611,7179]
@TCP Broadcast@ eth.dst == FF:FF:FF:FF:FF:FF and tcp@[39320,65534,65534][0,0,0]
@UDP Broadcast@xxxxxxx == FF:FF:FF:FF:FF:FF and udp@[39320,65534,52428][0,0,0]
@ARP@arp@[64045,64045,64045][0,45874,12997]
@SSL@ssl@[65535,58981,58981][0,0,0]
@HTTP@http@[58979,65533,65533][2368,28135,41703]
@FTP@ftp@[58980,65534,65534][8072,0,41939]
@Netbios session service@ nbss@[58980,65534,65534][46171,46171,4617]
@DCERPC TCP@dcerpc and tcp@[58980,65534,65534][45874,45874,4587]
@TCP@tcp@[58981,65535,65535][0,0,0]
@DNS@dns@[58979,65533,62256][0,45874,12997]
@Netbios Name Service@nbns@[58979,65533,62256][0,45874,12997]
@UDP@udp@[58976,65530,62258][0,0,0]
@netbios@netbios@[63895,65533,58979][45874,45874,4587]
@LLC@llc@[63895,65534,58980][45874,45874,4587]