aboutsummaryrefslogtreecommitdiffstats
path: root/epan
diff options
context:
space:
mode:
authorMichael Mann <mmann78@netscape.net>2015-12-22 15:07:00 -0500
committerMichael Mann <mmann78@netscape.net>2015-12-28 18:33:41 +0000
commit5e4bbcda9839d9fd4480db8c4f9386ff388d166c (patch)
tree9801cea61222e0e9e3f8c57f4574ddb6bab075c7 /epan
parentc752daf4b8816d809a92894155ce8de1b24613c7 (diff)
Refactor GUI dependencies out of color_filters.[ch] and move it to epan directory.
This also moved color.h into color_filters.h Change-Id: Ic19e27aa1b3ec67e764aa7ee8bbef7b1187bb12e Reviewed-on: https://code.wireshark.org/review/12831 Petri-Dish: Michael Mann <mmann78@netscape.net> Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: Michael Mann <mmann78@netscape.net>
Diffstat (limited to 'epan')
-rw-r--r--epan/CMakeLists.txt3
-rw-r--r--epan/Makefile.am2
-rw-r--r--epan/Makefile.common2
-rw-r--r--epan/color_filters.c843
-rw-r--r--epan/color_filters.h235
-rw-r--r--epan/dissectors/file-file.c3
-rw-r--r--epan/dissectors/packet-frame.c3
-rw-r--r--epan/prefs.h2
8 files changed, 1086 insertions, 7 deletions
diff --git a/epan/CMakeLists.txt b/epan/CMakeLists.txt
index 43ea761d66..fa0676286e 100644
--- a/epan/CMakeLists.txt
+++ b/epan/CMakeLists.txt
@@ -1592,6 +1592,7 @@ set(LIBWIRESHARK_FILES
capture_dissectors.c
charsets.c
circuit.c
+ color_filters.c
column.c
column-utils.c
conversation.c
@@ -1764,7 +1765,7 @@ endif()
ABICHECK(libwireshark)
-set(TOP_LEVEL_HEADERS ${CMAKE_BINARY_DIR}/config.h ${CMAKE_SOURCE_DIR}/color.h ${CMAKE_SOURCE_DIR}/register.h)
+set(TOP_LEVEL_HEADERS ${CMAKE_BINARY_DIR}/config.h ${CMAKE_SOURCE_DIR}/register.h)
file(GLOB CRYPT_HEADERS crypt/*.h)
file(GLOB COMPRESS_HEADERS compress/*.h)
file(GLOB DFILTER_HEADERS dfilter/*.h ../tools/lemon/cppmagic.h)
diff --git a/epan/Makefile.am b/epan/Makefile.am
index 2383af0433..0749d60a99 100644
--- a/epan/Makefile.am
+++ b/epan/Makefile.am
@@ -300,7 +300,7 @@ endif
dumpabi-libwireshark: all abi-descriptor.xml
rm -rf abi-check-headers abi_dumps .libs/*.abi.tar.gz
mkdir abi-check-headers
- cp ../color.h ../config.h ../register.h abi-check-headers/
+ cp ../config.h ../register.h abi-check-headers/
mkdir abi-check-headers/epan
cp *.h abi-check-headers/epan
mkdir abi-check-headers/crypt
diff --git a/epan/Makefile.common b/epan/Makefile.common
index bc57f50b42..d11786e993 100644
--- a/epan/Makefile.common
+++ b/epan/Makefile.common
@@ -32,6 +32,7 @@ LIBWIRESHARK_SRC = \
capture_dissectors.c \
charsets.c \
circuit.c \
+ color_filters.c \
column.c \
column-utils.c \
conversation.c \
@@ -161,6 +162,7 @@ LIBWIRESHARK_INCLUDES = \
charsets.h \
chdlctypes.h \
circuit.h \
+ color_filters.h \
column.h \
column-info.h \
column-utils.h \
diff --git a/epan/color_filters.c b/epan/color_filters.c
new file mode 100644
index 0000000000..cc95a08a31
--- /dev/null
+++ b/epan/color_filters.c
@@ -0,0 +1,843 @@
+/* color_filters.c
+ * Routines for color filters
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+/*
+ * Updated 1 Dec 10 jjm
+ */
+
+#include <config.h>
+
+#include <glib.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <wsutil/filesystem.h>
+#include <wsutil/file_util.h>
+
+#include <epan/packet.h>
+#include "color_filters.h"
+#include "file.h"
+#include <epan/dfilter/dfilter.h>
+#include <epan/prefs.h>
+
+
+#define RED_COMPONENT(x) (guint16) (((((x) >> 16) & 0xff) * 65535 / 255))
+#define GREEN_COMPONENT(x) (guint16) (((((x) >> 8) & 0xff) * 65535 / 255))
+#define BLUE_COMPONENT(x) (guint16) ( (((x) & 0xff) * 65535 / 255))
+
+static gboolean read_users_filters(GSList **cfl, gchar** err_msg, initialize_color_func init_func, color_filter_add_cb_func add_cb);
+
+/* the currently active filters */
+static GSList *color_filter_list = NULL;
+
+/* keep "old" deleted filters in this list until
+ * the dissection no longer needs them (e.g. file is closed) */
+static GSList *color_filter_deleted_list = NULL;
+static GSList *color_filter_valid_list = NULL;
+
+/* Color Filters can en-/disabled. */
+static gboolean filters_enabled = TRUE;
+
+/* Remember if there are temporary coloring filters set to
+ * add sensitivity to the "Reset Coloring 1-10" menu item
+ */
+static gboolean tmp_colors_set = FALSE;
+
+/* Create a new filter */
+color_filter_t *
+color_filter_new(const gchar *name, /* The name of the filter to create */
+ const gchar *filter_string, /* The string representing the filter */
+ color_t *bg_color, /* The background color */
+ color_t *fg_color, /* The foreground color */
+ gboolean disabled) /* Is the filter disabled? */
+{
+ color_filter_t *colorf;
+
+ colorf = (color_filter_t *)g_malloc0(sizeof (color_filter_t));
+ colorf->filter_name = g_strdup(name);
+ colorf->filter_text = g_strdup(filter_string);
+ colorf->bg_color = *bg_color;
+ colorf->fg_color = *fg_color;
+ colorf->disabled = disabled;
+ return colorf;
+}
+
+/* Add ten empty (temporary) colorfilters for easy coloring */
+static void
+color_filters_add_tmp(GSList **cfl, initialize_color_func init_func)
+{
+ gchar *name = NULL;
+ guint32 i;
+ gchar** bg_colors;
+ gchar** fg_colors;
+ gulong cval;
+ color_t bg_color, fg_color;
+ color_filter_t *colorf;
+
+ g_assert(strlen(prefs.gui_colorized_fg)==69);
+ g_assert(strlen(prefs.gui_colorized_bg)==69);
+ fg_colors = g_strsplit(prefs.gui_colorized_fg, ",", -1);
+ bg_colors = g_strsplit(prefs.gui_colorized_bg, ",", -1);
+
+ for ( i=1 ; i<=10 ; i++ ) {
+ name = g_strdup_printf("%s%02d",CONVERSATION_COLOR_PREFIX,i);
+
+ /* retrieve background and foreground colors */
+ cval = strtoul(fg_colors[i-1], NULL, 16);
+ init_func(&fg_color, RED_COMPONENT(cval),
+ GREEN_COMPONENT(cval),
+ BLUE_COMPONENT(cval) );
+ cval = strtoul(bg_colors[i-1], NULL, 16);
+ init_func(&bg_color, RED_COMPONENT(cval),
+ GREEN_COMPONENT(cval),
+ BLUE_COMPONENT(cval) );
+ colorf = color_filter_new(name, NULL, &bg_color, &fg_color, TRUE);
+ colorf->filter_text = g_strdup("frame");
+ *cfl = g_slist_append(*cfl, colorf);
+
+ g_free(name);
+ }
+
+ g_strfreev(fg_colors);
+ g_strfreev(bg_colors);
+
+ return;
+}
+
+static gint
+color_filters_find_by_name_cb(gconstpointer arg1, gconstpointer arg2)
+{
+ const color_filter_t *colorf = (const color_filter_t *)arg1;
+ const gchar *name = (const gchar *)arg2;
+
+ return (strstr(colorf->filter_name, name)==NULL) ? -1 : 0 ;
+}
+
+
+/* Set the filter off a temporary colorfilters and enable it */
+gboolean
+color_filters_set_tmp(guint8 filt_nr, const gchar *filter, gboolean disabled, gchar **err_msg)
+{
+ gchar *name = NULL;
+ const gchar *tmpfilter = NULL;
+ GSList *cfl;
+ color_filter_t *colorf;
+ dfilter_t *compiled_filter;
+ guint8 i;
+ gchar *local_err_msg = NULL;
+ /* Go through the temporary filters and look for the same filter string.
+ * If found, clear it so that a filter can be "moved" up and down the list
+ */
+ for ( i=1 ; i<=10 ; i++ ) {
+ /* If we need to reset the temporary filter (filter==NULL), don't look
+ * for other rules with the same filter string
+ */
+ if( i!=filt_nr && filter==NULL )
+ continue;
+
+ name = g_strdup_printf("%s%02d",CONVERSATION_COLOR_PREFIX,i);
+ cfl = g_slist_find_custom(color_filter_list, name, color_filters_find_by_name_cb);
+ colorf = (color_filter_t *)cfl->data;
+
+ /* Only change the filter rule if this is the rule to change or if
+ * a matching filter string has been found
+ */
+ if(colorf && ( (i==filt_nr) || (strstr(filter,colorf->filter_text)!=NULL) ) ) {
+ /* set filter string to "frame" if we are resetting the rules
+ * or if we found a matching filter string which need to be cleared
+ */
+ tmpfilter = ( (filter==NULL) || (i!=filt_nr) ) ? "frame" : filter;
+ if (!dfilter_compile(tmpfilter, &compiled_filter, &local_err_msg)) {
+ *err_msg = g_strdup_printf( "Could not compile color filter name: \"%s\" text: \"%s\".\n%s", name, filter, local_err_msg);
+ g_free(local_err_msg);
+ return FALSE;
+ } else {
+ if (colorf->filter_text != NULL)
+ g_free(colorf->filter_text);
+ if (colorf->c_colorfilter != NULL)
+ dfilter_free(colorf->c_colorfilter);
+ colorf->filter_text = g_strdup(tmpfilter);
+ colorf->c_colorfilter = compiled_filter;
+ colorf->disabled = ((i!=filt_nr) ? TRUE : disabled);
+ /* Remember that there are now temporary coloring filters set */
+ if( filter )
+ tmp_colors_set = TRUE;
+ }
+ }
+ g_free(name);
+ }
+ return TRUE;
+}
+
+const color_filter_t *
+color_filters_tmp_color(guint8 filter_num) {
+ gchar *name;
+ color_filter_t *colorf = NULL;
+ GSList *cfl;
+
+ name = g_strdup_printf("%s%02d", CONVERSATION_COLOR_PREFIX, filter_num);
+ cfl = g_slist_find_custom(color_filter_list, name, color_filters_find_by_name_cb);
+ if (cfl) {
+ colorf = (color_filter_t *)cfl->data;
+ }
+ g_free(name);
+
+ return colorf;
+}
+
+/* Reset the temporary colorfilters */
+gboolean
+color_filters_reset_tmp(gchar **err_msg)
+{
+ guint8 i;
+
+ for ( i=1 ; i<=10 ; i++ ) {
+ if (!color_filters_set_tmp(i, NULL, TRUE, err_msg))
+ return FALSE;
+ }
+ /* Remember that there are now *no* temporary coloring filters set */
+ tmp_colors_set = FALSE;
+ return TRUE;
+}
+
+/* delete the specified filter */
+void
+color_filter_delete(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);
+ g_free(colorf);
+}
+
+/* delete the specified filter (called from g_slist_foreach) */
+static void
+color_filter_delete_cb(gpointer filter_arg, gpointer unused _U_)
+{
+ color_filter_t *colorf = (color_filter_t *)filter_arg;
+
+ color_filter_delete(colorf);
+}
+
+/* delete the specified list */
+void
+color_filter_list_delete(GSList **cfl)
+{
+ g_slist_foreach(*cfl, color_filter_delete_cb, NULL);
+ g_slist_free(*cfl);
+ *cfl = NULL;
+}
+
+/* clone a single list entries from normal to edit list */
+static color_filter_t *
+color_filter_clone(color_filter_t *colorf)
+{
+ color_filter_t *new_colorf;
+
+ new_colorf = (color_filter_t *)g_malloc(sizeof (color_filter_t));
+ new_colorf->filter_name = g_strdup(colorf->filter_name);
+ new_colorf->filter_text = g_strdup(colorf->filter_text);
+ new_colorf->bg_color = colorf->bg_color;
+ new_colorf->fg_color = colorf->fg_color;
+ new_colorf->disabled = colorf->disabled;
+ new_colorf->c_colorfilter = NULL;
+ new_colorf->color_edit_dlg_info = NULL;
+ new_colorf->selected = FALSE;
+
+ return new_colorf;
+}
+
+static void
+color_filter_list_clone_cb(gpointer filter_arg, gpointer cfl_arg)
+{
+ GSList **cfl = (GSList **)cfl_arg;
+ color_filter_t *new_colorf;
+
+ new_colorf = color_filter_clone((color_filter_t *)filter_arg);
+ *cfl = g_slist_append(*cfl, new_colorf);
+}
+
+/* clone the specified list */
+static GSList *
+color_filter_list_clone(GSList *cfl)
+{
+ GSList *new_list = NULL;
+
+ g_slist_foreach(cfl, color_filter_list_clone_cb, &new_list);
+
+ return new_list;
+}
+
+/* Initialize the filter structures (reading from file) for general running, including app startup */
+gboolean
+color_filters_init(gchar** err_msg, initialize_color_func init_func, color_filter_add_cb_func add_cb)
+{
+ /* delete all currently existing filters */
+ color_filter_list_delete(&color_filter_list);
+
+ /* start the list with the temporary colorizing rules */
+ color_filters_add_tmp(&color_filter_list, init_func);
+
+ /* try to read the users filters */
+ if (!read_users_filters(&color_filter_list, err_msg, init_func, add_cb)) {
+ gchar* local_err_msg = NULL;
+
+ /* if that failed, try to read the global filters */
+ if (!color_filters_read_globals(&color_filter_list, &local_err_msg, init_func, add_cb)) {
+ /* Show the first error */
+ g_free(local_err_msg);
+ }
+
+ return (*err_msg == NULL);
+ }
+
+ return TRUE;
+}
+
+gboolean
+color_filters_reload(gchar** err_msg, initialize_color_func init_func, color_filter_add_cb_func add_cb)
+{
+ /* "move" old entries to the deleted list
+ * we must keep them until the dissection no longer needs them */
+ color_filter_deleted_list = g_slist_concat(color_filter_deleted_list, color_filter_list);
+ color_filter_list = NULL;
+
+ /* start the list with the temporary colorizing rules */
+ color_filters_add_tmp(&color_filter_list, init_func);
+
+ /* try to read the users filters */
+ if (!read_users_filters(&color_filter_list, err_msg, init_func, add_cb)) {
+ gchar* local_err_msg = NULL;
+
+ /* if that failed, try to read the global filters */
+ if (!color_filters_read_globals(&color_filter_list, &local_err_msg, init_func, add_cb)) {
+ /* Show the first error */
+ g_free(local_err_msg);
+ }
+
+ return (*err_msg == NULL);
+ }
+ return TRUE;
+}
+
+void
+color_filters_cleanup(void)
+{
+ /* delete the previously deleted filters */
+ color_filter_list_delete(&color_filter_deleted_list);
+}
+
+typedef struct _color_clone
+{
+ gpointer user_data;
+ color_filter_add_cb_func add_cb;
+} color_clone_t;
+
+static void
+color_filters_clone_cb(gpointer filter_arg, gpointer user_data)
+{
+ color_clone_t* clone_data = (color_clone_t*)user_data;
+ color_filter_t * new_colorf = color_filter_clone((color_filter_t *)filter_arg);
+
+ clone_data->add_cb (new_colorf, clone_data->user_data);
+}
+
+void
+color_filters_clone(gpointer user_data, color_filter_add_cb_func add_cb)
+{
+ color_clone_t clone_data;
+
+ clone_data.user_data = user_data;
+ clone_data.add_cb = add_cb;
+ g_slist_foreach(color_filter_list, color_filters_clone_cb, &clone_data);
+}
+
+
+static void
+color_filter_compile_cb(gpointer filter_arg, gpointer err)
+{
+ color_filter_t *colorf = (color_filter_t *)filter_arg;
+ gchar **err_msg = (gchar**)err;
+ gchar *local_err_msg = NULL;
+
+ g_assert(colorf->c_colorfilter == NULL);
+ if (!dfilter_compile(colorf->filter_text, &colorf->c_colorfilter, &local_err_msg)) {
+ *err_msg = g_strdup_printf("Could not compile color filter name: \"%s\" text: \"%s\".\n%s",
+ colorf->filter_name, colorf->filter_text, local_err_msg);
+ g_free(local_err_msg);
+ /* this filter was compilable before, so this should never happen */
+ /* except if the OK button of the parent window has been clicked */
+ /* so don't use g_assert_not_reached() but check the filters again */
+ }
+}
+
+static void
+color_filter_validate_cb(gpointer filter_arg, gpointer err)
+{
+ color_filter_t *colorf = (color_filter_t *)filter_arg;
+ gchar **err_msg = (gchar**)err;
+ gchar *local_err_msg;
+
+ g_assert(colorf->c_colorfilter == NULL);
+ if (!dfilter_compile(colorf->filter_text, &colorf->c_colorfilter, &local_err_msg)) {
+ *err_msg = g_strdup_printf("Removing color filter name: \"%s\" text: \"%s\".\n%s",
+ colorf->filter_name, colorf->filter_text, local_err_msg);
+ g_free(local_err_msg);
+ /* Delete the color filter from the list of color filters. */
+ color_filter_valid_list = g_slist_remove(color_filter_valid_list, colorf);
+ color_filter_delete(colorf);
+ }
+}
+
+/* apply changes from the edit list */
+gboolean
+color_filters_apply(GSList *tmp_cfl, GSList *edit_cfl, gchar** err_msg)
+{
+ gboolean ret = TRUE;
+
+ *err_msg = NULL;
+
+ /* "move" old entries to the deleted list
+ * we must keep them until the dissection no longer needs them */
+ color_filter_deleted_list = g_slist_concat(color_filter_deleted_list, color_filter_list);
+ color_filter_list = NULL;
+
+ /* clone all list entries from tmp/edit to normal list */
+ color_filter_valid_list = NULL;
+ color_filter_valid_list = color_filter_list_clone(tmp_cfl);
+ color_filter_valid_list = g_slist_concat(color_filter_valid_list,
+ color_filter_list_clone(edit_cfl) );
+
+ /* compile all filter */
+ g_slist_foreach(color_filter_valid_list, color_filter_validate_cb, err_msg);
+ if (*err_msg != NULL) {
+ ret = FALSE;
+ }
+
+ /* clone all list entries from tmp/edit to normal list */
+ color_filter_list = color_filter_list_clone(color_filter_valid_list);
+
+ /* compile all filter */
+ g_slist_foreach(color_filter_list, color_filter_compile_cb, err_msg);
+ if (*err_msg != NULL) {
+ ret = FALSE;
+ }
+
+ return ret;
+}
+
+gboolean
+color_filters_used(void)
+{
+ return color_filter_list != NULL && filters_enabled;
+}
+
+gboolean
+tmp_color_filters_used(void)
+{
+ return tmp_colors_set;
+}
+
+/* prepare the epan_dissect_t for the filter */
+static void
+prime_edt(gpointer data, gpointer user_data)
+{
+ color_filter_t *colorf = (color_filter_t *)data;
+ epan_dissect_t *edt = (epan_dissect_t *)user_data;
+
+ if (colorf->c_colorfilter != NULL)
+ epan_dissect_prime_dfilter(edt, colorf->c_colorfilter);
+}
+
+/* Prime the epan_dissect_t with all the compiler
+ * color filters in 'color_filter_list'. */
+void
+color_filters_prime_edt(epan_dissect_t *edt)
+{
+ if (color_filters_used())
+ g_slist_foreach(color_filter_list, prime_edt, edt);
+}
+
+/* * Return the color_t for later use */
+const color_filter_t *
+color_filters_colorize_packet(epan_dissect_t *edt)
+{
+ GSList *curr;
+ color_filter_t *colorf;
+
+ /* If we have color filters, "search" for the matching one. */
+ if (color_filters_used()) {
+ curr = color_filter_list;
+
+ while(curr != NULL) {
+ colorf = (color_filter_t *)curr->data;
+ if ( (!colorf->disabled) &&
+ (colorf->c_colorfilter != NULL) &&
+ dfilter_apply_edt(colorf->c_colorfilter, edt)) {
+ return colorf;
+ }
+ curr = g_slist_next(curr);
+ }
+ }
+
+ return NULL;
+}
+
+/* read filters from the given file */
+/* XXX - Would it make more sense to use GStrings here instead of reallocing
+ our buffers? */
+static gboolean
+read_filters_file(FILE *f, gpointer user_data, gchar** err_msg, initialize_color_func init_func, color_filter_add_cb_func add_cb)
+{
+#define INIT_BUF_SIZE 128
+ gchar *name = NULL;
+ gchar *filter_exp = NULL;
+ guint32 name_len = INIT_BUF_SIZE;
+ guint32 filter_exp_len = INIT_BUF_SIZE;
+ guint32 i = 0;
+ int c;
+ guint16 fg_r, fg_g, fg_b, bg_r, bg_g, bg_b;
+ gboolean disabled = FALSE;
+ gboolean skip_end_of_line = FALSE;
+ gboolean ret = TRUE;
+
+ name = (gchar *)g_malloc(name_len + 1);
+ filter_exp = (gchar *)g_malloc(filter_exp_len + 1);
+
+ while (1) {
+
+ if (skip_end_of_line) {
+ do {
+ c = getc(f);
+ } while (c != EOF && c != '\n');
+ if (c == EOF)
+ break;
+ disabled = FALSE;
+ skip_end_of_line = FALSE;
+ }
+
+ while ((c = getc(f)) != EOF && g_ascii_isspace(c)) {
+ if (c == '\n') {
+ continue;
+ }
+ }
+
+ if (c == EOF)
+ break;
+
+ if (c == '!') {
+ disabled = TRUE;
+ continue;
+ }
+
+ /* skip # comments and invalid lines */
+ if (c != '@') {
+ skip_end_of_line = TRUE;
+ continue;
+ }
+
+ /* we get the @ delimiter.
+ * Format is:
+ * @name@filter expression@[background r,g,b][foreground r,g,b]
+ */
+
+ /* retrieve name */
+ i = 0;
+ while (1) {
+ c = getc(f);
+ if (c == EOF || c == '@')
+ break;
+ if (i >= name_len) {
+ /* buffer isn't long enough; double its length.*/
+ name_len *= 2;
+ name = (gchar *)g_realloc(name, name_len + 1);
+ }
+ name[i++] = c;
+ }
+ name[i] = '\0';
+
+ if (c == EOF) {
+ break;
+ } else if (i == 0) {
+ skip_end_of_line = TRUE;
+ continue;
+ }
+
+ /* retrieve filter expression */
+ i = 0;
+ while (1) {
+ c = getc(f);
+ if (c == EOF || c == '@')
+ break;
+ if (i >= filter_exp_len) {
+ /* buffer isn't long enough; double its length.*/
+ filter_exp_len *= 2;
+ filter_exp = (gchar *)g_realloc(filter_exp, filter_exp_len + 1);
+ }
+ filter_exp[i++] = c;
+ }
+ filter_exp[i] = '\0';
+
+ if (c == EOF) {
+ break;
+ } else if (i == 0) {
+ skip_end_of_line = TRUE;
+ continue;
+ }
+
+ /* retrieve background and foreground colors */
+ if (fscanf(f,"[%hu,%hu,%hu][%hu,%hu,%hu]",
+ &bg_r, &bg_g, &bg_b, &fg_r, &fg_g, &fg_b) == 6) {
+
+ /* we got a complete color filter */
+
+ color_t bg_color, fg_color;
+ color_filter_t *colorf;
+ dfilter_t *temp_dfilter;
+ gchar *local_err_msg = NULL;
+
+ if (!dfilter_compile(filter_exp, &temp_dfilter, &local_err_msg)) {
+ g_warning("Could not compile \"%s\" in colorfilters file.\n%s",
+ name, local_err_msg);
+ g_free(local_err_msg);
+ prefs.unknown_colorfilters = TRUE;
+
+ skip_end_of_line = TRUE;
+ continue;
+ }
+
+ if (!init_func(&fg_color, fg_r, fg_g, fg_b)) {
+ /* oops */
+ *err_msg = g_strdup_printf("Could not allocate foreground color specified in input file for %s.", name);
+ dfilter_free(temp_dfilter);
+ skip_end_of_line = TRUE;
+ ret = FALSE;
+ continue;
+ }
+ if (!init_func(&bg_color, bg_r, bg_g, bg_b)) {
+ /* oops */
+ *err_msg = g_strdup_printf("Could not allocate background color specified in input file for %s.", name);
+ dfilter_free(temp_dfilter);
+ skip_end_of_line = TRUE;
+ ret = FALSE;
+ continue;
+ }
+
+ colorf = color_filter_new(name, filter_exp, &bg_color,
+ &fg_color, disabled);
+ if(user_data == &color_filter_list) {
+ GSList **cfl = (GSList **)user_data;
+
+ /* internal call */
+ colorf->c_colorfilter = temp_dfilter;
+ *cfl = g_slist_append(*cfl, colorf);
+ } else {
+ /* external call */
+ /* just editing, don't need the compiled filter */
+ dfilter_free(temp_dfilter);
+ add_cb(colorf, user_data);
+ }
+ } /* if sscanf */
+
+ skip_end_of_line = TRUE;
+ }
+
+ g_free(name);
+ g_free(filter_exp);
+ return ret;
+}
+
+/* read filters from the user's filter file */
+static gboolean
+read_users_filters(GSList **cfl, gchar** err_msg, initialize_color_func init_func, color_filter_add_cb_func add_cb)
+{
+ gchar *path;
+ FILE *f;
+ gboolean ret;
+
+ /* decide what file to open (from dfilter code) */
+ path = get_persconffile_path("colorfilters", TRUE);
+ if ((f = ws_fopen(path, "r")) == NULL) {
+ if (errno != ENOENT) {
+ *err_msg = g_strdup_printf("Could not open filter file\n\"%s\": %s.", path,
+ g_strerror(errno));
+ }
+ g_free(path);
+ return FALSE;
+ }
+ g_free(path);
+ path = NULL;
+
+ ret = read_filters_file(f, cfl, err_msg, init_func, add_cb);
+ fclose(f);
+ return ret;
+}
+
+/* read filters from the filter file */
+gboolean
+color_filters_read_globals(gpointer user_data, gchar** err_msg, initialize_color_func init_func, color_filter_add_cb_func add_cb)
+{
+ gchar *path;
+ FILE *f;
+ gboolean ret;
+
+ /* decide what file to open (from dfilter code) */
+ path = get_datafile_path("colorfilters");
+ if ((f = ws_fopen(path, "r")) == NULL) {
+ if (errno != ENOENT) {
+ *err_msg = g_strdup_printf("Could not open global filter file\n\"%s\": %s.", path,
+ g_strerror(errno));
+ }
+ g_free(path);
+ return FALSE;
+ }
+ g_free(path);
+ path = NULL;
+
+ ret = read_filters_file(f, user_data, err_msg, init_func, add_cb);
+ fclose(f);
+ return ret;
+}
+
+/* read filters from some other filter file (import) */
+gboolean
+color_filters_import(const gchar *path, const gpointer user_data, gchar** err_msg, initialize_color_func init_func, color_filter_add_cb_func add_cb)
+{
+ FILE *f;
+ gboolean ret;
+
+ if ((f = ws_fopen(path, "r")) == NULL) {
+ *err_msg = g_strdup_printf("Could not open\n%s\nfor reading: %s.",
+ path, g_strerror(errno));
+ return FALSE;
+ }
+
+ ret = read_filters_file(f, user_data, err_msg, init_func, add_cb);
+ fclose(f);
+ return ret;
+}
+
+struct write_filter_data
+{
+ FILE *f;
+ gboolean only_selected;
+};
+
+/* save a single filter */
+static void
+write_filter(gpointer filter_arg, gpointer data_arg)
+{
+ struct write_filter_data *data = (struct write_filter_data *)data_arg;
+ color_filter_t *colorf = (color_filter_t *)filter_arg;
+ FILE *f = data->f;
+
+ if ( (colorf->selected || !data->only_selected) &&
+ (strstr(colorf->filter_name,CONVERSATION_COLOR_PREFIX)==NULL) ) {
+ fprintf(f,"%s@%s@%s@[%u,%u,%u][%u,%u,%u]\n",
+ colorf->disabled ? "!" : "",
+ colorf->filter_name,
+ colorf->filter_text,
+ colorf->bg_color.red,
+ colorf->bg_color.green,
+ colorf->bg_color.blue,
+ colorf->fg_color.red,
+ colorf->fg_color.green,
+ colorf->fg_color.blue);
+ }
+}
+
+/* save filters in a filter file */
+static gboolean
+write_filters_file(const GSList *cfl, FILE *f, gboolean only_selected)
+{
+ struct write_filter_data data;
+
+ data.f = f;
+ data.only_selected = only_selected;
+
+ fprintf(f,"# DO NOT EDIT THIS FILE! It was created by Wireshark\n");
+ g_slist_foreach((GSList *) cfl, write_filter, &data);
+ return TRUE;
+}
+
+/* save filters in users filter file */
+gboolean
+color_filters_write(GSList *cfl, gchar** err_msg)
+{
+ gchar *pf_dir_path;
+ gchar *path;
+ FILE *f;
+
+ /* Create the directory that holds personal configuration files,
+ if necessary. */
+ if (create_persconffile_dir(&pf_dir_path) == -1) {
+ *err_msg = g_strdup_printf("Can't create directory\n\"%s\"\nfor color files: %s.",
+ pf_dir_path, g_strerror(errno));
+ g_free(pf_dir_path);
+ return FALSE;
+ }
+
+ path = get_persconffile_path("colorfilters", TRUE);
+ if ((f = ws_fopen(path, "w+")) == NULL) {
+ *err_msg = g_strdup_printf("Could not open\n%s\nfor writing: %s.",
+ path, g_strerror(errno));
+ g_free(path);
+ return FALSE;
+ }
+ g_free(path);
+ write_filters_file(cfl, f, FALSE);
+ fclose(f);
+ return TRUE;
+}
+
+/* save filters in some other filter file (export) */
+gboolean
+color_filters_export(const gchar *path, const GSList *cfl, gboolean only_marked, gchar** err_msg)
+{
+ FILE *f;
+
+ if ((f = ws_fopen(path, "w+")) == NULL) {
+ *err_msg = g_strdup_printf("Could not open\n%s\nfor writing: %s.",
+ path, g_strerror(errno));
+ return FALSE;
+ }
+ write_filters_file(cfl, f, only_marked);
+ fclose(f);
+ return TRUE;
+}
+
+/*
+ * Editor modelines - http://www.wireshark.org/tools/modelines.html
+ *
+ * Local variables:
+ * c-basic-offset: 4
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * vi: set shiftwidth=4 tabstop=8 expandtab:
+ * :indentSize=4:tabSize=8:noTabs=true:
+ */
diff --git a/epan/color_filters.h b/epan/color_filters.h
new file mode 100644
index 0000000000..2fe8b018cb
--- /dev/null
+++ b/epan/color_filters.h
@@ -0,0 +1,235 @@
+/* color_filters.h
+ * Definitions for color filters
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#ifndef __COLOR_FILTERS_H__
+#define __COLOR_FILTERS_H__
+
+#include "ws_symbol_export.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+struct epan_dissect;
+
+/*
+ * Data structure holding RGB value for a color.
+ *
+ * XXX - yes, I know, there's a "pixel" value in there as well; for
+ * now, it's intended to look just like a GdkColor but not to require
+ * that any GTK+ header files be included in order to use it.
+ * The way we handle colors needs to be cleaned up somewhat, in order
+ * to keep toolkit-specific stuff separate from toolkit-independent stuff.
+ */
+typedef struct {
+ guint32 pixel;
+ guint16 red;
+ guint16 green;
+ guint16 blue;
+} color_t;
+
+/** Initialize a color with R, G, and B values, including any toolkit-dependent
+ ** work that needs to be done.
+ *
+ * @param color the color_t to be filled
+ * @param red the red value for the color
+ * @param green the green value for the color
+ * @param blue the blue value for the color
+ * @return TRUE if it succeeds, FALSE if it fails
+ */
+typedef gboolean (*initialize_color_func)(color_t *color, guint16 red, guint16 green, guint16 blue);
+
+#define CONVERSATION_COLOR_PREFIX "___conversation_color_filter___"
+/** @file
+ * Color filters.
+ */
+
+/* Data for a color filter. */
+typedef struct _color_filter {
+ gchar *filter_name; /* name of the filter */
+ gchar *filter_text; /* text of the filter expression */
+ color_t bg_color; /* background color for packets that match */
+ color_t fg_color; /* foreground color for packets that match */
+ gboolean disabled; /* set if the filter is disabled */
+ gboolean selected; /* set if the filter is selected in the color dialog box. GTK+ only. */
+
+ /* only used inside of color_filters.c */
+ struct epan_dfilter *c_colorfilter; /* compiled filter expression */
+
+ /* only used outside of color_filters.c (beside init) */
+ void *color_edit_dlg_info; /* if filter is being edited, ptr to req'd info. GTK+ only. */
+} color_filter_t;
+
+/** A color filter was added (while importing).
+ * (color_filters.c calls this for every filter coming in)
+ *
+ * @param colorf the new color filter
+ * @param user_data from caller
+ */
+typedef void (*color_filter_add_cb_func)(color_filter_t *colorf, gpointer user_data);
+
+/** Init the color filters (incl. initial read from file). */
+WS_DLL_PUBLIC gboolean color_filters_init(gchar** err_msg, initialize_color_func init_func, color_filter_add_cb_func add_cb);
+
+/** Reload the color filters */
+WS_DLL_PUBLIC gboolean color_filters_reload(gchar** err_msg, initialize_color_func init_func, color_filter_add_cb_func add_cb);
+
+/** Cleanup remaining color filter zombies */
+WS_DLL_PUBLIC void color_filters_cleanup(void);
+
+/** Color filters currently used?
+ *
+ * @return TRUE, if filters are used
+ */
+WS_DLL_PUBLIC gboolean color_filters_used(void);
+
+/** Are there any temporary coloring filters used?
+ *
+ * @return TRUE, if temporary coloring filters are used
+ */
+WS_DLL_PUBLIC gboolean tmp_color_filters_used(void);
+
+/** Set the filter string of a temporary color filter
+ *
+ * @param filt_nr a number 1-10 pointing to a temporary color
+ * @param filter the new filter-string
+ * @param disabled whether the filter-rule should be disabled
+ */
+WS_DLL_PUBLIC gboolean
+color_filters_set_tmp(guint8 filt_nr, const gchar *filter, gboolean disabled, gchar **err_msg);
+
+/** Get a temporary color filter.
+ *
+ * @param filter_num A number from 1 to 10 specifying the color to fetch.
+ * @return The corresponding color or NULL.
+ */
+WS_DLL_PUBLIC const color_filter_t *
+color_filters_tmp_color(guint8 filter_num);
+
+/** Reset the temporary color filters
+ *
+ */
+WS_DLL_PUBLIC gboolean
+color_filters_reset_tmp(gchar **err_msg);
+
+/* Prime the epan_dissect_t with all the compiler
+ * color filters of the current filter list.
+ *
+ * @param the epan dissector details
+ */
+WS_DLL_PUBLIC void color_filters_prime_edt(struct epan_dissect *edt);
+
+/** Colorize a specific packet.
+ *
+ * @param edt the dissected packet
+ * @return the matching color filter or NULL
+ */
+WS_DLL_PUBLIC const color_filter_t *
+color_filters_colorize_packet(struct epan_dissect *edt);
+
+/** Clone the currently active filter list.
+ *
+ * @param user_data will be returned by each call to to color_filter_add_cb()
+ */
+WS_DLL_PUBLIC void color_filters_clone(gpointer user_data, color_filter_add_cb_func add_cb);
+
+/** Load filters (import) from some other filter file.
+ *
+ * @param path the path to the import file
+ * @param user_data will be returned by each call to to color_filter_add_cb()
+ * @return TRUE, if read succeeded
+ */
+WS_DLL_PUBLIC gboolean color_filters_import(const gchar *path, const gpointer user_data, gchar** err_msg, initialize_color_func init_func, color_filter_add_cb_func add_cb);
+
+/** Read filters from the global filter file (not the users file).
+ *
+ * @param user_data will be returned by each call to to color_filter_add_cb()
+ * @return TRUE, if read succeeded
+ */
+WS_DLL_PUBLIC gboolean color_filters_read_globals(gpointer user_data, gchar** err_msg, initialize_color_func init_func, color_filter_add_cb_func add_cb);
+
+
+/** Apply a changed filter list.
+ *
+ * @param tmp_cfl the temporary color filter list to apply
+ * @param edit_cfl the edited permanent color filter list to apply
+ */
+WS_DLL_PUBLIC gboolean color_filters_apply(GSList *tmp_cfl, GSList *edit_cfl, gchar** err_msg);
+
+/** Save filters in users filter file.
+ *
+ * @param cfl the filter list to write
+ * @return TRUE if write succeeded
+ */
+WS_DLL_PUBLIC gboolean color_filters_write(GSList *cfl, gchar** err_msg);
+
+/** Save filters (export) to some other filter file.
+ *
+ * @param path the path to the filter file
+ * @param cfl the filter list to write
+ * @param only_selected TRUE if only the selected filters should be saved
+ * @return TRUE, if write succeeded
+ */
+WS_DLL_PUBLIC gboolean color_filters_export(const gchar *path, const GSList *cfl, gboolean only_selected, gchar** err_msg);
+
+/** Create a new color filter (g_malloc'ed).
+ *
+ * @param name the name of the filter
+ * @param filter_string the filter string
+ * @param bg_color background color
+ * @param fg_color foreground color
+ * @param disabled gboolean
+ * @return the new color filter
+ */
+WS_DLL_PUBLIC color_filter_t *color_filter_new(
+ const gchar *name, const gchar *filter_string,
+ color_t *bg_color, color_t *fg_color, gboolean disabled);
+
+/** Delete a single color filter (g_free'ed).
+ *
+ * @param colorf the color filter to be removed
+ */
+WS_DLL_PUBLIC void color_filter_delete(color_filter_t *colorf);
+
+/** Delete a filter list including all entries.
+ *
+ * @param cfl the filter list to delete
+ */
+WS_DLL_PUBLIC void color_filter_list_delete(GSList **cfl);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
+
+/*
+ * Editor modelines - http://www.wireshark.org/tools/modelines.html
+ *
+ * Local variables:
+ * c-basic-offset: 4
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * vi: set shiftwidth=4 tabstop=8 expandtab:
+ * :indentSize=4:tabSize=8:noTabs=true:
+ */
diff --git a/epan/dissectors/file-file.c b/epan/dissectors/file-file.c
index b01f53cd33..e7a469a18e 100644
--- a/epan/dissectors/file-file.c
+++ b/epan/dissectors/file-file.c
@@ -39,8 +39,7 @@
#include <wsutil/md5.h>
#include <wsutil/str_util.h>
-#include "color.h"
-#include "color_filters.h"
+#include <epan/color_filters.h>
#include "file-file.h"
diff --git a/epan/dissectors/packet-frame.c b/epan/dissectors/packet-frame.c
index 0776295f6c..2a7b498ac4 100644
--- a/epan/dissectors/packet-frame.c
+++ b/epan/dissectors/packet-frame.c
@@ -44,8 +44,7 @@
#include "packet-frame.h"
#include "log.h"
-#include "color.h"
-#include "color_filters.h"
+#include <epan/color_filters.h>
void proto_register_frame(void);
void proto_reg_handoff_frame(void);
diff --git a/epan/prefs.h b/epan/prefs.h
index 0f2834e43b..b02a2b0c45 100644
--- a/epan/prefs.h
+++ b/epan/prefs.h
@@ -29,7 +29,7 @@ extern "C" {
#include <glib.h>
-#include "color.h"
+#include "color_filters.h"
#include <epan/params.h>
#include <epan/range.h>