from Thomas Palmer: add a combobox for the recently used capture filter strings
authorulfl <ulfl@f5534014-38df-0310-8fa8-9805f1628bb7>
Tue, 28 Sep 2004 18:04:15 +0000 (18:04 +0000)
committerulfl <ulfl@f5534014-38df-0310-8fa8-9805f1628bb7>
Tue, 28 Sep 2004 18:04:15 +0000 (18:04 +0000)
git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@12123 f5534014-38df-0310-8fa8-9805f1628bb7

gtk/Makefile.common
gtk/capture_dlg.c
gtk/cfilter_combo_utils.c [new file with mode: 0644]
gtk/cfilter_combo_utils.h [new file with mode: 0644]
gtk/recent.c

index 6bc2a1d8cc27ccb1c8715d34d55c0f077d2f8bb2..53b2215873f5fb27321fa42ffa12f036be3203d6 100644 (file)
@@ -34,6 +34,7 @@ ETHEREAL_GTK_SRC = \
        capture_if_dlg.c        \
        capture_info_dlg.c      \
        capture_prefs.c \
+       cfilter_combo_utils.c   \
        color_dlg.c     \
        color_utils.c   \
        colors.c        \
index 3f5150a0f9bffe7b577e8ecfc2291a2dcbf201ca..94a4d4dc53605f92331be842fc92623f1a298f24 100644 (file)
@@ -51,6 +51,7 @@
 #include "file_dlg.h"
 #include "help_dlg.h"
 #include "gtkglobals.h"
+#include "cfilter_combo_utils.h"
 
 #ifdef _WIN32
 #include "capture-wpcap.h"
@@ -488,7 +489,7 @@ capture_prep(void)
                 *linktype_hb, *linktype_lb, *linktype_om,
                 *snap_hb, *snap_cb, *snap_sb, *snap_lb,
                 *promisc_cb,
-                *filter_hb, *filter_bt, *filter_te,
+                *filter_hb, *filter_bt, *filter_te, *filter_cm,
 
                 *file_fr, *file_vb,
                 *file_hb, *file_bt, *file_lb, *file_te,
@@ -516,7 +517,7 @@ capture_prep(void)
   GtkTooltips   *tooltips;
   GtkAdjustment *snap_adj, *ringbuffer_nbf_adj,
                *stop_packets_adj, *stop_filesize_adj, *stop_duration_adj, *stop_files_adj, *ring_filesize_adj, *file_duration_adj;
-  GList         *if_list, *combo_list;
+  GList         *if_list, *combo_list, *filter_list;
   int           err;
   int           row;
   char          err_str[PCAP_ERRBUF_SIZE];
@@ -725,15 +726,24 @@ capture_prep(void)
     NULL);
   gtk_box_pack_start(GTK_BOX(filter_hb), filter_bt, FALSE, FALSE, 3);
 
-  filter_te = gtk_entry_new();
-  if (cfile.cfilter) gtk_entry_set_text(GTK_ENTRY(filter_te), cfile.cfilter);
-  OBJECT_SET_DATA(filter_bt, E_FILT_TE_PTR_KEY, filter_te);
+  /* Create the capture filter combo */
+  filter_cm = gtk_combo_new();
+
+  filter_list = OBJECT_GET_DATA(top_level, E_CFILTER_FL_KEY);
+  gtk_combo_disable_activate(GTK_COMBO(filter_cm));
+  gtk_combo_set_case_sensitive(GTK_COMBO(filter_cm), TRUE);
+  OBJECT_SET_DATA(top_level, E_CFILTER_FL_KEY, filter_list);
+  OBJECT_SET_DATA(top_level, E_CFILTER_CM_KEY, filter_cm);
+  filter_te = GTK_COMBO(filter_cm)->entry;
+
+  gtk_combo_set_popdown_strings(GTK_COMBO(filter_cm), filter_list);
+  gtk_entry_set_text(GTK_ENTRY(filter_te), ""); /* Default capture filter is empty */
   gtk_tooltips_set_tip(tooltips, filter_te,
     "Enter a capture filter to reduce the amount of packets to be captured. "
     "See \"Capture Filters\" in the online help for further information how to use it.",
     NULL);
-  gtk_box_pack_start(GTK_BOX(filter_hb), filter_te, TRUE, TRUE, 3);
-
+  WIDGET_SET_SIZE(filter_cm, 400, -1);
+  gtk_box_pack_start(GTK_BOX(filter_hb), filter_cm, FALSE, FALSE, 3);
   main_hb = gtk_hbox_new(FALSE, 5);
   gtk_container_border_width(GTK_CONTAINER(main_hb), 0);
   gtk_container_add(GTK_CONTAINER(main_vb), main_hb);
