summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2006-02-12 03:15:29 +0000
committerGuy Harris <guy@alum.mit.edu>2006-02-12 03:15:29 +0000
commitb8136fbfa9ba5cafbd7182f82b58759ee14a6555 (patch)
treef9d78126da180e876f8d40f12089268530ce1aca
parent9bc8780a661260a2446f556914cced07644999b9 (diff)
downloadwireshark-b8136fbfa9ba5cafbd7182f82b58759ee14a6555.tar.gz
Add a routine to attempt to get the absolute pathname of the executable
file, strip off the last component to get the pathname of the directory containing the executable file, and save it for future use. On Windows, you can get that from the OS, but, on UN*X, you have to look at argv[0] and derive the absolute path from that (argv[0] is not guaranteed to be an absolute path, or even a path at all). (In addition, if you're running from the build directory, you might have to strip off a ".libs/" added to argv[0] as an artifact of the libtoolizing script.) Use that in the About dialog, and use it to construct the path of dumpcap. Don't put quotes into the path of dumpcap; you don't have to quote strings with spaces in them when handing them to execvp and, in fact, you *mustn't* quote them, as the quotes will be treated as part of the pathname. svn path=/trunk/; revision=17267
-rw-r--r--capture_sync.c6
-rw-r--r--epan/filesystem.c282
-rw-r--r--epan/filesystem.h33
-rw-r--r--globals.h1
-rw-r--r--gtk/about_dlg.c6
-rw-r--r--gtk/main.c8
6 files changed, 255 insertions, 81 deletions
diff --git a/capture_sync.c b/capture_sync.c
index 56ee2ef9b3..2e99e86263 100644
--- a/capture_sync.c
+++ b/capture_sync.c
@@ -301,7 +301,6 @@ sync_pipe_start(capture_options *capture_opts) {
enum PIPES { PIPE_READ, PIPE_WRITE }; /* Constants 0 and 1 for PIPE_READ and PIPE_WRITE */
#endif
int sync_pipe_read_fd;
- char *dirname;
char *exename;
int argc;
const char **argv;
@@ -391,9 +390,8 @@ sync_pipe_start(capture_options *capture_opts) {
#endif
/* take ethereal's absolute program path and replace ethereal with dumpcap */
- dirname = get_dirname(g_strdup(ethereal_path));
- exename = g_strdup_printf("\"%s" G_DIR_SEPARATOR_S "dumpcap\"", dirname);
- g_free(dirname);
+ exename = g_strdup_printf("%s" G_DIR_SEPARATOR_S "dumpcap",
+ get_progfile_dir());
#ifdef _WIN32
argv = sync_pipe_add_arg(argv, &argc, "-B");
diff --git a/epan/filesystem.c b/epan/filesystem.c
index 9f4a34f17d..e084c751d6 100644
--- a/epan/filesystem.c
+++ b/epan/filesystem.c
@@ -204,9 +204,218 @@ test_for_fifo(const char *path)
return 0;
}
+static char *progfile_dir;
+
+/*
+ * Get the pathname of the directory from which the executable came,
+ * and save it for future use.
+ */
+void
+init_progfile_dir(const char *arg0
+#ifdef _WIN32
+ _U_
+#endif
+)
+{
+ char *dir_end;
+ char *path;
+#ifdef _WIN32
+ char prog_pathname[_MAX_PATH+2];
+ size_t progfile_dir_len;
+
+ /*
+ * Attempt to get the full pathname of the currently running
+ * program.
+ */
+ if (GetModuleFileName(NULL, prog_pathname, sizeof prog_pathname) != 0) {
+ /*
+ * We got it; strip off the last component, which would be
+ * the file name of the executable, giving us the pathname
+ * of the directory where the executable resies
+ *
+ * First, find the last "\\" in the directory, as that
+ * marks the end of the directory pathname.
+ *
+ * XXX - Can the pathname be something such as
+ * "C:ethereal.exe"? Or is it always a full pathname
+ * beginning with "\\" after the drive letter?
+ */
+ dir_end = strrchr(prog_pathname, '\\');
+ if (dir_end != NULL) {
+ /*
+ * Found it - now figure out how long the program
+ * directory pathname will be.
+ */
+ progfile_dir_len = (dir_end - prog_pathname);
+
+ /*
+ * Allocate a buffer for the program directory
+ * pathname, and construct it.
+ */
+ path = g_malloc(progfile_dir_len + 1);
+ strncpy(path, prog_pathname, progfile_dir_len);
+ path[progfile_dir_len] = '\0';
+ progfile_dir = path;
+ }
+ }
+#else
+ char *prog_pathname;
+ char *curdir;
+ long path_max;
+ char *path_start, *path_end;
+ size_t path_component_len;
+
+ /*
+ * Try to figure out the directory in which the currently running
+ * program resides, given the argv[0] it was started with. That
+ * might be the absolute path of the program, or a path relative
+ * to the current directory of the process that started it, or
+ * just a name for the program if it was started from the command
+ * line and was searched for in $PATH. It's not guaranteed to be
+ * any of those, however, so there are no guarantees....
+ */
+ if (arg0[0] == '/') {
+ /*
+ * It's an absolute path.
+ */
+ prog_pathname = g_strdup(arg0);
+ } else if (strchr(arg0, '/') != NULL) {
+ /*
+ * It's a relative path, with a directory in it.
+ * Get the current directory, and combine it
+ * with that directory.
+ */
+ path_max = pathconf(".", _PC_PATH_MAX);
+ if (path_max == -1) {
+ /*
+ * We have no idea how big a buffer to
+ * allocate for the current directory.
+ */
+ return;
+ }
+ curdir = g_malloc(path_max);
+ if (getcwd(curdir, sizeof curdir) == NULL) {
+ /*
+ * It failed - give up, and just stick
+ * with DATAFILE_DIR.
+ */
+ g_free(curdir);
+ return;
+ }
+ path = g_malloc(strlen(curdir) + 1 + strlen(arg0) + 1);
+ strcpy(path, curdir);
+ strcat(path, "/");
+ strcat(path, arg0);
+ g_free(curdir);
+ prog_pathname = path;
+ } else {
+ /*
+ * It's just a file name.
+ * Search the path for a file with that name
+ * that's executable.
+ */
+ prog_pathname = NULL; /* haven't found it yet */
+ path_start = getenv("PATH");
+ while (path_start != NULL) {
+ /*
+ * Is there anything left in the path?
+ */
+ if (*path_start == '\0')
+ break; /* no */
+
+ path_end = strchr(path_start, ':');
+ if (path_end == NULL)
+ path_end = path_start + strlen(path_start);
+ path_component_len = path_end - path_start;
+ path = g_malloc(path_component_len + 1
+ + strlen(arg0) + 1);
+ memcpy(path, path_start, path_component_len);
+ path[path_component_len] = '\0';
+ strcat(path, "/");
+ strcat(path, arg0);
+ if (access(path, X_OK) == 0) {
+ /*
+ * Found it!
+ */
+ prog_pathname = path;
+ break;
+ }
+
+ /*
+ * That's not it. If there are more
+ * path components to test, try them.
+ */
+ if (*path_end == '\0') {
+ /*
+ * There's nothing more to try.
+ */
+ break;
+ }
+ if (*path_start == ':')
+ path_start++;
+ g_free(path);
+ }
+ }
+
+ if (prog_pathname != NULL) {
+ /*
+ * OK, we have what we think is the pathname
+ * of the program.
+ *
+ * First, find the last "/" in the directory,
+ * as that marks the end of the directory pathname.
+ */
+ dir_end = strrchr(prog_pathname, '/');
+ if (dir_end != NULL) {
+ /*
+ * Found it. Strip off the last component,
+ * as that's the path of the program.
+ */
+ *dir_end = '\0';
+
+ /*
+ * Is there a "/.libs" at the end?
+ */
+ dir_end = strrchr(prog_pathname, '/');
+ if (dir_end != NULL) {
+ if (strcmp(dir_end, "/.libs") == 0) {
+ /*
+ * Yup, it's ".libs".
+ * Strip that off; it's an
+ * artifact of libtool.
+ */
+ *dir_end = '\0';
+ }
+ }
+
+ /*
+ * OK, we have the path we want.
+ */
+ progfile_dir = prog_pathname;
+ } else {
+ /*
+ * This "shouldn't happen"; we apparently
+ * have no "/" in the pathname.
+ * Just free up prog_pathname.
+ */
+ g_free(prog_pathname);
+ }
+ }
+#endif
+}
+
+/*
+ * Get the directory in which the program resides.
+ */
+const char *
+get_progfile_dir(void)
+{
+ return progfile_dir;
+}
+
/*
- * Get the directory in which Ethereal's global configuration and data
- * files are stored.
+ * Get the directory in which the global configuration and data files are
+ * stored.
*
* XXX - if we ever make libethereal a real library, used by multiple
* applications (more than just Tethereal and versions of Ethereal with
@@ -233,68 +442,25 @@ const char *
get_datafile_dir(void)
{
#ifdef _WIN32
- char prog_pathname[_MAX_PATH+2];
- char *dir_end;
- size_t datafile_dir_len;
- static char *datafile_dir;
-
- /*
- * Have we already gotten the pathname?
- * If so, just return it.
- */
- if (datafile_dir != NULL)
- return datafile_dir;
-
- /*
- * No, we haven't.
- * Start out by assuming it's the default installation directory.
- */
- datafile_dir = "C:\\Program Files\\Ethereal\\";
-
/*
- * Now we attempt to get the full pathname of the currently running
- * program, under the assumption that we're running an installed
- * version of the program. If we fail, we don't change "datafile_dir",
- * and thus end up using the default.
+ * Do we have the pathname of the program? If so, assume we're
+ * running an installed version of the program. If we fail,
+ * we don't change "datafile_dir", and thus end up using the
+ * default.
*
* XXX - does NSIS put the installation directory into
* "\HKEY_LOCAL_MACHINE\SOFTWARE\Ethereal\InstallDir"?
* If so, perhaps we should read that from the registry,
* instead.
*/
- if (GetModuleFileName(NULL, prog_pathname, sizeof prog_pathname) != 0) {
- /*
- * If the program is an installed version, the full pathname
- * includes the pathname of the directory in which it was
- * installed; get that directory's pathname, and construct
- * from it the pathname of the directory in which the
- * plugins were installed.
- *
- * First, find the last "\\" in the directory, as that
- * marks the end of the directory pathname.
- *
- * XXX - Can the pathname be something such as
- * "C:ethereal.exe"? Or is it always a full pathname
- * beginning with "\\" after the drive letter?
- */
- dir_end = strrchr(prog_pathname, '\\');
- if (dir_end != NULL) {
- /*
- * Found it - now figure out how long the datafile
- * directory pathname will be.
- */
- datafile_dir_len = (dir_end - prog_pathname);
+ if (progfile_dir != NULL)
+ return progfile_dir;
- /*
- * Allocate a buffer for the plugin directory
- * pathname, and construct it.
- */
- datafile_dir = g_malloc(datafile_dir_len + 1);
- strncpy(datafile_dir, prog_pathname, datafile_dir_len);
- datafile_dir[datafile_dir_len] = '\0';
- }
- }
- return datafile_dir;
+ /*
+ * No, we don't.
+ * Fall back on the default installation directory.
+ */
+ return "C:\\Program Files\\Ethereal\\";
#else
/*
* Just use DATAFILE_DIR, as that's what the configure script
@@ -307,8 +473,8 @@ get_datafile_dir(void)
/*
* Get the directory in which files that, at least on UNIX, are
* system files (such as "/etc/ethers") are stored; on Windows,
- * there's no "/etc" directory, so we get them from the Ethereal
- * global configuration and data file directory.
+ * there's no "/etc" directory, so we get them from the global
+ * configuration and data file directory.
*/
const char *
get_systemfile_dir(void)
diff --git a/epan/filesystem.h b/epan/filesystem.h
index 644cabc8d3..95c8a96444 100644
--- a/epan/filesystem.h
+++ b/epan/filesystem.h
@@ -28,14 +28,14 @@
/*
* Given a pathname, return the last component.
*/
-const char *get_basename(const char *);
+extern const char *get_basename(const char *);
/*
* Given a pathname, return a string containing everything but the
* last component. NOTE: this overwrites the pathname handed into
* it....
*/
-char *get_dirname(char *);
+extern char *get_dirname(char *);
/*
* Given a pathname, return:
@@ -48,7 +48,7 @@ char *get_dirname(char *);
* 0, if the attempt succeeded and the file turned out not
* to be a directory.
*/
-int test_for_directory(const char *);
+extern int test_for_directory(const char *);
/*
* Given a pathname, return:
@@ -61,7 +61,18 @@ int test_for_directory(const char *);
* 0, if the attempt succeeded and the file turned out not
* to be a FIFO.
*/
-int test_for_fifo(const char *);
+extern int test_for_fifo(const char *);
+
+/*
+ * Get the pathname of the directory from which the executable came,
+ * and save it for future use.
+ */
+extern void init_progfile_dir(const char *arg0);
+
+/*
+ * Get the directory in which the program resides.
+ */
+extern const char *get_progfile_dir(void);
/*
* Get the directory in which global configuration and data files are
@@ -81,7 +92,7 @@ extern char *get_datafile_path(const char *filename);
* there's no "/etc" directory, so we get them from the Ethereal
* global configuration and data file directory.
*/
-const char *get_systemfile_dir(void);
+extern const char *get_systemfile_dir(void);
/*
* Create the directory that holds personal configuration files, if
@@ -90,7 +101,7 @@ const char *get_systemfile_dir(void);
* to create (it's g_mallocated, so our caller should free it); otherwise,
* return 0.
*/
-int create_persconffile_dir(char **pf_dir_path_return);
+extern int create_persconffile_dir(char **pf_dir_path_return);
/*
* Construct the path name of a personal configuration file, given the
@@ -102,7 +113,7 @@ int create_persconffile_dir(char **pf_dir_path_return);
* exists; if it does, we return that, so that configuration files
* from earlier versions can be read.
*/
-char *get_persconffile_path(const char *filename, gboolean for_writing);
+extern char *get_persconffile_path(const char *filename, gboolean for_writing);
/*
* Construct the path name of a file in $TMP/%TEMP% directory.
@@ -113,19 +124,19 @@ char *get_persconffile_path(const char *filename, gboolean for_writing);
extern char *get_tempfile_path(const char *filename);
/* Delete a file */
-gboolean deletefile (const char *path);
+extern gboolean deletefile (const char *path);
/*
* Return an error message for UNIX-style errno indications on open or
* create operations.
*/
-const char *file_open_error_message(int err, gboolean for_writing);
+extern const char *file_open_error_message(int err, gboolean for_writing);
/*
* Return an error message for UNIX-style errno indications on write
* operations.
*/
-const char *file_write_error_message(int err);
+extern const char *file_write_error_message(int err);
/*
* Check, if file is existing.
@@ -141,7 +152,7 @@ extern gboolean files_identical(const char *fname1, const char *fname2);
/*
* utf8 version of getenv, needed to get win32 filename paths
*/
-char *getenv_utf8(const char *varname);
+extern char *getenv_utf8(const char *varname);
#endif
#endif /* FILESYSTEM_H */
diff --git a/globals.h b/globals.h
index dabc2ae263..196afd28d5 100644
--- a/globals.h
+++ b/globals.h
@@ -29,7 +29,6 @@
#include <epan/timestamp.h>
extern capture_file cfile;
-extern gchar *ethereal_path;
#ifdef HAVE_LIBPCAP
/** @todo move this to the gtk dir */
extern gboolean auto_scroll_live;
diff --git a/gtk/about_dlg.c b/gtk/about_dlg.c
index 1ce192618b..da0476c744 100644
--- a/gtk/about_dlg.c
+++ b/gtk/about_dlg.c
@@ -242,11 +242,9 @@ about_folders_page_new(void)
"\"ethers\", \"ipxnets\"");
/* program */
- path = g_strdup(ethereal_path);
- path = get_dirname(path);
- about_folders_row(table, "Program", path,
+ constpath = get_progfile_dir();
+ about_folders_row(table, "Program", constpath,
"program files");
- g_free((void *) path);
#ifdef HAVE_PLUGINS
/* pers plugins */
diff --git a/gtk/main.c b/gtk/main.c
index 8232c497d3..e73704f7e5 100644
--- a/gtk/main.c
+++ b/gtk/main.c
@@ -174,7 +174,6 @@ static guint main_ctx, file_ctx, help_ctx;
static guint packets_ctx;
static gchar *packets_str = NULL;
GString *comp_info_str, *runtime_info_str;
-gchar *ethereal_path = NULL;
gboolean have_capture_file = FALSE; /* XXX - is there an aquivalent in cfile? */
#ifdef _WIN32
@@ -1917,6 +1916,11 @@ main(int argc, char *argv[])
OPTSTRING_INIT OPTSTRING_WIN32;
/*
+ * Attempt to get the pathname of the executable file.
+ */
+ init_progfile_dir(argv[0]);
+
+ /*
* Get credential information for later use.
*/
get_credential_info();
@@ -2046,8 +2050,6 @@ main(int argc, char *argv[])
init_eth_clist_type();
#endif
- ethereal_path = argv[0];
-
/* Arrange that if we have no console window, and a GLib message logging
routine is called to log a message, we pop up a console window.