/* filesystem.c
* Filesystem utility routines
*
- * $Id$
- *
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
* Copyright 1998 Gerald Combs
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
-#include "config.h"
+#include <config.h>
/*
* Required with GNU libc to get dladdr().
*/
#define _GNU_SOURCE
-#ifdef HAVE_DIRENT_H
-#include <dirent.h>
-#endif
-
#include <stdio.h>
-#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <glib.h>
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
-#ifdef HAVE_FCNTL_H
-#include <fcntl.h>
-#endif
-
-#ifdef HAVE_SYS_STAT_H
-#include <sys/stat.h>
-#endif
-
#ifdef _WIN32
#include <windows.h>
#include <tchar.h>
#endif /* _WIN32 */
#include "filesystem.h"
-#include <wsutil/report_err.h>
+#include <wsutil/report_message.h>
#include <wsutil/privileges.h>
#include <wsutil/file_util.h>
+#include <wsutil/utf8_entities.h>
#include <wiretap/wtap.h> /* for WTAP_ERR_SHORT_WRITE */
#define PROFILES_DIR "profiles"
#define PLUGINS_DIR_NAME "plugins"
-
-#define U3_MY_CAPTURES "\\My Captures"
+#define PROFILES_INFO_NAME "profile_files.txt"
char *persconffile_dir = NULL;
char *persdatafile_dir = NULL;
* to be a directory.
*/
-/*
- * Visual C++ on Win32 systems doesn't define these. (Old UNIX systems don't
- * define them either.)
- *
- * Visual C++ on Win32 systems doesn't define S_IFIFO, it defines _S_IFIFO.
- */
-#ifndef S_ISREG
-#define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG)
-#endif
-#ifndef S_IFIFO
-#define S_IFIFO _S_IFIFO
-#endif
-#ifndef S_ISFIFO
-#define S_ISFIFO(mode) (((mode) & S_IFMT) == S_IFIFO)
-#endif
-#ifndef S_ISDIR
-#define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
-#endif
-
int
test_for_directory(const char *path)
{
* XXX - are there OS versions that support "exe" but not "self"?
*/
struct utsname name;
- static char executable_path[PATH_MAX];
+ static char executable_path[PATH_MAX + 1];
+ ssize_t r;
if (uname(&name) == -1)
return NULL;
strcmp(name.release, "2.1") == 0 ||
strncmp(name.release, "2.1.", 4) == 0)
return NULL; /* Linux 2.0.x or 2.1.x */
- if (readlink("/proc/self/exe", executable_path, sizeof executable_path) == -1)
+ if ((r = readlink("/proc/self/exe", executable_path, PATH_MAX)) == -1)
return NULL;
+ executable_path[r] = '\0';
return executable_path;
#elif defined(__FreeBSD__) && defined(KERN_PROC_PATHNAME)
/*
* XXX - are there OS versions that support "exe" but not "curproc"
* or "self"? Are there any that support "self" but not "curproc"?
*/
- static char executable_path[PATH_MAX];
+ static char executable_path[PATH_MAX + 1];
+ ssize_t r;
- if (readlink("/proc/curproc/exe", executable_path, sizeof executable_path) == -1)
+ if ((r = readlink("/proc/curproc/exe", executable_path, PATH_MAX)) == -1)
return NULL;
+ executable_path[r] = '\0';
return executable_path;
#elif defined(__DragonFly__)
/*
* instead; it appears to be supported by all versions of DragonFly
* BSD.
*/
- static char executable_path[PATH_MAX];
+ static char executable_path[PATH_MAX + 1];
+ ssize_t r;
- if (readlink("/proc/curproc/file", executable_path, sizeof executable_path) == -1)
+ if ((r = readlink("/proc/curproc/file", executable_path, PATH_MAX)) == -1)
return NULL;
+ executable_path[r] = '\0';
return executable_path;
#elif (defined(sun) || defined(__sun)) && defined(HAVE_GETEXECNAME)
/*
#ifdef _WIN32
_U_
#endif
-, int (*main_addr)(int, char **)
+, int (*function_addr)(int, char **)
#if defined(_WIN32) || !defined(HAVE_DLADDR)
_U_
#endif
*/
if (GetModuleFileName(NULL, prog_pathname_w, G_N_ELEMENTS(prog_pathname_w)) != 0 && GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
/*
- * XXX - Should we use g_utf16_to_utf8(), as in
- * getenv_utf8()?
+ * XXX - Should we use g_utf16_to_utf8()?
*/
prog_pathname = utf_16to8(prog_pathname_w);
/*
char *prog_pathname;
char *curdir;
long path_max;
- char *pathstr;
- char *path_start, *path_end;
+ const char *pathstr;
+ const char *path_start, *path_end;
size_t path_component_len, path_len;
char *retstr;
char *path;
* set, causes us to look for plugins and the like in the build
* directory.)
*/
- if (getenv("WIRESHARK_RUN_FROM_BUILD_DIRECTORY") != NULL
+ if (g_getenv("WIRESHARK_RUN_FROM_BUILD_DIRECTORY") != NULL
&& !started_with_special_privs())
running_in_build_directory_flag = TRUE;
execname = get_executable_path();
#ifdef HAVE_DLADDR
- if (main_addr != NULL && execname == NULL) {
+ if (function_addr != NULL && execname == NULL) {
/*
* Try to use dladdr() to find the pathname of the executable.
* dladdr() is not guaranteed to give you anything better than
* path and obviate the need for us to determine the absolute
* path.
*/
- if (dladdr((void *)main_addr, &info))
+DIAG_OFF(pedantic)
+ if (dladdr((void *)function_addr, &info)) {
+DIAG_ON(pedantic)
execname = info.dli_fname;
+ }
}
#endif
if (execname == NULL) {
* that's executable.
*/
prog_pathname = NULL; /* haven't found it yet */
- pathstr = getenv("PATH");
+ pathstr = g_getenv("PATH");
path_start = pathstr;
if (path_start != NULL) {
while (*path_start != '\0') {
if (!started_with_special_privs())
running_in_build_directory_flag = TRUE;
}
+ else if (!started_with_special_privs()) {
+ /*
+ * Check for the CMake output directory. As people may name
+ * their directories "run" (really?), also check for the
+ * CMakeCache.txt file before assuming a CMake output dir.
+ */
+ if (strcmp(dir_end, "/run") == 0) {
+ gchar *cmake_file;
+ cmake_file = g_strdup_printf("%.*s/CMakeCache.txt",
+ (int)(dir_end - prog_pathname),
+ prog_pathname);
+ if (file_exists(cmake_file))
+ running_in_build_directory_flag = TRUE;
+ g_free(cmake_file);
+ }
#ifdef __APPLE__
- else {
- if (!started_with_special_privs()) {
+ if (!running_in_build_directory_flag) {
/*
* Scan up the path looking for a component
* named "Contents". If we find it, we assume
p--;
}
}
- }
#endif
+ }
}
/*
const char *
get_datafile_dir(void)
{
-#ifdef _WIN32
- char *u3deviceexecpath;
-#endif
static const char *datafile_dir = NULL;
if (datafile_dir != NULL)
#ifdef _WIN32
/*
- * See if we are running in a U3 environment.
+ * 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\Wireshark\InstallDir"?
+ * If so, perhaps we should read that from the registry,
+ * instead.
*/
- u3deviceexecpath = getenv_utf8("U3_DEVICE_EXEC_PATH");
-
- if (u3deviceexecpath != NULL) {
+ if (progfile_dir != NULL) {
/*
- * We are; use the U3 device executable path.
+ * Yes, we do; use that.
*/
- datafile_dir = u3deviceexecpath;
+ datafile_dir = progfile_dir;
} else {
/*
- * 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\Wireshark\InstallDir"?
- * If so, perhaps we should read that from the registry,
- * instead.
+ * No, we don't.
+ * Fall back on the default installation directory.
*/
- if (progfile_dir != NULL) {
- /*
- * Yes, we do; use that.
- */
- datafile_dir = progfile_dir;
- } else {
- /*
- * No, we don't.
- * Fall back on the default installation directory.
- */
- datafile_dir = "C:\\Program Files\\Wireshark\\";
- }
+ datafile_dir = "C:\\Program Files\\Wireshark\\";
}
#else
* Use the top-level source directory as the datafile directory
* because most of our data files (radius/, COPYING) are there.
*/
- datafile_dir = g_strdup(TOP_SRCDIR);
+#ifdef TOP_SRCDIR
+ /*
+ * When TOP_SRCDIR is defined, assume autotools where files are not
+ * copied to the build directory. This fallback location is relied on by
+ * wslua_get_actual_filename().
+ */
+ datafile_dir = TOP_SRCDIR;
+#else
+ /*
+ * Otherwise assume CMake. Here, data files (console.lua, radius/, etc.)
+ * are copied to the build directory during the build.
+ */
+ datafile_dir = BUILD_TIME_DATAFILE_DIR;
+#endif
return datafile_dir;
} else {
- if (getenv("WIRESHARK_DATA_DIR") && !started_with_special_privs()) {
+ if (g_getenv("WIRESHARK_DATA_DIR") && !started_with_special_privs()) {
/*
* The user specified a different directory for data files
* and we aren't running with special privileges.
* XXX - We might be able to dispense with the priv check
*/
- datafile_dir = g_strdup(getenv("WIRESHARK_DATA_DIR"));
+ datafile_dir = g_strdup(g_getenv("WIRESHARK_DATA_DIR"));
}
#ifdef __APPLE__
/*
return datafile_dir;
}
-#ifdef HAVE_PYTHON
+#if defined(HAVE_PLUGINS) || defined(HAVE_LUA)
/*
- * Find the directory where the python dissectors are stored.
+ * Find the directory where the plugins are stored.
*
- * On Windows, we use the "py_dissector" subdirectory of the datafile directory.
+ * On Windows, we use the plugin\{VERSION} subdirectory of the datafile
+ * directory, where {VERSION} is the version number of this version of
+ * Wireshark.
*
- * On UN*X, we use the PYTHON_DIR value supplied by the configure
- * script, unless we think we're being run from the build directory,
- * in which case we use the "py_dissector" subdirectory of the datafile directory.
+ * On UN*X:
*
- * In both cases, we then use the subdirectory of that directory whose
- * name is the version number.
+ * if we appear to be run from the build directory, we use the
+ * "plugin" subdirectory of the datafile directory;
*
- * XXX - if we think we're being run from the build directory, 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.
+ * otherwise, if the WIRESHARK_PLUGIN_DIR environment variable is
+ * set and we aren't running with special privileges, we use the
+ * value of that environment variable;
+ *
+ * otherwise, if we're running from an app bundle in macOS, we
+ * use the Contents/PlugIns/wireshark subdirectory of the app bundle;
+ *
+ * otherwise, we use the PLUGIN_DIR value supplied by the
+ * configure script.
*/
-static const char *wspython_dir = NULL;
+static char *plugin_dir = NULL;
+static char *plugin_pers_dir = NULL;
static void
-init_wspython_dir(void)
+init_plugin_dir(void)
{
#ifdef _WIN32
/*
* On Windows, the data file directory is the installation
- * directory; the python dissectors are stored under it.
+ * 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.
*/
- wspython_dir = g_strdup_printf("%s\\python\\%s", get_datafile_dir(),
- VERSION);
+ plugin_dir = g_build_filename(get_datafile_dir(), "plugins", VERSION, (gchar *)NULL);
/*
* Make sure that pathname refers to a directory.
*/
- if (test_for_directory(wspython_dir) != EISDIR) {
+ 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}\python is the
+ * 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 python dissectors.
+ * directory for plugins.
*/
- g_free( (gpointer) wspython_dir);
- wspython_dir = g_strdup_printf("%s\\python", get_datafile_dir());
+ g_free(plugin_dir);
+ plugin_dir = g_build_filename(get_datafile_dir(), "plugins", (gchar *)NULL);
running_in_build_directory_flag = TRUE;
}
#else
/*
* We're (probably) being run from the build directory and
* weren't started with special privileges, so we'll use
- * the "python" subdirectory of the datafile directory
- * (the datafile directory is the build directory).
+ * the "plugins" subdirectory of the directory where the program
+ * we're running is (that's the build directory).
*/
- wspython_dir = g_strdup_printf("%s/epan/wspython/", get_datafile_dir());
+ plugin_dir = g_build_filename(get_progfile_dir(), "plugins", (gchar *)NULL);
} else {
- if (getenv("WIRESHARK_PYTHON_DIR") && !started_with_special_privs()) {
+ if (g_getenv("WIRESHARK_PLUGIN_DIR") && !started_with_special_privs()) {
/*
* The user specified a different directory for plugins
* and we aren't running with special privileges.
*/
- wspython_dir = g_strdup(getenv("WIRESHARK_PYTHON_DIR"));
+ plugin_dir = g_strdup(g_getenv("WIRESHARK_PLUGIN_DIR"));
}
#ifdef __APPLE__
/*
* If we're running from an app bundle and weren't started
- * with special privileges, use the Contents/Resources/lib/wireshark/python
+ * with special privileges, use the Contents/PlugIns/wireshark
* subdirectory of the app bundle.
*
* (appbundle_dir is not set to a non-null value if we're
* it; we don't need to call started_with_special_privs().)
*/
else if (appbundle_dir != NULL) {
- wspython_dir = g_strdup_printf("%s/Contents/Resources/lib/wireshark/python",
- appbundle_dir);
+ plugin_dir = g_build_filename(appbundle_dir, "Contents/PlugIns/wireshark", (gchar *)NULL);
}
#endif
else {
- wspython_dir = PYTHON_DIR;
+ plugin_dir = g_strdup(PLUGIN_DIR);
}
}
#endif
}
-#endif /* HAVE_PYTHON */
+
+static void
+init_plugin_pers_dir(void)
+{
+#ifdef _WIN32
+ plugin_pers_dir = get_persconffile_path(PLUGINS_DIR_NAME, FALSE);
+#else
+ plugin_pers_dir = g_build_filename(g_get_home_dir(), ".local/lib/wireshark/" PLUGINS_DIR_NAME, (gchar *)NULL);
+#endif
+}
+
+#endif /* HAVE_PLUGINS || HAVE_LUA */
/*
- * Get the directory in which the python dissectors are stored.
+ * Get the directory in which the plugins are stored.
*/
const char *
-get_wspython_dir(void)
+get_plugins_dir(void)
{
-#ifdef HAVE_PYTHON
- if (!wspython_dir) init_wspython_dir();
- return wspython_dir;
+#if defined(HAVE_PLUGINS) || defined(HAVE_LUA)
+ if (!plugin_dir) init_plugin_dir();
+ return plugin_dir;
#else
return NULL;
#endif
}
-
+/* Get the personal plugin dir */
+const char *
+get_plugins_pers_dir(void)
+{
#if defined(HAVE_PLUGINS) || defined(HAVE_LUA)
+ if (!plugin_pers_dir)
+ init_plugin_pers_dir();
+ return plugin_pers_dir;
+#else
+ return NULL;
+#endif
+}
+
+#if defined(HAVE_EXTCAP)
/*
- * Find the directory where the plugins are stored.
+ * Find the directory where the extcap hooks are stored.
*
- * On Windows, we use the "plugin" subdirectory of the datafile directory.
+ * On Windows, we use the "extcap" subdirectory of the datafile directory.
*
- * On UN*X, we use the PLUGIN_DIR value supplied by the configure
+ * On UN*X, we use the EXTCAP_DIR value supplied by the configure
* script, unless we think we're being run from the build directory,
- * in which case we use the "plugin" subdirectory of the datafile directory.
+ * in which case we use the "extcap" subdirectory of the datafile directory.
*
* In both cases, we then use the subdirectory of that directory whose
* name is the version number.
*
* XXX - if we think we're being run from the build directory, 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
+ * should have the extcap code not look in the version subdirectory
+ * of the extcap directory, but look in all of the subdirectories
+ * of the extcap directory, so it can just fetch the extcap hooks built
* as part of the build process.
*/
-static const char *plugin_dir = NULL;
+static char *extcap_dir = NULL;
-static void
-init_plugin_dir(void)
-{
+static void init_extcap_dir(void) {
#ifdef _WIN32
+ const char *alt_extcap_path;
+
/*
* On Windows, the data file directory is the installation
- * directory; the plugins are stored under it.
+ * directory; the extcap hooks 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) {
+ alt_extcap_path = g_getenv("WIRESHARK_EXTCAP_DIR");
+ if (alt_extcap_path) {
/*
- * 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.
+ * The user specified a different directory for extcap hooks.
*/
- g_free( (gpointer) plugin_dir);
- plugin_dir = g_strdup_printf("%s\\plugins", get_datafile_dir());
- running_in_build_directory_flag = TRUE;
+ extcap_dir = g_strdup(alt_extcap_path);
+ } else {
+ extcap_dir = g_build_filename(get_datafile_dir(), "extcap", (gchar *)NULL);
}
#else
if (running_in_build_directory_flag) {
/*
* We're (probably) being run from the build directory and
* weren't started with special privileges, so we'll use
- * the "plugins" subdirectory of the directory where the program
+ * the "extcap hooks" subdirectory of the directory where the program
* we're running is (that's the build directory).
*/
- plugin_dir = g_strdup_printf("%s/plugins", get_progfile_dir());
+ extcap_dir = g_build_filename(get_progfile_dir(), "extcap", (gchar *)NULL);
} else {
- if (getenv("WIRESHARK_PLUGIN_DIR") && !started_with_special_privs()) {
+ if (g_getenv("WIRESHARK_EXTCAP_DIR") && !started_with_special_privs()) {
/*
- * The user specified a different directory for plugins
+ * The user specified a different directory for extcap hooks
* and we aren't running with special privileges.
*/
- plugin_dir = g_strdup(getenv("WIRESHARK_PLUGIN_DIR"));
+ extcap_dir = g_strdup(g_getenv("WIRESHARK_EXTCAP_DIR"));
}
#ifdef __APPLE__
/*
* If we're running from an app bundle and weren't started
- * with special privileges, use the Contents/Resources/lib/wireshark/plugins
+ * with special privileges, use the Contents/MacOS/extcap
* subdirectory of the app bundle.
*
* (appbundle_dir is not set to a non-null value if we're
* it; we don't need to call started_with_special_privs().)
*/
else if (appbundle_dir != NULL) {
- plugin_dir = g_strdup_printf("%s/Contents/Resources/lib/wireshark/plugins",
- appbundle_dir);
+ extcap_dir = g_build_filename(appbundle_dir, "Contents/MacOS/extcap", (gchar *)NULL);
}
#endif
else {
- plugin_dir = PLUGIN_DIR;
+ extcap_dir = g_strdup(EXTCAP_DIR);
}
}
#endif
}
-#endif /* HAVE_PLUGINS || HAVE_LUA */
+#endif /* HAVE_EXTCAP */
/*
- * Get the directory in which the plugins are stored.
+ * Get the directory in which the extcap hooks are stored.
+ *
+ * XXX - A fix instead of HAVE_EXTCAP must be found
*/
const char *
-get_plugin_dir(void)
-{
-#if defined(HAVE_PLUGINS) || defined(HAVE_LUA)
- if (!plugin_dir) init_plugin_dir();
- return plugin_dir;
+get_extcap_dir(void) {
+#if defined(HAVE_EXTCAP)
+ if (!extcap_dir)
+ init_extcap_dir();
+ return extcap_dir;
#else
return NULL;
#endif
#endif
}
-/*
- * Name of directory, under the user's home directory, in which
- * personal configuration files are stored.
- */
-#ifdef _WIN32
-#define PF_DIR "Wireshark"
-#else
-/*
- * XXX - should this be ".libepan"? For backwards-compatibility, I'll keep
- * it ".wireshark" for now.
- */
-#define PF_DIR ".wireshark"
-#endif
-
void
set_profile_name(const gchar *profilename)
{
{
WS_DIR *dir;
WS_DIRENT *file;
- const gchar *global_dir = get_global_profiles_dir();
+ gchar *global_dir = get_global_profiles_dir();
gchar *filename;
gboolean has_global = FALSE;
}
ws_dir_close(dir);
}
-
+ g_free(global_dir);
return has_global;
}
}
/*
- * Get the directory in which personal configuration files reside;
- * in UNIX-compatible systems, it's ".wireshark", under the user's home
- * directory, and on Windows systems, it's "Wireshark", under %APPDATA%
- * or, if %APPDATA% isn't set, it's "%USERPROFILE%\Application Data"
- * (which is what %APPDATA% normally is on Windows 2000).
+ * Get the directory in which personal configuration files reside.
+ *
+ * On Windows, it's "Wireshark", under %APPDATA% or, if %APPDATA% isn't set,
+ * it's "%USERPROFILE%\Application Data" (which is what %APPDATA% normally
+ * is on Windows 2000).
+ *
+ * On UNIX-compatible systems, we first look in XDG_CONFIG_HOME/wireshark
+ * and, if that doesn't exist, ~/.wireshark, for backwards compatibility.
+ * If neither exists, we use XDG_CONFIG_HOME/wireshark, so that the directory
+ * is initially created as XDG_CONFIG_HOME/wireshark. We use that regardless
+ * of whether the user is running under an XDG desktop or not, so that
+ * if the user's home directory is on a server and shared between
+ * different desktop environments on different machines, they can all
+ * share the same configuration file directory.
+ *
+ * XXX - what about stuff that shouldn't be shared between machines,
+ * such as plugins in the form of shared loadable images?
*/
static const char *
get_persconffile_dir_no_profile(void)
{
#ifdef _WIN32
- char *appdatadir;
- char *userprofiledir;
- char *altappdatapath;
+ const char *env;
#else
- const char *homedir;
+ char *xdg_path, *path;
struct passwd *pwd;
+ const char *homedir;
#endif
/* Return the cached value, if available */
/*
* See if the user has selected an alternate environment.
*/
- altappdatapath = getenv_utf8("WIRESHARK_APPDATA");
- if (altappdatapath != NULL) {
- persconffile_dir = altappdatapath;
+ env = g_getenv("WIRESHARK_APPDATA");
+ if (env != NULL) {
+ persconffile_dir = g_strdup(env);
return persconffile_dir;
}
/*
- * See if we are running in a U3 environment.
+ * Use %APPDATA% or %USERPROFILE%, so that configuration
+ * files are stored in the user profile, rather than in
+ * the home directory. The Windows convention is to store
+ * configuration information in the user profile, and doing
+ * so means you can use Wireshark even if the home directory
+ * is an inaccessible network drive.
*/
- altappdatapath = getenv_utf8("U3_APP_DATA_PATH");
- if (altappdatapath != NULL) {
+ env = g_getenv("APPDATA");
+ if (env != NULL) {
/*
- * We are; use the U3 application data path.
+ * Concatenate %APPDATA% with "\Wireshark".
*/
- persconffile_dir = altappdatapath;
- } else {
- /*
- * Use %APPDATA% or %USERPROFILE%, so that configuration
- * files are stored in the user profile, rather than in
- * the home directory. The Windows convention is to store
- * configuration information in the user profile, and doing
- * so means you can use Wireshark even if the home directory
- * is an inaccessible network drive.
- */
- appdatadir = getenv_utf8("APPDATA");
- if (appdatadir != NULL) {
- /*
- * Concatenate %APPDATA% with "\Wireshark".
- */
- persconffile_dir = g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s",
- appdatadir, PF_DIR);
- } else {
- /*
- * OK, %APPDATA% wasn't set, so use
- * %USERPROFILE%\Application Data.
- */
- userprofiledir = getenv_utf8("USERPROFILE");
- if (userprofiledir != NULL) {
- persconffile_dir = g_strdup_printf(
- "%s" G_DIR_SEPARATOR_S "Application Data" G_DIR_SEPARATOR_S "%s",
- userprofiledir, PF_DIR);
- } else {
- /*
- * Give up and use "C:".
- */
- persconffile_dir = g_strdup_printf("C:" G_DIR_SEPARATOR_S "%s", PF_DIR);
- }
- }
+ persconffile_dir = g_build_filename(env, "Wireshark", NULL);
+ return persconffile_dir;
+ }
+
+ /*
+ * OK, %APPDATA% wasn't set, so use %USERPROFILE%\Application Data.
+ */
+ env = g_getenv("USERPROFILE");
+ if (env != NULL) {
+ persconffile_dir = g_build_filename(env, "Application Data", "Wireshark", NULL);
+ return persconffile_dir;
}
+
+ /*
+ * Give up and use "C:".
+ */
+ persconffile_dir = g_build_filename("C:", "Wireshark", NULL);
+ return persconffile_dir;
#else
/*
- * If $HOME is set, use that.
+ * Check if XDG_CONFIG_HOME/wireshark exists and is a directory.
*/
- homedir = getenv("HOME");
+ xdg_path = g_build_filename(g_get_user_config_dir(), "wireshark", NULL);
+ if (g_file_test(xdg_path, G_FILE_TEST_IS_DIR)) {
+ persconffile_dir = xdg_path;
+ return persconffile_dir;
+ }
+
+ /*
+ * It doesn't exist, or it does but isn't a directory, so try
+ * ~/.wireshark.
+ *
+ * If $HOME is set, use that for ~.
+ *
+ * (Note: before GLib 2.36, g_get_home_dir() didn't look at $HOME,
+ * but we always want to do so, so we don't use g_get_home_dir().)
+ */
+ homedir = g_getenv("HOME");
if (homedir == NULL) {
/*
+ * It's not set.
+ *
* Get their home directory from the password file.
* If we can't even find a password file entry for them,
* use "/tmp".
homedir = "/tmp";
}
}
- persconffile_dir = g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s", homedir, PF_DIR);
-#endif
+ path = g_build_filename(homedir, ".wireshark", NULL);
+ if (g_file_test(path, G_FILE_TEST_IS_DIR)) {
+ g_free(xdg_path);
+ persconffile_dir = path;
+ return persconffile_dir;
+ }
+ /*
+ * Neither are directories that exist; use the XDG path, so we'll
+ * create that as necessary.
+ */
+ g_free(path);
+ persconffile_dir = xdg_path;
return persconffile_dir;
+#endif
}
void
persconffile_dir = g_strdup(p);
}
-const char *
+char *
get_profiles_dir(void)
{
- static char *profiles_dir = NULL;
-
- g_free (profiles_dir);
- profiles_dir = g_strdup_printf ("%s%s%s", get_persconffile_dir_no_profile (),
+ return g_strdup_printf ("%s%s%s", get_persconffile_dir_no_profile (),
G_DIR_SEPARATOR_S, PROFILES_DIR);
-
- return profiles_dir;
}
-const char *
-get_global_profiles_dir(void)
+int
+create_profiles_dir(char **pf_dir_path_return)
{
- static char *global_profiles_dir = NULL;
+ char *pf_dir_path;
+ ws_statb64 s_buf;
- if (!global_profiles_dir) {
- global_profiles_dir = g_strdup_printf ("%s%s%s", get_datafile_dir(),
- G_DIR_SEPARATOR_S, PROFILES_DIR);
+ /*
+ * Create the "Default" personal configuration files directory, if necessary.
+ */
+ if (create_persconffile_profile (NULL, pf_dir_path_return) == -1) {
+ return -1;
}
- return global_profiles_dir;
+ /*
+ * Check if profiles directory exists.
+ * If not then create it.
+ */
+ pf_dir_path = get_profiles_dir ();
+ if (ws_stat64(pf_dir_path, &s_buf) != 0) {
+ if (errno != ENOENT) {
+ /* Some other problem; give up now. */
+ *pf_dir_path_return = pf_dir_path;
+ return -1;
+ }
+
+ /*
+ * It doesn't exist; try to create it.
+ */
+ int ret = ws_mkdir(pf_dir_path, 0755);
+ if (ret == -1) {
+ *pf_dir_path_return = pf_dir_path;
+ return ret;
+ }
+ }
+ g_free(pf_dir_path);
+
+ return 0;
}
-static const char *
-get_persconffile_dir(const gchar *profilename)
+char *
+get_global_profiles_dir(void)
{
- static char *persconffile_profile_dir = NULL;
+ return g_strdup_printf ("%s%s%s", get_datafile_dir(),
+ G_DIR_SEPARATOR_S, PROFILES_DIR);
+}
- g_free (persconffile_profile_dir);
+static char *
+get_persconffile_dir(const gchar *profilename)
+{
+ char *persconffile_profile_dir = NULL, *profile_dir;
if (profilename && strlen(profilename) > 0 &&
strcmp(profilename, DEFAULT_PROFILE) != 0) {
- persconffile_profile_dir = g_strdup_printf ("%s%s%s", get_profiles_dir (),
+ profile_dir = get_profiles_dir();
+ persconffile_profile_dir = g_strdup_printf ("%s%s%s", profile_dir,
G_DIR_SEPARATOR_S, profilename);
+ g_free(profile_dir);
} else {
persconffile_profile_dir = g_strdup (get_persconffile_dir_no_profile ());
}
gboolean
profile_exists(const gchar *profilename, gboolean global)
{
+ gchar *path = NULL, *global_path;
if (global) {
- gchar *path = g_strdup_printf ("%s%s%s", get_global_profiles_dir(),
+ global_path = get_global_profiles_dir();
+ path = g_strdup_printf ("%s%s%s", global_path,
G_DIR_SEPARATOR_S, profilename);
+ g_free(global_path);
if (test_for_directory (path) == EISDIR) {
g_free (path);
return TRUE;
}
- g_free (path);
} else {
- if (test_for_directory (get_persconffile_dir (profilename)) == EISDIR) {
+ path = get_persconffile_dir (profilename);
+ if (test_for_directory (path) == EISDIR) {
+ g_free (path);
return TRUE;
}
}
+ g_free (path);
return FALSE;
}
return ret;
}
+static int
+reset_default_profile(char **pf_dir_path_return)
+{
+ char *profile_dir = get_persconffile_dir(NULL);
+ gchar *filename, *del_file;
+ GList *files, *file;
+ int ret = 0;
+
+ files = g_hash_table_get_keys(profile_files);
+ file = g_list_first(files);
+ while (file) {
+ filename = (gchar *)file->data;
+ del_file = g_strdup_printf("%s%s%s", profile_dir, G_DIR_SEPARATOR_S, filename);
+
+ if (file_exists(del_file)) {
+ ret = ws_remove(del_file);
+ if (ret != 0) {
+ *pf_dir_path_return = profile_dir;
+ g_free(del_file);
+ return ret;
+ }
+ }
+
+ g_free(del_file);
+ file = g_list_next(file);
+ }
+ g_list_free(files);
+
+ g_free(profile_dir);
+ return 0;
+}
+
int
delete_persconffile_profile(const char *profilename, char **pf_dir_path_return)
{
- const char *profile_dir = get_persconffile_dir(profilename);
+ if (strcmp(profilename, DEFAULT_PROFILE) == 0) {
+ return reset_default_profile(pf_dir_path_return);
+ }
+
+ char *profile_dir = get_persconffile_dir(profilename);
int ret = 0;
if (test_for_directory (profile_dir) == EISDIR) {
ret = delete_directory (profile_dir, pf_dir_path_return);
}
+ g_free(profile_dir);
return ret;
}
rename_persconffile_profile(const char *fromname, const char *toname,
char **pf_from_dir_path_return, char **pf_to_dir_path_return)
{
- char *from_dir = g_strdup (get_persconffile_dir(fromname));
- char *to_dir = g_strdup (get_persconffile_dir(toname));
+ char *from_dir = get_persconffile_dir(fromname);
+ char *to_dir = get_persconffile_dir(toname);
int ret = 0;
ret = ws_rename (from_dir, to_dir);
if (ret != 0) {
- *pf_from_dir_path_return = g_strdup (from_dir);
- *pf_to_dir_path_return = g_strdup (to_dir);
+ *pf_from_dir_path_return = from_dir;
+ *pf_to_dir_path_return = to_dir;
+ return ret;
}
g_free (from_dir);
g_free (to_dir);
- return ret;
+ return 0;
}
/*
int
create_persconffile_profile(const char *profilename, char **pf_dir_path_return)
{
- const char *pf_dir_path;
+ char *pf_dir_path;
#ifdef _WIN32
char *pf_dir_path_copy, *pf_dir_parent_path;
size_t pf_dir_parent_path_len;
+ int save_errno;
#endif
ws_statb64 s_buf;
int ret;
if (profilename) {
/*
- * Create the "Default" personal configuration files directory, if necessary.
+ * Create the personal profiles directory, if necessary.
*/
- if (create_persconffile_profile (NULL, pf_dir_path_return) == -1) {
+ if (create_profiles_dir(pf_dir_path_return) == -1) {
return -1;
}
-
- /*
- * Check if profiles directory exists.
- * If not then create it.
- */
- pf_dir_path = get_profiles_dir ();
- if (ws_stat64(pf_dir_path, &s_buf) != 0 && errno == ENOENT) {
- ret = ws_mkdir(pf_dir_path, 0755);
- if (ret == -1) {
- *pf_dir_path_return = g_strdup(pf_dir_path);
- return ret;
- }
- }
}
pf_dir_path = get_persconffile_dir(profilename);
- if (ws_stat64(pf_dir_path, &s_buf) != 0 && errno == ENOENT) {
+ if (ws_stat64(pf_dir_path, &s_buf) != 0) {
+ if (errno != ENOENT) {
+ /* Some other problem; give up now. */
+ *pf_dir_path_return = pf_dir_path;
+ return -1;
+ }
#ifdef _WIN32
/*
* Does the parent directory of that directory
if (pf_dir_parent_path_len > 0
&& pf_dir_parent_path[pf_dir_parent_path_len - 1] != ':'
&& ws_stat64(pf_dir_parent_path, &s_buf) != 0) {
+ /*
+ * Not a drive letter and the stat() failed.
+ */
+ if (errno != ENOENT) {
+ /* Some other problem; give up now. */
+ *pf_dir_path_return = pf_dir_path;
+ save_errno = errno;
+ g_free(pf_dir_path_copy);
+ errno = save_errno;
+ return -1;
+ }
/*
* No, it doesn't exist - make it first.
*/
ret = ws_mkdir(pf_dir_parent_path, 0755);
if (ret == -1) {
*pf_dir_path_return = pf_dir_parent_path;
+ save_errno = errno;
+ g_free(pf_dir_path);
+ errno = save_errno;
return -1;
}
}
g_free(pf_dir_path_copy);
ret = ws_mkdir(pf_dir_path, 0755);
#else
- ret = ws_mkdir(pf_dir_path, 0755);
+ ret = g_mkdir_with_parents(pf_dir_path, 0755);
#endif
} else {
/*
ret = 0;
}
if (ret == -1)
- *pf_dir_path_return = g_strdup(pf_dir_path);
+ *pf_dir_path_return = pf_dir_path;
+ else
+ g_free(pf_dir_path);
+
return ret;
}
int
create_persconffile_dir(char **pf_dir_path_return)
{
- return create_persconffile_profile(persconfprofile, pf_dir_path_return);
+ return create_persconffile_profile(persconfprofile, pf_dir_path_return);
}
int
char **pf_filename_return, char **pf_to_dir_path_return, char **pf_from_dir_path_return)
{
gchar *from_dir;
- gchar *to_dir = g_strdup (get_persconffile_dir(toname));
- gchar *filename, *from_file, *to_file;
+ gchar *to_dir = get_persconffile_dir(toname);
+ gchar *filename, *from_file, *to_file, *global_path;
GList *files, *file;
if (from_global) {
if (strcmp(fromname, DEFAULT_PROFILE) == 0) {
- from_dir = g_strdup (get_global_profiles_dir());
+ from_dir = get_global_profiles_dir();
} else {
- from_dir = g_strdup_printf ("%s%s%s", get_global_profiles_dir(), G_DIR_SEPARATOR_S, fromname);
+ global_path = get_global_profiles_dir();
+ from_dir = g_strdup_printf ("%s%s%s", global_path, G_DIR_SEPARATOR_S, fromname);
+ g_free(global_path);
}
} else {
- from_dir = g_strdup (get_persconffile_dir(fromname));
+ from_dir = get_persconffile_dir(fromname);
}
files = g_hash_table_get_keys(profile_files);
/*
* Get the (default) directory in which personal data is stored.
*
- * On Win32, this is the "My Documents" folder in the personal profile,
- * except that, if we're running from a U3 device, this is the
- * "$U3_DEVICE_DOCUMENT_PATH\My Captures" folder.
+ * On Win32, this is the "My Documents" folder in the personal profile.
* On UNIX this is simply the current directory.
*/
/* XXX - should this and the get_home_dir() be merged? */
get_persdatafile_dir(void)
{
#ifdef _WIN32
- char *u3devicedocumentpath;
TCHAR tszPath[MAX_PATH];
/* Return the cached value, if available */
return persdatafile_dir;
/*
- * See if we are running in a U3 environment.
+ * Hint: SHGetFolderPath is not available on MSVC 6 - without
+ * Platform SDK
*/
- u3devicedocumentpath = getenv_utf8("U3_DEVICE_DOCUMENT_PATH");
-
- if (u3devicedocumentpath != NULL) {
- /* the "My Captures" sub-directory is created (if it doesn't
- exist) by u3util.exe when the U3 Wireshark is first run */
-
- persdatafile_dir = g_strdup_printf("%s%s", u3devicedocumentpath, U3_MY_CAPTURES);
+ if (SHGetSpecialFolderPath(NULL, tszPath, CSIDL_PERSONAL, FALSE)) {
+ persdatafile_dir = g_utf16_to_utf8(tszPath, -1, NULL, NULL, NULL);
return persdatafile_dir;
} else {
- /*
- * Hint: SHGetFolderPath is not available on MSVC 6 - without
- * Platform SDK
- */
- if (SHGetSpecialFolderPath(NULL, tszPath, CSIDL_PERSONAL, FALSE)) {
- persdatafile_dir = g_utf16_to_utf8(tszPath, -1, NULL, NULL, NULL);
- return persdatafile_dir;
- } else {
- return "";
- }
+ return "";
}
#else
return "";
get_home_dir(void)
{
static const char *home = NULL;
- char *homedrive, *homepath;
+ const char *homedrive, *homepath;
char *homestring;
char *lastsep;
* Is there a chance that it might be set but one or more of
* HOMEDRIVE or HOMEPATH isn't set?
*/
- homedrive = getenv_utf8("HOMEDRIVE");
+ homedrive = g_getenv("HOMEDRIVE");
if (homedrive != NULL) {
- homepath = getenv_utf8("HOMEPATH");
+ homepath = g_getenv("HOMEPATH");
if (homepath != NULL) {
/*
* This is cached, so we don't need to worry about
char *
get_persconffile_path(const char *filename, gboolean from_profile)
{
- char *path;
+ char *path, *dir = NULL;
+
if (do_store_persconffiles && from_profile && !g_hash_table_lookup (profile_files, filename)) {
/* Store filenames so we know which filenames belongs to a configuration profile */
g_hash_table_insert (profile_files, g_strdup(filename), g_strdup(filename));
}
if (from_profile) {
- path = g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s",
- get_persconffile_dir(persconfprofile), filename);
+ dir = get_persconffile_dir(persconfprofile);
} else {
- path = g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s",
- get_persconffile_dir(NULL), filename);
+ dir = get_persconffile_dir(NULL);
}
+ path = g_build_filename(dir, filename, NULL);
+ g_free(dir);
return path;
}
char *
get_datafile_path(const char *filename)
{
- if (running_in_build_directory_flag && !strcmp(filename, "AUTHORS-SHORT")) {
+ if (running_in_build_directory_flag &&
+ (!strcmp(filename, "AUTHORS-SHORT") ||
+ !strcmp(filename, "hosts"))) {
/* We're running in the build directory and the requested file is a
- * generated file. Return the file name in the build directory (not
- * in the source/data directory).
+ * generated (or a test) file. Return the file name in the build
+ * directory (not in the source/data directory).
+ * (Oh the things we do to keep the source directory pristine...)
*/
return g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s", get_progfile_dir(), filename);
} else {
}
}
-/* Get the personal plugin dir */
-/* Return value is malloced so the caller should g_free() it. */
-char *
-get_plugins_pers_dir(void)
-{
- return get_persconffile_path(PLUGINS_DIR_NAME, FALSE);
-}
-
/*
* Return an error message for UNIX-style errno indications on open or
* create operations.
errmsg = "The file \"%s\" could not be created because an invalid filename was specified.";
break;
+#ifdef ENAMETOOLONG
+ case ENAMETOOLONG:
+ /* XXX Make sure we truncate on a character boundary. */
+ errmsg = "The file name \"%.80s" UTF8_HORIZONTAL_ELLIPSIS "\" is too long.";
+ break;
+#endif
+
case ENOMEM:
/*
* The problem probably has nothing to do with how much RAM the
* Either you have a fixed swap partition or a fixed swap file,
* and it needs to be made bigger.
*
- * This is UN*X, but it's not OS X, so we assume the user is
+ * This is UN*X, but it's not macOS, so we assume the user is
* *somewhat* nerdy.
*/
#define ENOMEM_REASON "your system is out of swap space"
return FALSE;
}
-#ifdef _WIN32
+#if defined(_MSC_VER) && _MSC_VER < 1900
+
/*
* This is a bit tricky on win32. The st_ino field is documented as:
* "The inode, and therefore st_ino, has no meaning in the FAT, ..."
return FALSE;
}
+gchar *
+data_file_url(const gchar *filename)
+{
+ gchar *file_path;
+ gchar *uri;
+
+ /* Absolute path? */
+ if(g_path_is_absolute(filename)) {
+ file_path = g_strdup(filename);
+ } else if(running_in_build_directory()) {
+ file_path = g_strdup_printf("%s/doc/%s", get_datafile_dir(), filename);
+ } else {
+ file_path = g_strdup_printf("%s/%s", get_datafile_dir(), filename);
+ }
+
+ /* XXX - check, if the file is really existing, otherwise display a simple_dialog about the problem */
+
+ /* convert filename to uri */
+ uri = g_filename_to_uri(file_path, NULL, NULL);
+ g_free(file_path);
+ return uri;
+}
+
+void
+free_progdirs(void)
+{
+ g_free(persconffile_dir);
+ persconffile_dir = NULL;
+ g_free(persdatafile_dir);
+ persdatafile_dir = NULL;
+ g_free(persconfprofile);
+ persconfprofile = NULL;
+ g_free(progfile_dir);
+ progfile_dir = NULL;
+#if defined(HAVE_PLUGINS) || defined(HAVE_LUA)
+ g_free(plugin_dir);
+ plugin_dir = NULL;
+ g_free(plugin_pers_dir);
+ plugin_pers_dir = NULL;
+#endif
+#ifdef HAVE_EXTCAP
+ g_free(extcap_dir);
+ extcap_dir = NULL;
+#endif
+}
+
/*
* Editor modelines
*