summaryrefslogtreecommitdiff
path: root/epan/filesystem.c
diff options
context:
space:
mode:
Diffstat (limited to 'epan/filesystem.c')
-rw-r--r--epan/filesystem.c282
1 files changed, 224 insertions, 58 deletions
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)