@@ -1208,7 +1218,7 @@ capture_prep_file_cb(GtkWidget *file_bt, GtkWidget *file_te)
 
 static void
 capture_prep_ok_cb(GtkWidget *ok_bt _U_, gpointer parent_w) {
-  GtkWidget *if_cb, *snap_cb, *snap_sb, *promisc_cb, *filter_te,
+  GtkWidget *if_cb, *snap_cb, *snap_sb, *promisc_cb, *filter_te, *filter_cm,
             *file_te, *multi_files_on_cb, *ringbuffer_nbf_sb, *ringbuffer_nbf_cb,
             *linktype_om, *sync_cb, *auto_scroll_cb, *hide_info_cb,
             *stop_packets_cb, *stop_packets_sb,
@@ -1239,7 +1249,8 @@ capture_prep_ok_cb(GtkWidget *ok_bt _U_, gpointer parent_w) {
   buffer_size_sb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_BUFFER_SIZE_SB_KEY);
 #endif
   promisc_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_PROMISC_KEY);
-  filter_te = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_FILT_KEY);
+  filter_cm = OBJECT_GET_DATA(top_level, E_CFILTER_CM_KEY);
+  filter_te = GTK_COMBO(filter_cm)->entry;
   file_te   = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_FILE_TE_KEY);
   multi_files_on_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_MULTI_FILES_ON_CB_KEY);
   ringbuffer_nbf_cb = (GtkWidget *) OBJECT_GET_DATA(parent_w, E_CAP_RING_NBF_CB_KEY);
