Date: Tue, 25 Mar 2008 03:17:18 GMT From: dongmei <dongmei@FreeBSD.org> To: Perforce Change Reviews <perforce@FreeBSD.org> Subject: PERFORCE change 138490 for review Message-ID: <200803250317.m2P3HIYt041893@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=138490 Change 138490 by dongmei@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) <<<
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200803250317.m2P3HIYt041893>