PERFORCE change 138490 for review
dongmei
dongmei at FreeBSD.org
Tue Mar 25 03:17:19 UTC 2008
http://perforce.freebsd.org/chv.cgi?CH=138490
Change 138490 by dongmei at dongmei-soc2007-home on 2008/03/25 03:16:19
add find mechanism
Affected files ...
.. //depot/projects/soc2007/dongmei-auditanalyzer/eng/emem.c#1 add
.. //depot/projects/soc2007/dongmei-auditanalyzer/eng/emem.h#1 add
.. //depot/projects/soc2007/dongmei-auditanalyzer/eng/gnuc_format_check.h#1 add
.. //depot/projects/soc2007/dongmei-auditanalyzer/eng/strutil.c#1 add
.. //depot/projects/soc2007/dongmei-auditanalyzer/eng/strutil.h#1 add
.. //depot/projects/soc2007/dongmei-auditanalyzer/gtk/compat_macros.h#5 edit
.. //depot/projects/soc2007/dongmei-auditanalyzer/gtk/find_dlg.c#1 add
.. //depot/projects/soc2007/dongmei-auditanalyzer/gtk/find_dlg.h#1 add
.. //depot/projects/soc2007/dongmei-auditanalyzer/gtk/gui_utils.c#2 edit
.. //depot/projects/soc2007/dongmei-auditanalyzer/gtk/gui_utils.h#2 edit
.. //depot/projects/soc2007/dongmei-auditanalyzer/gtk/menu.c#5 edit
.. //depot/projects/soc2007/dongmei-auditanalyzer/gtk/menu.h#4 edit
.. //depot/projects/soc2007/dongmei-auditanalyzer/gtk/progress_dlg.h#1 add
.. //depot/projects/soc2007/dongmei-auditanalyzer/gtk/simple_dialog.c#4 edit
.. //depot/projects/soc2007/dongmei-auditanalyzer/gtk/simple_dialog.h#2 edit
.. //depot/projects/soc2007/dongmei-auditanalyzer/tfile.c#8 edit
.. //depot/projects/soc2007/dongmei-auditanalyzer/tfile.h#4 edit
Differences ...
==== //depot/projects/soc2007/dongmei-auditanalyzer/gtk/compat_macros.h#5 (text+ko) ====
@@ -25,10 +25,10 @@
* @param arg value to pass to your function
* @return the connection id
*/
-#define SIGNAL_CONNECT(widget, name, callback, arg) \
+/*#define SIGNAL_CONNECT(widget, name, callback, arg) \
gtk_signal_connect(GTK_OBJECT(widget), name, GTK_SIGNAL_FUNC(callback), \
(gpointer)(arg))
-
+*/
/** This function is for registering a callback that will call another object's callback.
* That is, instead of passing the object which is responsible for the event as the first
* parameter of the callback, it is switched with the user data (so the object which emits
==== //depot/projects/soc2007/dongmei-auditanalyzer/gtk/gui_utils.c#2 (text+ko) ====
@@ -1,5 +1,11 @@
#include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h>
+#include "gui_utils.h"
+
+#define WINDOW_GEOM_KEY "window_geom"
+
+static void
+dlg_activate (GtkWidget *widget, gpointer ok_button);
/* exit the main window */
void main_window_exit(void)
@@ -40,4 +46,159 @@
return FALSE;
}
+/* Set the "key_press_event" signal for a top-level dialog window to
+ call a routine to activate the "Cancel" button for a dialog box if
+ the key being pressed is the <Esc> key.
+
+ XXX - there should be a GTK+ widget that'll do that for you, and
+ let you specify a "Cancel" button. It should also not impose
+ a requirement that there be a separator in the dialog box, as
+ the GtkDialog widget does; the visual convention that there's
+ such a separator between the rest of the dialog boxes and buttons
+ such as "OK" and "Cancel" is, for better or worse, not universal
+ (not even in GTK+ - look at the GtkFileSelection dialog!). */
+static void
+window_set_cancel(GtkWidget *widget, GtkWidget *cancel_button)
+{
+ SIGNAL_CONNECT(widget, "key_press_event", window_key_press_cb, cancel_button);
+}
+
+/* set the actions needed for the cancel "Close"/"Ok"/"Cancel" button that closes the window */
+void window_set_cancel_button(GtkWidget *win, GtkWidget *bt, window_cancel_button_fct cb)
+{
+ if(cb)
+ SIGNAL_CONNECT(bt, "clicked", cb, win);
+
+ gtk_widget_grab_default(bt);
+
+ window_set_cancel(win, bt);
+}
+/* default callback handler for cancel button "clicked" signal */
+void window_cancel_button_cb(GtkWidget *w _U_, gpointer data)
+{
+ window_destroy(GTK_WIDGET(data));
+}
+/* default callback handler: the window managers X of the window was clicked (delete_event) */
+gboolean
+window_delete_event_cb(GtkWidget *win, GdkEvent *event _U_, gpointer user_data _U_)
+{
+ window_destroy(win);
+
+ /* event handled, don't do anything else */
+ return TRUE;
+}
+/* Set the "activate" signal for a widget to call a routine to
+ activate the "OK" button for a dialog box.
+
+ XXX - there should be a way to specify that a GtkEntry widget
+ shouldn't itself handle the Return key, but should let it be
+ passed on to the parent, so that you don't have to do this
+ by hand for every GtkEntry widget in a dialog box, but, alas,
+ there isn't. (Does this problem exist for other widgets?
+ I.e., are there any others that seize the Return key? */
+void
+dlg_set_activate(GtkWidget *widget, GtkWidget *ok_button)
+{
+ SIGNAL_CONNECT(widget, "activate", dlg_activate, ok_button);
+}
+
+static void
+dlg_activate (GtkWidget *widget _U_, gpointer ok_button)
+{
+ gtk_widget_activate(GTK_WIDGET(ok_button));
+}
+/* set the geometry of a window from window_new() */
+void
+window_set_geometry(GtkWidget *widget, window_geometry_t *geom)
+{
+ /* as we now have the geometry from the recent file, set it */
+ /* if the window was minimized, x and y are -32000 (at least on Win32) */
+ if (geom->set_pos && geom->x != -32000 && geom->y != -32000) {
+#if GTK_MAJOR_VERSION >= 2
+ gtk_window_move(GTK_WINDOW(widget),
+ geom->x,
+ geom->y);
+#else
+ gtk_widget_set_uposition(widget,
+ geom->x,
+ geom->y);
+#endif
+ }
+
+ if (geom->set_size) {
+#if GTK_MAJOR_VERSION >= 2
+ gtk_window_resize(GTK_WINDOW(widget),
+#else
+ gtk_window_set_default_size(GTK_WINDOW(widget),
+ geom->width,
+ geom->height);
+ gtk_widget_set_usize(widget,
+#endif
+ /*WIDGET_SET_SIZE(widget,*/
+ geom->width,
+ geom->height);
+ }
+
+#if GTK_MAJOR_VERSION >= 2
+ if(geom->set_maximized) {
+ if (geom->maximized) {
+ gdk_window_maximize(widget->window);
+ } else {
+ gdk_window_unmaximize(widget->window);
+ }
+ }
+#endif
+}
+
+
+
+/* the geometry hashtable for all known window classes,
+ * the window name is the key, and the geometry struct is the value */
+GHashTable *window_geom_hash = NULL;
+
+/* load the desired geometry for this window from the geometry hashtable */
+static gboolean
+window_geom_load(const gchar *name, window_geometry_t *geom)
+{
+ window_geometry_t *p;
+
+ /* init hashtable, if not already done */
+ if(!window_geom_hash) {
+ window_geom_hash = g_hash_table_new (g_str_hash, g_str_equal);
+ }
+
+ p = g_hash_table_lookup(window_geom_hash, name);
+ if(p) {
+ *geom = *p;
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+}
+
+
+/* Present the created window on the screen. */
+void
+window_present(GtkWidget *win)
+{
+ window_geometry_t geom;
+ const gchar *name;
+
+#if GTK_MAJOR_VERSION >= 2
+ /* present this window */
+ gtk_window_present(GTK_WINDOW(win));
+#endif
+
+ /* do we have a previously saved size and position of this window? */
+ name = OBJECT_GET_DATA(win, WINDOW_GEOM_KEY);
+ if(name) {
+ if(window_geom_load(name, &geom)) {
+ /* XXX - use prefs to select which values to set? */
+ geom.set_pos = TRUE;
+ geom.set_size = TRUE;
+ geom.set_maximized = TRUE;
+ window_set_geometry(win, &geom);
+ }
+ }
+}
==== //depot/projects/soc2007/dongmei-auditanalyzer/gtk/gui_utils.h#2 (text+ko) ====
@@ -1,7 +1,26 @@
#include <gtk/gtk.h>
+#include "compat_macros.h"
+/** geometry values for use in window_get_geometry() and window_set_geometry() */
+typedef struct window_geometry_s {
+ gchar *key; /**< current key in hashtable (internally used only) */
+ gboolean set_pos; /**< set the x and y position values */
+ gint x; /**< the windows x position */
+ gint y; /**< the windows y position */
+ gboolean set_size; /**< set the width and height values */
+ gint width; /**< the windows width */
+ gint height; /**< the windows height */
+
+ gboolean set_maximized; /**< set the maximized state (GTK2 only) */
+ gboolean maximized; /**< the windows maximized state (GTK2 only) */
+} window_geometry_t;
+
typedef void (*window_cancel_button_fct) (GtkWidget *w, gpointer data);
void main_window_exit(void);
void main_window_quit(void);
void window_destroy(GtkWidget *win);
gint window_key_press_cb (GtkWidget *widget, GdkEventKey *event, gpointer cancel_button);
+void window_set_cancel_button(GtkWidget *win, GtkWidget *bt, window_cancel_button_fct cb);
+extern void window_cancel_button_cb(GtkWidget *w _U_, gpointer data);
+extern gboolean window_delete_event_cb(GtkWidget *win, GdkEvent *event _U_, gpointer user_data _U_);
+
==== //depot/projects/soc2007/dongmei-auditanalyzer/gtk/menu.c#5 (text+ko) ====
@@ -2,6 +2,7 @@
#include <string.h>
#include "compat_macros.h"
#include "trail_file_dlg.h"
+#include "find_dlg.h"
#include "main.h"
#include "../capture.h"
#define GTK_MENU_FUNC(a) ((GtkItemFactoryCallback)(a))
@@ -16,6 +17,8 @@
0, GTK_STOCK_QUIT),
ITEM_FACTORY_ENTRY("/_Edit", NULL, NULL, 0, "<Branch>", NULL),
+ ITEM_FACTORY_STOCK_ENTRY("/Edit/_Find Record...", "<control>F",
+ find_frame_cb,0, GTK_STOCK_FIND),
#if 0
/* Un-#if this when we actually implement Cut/Copy/Paste. */
ITEM_FACTORY_STOCK_ENTRY("/Edit/Cut", "<control>X", NULL,
==== //depot/projects/soc2007/dongmei-auditanalyzer/gtk/menu.h#4 (text+ko) ====
==== //depot/projects/soc2007/dongmei-auditanalyzer/gtk/simple_dialog.c#4 (text+ko) ====
@@ -387,34 +387,6 @@
return hbox;
}
-/* Set the "key_press_event" signal for a top-level dialog window to
- call a routine to activate the "Cancel" button for a dialog box if
- the key being pressed is the <Esc> key.
-
- XXX - there should be a GTK+ widget that'll do that for you, and
- let you specify a "Cancel" button. It should also not impose
- a requirement that there be a separator in the dialog box, as
- the GtkDialog widget does; the visual convention that there's
- such a separator between the rest of the dialog boxes and buttons
- such as "OK" and "Cancel" is, for better or worse, not universal
- (not even in GTK+ - look at the GtkFileSelection dialog!). */
-static void
-window_set_cancel(GtkWidget *widget, GtkWidget *cancel_button)
-{
- SIGNAL_CONNECT(widget, "key_press_event", window_key_press_cb, cancel_button);
-}
-
-/* set the actions needed for the cancel "Close"/"Ok"/"Cancel" button that closes the window */
-void
-window_set_cancel_button(GtkWidget *win, GtkWidget *bt, window_cancel_button_fct cb)
-{
- if(cb)
- SIGNAL_CONNECT(bt, "clicked", cb, win);
-
- gtk_widget_grab_default(bt);
-
- window_set_cancel(win, bt);
-}
/*
* Set the focus and default for the nth item in a button row, with
* 0 being the first item.
==== //depot/projects/soc2007/dongmei-auditanalyzer/gtk/simple_dialog.h#2 (text+ko) ====
==== //depot/projects/soc2007/dongmei-auditanalyzer/tfile.c#8 (text+ko) ====
@@ -24,8 +24,36 @@
u_char *buf;
int reclen;
};
+typedef struct {
+ const char *string;
+ size_t string_len;
+ trailer_file *cf;
+ gboolean frame_matched;
+} match_data;
+typedef struct {
+ const guint8 *data;
+ size_t data_len;
+} cbs_t; /* "Counted byte string" */
static guint32 cum_bytes = 0;
+static gboolean match_protocol_tree(trailer_file *cf, record_data *fdata,
+ void *criterion);
+static gboolean match_summary_line(trailer_file *cf, record_data *fdata,
+ void *criterion);
+static gboolean match_ascii_and_unicode(trailer_file *cf, record_data *fdata,
+ void *criterion);
+static gboolean match_ascii(trailer_file *cf, record_data *fdata,
+ void *criterion);
+static gboolean match_unicode(trailer_file *cf, record_data *fdata,
+ void *criterion);
+static gboolean match_binary(trailer_file *cf, record_data *fdata,
+ void *criterion);
+static gboolean match_dfilter(trailer_file *cf, record_data *fdata,
+ void *criterion);
+static gboolean find_packet(trailer_file *cf,
+ gboolean (*match_function)(trailer_file *, record_data *, void *),
+ void *criterion);
+
void
init_trail_file(trailer_file *cf)
{
@@ -506,3 +534,644 @@
}
}
+const gchar *
+cf_get_display_name(trailer_file *cf)
+{
+ const gchar *displayname;
+
+ /* Return a name to use in displays */
+ if (!cf->is_tempfile) {
+ /* Get the last component of the file name, and use that. */
+ if (cf->filename){
+ displayname = get_basename(cf->filename);
+ } else {
+ displayname="(No file)";
+ }
+ } else {
+ /* The file we read is a temporary file from a live capture;
+ we don't mention its name. */
+ displayname = "(Untitled)";
+ }
+ return displayname;
+}
+
+/* XXX - use a macro instead? */
+int
+cf_get_packet_count(trailer_file *cf)
+{
+ return cf->count;
+}
+
+/* XXX - use a macro instead? */
+void
+cf_set_packet_count(trailer_file *cf, int packet_count)
+{
+ cf->count = packet_count;
+}
+
+/* XXX - use a macro instead? */
+gboolean
+cf_is_tempfile(trailer_file *cf)
+{
+ return cf->is_tempfile;
+}
+
+void cf_set_tempfile(trailer_file *cf, gboolean is_tempfile)
+{
+ cf->is_tempfile = is_tempfile;
+}
+
+
+/* XXX - use a macro instead? */
+void cf_set_drops(trailer_file *cf, guint32 drops)
+{
+ cf->drops = drops;
+}
+
+/* XXX - use a macro instead? */
+gboolean cf_get_drops_known(trailer_file *cf)
+{
+ return cf->drops_known;
+}
+
+/* XXX - use a macro instead? */
+guint32 cf_get_drops(trailer_file *cf)
+{
+ return cf->drops;
+}
+#ifdef FILTER_EXPRESSION
+void cf_set_rfcode(trailer_file *cf, dfilter_t *rfcode)
+{
+ cf->rfcode = rfcode;
+}
+#endif
+gboolean
+cf_find_packet_summary_line(trailer_file *cf, const char *string)
+{
+ match_data mdata;
+
+ mdata.string = string;
+ mdata.string_len = strlen(string);
+ return find_packet(cf, match_summary_line, &mdata);
+}
+gboolean
+cf_find_packet_data(trailer_file *cf, const guint8 *string, size_t string_size)
+{
+ cbs_t info;
+
+ info.data = string;
+ info.data_len = string_size;
+
+ /* String or hex search? */
+ if (cf->string) {
+ /* String search - what type of string? */
+ switch (cf->scs_type) {
+
+ case SCS_ASCII_AND_UNICODE:
+ return find_packet(cf, match_ascii_and_unicode, &info);
+
+ case SCS_ASCII:
+ return find_packet(cf, match_ascii, &info);
+
+ case SCS_UNICODE:
+ return find_packet(cf, match_unicode, &info);
+
+ default:
+ g_assert_not_reached();
+ return FALSE;
+ }
+ } else
+ return find_packet(cf, match_binary, &info);
+}
+static gboolean
+match_ascii_and_unicode(trailer_file *cf, record_data *fdata, void *criterion)
+{
+ cbs_t *info = criterion;
+ const char *ascii_text = info->data;
+ size_t textlen = info->data_len;
+ gboolean frame_matched;
+ guint32 buf_len;
+ guint32 i;
+ guint8 c_char;
+ size_t c_match = 0;
+
+ frame_matched = FALSE;
+ buf_len = fdata->record_len;
+ for (i = 0; i < buf_len; i++) {
+ c_char = cf->pd[i];
+ if (cf->case_type)
+ c_char = toupper(c_char);
+ if (c_char != 0) {
+ if (c_char == ascii_text[c_match]) {
+ c_match++;
+ if (c_match == textlen) {
+ frame_matched = TRUE;
+ cf->search_pos = i; /* Save the position of the last character
+ for highlighting the field. */
+ break;
+ }
+ } else
+ c_match = 0;
+ }
+ }
+ return frame_matched;
+}
+
+static gboolean
+match_ascii(trailer_file *cf, record_data *fdata, void *criterion)
+{
+ cbs_t *info = criterion;
+ const char *ascii_text = info->data;
+ size_t textlen = info->data_len;
+ gboolean frame_matched;
+ guint32 buf_len;
+ guint32 i;
+ guint8 c_char;
+ size_t c_match = 0;
+
+ frame_matched = FALSE;
+ buf_len = fdata->record_len;
+ for (i = 0; i < buf_len; i++) {
+ c_char = cf->pd[i];
+ if (cf->case_type)
+ c_char = toupper(c_char);
+ if (c_char == ascii_text[c_match]) {
+ c_match++;
+ if (c_match == textlen) {
+ frame_matched = TRUE;
+ cf->search_pos = i; /* Save the position of the last character
+ for highlighting the field. */
+ break;
+ }
+ } else
+ c_match = 0;
+ }
+ return frame_matched;
+}
+
+static gboolean
+match_unicode(trailer_file *cf, record_data *fdata, void *criterion)
+{
+ cbs_t *info = criterion;
+ const char *ascii_text = info->data;
+ size_t textlen = info->data_len;
+ gboolean frame_matched;
+ guint32 buf_len;
+ guint32 i;
+ guint8 c_char;
+ size_t c_match = 0;
+
+ frame_matched = FALSE;
+ buf_len = fdata->record_len;
+ for (i = 0; i < buf_len; i++) {
+ c_char = cf->pd[i];
+ if (cf->case_type)
+ c_char = toupper(c_char);
+ if (c_char == ascii_text[c_match]) {
+ c_match++;
+ i++;
+ if (c_match == textlen) {
+ frame_matched = TRUE;
+ cf->search_pos = i; /* Save the position of the last character
+ for highlighting the field. */
+ break;
+ }
+ } else
+ c_match = 0;
+ }
+ return frame_matched;
+}
+
+static gboolean
+match_binary(trailer_file *cf, record_data *fdata, void *criterion)
+{
+ cbs_t *info = criterion;
+ const guint8 *binary_data = info->data;
+ size_t datalen = info->data_len;
+ gboolean frame_matched;
+ guint32 buf_len;
+ guint32 i;
+ size_t c_match = 0;
+
+ frame_matched = FALSE;
+ buf_len = fdata->record_len;
+ for (i = 0; i < buf_len; i++) {
+ if (cf->pd[i] == binary_data[c_match]) {
+ c_match++;
+ if (c_match == datalen) {
+ frame_matched = TRUE;
+ cf->search_pos = i; /* Save the position of the last character
+ for highlighting the field. */
+ break;
+ }
+ } else
+ c_match = 0;
+ }
+ return frame_matched;
+}
+#ifdef FILTER_EXPRESSION
+gboolean
+cf_find_packet_dfilter(trailer_file *cf, dfilter_t *sfcode)
+{
+ return find_packet(cf, match_dfilter, sfcode);
+}
+
+static gboolean
+match_dfilter(trailer_file *cf, record_data *fdata, void *criterion)
+{
+ dfilter_t *sfcode = criterion;
+ epan_dissect_t *edt;
+ gboolean frame_matched;
+
+ edt = epan_dissect_new(TRUE, FALSE);
+ epan_dissect_prime_dfilter(edt, sfcode);
+ epan_dissect_run(edt, &cf->pseudo_header, cf->pd, fdata, NULL);
+ frame_matched = dfilter_apply_edt(sfcode, edt);
+ epan_dissect_free(edt);
+ return frame_matched;
+}
+
+#endif
+static gboolean
+find_packet(trailer_file *cf,
+ gboolean (*match_function)(trailer_file *, record_data *, void *),
+ void *criterion)
+{
+ record_data *start_fd;
+ record_data *fdata;
+ record_data *new_fd = NULL;
+ progdlg_t *progbar = NULL;
+ gboolean stop_flag;
+ int count;
+ int err;
+ gchar *err_info;
+ int row;
+ float progbar_val;
+ GTimeVal start_time;
+ gchar status_str[100];
+ int progbar_nextstep;
+ int progbar_quantum;
+ char *title;
+
+ start_fd = cf->current_record;
+ if (start_fd != NULL) {
+ /* Iterate through the list of packets, starting at the packet we've
+ picked, calling a routine to run the filter on the packet, see if
+ it matches, and stop if so. */
+ count = 0;
+ fdata = start_fd;
+
+ /* Update the progress bar when it gets to this value. */
+ progbar_nextstep = 0;
+ /* When we reach the value that triggers a progress bar update,
+ bump that value by this amount. */
+ progbar_quantum = cf->count/N_PROGBAR_UPDATES;
+ /* Progress so far. */
+ progbar_val = 0.0;
+
+ stop_flag = FALSE;
+ g_get_current_time(&start_time);
+
+ fdata = start_fd;
+ title = cf->sfilter?cf->sfilter:"";
+ for (;;) {
+ /* Create the progress bar if necessary.
+ We check on every iteration of the loop, so that it takes no
+ longer than the standard time to create it (otherwise, for a
+ large file, we might take considerably longer than that standard
+ time in order to get to the next progress bar step). */
+ if (progbar == NULL)
+ progbar = delayed_create_progress_dlg("Searching", title,
+ FALSE, &stop_flag, &start_time, progbar_val);
+
+ /* Update the progress bar, but do it only N_PROGBAR_UPDATES times;
+ when we update it, we have to run the GTK+ main loop to get it
+ to repaint what's pending, and doing so may involve an "ioctl()"
+ to see if there's any pending input from an X server, and doing
+ that for every packet can be costly, especially on a big file. */
+ if (count >= progbar_nextstep) {
+ /* let's not divide by zero. I should never be started
+ * with count == 0, so let's assert that
+ */
+ g_assert(cf->count > 0);
+
+ progbar_val = (gfloat) count / cf->count;
+
+ if (progbar != NULL) {
+ g_snprintf(status_str, sizeof(status_str),
+ "%4u of %u packets", count, cf->count);
+ update_progress_dlg(progbar, progbar_val, status_str);
+ }
+
+ progbar_nextstep += progbar_quantum;
+ }
+
+ if (stop_flag) {
+ /* Well, the user decided to abort the search. Go back to the
+ frame where we started. */
+ new_fd = start_fd;
+ break;
+ }
+
+ /* Go past the current frame. */
+ if (cf->sbackward) {
+ /* Go on to the previous frame. */
+ fdata = fdata->prev;
+ if (fdata == NULL) {
+ /*
+ * XXX - other apps have a bit more of a detailed message
+ * for this, and instead of offering "OK" and "Cancel",
+ * they offer things such as "Continue" and "Cancel";
+ * we need an API for popping up alert boxes with
+ * {Verb} and "Cancel".
+ */
+#ifdef HAVE_PREFS
+ if (prefs.gui_find_wrap)
+ {
+ simple_dialog(ESD_TYPE_INFO, ESD_BTN_OK,
+ "%sBeginning of capture exceeded!%s\n\n"
+ "Search is continued from the end of the capture.",
+ simple_dialog_primary_start(), simple_dialog_primary_end());
+ fdata = cf->rlist_end; /* wrap around */
+ }
+ else
+ {
+#endif
+ simple_dialog(ESD_TYPE_INFO, ESD_BTN_OK,
+ "%sBeginning of capture exceeded!%s\n\n"
+ "Try searching forwards.",
+ simple_dialog_primary_start(), simple_dialog_primary_end());
+ fdata = start_fd; /* stay on previous packet */
+#ifdef HAVE_PREFS
+ }
+#endif
+ }
+ } else {
+ /* Go on to the next frame. */
+ fdata = fdata->next;
+ if (fdata == NULL) {
+#ifdef HAVE_PREFS
+ if (prefs.gui_find_wrap)
+ {
+ simple_dialog(ESD_TYPE_INFO, ESD_BTN_OK,
+ "%sEnd of capture exceeded!%s\n\n"
+ "Search is continued from the start of the capture.",
+ simple_dialog_primary_start(), simple_dialog_primary_end());
+ fdata = cf->rlist; /* wrap around */
+ }
+ else
+ {
+#endif
+ simple_dialog(ESD_TYPE_INFO, ESD_BTN_OK,
+ "%sEnd of capture exceeded!%s\n\n"
+ "Try searching backwards.",
+ simple_dialog_primary_start(), simple_dialog_primary_end());
+ fdata = start_fd; /* stay on previous packet */
+
+#ifdef HAVE_PREFS
+ }
+#endif
+ }
+ }
+
+ count++;
+#ifdef FILTER_EXPRESSION
+ /* Is this packet in the display? */
+ if (fdata->flags.passed_dfilter) {
+ /* Yes. Load its data. */
+ if (!wtap_seek_read(cf->wth, fdata->file_off, &cf->pseudo_header,
+ cf->pd, fdata->cap_len, &err, &err_info)) {
+ /* Read error. Report the error, and go back to the frame
+ where we started. */
+ simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
+ cf_read_error_message(err, err_info), cf->filename);
+ new_fd = start_fd;
+ break;
+ }
+
+ /* Does it match the search criterion? */
+ if ((*match_function)(cf, fdata, criterion)) {
+ new_fd = fdata;
+ break; /* found it! */
+ }
+ }
+
+#endif
+ if (fdata == start_fd) {
+ /* We're back to the frame we were on originally, and that frame
+ doesn't match the search filter. The search failed. */
+ break;
+ }
+ }
+
+ /* We're done scanning the packets; destroy the progress bar if it
+ was created. */
+ if (progbar != NULL)
+ destroy_progress_dlg(progbar);
+ }
+
+ if (new_fd != NULL) {
+ /* We found a frame. Find what row it's in. */
+ row = packet_list_find_row_from_data(new_fd);
+ g_assert(row != -1);
+
+ /* Select that row, make it the focus row, and make it visible. */
+ packet_list_set_selected_row(row);
+ return TRUE; /* success */
+ } else
+ return FALSE; /* failure */
+}
+
+gboolean
+cf_goto_frame(trailer_file *cf, guint fnumber)
+{
+ record_data *fdata;
+ int row;
+
+ for (fdata = cf->rlist; fdata != NULL && fdata->num < fnumber; fdata = fdata->next)
+ ;
+
+ if (fdata == NULL) {
+ /* we didn't find a packet with that packet number */
+ simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
+ "There is no packet with the packet number %u.", fnumber);
+ return FALSE; /* we failed to go to that packet */
+ }
+#ifdef FILTER_EXPRESSION
+ if (!fdata->flags.passed_dfilter) {
+ /* that packet currently isn't displayed */
+ /* XXX - add it to the set of displayed packets? */
+ simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
+ "The packet number %u isn't currently being displayed.", fnumber);
+ return FALSE; /* we failed to go to that packet */
+ }
+#endif
+ /* We found that packet, and it's currently being displayed.
+ Find what row it's in. */
+ row = packet_list_find_row_from_data(fdata);
+ g_assert(row != -1);
+
+ /* Select that row, make it the focus row, and make it visible. */
+ packet_list_set_selected_row(row);
+ return TRUE; /* we got to that packet */
+}
+
+gboolean
+cf_goto_top_frame(trailer_file *cf)
+{
+ record_data *fdata;
+ int row;
+ record_data *lowest_fdata = NULL;
+
+#ifdef FILTER_EXPRESSION
+ for (fdata = cf->rlist; fdata != NULL; fdata = fdata->next) {
+ if (fdata->flags.passed_dfilter) {
+ lowest_fdata = fdata;
+ break;
+ }
+ }
+#endif
+ if (lowest_fdata == NULL) {
+ return FALSE;
+ }
+
+ /* We found that packet, and it's currently being displayed.
+ Find what row it's in. */
+ row = packet_list_find_row_from_data(lowest_fdata);
+ g_assert(row != -1);
+
+ /* Select that row, make it the focus row, and make it visible. */
+ packet_list_set_selected_row(row);
+ return TRUE; /* we got to that packet */
+}
+
+gboolean
+cf_goto_bottom_frame(trailer_file *cf)
+{
+ record_data *fdata;
+ int row;
+ record_data *highest_fdata = NULL;
+
+#ifdef FILTER_EXPRESSION
+ for (fdata = cf->rlist; fdata != NULL; fdata = fdata->next) {
+ if (fdata->flags.passed_dfilter) {
+ highest_fdata = fdata;
+ }
+ }
+#endif
+ if (highest_fdata == NULL) {
+ return FALSE;
+ }
+
+ /* We found that packet, and it's currently being displayed.
+ Find what row it's in. */
+ row = packet_list_find_row_from_data(highest_fdata);
+ g_assert(row != -1);
+
+ /* Select that row, make it the focus row, and make it visible. */
+ packet_list_set_selected_row(row);
+ return TRUE; /* we got to that packet */
+}
+
+/*
+ * Go to frame specified by currently selected protocol tree item.
+ */
+/*
+gboolean
+cf_goto_framenum(trailer_file *cf)
+{
+ header_field_info *hfinfo;
+ guint32 framenum;
+
+ if (cf->finfo_selected) {
+ hfinfo = cf->finfo_selected->hfinfo;
+ g_assert(hfinfo);
+ if (hfinfo->type == FT_FRAMENUM) {
+ framenum = fvalue_get_integer(&cf->finfo_selected->value);
+ if (framenum != 0)
+ return cf_goto_frame(cf, framenum);
+ }
+ }
+
+ return FALSE;
+}
+*/
+static gboolean
+match_summary_line(trailer_file *cf, record_data *fdata, void *criterion)
+{
+ match_data *mdata = criterion;
+ const gchar *string = mdata->string;
+ size_t string_len = mdata->string_len;
+#ifdef HAVE_DISSECT
+ epan_dissect_t *edt;
+#endif
+ const char *info_column;
+ size_t info_column_len;
+ gboolean frame_matched = FALSE;
+ gint colx;
+ guint32 i;
+ guint8 c_char;
+ size_t c_match = 0;
+
+#ifdef HAVE_DISSECT
+ /* Don't bother constructing the protocol tree */
+ edt = epan_dissect_new(FALSE, FALSE);
+ /* Get the column information */
+ epan_dissect_run(edt, &cf->pseudo_header, cf->pd, fdata, &cf->cinfo);
+ /* Find the Info column */
+ for (colx = 0; colx < cf->cinfo.num_cols; colx++) {
+ if (cf->cinfo.fmt_matx[colx][COL_INFO]) {
+ /* Found it. See if we match. */
+ info_column = edt->pi.cinfo->col_data[colx];
+ info_column_len = strlen(info_column);
+ for (i = 0; i < info_column_len; i++) {
+ c_char = info_column[i];
+ if (cf->case_type)
+ c_char = toupper(c_char);
+ if (c_char == string[c_match]) {
+ c_match++;
+ if (c_match == string_len) {
+ frame_matched = TRUE;
+ break;
+ }
+ } else
+ c_match = 0;
+ }
+ break;
+ }
+ }
+ epan_dissect_free(edt);
+#endif
+ return frame_matched;
+}
+
+gboolean
+cf_find_packet_protocol_tree(trailer_file *cf, const char *string)
+{
+ match_data mdata;
+
+ mdata.string = string;
+ mdata.string_len = strlen(string);
+ return find_packet(cf, match_protocol_tree, &mdata);
+}
+static gboolean
+match_protocol_tree(trailer_file *cf, record_data *fdata, void *criterion)
+{
+ match_data *mdata = criterion;
+#ifdef HAVE_DISSECT
+ epan_dissect_t *edt;
+
+ /* Construct the protocol tree, including the displayed text */
+ edt = epan_dissect_new(TRUE, TRUE);
+ /* We don't need the column information */
+ epan_dissect_run(edt, &cf->pseudo_header, cf->pd, fdata, NULL);
+
+ /* Iterate through all the nodes, seeing if they have text that matches. */
+ mdata->cf = cf;
+ mdata->frame_matched = FALSE;
+ proto_tree_children_foreach(edt->tree, match_subtree_text, mdata);
+ epan_dissect_free(edt);
+#endif
+ return mdata->frame_matched;
+}
+
==== //depot/projects/soc2007/dongmei-auditanalyzer/tfile.h#4 (text+ko) ====
@@ -3,6 +3,7 @@
#include <glib.h>
>>> TRUNCATED FOR MAIL (1000 lines) <<<
More information about the p4-projects
mailing list