summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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.