Add a WIRESHARK_RUN_FROM_BUILD_DIRECTORY environment variable on UN*X;

if set, and if the program isn't running with additional privileges,
it'll treat the directory in which the program is found as the data
directory.

If, on Windows, the version-number subdirectory of {data
directory}\plugins doesn't exist (which is assumed to mean that the
program is being run from the build directory), or if, on UN*X,
WIRESHARK_RUN_FROM_BUILD_DIRECTORY is set, the plugin directory is the
"plugins" subdirectory of the data directory, and all subdirectories of
that directory are scanned for plugins, as the "plugins" subdirectory of
the build directory contains subdirectories for the plugins; this means
that if we're running from the build directory, we'll find the plugins
we built in the build tree.

When generating the wireshark-filter man page, run tshark with
WIRESHARK_RUN_FROM_BUILD_DIRECTORY set, so it uses the plugins from the
build to generate the list of filters.

svn path=/trunk/; revision=20261
This commit is contained in:
Guy Harris 2007-01-02 06:49:40 +00:00
parent 3722c2687b
commit 44c0624bd9
14 changed files with 260 additions and 136 deletions

View File

@ -66,18 +66,28 @@ main(int argc, char **argv)
e_prefs *prefs;
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);

View File

@ -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) \

View File

@ -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();

View File

@ -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),

View File

@ -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,15 +556,130 @@ get_datafile_dir(void)
}
}
#else
/*
* Just use DATAFILE_DIR, as that's what the configure script
* set it to be.
*/
datafile_dir = DATAFILE_DIR;
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);
/*
* Make sure that pathname refers to a directory.
*/
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
}
/*
* 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;
}
/*
* Get the directory in which files that, at least on UNIX, are
* system files (such as "/etc/ethers") are stored; on Windows,

View File

@ -81,6 +81,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.

View File

@ -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

View File

@ -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);
}
}
}

View File

@ -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);

View File

@ -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. */

View File

@ -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);

View File

@ -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);

View File

@ -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 ...");

View File

@ -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. */