X-Git-Url: http://git.samba.org/samba.git/?a=blobdiff_plain;f=color_filters.c;h=648dab26377d47ec02da892ed40e168a082891cb;hb=33ce608e1eef6a2c7efb7836423309ae0a219428;hp=b2572a60e6999e13c2064159127f8da8f2252b1c;hpb=3a7179d7237e6cd91ef08e905ba8fa6df87c44af;p=obnox%2Fwireshark%2Fwip.git diff --git a/color_filters.c b/color_filters.c index b2572a60e6..648dab2637 100644 --- a/color_filters.c +++ b/color_filters.c @@ -3,8 +3,8 @@ * * $Id$ * - * Ethereal - Network traffic analyzer - * By Gerald Combs + * Wireshark - Network traffic analyzer + * By Gerald Combs * Copyright 1998 Gerald Combs * * This program is free software; you can redistribute it and/or @@ -34,6 +34,7 @@ #include #include +#include "file_util.h" #include #include "color.h" @@ -41,31 +42,44 @@ #include "file.h" #include #include "simple_dialog.h" +#include "ui_util.h" -static gboolean read_filters(void); -static gboolean read_global_filters(void); +static gboolean read_users_filters(GSList **cfl); -/* Variables and routines defined in color.h */ +/* the currently active filters */ +static GSList *color_filter_list = NULL; -GSList *color_filter_list = NULL; -GSList *removed_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; -/* Remove the specified filter from the list of existing color filters, - * and add it to the list of removed color filters. - * This way, unmarking and marking a packet which matches a now removed - * color filter will still be colored correctly as the color filter is - * still reachable. */ -void color_filter_remove(color_filter_t *colorf) +/* Color Filters can en-/disabled. */ +gboolean filters_enabled = TRUE; + + +/* 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 */ { - /* Remove colorf from the list of color filters */ - color_filter_list = g_slist_remove(color_filter_list, colorf); - /* Add colorf to the list of removed color filters */ - removed_filter_list = g_slist_prepend(removed_filter_list, colorf); + color_filter_t *colorf; + + colorf = g_malloc(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->c_colorfilter = NULL; + colorf->edit_dialog = NULL; + colorf->selected = FALSE; + return colorf; } /* delete the specified filter */ -static void -delete_color_filter(color_filter_t *colorf) +void +color_filter_delete(color_filter_t *colorf) { if (colorf->filter_name != NULL) g_free(colorf->filter_name); @@ -76,56 +90,143 @@ delete_color_filter(color_filter_t *colorf) g_free(colorf); } -/* delete the specified filter as an iterator */ +/* delete the specified filter (called from g_slist_foreach) */ static void -delete_color_filter_it(gpointer filter_arg, gpointer unused _U_) +color_filter_delete_cb(gpointer filter_arg, gpointer unused _U_) { color_filter_t *colorf = filter_arg; - delete_color_filter(colorf); + + 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 = 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->c_colorfilter = NULL; + new_colorf->edit_dialog = NULL; + new_colorf->selected = FALSE; + + return new_colorf; } -/* delete all the filters */ static void -delete_all_color_filters (void) +color_filter_list_clone_cb(gpointer filter_arg, gpointer cfl_arg) +{ + gpointer *cfl = cfl_arg; + color_filter_t *new_colorf; + + new_colorf = color_filter_clone(filter_arg); + *cfl = g_slist_append(*cfl, new_colorf); +} + +/* clone the specified list */ +static GSList * +color_filter_list_clone(GSList *cfl) { - g_slist_foreach(color_filter_list, delete_color_filter_it, NULL); - g_slist_free(color_filter_list); - color_filter_list = NULL; - g_slist_foreach(removed_filter_list, delete_color_filter_it, NULL); - g_slist_free(removed_filter_list); - removed_filter_list = NULL; + 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 */ void color_filters_init(void) { - delete_all_color_filters(); - if (!read_filters()) - read_global_filters(); + /* delete all currently existing filters */ + color_filter_list_delete(&color_filter_list); + + /* try to read the users filters */ + if (!read_users_filters(&color_filter_list)) + /* if that failed, try to read the global filters */ + color_filters_read_globals(&color_filter_list); } -/* Create a new filter */ -color_filter_t * -color_filter_new(gchar *name, /* The name of the filter to create */ - gchar *filter_string, /* The string representing the filter */ - color_t *bg_color, /* The background color */ - color_t *fg_color) /* The foreground color */ +void +color_filters_cleanup(void) { - color_filter_t *colorf; + /* delete the previously deleted filters */ + color_filter_list_delete(&color_filter_deleted_list); +} - colorf = g_malloc(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->c_colorfilter = NULL; - colorf->edit_dialog = NULL; - colorf->marked = FALSE; - color_filter_list = g_slist_append(color_filter_list, colorf); - return colorf; +static void +color_filters_clone_cb(gpointer filter_arg, gpointer user_data) +{ + color_filter_t * new_colorf = color_filter_clone(filter_arg); + + color_filter_add_cb (new_colorf, user_data); } +void +color_filters_clone(gpointer user_data) +{ + g_slist_foreach(color_filter_list, color_filters_clone_cb, user_data); +} + + +static void +color_filter_compile_cb(gpointer filter_arg, gpointer unused _U_) +{ + color_filter_t *colorf = filter_arg; + + g_assert(colorf->c_colorfilter == NULL); + if (!dfilter_compile(colorf->filter_text, &colorf->c_colorfilter)) { + simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, + "Could not compile color filter name: \"%s\" text: \"%s\".\n%s", + colorf->filter_name, colorf->filter_text, dfilter_error_msg); + /* this filter was compilable before, so this should never happen */ + g_assert_not_reached(); + } +} + +/* apply changes from the edit list */ +void +color_filters_apply(GSList *cfl) +{ + /* "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 edit to normal list */ + color_filter_list = color_filter_list_clone(cfl); + + /* compile all filter */ + g_slist_foreach(color_filter_list, color_filter_compile_cb, NULL); +} + +gboolean +color_filters_used(void) +{ + return color_filter_list != NULL && filters_enabled; +} + +void +color_filters_enable(gboolean enable) +{ + filters_enabled = enable; +} + + +/* prepare the epan_dissect_t for the filter */ static void prime_edt(gpointer data, gpointer user_data) { @@ -144,12 +245,37 @@ color_filters_prime_edt(epan_dissect_t *edt) g_slist_foreach(color_filter_list, prime_edt, edt); } -/* read filters from the given file */ +/* Colorize a single packet of the packet list */ +color_filter_t * +color_filters_colorize_packet(gint row, 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 = curr->data; + if ((colorf->c_colorfilter != NULL) && + dfilter_apply_edt(colorf->c_colorfilter, edt)) { + /* this is the filter to use, apply it to the packet list */ + packet_list_set_colors(row, &(colorf->fg_color), &(colorf->bg_color)); + 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 arg) +read_filters_file(FILE *f, gpointer user_data) { #define INIT_BUF_SIZE 128 gchar *name = NULL; @@ -278,10 +404,18 @@ read_filters_file(FILE *f, gpointer arg) colorf = color_filter_new(name, filter_exp, &bg_color, &fg_color); - colorf->c_colorfilter = temp_dfilter; - - if (arg != NULL) - color_filter_add_cb (colorf, arg); + 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); + color_filter_add_cb (colorf, user_data); + } } /* if sscanf */ skip_end_of_line = TRUE; @@ -294,7 +428,7 @@ read_filters_file(FILE *f, gpointer arg) /* read filters from the user's filter file */ static gboolean -read_filters(void) +read_users_filters(GSList **cfl) { gchar *path; FILE *f; @@ -302,7 +436,7 @@ read_filters(void) /* decide what file to open (from dfilter code) */ path = get_persconffile_path("colorfilters", FALSE); - if ((f = fopen(path, "r")) == NULL) { + if ((f = eth_fopen(path, "r")) == NULL) { if (errno != ENOENT) { simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Could not open filter file\n\"%s\": %s.", path, @@ -314,14 +448,14 @@ read_filters(void) g_free(path); path = NULL; - ret = read_filters_file(f, NULL); + ret = read_filters_file(f, cfl); fclose(f); return ret; } /* read filters from the filter file */ -static gboolean -read_global_filters(void) +gboolean +color_filters_read_globals(gpointer user_data) { gchar *path; FILE *f; @@ -329,7 +463,7 @@ read_global_filters(void) /* decide what file to open (from dfilter code) */ path = get_datafile_path("colorfilters"); - if ((f = fopen(path, "r")) == NULL) { + if ((f = eth_fopen(path, "r")) == NULL) { if (errno != ENOENT) { simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Could not open global filter file\n\"%s\": %s.", path, @@ -341,26 +475,26 @@ read_global_filters(void) g_free(path); path = NULL; - ret = read_filters_file(f, NULL); + ret = read_filters_file(f, user_data); fclose(f); return ret; } /* read filters from some other filter file (import) */ gboolean -color_filters_import(gchar *path, gpointer arg) +color_filters_import(gchar *path, gpointer user_data) { FILE *f; gboolean ret; - if ((f = fopen(path, "r")) == NULL) { + if ((f = eth_fopen(path, "r")) == NULL) { simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Could not open\n%s\nfor reading: %s.", path, strerror(errno)); return FALSE; } - ret = read_filters_file(f, arg); + ret = read_filters_file(f, user_data); fclose(f); return ret; } @@ -368,7 +502,7 @@ color_filters_import(gchar *path, gpointer arg) struct write_filter_data { FILE * f; - gboolean only_marked; + gboolean only_selected; }; /* save a single filter */ @@ -379,7 +513,7 @@ write_filter(gpointer filter_arg, gpointer data_arg) color_filter_t *colorf = filter_arg; FILE *f = data->f; - if (colorf->marked || !data->only_marked) { + if (colorf->selected || !data->only_selected) { fprintf(f,"@%s@%s@[%d,%d,%d][%d,%d,%d]\n", colorf->filter_name, colorf->filter_text, @@ -393,22 +527,22 @@ write_filter(gpointer filter_arg, gpointer data_arg) } /* save filters in a filter file */ -gboolean -write_filters_file(FILE *f, gboolean only_marked) +static gboolean +write_filters_file(GSList *cfl, FILE *f, gboolean only_selected) { struct write_filter_data data; data.f = f; - data.only_marked = only_marked; + data.only_selected = only_selected; - fprintf(f,"# DO NOT EDIT THIS FILE! It was created by Ethereal\n"); - g_slist_foreach(color_filter_list, write_filter, &data); + fprintf(f,"# DO NOT EDIT THIS FILE! It was created by Wireshark\n"); + g_slist_foreach(cfl, write_filter, &data); return TRUE; } /* save filters in users filter file */ gboolean -color_filters_write(void) +color_filters_write(GSList *cfl) { gchar *pf_dir_path; const gchar *path; @@ -425,61 +559,31 @@ color_filters_write(void) } path = get_persconffile_path("colorfilters", TRUE); - if ((f = fopen(path, "w+")) == NULL) { + if ((f = eth_fopen(path, "w+")) == NULL) { simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Could not open\n%s\nfor writing: %s.", path, strerror(errno)); return FALSE; } - write_filters_file(f, FALSE); + write_filters_file(cfl, f, FALSE); fclose(f); return TRUE; } -/* delete users filter file and reload global filters */ -gboolean -color_filters_revert(void) -{ - gchar *pf_dir_path; - gchar *path; - - /* Create the directory that holds personal configuration files, - if necessary. */ - if (create_persconffile_dir(&pf_dir_path) == -1) { - simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, - "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)) { - g_free(path); - return FALSE; - } - - g_free(path); - - /* Reload the (global) filters - Note: this does not update the dialog. */ - color_filters_init(); - return TRUE; -} - - /* save filters in some other filter file (export) */ gboolean -color_filters_export(gchar *path, gboolean only_marked) +color_filters_export(gchar *path, GSList *cfl, gboolean only_marked) { FILE *f; - if ((f = fopen(path, "w+")) == NULL) { + if ((f = eth_fopen(path, "w+")) == NULL) { simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Could not open\n%s\nfor writing: %s.", path, strerror(errno)); return FALSE; } - write_filters_file(f, only_marked); + write_filters_file(cfl, f, only_marked); fclose(f); return TRUE; } +