2 * Filesystem utility routines
4 * Wireshark - Network traffic analyzer
5 * By Gerald Combs <gerald@wireshark.org>
6 * Copyright 1998 Gerald Combs
8 * SPDX-License-Identifier: GPL-2.0+
14 * Required with GNU libc to get dladdr().
15 * We define it here because <dlfcn.h> apparently gets included by
16 * one of the headers we include below.
31 #include <wsutil/unicode-utils.h>
34 #include <mach-o/dyld.h>
37 #include <sys/utsname.h>
40 #include <sys/types.h>
41 #include <sys/sysctl.h>
49 #include "filesystem.h"
50 #include <wsutil/report_message.h>
51 #include <wsutil/privileges.h>
52 #include <wsutil/file_util.h>
53 #include <wsutil/utf8_entities.h>
55 #include <wiretap/wtap.h> /* for WTAP_ERR_SHORT_WRITE */
57 #define PROFILES_DIR "profiles"
58 #define PLUGINS_DIR_NAME "plugins"
59 #define PROFILES_INFO_NAME "profile_files.txt"
61 char *persconffile_dir = NULL;
62 char *persdatafile_dir = NULL;
63 char *persconfprofile = NULL;
65 static gboolean do_store_persconffiles = FALSE;
66 static GHashTable *profile_files = NULL;
69 * Given a pathname, return a pointer to the last pathname separator
70 * character in the pathname, or NULL if the pathname contains no
74 find_last_pathname_separator(const char *path)
82 * We have to scan for '\' or '/'.
83 * Get to the end of the string.
85 separator = strchr(path, '\0'); /* points to ending '\0' */
86 while (separator > path) {
88 if (c == '\\' || c == '/')
89 return separator; /* found it */
93 * OK, we didn't find any, so no directories - but there might
94 * be a drive letter....
96 return strchr(path, ':');
98 separator = strrchr(path, '/');
104 * Given a pathname, return the last component.
107 get_basename(const char *path)
109 const char *filename;
111 g_assert(path != NULL);
112 filename = find_last_pathname_separator(path);
113 if (filename == NULL) {
115 * There're no directories, drive letters, etc. in the
116 * name; the pathname *is* the file name.
121 * Skip past the pathname or drive letter separator.
129 * Given a pathname, return a string containing everything but the
130 * last component. NOTE: this overwrites the pathname handed into
134 get_dirname(char *path)
138 g_assert(path != NULL);
139 separator = find_last_pathname_separator(path);
140 if (separator == NULL) {
142 * There're no directories, drive letters, etc. in the
143 * name; there is no directory path to return.
149 * Get rid of the last pathname separator and the final file
155 * "path" now contains the pathname of the directory containing
156 * the file/directory to which it referred.
162 * Given a pathname, return:
164 * the errno, if an attempt to "stat()" the file fails;
166 * EISDIR, if the attempt succeeded and the file turned out
169 * 0, if the attempt succeeded and the file turned out not
174 test_for_directory(const char *path)
178 if (ws_stat64(path, &statb) < 0)
181 if (S_ISDIR(statb.st_mode))
188 test_for_fifo(const char *path)
192 if (ws_stat64(path, &statb) < 0)
195 if (S_ISFIFO(statb.st_mode))
202 * Directory from which the executable came.
204 static char *progfile_dir;
208 * Directory of the application bundle in which we're contained,
209 * if we're contained in an application bundle. Otherwise, NULL.
211 * Note: Table 2-5 "Subdirectories of the Contents directory" of
213 * https://developer.apple.com/library/mac/documentation/CoreFoundation/Conceptual/CFBundles/BundleTypes/BundleTypes.html#//apple_ref/doc/uid/10000123i-CH101-SW1
215 * says that the "Frameworks" directory
217 * Contains any private shared libraries and frameworks used by the
218 * executable. The frameworks in this directory are revision-locked
219 * to the application and cannot be superseded by any other, even
220 * newer, versions that may be available to the operating system. In
221 * other words, the frameworks included in this directory take precedence
222 * over any other similarly named frameworks found in other parts of
223 * the operating system. For information on how to add private
224 * frameworks to your application bundle, see Framework Programming Guide.
226 * so if we were to ship with any frameworks (e.g. Qt) we should
227 * perhaps put them in a Frameworks directory rather than under
230 * It also says that the "PlugIns" directory
232 * Contains loadable bundles that extend the basic features of your
233 * application. You use this directory to include code modules that
234 * must be loaded into your applicationbs process space in order to
235 * be used. You would not use this directory to store standalone
238 * Our plugins are just raw .so/.dylib files; I don't know whether by
239 * "bundles" they mean application bundles (i.e., directory hierarchies)
240 * or just "bundles" in the Mach-O sense (which are an image type that
241 * can be loaded with dlopen() but not linked as libraries; our plugins
242 * are, I think, built as dylibs and can be loaded either way).
244 * And it says that the "SharedSupport" directory
246 * Contains additional non-critical resources that do not impact the
247 * ability of the application to run. You might use this directory to
248 * include things like document templates, clip art, and tutorials
249 * that your application expects to be present but that do not affect
250 * the ability of your application to run.
252 * I don't think I'd put the files that currently go under Resources/share
253 * into that category; they're not, for example, sample Lua scripts that
254 * don't actually get run by Wireshark, they're configuration/data files
255 * for Wireshark whose absence might not prevent Wireshark from running
256 * but that would affect how it behaves when run.
258 static char *appbundle_dir;
262 * TRUE if we're running from the build directory and we aren't running
263 * with special privileges.
265 static gboolean running_in_build_directory_flag = FALSE;
269 * Get the pathname of the executable using various platform-
270 * dependent mechanisms for various UN*Xes.
272 * These calls all should return something independent of the argv[0]
273 * passed to the program, so it shouldn't be fooled by an argv[0]
274 * that doesn't match the executable path.
276 * Sadly, not all UN*Xes necessarily have dladdr(), and those that
277 * do don't necessarily have dladdr(main) return information about
278 * the executable image, and those that do aren't necessarily running
279 * on a platform wherein the executable image can get its own path
280 * from the kernel (either by a call or by it being handed to it along
281 * with argv[] and the environment), and those that can don't
282 * necessarily use that to supply the path you get from dladdr(main),
283 * so we try this first and, if that fails, use dladdr(main) if
286 * In particular, some dynamic linkers supply a dladdr() such that
287 * dladdr(main) just returns something derived from argv[0], so
288 * just using dladdr(main) is the wrong thing to do if there's
289 * another mechanism that can get you a more reliable version of
290 * the executable path.
292 * However, at least in newer versions of DragonFly BSD, the dynamic
293 * linker *does* get it from the aux vector passed to the program
294 * by the kernel, readlink /proc/curproc/file - which came first?
296 * On OpenBSD, dladdr(main) returns a value derived from argv[0],
297 * and there doesn't appear to be any way to get the executable path
298 * from the kernel, so we're out of luck there.
300 * So, on platforms where some versions have a version of dladdr()
301 * that gives an argv[0]-based path and that also have a mechanism
302 * to get a more reliable version of the path, we try that. On
303 * other platforms, we return NULL. If our caller gets back a NULL
304 * from us, it falls back on dladdr(main) if dladdr() is available,
305 * and if that fails or is unavailable, it falls back on processing
308 * This is not guaranteed to return an absolute path; if it doesn't,
309 * our caller must prepend the current directory if it's a path.
311 * This is not guaranteed to return the "real path"; it might return
312 * something with symbolic links in the path. Our caller must
313 * use realpath() if they want the real thing, but that's also true of
314 * something obtained by looking at argv[0].
317 get_executable_path(void)
319 #if defined(__APPLE__)
320 char *executable_path;
321 uint32_t path_buf_size;
323 path_buf_size = PATH_MAX;
324 executable_path = (char *)g_malloc(path_buf_size);
325 if (_NSGetExecutablePath(executable_path, &path_buf_size) == -1) {
326 executable_path = (char *)g_realloc(executable_path, path_buf_size);
327 if (_NSGetExecutablePath(executable_path, &path_buf_size) == -1)
330 return executable_path;
331 #elif defined(__linux__)
333 * In older versions of GNU libc's dynamic linker, as used on Linux,
334 * dladdr(main) supplies a path based on argv[0], so we use
335 * /proc/self/exe instead; there are Linux distributions with
336 * kernels that support /proc/self/exe and those older versions
337 * of the dynamic linker, and this will get a better answer on
340 * It only works on Linux 2.2 or later, so we just give up on
343 * XXX - are there OS versions that support "exe" but not "self"?
346 static char executable_path[PATH_MAX + 1];
349 if (uname(&name) == -1)
351 if (strncmp(name.release, "1.", 2) == 0)
352 return NULL; /* Linux 1.x */
353 if (strcmp(name.release, "2.0") == 0 ||
354 strncmp(name.release, "2.0.", 4) == 0 ||
355 strcmp(name.release, "2.1") == 0 ||
356 strncmp(name.release, "2.1.", 4) == 0)
357 return NULL; /* Linux 2.0.x or 2.1.x */
358 if ((r = readlink("/proc/self/exe", executable_path, PATH_MAX)) == -1)
360 executable_path[r] = '\0';
361 return executable_path;
362 #elif defined(__FreeBSD__) && defined(KERN_PROC_PATHNAME)
364 * In older versions of FreeBSD's dynamic linker, dladdr(main)
365 * supplies a path based on argv[0], so we use the KERN_PROC_PATHNAME
366 * sysctl instead; there are, I think, versions of FreeBSD
367 * that support the sysctl that have and those older versions
368 * of the dynamic linker, and this will get a better answer on
372 char *executable_path;
373 size_t path_buf_size;
377 mib[2] = KERN_PROC_PATHNAME;
379 path_buf_size = PATH_MAX;
380 executable_path = (char *)g_malloc(path_buf_size);
381 if (sysctl(mib, 4, executable_path, &path_buf_size, NULL, 0) == -1) {
384 executable_path = (char *)g_realloc(executable_path, path_buf_size);
385 if (sysctl(mib, 4, executable_path, &path_buf_size, NULL, 0) == -1)
388 return executable_path;
389 #elif defined(__NetBSD__)
391 * In all versions of NetBSD's dynamic linker as of 2013-08-12,
392 * dladdr(main) supplies a path based on argv[0], so we use
393 * /proc/curproc/exe instead.
395 * XXX - are there OS versions that support "exe" but not "curproc"
396 * or "self"? Are there any that support "self" but not "curproc"?
398 static char executable_path[PATH_MAX + 1];
401 if ((r = readlink("/proc/curproc/exe", executable_path, PATH_MAX)) == -1)
403 executable_path[r] = '\0';
404 return executable_path;
405 #elif defined(__DragonFly__)
407 * In older versions of DragonFly BSD's dynamic linker, dladdr(main)
408 * supplies a path based on argv[0], so we use /proc/curproc/file
409 * instead; it appears to be supported by all versions of DragonFly
412 static char executable_path[PATH_MAX + 1];
415 if ((r = readlink("/proc/curproc/file", executable_path, PATH_MAX)) == -1)
417 executable_path[r] = '\0';
418 return executable_path;
419 #elif (defined(sun) || defined(__sun)) && defined(HAVE_GETEXECNAME)
421 * It appears that getexecname() dates back to at least Solaris 8,
422 * but /proc/{pid}/path is first documented in the Solaris 10 documentation,
423 * so we use getexecname() if available, rather than /proc/self/path/a.out
424 * (which isn't documented, but appears to be a symlink to the
425 * executable image file).
427 return getexecname();
429 /* Fill in your favorite UN*X's code here, if there is something */
436 * Get the pathname of the directory from which the executable came,
437 * and save it for future use. Returns NULL on success, and a
438 * g_mallocated string containing an error on failure.
441 init_progfile_dir(const char *arg0
445 , int (*function_addr)(int, char **)
446 #if defined(_WIN32) || !defined(HAVE_DLADDR)
452 TCHAR prog_pathname_w[_MAX_PATH+2];
460 * Attempt to get the full pathname of the currently running
463 if (GetModuleFileName(NULL, prog_pathname_w, G_N_ELEMENTS(prog_pathname_w)) != 0 && GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
465 * XXX - Should we use g_utf16_to_utf8()?
467 prog_pathname = utf_16to8(prog_pathname_w);
469 * We got it; strip off the last component, which would be
470 * the file name of the executable, giving us the pathname
471 * of the directory where the executable resides.
473 progfile_dir = g_path_get_dirname(prog_pathname);
474 if (progfile_dir != NULL) {
475 return NULL; /* we succeeded */
478 * OK, no. What do we do now?
480 return g_strdup_printf("No \\ in executable pathname \"%s\"",
485 * Oh, well. Return an indication of the error.
487 error = GetLastError();
488 if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,
489 NULL, error, 0, (LPTSTR) &msg_w, 0, NULL) == 0) {
491 * Gak. We can't format the message.
493 return g_strdup_printf("GetModuleFileName failed: %u (FormatMessage failed: %u)",
494 error, GetLastError());
496 msg = utf_16to8(msg_w);
499 * "FormatMessage()" "helpfully" sticks CR/LF at the
500 * end of the message. Get rid of it.
502 msglen = strlen(msg);
504 msg[msglen - 1] = '\0';
505 msg[msglen - 2] = '\0';
507 return g_strdup_printf("GetModuleFileName failed: %s (%u)",
514 const char *execname;
519 const char *path_start, *path_end;
520 size_t path_component_len, path_len;
526 * Check whether WIRESHARK_RUN_FROM_BUILD_DIRECTORY is set in the
527 * environment; if so, set running_in_build_directory_flag if we
528 * weren't started with special privileges. (If we were started
529 * with special privileges, it's not safe to allow the user to point
530 * us to some other directory; running_in_build_directory_flag, when
531 * set, causes us to look for plugins and the like in the build
534 if (g_getenv("WIRESHARK_RUN_FROM_BUILD_DIRECTORY") != NULL
535 && !started_with_special_privs())
536 running_in_build_directory_flag = TRUE;
538 execname = get_executable_path();
540 if (function_addr != NULL && execname == NULL) {
542 * Try to use dladdr() to find the pathname of the executable.
543 * dladdr() is not guaranteed to give you anything better than
544 * argv[0] (i.e., it might not contain a / at all, much less
545 * being an absolute path), and doesn't appear to do so on
546 * Linux, but on other platforms it could give you an absolute
547 * path and obviate the need for us to determine the absolute
551 if (dladdr((void *)function_addr, &info)) {
553 execname = info.dli_fname;
557 if (execname == NULL) {
559 * OK, guess based on argv[0].
565 * Try to figure out the directory in which the currently running
566 * program resides, given something purporting to be the executable
567 * name (from dladdr() or from the argv[0] it was started with.
568 * That might be the absolute path of the program, or a path relative
569 * to the current directory of the process that started it, or
570 * just a name for the program if it was started from the command
571 * line and was searched for in $PATH. It's not guaranteed to be
572 * any of those, however, so there are no guarantees....
574 if (execname[0] == '/') {
576 * It's an absolute path.
578 prog_pathname = g_strdup(execname);
579 } else if (strchr(execname, '/') != NULL) {
581 * It's a relative path, with a directory in it.
582 * Get the current directory, and combine it
583 * with that directory.
585 path_max = pathconf(".", _PC_PATH_MAX);
586 if (path_max == -1) {
588 * We have no idea how big a buffer to
589 * allocate for the current directory.
591 return g_strdup_printf("pathconf failed: %s\n",
594 curdir = (char *)g_malloc(path_max);
595 if (getcwd(curdir, path_max) == NULL) {
597 * It failed - give up, and just stick
601 return g_strdup_printf("getcwd failed: %s\n",
604 path = g_strdup_printf("%s/%s", curdir, execname);
606 prog_pathname = path;
609 * It's just a file name.
610 * Search the path for a file with that name
613 prog_pathname = NULL; /* haven't found it yet */
614 pathstr = g_getenv("PATH");
615 path_start = pathstr;
616 if (path_start != NULL) {
617 while (*path_start != '\0') {
618 path_end = strchr(path_start, ':');
619 if (path_end == NULL)
620 path_end = path_start + strlen(path_start);
621 path_component_len = path_end - path_start;
622 path_len = path_component_len + 1
623 + strlen(execname) + 1;
624 path = (char *)g_malloc(path_len);
625 memcpy(path, path_start, path_component_len);
626 path[path_component_len] = '\0';
627 g_strlcat(path, "/", path_len);
628 g_strlcat(path, execname, path_len);
629 if (access(path, X_OK) == 0) {
633 prog_pathname = path;
638 * That's not it. If there are more
639 * path components to test, try them.
641 if (*path_end == '\0') {
643 * There's nothing more to try.
647 if (*path_end == ':')
649 path_start = path_end;
652 if (prog_pathname == NULL) {
654 * Program not found in path.
656 return g_strdup_printf("\"%s\" not found in \"%s\"",
662 * XXX - should we pick a default?
664 return g_strdup("PATH isn't set");
669 * OK, we have what we think is the pathname
672 * First, find the last "/" in the directory,
673 * as that marks the end of the directory pathname.
675 dir_end = strrchr(prog_pathname, '/');
676 if (dir_end != NULL) {
678 * Found it. Strip off the last component,
679 * as that's the path of the program.
684 * Is there a "/.libs" at the end?
686 dir_end = strrchr(prog_pathname, '/');
687 if (dir_end != NULL) {
688 if (strcmp(dir_end, "/.libs") == 0) {
691 * Strip that off; it's an
692 * artifact of libtool.
697 * This presumably means we're run from
698 * the libtool wrapper, which probably
699 * means we're being run from the build
700 * directory. If we weren't started
701 * with special privileges, set
702 * running_in_build_directory_flag.
704 * XXX - should we check whether what
705 * follows ".libs/" begins with "lt-"?
707 if (!started_with_special_privs())
708 running_in_build_directory_flag = TRUE;
710 else if (!started_with_special_privs()) {
712 * Check for the CMake output directory. As people may name
713 * their directories "run" (really?), also check for the
714 * CMakeCache.txt file before assuming a CMake output dir.
716 if (strcmp(dir_end, "/run") == 0) {
718 cmake_file = g_strdup_printf("%.*s/CMakeCache.txt",
719 (int)(dir_end - prog_pathname),
721 if (file_exists(cmake_file))
722 running_in_build_directory_flag = TRUE;
726 if (!running_in_build_directory_flag) {
728 * Scan up the path looking for a component
729 * named "Contents". If we find it, we assume
730 * we're in a bundle, and that the top-level
731 * directory of the bundle is the one containing
734 * Not all executables are in the Contents/MacOS
735 * directory, so we can't just check for those
736 * in the path and strip them off.
738 * XXX - should we assume that it's either
739 * Contents/MacOS or Resources/bin?
741 char *component_end, *p;
743 component_end = strchr(prog_pathname, '\0');
746 while (p >= prog_pathname && *p != '/')
748 if (p == prog_pathname) {
750 * We're looking at the first component of
751 * the pathname now, so we're definitely
752 * not in a bundle, even if we're in
757 if (strncmp(p, "/Contents", component_end - p) == 0) {
759 appbundle_dir = (char *)g_malloc(p - prog_pathname + 1);
760 memcpy(appbundle_dir, prog_pathname, p - prog_pathname);
761 appbundle_dir[p - prog_pathname] = '\0';
773 * OK, we have the path we want.
775 progfile_dir = prog_pathname;
779 * This "shouldn't happen"; we apparently
780 * have no "/" in the pathname.
781 * Just free up prog_pathname.
783 retstr = g_strdup_printf("No / found in \"%s\"", prog_pathname);
784 g_free(prog_pathname);
791 * Get the directory in which the program resides.
794 get_progfile_dir(void)
800 * Get the directory in which the global configuration and data files are
803 * On Windows, we use the directory in which the executable for this
806 * On UN*X, we use the DATAFILE_DIR value supplied by the configure
807 * script, unless we think we're being run from the build directory,
808 * in which case we use the directory in which the executable for this
811 * XXX - if we ever make libwireshark a real library, used by multiple
812 * applications (more than just TShark and versions of Wireshark with
813 * various UIs), should the configuration files belong to the library
814 * (and be shared by all those applications) or to the applications?
816 * If they belong to the library, that could be done on UNIX by the
817 * configure script, but it's trickier on Windows, as you can't just
818 * use the pathname of the executable.
820 * If they belong to the application, that could be done on Windows
821 * by using the pathname of the executable, but we'd have to have it
822 * passed in as an argument, in some call, on UNIX.
824 * Note that some of those configuration files might be used by code in
825 * libwireshark, some of them might be used by dissectors (would they
826 * belong to libwireshark, the application, or a separate library?),
827 * and some of them might be used by other code (the Wireshark preferences
828 * file includes resolver preferences that control the behavior of code
829 * in libwireshark, dissector preferences, and UI preferences, for
833 get_datafile_dir(void)
835 static const char *datafile_dir = NULL;
837 if (datafile_dir != NULL)
842 * Do we have the pathname of the program? If so, assume we're
843 * running an installed version of the program. If we fail,
844 * we don't change "datafile_dir", and thus end up using the
847 * XXX - does NSIS put the installation directory into
848 * "\HKEY_LOCAL_MACHINE\SOFTWARE\Wireshark\InstallDir"?
849 * If so, perhaps we should read that from the registry,
852 if (progfile_dir != NULL) {
854 * Yes, we do; use that.
856 datafile_dir = progfile_dir;
860 * Fall back on the default installation directory.
862 datafile_dir = "C:\\Program Files\\Wireshark\\";
866 if (running_in_build_directory_flag) {
868 * We're (probably) being run from the build directory and
869 * weren't started with special privileges.
871 * (running_in_build_directory_flag is never set to TRUE
872 * if we're started with special privileges, so we need
873 * only check it; we don't need to call started_with_special_privs().)
875 * Use the top-level source directory as the datafile directory
876 * because most of our data files (radius/, COPYING) are there.
880 * When TOP_SRCDIR is defined, assume autotools where files are not
881 * copied to the build directory. This fallback location is relied on by
882 * wslua_get_actual_filename().
884 datafile_dir = TOP_SRCDIR;
887 * Otherwise assume CMake. Here, data files (console.lua, radius/, etc.)
888 * are copied to the build directory during the build.
890 datafile_dir = BUILD_TIME_DATAFILE_DIR;
894 if (g_getenv("WIRESHARK_DATA_DIR") && !started_with_special_privs()) {
896 * The user specified a different directory for data files
897 * and we aren't running with special privileges.
898 * XXX - We might be able to dispense with the priv check
900 datafile_dir = g_strdup(g_getenv("WIRESHARK_DATA_DIR"));
904 * If we're running from an app bundle and weren't started
905 * with special privileges, use the Contents/Resources/share/wireshark
906 * subdirectory of the app bundle.
908 * (appbundle_dir is not set to a non-null value if we're
909 * started with special privileges, so we need only check
910 * it; we don't need to call started_with_special_privs().)
912 else if (appbundle_dir != NULL) {
913 datafile_dir = g_strdup_printf("%s/Contents/Resources/share/wireshark",
918 datafile_dir = DATAFILE_DIR;
927 * Find the directory where the plugins are stored.
929 * On Windows, we use the plugin\{VERSION} subdirectory of the datafile
930 * directory, where {VERSION} is the version number of this version of
935 * if we appear to be run from the build directory, we use the
936 * "plugin" subdirectory of the datafile directory;
938 * otherwise, if the WIRESHARK_PLUGIN_DIR environment variable is
939 * set and we aren't running with special privileges, we use the
940 * value of that environment variable;
942 * otherwise, if we're running from an app bundle in macOS, we
943 * use the Contents/PlugIns/wireshark subdirectory of the app bundle;
945 * otherwise, we use the PLUGIN_DIR value supplied by the
948 static char *plugin_dir = NULL;
949 static char *plugin_dir_with_version = NULL;
950 static char *plugin_pers_dir = NULL;
951 static char *plugin_pers_dir_with_version = NULL;
954 init_plugin_dir(void)
956 #if defined(HAVE_PLUGINS) || defined(HAVE_LUA)
959 * On Windows, the data file directory is the installation
960 * directory; the plugins are stored under it.
962 * Assume we're running the installed version of Wireshark;
963 * on Windows, the data file directory is the directory
964 * in which the Wireshark binary resides.
966 plugin_dir = g_build_filename(get_datafile_dir(), "plugins", (gchar *)NULL);
969 * Make sure that pathname refers to a directory.
971 if (test_for_directory(plugin_dir) != EISDIR) {
973 * Either it doesn't refer to a directory or it
974 * refers to something that doesn't exist.
976 * Assume that means we're running a version of
977 * Wireshark we've built in a build directory,
978 * in which case {datafile dir}\plugins is the
979 * top-level plugins source directory, and use
980 * that directory and set the "we're running in
981 * a build directory" flag, so the plugin
982 * scanner will check all subdirectories of that
983 * directory for plugins.
986 plugin_dir = g_build_filename(get_datafile_dir(), "plugins", (gchar *)NULL);
987 running_in_build_directory_flag = TRUE;
990 if (running_in_build_directory_flag) {
992 * We're (probably) being run from the build directory and
993 * weren't started with special privileges, so we'll use
994 * the "plugins" subdirectory of the directory where the program
995 * we're running is (that's the build directory).
997 plugin_dir = g_build_filename(get_progfile_dir(), "plugins", (gchar *)NULL);
999 if (g_getenv("WIRESHARK_PLUGIN_DIR") && !started_with_special_privs()) {
1001 * The user specified a different directory for plugins
1002 * and we aren't running with special privileges.
1004 plugin_dir = g_strdup(g_getenv("WIRESHARK_PLUGIN_DIR"));
1008 * If we're running from an app bundle and weren't started
1009 * with special privileges, use the Contents/PlugIns/wireshark
1010 * subdirectory of the app bundle.
1012 * (appbundle_dir is not set to a non-null value if we're
1013 * started with special privileges, so we need only check
1014 * it; we don't need to call started_with_special_privs().)
1016 else if (appbundle_dir != NULL) {
1017 plugin_dir = g_build_filename(appbundle_dir, "Contents/PlugIns/wireshark", (gchar *)NULL);
1021 plugin_dir = g_strdup(PLUGIN_DIR);
1025 #endif /* defined(HAVE_PLUGINS) || defined(HAVE_LUA) */
1029 init_plugin_pers_dir(void)
1031 #if defined(HAVE_PLUGINS) || defined(HAVE_LUA)
1033 plugin_pers_dir = get_persconffile_path(PLUGINS_DIR_NAME, FALSE);
1035 plugin_pers_dir = g_build_filename(g_get_home_dir(), ".local/lib/wireshark/" PLUGINS_DIR_NAME, (gchar *)NULL);
1037 #endif /* defined(HAVE_PLUGINS) || defined(HAVE_LUA) */
1041 * Get the directory in which the plugins are stored.
1044 get_plugins_dir(void)
1052 get_plugins_dir_with_version(void)
1056 if (plugin_dir && !plugin_dir_with_version)
1057 plugin_dir_with_version = g_build_filename(plugin_dir, VERSION_RELEASE, (gchar *)NULL);
1058 return plugin_dir_with_version;
1061 /* Get the personal plugin dir */
1063 get_plugins_pers_dir(void)
1065 if (!plugin_pers_dir)
1066 init_plugin_pers_dir();
1067 return plugin_pers_dir;
1071 get_plugins_pers_dir_with_version(void)
1073 if (!plugin_pers_dir)
1074 init_plugin_pers_dir();
1075 if (plugin_pers_dir && !plugin_pers_dir_with_version)
1076 plugin_pers_dir_with_version = g_build_filename(plugin_pers_dir, VERSION_RELEASE, (gchar *)NULL);
1077 return plugin_pers_dir_with_version;
1080 #if defined(HAVE_EXTCAP)
1082 * Find the directory where the extcap hooks are stored.
1084 * On Windows, we use the "extcap" subdirectory of the datafile directory.
1086 * On UN*X, we use the EXTCAP_DIR value supplied by the configure
1087 * script, unless we think we're being run from the build directory,
1088 * in which case we use the "extcap" subdirectory of the datafile directory.
1090 * In both cases, we then use the subdirectory of that directory whose
1091 * name is the version number.
1093 * XXX - if we think we're being run from the build directory, perhaps we
1094 * should have the extcap code not look in the version subdirectory
1095 * of the extcap directory, but look in all of the subdirectories
1096 * of the extcap directory, so it can just fetch the extcap hooks built
1097 * as part of the build process.
1099 static char *extcap_dir = NULL;
1101 static void init_extcap_dir(void) {
1103 const char *alt_extcap_path;
1106 * On Windows, the data file directory is the installation
1107 * directory; the extcap hooks are stored under it.
1109 * Assume we're running the installed version of Wireshark;
1110 * on Windows, the data file directory is the directory
1111 * in which the Wireshark binary resides.
1113 alt_extcap_path = g_getenv("WIRESHARK_EXTCAP_DIR");
1114 if (alt_extcap_path) {
1116 * The user specified a different directory for extcap hooks.
1118 extcap_dir = g_strdup(alt_extcap_path);
1120 extcap_dir = g_build_filename(get_datafile_dir(), "extcap", (gchar *)NULL);
1123 if (running_in_build_directory_flag) {
1125 * We're (probably) being run from the build directory and
1126 * weren't started with special privileges, so we'll use
1127 * the "extcap hooks" subdirectory of the directory where the program
1128 * we're running is (that's the build directory).
1130 extcap_dir = g_build_filename(get_progfile_dir(), "extcap", (gchar *)NULL);
1132 if (g_getenv("WIRESHARK_EXTCAP_DIR") && !started_with_special_privs()) {
1134 * The user specified a different directory for extcap hooks
1135 * and we aren't running with special privileges.
1137 extcap_dir = g_strdup(g_getenv("WIRESHARK_EXTCAP_DIR"));
1141 * If we're running from an app bundle and weren't started
1142 * with special privileges, use the Contents/MacOS/extcap
1143 * subdirectory of the app bundle.
1145 * (appbundle_dir is not set to a non-null value if we're
1146 * started with special privileges, so we need only check
1147 * it; we don't need to call started_with_special_privs().)
1149 else if (appbundle_dir != NULL) {
1150 extcap_dir = g_build_filename(appbundle_dir, "Contents/MacOS/extcap", (gchar *)NULL);
1154 extcap_dir = g_strdup(EXTCAP_DIR);
1159 #endif /* HAVE_EXTCAP */
1162 * Get the directory in which the extcap hooks are stored.
1164 * XXX - A fix instead of HAVE_EXTCAP must be found
1167 get_extcap_dir(void) {
1168 #if defined(HAVE_EXTCAP)
1178 * Get the flag indicating whether we're running from a build
1182 running_in_build_directory(void)
1184 return running_in_build_directory_flag;
1188 * Get the directory in which files that, at least on UNIX, are
1189 * system files (such as "/etc/ethers") are stored; on Windows,
1190 * there's no "/etc" directory, so we get them from the global
1191 * configuration and data file directory.
1194 get_systemfile_dir(void)
1197 return get_datafile_dir();
1204 set_profile_name(const gchar *profilename)
1206 g_free (persconfprofile);
1208 if (profilename && strlen(profilename) > 0 &&
1209 strcmp(profilename, DEFAULT_PROFILE) != 0) {
1210 persconfprofile = g_strdup (profilename);
1212 /* Default Profile */
1213 persconfprofile = NULL;
1218 get_profile_name(void)
1220 if (persconfprofile) {
1221 return persconfprofile;
1223 return DEFAULT_PROFILE;
1228 is_default_profile(void)
1230 return (!persconfprofile || strcmp(persconfprofile, DEFAULT_PROFILE) == 0) ? TRUE : FALSE;
1234 has_global_profiles(void)
1238 gchar *global_dir = get_global_profiles_dir();
1240 gboolean has_global = FALSE;
1242 if ((test_for_directory(global_dir) == EISDIR) &&
1243 ((dir = ws_dir_open(global_dir, 0, NULL)) != NULL))
1245 while ((file = ws_dir_read_name(dir)) != NULL) {
1246 filename = g_strdup_printf ("%s%s%s", global_dir, G_DIR_SEPARATOR_S,
1247 ws_dir_get_name(file));
1248 if (test_for_directory(filename) == EISDIR) {
1262 profile_store_persconffiles(gboolean store)
1265 profile_files = g_hash_table_new (g_str_hash, g_str_equal);
1267 do_store_persconffiles = store;
1271 * Get the directory in which personal configuration files reside.
1273 * On Windows, it's "Wireshark", under %APPDATA% or, if %APPDATA% isn't set,
1274 * it's "%USERPROFILE%\Application Data" (which is what %APPDATA% normally
1275 * is on Windows 2000).
1277 * On UNIX-compatible systems, we first look in XDG_CONFIG_HOME/wireshark
1278 * and, if that doesn't exist, ~/.wireshark, for backwards compatibility.
1279 * If neither exists, we use XDG_CONFIG_HOME/wireshark, so that the directory
1280 * is initially created as XDG_CONFIG_HOME/wireshark. We use that regardless
1281 * of whether the user is running under an XDG desktop or not, so that
1282 * if the user's home directory is on a server and shared between
1283 * different desktop environments on different machines, they can all
1284 * share the same configuration file directory.
1286 * XXX - what about stuff that shouldn't be shared between machines,
1287 * such as plugins in the form of shared loadable images?
1290 get_persconffile_dir_no_profile(void)
1295 char *xdg_path, *path;
1297 const char *homedir;
1300 /* Return the cached value, if available */
1301 if (persconffile_dir != NULL)
1302 return persconffile_dir;
1306 * See if the user has selected an alternate environment.
1308 env = g_getenv("WIRESHARK_APPDATA");
1310 persconffile_dir = g_strdup(env);
1311 return persconffile_dir;
1315 * Use %APPDATA% or %USERPROFILE%, so that configuration
1316 * files are stored in the user profile, rather than in
1317 * the home directory. The Windows convention is to store
1318 * configuration information in the user profile, and doing
1319 * so means you can use Wireshark even if the home directory
1320 * is an inaccessible network drive.
1322 env = g_getenv("APPDATA");
1325 * Concatenate %APPDATA% with "\Wireshark".
1327 persconffile_dir = g_build_filename(env, "Wireshark", NULL);
1328 return persconffile_dir;
1332 * OK, %APPDATA% wasn't set, so use %USERPROFILE%\Application Data.
1334 env = g_getenv("USERPROFILE");
1336 persconffile_dir = g_build_filename(env, "Application Data", "Wireshark", NULL);
1337 return persconffile_dir;
1341 * Give up and use "C:".
1343 persconffile_dir = g_build_filename("C:", "Wireshark", NULL);
1344 return persconffile_dir;
1347 * Check if XDG_CONFIG_HOME/wireshark exists and is a directory.
1349 xdg_path = g_build_filename(g_get_user_config_dir(), "wireshark", NULL);
1350 if (g_file_test(xdg_path, G_FILE_TEST_IS_DIR)) {
1351 persconffile_dir = xdg_path;
1352 return persconffile_dir;
1356 * It doesn't exist, or it does but isn't a directory, so try
1359 * If $HOME is set, use that for ~.
1361 * (Note: before GLib 2.36, g_get_home_dir() didn't look at $HOME,
1362 * but we always want to do so, so we don't use g_get_home_dir().)
1364 homedir = g_getenv("HOME");
1365 if (homedir == NULL) {
1369 * Get their home directory from the password file.
1370 * If we can't even find a password file entry for them,
1373 pwd = getpwuid(getuid());
1375 homedir = pwd->pw_dir;
1380 path = g_build_filename(homedir, ".wireshark", NULL);
1381 if (g_file_test(path, G_FILE_TEST_IS_DIR)) {
1383 persconffile_dir = path;
1384 return persconffile_dir;
1388 * Neither are directories that exist; use the XDG path, so we'll
1389 * create that as necessary.
1392 persconffile_dir = xdg_path;
1393 return persconffile_dir;
1398 set_persconffile_dir(const char *p)
1400 g_free(persconffile_dir);
1401 persconffile_dir = g_strdup(p);
1405 get_profiles_dir(void)
1407 return g_strdup_printf ("%s%s%s", get_persconffile_dir_no_profile (),
1408 G_DIR_SEPARATOR_S, PROFILES_DIR);
1412 create_profiles_dir(char **pf_dir_path_return)
1418 * Create the "Default" personal configuration files directory, if necessary.
1420 if (create_persconffile_profile (NULL, pf_dir_path_return) == -1) {
1425 * Check if profiles directory exists.
1426 * If not then create it.
1428 pf_dir_path = get_profiles_dir ();
1429 if (ws_stat64(pf_dir_path, &s_buf) != 0) {
1430 if (errno != ENOENT) {
1431 /* Some other problem; give up now. */
1432 *pf_dir_path_return = pf_dir_path;
1437 * It doesn't exist; try to create it.
1439 int ret = ws_mkdir(pf_dir_path, 0755);
1441 *pf_dir_path_return = pf_dir_path;
1445 g_free(pf_dir_path);
1451 get_global_profiles_dir(void)
1453 return g_strdup_printf ("%s%s%s", get_datafile_dir(),
1454 G_DIR_SEPARATOR_S, PROFILES_DIR);
1458 get_persconffile_dir(const gchar *profilename)
1460 char *persconffile_profile_dir = NULL, *profile_dir;
1462 if (profilename && strlen(profilename) > 0 &&
1463 strcmp(profilename, DEFAULT_PROFILE) != 0) {
1464 profile_dir = get_profiles_dir();
1465 persconffile_profile_dir = g_strdup_printf ("%s%s%s", profile_dir,
1466 G_DIR_SEPARATOR_S, profilename);
1467 g_free(profile_dir);
1469 persconffile_profile_dir = g_strdup (get_persconffile_dir_no_profile ());
1472 return persconffile_profile_dir;
1476 profile_exists(const gchar *profilename, gboolean global)
1478 gchar *path = NULL, *global_path;
1482 global_path = get_global_profiles_dir();
1483 path = g_strdup_printf ("%s%s%s", global_path,
1484 G_DIR_SEPARATOR_S, profilename);
1485 g_free(global_path);
1486 if (test_for_directory (path) == EISDIR) {
1491 path = get_persconffile_dir (profilename);
1492 if (test_for_directory (path) == EISDIR) {
1503 delete_directory (const char *directory, char **pf_dir_path_return)
1510 if ((dir = ws_dir_open(directory, 0, NULL)) != NULL) {
1511 while ((file = ws_dir_read_name(dir)) != NULL) {
1512 filename = g_strdup_printf ("%s%s%s", directory, G_DIR_SEPARATOR_S,
1513 ws_dir_get_name(file));
1514 if (test_for_directory(filename) != EISDIR) {
1515 ret = ws_remove(filename);
1518 /* The user has manually created a directory in the profile directory */
1519 /* I do not want to delete the directory recursively yet */
1520 ret = delete_directory (filename, pf_dir_path_return);
1524 *pf_dir_path_return = filename;
1532 if (ret == 0 && (ret = ws_remove(directory)) != 0) {
1533 *pf_dir_path_return = g_strdup (directory);
1540 reset_default_profile(char **pf_dir_path_return)
1542 char *profile_dir = get_persconffile_dir(NULL);
1543 gchar *filename, *del_file;
1544 GList *files, *file;
1547 files = g_hash_table_get_keys(profile_files);
1548 file = g_list_first(files);
1550 filename = (gchar *)file->data;
1551 del_file = g_strdup_printf("%s%s%s", profile_dir, G_DIR_SEPARATOR_S, filename);
1553 if (file_exists(del_file)) {
1554 ret = ws_remove(del_file);
1556 *pf_dir_path_return = profile_dir;
1563 file = g_list_next(file);
1567 g_free(profile_dir);
1572 delete_persconffile_profile(const char *profilename, char **pf_dir_path_return)
1574 if (strcmp(profilename, DEFAULT_PROFILE) == 0) {
1575 return reset_default_profile(pf_dir_path_return);
1578 char *profile_dir = get_persconffile_dir(profilename);
1581 if (test_for_directory (profile_dir) == EISDIR) {
1582 ret = delete_directory (profile_dir, pf_dir_path_return);
1585 g_free(profile_dir);
1590 rename_persconffile_profile(const char *fromname, const char *toname,
1591 char **pf_from_dir_path_return, char **pf_to_dir_path_return)
1593 char *from_dir = get_persconffile_dir(fromname);
1594 char *to_dir = get_persconffile_dir(toname);
1597 ret = ws_rename (from_dir, to_dir);
1599 *pf_from_dir_path_return = from_dir;
1600 *pf_to_dir_path_return = to_dir;
1611 * Create the directory that holds personal configuration files, if
1612 * necessary. If we attempted to create it, and failed, return -1 and
1613 * set "*pf_dir_path_return" to the pathname of the directory we failed
1614 * to create (it's g_mallocated, so our caller should free it); otherwise,
1618 create_persconffile_profile(const char *profilename, char **pf_dir_path_return)
1622 char *pf_dir_path_copy, *pf_dir_parent_path;
1623 size_t pf_dir_parent_path_len;
1631 * Create the personal profiles directory, if necessary.
1633 if (create_profiles_dir(pf_dir_path_return) == -1) {
1638 pf_dir_path = get_persconffile_dir(profilename);
1639 if (ws_stat64(pf_dir_path, &s_buf) != 0) {
1640 if (errno != ENOENT) {
1641 /* Some other problem; give up now. */
1642 *pf_dir_path_return = pf_dir_path;
1647 * Does the parent directory of that directory
1648 * exist? %APPDATA% may not exist even though
1649 * %USERPROFILE% does.
1651 * We check for the existence of the directory
1652 * by first checking whether the parent directory
1653 * is just a drive letter and, if it's not, by
1654 * doing a "stat()" on it. If it's a drive letter,
1655 * or if the "stat()" succeeds, we assume it exists.
1657 pf_dir_path_copy = g_strdup(pf_dir_path);
1658 pf_dir_parent_path = get_dirname(pf_dir_path_copy);
1659 pf_dir_parent_path_len = strlen(pf_dir_parent_path);
1660 if (pf_dir_parent_path_len > 0
1661 && pf_dir_parent_path[pf_dir_parent_path_len - 1] != ':'
1662 && ws_stat64(pf_dir_parent_path, &s_buf) != 0) {
1664 * Not a drive letter and the stat() failed.
1666 if (errno != ENOENT) {
1667 /* Some other problem; give up now. */
1668 *pf_dir_path_return = pf_dir_path;
1670 g_free(pf_dir_path_copy);
1675 * No, it doesn't exist - make it first.
1677 ret = ws_mkdir(pf_dir_parent_path, 0755);
1679 *pf_dir_path_return = pf_dir_parent_path;
1681 g_free(pf_dir_path);
1686 g_free(pf_dir_path_copy);
1687 ret = ws_mkdir(pf_dir_path, 0755);
1689 ret = g_mkdir_with_parents(pf_dir_path, 0755);
1693 * Something with that pathname exists; if it's not
1694 * a directory, we'll get an error if we try to put
1695 * something in it, so we don't fail here, we wait
1696 * for that attempt fo fail.
1701 *pf_dir_path_return = pf_dir_path;
1703 g_free(pf_dir_path);
1709 create_persconffile_dir(char **pf_dir_path_return)
1711 return create_persconffile_profile(persconfprofile, pf_dir_path_return);
1715 copy_persconffile_profile(const char *toname, const char *fromname, gboolean from_global,
1716 char **pf_filename_return, char **pf_to_dir_path_return, char **pf_from_dir_path_return)
1719 gchar *to_dir = get_persconffile_dir(toname);
1720 gchar *filename, *from_file, *to_file, *global_path;
1721 GList *files, *file;
1724 if (strcmp(fromname, DEFAULT_PROFILE) == 0) {
1725 from_dir = get_global_profiles_dir();
1727 global_path = get_global_profiles_dir();
1728 from_dir = g_strdup_printf ("%s%s%s", global_path, G_DIR_SEPARATOR_S, fromname);
1729 g_free(global_path);
1732 from_dir = get_persconffile_dir(fromname);
1735 files = g_hash_table_get_keys(profile_files);
1736 file = g_list_first(files);
1738 filename = (gchar *)file->data;
1739 from_file = g_strdup_printf ("%s%s%s", from_dir, G_DIR_SEPARATOR_S, filename);
1740 to_file = g_strdup_printf ("%s%s%s", to_dir, G_DIR_SEPARATOR_S, filename);
1742 if (file_exists(from_file) && !copy_file_binary_mode(from_file, to_file)) {
1743 *pf_filename_return = g_strdup(filename);
1744 *pf_to_dir_path_return = to_dir;
1745 *pf_from_dir_path_return = from_dir;
1754 file = g_list_next(file);
1757 g_list_free (files);
1765 * Get the (default) directory in which personal data is stored.
1767 * On Win32, this is the "My Documents" folder in the personal profile.
1768 * On UNIX this is simply the current directory.
1770 /* XXX - should this and the get_home_dir() be merged? */
1772 get_persdatafile_dir(void)
1775 TCHAR tszPath[MAX_PATH];
1777 /* Return the cached value, if available */
1778 if (persdatafile_dir != NULL)
1779 return persdatafile_dir;
1782 * Hint: SHGetFolderPath is not available on MSVC 6 - without
1785 if (SHGetSpecialFolderPath(NULL, tszPath, CSIDL_PERSONAL, FALSE)) {
1786 persdatafile_dir = g_utf16_to_utf8(tszPath, -1, NULL, NULL, NULL);
1787 return persdatafile_dir;
1797 set_persdatafile_dir(const char *p)
1799 g_free(persdatafile_dir);
1800 persdatafile_dir = g_strdup(p);
1805 * Returns the user's home directory on Win32.
1810 static const char *home = NULL;
1811 const char *homedrive, *homepath;
1815 /* Return the cached value, if available */
1820 * XXX - should we use USERPROFILE anywhere in this process?
1821 * Is there a chance that it might be set but one or more of
1822 * HOMEDRIVE or HOMEPATH isn't set?
1824 homedrive = g_getenv("HOMEDRIVE");
1825 if (homedrive != NULL) {
1826 homepath = g_getenv("HOMEPATH");
1827 if (homepath != NULL) {
1829 * This is cached, so we don't need to worry about
1830 * allocating multiple ones of them.
1832 homestring = g_strdup_printf("%s%s", homedrive, homepath);
1835 * Trim off any trailing slash or backslash.
1837 lastsep = find_last_pathname_separator(homestring);
1838 if (lastsep != NULL && *(lastsep + 1) == '\0') {
1840 * Last separator is the last character
1841 * in the string. Nuke it.
1850 * Give up and use C:.
1860 * Construct the path name of a personal configuration file, given the
1863 * On Win32, if "for_writing" is FALSE, we check whether the file exists
1864 * and, if not, construct a path name relative to the ".wireshark"
1865 * subdirectory of the user's home directory, and check whether that
1866 * exists; if it does, we return that, so that configuration files
1867 * from earlier versions can be read.
1869 * The returned file name was g_malloc()'d so it must be g_free()d when the
1870 * caller is done with it.
1873 get_persconffile_path(const char *filename, gboolean from_profile)
1875 char *path, *dir = NULL;
1877 if (do_store_persconffiles && from_profile && !g_hash_table_lookup (profile_files, filename)) {
1878 /* Store filenames so we know which filenames belongs to a configuration profile */
1879 g_hash_table_insert (profile_files, g_strdup(filename), g_strdup(filename));
1883 dir = get_persconffile_dir(persconfprofile);
1885 dir = get_persconffile_dir(NULL);
1887 path = g_build_filename(dir, filename, NULL);
1894 * Construct the path name of a global configuration file, given the
1897 * The returned file name was g_malloc()'d so it must be g_free()d when the
1898 * caller is done with it.
1901 get_datafile_path(const char *filename)
1903 if (running_in_build_directory_flag &&
1904 (!strcmp(filename, "AUTHORS-SHORT") ||
1905 !strcmp(filename, "hosts"))) {
1906 /* We're running in the build directory and the requested file is a
1907 * generated (or a test) file. Return the file name in the build
1908 * directory (not in the source/data directory).
1909 * (Oh the things we do to keep the source directory pristine...)
1911 return g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s", get_progfile_dir(), filename);
1913 return g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s", get_datafile_dir(), filename);
1918 * Return an error message for UNIX-style errno indications on open or
1919 * create operations.
1922 file_open_error_message(int err, gboolean for_writing)
1925 static char errmsg_errno[1024+1];
1931 errmsg = "The path to the file \"%s\" doesn't exist.";
1933 errmsg = "The file \"%s\" doesn't exist.";
1938 errmsg = "You don't have permission to create or write to the file \"%s\".";
1940 errmsg = "You don't have permission to read the file \"%s\".";
1944 errmsg = "\"%s\" is a directory (folder), not a file.";
1948 errmsg = "The file \"%s\" could not be created because there is no space left on the file system.";
1953 errmsg = "The file \"%s\" could not be created because you are too close to, or over, your disk quota.";
1958 errmsg = "The file \"%s\" could not be created because an invalid filename was specified.";
1963 /* XXX Make sure we truncate on a character boundary. */
1964 errmsg = "The file name \"%.80s" UTF8_HORIZONTAL_ELLIPSIS "\" is too long.";
1970 * The problem probably has nothing to do with how much RAM the
1971 * user has on their machine, so don't confuse them by saying
1972 * "memory". The problem is probably either virtual address
1973 * space or swap space.
1975 #if GLIB_SIZEOF_VOID_P == 4
1977 * ILP32; we probably ran out of virtual address space.
1979 #define ENOMEM_REASON "it can't be handled by a 32-bit application"
1982 * LP64 or LLP64; we probably ran out of swap space.
1986 * You need to make the pagefile bigger.
1988 #define ENOMEM_REASON "the pagefile is too small"
1989 #elif defined(__APPLE__)
1991 * dynamic_pager couldn't, or wouldn't, create more swap files.
1993 #define ENOMEM_REASON "your system ran out of swap file space"
1996 * Either you have a fixed swap partition or a fixed swap file,
1997 * and it needs to be made bigger.
1999 * This is UN*X, but it's not macOS, so we assume the user is
2002 #define ENOMEM_REASON "your system is out of swap space"
2004 #endif /* GLIB_SIZEOF_VOID_P == 4 */
2006 errmsg = "The file \"%s\" could not be created because " ENOMEM_REASON ".";
2008 errmsg = "The file \"%s\" could not be opened because " ENOMEM_REASON ".";
2012 g_snprintf(errmsg_errno, sizeof(errmsg_errno),
2013 "The file \"%%s\" could not be %s: %s.",
2014 for_writing ? "created" : "opened",
2016 errmsg = errmsg_errno;
2023 * Return an error message for UNIX-style errno indications on write
2027 file_write_error_message(int err)
2030 static char errmsg_errno[1024+1];
2035 errmsg = "The file \"%s\" could not be saved because there is no space left on the file system.";
2040 errmsg = "The file \"%s\" could not be saved because you are too close to, or over, your disk quota.";
2045 g_snprintf(errmsg_errno, sizeof(errmsg_errno),
2046 "An error occurred while writing to the file \"%%s\": %s.",
2048 errmsg = errmsg_errno;
2056 file_exists(const char *fname)
2058 ws_statb64 file_stat;
2064 #if defined(_MSC_VER) && _MSC_VER < 1900
2067 * This is a bit tricky on win32. The st_ino field is documented as:
2068 * "The inode, and therefore st_ino, has no meaning in the FAT, ..."
2069 * but it *is* set to zero if stat() returns without an error,
2070 * so this is working, but maybe not quite the way expected. ULFL
2072 file_stat.st_ino = 1; /* this will make things work if an error occurred */
2073 ws_stat64(fname, &file_stat);
2074 if (file_stat.st_ino == 0) {
2080 if (ws_stat64(fname, &file_stat) != 0 && errno == ENOENT) {
2089 * Check that the from file is not the same as to file
2090 * We do it here so we catch all cases ...
2091 * Unfortunately, the file requester gives us an absolute file
2092 * name and the read file name may be relative (if supplied on
2093 * the command line), so we can't just compare paths. From Joerg Mayer.
2096 files_identical(const char *fname1, const char *fname2)
2098 /* Two different implementations, because:
2100 * - _fullpath is not available on UN*X, so we can't get full
2101 * paths and compare them (which wouldn't work with hard links
2104 * - st_ino isn't filled in with a meaningful value on Windows.
2107 char full1[MAX_PATH], full2[MAX_PATH];
2110 * Get the absolute full paths of the file and compare them.
2111 * That won't work if you have hard links, but those aren't
2112 * much used on Windows, even though NTFS supports them.
2114 * XXX - will _fullpath work with UNC?
2116 if( _fullpath( full1, fname1, MAX_PATH ) == NULL ) {
2120 if( _fullpath( full2, fname2, MAX_PATH ) == NULL ) {
2124 if(strcmp(full1, full2) == 0) {
2130 ws_statb64 filestat1, filestat2;
2133 * Compare st_dev and st_ino.
2135 if (ws_stat64(fname1, &filestat1) == -1)
2136 return FALSE; /* can't get info about the first file */
2137 if (ws_stat64(fname2, &filestat2) == -1)
2138 return FALSE; /* can't get info about the second file */
2139 return (filestat1.st_dev == filestat2.st_dev &&
2140 filestat1.st_ino == filestat2.st_ino);
2145 * Copy a file in binary mode, for those operating systems that care about
2146 * such things. This should be OK for all files, even text files, as
2147 * we'll copy the raw bytes, and we don't look at the bytes as we copy
2150 * Returns TRUE on success, FALSE on failure. If a failure, it also
2151 * displays a simple dialog window with the error message.
2154 copy_file_binary_mode(const char *from_filename, const char *to_filename)
2156 int from_fd, to_fd, err;
2157 ssize_t nread, nwritten;
2160 /* Copy the raw bytes of the file. */
2161 from_fd = ws_open(from_filename, O_RDONLY | O_BINARY, 0000 /* no creation so don't matter */);
2163 report_open_failure(from_filename, errno, FALSE);
2167 /* Use open() instead of creat() so that we can pass the O_BINARY
2168 flag, which is relevant on Win32; it appears that "creat()"
2169 may open the file in text mode, not binary mode, but we want
2170 to copy the raw bytes of the file, so we need the output file
2171 to be open in binary mode. */
2172 to_fd = ws_open(to_filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644);
2174 report_open_failure(to_filename, errno, TRUE);
2179 #define FS_READ_SIZE 65536
2180 pd = (guint8 *)g_malloc(FS_READ_SIZE);
2181 while ((nread = ws_read(from_fd, pd, FS_READ_SIZE)) > 0) {
2182 nwritten = ws_write(to_fd, pd, nread);
2183 if (nwritten < nread) {
2187 err = WTAP_ERR_SHORT_WRITE;
2188 report_write_failure(to_filename, err);
2196 report_read_failure(from_filename, err);
2202 if (ws_close(to_fd) < 0) {
2203 report_write_failure(to_filename, errno);
2217 data_file_url(const gchar *filename)
2222 /* Absolute path? */
2223 if(g_path_is_absolute(filename)) {
2224 file_path = g_strdup(filename);
2225 } else if(running_in_build_directory()) {
2226 file_path = g_strdup_printf("%s/doc/%s", get_datafile_dir(), filename);
2228 file_path = g_strdup_printf("%s/%s", get_datafile_dir(), filename);
2231 /* XXX - check, if the file is really existing, otherwise display a simple_dialog about the problem */
2233 /* convert filename to uri */
2234 uri = g_filename_to_uri(file_path, NULL, NULL);
2242 g_free(persconffile_dir);
2243 persconffile_dir = NULL;
2244 g_free(persdatafile_dir);
2245 persdatafile_dir = NULL;
2246 g_free(persconfprofile);
2247 persconfprofile = NULL;
2248 g_free(progfile_dir);
2249 progfile_dir = NULL;
2250 #if defined(HAVE_PLUGINS) || defined(HAVE_LUA)
2253 g_free(plugin_dir_with_version);
2254 plugin_dir_with_version = NULL;
2255 g_free(plugin_pers_dir);
2256 plugin_pers_dir = NULL;
2257 g_free(plugin_pers_dir_with_version);
2258 plugin_pers_dir_with_version = NULL;
2272 * indent-tabs-mode: nil
2275 * ex: set shiftwidth=4 tabstop=8 expandtab:
2276 * :indentSize=4:tabSize=8:noTabs=true: