2003-01-08 01:59:42 +00:00
|
|
|
/* color_filters.c
|
|
|
|
* Routines for color filters
|
|
|
|
*
|
2006-05-21 05:12:17 +00:00
|
|
|
* Wireshark - Network traffic analyzer
|
|
|
|
* By Gerald Combs <gerald@wireshark.org>
|
2003-01-08 01:59:42 +00:00
|
|
|
* Copyright 1998 Gerald Combs
|
|
|
|
*
|
2018-02-08 16:59:17 +00:00
|
|
|
* SPDX-License-Identifier: GPL-2.0-or-later
|
2003-01-08 01:59:42 +00:00
|
|
|
*/
|
|
|
|
/*
|
|
|
|
* Updated 1 Dec 10 jjm
|
|
|
|
*/
|
2008-05-22 15:46:27 +00:00
|
|
|
|
2014-08-22 21:13:05 +00:00
|
|
|
#include <config.h>
|
2021-06-14 23:06:02 +00:00
|
|
|
#define WS_LOG_DOMAIN LOG_DOMAIN_EPAN
|
2003-01-08 01:59:42 +00:00
|
|
|
|
2004-07-24 01:16:45 +00:00
|
|
|
#include <glib.h>
|
2009-08-26 19:27:49 +00:00
|
|
|
|
2023-06-28 22:39:11 +00:00
|
|
|
#include <errno.h>
|
2009-08-26 19:27:49 +00:00
|
|
|
#include <stdio.h>
|
2013-12-03 22:16:49 +00:00
|
|
|
#include <stdlib.h>
|
2003-01-08 01:59:42 +00:00
|
|
|
#include <string.h>
|
|
|
|
|
2013-11-17 02:55:14 +00:00
|
|
|
#include <wsutil/filesystem.h>
|
2008-05-22 15:46:27 +00:00
|
|
|
#include <wsutil/file_util.h>
|
colors: Improve handling of errors
Pop up a dialog about bad coloring rules when reading the file
(e.g., when first starting Wireshark), rather than waiting until
you try to edit them.
Have that dialog have details of the problem with the filter
instead of a generic message. The report_warning code will
consolidate multiple warnings into one if more than one filter
has an error, rather than have lots of pop-ups.
Since the dialog (or console message, in the unlikely event that
somehow the colorfilters are read in a CLI tool) is called from
the color filters code, get rid of the separate non-specific
pop-up in ColoringRulesDialog and the special preference for
having a bogus filter.
Now, if the user has a bogus filter in the current profile's
colorfilter, they'll get a useful pop-up warning at startup,
when that filter is disabled. For filters imported / copied from
other profiles through the coloring rules dialog, they'll get the
same useful pop-up.
For trying to enable a disabled coloring rules with an error, or
inserting a *new* coloring rule with invalid filter expression (despite
the editor's Red background warning about an invalid expression),
there's already both the hint at the bottom of the screen and the
OK button becomes disabled. (Maybe the hint could be larger or
bold or something when there's an error.)
Fix #14906. Fix #15034
2023-02-25 04:53:31 +00:00
|
|
|
#include <wsutil/report_message.h>
|
2021-06-14 23:06:02 +00:00
|
|
|
#include <wsutil/wslog.h>
|
2021-06-18 18:21:42 +00:00
|
|
|
#include <wsutil/ws_assert.h>
|
2003-01-08 01:59:42 +00:00
|
|
|
|
|
|
|
#include <epan/packet.h>
|
|
|
|
#include "color_filters.h"
|
|
|
|
#include "file.h"
|
|
|
|
#include <epan/dfilter/dfilter.h>
|
2007-11-24 11:38:16 +00:00
|
|
|
#include <epan/prefs.h>
|
2015-12-30 20:28:07 +00:00
|
|
|
#include <epan/epan_dissect.h>
|
2007-11-24 11:38:16 +00:00
|
|
|
|
|
|
|
#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))
|
2003-01-08 01:59:42 +00:00
|
|
|
|
2017-06-09 22:04:32 +00:00
|
|
|
static int read_filters_file(const gchar *path, FILE *f, gpointer user_data, color_filter_add_cb_func add_cb);
|
2003-01-08 01:59:42 +00:00
|
|
|
|
2006-10-03 23:24:48 +00:00
|
|
|
/* the currently active filters */
|
2006-10-03 18:39:36 +00:00
|
|
|
static GSList *color_filter_list = NULL;
|
2004-01-09 20:20:42 +00:00
|
|
|
|
2008-05-22 15:46:27 +00:00
|
|
|
/* keep "old" deleted filters in this list until
|
2006-10-03 23:24:48 +00:00
|
|
|
* the dissection no longer needs them (e.g. file is closed) */
|
|
|
|
static GSList *color_filter_deleted_list = NULL;
|
2013-02-27 16:15:18 +00:00
|
|
|
static GSList *color_filter_valid_list = NULL;
|
2006-10-03 23:24:48 +00:00
|
|
|
|
2005-03-27 02:19:51 +00:00
|
|
|
/* Color Filters can en-/disabled. */
|
2010-10-12 19:26:07 +00:00
|
|
|
static gboolean filters_enabled = TRUE;
|
2005-03-27 02:19:51 +00:00
|
|
|
|
2007-12-15 23:38:29 +00:00
|
|
|
/* Remember if there are temporary coloring filters set to
|
|
|
|
* add sensitivity to the "Reset Coloring 1-10" menu item
|
|
|
|
*/
|
2010-10-12 19:26:07 +00:00
|
|
|
static gboolean tmp_colors_set = FALSE;
|
2006-10-03 18:39:36 +00:00
|
|
|
|
|
|
|
/* Create a new filter */
|
|
|
|
color_filter_t *
|
2013-02-27 16:15:18 +00:00
|
|
|
color_filter_new(const gchar *name, /* The name of the filter to create */
|
2006-10-03 18:39:36 +00:00
|
|
|
const gchar *filter_string, /* The string representing the filter */
|
2013-02-27 16:15:18 +00:00
|
|
|
color_t *bg_color, /* The background color */
|
|
|
|
color_t *fg_color, /* The foreground color */
|
|
|
|
gboolean disabled) /* Is the filter disabled? */
|
|
|
|
{
|
|
|
|
color_filter_t *colorf;
|
|
|
|
|
2020-12-21 02:30:28 +00:00
|
|
|
colorf = g_new0(color_filter_t, 1);
|
2013-02-28 23:05:09 +00:00
|
|
|
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;
|
2011-08-17 07:10:33 +00:00
|
|
|
return colorf;
|
2004-01-09 20:20:42 +00:00
|
|
|
}
|
2003-01-08 01:59:42 +00:00
|
|
|
|
2007-11-24 11:38:16 +00:00
|
|
|
/* Add ten empty (temporary) colorfilters for easy coloring */
|
2009-10-19 14:21:11 +00:00
|
|
|
static void
|
2016-01-01 04:14:08 +00:00
|
|
|
color_filters_add_tmp(GSList **cfl)
|
2007-11-24 11:38:16 +00:00
|
|
|
{
|
2013-02-27 16:15:18 +00:00
|
|
|
gchar *name = NULL;
|
|
|
|
guint32 i;
|
|
|
|
gchar** bg_colors;
|
|
|
|
gchar** fg_colors;
|
|
|
|
gulong cval;
|
|
|
|
color_t bg_color, fg_color;
|
2011-08-17 07:10:33 +00:00
|
|
|
color_filter_t *colorf;
|
|
|
|
|
2021-06-18 18:21:42 +00:00
|
|
|
ws_assert(strlen(prefs.gui_colorized_fg)==69);
|
|
|
|
ws_assert(strlen(prefs.gui_colorized_bg)==69);
|
2011-08-17 07:10:33 +00:00
|
|
|
fg_colors = g_strsplit(prefs.gui_colorized_fg, ",", -1);
|
|
|
|
bg_colors = g_strsplit(prefs.gui_colorized_bg, ",", -1);
|
2007-11-24 11:38:16 +00:00
|
|
|
|
2013-02-27 16:15:18 +00:00
|
|
|
for ( i=1 ; i<=10 ; i++ ) {
|
2021-12-16 18:06:18 +00:00
|
|
|
name = ws_strdup_printf("%s%02d",CONVERSATION_COLOR_PREFIX,i);
|
2013-02-27 16:15:18 +00:00
|
|
|
|
|
|
|
/* retrieve background and foreground colors */
|
|
|
|
cval = strtoul(fg_colors[i-1], NULL, 16);
|
2016-01-01 04:14:08 +00:00
|
|
|
fg_color.red = RED_COMPONENT(cval);
|
|
|
|
fg_color.green = GREEN_COMPONENT(cval);
|
|
|
|
fg_color.blue = BLUE_COMPONENT(cval);
|
2013-02-27 16:15:18 +00:00
|
|
|
cval = strtoul(bg_colors[i-1], NULL, 16);
|
2016-01-01 04:14:08 +00:00
|
|
|
bg_color.red = RED_COMPONENT(cval);
|
|
|
|
bg_color.green = GREEN_COMPONENT(cval);
|
|
|
|
bg_color.blue = BLUE_COMPONENT(cval);
|
2013-02-27 16:15:18 +00:00
|
|
|
colorf = color_filter_new(name, NULL, &bg_color, &fg_color, TRUE);
|
|
|
|
colorf->filter_text = g_strdup("frame");
|
2013-10-18 15:08:19 +00:00
|
|
|
*cfl = g_slist_append(*cfl, colorf);
|
2013-02-27 16:15:18 +00:00
|
|
|
|
|
|
|
g_free(name);
|
2011-08-17 07:10:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
g_strfreev(fg_colors);
|
|
|
|
g_strfreev(bg_colors);
|
2007-11-24 11:38:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static gint
|
|
|
|
color_filters_find_by_name_cb(gconstpointer arg1, gconstpointer arg2)
|
|
|
|
{
|
2013-02-27 16:15:18 +00:00
|
|
|
const color_filter_t *colorf = (const color_filter_t *)arg1;
|
|
|
|
const gchar *name = (const gchar *)arg2;
|
2007-11-24 11:38:16 +00:00
|
|
|
|
2015-12-30 20:28:07 +00:00
|
|
|
return strcmp(colorf->filter_name, name);
|
2007-11-24 11:38:16 +00:00
|
|
|
}
|
|
|
|
|
2020-06-18 18:43:20 +00:00
|
|
|
/* Get the filter of a temporary color filter */
|
|
|
|
gchar*
|
|
|
|
color_filters_get_tmp(guint8 filt_nr)
|
|
|
|
{
|
|
|
|
gchar* name = NULL;
|
|
|
|
gchar* filter = NULL;
|
|
|
|
GSList* cfl;
|
|
|
|
color_filter_t* colorf;
|
|
|
|
/* Only perform a lookup if the supplied filter number is in the expected range */
|
|
|
|
if (filt_nr < 1 || filt_nr > 10)
|
|
|
|
return NULL;
|
|
|
|
|
2021-12-16 18:06:18 +00:00
|
|
|
name = ws_strdup_printf("%s%02d", CONVERSATION_COLOR_PREFIX, filt_nr);
|
2020-06-18 18:43:20 +00:00
|
|
|
cfl = g_slist_find_custom(color_filter_list, name, color_filters_find_by_name_cb);
|
|
|
|
colorf = (color_filter_t*)cfl->data;
|
|
|
|
|
|
|
|
if (!colorf->disabled)
|
|
|
|
filter = g_strdup(colorf->filter_text);
|
|
|
|
|
|
|
|
g_free(name);
|
|
|
|
|
|
|
|
return filter;
|
|
|
|
}
|
2007-11-24 11:38:16 +00:00
|
|
|
|
|
|
|
/* Set the filter off a temporary colorfilters and enable it */
|
2015-12-22 20:07:00 +00:00
|
|
|
gboolean
|
|
|
|
color_filters_set_tmp(guint8 filt_nr, const gchar *filter, gboolean disabled, gchar **err_msg)
|
2007-11-24 11:38:16 +00:00
|
|
|
{
|
2013-02-27 16:15:18 +00:00
|
|
|
gchar *name = NULL;
|
|
|
|
const gchar *tmpfilter = NULL;
|
|
|
|
GSList *cfl;
|
|
|
|
color_filter_t *colorf;
|
|
|
|
dfilter_t *compiled_filter;
|
|
|
|
guint8 i;
|
2022-11-19 19:21:19 +00:00
|
|
|
df_error_t *df_err = NULL;
|
2015-07-10 23:15:55 +00:00
|
|
|
/* Go through the temporary filters and look for the same filter string.
|
2013-02-27 16:15:18 +00:00
|
|
|
* 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;
|
|
|
|
|
2021-12-16 18:06:18 +00:00
|
|
|
name = ws_strdup_printf("%s%02d",CONVERSATION_COLOR_PREFIX,i);
|
2013-02-27 16:15:18 +00:00
|
|
|
cfl = g_slist_find_custom(color_filter_list, name, color_filters_find_by_name_cb);
|
|
|
|
colorf = (color_filter_t *)cfl->data;
|
2007-11-25 15:55:45 +00:00
|
|
|
|
2013-02-27 16:15:18 +00:00
|
|
|
/* Only change the filter rule if this is the rule to change or if
|
|
|
|
* a matching filter string has been found
|
2007-11-25 15:55:45 +00:00
|
|
|
*/
|
2023-04-10 13:34:58 +00:00
|
|
|
if(colorf && ( i == filt_nr || filter == NULL || !strcmp(filter, colorf->filter_text) ) ) {
|
2013-02-27 16:15:18 +00:00
|
|
|
/* 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;
|
2022-11-19 19:21:19 +00:00
|
|
|
if (!dfilter_compile(tmpfilter, &compiled_filter, &df_err)) {
|
|
|
|
*err_msg = ws_strdup_printf( "Could not compile color filter name: \"%s\" text: \"%s\".\n%s", name, filter, df_err->msg);
|
2023-04-14 23:18:53 +00:00
|
|
|
df_error_free(&df_err);
|
2020-05-02 22:25:02 +00:00
|
|
|
g_free(name);
|
2015-12-22 20:07:00 +00:00
|
|
|
return FALSE;
|
2013-02-27 16:15:18 +00:00
|
|
|
} else {
|
2017-08-26 08:30:47 +00:00
|
|
|
g_free(colorf->filter_text);
|
|
|
|
dfilter_free(colorf->c_colorfilter);
|
2013-02-27 16:15:18 +00:00
|
|
|
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;
|
|
|
|
}
|
2007-11-24 11:38:16 +00:00
|
|
|
}
|
2013-02-27 16:15:18 +00:00
|
|
|
g_free(name);
|
|
|
|
}
|
2015-12-22 20:07:00 +00:00
|
|
|
return TRUE;
|
2007-11-24 11:38:16 +00:00
|
|
|
}
|
|
|
|
|
2015-07-10 23:15:55 +00:00
|
|
|
const color_filter_t *
|
|
|
|
color_filters_tmp_color(guint8 filter_num) {
|
|
|
|
gchar *name;
|
|
|
|
color_filter_t *colorf = NULL;
|
|
|
|
GSList *cfl;
|
|
|
|
|
2021-12-16 18:06:18 +00:00
|
|
|
name = ws_strdup_printf("%s%02d", CONVERSATION_COLOR_PREFIX, filter_num);
|
2015-07-10 23:15:55 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2007-11-25 14:17:56 +00:00
|
|
|
/* Reset the temporary colorfilters */
|
2015-12-22 20:07:00 +00:00
|
|
|
gboolean
|
|
|
|
color_filters_reset_tmp(gchar **err_msg)
|
2007-11-25 14:17:56 +00:00
|
|
|
{
|
2013-02-27 16:15:18 +00:00
|
|
|
guint8 i;
|
2007-11-25 14:17:56 +00:00
|
|
|
|
2013-02-27 16:15:18 +00:00
|
|
|
for ( i=1 ; i<=10 ; i++ ) {
|
2015-12-22 20:07:00 +00:00
|
|
|
if (!color_filters_set_tmp(i, NULL, TRUE, err_msg))
|
|
|
|
return FALSE;
|
2013-02-27 16:15:18 +00:00
|
|
|
}
|
|
|
|
/* Remember that there are now *no* temporary coloring filters set */
|
|
|
|
tmp_colors_set = FALSE;
|
2015-12-22 20:07:00 +00:00
|
|
|
return TRUE;
|
2007-11-25 14:17:56 +00:00
|
|
|
}
|
|
|
|
|
2003-05-15 07:44:54 +00:00
|
|
|
/* delete the specified filter */
|
2006-10-03 18:39:36 +00:00
|
|
|
void
|
2006-10-02 23:01:33 +00:00
|
|
|
color_filter_delete(color_filter_t *colorf)
|
2003-05-15 07:44:54 +00:00
|
|
|
{
|
2017-08-26 08:30:47 +00:00
|
|
|
g_free(colorf->filter_name);
|
|
|
|
g_free(colorf->filter_text);
|
|
|
|
dfilter_free(colorf->c_colorfilter);
|
2013-02-27 16:15:18 +00:00
|
|
|
g_free(colorf);
|
2003-05-15 07:44:54 +00:00
|
|
|
}
|
|
|
|
|
2006-10-02 23:01:33 +00:00
|
|
|
/* delete the specified filter (called from g_slist_foreach) */
|
2003-05-15 07:44:54 +00:00
|
|
|
static void
|
2018-04-17 10:48:35 +00:00
|
|
|
color_filter_delete_cb(gpointer filter_arg)
|
2003-05-15 07:44:54 +00:00
|
|
|
{
|
2013-02-27 16:15:18 +00:00
|
|
|
color_filter_t *colorf = (color_filter_t *)filter_arg;
|
2006-10-03 18:39:36 +00:00
|
|
|
|
2013-02-27 16:15:18 +00:00
|
|
|
color_filter_delete(colorf);
|
2003-05-15 07:44:54 +00:00
|
|
|
}
|
|
|
|
|
2006-10-03 18:39:36 +00:00
|
|
|
/* delete the specified list */
|
|
|
|
void
|
|
|
|
color_filter_list_delete(GSList **cfl)
|
|
|
|
{
|
2018-04-17 10:48:35 +00:00
|
|
|
g_slist_free_full(*cfl, color_filter_delete_cb);
|
2013-02-27 16:15:18 +00:00
|
|
|
*cfl = NULL;
|
2006-10-03 18:39:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* clone a single list entries from normal to edit list */
|
|
|
|
static color_filter_t *
|
|
|
|
color_filter_clone(color_filter_t *colorf)
|
|
|
|
{
|
2013-02-27 16:15:18 +00:00
|
|
|
color_filter_t *new_colorf;
|
2006-10-03 18:39:36 +00:00
|
|
|
|
2020-12-21 02:30:28 +00:00
|
|
|
new_colorf = g_new(color_filter_t, 1);
|
2013-02-28 23:05:09 +00:00
|
|
|
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;
|
2006-10-03 18:39:36 +00:00
|
|
|
|
2011-08-17 07:10:33 +00:00
|
|
|
return new_colorf;
|
2006-10-03 18:39:36 +00:00
|
|
|
}
|
|
|
|
|
2003-05-15 07:44:54 +00:00
|
|
|
static void
|
2006-10-10 08:07:14 +00:00
|
|
|
color_filter_list_clone_cb(gpointer filter_arg, gpointer cfl_arg)
|
2003-05-15 07:44:54 +00:00
|
|
|
{
|
2013-02-27 16:15:18 +00:00
|
|
|
GSList **cfl = (GSList **)cfl_arg;
|
|
|
|
color_filter_t *new_colorf;
|
2006-10-03 18:39:36 +00:00
|
|
|
|
2013-02-27 16:15:18 +00:00
|
|
|
new_colorf = color_filter_clone((color_filter_t *)filter_arg);
|
2013-10-18 15:08:19 +00:00
|
|
|
*cfl = g_slist_append(*cfl, new_colorf);
|
2006-10-03 18:39:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* clone the specified list */
|
|
|
|
static GSList *
|
|
|
|
color_filter_list_clone(GSList *cfl)
|
|
|
|
{
|
2013-02-27 16:15:18 +00:00
|
|
|
GSList *new_list = NULL;
|
2006-10-03 18:39:36 +00:00
|
|
|
|
2013-02-27 16:15:18 +00:00
|
|
|
g_slist_foreach(cfl, color_filter_list_clone_cb, &new_list);
|
2006-10-03 18:39:36 +00:00
|
|
|
|
2013-02-27 16:15:18 +00:00
|
|
|
return new_list;
|
2003-05-15 07:44:54 +00:00
|
|
|
}
|
|
|
|
|
2017-06-09 22:04:32 +00:00
|
|
|
static gboolean
|
|
|
|
color_filters_get(gchar** err_msg, color_filter_add_cb_func add_cb)
|
2003-01-08 01:59:42 +00:00
|
|
|
{
|
2017-06-09 22:04:32 +00:00
|
|
|
gchar *path;
|
|
|
|
FILE *f;
|
|
|
|
int ret;
|
2006-10-02 23:01:33 +00:00
|
|
|
|
2013-02-27 16:15:18 +00:00
|
|
|
/* start the list with the temporary colorizing rules */
|
2016-01-01 04:14:08 +00:00
|
|
|
color_filters_add_tmp(&color_filter_list);
|
2007-11-24 11:38:16 +00:00
|
|
|
|
2017-06-09 22:04:32 +00:00
|
|
|
/*
|
|
|
|
* Try to get the user's filters.
|
|
|
|
*
|
|
|
|
* Get the path for the file that would have their filters, and
|
|
|
|
* try to open it.
|
|
|
|
*/
|
2018-10-09 09:46:00 +00:00
|
|
|
path = get_persconffile_path(COLORFILTERS_FILE_NAME, TRUE);
|
2017-06-09 22:04:32 +00:00
|
|
|
if ((f = ws_fopen(path, "r")) == NULL) {
|
|
|
|
if (errno != ENOENT) {
|
|
|
|
/* Error trying to open the file; give up. */
|
2021-12-16 18:06:18 +00:00
|
|
|
*err_msg = ws_strdup_printf("Could not open filter file\n\"%s\": %s.", path,
|
2017-06-09 22:04:32 +00:00
|
|
|
g_strerror(errno));
|
|
|
|
g_free(path);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
/* They don't have any filters; try to read the global filters */
|
|
|
|
g_free(path);
|
|
|
|
return color_filters_read_globals(&color_filter_list, err_msg, add_cb);
|
|
|
|
}
|
2015-12-22 20:07:00 +00:00
|
|
|
|
2017-06-09 22:04:32 +00:00
|
|
|
/*
|
|
|
|
* We've opened it; try to read it.
|
|
|
|
*/
|
|
|
|
ret = read_filters_file(path, f, &color_filter_list, add_cb);
|
|
|
|
if (ret != 0) {
|
2021-12-16 18:06:18 +00:00
|
|
|
*err_msg = ws_strdup_printf("Error reading filter file\n\"%s\": %s.",
|
2017-06-09 22:04:32 +00:00
|
|
|
path, g_strerror(errno));
|
|
|
|
fclose(f);
|
|
|
|
g_free(path);
|
|
|
|
return FALSE;
|
2015-12-22 20:07:00 +00:00
|
|
|
}
|
|
|
|
|
2017-06-09 22:04:32 +00:00
|
|
|
/* Success. */
|
|
|
|
fclose(f);
|
|
|
|
g_free(path);
|
2015-12-22 20:07:00 +00:00
|
|
|
return TRUE;
|
2003-01-08 01:59:42 +00:00
|
|
|
}
|
|
|
|
|
2017-06-09 22:04:32 +00:00
|
|
|
/* Initialize the filter structures (reading from file) for general running, including app startup */
|
|
|
|
gboolean
|
|
|
|
color_filters_init(gchar** err_msg, color_filter_add_cb_func add_cb)
|
|
|
|
{
|
|
|
|
/* delete all currently existing filters */
|
|
|
|
color_filter_list_delete(&color_filter_list);
|
|
|
|
|
|
|
|
/* now try to construct the filters list */
|
|
|
|
return color_filters_get(err_msg, add_cb);
|
|
|
|
}
|
|
|
|
|
2015-12-22 20:07:00 +00:00
|
|
|
gboolean
|
2016-01-01 04:14:08 +00:00
|
|
|
color_filters_reload(gchar** err_msg, color_filter_add_cb_func add_cb)
|
2008-01-14 16:40:23 +00:00
|
|
|
{
|
2011-08-17 07:10:33 +00:00
|
|
|
/* "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;
|
2008-01-14 16:40:23 +00:00
|
|
|
|
2017-06-09 22:04:32 +00:00
|
|
|
/* now try to construct the filters list */
|
|
|
|
return color_filters_get(err_msg, add_cb);
|
2008-01-14 16:40:23 +00:00
|
|
|
}
|
|
|
|
|
2006-10-03 23:24:48 +00:00
|
|
|
void
|
|
|
|
color_filters_cleanup(void)
|
|
|
|
{
|
2011-08-17 07:10:33 +00:00
|
|
|
/* delete the previously deleted filters */
|
|
|
|
color_filter_list_delete(&color_filter_deleted_list);
|
2006-10-03 23:24:48 +00:00
|
|
|
}
|
|
|
|
|
2015-12-22 20:07:00 +00:00
|
|
|
typedef struct _color_clone
|
|
|
|
{
|
|
|
|
gpointer user_data;
|
|
|
|
color_filter_add_cb_func add_cb;
|
|
|
|
} color_clone_t;
|
|
|
|
|
2006-10-03 18:39:36 +00:00
|
|
|
static void
|
|
|
|
color_filters_clone_cb(gpointer filter_arg, gpointer user_data)
|
2003-01-08 01:59:42 +00:00
|
|
|
{
|
2015-12-22 20:07:00 +00:00
|
|
|
color_clone_t* clone_data = (color_clone_t*)user_data;
|
2013-02-27 16:15:18 +00:00
|
|
|
color_filter_t * new_colorf = color_filter_clone((color_filter_t *)filter_arg);
|
2015-12-22 20:07:00 +00:00
|
|
|
|
|
|
|
clone_data->add_cb (new_colorf, clone_data->user_data);
|
2006-10-03 18:39:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2015-12-22 20:07:00 +00:00
|
|
|
color_filters_clone(gpointer user_data, color_filter_add_cb_func add_cb)
|
2006-10-03 18:39:36 +00:00
|
|
|
{
|
2015-12-22 20:07:00 +00:00
|
|
|
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);
|
2006-10-03 18:39:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
2015-12-22 20:07:00 +00:00
|
|
|
color_filter_compile_cb(gpointer filter_arg, gpointer err)
|
2006-10-03 18:39:36 +00:00
|
|
|
{
|
2013-02-27 16:15:18 +00:00
|
|
|
color_filter_t *colorf = (color_filter_t *)filter_arg;
|
2015-12-22 20:07:00 +00:00
|
|
|
gchar **err_msg = (gchar**)err;
|
2022-11-19 19:21:19 +00:00
|
|
|
df_error_t *df_err = NULL;
|
2006-10-03 18:39:36 +00:00
|
|
|
|
2021-06-18 18:21:42 +00:00
|
|
|
ws_assert(colorf->c_colorfilter == NULL);
|
2016-09-20 18:30:38 +00:00
|
|
|
|
|
|
|
/* If the filter is disabled it doesn't matter if it compiles or not. */
|
|
|
|
if (colorf->disabled) return;
|
|
|
|
|
2022-11-19 19:21:19 +00:00
|
|
|
if (!dfilter_compile(colorf->filter_text, &colorf->c_colorfilter, &df_err)) {
|
2021-12-16 18:06:18 +00:00
|
|
|
*err_msg = ws_strdup_printf("Could not compile color filter name: \"%s\" text: \"%s\".\n%s",
|
2022-11-19 19:21:19 +00:00
|
|
|
colorf->filter_name, colorf->filter_text, df_err->msg);
|
2023-04-14 23:18:53 +00:00
|
|
|
df_error_free(&df_err);
|
2013-02-27 16:15:18 +00:00
|
|
|
/* this filter was compilable before, so this should never happen */
|
|
|
|
/* except if the OK button of the parent window has been clicked */
|
2021-06-18 18:21:42 +00:00
|
|
|
/* so don't use ws_assert_not_reached() but check the filters again */
|
2013-02-27 16:15:18 +00:00
|
|
|
}
|
2007-08-21 21:15:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2015-12-22 20:07:00 +00:00
|
|
|
color_filter_validate_cb(gpointer filter_arg, gpointer err)
|
2007-08-21 21:15:57 +00:00
|
|
|
{
|
2013-02-27 16:15:18 +00:00
|
|
|
color_filter_t *colorf = (color_filter_t *)filter_arg;
|
2015-12-22 20:07:00 +00:00
|
|
|
gchar **err_msg = (gchar**)err;
|
2022-11-19 19:21:19 +00:00
|
|
|
df_error_t *df_err = NULL;
|
2007-08-21 21:15:57 +00:00
|
|
|
|
2021-06-18 18:21:42 +00:00
|
|
|
ws_assert(colorf->c_colorfilter == NULL);
|
2016-09-20 18:30:38 +00:00
|
|
|
|
|
|
|
/* If the filter is disabled it doesn't matter if it compiles or not. */
|
|
|
|
if (colorf->disabled) return;
|
|
|
|
|
2022-11-19 19:21:19 +00:00
|
|
|
if (!dfilter_compile(colorf->filter_text, &colorf->c_colorfilter, &df_err)) {
|
2021-12-16 18:06:18 +00:00
|
|
|
*err_msg = ws_strdup_printf("Disabling color filter name: \"%s\" filter: \"%s\".\n%s",
|
2022-11-19 19:21:19 +00:00
|
|
|
colorf->filter_name, colorf->filter_text, df_err->msg);
|
2023-04-14 23:18:53 +00:00
|
|
|
df_error_free(&df_err);
|
2018-09-28 21:45:35 +00:00
|
|
|
|
|
|
|
/* Disable the color filter in the list of color filters. */
|
|
|
|
colorf->disabled = TRUE;
|
2013-02-27 16:15:18 +00:00
|
|
|
}
|
2023-02-19 02:52:50 +00:00
|
|
|
|
|
|
|
/* XXX: What if the color filter tests "frame.coloring_rule.name" or
|
|
|
|
* "frame.coloring_rule.string"?
|
|
|
|
*/
|
2006-10-03 18:39:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* apply changes from the edit list */
|
2015-12-22 20:07:00 +00:00
|
|
|
gboolean
|
|
|
|
color_filters_apply(GSList *tmp_cfl, GSList *edit_cfl, gchar** err_msg)
|
2006-10-03 18:39:36 +00:00
|
|
|
{
|
2015-12-22 20:07:00 +00:00
|
|
|
gboolean ret = TRUE;
|
|
|
|
|
|
|
|
*err_msg = NULL;
|
|
|
|
|
2013-02-27 16:15:18 +00:00
|
|
|
/* "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;
|
2006-10-03 18:39:36 +00:00
|
|
|
|
2013-02-27 16:15:18 +00:00
|
|
|
/* clone all list entries from tmp/edit to normal list */
|
2023-06-20 11:53:41 +00:00
|
|
|
color_filter_list_delete(&color_filter_valid_list);
|
2013-02-27 16:15:18 +00:00
|
|
|
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) );
|
2007-08-21 21:15:57 +00:00
|
|
|
|
2013-02-27 16:15:18 +00:00
|
|
|
/* compile all filter */
|
2015-12-22 20:07:00 +00:00
|
|
|
g_slist_foreach(color_filter_valid_list, color_filter_validate_cb, err_msg);
|
|
|
|
if (*err_msg != NULL) {
|
|
|
|
ret = FALSE;
|
|
|
|
}
|
2007-08-21 21:15:57 +00:00
|
|
|
|
2013-02-27 16:15:18 +00:00
|
|
|
/* clone all list entries from tmp/edit to normal list */
|
|
|
|
color_filter_list = color_filter_list_clone(color_filter_valid_list);
|
2006-10-03 18:39:36 +00:00
|
|
|
|
2013-02-27 16:15:18 +00:00
|
|
|
/* compile all filter */
|
2015-12-22 20:07:00 +00:00
|
|
|
g_slist_foreach(color_filter_list, color_filter_compile_cb, err_msg);
|
|
|
|
if (*err_msg != NULL) {
|
|
|
|
ret = FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
2003-01-08 01:59:42 +00:00
|
|
|
}
|
|
|
|
|
2008-05-22 15:46:27 +00:00
|
|
|
gboolean
|
2005-03-26 11:32:43 +00:00
|
|
|
color_filters_used(void)
|
|
|
|
{
|
2013-02-27 16:15:18 +00:00
|
|
|
return color_filter_list != NULL && filters_enabled;
|
2005-03-27 02:19:51 +00:00
|
|
|
}
|
|
|
|
|
2008-05-22 15:46:27 +00:00
|
|
|
gboolean
|
2007-12-15 23:38:29 +00:00
|
|
|
tmp_color_filters_used(void)
|
|
|
|
{
|
2013-02-27 16:15:18 +00:00
|
|
|
return tmp_colors_set;
|
2007-12-15 23:38:29 +00:00
|
|
|
}
|
|
|
|
|
2006-10-02 21:55:26 +00:00
|
|
|
/* prepare the epan_dissect_t for the filter */
|
2005-03-26 11:32:43 +00:00
|
|
|
static void
|
2006-10-02 21:55:26 +00:00
|
|
|
prime_edt(gpointer data, gpointer user_data)
|
2005-03-26 11:32:43 +00:00
|
|
|
{
|
2013-02-27 16:15:18 +00:00
|
|
|
color_filter_t *colorf = (color_filter_t *)data;
|
|
|
|
epan_dissect_t *edt = (epan_dissect_t *)user_data;
|
2005-03-26 11:32:43 +00:00
|
|
|
|
2013-02-27 16:15:18 +00:00
|
|
|
if (colorf->c_colorfilter != NULL)
|
2017-04-12 04:56:14 +00:00
|
|
|
epan_dissect_prime_with_dfilter(edt, colorf->c_colorfilter);
|
2005-03-26 11:32:43 +00:00
|
|
|
}
|
|
|
|
|
2006-10-02 21:55:26 +00:00
|
|
|
/* Prime the epan_dissect_t with all the compiler
|
|
|
|
* color filters in 'color_filter_list'. */
|
|
|
|
void
|
|
|
|
color_filters_prime_edt(epan_dissect_t *edt)
|
|
|
|
{
|
2013-02-27 16:15:18 +00:00
|
|
|
if (color_filters_used())
|
|
|
|
g_slist_foreach(color_filter_list, prime_edt, edt);
|
2006-10-02 21:55:26 +00:00
|
|
|
}
|
2005-03-26 11:32:43 +00:00
|
|
|
|
2023-02-19 02:52:50 +00:00
|
|
|
static gint
|
|
|
|
find_hfid(gconstpointer data, gconstpointer user_data)
|
|
|
|
{
|
|
|
|
color_filter_t *colorf = (color_filter_t *)data;
|
|
|
|
int hfid = GPOINTER_TO_INT(user_data);
|
|
|
|
|
|
|
|
if ((!colorf->disabled) && colorf->c_colorfilter != NULL) {
|
|
|
|
if (dfilter_interested_in_field(colorf->c_colorfilter, hfid)) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
gboolean
|
|
|
|
color_filters_use_hfid(int hfid)
|
|
|
|
{
|
|
|
|
GSList *item = NULL;
|
|
|
|
if (color_filters_used())
|
|
|
|
item = g_slist_find_custom(color_filter_list, GINT_TO_POINTER(hfid), find_hfid);
|
|
|
|
return (item != NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
static gint
|
|
|
|
find_proto(gconstpointer data, gconstpointer user_data)
|
|
|
|
{
|
|
|
|
color_filter_t *colorf = (color_filter_t *)data;
|
|
|
|
int proto_id = GPOINTER_TO_INT(user_data);
|
|
|
|
|
|
|
|
if ((!colorf->disabled) && colorf->c_colorfilter != NULL) {
|
|
|
|
if (dfilter_interested_in_proto(colorf->c_colorfilter, proto_id)) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
gboolean
|
|
|
|
color_filters_use_proto(int proto_id)
|
|
|
|
{
|
|
|
|
GSList *item = NULL;
|
|
|
|
if (color_filters_used())
|
|
|
|
item = g_slist_find_custom(color_filter_list, GINT_TO_POINTER(proto_id), find_proto);
|
|
|
|
return (item != NULL);
|
|
|
|
}
|
|
|
|
|
2011-03-08 20:23:48 +00:00
|
|
|
/* * Return the color_t for later use */
|
2009-09-21 18:48:53 +00:00
|
|
|
const color_filter_t *
|
2009-09-06 06:07:53 +00:00
|
|
|
color_filters_colorize_packet(epan_dissect_t *edt)
|
2005-03-26 11:32:43 +00:00
|
|
|
{
|
2013-02-27 16:15:18 +00:00
|
|
|
GSList *curr;
|
|
|
|
color_filter_t *colorf;
|
2010-10-12 19:26:07 +00:00
|
|
|
|
2013-02-27 16:15:18 +00:00
|
|
|
/* If we have color filters, "search" for the matching one. */
|
2015-12-30 20:28:07 +00:00
|
|
|
if ((edt->tree != NULL) && (color_filters_used())) {
|
2013-02-27 16:15:18 +00:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
2005-03-26 11:32:43 +00:00
|
|
|
|
2013-02-27 16:15:18 +00:00
|
|
|
return NULL;
|
2003-01-08 01:59:42 +00:00
|
|
|
}
|
|
|
|
|
2003-05-15 07:44:54 +00:00
|
|
|
/* read filters from the given file */
|
2004-07-24 01:32:29 +00:00
|
|
|
/* XXX - Would it make more sense to use GStrings here instead of reallocing
|
|
|
|
our buffers? */
|
2016-01-01 04:14:08 +00:00
|
|
|
static int
|
2016-08-04 01:05:21 +00:00
|
|
|
read_filters_file(const gchar *path, FILE *f, gpointer user_data, color_filter_add_cb_func add_cb)
|
2003-01-08 01:59:42 +00:00
|
|
|
{
|
2004-03-14 23:55:53 +00:00
|
|
|
#define INIT_BUF_SIZE 128
|
Fix some cppcheck issues:
- Some redundant assignments or tests.
- Some declarations were changed to match definitions in terms of
including _U_ for the same parameters
- Some parenthesis added/changed to made precedence more obvious
epan/color_filters.c:533: style: Variable 'name' is reassigned a value before the old one has been used.
epan/color_filters.c:534: style: Variable 'filter_exp' is reassigned a value before the old one has been used.
asn1/tcap/packet-tcap-template.c:2199: warning: Function 'dissect_tcap_ITU_ComponentPDU' argument order different: declaration '_U_, tvb, offset, _U_, tree, _U_' definition '_U_, tvb, offset, actx, tree, _U_'
epan/dissectors/packet-aim.c:2546: warning: Function 'dissect_aim_tlv_value_icq' argument order different: declaration 'ti, subtype, tvb, _U_' definition 'ti, _U_, tvb, pinfo'
epan/dissectors/packet-arp.c:1133: style: Clarify calculation precedence for '&' and '?'.
epan/dissectors/packet-arp.c:1143: style: Clarify calculation precedence for '&' and '?'.
epan/dissectors/packet-arp.c:1158: style: Clarify calculation precedence for '&' and '?'.
epan/dissectors/packet-arp.c:1168: style: Clarify calculation precedence for '&' and '?'.
epan/dissectors/packet-gtpv2.c:5997: warning: Function 'dissect_gtpv2_mbms_service_area' argument order different: declaration 'tvb, _U_, tree, _U_, _U_, _U_, _U_, _U_' definition 'tvb, _U_, tree, item, _U_, _U_, _U_, _U_'
epan/dissectors/packet-gtpv2.c:6291: warning: Function 'dissect_gtpv2_mbms_time_to_data_xfer' argument order different: declaration 'tvb, _U_, tree, _U_, _U_, _U_, _U_, _U_' definition 'tvb, _U_, tree, item, _U_, _U_, _U_, _U_'
epan/dissectors/packet-gtpv2.c:6369: warning: Function 'dissect_gtpv2_epc_timer' argument order different: declaration 'tvb, _U_, tree, _U_, _U_, _U_, _U_, _U_' definition 'tvb, _U_, tree, item, _U_, message_type, _U_, _U_'
epan/dissectors/packet-knxip.c:2939: style: Condition 'mac_error' is always false (just added comment)
epan/dissectors/packet-mac-lte.c:4386: style: Clarify calculation precedence for '&' and '?'.
epan/dissectors/packet-nas_5gs.c:1828: style: Variable 'nas5gs_data->payload_container_type' is reassigned a value before the old one has been used. (noted confusing recursion)
epan/dissectors/packet-rpcrdma.c:587: warning: Identical condition 'offset>max_offset', second condition is always false
epan/dissectors/packet-rsl.c:2098: style: Assignment of function parameter has no effect outside the function.
Change-Id: Ib5c9a04cfb6e6233972bc041434601c8ef09c969
Reviewed-on: https://code.wireshark.org/review/37343
Petri-Dish: Martin Mathieson <martin.r.mathieson@googlemail.com>
Tested-by: Petri Dish Buildbot
Reviewed-by: Martin Mathieson <martin.r.mathieson@googlemail.com>
2020-05-31 10:02:09 +00:00
|
|
|
gchar *name;
|
|
|
|
gchar *filter_exp;
|
2013-02-27 16:15:18 +00:00
|
|
|
guint32 name_len = INIT_BUF_SIZE;
|
|
|
|
guint32 filter_exp_len = INIT_BUF_SIZE;
|
|
|
|
guint32 i = 0;
|
2014-10-17 23:42:40 +00:00
|
|
|
int c;
|
2013-02-27 16:15:18 +00:00
|
|
|
guint16 fg_r, fg_g, fg_b, bg_r, bg_g, bg_b;
|
|
|
|
gboolean disabled = FALSE;
|
|
|
|
gboolean skip_end_of_line = FALSE;
|
2016-01-01 04:14:08 +00:00
|
|
|
int ret = 0;
|
2013-02-27 16:15:18 +00:00
|
|
|
|
|
|
|
name = (gchar *)g_malloc(name_len + 1);
|
|
|
|
filter_exp = (gchar *)g_malloc(filter_exp_len + 1);
|
|
|
|
|
|
|
|
while (1) {
|
|
|
|
|
|
|
|
if (skip_end_of_line) {
|
|
|
|
do {
|
2016-03-18 20:13:44 +00:00
|
|
|
c = ws_getc_unlocked(f);
|
2013-02-27 16:15:18 +00:00
|
|
|
} while (c != EOF && c != '\n');
|
|
|
|
if (c == EOF)
|
|
|
|
break;
|
|
|
|
disabled = FALSE;
|
|
|
|
skip_end_of_line = FALSE;
|
|
|
|
}
|
|
|
|
|
2016-03-18 20:13:44 +00:00
|
|
|
while ((c = ws_getc_unlocked(f)) != EOF && g_ascii_isspace(c)) {
|
2013-02-27 16:15:18 +00:00
|
|
|
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) {
|
2016-03-18 20:13:44 +00:00
|
|
|
c = ws_getc_unlocked(f);
|
2013-02-27 16:15:18 +00:00
|
|
|
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) {
|
2016-03-18 20:13:44 +00:00
|
|
|
c = ws_getc_unlocked(f);
|
2013-02-27 16:15:18 +00:00
|
|
|
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;
|
2016-10-04 16:05:31 +00:00
|
|
|
dfilter_t *temp_dfilter = NULL;
|
2022-11-19 19:21:19 +00:00
|
|
|
df_error_t *df_err = NULL;
|
2013-02-27 16:15:18 +00:00
|
|
|
|
2022-11-19 19:21:19 +00:00
|
|
|
if (!disabled && !dfilter_compile(filter_exp, &temp_dfilter, &df_err)) {
|
colors: Improve handling of errors
Pop up a dialog about bad coloring rules when reading the file
(e.g., when first starting Wireshark), rather than waiting until
you try to edit them.
Have that dialog have details of the problem with the filter
instead of a generic message. The report_warning code will
consolidate multiple warnings into one if more than one filter
has an error, rather than have lots of pop-ups.
Since the dialog (or console message, in the unlikely event that
somehow the colorfilters are read in a CLI tool) is called from
the color filters code, get rid of the separate non-specific
pop-up in ColoringRulesDialog and the special preference for
having a bogus filter.
Now, if the user has a bogus filter in the current profile's
colorfilter, they'll get a useful pop-up warning at startup,
when that filter is disabled. For filters imported / copied from
other profiles through the coloring rules dialog, they'll get the
same useful pop-up.
For trying to enable a disabled coloring rules with an error, or
inserting a *new* coloring rule with invalid filter expression (despite
the editor's Red background warning about an invalid expression),
there's already both the hint at the bottom of the screen and the
OK button becomes disabled. (Maybe the hint could be larger or
bold or something when there's an error.)
Fix #14906. Fix #15034
2023-02-25 04:53:31 +00:00
|
|
|
report_warning("Disabling color filter: Could not compile \"%s\" in colorfilters file \"%s\".\n%s", name, path, df_err->msg);
|
2023-04-14 23:18:53 +00:00
|
|
|
df_error_free(&df_err);
|
2013-07-18 04:28:36 +00:00
|
|
|
|
2016-07-25 17:49:30 +00:00
|
|
|
/* skip_end_of_line = TRUE; */
|
|
|
|
disabled = TRUE;
|
2013-02-27 16:15:18 +00:00
|
|
|
}
|
|
|
|
|
2016-01-01 04:14:08 +00:00
|
|
|
fg_color.red = fg_r;
|
|
|
|
fg_color.green = fg_g;
|
|
|
|
fg_color.blue = fg_b;
|
|
|
|
|
|
|
|
bg_color.red = bg_r;
|
|
|
|
bg_color.green = bg_g;
|
|
|
|
bg_color.blue = bg_b;
|
2013-02-27 16:15:18 +00:00
|
|
|
|
|
|
|
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;
|
2013-10-18 15:08:19 +00:00
|
|
|
*cfl = g_slist_append(*cfl, colorf);
|
2013-02-27 16:15:18 +00:00
|
|
|
} else {
|
|
|
|
/* external call */
|
|
|
|
/* just editing, don't need the compiled filter */
|
|
|
|
dfilter_free(temp_dfilter);
|
2015-12-22 20:07:00 +00:00
|
|
|
add_cb(colorf, user_data);
|
2013-02-27 16:15:18 +00:00
|
|
|
}
|
|
|
|
} /* if sscanf */
|
|
|
|
|
|
|
|
skip_end_of_line = TRUE;
|
|
|
|
}
|
|
|
|
|
2016-01-01 04:14:08 +00:00
|
|
|
if (ferror(f))
|
|
|
|
ret = errno;
|
|
|
|
|
2013-02-27 16:15:18 +00:00
|
|
|
g_free(name);
|
|
|
|
g_free(filter_exp);
|
2015-12-22 20:07:00 +00:00
|
|
|
return ret;
|
2003-01-08 01:59:42 +00:00
|
|
|
}
|
2003-08-27 22:55:51 +00:00
|
|
|
|
2003-05-15 07:44:54 +00:00
|
|
|
/* read filters from the filter file */
|
2006-10-03 18:39:36 +00:00
|
|
|
gboolean
|
2016-01-01 04:14:08 +00:00
|
|
|
color_filters_read_globals(gpointer user_data, gchar** err_msg, color_filter_add_cb_func add_cb)
|
2003-05-15 07:44:54 +00:00
|
|
|
{
|
2013-02-27 16:15:18 +00:00
|
|
|
gchar *path;
|
|
|
|
FILE *f;
|
2016-01-01 04:14:08 +00:00
|
|
|
int ret;
|
2013-02-27 16:15:18 +00:00
|
|
|
|
2017-06-09 22:04:32 +00:00
|
|
|
/*
|
|
|
|
* Try to get the global filters.
|
|
|
|
*
|
|
|
|
* Get the path for the file that would have the global filters, and
|
|
|
|
* try to open it.
|
|
|
|
*/
|
2018-10-09 09:46:00 +00:00
|
|
|
path = get_datafile_path(COLORFILTERS_FILE_NAME);
|
2013-02-27 16:15:18 +00:00
|
|
|
if ((f = ws_fopen(path, "r")) == NULL) {
|
|
|
|
if (errno != ENOENT) {
|
2017-06-09 22:04:32 +00:00
|
|
|
/* Error trying to open the file; give up. */
|
2021-12-16 18:06:18 +00:00
|
|
|
*err_msg = ws_strdup_printf("Could not open global filter file\n\"%s\": %s.", path,
|
2017-06-09 22:04:32 +00:00
|
|
|
g_strerror(errno));
|
|
|
|
g_free(path);
|
|
|
|
return FALSE;
|
2013-02-27 16:15:18 +00:00
|
|
|
}
|
2017-06-09 22:04:32 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* There is no global filter file; treat that as equivalent to
|
|
|
|
* that file existing bug being empty, and say we succeeded.
|
|
|
|
*/
|
2018-02-01 22:48:29 +00:00
|
|
|
g_free(path);
|
2017-06-09 22:04:32 +00:00
|
|
|
return TRUE;
|
2013-02-27 16:15:18 +00:00
|
|
|
}
|
|
|
|
|
2016-08-04 01:05:21 +00:00
|
|
|
ret = read_filters_file(path, f, user_data, add_cb);
|
2016-01-01 04:14:08 +00:00
|
|
|
if (ret != 0) {
|
2021-12-16 18:06:18 +00:00
|
|
|
*err_msg = ws_strdup_printf("Error reading global filter file\n\"%s\": %s.",
|
2016-01-01 04:14:08 +00:00
|
|
|
path, g_strerror(errno));
|
|
|
|
fclose(f);
|
2016-08-04 01:05:21 +00:00
|
|
|
g_free(path);
|
2016-01-01 04:14:08 +00:00
|
|
|
return FALSE;
|
|
|
|
}
|
2016-01-01 04:17:39 +00:00
|
|
|
|
2013-02-27 16:15:18 +00:00
|
|
|
fclose(f);
|
2016-08-04 01:05:21 +00:00
|
|
|
g_free(path);
|
2016-01-01 04:14:08 +00:00
|
|
|
return TRUE;
|
2003-05-15 07:44:54 +00:00
|
|
|
}
|
2003-01-08 01:59:42 +00:00
|
|
|
|
2004-09-21 05:17:59 +00:00
|
|
|
/* read filters from some other filter file (import) */
|
2003-08-18 21:27:11 +00:00
|
|
|
gboolean
|
2016-01-05 12:06:36 +00:00
|
|
|
color_filters_import(const gchar *path, gpointer user_data, gchar **err_msg, color_filter_add_cb_func add_cb)
|
2003-08-18 21:27:11 +00:00
|
|
|
{
|
2013-02-27 16:15:18 +00:00
|
|
|
FILE *f;
|
2016-01-01 04:14:08 +00:00
|
|
|
int ret;
|
2003-08-18 21:27:11 +00:00
|
|
|
|
2013-02-27 16:15:18 +00:00
|
|
|
if ((f = ws_fopen(path, "r")) == NULL) {
|
2021-12-16 18:06:18 +00:00
|
|
|
*err_msg = ws_strdup_printf("Could not open filter file\n%s\nfor reading: %s.",
|
2013-02-27 16:15:18 +00:00
|
|
|
path, g_strerror(errno));
|
|
|
|
return FALSE;
|
|
|
|
}
|
2003-08-18 21:27:11 +00:00
|
|
|
|
2016-08-04 01:05:21 +00:00
|
|
|
ret = read_filters_file(path, f, user_data, add_cb);
|
2016-01-01 04:14:08 +00:00
|
|
|
if (ret != 0) {
|
2021-12-16 18:06:18 +00:00
|
|
|
*err_msg = ws_strdup_printf("Error reading filter file\n\"%s\": %s.",
|
2016-01-01 04:14:08 +00:00
|
|
|
path, g_strerror(errno));
|
|
|
|
fclose(f);
|
|
|
|
return FALSE;
|
|
|
|
}
|
2016-01-01 04:17:39 +00:00
|
|
|
|
2013-02-27 16:15:18 +00:00
|
|
|
fclose(f);
|
2016-01-01 04:14:08 +00:00
|
|
|
return TRUE;
|
2003-08-18 21:27:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
struct write_filter_data
|
|
|
|
{
|
2013-02-27 16:15:18 +00:00
|
|
|
FILE *f;
|
|
|
|
gboolean only_selected;
|
2003-08-18 21:27:11 +00:00
|
|
|
};
|
|
|
|
|
2004-09-21 05:17:59 +00:00
|
|
|
/* save a single filter */
|
2003-01-08 01:59:42 +00:00
|
|
|
static void
|
2003-08-18 21:27:11 +00:00
|
|
|
write_filter(gpointer filter_arg, gpointer data_arg)
|
2003-01-08 01:59:42 +00:00
|
|
|
{
|
2013-02-27 16:15:18 +00:00
|
|
|
struct write_filter_data *data = (struct write_filter_data *)data_arg;
|
|
|
|
color_filter_t *colorf = (color_filter_t *)filter_arg;
|
|
|
|
FILE *f = data->f;
|
|
|
|
|
2018-04-16 00:35:42 +00:00
|
|
|
if ( (!data->only_selected) &&
|
2013-02-27 16:15:18 +00:00
|
|
|
(strstr(colorf->filter_name,CONVERSATION_COLOR_PREFIX)==NULL) ) {
|
2015-02-09 18:42:51 +00:00
|
|
|
fprintf(f,"%s@%s@%s@[%u,%u,%u][%u,%u,%u]\n",
|
2013-02-27 16:15:18 +00:00
|
|
|
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);
|
|
|
|
}
|
2003-01-08 01:59:42 +00:00
|
|
|
}
|
|
|
|
|
2003-05-15 07:44:54 +00:00
|
|
|
/* save filters in a filter file */
|
2005-08-14 23:25:20 +00:00
|
|
|
static gboolean
|
2016-01-20 13:24:09 +00:00
|
|
|
write_filters_file(GSList *cfl, FILE *f, gboolean only_selected)
|
2003-05-15 07:44:54 +00:00
|
|
|
{
|
2013-02-27 16:15:18 +00:00
|
|
|
struct write_filter_data data;
|
2003-08-27 22:55:51 +00:00
|
|
|
|
2013-02-27 16:15:18 +00:00
|
|
|
data.f = f;
|
|
|
|
data.only_selected = only_selected;
|
2008-05-22 15:46:27 +00:00
|
|
|
|
2022-04-28 20:41:27 +00:00
|
|
|
fprintf(f,"# This file was created by %s. Edit with care.\n", get_configuration_namespace());
|
2016-01-20 13:24:09 +00:00
|
|
|
g_slist_foreach(cfl, write_filter, &data);
|
2013-02-27 16:15:18 +00:00
|
|
|
return TRUE;
|
2003-05-15 07:44:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* save filters in users filter file */
|
2003-01-08 01:59:42 +00:00
|
|
|
gboolean
|
2015-12-22 20:07:00 +00:00
|
|
|
color_filters_write(GSList *cfl, gchar** err_msg)
|
2003-01-08 01:59:42 +00:00
|
|
|
{
|
2013-02-27 16:15:18 +00:00
|
|
|
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) {
|
2021-12-16 18:06:18 +00:00
|
|
|
*err_msg = ws_strdup_printf("Can't create directory\n\"%s\"\nfor color files: %s.",
|
2013-02-27 16:15:18 +00:00
|
|
|
pf_dir_path, g_strerror(errno));
|
|
|
|
g_free(pf_dir_path);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2018-10-09 09:46:00 +00:00
|
|
|
path = get_persconffile_path(COLORFILTERS_FILE_NAME, TRUE);
|
2013-02-27 16:15:18 +00:00
|
|
|
if ((f = ws_fopen(path, "w+")) == NULL) {
|
2021-12-16 18:06:18 +00:00
|
|
|
*err_msg = ws_strdup_printf("Could not open\n%s\nfor writing: %s.",
|
2013-02-27 16:15:18 +00:00
|
|
|
path, g_strerror(errno));
|
|
|
|
g_free(path);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
g_free(path);
|
|
|
|
write_filters_file(cfl, f, FALSE);
|
|
|
|
fclose(f);
|
|
|
|
return TRUE;
|
2003-05-15 07:44:54 +00:00
|
|
|
}
|
|
|
|
|
2006-10-02 21:55:26 +00:00
|
|
|
/* save filters in some other filter file (export) */
|
|
|
|
gboolean
|
2016-01-20 13:24:09 +00:00
|
|
|
color_filters_export(const gchar *path, GSList *cfl, gboolean only_marked, gchar** err_msg)
|
2006-10-02 21:55:26 +00:00
|
|
|
{
|
2013-02-27 16:15:18 +00:00
|
|
|
FILE *f;
|
2006-10-02 21:55:26 +00:00
|
|
|
|
2013-02-27 16:15:18 +00:00
|
|
|
if ((f = ws_fopen(path, "w+")) == NULL) {
|
2021-12-16 18:06:18 +00:00
|
|
|
*err_msg = ws_strdup_printf("Could not open\n%s\nfor writing: %s.",
|
2013-02-27 16:15:18 +00:00
|
|
|
path, g_strerror(errno));
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
write_filters_file(cfl, f, only_marked);
|
|
|
|
fclose(f);
|
|
|
|
return TRUE;
|
2006-10-02 21:55:26 +00:00
|
|
|
}
|
|
|
|
|
2013-02-27 16:15:18 +00:00
|
|
|
/*
|
2019-07-26 18:43:17 +00:00
|
|
|
* Editor modelines - https://www.wireshark.org/tools/modelines.html
|
2013-02-27 16:15:18 +00:00
|
|
|
*
|
|
|
|
* 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:
|
|
|
|
*/
|