summaryrefslogtreecommitdiff
path: root/ui/recent.c
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2013-07-27 22:37:26 +0000
committerGuy Harris <guy@alum.mit.edu>2013-07-27 22:37:26 +0000
commit210507cc7660b108f991382f44a45d63a225d754 (patch)
tree78746f785a24c5bd6faa48f14f1653d41f8d44e9 /ui/recent.c
parent3663498a8b39f4159ca90eaee2fbc915df27712a (diff)
downloadwireshark-210507cc7660b108f991382f44a45d63a225d754.tar.gz
Have separate lists of recent capture filters for all interfaces, in
addition to a "global" list. Store all of those lists in the recent file. Maintain the lists in ui/recent.c, rather than attaching them to widgets; have the code that populates the combo boxes get the lists from the ui/recent.c code. This makes a little more of the code GUI-toolkit-independent, and should fix bug 7278. #BACKPORT 1.10, 1.8 svn path=/trunk/; revision=50956
Diffstat (limited to 'ui/recent.c')
-rw-r--r--ui/recent.c130
1 files changed, 127 insertions, 3 deletions
diff --git a/ui/recent.c b/ui/recent.c
index c739397144..e5a14fcaad 100644
--- a/ui/recent.c
+++ b/ui/recent.c
@@ -283,6 +283,127 @@ window_geom_recent_write_all(FILE *rf)
g_hash_table_foreach(window_geom_hash, write_recent_geom, rf);
}
+/* Global list of recent capture filters. */
+static GList *recent_cfilter_list;
+
+/*
+ * Per-interface lists of recent capture filters; stored in a hash
+ * table indexed by interface name.
+ */
+static GHashTable *per_interface_cfilter_lists_hash;
+
+/* XXX: use a preference for this setting! */
+static guint cfilter_combo_max_recent = 20;
+
+/**
+ * Returns a list of recent capture filters.
+ *
+ * @param ifname interface name; NULL refers to the global list.
+ */
+GList *
+recent_get_cfilter_list(const gchar *ifname)
+{
+ if (ifname == NULL)
+ return recent_cfilter_list;
+ if (per_interface_cfilter_lists_hash == NULL) {
+ /* No such lists exist. */
+ return NULL;
+ }
+ return (GList *)g_hash_table_lookup(per_interface_cfilter_lists_hash, ifname);
+}
+
+/**
+ * Add a capture filter to the global recent capture filter list or
+ * the recent capture filter list for an interface.
+ *
+ * @param ifname interface name; NULL refers to the global list.
+ * @param s text of capture filter
+ */
+void
+recent_add_cfilter(const gchar *ifname, const gchar *s)
+{
+ GList *cfilter_list;
+ GList *li;
+ gchar *li_filter, *newfilter = NULL;
+
+ /* Don't add empty filters to the list. */
+ if (s[0] == '\0')
+ return;
+
+ if (ifname == NULL)
+ cfilter_list = recent_cfilter_list;
+ else {
+ if (per_interface_cfilter_lists_hash == NULL)
+ per_interface_cfilter_lists_hash = g_hash_table_new(g_str_hash, g_str_equal);
+ cfilter_list = (GList *)g_hash_table_lookup(per_interface_cfilter_lists_hash, ifname);
+ }
+
+ li = g_list_first(cfilter_list);
+ while (li) {
+ /* If the filter is already in the list, remove the old one and
+ * append the new one at the latest position (at g_list_append() below) */
+ li_filter = (char *)li->data;
+ if (strcmp(s, li_filter) == 0) {
+ /* No need to copy the string, we're just moving it. */
+ newfilter = li_filter;
+ recent_cfilter_list = g_list_remove(cfilter_list, li->data);
+ break;
+ }
+ li = li->next;
+ }
+ if (newfilter == NULL) {
+ /* The filter wasn't already in the list; make a copy to add. */
+ newfilter = g_strdup(s);
+ }
+ cfilter_list = g_list_append(cfilter_list, newfilter);
+
+ if (ifname == NULL)
+ recent_cfilter_list = cfilter_list;
+ else
+ g_hash_table_insert(per_interface_cfilter_lists_hash, g_strdup(ifname), cfilter_list);
+}
+
+static void
+cfilter_recent_write_all_list(FILE *rf, const gchar *ifname, GList *cfilter_list)
+{
+ guint max_count = 0;
+ GList *li;
+
+ /* write all non empty capture filter strings to the recent file (until max count) */
+ li = g_list_first(cfilter_list);
+ while (li && (max_count++ <= cfilter_combo_max_recent) ) {
+ if (li->data && strlen((const char *)li->data)) {
+ if (ifname == NULL)
+ fprintf (rf, RECENT_KEY_CAPTURE_FILTER ": %s\n", (char *)li->data);
+ else
+ fprintf (rf, RECENT_KEY_CAPTURE_FILTER ".%s: %s\n", ifname, (char *)li->data);
+ }
+ li = li->next;
+ }
+}
+
+static void
+cfilter_recent_write_all_hash_callback(gpointer key, gpointer value, gpointer user_data)
+{
+ cfilter_recent_write_all_list((FILE *)user_data, (const gchar *)key, (GList *)value);
+}
+
+/** Write all capture filter values to the recent file.
+ *
+ * @param rf recent file handle from caller
+ */
+static void
+cfilter_recent_write_all(FILE *rf)
+{
+ /* Write out the global list. */
+ cfilter_recent_write_all_list(rf, NULL, recent_cfilter_list);
+
+ /* Write out all the per-interface lists. */
+ if (per_interface_cfilter_lists_hash != NULL) {
+ g_hash_table_foreach(per_interface_cfilter_lists_hash, cfilter_recent_write_all_hash_callback, (gpointer)rf);
+ }
+}
+
/* Attempt to Write out "recent common" to the user's recent common file.
If we got an error report it with a dialog box and return FALSE,
otherwise return TRUE. */
@@ -333,7 +454,7 @@ write_recent(void)
"######## Recent capture filters (latest last), cannot be altered through command line ########\n"
"\n", rf);
- cfilter_combo_recent_write_all(rf);
+ cfilter_recent_write_all(rf);
fputs("\n"
"######## Recent display filters (latest last), cannot be altered through command line ########\n"
@@ -866,14 +987,17 @@ read_set_recent_pair_dynamic(gchar *key, const gchar *value,
return PREFS_SET_SYNTAX_ERR;
}
if (strcmp(key, RECENT_KEY_CAPTURE_FILE) == 0) {
- if(u3_active())
+ if (u3_active())
add_menu_recent_capture_file(u3_expand_device_path(value));
else
add_menu_recent_capture_file(value);
} else if (strcmp(key, RECENT_KEY_DISPLAY_FILTER) == 0) {
dfilter_combo_add_recent(value);
} else if (strcmp(key, RECENT_KEY_CAPTURE_FILTER) == 0) {
- cfilter_combo_add_recent(value);
+ recent_add_cfilter(NULL, value);
+ } else if (g_str_has_prefix(key, RECENT_KEY_CAPTURE_FILTER ".")) {
+ /* strrchr() can't fail - string has a prefix that ends with a "." */
+ recent_add_cfilter(strrchr(key, '.') + 1, value);
#ifdef HAVE_PCAP_REMOTE
} else if (strcmp(key, RECENT_KEY_REMOTE_HOST) == 0) {
capture_remote_combo_add_recent(value);