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-or-later
24 #include <wsutil/unicode-utils.h>
27 #include <mach-o/dyld.h>
30 #include <sys/utsname.h>
33 #include <sys/types.h>
34 #include <sys/sysctl.h>
42 #include "filesystem.h"
43 #include <wsutil/report_message.h>
44 #include <wsutil/privileges.h>
45 #include <wsutil/file_util.h>
46 #include <wsutil/utf8_entities.h>
48 #include <wiretap/wtap.h> /* for WTAP_ERR_SHORT_WRITE */
50 #define PROFILES_DIR "profiles"
51 #define PLUGINS_DIR_NAME "plugins"
52 #define PROFILES_INFO_NAME "profile_files.txt"
54 #define ENV_CONFIG_PATH_VAR "WIRESHARK_CONFIG_DIR"
56 char *persconffile_dir = NULL;
57 char *datafile_dir = NULL;
58 char *persdatafile_dir = NULL;
59 char *persconfprofile = NULL;
61 static gboolean do_store_persconffiles = FALSE;
62 static GHashTable *profile_files = NULL;
65 * Given a pathname, return a pointer to the last pathname separator
66 * character in the pathname, or NULL if the pathname contains no
70 find_last_pathname_separator(const char *path)
78 * We have to scan for '\' or '/'.
79 * Get to the end of the string.
81 separator = strchr(path, '\0'); /* points to ending '\0' */
82 while (separator > path) {
84 if (c == '\\' || c == '/')
85 return separator; /* found it */
89 * OK, we didn't find any, so no directories - but there might
90 * be a drive letter....
92 return strchr(path, ':');
94 separator = strrchr(path, '/');
100 * Given a pathname, return the last component.
103 get_basename(const char *path)
105 const char *filename;
107 g_assert(path != NULL);
108 filename = find_last_pathname_separator(path);
109 if (filename == NULL) {
111 * There're no directories, drive letters, etc. in the
112 * name; the pathname *is* the file name.
117 * Skip past the pathname or drive letter separator.
125 * Given a pathname, return a string containing everything but the
126 * last component. NOTE: this overwrites the pathname handed into
130 get_dirname(char *path)
134 g_assert(path != NULL);
135 separator = find_last_pathname_separator(path);
136 if (separator == NULL) {
138 * There're no directories, drive letters, etc. in the
139 * name; there is no directory path to return.
145 * Get rid of the last pathname separator and the final file
151 * "path" now contains the pathname of the directory containing
152 * the file/directory to which it referred.
158 * Given a pathname, return:
160 * the errno, if an attempt to "stat()" the file fails;
162 * EISDIR, if the attempt succeeded and the file turned out
165 * 0, if the attempt succeeded and the file turned out not
170 test_for_directory(const char *path)
174 if (ws_stat64(path, &statb) < 0)
177 if (S_ISDIR(statb.st_mode))
184 test_for_fifo(const char *path)
188 if (ws_stat64(path, &statb) < 0)
191 if (S_ISFIFO(statb.st_mode))
198 * Directory from which the executable came.
200 static char *progfile_dir;
204 * Directory of the application bundle in which we're contained,
205 * if we're contained in an application bundle. Otherwise, NULL.
207 * Note: Table 2-5 "Subdirectories of the Contents directory" of
209 * https://developer.apple.com/library/mac/documentation/CoreFoundation/Conceptual/CFBundles/BundleTypes/BundleTypes.html#//apple_ref/doc/uid/10000123i-CH101-SW1
211 * says that the "Frameworks" directory
213 * Contains any private shared libraries and frameworks used by the
214 * executable. The frameworks in this directory are revision-locked
215 * to the application and cannot be superseded by any other, even
216 * newer, versions that may be available to the operating system. In
217 * other words, the frameworks included in this directory take precedence
218 * over any other similarly named frameworks found in other parts of
219 * the operating system. For information on how to add private
220 * frameworks to your application bundle, see Framework Programming Guide.
222 * so if we were to ship with any frameworks (e.g. Qt) we should
223 * perhaps put them in a Frameworks directory rather than under
226 * It also says that the "PlugIns" directory
228 * Contains loadable bundles that extend the basic features of your
229 * application. You use this directory to include code modules that
230 * must be loaded into your applicationbs process space in order to
231 * be used. You would not use this directory to store standalone
234 * Our plugins are just raw .so/.dylib files; I don't know whether by
235 * "bundles" they mean application bundles (i.e., directory hierarchies)
236 * or just "bundles" in the Mach-O sense (which are an image type that
237 * can be loaded with dlopen() but not linked as libraries; our plugins
238 * are, I think, built as dylibs and can be loaded either way).
240 * And it says that the "SharedSupport" directory
242 * Contains additional non-critical resources that do not impact the
243 * ability of the application to run. You might use this directory to
244 * include things like document templates, clip art, and tutorials
245 * that your application expects to be present but that do not affect
246 * the ability of your application to run.
248 * I don't think I'd put the files that currently go under Resources/share
249 * into that category; they're not, for example, sample Lua scripts that
250 * don't actually get run by Wireshark, they're configuration/data files
251 * for Wireshark whose absence might not prevent Wireshark from running
252 * but that would affect how it behaves when run.
254 static char *appbundle_dir;
258 * TRUE if we're running from the build directory and we aren't running
259 * with special privileges.
261 static gboolean running_in_build_directory_flag = FALSE;
265 * Get the pathname of the executable using various platform-
266 * dependent mechanisms for various UN*Xes.
268 * These calls all should return something independent of the argv[0]
269 * passed to the program, so it shouldn't be fooled by an argv[0]
270 * that doesn't match the executable path.
272 * We don't use dladdr() because:
274 * not all UN*Xes necessarily have dladdr();
276 * those that do have it don't necessarily have dladdr(main)
277 * return information about the executable image;
279 * those that do have a dladdr() where dladdr(main) returns
280 * information about the executable image don't necessarily
281 * have a mechanism by which the executable image can get
282 * its own path from the kernel (either by a call or by it
283 * being handed to it along with argv[] and the environment),
284 * so they just fall back on getting it from argv[0], which we
285 * already have code to do;
287 * those that do have such a mechanism don't necessarily use
288 * it in dladdr(), and, instead, just fall back on getting it
291 * so the only places where it's worth bothering to use dladdr()
292 * are platforms where dladdr(main) return information about the
293 * executable image by getting it from the kernel rather than
294 * by looking at argv[0], and where we can't get at that information
295 * ourselves, and we haven't seen any indication that there are any
298 * In particular, some dynamic linkers supply a dladdr() such that
299 * dladdr(main) just returns something derived from argv[0], so
300 * just using dladdr(main) is the wrong thing to do if there's
301 * another mechanism that can get you a more reliable version of
302 * the executable path.
304 * So, on platforms where we know of a mechanism to get that path
305 * (where getting that path doesn't involve argv[0], which is not
306 * guaranteed to reflect the path to the binary), this routine
307 * attempsts to use that platform's mechanism. On other platforms,
308 * it just returns NULL.
310 * This is not guaranteed to return an absolute path; if it doesn't,
311 * our caller must prepend the current directory if it's a path.
313 * This is not guaranteed to return the "real path"; it might return
314 * something with symbolic links in the path. Our caller must
315 * use realpath() if they want the real thing, but that's also true of
316 * something obtained by looking at argv[0].
319 get_executable_path(void)
321 #if defined(__APPLE__)
322 char *executable_path;
323 uint32_t path_buf_size;
325 path_buf_size = PATH_MAX;
326 executable_path = (char *)g_malloc(path_buf_size);
327 if (_NSGetExecutablePath(executable_path, &path_buf_size) == -1) {
328 executable_path = (char *)g_realloc(executable_path, path_buf_size);
329 if (_NSGetExecutablePath(executable_path, &path_buf_size) == -1)
332 return executable_path;
333 #elif defined(__linux__)
335 * In older versions of GNU libc's dynamic linker, as used on Linux,
336 * dladdr(main) supplies a path based on argv[0], so we use
337 * /proc/self/exe instead; there are Linux distributions with
338 * kernels that support /proc/self/exe and those older versions
339 * of the dynamic linker, and this will get a better answer on
342 * It only works on Linux 2.2 or later, so we just give up on
345 * XXX - are there OS versions that support "exe" but not "self"?
348 static char executable_path[PATH_MAX + 1];
351 if (uname(&name) == -1)
353 if (strncmp(name.release, "1.", 2) == 0)
354 return NULL; /* Linux 1.x */
355 if (strcmp(name.release, "2.0") == 0 ||
356 strncmp(name.release, "2.0.", 4) == 0 ||
357 strcmp(name.release, "2.1") == 0 ||
358 strncmp(name.release, "2.1.", 4) == 0)
359 return NULL; /* Linux 2.0.x or 2.1.x */
360 if ((r = readlink("/proc/self/exe", executable_path, PATH_MAX)) == -1)
362 executable_path[r] = '\0';
363 return executable_path;
364 #elif defined(__FreeBSD__) && defined(KERN_PROC_PATHNAME)
366 * In older versions of FreeBSD's dynamic linker, dladdr(main)
367 * supplies a path based on argv[0], so we use the KERN_PROC_PATHNAME
368 * sysctl instead; there are, I think, versions of FreeBSD
369 * that support the sysctl that have and those older versions
370 * of the dynamic linker, and this will get a better answer on
374 char *executable_path;
375 size_t path_buf_size;
379 mib[2] = KERN_PROC_PATHNAME;
381 path_buf_size = PATH_MAX;
382 executable_path = (char *)g_malloc(path_buf_size);
383 if (sysctl(mib, 4, executable_path, &path_buf_size, NULL, 0) == -1) {
386 executable_path = (char *)g_realloc(executable_path, path_buf_size);
387 if (sysctl(mib, 4, executable_path, &path_buf_size, NULL, 0) == -1)
390 return executable_path;
391 #elif defined(__NetBSD__)
393 * In all versions of NetBSD's dynamic linker as of 2013-08-12,
394 * dladdr(main) supplies a path based on argv[0], so we use
395 * /proc/curproc/exe instead.
397 * XXX - are there OS versions that support "exe" but not "curproc"
398 * or "self"? Are there any that support "self" but not "curproc"?
400 static char executable_path[PATH_MAX + 1];
403 if ((r = readlink("/proc/curproc/exe", executable_path, PATH_MAX)) == -1)
405 executable_path[r] = '\0';
406 return executable_path;
407 #elif defined(__DragonFly__)
409 * In older versions of DragonFly BSD's dynamic linker, dladdr(main)
410 * supplies a path based on argv[0], so we use /proc/curproc/file
411 * instead; it appears to be supported by all versions of DragonFly
414 static char executable_path[PATH_MAX + 1];
417 if ((r = readlink("/proc/curproc/file", executable_path, PATH_MAX)) == -1)
419 executable_path[r] = '\0';
420 return executable_path;
421 #elif defined(HAVE_GETEXECNAME)
423 * Solaris, with getexecname().
424 * It appears that getexecname() dates back to at least Solaris 8,
425 * but /proc/{pid}/path is first documented in the Solaris 10 documentation,
426 * so we use getexecname() if available, rather than /proc/self/path/a.out
427 * (which isn't documented, but appears to be a symlink to the
428 * executable image file).
430 return getexecname();
431 #elif defined(HAVE_DLGET)
433 * HP-UX 11, with dlget(); use dlget() and dlgetname().
436 * https://web.archive.org/web/20081025174755/http://h21007.www2.hp.com/portal/site/dspp/menuitem.863c3e4cbcdc3f3515b49c108973a801?ciid=88086d6e1de021106d6e1de02110275d6e10RCRD#two
438 struct load_module_desc desc;
440 if (dlget(-2, &desc, sizeof(desc)) != NULL)
441 return dlgetname(&desc, sizeof(desc), NULL, NULL, NULL);
445 /* Fill in your favorite UN*X's code here, if there is something */
452 * Get the pathname of the directory from which the executable came,
453 * and save it for future use. Returns NULL on success, and a
454 * g_mallocated string containing an error on failure.
457 init_progfile_dir(const char *arg0
464 TCHAR prog_pathname_w[_MAX_PATH+2];
472 * Attempt to get the full pathname of the currently running
475 if (GetModuleFileName(NULL, prog_pathname_w, G_N_ELEMENTS(prog_pathname_w)) != 0 && GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
477 * XXX - Should we use g_utf16_to_utf8()?
479 prog_pathname = utf_16to8(prog_pathname_w);
481 * We got it; strip off the last component, which would be
482 * the file name of the executable, giving us the pathname
483 * of the directory where the executable resides.
485 progfile_dir = g_path_get_dirname(prog_pathname);
486 if (progfile_dir != NULL) {
487 return NULL; /* we succeeded */
490 * OK, no. What do we do now?
492 return g_strdup_printf("No \\ in executable pathname \"%s\"",
497 * Oh, well. Return an indication of the error.
499 error = GetLastError();
500 if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,
501 NULL, error, 0, (LPTSTR) &msg_w, 0, NULL) == 0) {
503 * Gak. We can't format the message.
505 return g_strdup_printf("GetModuleFileName failed: %u (FormatMessage failed: %u)",
506 error, GetLastError());
508 msg = utf_16to8(msg_w);
511 * "FormatMessage()" "helpfully" sticks CR/LF at the
512 * end of the message. Get rid of it.
514 msglen = strlen(msg);
516 msg[msglen - 1] = '\0';
517 msg[msglen - 2] = '\0';
519 return g_strdup_printf("GetModuleFileName failed: %s (%u)",
523 const char *execname;
528 const char *path_start, *path_end;
529 size_t path_component_len, path_len;
535 * Check whether WIRESHARK_RUN_FROM_BUILD_DIRECTORY is set in the
536 * environment; if so, set running_in_build_directory_flag if we
537 * weren't started with special privileges. (If we were started
538 * with special privileges, it's not safe to allow the user to point
539 * us to some other directory; running_in_build_directory_flag, when
540 * set, causes us to look for plugins and the like in the build
543 if (g_getenv("WIRESHARK_RUN_FROM_BUILD_DIRECTORY") != NULL
544 && !started_with_special_privs())
545 running_in_build_directory_flag = TRUE;
547 execname = get_executable_path();
548 if (execname == NULL) {
550 * OK, guess based on argv[0].
556 * Try to figure out the directory in which the currently running
557 * program resides, given something purporting to be the executable
558 * name (from an OS mechanism or from the argv[0] it was started with).
559 * That might be the absolute path of the program, or a path relative
560 * to the current directory of the process that started it, or
561 * just a name for the program if it was started from the command
562 * line and was searched for in $PATH. It's not guaranteed to be
563 * any of those, however, so there are no guarantees....
565 if (execname[0] == '/') {
567 * It's an absolute path.
569 prog_pathname = g_strdup(execname);
570 } else if (strchr(execname, '/') != NULL) {
572 * It's a relative path, with a directory in it.
573 * Get the current directory, and combine it
574 * with that directory.
576 path_max = pathconf(".", _PC_PATH_MAX);
577 if (path_max == -1) {
579 * We have no idea how big a buffer to
580 * allocate for the current directory.
582 return g_strdup_printf("pathconf failed: %s\n",
585 curdir = (char *)g_malloc(path_max);
586 if (getcwd(curdir, path_max) == NULL) {
588 * It failed - give up, and just stick
592 return g_strdup_printf("getcwd failed: %s\n",
595 path = g_strdup_printf("%s/%s", curdir, execname);
597 prog_pathname = path;
600 * It's just a file name.
601 * Search the path for a file with that name
604 prog_pathname = NULL; /* haven't found it yet */
605 pathstr = g_getenv("PATH");
606 path_start = pathstr;
607 if (path_start != NULL) {
608 while (*path_start != '\0') {
609 path_end = strchr(path_start, ':');
610 if (path_end == NULL)
611 path_end = path_start + strlen(path_start);
612 path_component_len = path_end - path_start;
613 path_len = path_component_len + 1
614 + strlen(execname) + 1;
615 path = (char *)g_malloc(path_len);
616 memcpy(path, path_start, path_component_len);
617 path[path_component_len] = '\0';
618 g_strlcat(path, "/", path_len);
619 g_strlcat(path, execname, path_len);
620 if (access(path, X_OK) == 0) {
624 prog_pathname = path;
629 * That's not it. If there are more
630 * path components to test, try them.
632 if (*path_end == ':')
634 path_start = path_end;
637 if (prog_pathname == NULL) {
639 * Program not found in path.
641 return g_strdup_printf("\"%s\" not found in \"%s\"",
647 * XXX - should we pick a default?
649 return g_strdup("PATH isn't set");
654 * OK, we have what we think is the pathname
657 * First, find the last "/" in the directory,
658 * as that marks the end of the directory pathname.
660 dir_end = strrchr(prog_pathname, '/');
661 if (dir_end != NULL) {
663 * Found it. Strip off the last component,
664 * as that's the path of the program.
669 * Is there a "/run" at the end?
671 dir_end = strrchr(prog_pathname, '/');
672 if (dir_end != NULL) {
673 if (!started_with_special_privs()) {
675 * Check for the CMake output directory. As people may name
676 * their directories "run" (really?), also check for the
677 * CMakeCache.txt file before assuming a CMake output dir.
679 if (strcmp(dir_end, "/run") == 0) {
681 cmake_file = g_strdup_printf("%.*s/CMakeCache.txt",
682 (int)(dir_end - prog_pathname),
684 if (file_exists(cmake_file))
685 running_in_build_directory_flag = TRUE;
691 * Scan up the path looking for a component
692 * named "Contents". If we find it, we assume
693 * we're in a bundle, and that the top-level
694 * directory of the bundle is the one containing
697 * Not all executables are in the Contents/MacOS
698 * directory, so we can't just check for those
699 * in the path and strip them off.
701 * XXX - should we assume that it's either
702 * Contents/MacOS or Resources/bin?
704 char *component_end, *p;
706 component_end = strchr(prog_pathname, '\0');
709 while (p >= prog_pathname && *p != '/')
711 if (p == prog_pathname) {
713 * We're looking at the first component of
714 * the pathname now, so we're definitely
715 * not in a bundle, even if we're in
720 if (strncmp(p, "/Contents", component_end - p) == 0) {
722 appbundle_dir = (char *)g_malloc(p - prog_pathname + 1);
723 memcpy(appbundle_dir, prog_pathname, p - prog_pathname);
724 appbundle_dir[p - prog_pathname] = '\0';
736 * OK, we have the path we want.
738 progfile_dir = prog_pathname;
742 * This "shouldn't happen"; we apparently
743 * have no "/" in the pathname.
744 * Just free up prog_pathname.
746 retstr = g_strdup_printf("No / found in \"%s\"", prog_pathname);
747 g_free(prog_pathname);
754 * Get the directory in which the program resides.
757 get_progfile_dir(void)
763 * Get the directory in which the global configuration and data files are
766 * On Windows, we use the directory in which the executable for this
769 * On macOS (when executed from an app bundle), use a directory within
772 * Otherwise, if the program was executed from the build directory, use the
773 * directory in which the executable for this process resides. In all other
774 * cases, use the DATA_DIR value that was set at compile time.
776 * XXX - if we ever make libwireshark a real library, used by multiple
777 * applications (more than just TShark and versions of Wireshark with
778 * various UIs), should the configuration files belong to the library
779 * (and be shared by all those applications) or to the applications?
781 * If they belong to the library, that could be done on UNIX by the
782 * configure script, but it's trickier on Windows, as you can't just
783 * use the pathname of the executable.
785 * If they belong to the application, that could be done on Windows
786 * by using the pathname of the executable, but we'd have to have it
787 * passed in as an argument, in some call, on UNIX.
789 * Note that some of those configuration files might be used by code in
790 * libwireshark, some of them might be used by dissectors (would they
791 * belong to libwireshark, the application, or a separate library?),
792 * and some of them might be used by other code (the Wireshark preferences
793 * file includes resolver preferences that control the behavior of code
794 * in libwireshark, dissector preferences, and UI preferences, for
798 get_datafile_dir(void)
800 if (datafile_dir != NULL)
805 * Do we have the pathname of the program? If so, assume we're
806 * running an installed version of the program. If we fail,
807 * we don't change "datafile_dir", and thus end up using the
810 * XXX - does NSIS put the installation directory into
811 * "\HKEY_LOCAL_MACHINE\SOFTWARE\Wireshark\InstallDir"?
812 * If so, perhaps we should read that from the registry,
815 if (progfile_dir != NULL) {
817 * Yes, we do; use that.
819 datafile_dir = g_strdup(progfile_dir);
823 * Fall back on the default installation directory.
825 datafile_dir = g_strdup("C:\\Program Files\\Wireshark\\");
829 if (g_getenv("WIRESHARK_DATA_DIR") && !started_with_special_privs()) {
831 * The user specified a different directory for data files
832 * and we aren't running with special privileges.
833 * XXX - We might be able to dispense with the priv check
835 datafile_dir = g_strdup(g_getenv("WIRESHARK_DATA_DIR"));
839 * If we're running from an app bundle and weren't started
840 * with special privileges, use the Contents/Resources/share/wireshark
841 * subdirectory of the app bundle.
843 * (appbundle_dir is not set to a non-null value if we're
844 * started with special privileges, so we need only check
845 * it; we don't need to call started_with_special_privs().)
847 else if (appbundle_dir != NULL) {
848 datafile_dir = g_strdup_printf("%s/Contents/Resources/share/wireshark",
852 else if (running_in_build_directory_flag && progfile_dir != NULL) {
854 * We're (probably) being run from the build directory and
855 * weren't started with special privileges.
857 * (running_in_build_directory_flag is never set to TRUE
858 * if we're started with special privileges, so we need
859 * only check it; we don't need to call started_with_special_privs().)
861 * Data files (console.lua, radius/, etc.) are copied to the build
862 * directory during the build which also contains executables. A special
863 * exception is macOS (when built with an app bundle).
865 datafile_dir = g_strdup(progfile_dir);
867 datafile_dir = g_strdup(DATA_DIR);
875 * Find the directory where the plugins are stored.
877 * On Windows, we use the plugin\{VERSION} subdirectory of the datafile
878 * directory, where {VERSION} is the version number of this version of
883 * if we appear to be run from the build directory, we use the
884 * "plugin" subdirectory of the datafile directory;
886 * otherwise, if the WIRESHARK_PLUGIN_DIR environment variable is
887 * set and we aren't running with special privileges, we use the
888 * value of that environment variable;
890 * otherwise, if we're running from an app bundle in macOS, we
891 * use the Contents/PlugIns/wireshark subdirectory of the app bundle;
893 * otherwise, we use the PLUGIN_DIR value supplied by the
896 static char *plugin_dir = NULL;
897 static char *plugin_dir_with_version = NULL;
898 static char *plugin_pers_dir = NULL;
899 static char *plugin_pers_dir_with_version = NULL;
902 init_plugin_dir(void)
904 #if defined(HAVE_PLUGINS) || defined(HAVE_LUA)
907 * On Windows, the data file directory is the installation
908 * directory; the plugins are stored under it.
910 * Assume we're running the installed version of Wireshark;
911 * on Windows, the data file directory is the directory
912 * in which the Wireshark binary resides.
914 plugin_dir = g_build_filename(get_datafile_dir(), "plugins", (gchar *)NULL);
917 * Make sure that pathname refers to a directory.
919 if (test_for_directory(plugin_dir) != EISDIR) {
921 * Either it doesn't refer to a directory or it
922 * refers to something that doesn't exist.
924 * Assume that means we're running a version of
925 * Wireshark we've built in a build directory,
926 * in which case {datafile dir}\plugins is the
927 * top-level plugins source directory, and use
928 * that directory and set the "we're running in
929 * a build directory" flag, so the plugin
930 * scanner will check all subdirectories of that
931 * directory for plugins.
934 plugin_dir = g_build_filename(get_datafile_dir(), "plugins", (gchar *)NULL);
935 running_in_build_directory_flag = TRUE;
938 if (running_in_build_directory_flag) {
940 * We're (probably) being run from the build directory and
941 * weren't started with special privileges, so we'll use
942 * the "plugins" subdirectory of the directory where the program
943 * we're running is (that's the build directory).
945 plugin_dir = g_build_filename(get_progfile_dir(), "plugins", (gchar *)NULL);
947 if (g_getenv("WIRESHARK_PLUGIN_DIR") && !started_with_special_privs()) {
949 * The user specified a different directory for plugins
950 * and we aren't running with special privileges.
952 plugin_dir = g_strdup(g_getenv("WIRESHARK_PLUGIN_DIR"));
956 * If we're running from an app bundle and weren't started
957 * with special privileges, use the Contents/PlugIns/wireshark
958 * subdirectory of the app bundle.
960 * (appbundle_dir is not set to a non-null value if we're
961 * started with special privileges, so we need only check
962 * it; we don't need to call started_with_special_privs().)
964 else if (appbundle_dir != NULL) {
965 plugin_dir = g_build_filename(appbundle_dir, "Contents/PlugIns/wireshark", (gchar *)NULL);
969 plugin_dir = g_strdup(PLUGIN_DIR);
973 #endif /* defined(HAVE_PLUGINS) || defined(HAVE_LUA) */
977 init_plugin_pers_dir(void)
979 #if defined(HAVE_PLUGINS) || defined(HAVE_LUA)
981 plugin_pers_dir = get_persconffile_path(PLUGINS_DIR_NAME, FALSE);
983 plugin_pers_dir = g_build_filename(g_get_home_dir(), ".local/lib/wireshark/" PLUGINS_DIR_NAME, (gchar *)NULL);
985 #endif /* defined(HAVE_PLUGINS) || defined(HAVE_LUA) */
989 * Get the directory in which the plugins are stored.
992 get_plugins_dir(void)
1000 get_plugins_dir_with_version(void)
1004 if (plugin_dir && !plugin_dir_with_version)
1005 plugin_dir_with_version = g_build_filename(plugin_dir, VERSION_RELEASE, (gchar *)NULL);
1006 return plugin_dir_with_version;
1009 /* Get the personal plugin dir */
1011 get_plugins_pers_dir(void)
1013 if (!plugin_pers_dir)
1014 init_plugin_pers_dir();
1015 return plugin_pers_dir;
1019 get_plugins_pers_dir_with_version(void)
1021 if (!plugin_pers_dir)
1022 init_plugin_pers_dir();
1023 if (plugin_pers_dir && !plugin_pers_dir_with_version)
1024 plugin_pers_dir_with_version = g_build_filename(plugin_pers_dir, VERSION_RELEASE, (gchar *)NULL);
1025 return plugin_pers_dir_with_version;
1029 * Find the directory where the extcap hooks are stored.
1031 * On Windows, we use the "extcap" subdirectory of the datafile directory.
1033 * On UN*X, we use the EXTCAP_DIR value supplied by the configure
1034 * script, unless we think we're being run from the build directory,
1035 * in which case we use the "extcap" subdirectory of the datafile directory.
1037 * In both cases, we then use the subdirectory of that directory whose
1038 * name is the version number.
1040 * XXX - if we think we're being run from the build directory, perhaps we
1041 * should have the extcap code not look in the version subdirectory
1042 * of the extcap directory, but look in all of the subdirectories
1043 * of the extcap directory, so it can just fetch the extcap hooks built
1044 * as part of the build process.
1046 static char *extcap_dir = NULL;
1048 static void init_extcap_dir(void) {
1050 const char *alt_extcap_path;
1053 * On Windows, the data file directory is the installation
1054 * directory; the extcap hooks are stored under it.
1056 * Assume we're running the installed version of Wireshark;
1057 * on Windows, the data file directory is the directory
1058 * in which the Wireshark binary resides.
1060 alt_extcap_path = g_getenv("WIRESHARK_EXTCAP_DIR");
1061 if (alt_extcap_path) {
1063 * The user specified a different directory for extcap hooks.
1065 extcap_dir = g_strdup(alt_extcap_path);
1067 extcap_dir = g_build_filename(get_datafile_dir(), "extcap", (gchar *)NULL);
1070 if (running_in_build_directory_flag) {
1072 * We're (probably) being run from the build directory and
1073 * weren't started with special privileges, so we'll use
1074 * the "extcap hooks" subdirectory of the directory where the program
1075 * we're running is (that's the build directory).
1077 extcap_dir = g_build_filename(get_progfile_dir(), "extcap", (gchar *)NULL);
1079 if (g_getenv("WIRESHARK_EXTCAP_DIR") && !started_with_special_privs()) {
1081 * The user specified a different directory for extcap hooks
1082 * and we aren't running with special privileges.
1084 extcap_dir = g_strdup(g_getenv("WIRESHARK_EXTCAP_DIR"));
1088 * If we're running from an app bundle and weren't started
1089 * with special privileges, use the Contents/MacOS/extcap
1090 * subdirectory of the app bundle.
1092 * (appbundle_dir is not set to a non-null value if we're
1093 * started with special privileges, so we need only check
1094 * it; we don't need to call started_with_special_privs().)
1096 else if (appbundle_dir != NULL) {
1097 extcap_dir = g_build_filename(appbundle_dir, "Contents/MacOS/extcap", (gchar *)NULL);
1101 extcap_dir = g_strdup(EXTCAP_DIR);
1108 * Get the directory in which the extcap hooks are stored.
1112 get_extcap_dir(void)
1120 * Get the flag indicating whether we're running from a build
1124 running_in_build_directory(void)
1126 return running_in_build_directory_flag;
1130 * Get the directory in which files that, at least on UNIX, are
1131 * system files (such as "/etc/ethers") are stored; on Windows,
1132 * there's no "/etc" directory, so we get them from the global
1133 * configuration and data file directory.
1136 get_systemfile_dir(void)
1139 return get_datafile_dir();
1146 set_profile_name(const gchar *profilename)
1148 g_free (persconfprofile);
1150 if (profilename && strlen(profilename) > 0 &&
1151 strcmp(profilename, DEFAULT_PROFILE) != 0) {
1152 persconfprofile = g_strdup (profilename);
1154 /* Default Profile */
1155 persconfprofile = NULL;
1160 get_profile_name(void)
1162 if (persconfprofile) {
1163 return persconfprofile;
1165 return DEFAULT_PROFILE;
1170 is_default_profile(void)
1172 return (!persconfprofile || strcmp(persconfprofile, DEFAULT_PROFILE) == 0) ? TRUE : FALSE;
1176 has_global_profiles(void)
1180 gchar *global_dir = get_global_profiles_dir();
1182 gboolean has_global = FALSE;
1184 if ((test_for_directory(global_dir) == EISDIR) &&
1185 ((dir = ws_dir_open(global_dir, 0, NULL)) != NULL))
1187 while ((file = ws_dir_read_name(dir)) != NULL) {
1188 filename = g_strdup_printf ("%s%s%s", global_dir, G_DIR_SEPARATOR_S,
1189 ws_dir_get_name(file));
1190 if (test_for_directory(filename) == EISDIR) {
1204 profile_store_persconffiles(gboolean store)
1207 profile_files = g_hash_table_new (g_str_hash, g_str_equal);
1209 do_store_persconffiles = store;
1213 * Get the directory in which personal configuration files reside.
1215 * On Windows, it's "Wireshark", under %APPDATA% or, if %APPDATA% isn't set,
1216 * it's "%USERPROFILE%\Application Data" (which is what %APPDATA% normally
1217 * is on Windows 2000).
1219 * On UNIX-compatible systems, we first look in XDG_CONFIG_HOME/wireshark
1220 * and, if that doesn't exist, ~/.wireshark, for backwards compatibility.
1221 * If neither exists, we use XDG_CONFIG_HOME/wireshark, so that the directory
1222 * is initially created as XDG_CONFIG_HOME/wireshark. We use that regardless
1223 * of whether the user is running under an XDG desktop or not, so that
1224 * if the user's home directory is on a server and shared between
1225 * different desktop environments on different machines, they can all
1226 * share the same configuration file directory.
1228 * XXX - what about stuff that shouldn't be shared between machines,
1229 * such as plugins in the form of shared loadable images?
1232 get_persconffile_dir_no_profile(void)
1236 /* Return the cached value, if available */
1237 if (persconffile_dir != NULL)
1238 return persconffile_dir;
1241 * See if the user has selected an alternate environment.
1243 env = g_getenv(ENV_CONFIG_PATH_VAR);
1246 /* for backward compatibility */
1247 env = g_getenv("WIRESHARK_APPDATA");
1251 persconffile_dir = g_strdup(env);
1252 return persconffile_dir;
1257 * Use %APPDATA% or %USERPROFILE%, so that configuration
1258 * files are stored in the user profile, rather than in
1259 * the home directory. The Windows convention is to store
1260 * configuration information in the user profile, and doing
1261 * so means you can use Wireshark even if the home directory
1262 * is an inaccessible network drive.
1264 env = g_getenv("APPDATA");
1267 * Concatenate %APPDATA% with "\Wireshark".
1269 persconffile_dir = g_build_filename(env, "Wireshark", NULL);
1270 return persconffile_dir;
1274 * OK, %APPDATA% wasn't set, so use %USERPROFILE%\Application Data.
1276 env = g_getenv("USERPROFILE");
1278 persconffile_dir = g_build_filename(env, "Application Data", "Wireshark", NULL);
1279 return persconffile_dir;
1283 * Give up and use "C:".
1285 persconffile_dir = g_build_filename("C:", "Wireshark", NULL);
1286 return persconffile_dir;
1288 char *xdg_path, *path;
1290 const char *homedir;
1293 * Check if XDG_CONFIG_HOME/wireshark exists and is a directory.
1295 xdg_path = g_build_filename(g_get_user_config_dir(), "wireshark", NULL);
1296 if (g_file_test(xdg_path, G_FILE_TEST_IS_DIR)) {
1297 persconffile_dir = xdg_path;
1298 return persconffile_dir;
1302 * It doesn't exist, or it does but isn't a directory, so try
1305 * If $HOME is set, use that for ~.
1307 * (Note: before GLib 2.36, g_get_home_dir() didn't look at $HOME,
1308 * but we always want to do so, so we don't use g_get_home_dir().)
1310 homedir = g_getenv("HOME");
1311 if (homedir == NULL) {
1315 * Get their home directory from the password file.
1316 * If we can't even find a password file entry for them,
1319 pwd = getpwuid(getuid());
1321 homedir = pwd->pw_dir;
1326 path = g_build_filename(homedir, ".wireshark", NULL);
1327 if (g_file_test(path, G_FILE_TEST_IS_DIR)) {
1329 persconffile_dir = path;
1330 return persconffile_dir;
1334 * Neither are directories that exist; use the XDG path, so we'll
1335 * create that as necessary.
1338 persconffile_dir = xdg_path;
1339 return persconffile_dir;
1344 set_persconffile_dir(const char *p)
1346 g_free(persconffile_dir);
1347 persconffile_dir = g_strdup(p);
1351 get_profiles_dir(void)
1353 return g_strdup_printf ("%s%s%s", get_persconffile_dir_no_profile (),
1354 G_DIR_SEPARATOR_S, PROFILES_DIR);
1358 create_profiles_dir(char **pf_dir_path_return)
1364 * Create the "Default" personal configuration files directory, if necessary.
1366 if (create_persconffile_profile (NULL, pf_dir_path_return) == -1) {
1371 * Check if profiles directory exists.
1372 * If not then create it.
1374 pf_dir_path = get_profiles_dir ();
1375 if (ws_stat64(pf_dir_path, &s_buf) != 0) {
1376 if (errno != ENOENT) {
1377 /* Some other problem; give up now. */
1378 *pf_dir_path_return = pf_dir_path;
1383 * It doesn't exist; try to create it.
1385 int ret = ws_mkdir(pf_dir_path, 0755);
1387 *pf_dir_path_return = pf_dir_path;
1391 g_free(pf_dir_path);
1397 get_global_profiles_dir(void)
1399 return g_strdup_printf ("%s%s%s", get_datafile_dir(),
1400 G_DIR_SEPARATOR_S, PROFILES_DIR);
1404 get_persconffile_dir(const gchar *profilename)
1406 char *persconffile_profile_dir = NULL, *profile_dir;
1408 if (profilename && strlen(profilename) > 0 &&
1409 strcmp(profilename, DEFAULT_PROFILE) != 0) {
1410 profile_dir = get_profiles_dir();
1411 persconffile_profile_dir = g_strdup_printf ("%s%s%s", profile_dir,
1412 G_DIR_SEPARATOR_S, profilename);
1413 g_free(profile_dir);
1415 persconffile_profile_dir = g_strdup (get_persconffile_dir_no_profile ());
1418 return persconffile_profile_dir;
1422 get_profile_dir(const char *profilename, gboolean is_global)
1427 if (profilename && strlen(profilename) > 0 &&
1428 strcmp(profilename, DEFAULT_PROFILE) != 0)
1430 gchar *global_path = get_global_profiles_dir();
1431 profile_dir = g_build_filename(global_path, profilename, NULL);
1432 g_free(global_path);
1434 profile_dir = g_strdup(get_datafile_dir());
1438 * If we didn't supply a profile name, i.e. if profilename is
1439 * null, get_persconffile_dir() returns the default profile.
1441 profile_dir = get_persconffile_dir(profilename);
1448 profile_exists(const gchar *profilename, gboolean global)
1454 * If we're looking up a global profile, we must have a
1457 if (global && !profilename)
1460 path = get_profile_dir(profilename, global);
1461 exists = (test_for_directory(path) == EISDIR) ? TRUE : FALSE;
1468 delete_directory (const char *directory, char **pf_dir_path_return)
1475 if ((dir = ws_dir_open(directory, 0, NULL)) != NULL) {
1476 while ((file = ws_dir_read_name(dir)) != NULL) {
1477 filename = g_strdup_printf ("%s%s%s", directory, G_DIR_SEPARATOR_S,
1478 ws_dir_get_name(file));
1479 if (test_for_directory(filename) != EISDIR) {
1480 ret = ws_remove(filename);
1483 /* The user has manually created a directory in the profile directory */
1484 /* I do not want to delete the directory recursively yet */
1485 ret = delete_directory (filename, pf_dir_path_return);
1489 *pf_dir_path_return = filename;
1497 if (ret == 0 && (ret = ws_remove(directory)) != 0) {
1498 *pf_dir_path_return = g_strdup (directory);
1505 reset_default_profile(char **pf_dir_path_return)
1507 char *profile_dir = get_persconffile_dir(NULL);
1508 gchar *filename, *del_file;
1509 GList *files, *file;
1512 files = g_hash_table_get_keys(profile_files);
1513 file = g_list_first(files);
1515 filename = (gchar *)file->data;
1516 del_file = g_strdup_printf("%s%s%s", profile_dir, G_DIR_SEPARATOR_S, filename);
1518 if (file_exists(del_file)) {
1519 ret = ws_remove(del_file);
1521 *pf_dir_path_return = profile_dir;
1528 file = g_list_next(file);
1532 g_free(profile_dir);
1537 delete_persconffile_profile(const char *profilename, char **pf_dir_path_return)
1539 if (strcmp(profilename, DEFAULT_PROFILE) == 0) {
1540 return reset_default_profile(pf_dir_path_return);
1543 char *profile_dir = get_persconffile_dir(profilename);
1546 if (test_for_directory (profile_dir) == EISDIR) {
1547 ret = delete_directory (profile_dir, pf_dir_path_return);
1550 g_free(profile_dir);
1555 rename_persconffile_profile(const char *fromname, const char *toname,
1556 char **pf_from_dir_path_return, char **pf_to_dir_path_return)
1558 char *from_dir = get_persconffile_dir(fromname);
1559 char *to_dir = get_persconffile_dir(toname);
1562 ret = ws_rename (from_dir, to_dir);
1564 *pf_from_dir_path_return = from_dir;
1565 *pf_to_dir_path_return = to_dir;
1576 * Create the directory that holds personal configuration files, if
1577 * necessary. If we attempted to create it, and failed, return -1 and
1578 * set "*pf_dir_path_return" to the pathname of the directory we failed
1579 * to create (it's g_mallocated, so our caller should free it); otherwise,
1583 create_persconffile_profile(const char *profilename, char **pf_dir_path_return)
1587 char *pf_dir_path_copy, *pf_dir_parent_path;
1588 size_t pf_dir_parent_path_len;
1596 * Create the personal profiles directory, if necessary.
1598 if (create_profiles_dir(pf_dir_path_return) == -1) {
1603 pf_dir_path = get_persconffile_dir(profilename);
1604 if (ws_stat64(pf_dir_path, &s_buf) != 0) {
1605 if (errno != ENOENT) {
1606 /* Some other problem; give up now. */
1607 *pf_dir_path_return = pf_dir_path;
1612 * Does the parent directory of that directory
1613 * exist? %APPDATA% may not exist even though
1614 * %USERPROFILE% does.
1616 * We check for the existence of the directory
1617 * by first checking whether the parent directory
1618 * is just a drive letter and, if it's not, by
1619 * doing a "stat()" on it. If it's a drive letter,
1620 * or if the "stat()" succeeds, we assume it exists.
1622 pf_dir_path_copy = g_strdup(pf_dir_path);
1623 pf_dir_parent_path = get_dirname(pf_dir_path_copy);
1624 pf_dir_parent_path_len = strlen(pf_dir_parent_path);
1625 if (pf_dir_parent_path_len > 0
1626 && pf_dir_parent_path[pf_dir_parent_path_len - 1] != ':'
1627 && ws_stat64(pf_dir_parent_path, &s_buf) != 0) {
1629 * Not a drive letter and the stat() failed.
1631 if (errno != ENOENT) {
1632 /* Some other problem; give up now. */
1633 *pf_dir_path_return = pf_dir_path;
1635 g_free(pf_dir_path_copy);
1640 * No, it doesn't exist - make it first.
1642 ret = ws_mkdir(pf_dir_parent_path, 0755);
1644 *pf_dir_path_return = pf_dir_parent_path;
1646 g_free(pf_dir_path);
1651 g_free(pf_dir_path_copy);
1652 ret = ws_mkdir(pf_dir_path, 0755);
1654 ret = g_mkdir_with_parents(pf_dir_path, 0755);
1658 * Something with that pathname exists; if it's not
1659 * a directory, we'll get an error if we try to put
1660 * something in it, so we don't fail here, we wait
1661 * for that attempt fo fail.
1666 *pf_dir_path_return = pf_dir_path;
1668 g_free(pf_dir_path);
1674 create_persconffile_dir(char **pf_dir_path_return)
1676 return create_persconffile_profile(persconfprofile, pf_dir_path_return);
1680 copy_persconffile_profile(const char *toname, const char *fromname, gboolean from_global,
1681 char **pf_filename_return, char **pf_to_dir_path_return, char **pf_from_dir_path_return)
1684 gchar *to_dir = get_persconffile_dir(toname);
1685 gchar *filename, *from_file, *to_file;
1686 GList *files, *file;
1688 from_dir = get_profile_dir(fromname, from_global);
1690 files = g_hash_table_get_keys(profile_files);
1691 file = g_list_first(files);
1693 filename = (gchar *)file->data;
1694 from_file = g_strdup_printf ("%s%s%s", from_dir, G_DIR_SEPARATOR_S, filename);
1695 to_file = g_strdup_printf ("%s%s%s", to_dir, G_DIR_SEPARATOR_S, filename);
1697 if (file_exists(from_file) && !copy_file_binary_mode(from_file, to_file)) {
1698 *pf_filename_return = g_strdup(filename);
1699 *pf_to_dir_path_return = to_dir;
1700 *pf_from_dir_path_return = from_dir;
1709 file = g_list_next(file);
1712 g_list_free (files);
1720 * Get the (default) directory in which personal data is stored.
1722 * On Win32, this is the "My Documents" folder in the personal profile.
1723 * On UNIX this is simply the current directory.
1725 /* XXX - should this and the get_home_dir() be merged? */
1727 get_persdatafile_dir(void)
1730 TCHAR tszPath[MAX_PATH];
1732 /* Return the cached value, if available */
1733 if (persdatafile_dir != NULL)
1734 return persdatafile_dir;
1737 * Hint: SHGetFolderPath is not available on MSVC 6 - without
1740 if (SHGetSpecialFolderPath(NULL, tszPath, CSIDL_PERSONAL, FALSE)) {
1741 persdatafile_dir = g_utf16_to_utf8(tszPath, -1, NULL, NULL, NULL);
1742 return persdatafile_dir;
1752 set_persdatafile_dir(const char *p)
1754 g_free(persdatafile_dir);
1755 persdatafile_dir = g_strdup(p);
1760 * Returns the user's home directory on Win32.
1765 static const char *home = NULL;
1766 const char *homedrive, *homepath;
1770 /* Return the cached value, if available */
1775 * XXX - should we use USERPROFILE anywhere in this process?
1776 * Is there a chance that it might be set but one or more of
1777 * HOMEDRIVE or HOMEPATH isn't set?
1779 homedrive = g_getenv("HOMEDRIVE");
1780 if (homedrive != NULL) {
1781 homepath = g_getenv("HOMEPATH");
1782 if (homepath != NULL) {
1784 * This is cached, so we don't need to worry about
1785 * allocating multiple ones of them.
1787 homestring = g_strdup_printf("%s%s", homedrive, homepath);
1790 * Trim off any trailing slash or backslash.
1792 lastsep = find_last_pathname_separator(homestring);
1793 if (lastsep != NULL && *(lastsep + 1) == '\0') {
1795 * Last separator is the last character
1796 * in the string. Nuke it.
1805 * Give up and use C:.
1815 * Construct the path name of a personal configuration file, given the
1818 * On Win32, if "for_writing" is FALSE, we check whether the file exists
1819 * and, if not, construct a path name relative to the ".wireshark"
1820 * subdirectory of the user's home directory, and check whether that
1821 * exists; if it does, we return that, so that configuration files
1822 * from earlier versions can be read.
1824 * The returned file name was g_malloc()'d so it must be g_free()d when the
1825 * caller is done with it.
1828 get_persconffile_path(const char *filename, gboolean from_profile)
1830 char *path, *dir = NULL;
1832 if (do_store_persconffiles && from_profile && !g_hash_table_lookup (profile_files, filename)) {
1833 /* Store filenames so we know which filenames belongs to a configuration profile */
1834 g_hash_table_insert (profile_files, g_strdup(filename), g_strdup(filename));
1838 dir = get_persconffile_dir(persconfprofile);
1840 dir = get_persconffile_dir(NULL);
1842 path = g_build_filename(dir, filename, NULL);
1849 * Construct the path name of a global configuration file, given the
1852 * The returned file name was g_malloc()'d so it must be g_free()d when the
1853 * caller is done with it.
1856 get_datafile_path(const char *filename)
1858 if (running_in_build_directory_flag &&
1859 (!strcmp(filename, "AUTHORS-SHORT") ||
1860 !strcmp(filename, "hosts"))) {
1861 /* We're running in the build directory and the requested file is a
1862 * generated (or a test) file. Return the file name in the build
1863 * directory (not in the source/data directory).
1864 * (Oh the things we do to keep the source directory pristine...)
1866 return g_build_filename(get_progfile_dir(), filename, (char *)NULL);
1868 return g_build_filename(get_datafile_dir(), filename, (char *)NULL);
1873 * Return an error message for UNIX-style errno indications on open or
1874 * create operations.
1877 file_open_error_message(int err, gboolean for_writing)
1880 static char errmsg_errno[1024+1];
1886 errmsg = "The path to the file \"%s\" doesn't exist.";
1888 errmsg = "The file \"%s\" doesn't exist.";
1893 errmsg = "You don't have permission to create or write to the file \"%s\".";
1895 errmsg = "You don't have permission to read the file \"%s\".";
1899 errmsg = "\"%s\" is a directory (folder), not a file.";
1903 errmsg = "The file \"%s\" could not be created because there is no space left on the file system.";
1908 errmsg = "The file \"%s\" could not be created because you are too close to, or over, your disk quota.";
1913 errmsg = "The file \"%s\" could not be created because an invalid filename was specified.";
1918 /* XXX Make sure we truncate on a character boundary. */
1919 errmsg = "The file name \"%.80s" UTF8_HORIZONTAL_ELLIPSIS "\" is too long.";
1925 * The problem probably has nothing to do with how much RAM the
1926 * user has on their machine, so don't confuse them by saying
1927 * "memory". The problem is probably either virtual address
1928 * space or swap space.
1930 #if GLIB_SIZEOF_VOID_P == 4
1932 * ILP32; we probably ran out of virtual address space.
1934 #define ENOMEM_REASON "it can't be handled by a 32-bit application"
1937 * LP64 or LLP64; we probably ran out of swap space.
1941 * You need to make the pagefile bigger.
1943 #define ENOMEM_REASON "the pagefile is too small"
1944 #elif defined(__APPLE__)
1946 * dynamic_pager couldn't, or wouldn't, create more swap files.
1948 #define ENOMEM_REASON "your system ran out of swap file space"
1951 * Either you have a fixed swap partition or a fixed swap file,
1952 * and it needs to be made bigger.
1954 * This is UN*X, but it's not macOS, so we assume the user is
1957 #define ENOMEM_REASON "your system is out of swap space"
1959 #endif /* GLIB_SIZEOF_VOID_P == 4 */
1961 errmsg = "The file \"%s\" could not be created because " ENOMEM_REASON ".";
1963 errmsg = "The file \"%s\" could not be opened because " ENOMEM_REASON ".";
1967 g_snprintf(errmsg_errno, sizeof(errmsg_errno),
1968 "The file \"%%s\" could not be %s: %s.",
1969 for_writing ? "created" : "opened",
1971 errmsg = errmsg_errno;
1978 * Return an error message for UNIX-style errno indications on write
1982 file_write_error_message(int err)
1985 static char errmsg_errno[1024+1];
1990 errmsg = "The file \"%s\" could not be saved because there is no space left on the file system.";
1995 errmsg = "The file \"%s\" could not be saved because you are too close to, or over, your disk quota.";
2000 g_snprintf(errmsg_errno, sizeof(errmsg_errno),
2001 "An error occurred while writing to the file \"%%s\": %s.",
2003 errmsg = errmsg_errno;
2011 file_exists(const char *fname)
2013 ws_statb64 file_stat;
2019 if (ws_stat64(fname, &file_stat) != 0 && errno == ENOENT) {
2026 gboolean config_file_exists_with_entries(const char *fname, char comment_char)
2028 gboolean start_of_line = TRUE;
2029 gboolean has_entries = FALSE;
2037 if ((file = ws_fopen(fname, "r")) == NULL) {
2042 c = ws_getc_unlocked(file);
2043 if (start_of_line && c != comment_char && !g_ascii_isspace(c) && g_ascii_isprint(c)) {
2047 if (c == '\n' || !g_ascii_isspace(c)) {
2048 start_of_line = (c == '\n');
2057 * Check that the from file is not the same as to file
2058 * We do it here so we catch all cases ...
2059 * Unfortunately, the file requester gives us an absolute file
2060 * name and the read file name may be relative (if supplied on
2061 * the command line), so we can't just compare paths. From Joerg Mayer.
2064 files_identical(const char *fname1, const char *fname2)
2066 /* Two different implementations, because:
2068 * - _fullpath is not available on UN*X, so we can't get full
2069 * paths and compare them (which wouldn't work with hard links
2072 * - st_ino isn't filled in with a meaningful value on Windows.
2075 char full1[MAX_PATH], full2[MAX_PATH];
2078 * Get the absolute full paths of the file and compare them.
2079 * That won't work if you have hard links, but those aren't
2080 * much used on Windows, even though NTFS supports them.
2082 * XXX - will _fullpath work with UNC?
2084 if( _fullpath( full1, fname1, MAX_PATH ) == NULL ) {
2088 if( _fullpath( full2, fname2, MAX_PATH ) == NULL ) {
2092 if(strcmp(full1, full2) == 0) {
2098 ws_statb64 filestat1, filestat2;
2101 * Compare st_dev and st_ino.
2103 if (ws_stat64(fname1, &filestat1) == -1)
2104 return FALSE; /* can't get info about the first file */
2105 if (ws_stat64(fname2, &filestat2) == -1)
2106 return FALSE; /* can't get info about the second file */
2107 return (filestat1.st_dev == filestat2.st_dev &&
2108 filestat1.st_ino == filestat2.st_ino);
2113 * Copy a file in binary mode, for those operating systems that care about
2114 * such things. This should be OK for all files, even text files, as
2115 * we'll copy the raw bytes, and we don't look at the bytes as we copy
2118 * Returns TRUE on success, FALSE on failure. If a failure, it also
2119 * displays a simple dialog window with the error message.
2122 copy_file_binary_mode(const char *from_filename, const char *to_filename)
2124 int from_fd, to_fd, err;
2125 ssize_t nread, nwritten;
2128 /* Copy the raw bytes of the file. */
2129 from_fd = ws_open(from_filename, O_RDONLY | O_BINARY, 0000 /* no creation so don't matter */);
2131 report_open_failure(from_filename, errno, FALSE);
2135 /* Use open() instead of creat() so that we can pass the O_BINARY
2136 flag, which is relevant on Win32; it appears that "creat()"
2137 may open the file in text mode, not binary mode, but we want
2138 to copy the raw bytes of the file, so we need the output file
2139 to be open in binary mode. */
2140 to_fd = ws_open(to_filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644);
2142 report_open_failure(to_filename, errno, TRUE);
2147 #define FS_READ_SIZE 65536
2148 pd = (guint8 *)g_malloc(FS_READ_SIZE);
2149 while ((nread = ws_read(from_fd, pd, FS_READ_SIZE)) > 0) {
2150 nwritten = ws_write(to_fd, pd, nread);
2151 if (nwritten < nread) {
2155 err = WTAP_ERR_SHORT_WRITE;
2156 report_write_failure(to_filename, err);
2164 report_read_failure(from_filename, err);
2170 if (ws_close(to_fd) < 0) {
2171 report_write_failure(to_filename, errno);
2185 data_file_url(const gchar *filename)
2190 /* Absolute path? */
2191 if(g_path_is_absolute(filename)) {
2192 file_path = g_strdup(filename);
2193 } else if(running_in_build_directory()) {
2194 file_path = g_strdup_printf("%s/doc/%s", get_datafile_dir(), filename);
2196 file_path = g_strdup_printf("%s/%s", get_datafile_dir(), filename);
2199 /* XXX - check, if the file is really existing, otherwise display a simple_dialog about the problem */
2201 /* convert filename to uri */
2202 uri = g_filename_to_uri(file_path, NULL, NULL);
2210 g_free(persconffile_dir);
2211 persconffile_dir = NULL;
2212 g_free(datafile_dir);
2213 datafile_dir = NULL;
2214 g_free(persdatafile_dir);
2215 persdatafile_dir = NULL;
2216 g_free(persconfprofile);
2217 persconfprofile = NULL;
2218 g_free(progfile_dir);
2219 progfile_dir = NULL;
2220 #if defined(HAVE_PLUGINS) || defined(HAVE_LUA)
2223 g_free(plugin_dir_with_version);
2224 plugin_dir_with_version = NULL;
2225 g_free(plugin_pers_dir);
2226 plugin_pers_dir = NULL;
2227 g_free(plugin_pers_dir_with_version);
2228 plugin_pers_dir_with_version = NULL;
2240 * indent-tabs-mode: nil
2243 * ex: set shiftwidth=4 tabstop=8 expandtab:
2244 * :indentSize=4:tabSize=8:noTabs=true: