diff options
-rw-r--r-- | dftest.c | 20 | ||||
-rw-r--r-- | doc/Makefile.am | 2 | ||||
-rw-r--r-- | epan/epan.c | 25 | ||||
-rw-r--r-- | epan/epan.h | 2 | ||||
-rw-r--r-- | epan/filesystem.c | 139 | ||||
-rw-r--r-- | epan/filesystem.h | 17 | ||||
-rw-r--r-- | epan/libwireshark.def | 4 | ||||
-rw-r--r-- | epan/plugins.c | 126 | ||||
-rw-r--r-- | epan/plugins.h | 6 | ||||
-rw-r--r-- | epan/proto.c | 23 | ||||
-rw-r--r-- | epan/proto.h | 6 | ||||
-rw-r--r-- | gtk/about_dlg.c | 4 | ||||
-rw-r--r-- | gtk/main.c | 7 | ||||
-rw-r--r-- | tshark.c | 13 |
14 files changed, 259 insertions, 135 deletions
@@ -67,17 +67,27 @@ main(int argc, char **argv) dfilter_t *df; /* + * Attempt to get the pathname of the executable file. + */ + init_progfile_dir(argv[0]); + + /* * Get credential information for later use. */ get_credential_info(); + /* + * Now attempt to get the pathname of the plugins. + */ + init_plugin_dir(); + timestamp_set_type(TS_RELATIVE); - /* register all dissectors; we must do this before checking for the - "-g" flag, as the "-g" flag dumps a list of fields registered - by the dissectors, and we must do it before we read the preferences, - in case any dissectors register preferences. */ - epan_init(PLUGIN_DIR,register_all_protocols, + /* Register all dissectors; we must do this before checking for the + "-g" flag, as the "-g" flag dumps a list of fields 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, failure_message, open_failure_message, read_failure_message); diff --git a/doc/Makefile.am b/doc/Makefile.am index 205438270d..2a3502a6f2 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -65,7 +65,7 @@ wireshark-tmp.pod: $(srcdir)/wireshark.pod $(top_builddir)/AUTHORS-SHORT-FORMAT wireshark-filter.pod > ../wireshark-filter.html wireshark-filter.pod: wireshark-filter.pod.template ../tshark - ../tshark -G fields | $(PERL) $(srcdir)/dfilter2pod.pl $(srcdir)/wireshark-filter.pod.template > wireshark-filter.pod + WIRESHARK_RUN_FROM_BUILD_DIRECTORY=1 ../tshark -G fields | $(PERL) $(srcdir)/dfilter2pod.pl $(srcdir)/wireshark-filter.pod.template > wireshark-filter.pod ../capinfos.1: capinfos.pod ../config.h $(POD2MAN) \ diff --git a/epan/epan.c b/epan/epan.c index 20290ee9cd..f532b6fc7c 100644 --- a/epan/epan.c +++ b/epan/epan.c @@ -67,29 +67,8 @@ epan_get_version(void) { return VERSION; } -/* - * XXX - this takes the plugin directory as an argument, because - * libwireshark now has its own configure script and "config.h" file, - * which is what code in the "epan" directory includes, but we need - * to define PLUGIN_DIR in the top-level directory, as it's used by, - * for example, the Makefile for the Gryphon plugin, so it knows - * where to install the plugin. - * - * Eventually, we should probably have an "epan-configure" script - * (or "libwireshark-configure", or whatever), along the lines of what - * GTK+ and GLib have, that can print, among other things, the directory - * into which plugins should be installed. That way, only libwireshark - * need know what directory that is; programs using it won't, *and* - * Makefiles for plugins can just use "epan-configure" to figure out - * where to install the plugins. - * - * (Would that *more* libraries had configure scripts like that, so - * that configure scripts didn't have to go through various contortions - * to figure out where the header files and libraries for various - * libraries are located.) - */ void -epan_init(const char *plugin_dir, void (*register_all_protocols)(void), +epan_init(void (*register_all_protocols)(void), void (*register_all_handoffs)(void), void (*report_failure)(const char *, va_list), void (*report_open_failure)(const char *, int, gboolean), @@ -115,7 +94,7 @@ epan_init(const char *plugin_dir, void (*register_all_protocols)(void), tvbuff_init(); oid_resolv_init(); tap_init(); - proto_init(plugin_dir,register_all_protocols,register_all_handoffs); + proto_init(register_all_protocols, register_all_handoffs); packet_init(); dfilter_init(); final_registration_all_protocols(); diff --git a/epan/epan.h b/epan/epan.h index 2a7bf6fcb2..e78815da2a 100644 --- a/epan/epan.h +++ b/epan/epan.h @@ -33,7 +33,7 @@ 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(const char * plugindir, void (*register_all_protocols)(void), +void epan_init(void (*register_all_protocols)(void), void (*register_all_handoffs)(void), void (*report_failure)(const char *, va_list), void (*report_open_failure)(const char *, int, gboolean), diff --git a/epan/filesystem.c b/epan/filesystem.c index 436d722d7d..77978dc311 100644 --- a/epan/filesystem.c +++ b/epan/filesystem.c @@ -50,6 +50,7 @@ #endif #include "filesystem.h" +#include "privileges.h" #include <wiretap/file_util.h> /* @@ -478,6 +479,14 @@ get_progfile_dir(void) * Get the directory in which the global configuration and data files are * stored. * + * On Windows, we use the directory in which the executable for this + * process resides. + * + * On UN*X, we use the DATAFILE_DIR value supplied by the configure + * script, unless the WIRESHARK_RUN_FROM_BUILD_DIRECTORY environment + * variable is set, in which case we use the directory in which the + * executable for this process resides. + * * XXX - if we ever make libwireshark a real library, used by multiple * applications (more than just TShark and versions of Wireshark with * various UIs), should the configuration files belong to the library @@ -511,10 +520,15 @@ get_datafile_dir(void) return datafile_dir; #ifdef _WIN32 - + /* + * See if we are running in a U3 environment. + */ u3deviceexecpath = getenv_utf8("U3_DEVICE_EXEC_PATH"); if (u3deviceexecpath != NULL) { + /* + * We are; use the U3 device executable path. + */ datafile_dir = u3deviceexecpath; } else { /* @@ -542,13 +556,128 @@ get_datafile_dir(void) } } #else + if (getenv("WIRESHARK_RUN_FROM_BUILD_DIRECTORY") != NULL + && !started_with_special_privs() && progfile_dir != NULL) { + /* + * WIRESHARK_RUN_FROM_BUILD_DIRECTORY is set, and + * we weren't started with special privileges, and + * we were able to determine the directory in which + * the program was found, so use that. + */ + datafile_dir = progfile_dir; + } else { + /* + * Return the directory specified when the build + * was configured. + */ + datafile_dir = DATAFILE_DIR; + } + +#endif + return datafile_dir; +} + +/* + * Find the directory where the plugins are stored. + * + * On Windows, we use the "plugin" subdirectory of the datafile directory. + * + * On UN*X, we use the PLUGIN_DIR value supplied by the configure + * script, unless the WIRESHARK_RUN_FROM_BUILD_DIRECTORY environment + * variable is set, in which case we use the "plugin" subdirectory of + * the datafile directory. + * + * In both cases, we then use the subdirectory of that directory whose + * name is the version number. + * + * XXX - if WIRESHARK_RUN_FROM_BUILD_DIRECTORY is set, perhaps we + * should have the plugin code not look in the version subdirectory + * of the plugin directory, but look in all of the subdirectories + * of the plugin directory, so it can just fetch the plugins built + * as part of the build process. + */ +static const char *plugin_dir; + +/* + * TRUE if we're running from the build directory. + */ +static gboolean running_in_build_directory_flag = FALSE; + +void +init_plugin_dir(void) +{ +#ifdef _WIN32 + /* + * On Windows, the data file directory is the installation + * directory; the plugins are stored under it. + * + * Assume we're running the installed version of Wireshark; + * on Windows, the data file directory is the directory + * in which the Wireshark binary resides. + */ + plugin_dir = g_strdup_printf("%s\\plugins\\%s", get_datafile_dir(), + VERSION); + /* - * Just use DATAFILE_DIR, as that's what the configure script - * set it to be. + * Make sure that pathname refers to a directory. */ - datafile_dir = DATAFILE_DIR; + if (test_for_directory(plugin_dir) != EISDIR) { + /* + * Either it doesn't refer to a directory or it + * refers to something that doesn't exist. + * + * Assume that means we're running a version of + * Wireshark we've built in a build directory, + * in which case {datafile dir}\plugins is the + * top-level plugins source directory, and use + * that directory and set the "we're running in + * a build directory" flag, so the plugin + * scanner will check all subdirectories of that + * directory for plugins. + */ + g_free(plugin_dir); + plugin_dir = g_strdup_printf("%s\\plugins", get_datafile_dir()); + running_in_build_directory_flag = TRUE; + } +#else + if (getenv("WIRESHARK_RUN_FROM_BUILD_DIRECTORY") != NULL + && !started_with_special_privs()) { + /* + * WIRESHARK_RUN_FROM_BUILD_DIRECTORY is set, and + * we weren't started with special privileges, so + * we'll use the "plugins" subdirectory of the + * datafile directory (the datafile directory is + * the build directory), and set the "we're running + * in a build directory" flag, so the plugin scanner + * will check all subdirectories of that directory + * for plugins. (If we were started with special + * privileges, it's not safe to allow the user to + * point us to some other directory.) + */ + plugin_dir = g_strdup_printf("%s/plugins", get_datafile_dir()); + running_in_build_directory_flag = TRUE; + } else + plugin_dir = PLUGIN_DIR; #endif - return datafile_dir; +} + +/* + * Get the directory in which the plugins are stored. + */ +const char * +get_plugin_dir(void) +{ + return plugin_dir; +} + +/* + * Get the flag indicating whether we're running from a build + * directory. + */ +gboolean +running_in_build_directory(void) +{ + return running_in_build_directory_flag; } /* diff --git a/epan/filesystem.h b/epan/filesystem.h index 8458b13bc2..9f5356a39c 100644 --- a/epan/filesystem.h +++ b/epan/filesystem.h @@ -82,6 +82,23 @@ extern const char *get_progfile_dir(void); extern const char *get_datafile_dir(void); /* + * Find the directory in which plugins are stored; this must be called + * after init_progfile_dir() is called. + */ +extern void init_plugin_dir(void); + +/* + * Get the directory in which plugins are stored. + */ +extern const char *get_plugin_dir(void); + +/* + * Get the flag indicating whether we're running from a build + * directory. + */ +extern gboolean running_in_build_directory(void); + +/* * Construct the path name of a global configuration file, given the * file name. */ diff --git a/epan/libwireshark.def b/epan/libwireshark.def index 1d0f340c91..5285ec31ed 100644 --- a/epan/libwireshark.def +++ b/epan/libwireshark.def @@ -386,7 +386,7 @@ get_manuf_name_if_known get_oid_name get_oid_str_name get_persconffile_path -get_plugins_global_dir +get_plugin_dir get_plugins_pers_dir get_progfile_dir get_systemfile_dir @@ -427,6 +427,7 @@ ieee802a_add_oui incomplete_tcp_stream DATA InfoRequestNakReason_vals DATA init_dissection +init_plugin_dir init_progfile_dir ip6_to_str ipv4_get_net_order_addr @@ -651,6 +652,7 @@ rtp_add_address rtp_free_hash_dyn_payload rtp_payload_type_vals DATA rtp_payload_type_short_vals DATA +running_in_build_directory scsi_mmc_vals DATA scsi_smc_vals DATA scsi_sbc_vals DATA diff --git a/epan/plugins.c b/epan/plugins.c index f663f36be9..241ee45f98 100644 --- a/epan/plugins.c +++ b/epan/plugins.c @@ -174,20 +174,23 @@ plugins_scan_dir(const char *dirname) #if GLIB_MAJOR_VERSION < 2 /* don't try to open "." and ".." */ if (!(strcmp(name, "..") && - strcmp(name, "."))) continue; + strcmp(name, "."))) + continue; /* skip anything but files with lt_lib_ext */ dot = strrchr(name, '.'); - if (dot == NULL || strcmp(dot, lt_lib_ext) != 0) continue; + if (dot == NULL || strcmp(dot, lt_lib_ext) != 0) + continue; #else /* GLIB 2 */ - /* - * GLib 2.x defines G_MODULE_SUFFIX as the extension used on this - * platform for loadable modules. - */ + /* + * GLib 2.x defines G_MODULE_SUFFIX as the extension used on + * this platform for loadable modules. + */ /* skip anything but files with G_MODULE_SUFFIX */ dot = strrchr(name, '.'); - if (dot == NULL || strcmp(dot+1, G_MODULE_SUFFIX) != 0) continue; + if (dot == NULL || strcmp(dot+1, G_MODULE_SUFFIX) != 0) + continue; #endif g_snprintf(filename, FILENAME_LEN, "%s" G_DIR_SEPARATOR_S "%s", @@ -338,59 +341,6 @@ plugins_scan_dir(const char *dirname) #endif } - -/* get the global plugin dir */ -/* Return value is malloced so the caller should g_free() it. */ -char *get_plugins_global_dir(const char *plugin_dir) -{ -#ifdef _WIN32 - char *install_plugin_dir; - - /* - * On Windows, the data file directory is the installation - * directory; the plugins are stored under it. - * - * Assume we're running the installed version of Wireshark; - * on Windows, the data file directory is the directory - * in which the Wireshark binary resides. - */ - install_plugin_dir = g_strdup_printf("%s\\plugins\\%s", get_datafile_dir(), VERSION); - - /* - * Make sure that pathname refers to a directory. - */ - if (test_for_directory(install_plugin_dir) != EISDIR) { - /* - * Either it doesn't refer to a directory or it - * refers to something that doesn't exist. - * - * Assume that means we're running, for example, - * a version of Wireshark we've built in a source - * directory, and fall back on the default - * installation directory, so you can put the plugins - * somewhere so they can be used with this version - * of Wireshark. - * - * XXX - should we, instead, have the Windows build - * procedure create a subdirectory of the "plugins" - * source directory, and copy the plugin DLLs there, - * so that you use the plugins from the build tree? - */ - g_free(install_plugin_dir); - install_plugin_dir = - g_strdup("C:\\Program Files\\Wireshark\\plugins\\" VERSION); - } - - return install_plugin_dir; -#else - /* - * Scan the plugin directory. - */ - return g_strdup(plugin_dir); -#endif -} - - /* get the personal plugin dir */ /* Return value is malloced so the caller should g_free() it. */ char *get_plugins_pers_dir(void) @@ -402,18 +352,58 @@ char *get_plugins_pers_dir(void) * init plugins */ void -init_plugins(const char *plugin_dir) +init_plugins(void) { - char *datafile_dir; + const char *plugin_dir; + const char *name; + char *plugin_dir_path; + char *plugins_pers_dir; + ETH_DIR *dir; /* scanned directory */ + ETH_DIRENT *file; /* current file */ if (plugin_list == NULL) /* ensure init_plugins is only run once */ { /* * Scan the global plugin directory. + * If we're running from a build directory, scan the subdirectories + * of that directory, as the global plugin directory is the + * "plugins" directory of the source tree, and the subdirectories + * are the source directories for the plugins, with the plugins + * built in those subdirectories. */ - datafile_dir = get_plugins_global_dir(plugin_dir); - plugins_scan_dir(datafile_dir); - g_free(datafile_dir); + plugin_dir = get_plugin_dir(); + if (running_in_build_directory()) { + if ((dir = eth_dir_open(plugin_dir, 0, NULL)) != NULL) { + while ((file = eth_dir_read_name(dir)) != NULL) { + name = eth_dir_get_name(file); + if (strcmp(name, ".") == 0 || strcmp(name, "..") == 0) + continue; /* skip "." and ".." */ + /* + * Get the full path of a ".libs" subdirectory of that + * directory. + */ + plugin_dir_path = g_strdup_printf( + "%s" G_DIR_SEPARATOR_S "%s" G_DIR_SEPARATOR_S ".libs", + plugin_dir, name); + if (test_for_directory(plugin_dir_path) != EISDIR) { + /* + * Either it doesn't refer to a directory or it + * refers to something that doesn't exist. + * + * Assume that means that the plugins are in + * the subdirectory of the plugin directory, not + * a ".libs" subdirectory of that subdirectory. + */ + g_free(plugin_dir_path); + plugin_dir_path = g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s", + plugin_dir, name); + } + plugins_scan_dir(plugin_dir_path); + g_free(plugin_dir_path); + } + } + } else + plugins_scan_dir(plugin_dir); /* * If the program wasn't started with special privileges, @@ -424,9 +414,9 @@ init_plugins(const char *plugin_dir) * reclaim them before each time we start capturing.) */ if (!started_with_special_privs()) { - datafile_dir = get_plugins_pers_dir(); - plugins_scan_dir(datafile_dir); - g_free(datafile_dir); + plugins_pers_dir = get_plugins_pers_dir(); + plugins_scan_dir(plugins_pers_dir); + g_free(plugins_pers_dir); } } } diff --git a/epan/plugins.h b/epan/plugins.h index 44d942fbc8..f806522cf9 100644 --- a/epan/plugins.h +++ b/epan/plugins.h @@ -42,14 +42,10 @@ typedef struct _plugin { WS_VAR_IMPORT plugin *plugin_list; -extern void init_plugins(const char *); +extern void init_plugins(void); extern void register_all_plugin_handoffs(void); extern void register_all_plugin_tap_listeners(void); -/* get the global plugin dir */ -/* Return value is g_malloced so the caller should g_free() it. */ -extern char *get_plugins_global_dir(const char *plugin_dir); - /* get the personal plugin dir */ /* Return value is g_malloced so the caller should g_free() it. */ extern char *get_plugins_pers_dir(void); diff --git a/epan/proto.c b/epan/proto.c index cea1820cb6..6a8c1d523a 100644 --- a/epan/proto.c +++ b/epan/proto.c @@ -279,12 +279,7 @@ proto_compare_name(gconstpointer p1_arg, gconstpointer p2_arg) /* initialize data structures and register protocols and fields */ void -proto_init(const char *plugin_dir -#ifndef HAVE_PLUGINS - _U_ -#endif - , - void (register_all_protocols)(void), +proto_init(void (register_all_protocols)(void), void (register_all_protocol_handoffs)(void)) { static hf_register_info hf[] = { @@ -294,16 +289,16 @@ proto_init(const char *plugin_dir }; - proto_names = g_hash_table_new(g_int_hash, g_int_equal); - proto_short_names = g_hash_table_new(g_int_hash, g_int_equal); - proto_filter_names = g_hash_table_new(g_int_hash, g_int_equal); + proto_names = g_hash_table_new(g_int_hash, g_int_equal); + proto_short_names = g_hash_table_new(g_int_hash, g_int_equal); + proto_filter_names = g_hash_table_new(g_int_hash, g_int_equal); proto_cleanup(); gmc_hfinfo = g_mem_chunk_new("gmc_hfinfo", sizeof(header_field_info), - INITIAL_NUM_PROTOCOL_HFINFO * sizeof(header_field_info), - G_ALLOC_ONLY); + INITIAL_NUM_PROTOCOL_HFINFO * sizeof(header_field_info), + G_ALLOC_ONLY); gpa_hfinfo.len=0; gpa_hfinfo.allocated_len=0; @@ -327,7 +322,7 @@ proto_init(const char *plugin_dir #ifdef HAVE_PLUGINS /* Now scan for plugins and load all the ones we find, calling their register routines to do the stuff described above. */ - init_plugins(plugin_dir); + init_plugins(); #endif /* Now call the "handoff registration" routines of all built-in @@ -341,8 +336,8 @@ proto_init(const char *plugin_dir register_all_plugin_handoffs(); #endif - /* sort the protocols by protocol name */ - protocols = g_list_sort(protocols, proto_compare_name); + /* sort the protocols by protocol name */ + protocols = g_list_sort(protocols, proto_compare_name); /* We've assigned all the subtree type values; allocate the array for them, and zero it out. */ diff --git a/epan/proto.h b/epan/proto.h index fbc3b890e8..786f24eb33 100644 --- a/epan/proto.h +++ b/epan/proto.h @@ -310,11 +310,9 @@ extern void proto_tree_children_foreach(proto_tree *tree, /** Retrieve the tree_data_t from a proto_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(const char *plugin_dir, - void (register_all_protocols)(void), void (register_all_handoffs)(void)); +extern void proto_init(void (register_all_protocols)(void), + void (register_all_handoffs)(void)); /** 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 3744530c8b..49a1796aed 100644 --- a/gtk/about_dlg.c +++ b/gtk/about_dlg.c @@ -257,10 +257,8 @@ about_folders_page_new(void) g_free((void *) path); /* global plugins */ - path = get_plugins_global_dir(PLUGIN_DIR); - about_folders_row(table, "Global Plugins", path, + about_folders_row(table, "Global Plugins", get_plugin_dir(), "dissector plugins"); - g_free((void *) path); #endif gtk_container_add(GTK_CONTAINER(scrolledwindow), table); diff --git a/gtk/main.c b/gtk/main.c index 8c14baeb7e..63f8ce4999 100644 --- a/gtk/main.c +++ b/gtk/main.c @@ -2138,6 +2138,11 @@ main(int argc, char *argv[]) */ get_credential_info(); + /* + * Now attempt to get the pathname of the plugins. + */ + init_plugin_dir(); + /* initialize the funnel mini-api */ initialize_funnel_ops(); @@ -2356,7 +2361,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(PLUGIN_DIR,register_all_protocols,register_all_protocol_handoffs, + epan_init(register_all_protocols,register_all_protocol_handoffs, failure_alert_box,open_failure_alert_box,read_failure_alert_box); splash_update(splash_win, "Init tap listeners ..."); @@ -724,8 +724,13 @@ main(int argc, char *argv[]) get_credential_info(); /* - * in order to have the -X otps assigned before the wslua machine starts - * we need to getopts before epan_init() gets called + * Now attempt to get the pathname of the plugins. + */ + init_plugin_dir(); + + /* + * In order to have the -X opts assigned before the wslua machine starts + * we need to call getopts before epan_init() gets called. */ opterr = 0; optind_initial = optind; @@ -773,8 +778,8 @@ 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(PLUGIN_DIR,register_all_protocols,register_all_protocol_handoffs, - failure_message,open_failure_message,read_failure_message); + epan_init(register_all_protocols, register_all_protocol_handoffs, + failure_message, open_failure_message, read_failure_message); /* Register all tap listeners; we do this before we parse the arguments, as the "-z" argument can specify a registered tap. */ |