aboutsummaryrefslogtreecommitdiffstats
path: root/filter.c
diff options
context:
space:
mode:
authorGerald Combs <gerald@wireshark.org>1998-09-16 02:39:15 +0000
committerGerald Combs <gerald@wireshark.org>1998-09-16 02:39:15 +0000
commit86534f46e150856fcce76af5c7598d354fb32ca9 (patch)
tree681b71cababcf54c865c4dfa3c52a98b1d793231 /filter.c
Initial revision
svn path=/trunk/; revision=2
Diffstat (limited to 'filter.c')
-rw-r--r--filter.c472
1 files changed, 472 insertions, 0 deletions
diff --git a/filter.c b/filter.c
new file mode 100644
index 0000000000..d3ea96f896
--- /dev/null
+++ b/filter.c
@@ -0,0 +1,472 @@
+/* filter.c
+ * Routines for managing filter sets
+ *
+ * Ethereal - Network traffic analyzer
+ * By Gerald Combs <gerald@zing.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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <gtk/gtk.h>
+
+#include <string.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include "filter.h"
+#include "packet.h"
+#include "file.h"
+#include "menu.h"
+
+extern capture_file cf;
+
+const gchar *fn_key = "filter_name";
+const gchar *fl_key = "filter_label";
+GtkWidget *filter_l, *chg_bt, *copy_bt, *del_bt, *name_te, *filter_te;
+gint in_cancel = FALSE;
+GList *fl = NULL;
+
+GList *
+read_filter_list() {
+ filter_def *filt;
+ FILE *ff;
+ gchar *ff_path, *ff_name = ".ethereal/filters", f_buf[256];
+ gchar *name_begin, *name_end, *filt_begin;
+ int len, line = 0;
+
+ in_cancel = FALSE;
+
+ /* To do: generalize this */
+ ff_path = (gchar *) g_malloc(strlen(getenv("HOME")) + strlen(ff_name) + 4);
+ sprintf(ff_path, "%s/%s", getenv("HOME"), ff_name);
+
+ if ((ff = fopen(ff_path, "r")) == NULL) {
+ g_free(ff_path);
+ return NULL;
+ }
+
+ while (fgets(f_buf, 256, ff)) {
+ line++;
+ len = strlen(f_buf);
+ if (f_buf[len - 1] = '\n') {
+ len--;
+ f_buf[len] = '\0';
+ }
+ name_begin = strchr(f_buf, '"');
+ /* Empty line */
+ if (name_begin == NULL)
+ continue;
+ name_end = strchr(name_begin + 1, '"');
+ /* No terminating quote */
+ if (name_end == NULL) {
+ g_warning("Malformed filter in '%s' line %d.", ff_path, line);
+ continue;
+ }
+ name_begin++;
+ name_end[0] = '\0';
+ filt_begin = name_end + 1;
+ while(isspace(filt_begin[0])) filt_begin++;
+ /* No filter string */
+ if (filt_begin[0] == '\0') {
+ g_warning("Malformed filter in '%s' line %d.", ff_path, line);
+ continue;
+ }
+ filt = (filter_def *) g_malloc(sizeof(filter_def));
+ filt->name = g_strdup(name_begin);
+ filt->strval = g_strdup(filt_begin);
+ fl = g_list_append(fl, filt);
+ }
+ fclose(ff);
+ g_free(ff_path);
+ return fl;
+}
+
+/* filter_sel_cb - Create and display the filter selection dialog. */
+/* Called when the 'Filter' menu item is selected. */
+void
+filter_sel_cb(GtkWidget *w, gpointer d) {
+ GtkWidget *filter_w, *main_vb, *top_hb, *list_bb, *bbox,
+ *new_bt, *ok_bt, *save_bt, *cancel_bt, *filter_sc, *nl_item,
+ *nl_lb, *middle_hb, *name_lb, *bottom_hb, *filter_lb;
+ GtkWidget *l_select = NULL;
+ GList *flp = NULL, *nl = NULL;
+ filter_def *filt;
+
+ fl = read_filter_list();
+
+ filter_w = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+ gtk_window_set_title(GTK_WINDOW(filter_w), "Ethereal: Filters");
+
+ /* Container for each row of widgets */
+ main_vb = gtk_vbox_new(FALSE, 5);
+ gtk_container_border_width(GTK_CONTAINER(main_vb), 5);
+ gtk_container_add(GTK_CONTAINER(filter_w), main_vb);
+ gtk_widget_show(main_vb);
+
+ /* Top row: Filter list and buttons */
+ top_hb = gtk_hbox_new(FALSE, 5);
+ gtk_container_add(GTK_CONTAINER(main_vb), top_hb);
+ gtk_widget_show(top_hb);
+
+ list_bb = gtk_vbutton_box_new();
+ gtk_button_box_set_layout (GTK_BUTTON_BOX (list_bb), GTK_BUTTONBOX_START);
+ gtk_container_add(GTK_CONTAINER(top_hb), list_bb);
+ gtk_widget_show(list_bb);
+
+ new_bt = gtk_button_new_with_label ("New");
+ gtk_signal_connect(GTK_OBJECT(new_bt), "clicked",
+ GTK_SIGNAL_FUNC(filter_sel_new_cb), NULL);
+ gtk_container_add(GTK_CONTAINER(list_bb), new_bt);
+ gtk_widget_show(new_bt);
+
+ chg_bt = gtk_button_new_with_label ("Change");
+ gtk_widget_set_sensitive(chg_bt, FALSE);
+ gtk_signal_connect(GTK_OBJECT(chg_bt), "clicked",
+ GTK_SIGNAL_FUNC(filter_sel_chg_cb), NULL);
+ gtk_container_add(GTK_CONTAINER(list_bb), chg_bt);
+ gtk_widget_show(chg_bt);
+
+ copy_bt = gtk_button_new_with_label ("Copy");
+ gtk_widget_set_sensitive(copy_bt, FALSE);
+ gtk_signal_connect(GTK_OBJECT(copy_bt), "clicked",
+ GTK_SIGNAL_FUNC(filter_sel_copy_cb), NULL);
+ gtk_container_add(GTK_CONTAINER(list_bb), copy_bt);
+ gtk_widget_show(copy_bt);
+
+ del_bt = gtk_button_new_with_label ("Delete");
+ gtk_widget_set_sensitive(del_bt, FALSE);
+ gtk_signal_connect(GTK_OBJECT(del_bt), "clicked",
+ GTK_SIGNAL_FUNC(filter_sel_del_cb), NULL);
+ gtk_container_add(GTK_CONTAINER(list_bb), del_bt);
+ gtk_widget_show(del_bt);
+
+ filter_sc = gtk_scrolled_window_new(NULL, NULL);
+ gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(filter_sc),
+ GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+ gtk_widget_set_usize(filter_sc, 250, 150);
+ gtk_container_add(GTK_CONTAINER(top_hb), filter_sc);
+ gtk_widget_show(filter_sc);
+
+ filter_l = gtk_list_new();
+ gtk_signal_connect(GTK_OBJECT(filter_l), "selection_changed",
+ GTK_SIGNAL_FUNC(filter_sel_list_cb), NULL);
+ gtk_container_add(GTK_CONTAINER(filter_sc), filter_l);
+ gtk_widget_show(filter_l);
+
+ flp = g_list_first(fl);
+ while (flp) {
+ filt = (filter_def *) flp->data;
+ nl_lb = gtk_label_new(filt->name);
+ nl_item = gtk_list_item_new();
+ gtk_misc_set_alignment (GTK_MISC (nl_lb), 0.0, 0.5);
+ gtk_container_add(GTK_CONTAINER(nl_item), nl_lb);
+ gtk_widget_show(nl_lb);
+ gtk_container_add(GTK_CONTAINER(filter_l), nl_item);
+ gtk_widget_show(nl_item);
+ gtk_object_set_data(GTK_OBJECT(nl_item), fl_key, nl_lb);
+ gtk_object_set_data(GTK_OBJECT(nl_item), fn_key, flp);
+ if (cf.filter && filt->strval)
+ if (strcmp(cf.filter, filt->strval) == 0)
+ l_select = nl_item;
+ flp = flp->next;
+ }
+
+ /* Middle row: Filter name entry */
+ middle_hb = gtk_hbox_new(FALSE, 5);
+ gtk_container_add(GTK_CONTAINER(main_vb), middle_hb);
+ gtk_widget_show(middle_hb);
+
+ name_lb = gtk_label_new("Filter name:");
+ gtk_box_pack_start(GTK_BOX(middle_hb), name_lb, FALSE, FALSE, 3);
+ gtk_widget_show(name_lb);
+
+ name_te = gtk_entry_new();
+ gtk_box_pack_start(GTK_BOX(middle_hb), name_te, TRUE, TRUE, 3);
+ gtk_widget_show(name_te);
+
+ /* Bottom row: Filter text entry */
+ bottom_hb = gtk_hbox_new(FALSE, 5);
+ gtk_container_add(GTK_CONTAINER(main_vb), bottom_hb);
+ gtk_widget_show(bottom_hb);
+
+ filter_lb = gtk_label_new("Filter string:");
+ gtk_box_pack_start(GTK_BOX(bottom_hb), filter_lb, FALSE, FALSE, 3);
+ gtk_widget_show(filter_lb);
+
+ filter_te = gtk_entry_new();
+ gtk_box_pack_start(GTK_BOX(bottom_hb), filter_te, TRUE, TRUE, 3);
+ gtk_widget_show(filter_te);
+
+ /* Button row: OK and cancel buttons */
+ bbox = gtk_hbutton_box_new();
+ gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), GTK_BUTTONBOX_END);
+ gtk_container_add(GTK_CONTAINER(main_vb), bbox);
+ gtk_widget_show(bbox);
+
+ ok_bt = gtk_button_new_with_label ("OK");
+ gtk_signal_connect(GTK_OBJECT(ok_bt), "clicked",
+ GTK_SIGNAL_FUNC(filter_sel_ok_cb), (gpointer) filter_w);
+ gtk_container_add(GTK_CONTAINER(bbox), ok_bt);
+ GTK_WIDGET_SET_FLAGS(ok_bt, GTK_CAN_DEFAULT);
+ gtk_widget_grab_default(ok_bt);
+ gtk_widget_show(ok_bt);
+
+ save_bt = gtk_button_new_with_label ("Save");
+ gtk_signal_connect(GTK_OBJECT(save_bt), "clicked",
+ GTK_SIGNAL_FUNC(filter_sel_save_cb), (gpointer) fl);
+ gtk_container_add(GTK_CONTAINER(bbox), save_bt);
+ gtk_widget_show(save_bt);
+
+ cancel_bt = gtk_button_new_with_label ("Cancel");
+ gtk_signal_connect(GTK_OBJECT(cancel_bt), "clicked",
+ GTK_SIGNAL_FUNC(filter_sel_cancel_cb), (gpointer) filter_w);
+ gtk_container_add(GTK_CONTAINER(bbox), cancel_bt);
+ gtk_widget_show(cancel_bt);
+
+ gtk_widget_show(filter_w);
+
+ if (l_select)
+ gtk_list_select_child(GTK_LIST(filter_l), l_select);
+}
+
+void
+filter_sel_list_cb(GtkWidget *l, gpointer data) {
+ filter_def *filt;
+ gchar *name = "", *strval = "";
+ GList *sl, *flp;
+ GtkObject *l_item;
+ gint sensitivity = FALSE;
+
+ sl = GTK_LIST(l)->selection;
+
+ if (sl) { /* Something was selected */
+ l_item = GTK_OBJECT(sl->data);
+ flp = (GList *) gtk_object_get_data(l_item, fn_key);
+ if (flp) {
+ filt = (filter_def *) flp->data;
+ name = filt->name;
+ strval = filt->strval;
+ sensitivity = TRUE;
+ }
+ }
+
+ /* Did you know that this function is called when the window is destroyed? */
+ /* Funny, that. */
+ if (!in_cancel) {
+ gtk_entry_set_text(GTK_ENTRY(name_te), name);
+ gtk_entry_set_text(GTK_ENTRY(filter_te), strval);
+ gtk_widget_set_sensitive(chg_bt, sensitivity);
+ gtk_widget_set_sensitive(copy_bt, sensitivity);
+ gtk_widget_set_sensitive(del_bt, sensitivity);
+ }
+}
+
+/* To do: add input checking to each of these callbacks */
+
+void
+filter_sel_new_cb(GtkWidget *w, gpointer data) {
+ GList *nl = NULL;
+ filter_def *filt;
+ gchar *name, *strval;
+ GtkWidget *nl_item, *nl_lb;
+
+ name = gtk_entry_get_text(GTK_ENTRY(name_te));
+ strval = gtk_entry_get_text(GTK_ENTRY(filter_te));
+
+ if (strlen(name) > 0 && strlen(strval) > 0) {
+ filt = (filter_def *) g_malloc(sizeof(filter_def));
+ filt->name = g_strdup(name);
+ filt->strval = g_strdup(strval);
+ fl = g_list_append(fl, filt);
+ nl_lb = gtk_label_new(filt->name);
+ nl_item = gtk_list_item_new();
+ gtk_misc_set_alignment (GTK_MISC (nl_lb), 0.0, 0.5);
+ gtk_container_add(GTK_CONTAINER(nl_item), nl_lb);
+ gtk_widget_show(nl_lb);
+ gtk_container_add(GTK_CONTAINER(filter_l), nl_item);
+ gtk_widget_show(nl_item);
+ gtk_object_set_data(GTK_OBJECT(nl_item), fl_key, nl_lb);
+ gtk_object_set_data(GTK_OBJECT(nl_item), fn_key, g_list_last(fl));
+ }
+}
+
+void
+filter_sel_chg_cb(GtkWidget *w, gpointer data) {
+ filter_def *filt;
+ gchar *name = "", *strval = "";
+ GList *sl, *flp;
+ GtkObject *l_item;
+ GtkLabel *nl_lb;
+ gint sensitivity = FALSE;
+
+ sl = GTK_LIST(filter_l)->selection;
+ name = gtk_entry_get_text(GTK_ENTRY(name_te));
+ strval = gtk_entry_get_text(GTK_ENTRY(filter_te));
+
+ if (sl) { /* Something was selected */
+ l_item = GTK_OBJECT(sl->data);
+ flp = (GList *) gtk_object_get_data(l_item, fn_key);
+ nl_lb = (GtkLabel *) gtk_object_get_data(l_item, fl_key);
+ if (flp && nl_lb) {
+ filt = (filter_def *) flp->data;
+
+ if (strlen(name) > 0 && strlen(strval) > 0 && filt) {
+ g_free(filt->name);
+ g_free(filt->strval);
+ filt->name = g_strdup(name);
+ filt->strval = g_strdup(strval);
+ gtk_label_set(nl_lb, filt->name);
+ }
+ }
+ }
+}
+
+void
+filter_sel_copy_cb(GtkWidget *w, gpointer data) {
+ GList *nl = NULL, *sl, *flp;
+ filter_def *filt, *nfilt;
+ gchar *name, *strval, *prefix = "Copy of ";
+ GtkObject *l_item;
+ GtkWidget *nl_item, *nl_lb;
+
+ sl = GTK_LIST(filter_l)->selection;
+ if (sl) { /* Something was selected */
+ l_item = GTK_OBJECT(sl->data);
+ flp = (GList *) gtk_object_get_data(l_item, fn_key);
+ if (flp) {
+ filt = (filter_def *) flp->data;
+ nfilt = (filter_def *) g_malloc(sizeof(filter_def));
+ nfilt->name = g_malloc(strlen(prefix) + strlen(filt->name) + 1);
+ sprintf(nfilt->name, "%s%s", prefix, filt->name);
+ nfilt->strval = g_strdup(filt->strval);
+ fl = g_list_append(fl, nfilt);
+ nl_lb = gtk_label_new(nfilt->name);
+ nl_item = gtk_list_item_new();
+ gtk_misc_set_alignment (GTK_MISC (nl_lb), 0.0, 0.5);
+ gtk_container_add(GTK_CONTAINER(nl_item), nl_lb);
+ gtk_widget_show(nl_lb);
+ gtk_container_add(GTK_CONTAINER(filter_l), nl_item);
+ gtk_widget_show(nl_item);
+ gtk_object_set_data(GTK_OBJECT(nl_item), fl_key, nl_lb);
+ gtk_object_set_data(GTK_OBJECT(nl_item), fn_key, g_list_last(fl));
+ }
+ }
+}
+
+void
+filter_sel_del_cb(GtkWidget *w, gpointer data) {
+ GList *sl, *flp;
+ filter_def *filt;
+ GtkObject *l_item;
+ GtkWidget *nl_item;
+ gint pos;
+
+ sl = GTK_LIST(filter_l)->selection;
+ if (sl) { /* Something was selected */
+ l_item = GTK_OBJECT(sl->data);
+ pos = gtk_list_child_position(GTK_LIST(filter_l),
+ GTK_WIDGET(l_item));
+ flp = (GList *) gtk_object_get_data(l_item, fn_key);
+ if (flp) {
+ filt = (filter_def *) flp->data;
+ g_free(filt->name);
+ g_free(filt->strval);
+ g_free(filt);
+ fl = g_list_remove_link(fl, flp);
+ gtk_list_clear_items(GTK_LIST(filter_l), pos, pos + 1);
+ }
+ }
+}
+
+void
+filter_sel_ok_cb(GtkWidget *w, gpointer data) {
+ GList *flp, *sl;
+ GtkObject *l_item;
+ filter_def *filt;
+
+ if (cf.filter) {
+ g_free(cf.filter);
+ cf.filter = NULL;
+ }
+
+ sl = GTK_LIST(filter_l)->selection;
+ if (sl) { /* Something was selected */
+ l_item = GTK_OBJECT(sl->data);
+ flp = (GList *) gtk_object_get_data(l_item, fn_key);
+ if (flp) {
+ filt = (filter_def *) flp->data;
+ cf.filter = g_strdup(filt->strval);
+ }
+ }
+
+ filter_sel_cancel_cb(w, data);
+}
+
+void
+filter_sel_save_cb(GtkWidget *w, gpointer data) {
+ GList *flp;
+ filter_def *filt;
+ gchar *ff_path, *ff_dir = ".ethereal", *ff_name = "filters";
+ FILE *ff;
+ struct stat s_buf;
+
+ ff_path = (gchar *) g_malloc(strlen(getenv("HOME")) + strlen(ff_dir) +
+ strlen(ff_name) + 4);
+ sprintf(ff_path, "%s/%s", getenv("HOME"), ff_dir);
+
+ if (stat(ff_path, &s_buf) != 0)
+ mkdir(ff_path, 0755);
+
+ sprintf(ff_path, "%s/%s/%s", getenv("HOME"), ff_dir, ff_name);
+
+ if ((ff = fopen(ff_path, "w")) != NULL) {
+ flp = g_list_first(fl);
+ while (flp) {
+ filt = (filter_def *) flp->data;
+ fprintf(ff, "\"%s\" %s\n", filt->name, filt->strval);
+ flp = flp->next;
+ }
+ fclose(ff);
+ }
+
+ g_free(ff_path);
+}
+
+void
+filter_sel_cancel_cb(GtkWidget *w, gpointer win) {
+ filter_def *filt;
+ GList *sl;
+
+ while (fl) {
+ if (fl->data) {
+ filt = (filter_def *) fl->data;
+ g_free(filt->name);
+ g_free(filt->strval);
+ g_free(filt);
+ }
+ fl = g_list_remove_link(fl, fl);
+ }
+
+ /* Let the list cb know we're about to destroy the widget tree, so it */
+ /* doesn't operate on widgets that don't exist. */
+ in_cancel = TRUE;
+ gtk_widget_destroy(GTK_WIDGET(win));
+}