@@ -1282,6 +1293,10 @@ capture_prep_ok_cb(GtkWidget *ok_bt _U_, gpointer parent_w) {
   cfile.iface = g_strdup(if_name);
   g_free(entry_text);
 
+  /* Add this capture filter to the recent capture filter list if it passes a syntax check */
+  if(check_capture_filter_syntax(cfile.iface, (gchar *) gtk_entry_get_text(GTK_ENTRY(filter_te))))
+    cfilter_combo_add_recent((gchar *) gtk_entry_get_text(GTK_ENTRY(filter_te)));
+
   capture_opts.linktype =
       GPOINTER_TO_INT(OBJECT_GET_DATA(linktype_om, E_CAP_OM_LT_VALUE_KEY));
 
diff --git a/gtk/cfilter_combo_utils.c b/gtk/cfilter_combo_utils.c
new file mode 100644 (file)
index 0000000..fe10194
--- /dev/null
@@ -0,0 +1,107 @@
+/* cfilter_combo_utils.c\r
+ * Capture filter combo box routines\r
+ *\r
+ * $Id: cfilter_combo_utils.c 12115 2004-09-27 22:55:15Z guy $\r
+ *\r
+ * Ethereal - Network traffic analyzer\r
+ * By Gerald Combs <gerald@ethereal.com>\r
+ * Copyright 1998 Gerald Combs\r
+ *\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+ *\r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.\r
+ */\r
+\r
+#include <gtk/gtk.h>\r
+#include "compat_macros.h"\r
+#include "main.h"\r
+#include "gtkglobals.h"\r
+#include "cfilter_combo_utils.h"\r
+#include "recent.h"\r
+#ifdef HAVE_LIBPCAP\r
+#include <pcap.h>\r
+#endif\r
+\r
+/* XXX: use a preference for this setting! */\r
+static guint cfilter_combo_max_recent = 20;\r
+\r
+gboolean\r
+cfilter_combo_add(gchar *s) {\r
+  GList     *li;\r
+  GList     *fl = OBJECT_GET_DATA(top_level, E_CFILTER_FL_KEY);\r
+\r
+  li = g_list_first(fl);\r
+  while (li) {\r
+    /* If the filter is already in the list, remove the old one and\r
+     * append the new one at the latest position (at g_list_append() below) */\r
+    if (li->data && strcmp(s, li->data) == 0) {\r
+      fl = g_list_remove(fl, li->data);\r
+      break;\r
+    }\r
+    li = li->next;\r
+  }\r
+  fl = g_list_append(fl, s);\r
+  OBJECT_SET_DATA(top_level, E_CFILTER_FL_KEY, fl);\r
+  return TRUE;\r
+}\r
+\r
+\r
+/* write all non empty capture filters (until maximum count)\r
+ * of the combo box GList to the user's recent file */\r
+void\r
+ cfilter_combo_recent_write_all(FILE *rf) {\r
+   GList     *filter_list = OBJECT_GET_DATA(top_level, E_CFILTER_FL_KEY);\r
+   GList     *li;\r
+   guint      max_count = 0;\r
+\r
+   /* write all non empty display filter strings to the recent file (until max count) */\r
+   li = g_list_first(filter_list);\r
+   while ( li && (max_count++ <= cfilter_combo_max_recent) ) {\r
+     if (strlen(li->data)) {\r
+       fprintf (rf, RECENT_KEY_CAPTURE_FILTER ": %s\n", (char *)li->data);\r
+     }\r
+     li = li->next;\r
+   }\r
+}\r
+\r
+/* add a capture filter coming from the user's recent file to the cfilter combo box */\r
+gboolean\r
+ cfilter_combo_add_recent(gchar *s) {\r
+   gchar *dup;\r
+\r
+   dup = g_strdup(s);\r
+   if (!cfilter_combo_add(dup)) {\r
+     g_free(dup);\r
+     return FALSE;\r
+   }\r
+   return TRUE;\r
+}\r
+\r
+gboolean check_capture_filter_syntax(gchar *interface_name, gchar *filter_str){\r
+  struct bpf_program fcode;\r
+  gchar       open_err_str[PCAP_ERRBUF_SIZE];\r
+  pcap_t     *pch;\r
+  int        status=0;\r
+\r
+  open_err_str[0] = '\0';\r
+  pch = pcap_open_live(interface_name, WTAP_MAX_PACKET_SIZE, 0, 250, open_err_str);\r
+  status = pcap_compile(pch, &fcode, filter_str, 1, 0);\r
+  pcap_close(pch);\r
+\r
+  if (status < 0){\r
+    return FALSE;\r
+  }\r
+  else{\r
+    return TRUE;\r
+  }\r
+}\r
diff --git a/gtk/cfilter_combo_utils.h b/gtk/cfilter_combo_utils.h
new file mode 100644 (file)
index 0000000..1a4560c
--- /dev/null
@@ -0,0 +1,36 @@
+/* cfilter_combo_utils.h\r
+ * Capture filter combo box routines\r
+ *\r
+ * $Id: cfilter_combo_utils.h 12115 2004-09-27 22:55:15Z guy $\r
+ *\r
+ * Ethereal - Network traffic analyzer\r
+ * By Gerald Combs <gerald@ethereal.com>\r
+ * Copyright 1998 Gerald Combs\r
+ *\r
+ * This program is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License\r
+ * as published by the Free Software Foundation; either version 2\r
+ * of the License, or (at your option) any later version.\r
+ *\r
+ * This program is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program; if not, write to the Free Software\r
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.\r
+ */\r
+\r
+extern void cfilter_combo_recent_write_all(FILE *rf);\r
+extern gboolean cfilter_combo_add_recent(gchar *s);\r
+/** Check the syntax of a capture filter string. This is done by calling pcap_open_live().\r
+ *\r
+ * @param interface_name The interface name to be opened by pcap_open_live().\r
+ * @param filter_str The filter string to be verified.\r
+ */\r
+extern gboolean check_capture_filter_syntax(gchar *interface_name, gchar *filter_str);\r
+\r
+#define E_CFILTER_CM_KEY          "capture_filter_combo"\r
+#define E_CFILTER_FL_KEY          "capture_filter_list"\r
+#define RECENT_KEY_CAPTURE_FILTER "recent.capture_filter"
\ No newline at end of file
index de198e8a6f1d3248481079422d6059d93f0a426f..544b4c449f844b62a0aadfda26280b467f580aa9 100644 (file)
@@ -40,7 +40,7 @@
 #include "prefs-int.h"
 #include "ui_util.h"
 #include "dlg_utils.h"
-
+#include "cfilter_combo_utils.h"
 
 #define RECENT_KEY_MAIN_TOOLBAR_SHOW        "gui.toolbar_main_show"
 #define RECENT_KEY_FILTER_TOOLBAR_SHOW      "gui.filter_toolbar_show"
@@ -122,6 +122,12 @@ write_recent(char **rf_path_return)
 
   menu_recent_file_write_all(rf);
 
+  fputs("\n"
+    "######## Recent capture filters (latest last) ########\n"
+    "\n", rf);
+
+  cfilter_combo_recent_write_all(rf);
+
   fputs("\n"
     "######## Recent display filters (latest last) ########\n"
     "\n", rf);
@@ -247,6 +253,8 @@ read_set_recent_pair(gchar *key, gchar *value)
        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);
   } else if (strcmp(key, RECENT_KEY_MAIN_TOOLBAR_SHOW) == 0) {
     if (strcasecmp(value, "true") == 0) {
         recent.main_toolbar_show = TRUE;