diff --git a/dftest.c b/dftest.c index 69d4d7875a..e42ff526b1 100644 --- a/dftest.c +++ b/dftest.c @@ -88,7 +88,7 @@ main(int argc, char **argv) by the dissectors, and we must do it before we read the preferences, in case any dissectors register preferences. */ epan_init(register_all_protocols, - register_all_protocol_handoffs, + register_all_protocol_handoffs, NULL, NULL, failure_message, open_failure_message, read_failure_message); /* now register the preferences for any non-dissector modules. diff --git a/epan/epan.c b/epan/epan.c index f532b6fc7c..765859036b 100644 --- a/epan/epan.c +++ b/epan/epan.c @@ -68,8 +68,10 @@ epan_get_version(void) { } void -epan_init(void (*register_all_protocols)(void), - void (*register_all_handoffs)(void), +epan_init(void (*register_all_protocols)(register_cb cb, gpointer client_data), + void (*register_all_handoffs)(register_cb cb, gpointer client_data), + register_cb cb, + gpointer client_data, void (*report_failure)(const char *, va_list), void (*report_open_failure)(const char *, int, gboolean), void (*report_read_failure)(const char *, int)) @@ -94,7 +96,7 @@ epan_init(void (*register_all_protocols)(void), tvbuff_init(); oid_resolv_init(); tap_init(); - proto_init(register_all_protocols, register_all_handoffs); + proto_init(register_all_protocols, register_all_handoffs, cb, client_data); packet_init(); dfilter_init(); final_registration_all_protocols(); diff --git a/epan/epan.h b/epan/epan.h index e78815da2a..708510d82d 100644 --- a/epan/epan.h +++ b/epan/epan.h @@ -27,14 +27,17 @@ #include #include "frame_data.h" #include "column_info.h" +#include "register.h" typedef struct _epan_dissect_t epan_dissect_t; #include "dfilter/dfilter.h" /* init the whole epan module, this is used to be called only once in a program */ -void epan_init(void (*register_all_protocols)(void), - void (*register_all_handoffs)(void), +void epan_init(void (*register_all_protocols)(register_cb cb, gpointer client_data), + void (*register_all_handoffs)(register_cb cb, gpointer client_data), + register_cb cb, + void *client_data, void (*report_failure)(const char *, va_list), void (*report_open_failure)(const char *, int, gboolean), void (*report_read_failure)(const char *, int)); diff --git a/epan/libwireshark.def b/epan/libwireshark.def index 2b9d5aac78..78d4779525 100644 --- a/epan/libwireshark.def +++ b/epan/libwireshark.def @@ -656,6 +656,7 @@ register_all_protocols register_all_protocol_handoffs register_ber_syntax_dissector register_ber_oid_syntax +register_count register_dissector register_dissector_table register_final_registration_routine diff --git a/epan/proto.c b/epan/proto.c index 5cfaee7b3d..88e3accdc9 100644 --- a/epan/proto.c +++ b/epan/proto.c @@ -292,8 +292,10 @@ proto_compare_name(gconstpointer p1_arg, gconstpointer p2_arg) /* initialize data structures and register protocols and fields */ void -proto_init(void (register_all_protocols)(void), - void (register_all_protocol_handoffs)(void)) +proto_init(void (register_all_protocols)(register_cb cb, gpointer client_data), + void (register_all_protocol_handoffs)(register_cb cb, gpointer client_data), + register_cb cb, + gpointer client_data) { static hf_register_info hf[] = { { &hf_text_only, @@ -330,11 +332,13 @@ proto_init(void (register_all_protocols)(void), dissector tables, and dissectors to be called through a handle, and do whatever one-time initialization it needs to do. */ - register_all_protocols(); + register_all_protocols(cb, client_data); #ifdef HAVE_PLUGINS /* Now scan for plugins and load all the ones we find, calling their register routines to do the stuff described above. */ + if(cb) + (*cb)(RA_PLUGIN_REGISTER, NULL, client_data); init_plugins(); #endif @@ -342,10 +346,12 @@ proto_init(void (register_all_protocols)(void), dissectors; those routines register the dissector in other dissectors' handoff tables, and fetch any dissector handles they need. */ - register_all_protocol_handoffs(); + register_all_protocol_handoffs(cb, client_data); #ifdef HAVE_PLUGINS /* Now do the same with plugins. */ + if(cb) + (*cb)(RA_PLUGIN_HANDOFF, NULL, client_data); register_all_plugin_handoffs(); #endif diff --git a/epan/proto.h b/epan/proto.h index 1f5b8a1c1b..56628c511c 100644 --- a/epan/proto.h +++ b/epan/proto.h @@ -50,6 +50,7 @@ #include "nstime.h" #include "tvbuff.h" #include "ftypes/ftypes.h" +#include "register.h" #ifdef __cplusplus extern "C" { @@ -327,8 +328,10 @@ extern void proto_tree_children_foreach(proto_tree *tree, #define PTREE_DATA(proto_tree) ((proto_tree)->tree_data) /** Sets up memory used by proto routines. Called at program startup */ -extern void proto_init(void (register_all_protocols)(void), - void (register_all_handoffs)(void)); +extern void proto_init(void (register_all_protocols)(register_cb cb, gpointer client_data), + void (register_all_handoffs)(register_cb cb, gpointer client_data), + register_cb cb, void *client_data); + /** Frees memory used by proto routines. Called at program shutdown */ extern void proto_cleanup(void); diff --git a/gtk/about_dlg.c b/gtk/about_dlg.c index 18f8a7efdc..10109e6383 100644 --- a/gtk/about_dlg.c +++ b/gtk/about_dlg.c @@ -79,6 +79,20 @@ about_wireshark(GtkWidget *parent, GtkWidget *main_vb, const char *title) gtk_container_add(GTK_CONTAINER(main_vb), msg_label); } +static void +splash_update_label(GtkWidget *win, char *message) +{ + GtkWidget *main_lb; + + if (win == NULL) return; + + main_lb = OBJECT_GET_DATA(win, "splash_label"); + gtk_label_set_text(GTK_LABEL(main_lb), message); + + /* Process all pending GUI events before continuing, so that + the splash screen window gets updated. */ + while (gtk_events_pending()) gtk_main_iteration(); +} GtkWidget* splash_new(char *message) @@ -87,6 +101,9 @@ splash_new(char *message) GtkWidget *main_lb; GtkWidget *main_vb; + GtkWidget *percentage_hb; + GtkWidget *prog_bar; + GtkWidget *percentage_lb; win = splash_window_new(); @@ -106,26 +123,128 @@ splash_new(char *message) gtk_container_add(GTK_CONTAINER(main_vb), main_lb); OBJECT_SET_DATA(win, "splash_label", main_lb); + main_lb = gtk_label_new(""); + gtk_container_add(GTK_CONTAINER(main_vb), main_lb); + OBJECT_SET_DATA(win, "protocol_label", main_lb); + + percentage_hb = gtk_hbox_new(FALSE, 1); + gtk_box_pack_start(GTK_BOX(main_vb), percentage_hb, FALSE, TRUE, 3); + + prog_bar = gtk_progress_bar_new(); +#if GTK_MAJOR_VERSION < 2 + gtk_progress_set_activity_mode(GTK_PROGRESS(prog_bar), FALSE); +#endif + gtk_box_pack_start(GTK_BOX(percentage_hb), prog_bar, FALSE, TRUE, 3); + OBJECT_SET_DATA(win, "progress_bar", prog_bar); + + percentage_lb = gtk_label_new(" 0%"); + gtk_misc_set_alignment(GTK_MISC(percentage_lb), 0.0, 0.0); + gtk_box_pack_start(GTK_BOX(percentage_hb), percentage_lb, FALSE, TRUE, 3); + OBJECT_SET_DATA(win, "percentage_label", percentage_lb); + gtk_widget_show_all(win); - splash_update(win, message); + splash_update_label(win, message); return win; } void -splash_update(GtkWidget *win, char *message) +splash_update(register_action_e action, char *message, gpointer client_data) { + GtkWidget *win; GtkWidget *main_lb; + GtkWidget *prog_bar; + GtkWidget *percentage_lb; + gfloat percentage; + gulong ul_percentage; + gchar tmp[100]; + char *action_msg; + + static gulong ul_sofar = 0; + static gulong ul_count = 0; + + static register_action_e last_action = RA_NONE; + + win = (GtkWidget *)client_data; if (win == NULL) return; - main_lb = OBJECT_GET_DATA(win, "splash_label"); - gtk_label_set_text(GTK_LABEL(main_lb), message); + if(last_action != action) { + /* the action has changed */ + switch(action) { + case RA_DISSECTORS: + action_msg = "Initializing dissectors ..."; + break; + case RA_LISTENERS: + action_msg = "Initializing tap listeners ..."; + break; + case RA_REGISTER: + action_msg = "Registering dissector ..."; + break; + case RA_PLUGIN_REGISTER: + action_msg = "Registering plugins ..."; + break; + case RA_HANDOFF: + action_msg = "Handing off dissector ..."; + break; + case RA_PLUGIN_HANDOFF: + action_msg = "Handing off plugins ..."; + break; + case RA_PREFERENCES: + action_msg = "Loading module preferences ..."; + break; + case RA_CONFIGURATION: + action_msg = "Loading configuration files ..."; + break; + default: + action_msg = "(Unknown action)";; + break; + } + splash_update_label(win, action_msg); + last_action = action; + } + + if(ul_count == 0) /* get the count of dissectors */ + ul_count = register_count() + 6; /* additional 6 for: + dissectors, listeners, + registering plugins, handingoff plugins, + preferences and configuration */ + + main_lb = OBJECT_GET_DATA(win, "protocol_label"); + /* make_dissector_reg.py changed - + so we need to strip off the leading elements to get back to the protocol */ + if(message) { + if(!strncmp(message, "proto_register_", 15)) + message += 15; + else if(!strncmp(message, "proto_reg_handoff_", 18)) + message += 18; + } + gtk_label_set_text(GTK_LABEL(main_lb), message ? message : ""); + + ul_sofar++; + + g_assert (ul_sofar <= ul_count); + + percentage = (gfloat)ul_sofar/(gfloat)ul_count; + ul_percentage = (gulong)(percentage * 100); + + /* update progress bar */ + prog_bar = OBJECT_GET_DATA(win, "progress_bar"); +#if GTK_MAJOR_VERSION < 2 + gtk_progress_bar_update(GTK_PROGRESS_BAR(prog_bar), percentage); +#else + gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(prog_bar), percentage); +#endif + + percentage_lb = OBJECT_GET_DATA(win, "percentage_label"); + g_snprintf(tmp, sizeof(tmp), "%lu%%", ul_percentage); + gtk_label_set_text((GtkLabel*)percentage_lb, tmp); /* Process all pending GUI events before continuing, so that the splash screen window gets updated. */ while (gtk_events_pending()) gtk_main_iteration(); + } guint diff --git a/gtk/about_dlg.h b/gtk/about_dlg.h index 7744865690..d80a658893 100644 --- a/gtk/about_dlg.h +++ b/gtk/about_dlg.h @@ -37,12 +37,13 @@ */ extern GtkWidget *splash_new(char *message); -/** Update the splash screen message. +/** Update the splash screen message when loading dissectors and handoffs * - * @param win the window handle from splash_new() - * @param message the new message to be displayed + * @param action the initialisation action being performed + * @param message additional information + * @param client_data the window handle from splash_new() */ -extern void splash_update(GtkWidget *win, char *message); +extern void splash_update(register_action_e action, char *message, void *call_data); /** Destroy the splash screen. * diff --git a/gtk/main.c b/gtk/main.c index 350f510c13..c395ce6f90 100644 --- a/gtk/main.c +++ b/gtk/main.c @@ -2386,16 +2386,17 @@ main(int argc, char *argv[]) g_free(init_progfile_dir_error); } - splash_update(splash_win, "Init dissectors ..."); + splash_update(RA_DISSECTORS, NULL, (gpointer)splash_win); /* Register all dissectors; we must do this before checking for the "-G" flag, as the "-G" flag dumps information registered by the dissectors, and we must do it before we read the preferences, in case any dissectors register preferences. */ - epan_init(register_all_protocols,register_all_protocol_handoffs, + epan_init(register_all_protocols,register_all_protocol_handoffs, + splash_update, (gpointer) splash_win, failure_alert_box,open_failure_alert_box,read_failure_alert_box); - splash_update(splash_win, "Init tap listeners ..."); + splash_update(RA_LISTENERS, NULL, (gpointer)splash_win); /* Register all tap listeners; we do this before we parse the arguments, as the "-z" argument can specify a registered tap. */ @@ -2410,7 +2411,7 @@ main(int argc, char *argv[]) register_all_tap_listeners(); - splash_update(splash_win, "Loading module preferences ..."); + splash_update(RA_PREFERENCES, NULL, (gpointer)splash_win); /* Now register the preferences for any non-dissector modules. We must do that before we read the preferences as well. */ @@ -2434,7 +2435,7 @@ main(int argc, char *argv[]) gtk_timeout_add(750, (GtkFunction) host_name_lookup_process, NULL); #endif - splash_update(splash_win, "Loading configuration files ..."); + splash_update(RA_CONFIGURATION, NULL, (gpointer)splash_win); /* Read the preference files. */ prefs = read_prefs(&gpf_open_errno, &gpf_read_errno, &gpf_path, @@ -2879,7 +2880,7 @@ main(int argc, char *argv[]) font_init(); /* close the splash screen, as we are going to open the main window now */ - splash_destroy(splash_win); + splash_destroy(splash_win); /************************************************************************/ /* Everything is prepared now, preferences and command line was read in */ diff --git a/register.h b/register.h index 1d25c20264..b11420a717 100644 --- a/register.h +++ b/register.h @@ -25,7 +25,24 @@ #ifndef __REGISTER_H__ #define __REGISTER_H__ -extern void register_all_protocols(void); -extern void register_all_protocol_handoffs(void); +#include + +typedef enum { + RA_NONE, /* for initialization */ + RA_DISSECTORS, /* Initializing dissectors */ + RA_LISTENERS, /* Tap listeners */ + RA_REGISTER, /* register */ + RA_PLUGIN_REGISTER, /* plugin register */ + RA_HANDOFF, /* handoff */ + RA_PLUGIN_HANDOFF, /* plugin handoff */ + RA_PREFERENCES, /* module preferences */ + RA_CONFIGURATION /* configuration files */ +} register_action_e; + +typedef void (*register_cb)(register_action_e action, char *message, gpointer client_data); + +extern void register_all_protocols(register_cb cb, gpointer client_data); +extern void register_all_protocol_handoffs(register_cb cb, gpointer client_data); extern void register_all_tap_listeners(void); +extern gulong register_count(void); #endif /* __REGISTER_H__ */ diff --git a/tools/make-dissector-reg b/tools/make-dissector-reg index d4c6739777..6bf9a28adf 100755 --- a/tools/make-dissector-reg +++ b/tools/make-dissector-reg @@ -54,15 +54,6 @@ G_MODULE_EXPORT void plugin_register (void) { EOF -else - cat <<"EOF" >>${outfile}-tmp -#include "register.h" -void -register_all_protocols(void) -{ -EOF -fi - # # Build code to call all the protocol registration routines. # @@ -86,8 +77,41 @@ do fi grep '^void proto_register_[a-z_0-9A-Z]* *(' $srcfile 2>/dev/null | grep -v ';' done | sed -e 's/^.*://' -e 's/^void \([a-z_0-9A-Z]*\).*/ {extern void \1 (void); \1 ();}/' >>${outfile}-tmp +else + cat <<"EOF" >>${outfile}-tmp +#include "register.h" +void +register_all_protocols(register_cb cb, gpointer client_data) +{ +EOF +# +# Build code to call all the protocol registration routines. +# +for f in "$@" +do + if [ -f $f ] + then + srcfile=$f + else + srcfile=$srcdir/$f + fi + grep '^proto_register_[a-z_0-9A-Z]* *(' $srcfile 2>/dev/null | grep -v ';' +done | sed -e 's/^.*://' -e 's/^\([a-z_0-9A-Z]*\).*/ {extern void \1 (void); if(cb) (*cb)(RA_REGISTER, \"\1\", client_data); \1 ();}/' >>${outfile}-tmp +for f in "$@" +do + if [ -f $f ] + then + srcfile=$f + else + srcfile=$srcdir/$f + fi + grep '^void proto_register_[a-z_0-9A-Z]* *(' $srcfile 2>/dev/null | grep -v ';' +done | sed -e 's/^.*://' -e 's/^void \([a-z_0-9A-Z]*\).*/ {extern void \1 (void); if(cb) (*cb)(RA_REGISTER, \"\1\", client_data); \1 ();}/' >>${outfile}-tmp + +fi echo '}' >>${outfile}-tmp + # # Build code to call all the protocol handoff registration routines. # @@ -98,13 +122,6 @@ G_MODULE_EXPORT void plugin_reg_handoff(void) { EOF -else - cat <<"EOF" >>${outfile}-tmp -void -register_all_protocol_handoffs(void) -{ -EOF -fi for f in "$@" do if [ -f $f ] @@ -125,9 +142,45 @@ do fi grep '^void proto_reg_handoff_[a-z_0-9A-Z]* *(' $srcfile 2>/dev/null | grep -v ';' done | sed -e 's/^.*://' -e 's/^void \([a-z_0-9A-Z]*\).*/ {extern void \1 (void); \1 ();}/' >>${outfile}-tmp +else + cat <<"EOF" >>${outfile}-tmp +void +register_all_protocol_handoffs(register_cb cb, gpointer client_data) +{ +EOF +for f in "$@" +do + if [ -f $f ] + then + srcfile=$f + else + srcfile=$srcdir/$f + fi + grep '^proto_reg_handoff_[a-z_0-9A-Z]* *(' $srcfile 2>/dev/null | grep -v ';' +done | sed -e 's/^.*://' -e 's/^\([a-z_0-9A-Z]*\).*/ {extern void \1 (void); if(cb) (*cb)(RA_HANDOFF, \"\1\", client_data); \1 ();}/' >>${outfile}-tmp +for f in "$@" +do + if [ -f $f ] + then + srcfile=$f + else + srcfile=$srcdir/$f + fi + grep '^void proto_reg_handoff_[a-z_0-9A-Z]* *(' $srcfile 2>/dev/null | grep -v ';' +done | sed -e 's/^.*://' -e 's/^void \([a-z_0-9A-Z]*\).*/ {extern void \1 (void); if(cb) (*cb)(RA_HANDOFF, \"\1\", client_data); \1 ();}/' >>${outfile}-tmp +fi echo '}' >>${outfile}-tmp if [ "$registertype" = plugin ] then echo '#endif' >>${outfile}-tmp +else + cat <<"EOF" >>${outfile}-tmp +gulong register_count(void) +{ +EOF + proto_regs=`grep RA_REGISTER ${outfile}-tmp | wc -l` + handoff_regs=`grep RA_HANDOFF ${outfile}-tmp | wc -l` + echo " return $proto_regs + $handoff_regs;" >>${outfile}-tmp + echo '}' >>${outfile}-tmp fi mv ${outfile}-tmp ${outfile} diff --git a/tools/make-dissector-reg.py b/tools/make-dissector-reg.py index 0b9776b42b..f9745bb384 100644 --- a/tools/make-dissector-reg.py +++ b/tools/make-dissector-reg.py @@ -169,12 +169,15 @@ else: reg_code.write(""" #include "register.h" void -register_all_protocols(void) +register_all_protocols(register_cb cb, gpointer client_data) { """); for symbol in regs['proto_reg']: - line = " {extern void %s (void); %s ();}\n" % (symbol, symbol) + if registertype == "plugin": + line = " {extern void %s (void); %s ();}\n" % (symbol, symbol) + else: + line = " {extern void %s (void); if(cb) (*cb)(RA_REGISTER, \"%s\", client_data); %s ();}\n" % (symbol, symbol, symbol) reg_code.write(line) reg_code.write("}\n") @@ -190,18 +193,34 @@ plugin_reg_handoff(void) else: reg_code.write(""" void -register_all_protocol_handoffs(void) +register_all_protocol_handoffs(register_cb cb, gpointer client_data) { """); for symbol in regs['handoff_reg']: - line = " {extern void %s (void); %s ();}\n" % (symbol, symbol) + if registertype == "plugin": + line = " {extern void %s (void); %s ();}\n" % (symbol, symbol) + else: + line = " {extern void %s (void); if(cb) (*cb)(RA_HANDOFF, \"%s\", client_data); %s ();}\n" % (symbol, symbol, symbol) reg_code.write(line) reg_code.write("}\n") if registertype == "plugin": reg_code.write("#endif\n"); +else: + reg_code.write(""" +gulong register_count(void) +{ +"""); + + line = " return %d + %d;\n" % (len(regs['proto_reg']), len(regs['handoff_reg'])) + reg_code.write(line) + + reg_code.write(""" +} +"""); + # Close the file reg_code.close() diff --git a/tshark.c b/tshark.c index 71d3b2eee1..42ecf77042 100644 --- a/tshark.c +++ b/tshark.c @@ -786,7 +786,7 @@ main(int argc, char *argv[]) "-G" flag, as the "-G" flag dumps information registered by the dissectors, and we must do it before we read the preferences, in case any dissectors register preferences. */ - epan_init(register_all_protocols, register_all_protocol_handoffs, + epan_init(register_all_protocols, register_all_protocol_handoffs, NULL, NULL, failure_message, open_failure_message, read_failure_message); /* Register all tap listeners; we do this before we parse the arguments,