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 *persdatafile_dir = NULL;
58 char *persconfprofile = NULL;
60 static gboolean do_store_persconffiles = FALSE;
61 static GHashTable *profile_files = NULL;
64 * Given a pathname, return a pointer to the last pathname separator
65 * character in the pathname, or NULL if the pathname contains no
69 find_last_pathname_separator(const char *path)
77 * We have to scan for '\' or '/'.
78 * Get to the end of the string.
80 separator = strchr(path, '\0'); /* points to ending '\0' */
81 while (separator > path) {
83 if (c == '\\' || c == '/')
84 return separator; /* found it */
88 * OK, we didn't find any, so no directories - but there might
89 * be a drive letter....
91 return strchr(path, ':');
93 separator = strrchr(path, '/');
99 * Given a pathname, return the last component.
102 get_basename(const char *path)
104 const char *filename;
106 g_assert(path != NULL);
107 filename = find_last_pathname_separator(path);
108 if (filename == NULL) {
110 * There're no directories, drive letters, etc. in the
111 * name; the pathname *is* the file name.
116 * Skip past the pathname or drive letter separator.
124 * Given a pathname, return a string containing everything but the
125 * last component. NOTE: this overwrites the pathname handed into
129 get_dirname(char *path)
133 g_assert(path != NULL);
134 separator = find_last_pathname_separator(path);
135 if (separator == NULL) {
137 * There're no directories, drive letters, etc. in the
138 * name; there is no directory path to return.
144 * Get rid of the last pathname separator and the final file
150 * "path" now contains the pathname of the directory containing
151 * the file/directory to which it referred.
157 * Given a pathname, return:
159 * the errno, if an attempt to "stat()" the file fails;
161 * EISDIR, if the attempt succeeded and the file turned out
164 * 0, if the attempt succeeded and the file turned out not
169 test_for_directory(const char *path)
173 if (ws_stat64(path, &statb) < 0)
176 if (S_ISDIR(statb.st_mode))
183 test_for_fifo(const char *path)
187 if (ws_stat64(path, &statb) < 0)
190 if (S_ISFIFO(statb.st_mode))
197 * Directory from which the executable came.
199 static char *progfile_dir;
203 * Directory of the application bundle in which we're contained,
204 * if we're contained in an application bundle. Otherwise, NULL.
206 * Note: Table 2-5 "Subdirectories of the Contents directory" of
208 * https://developer.apple.com/library/mac/documentation/CoreFoundation/Conceptual/CFBundles/BundleTypes/BundleTypes.html#//apple_ref/doc/uid/10000123i-CH101-SW1
210 * says that the "Frameworks" directory
212 * Contains any private shared libraries and frameworks used by the
213 * executable. The frameworks in this directory are revision-locked
214 * to the application and cannot be superseded by any other, even
215 * newer, versions that may be available to the operating system. In
216 * other words, the frameworks included in this directory take precedence
217 * over any other similarly named frameworks found in other parts of
218 * the operating system. For information on how to add private
219 * frameworks to your application bundle, see Framework Programming Guide.
221 * so if we were to ship with any frameworks (e.g. Qt) we should
222 * perhaps put them in a Frameworks directory rather than under
225 * It also says that the "PlugIns" directory
227 * Contains loadable bundles that extend the basic features of your
228 * application. You use this directory to include code modules that
229 * must be loaded into your applicationbs process space in order to
230 * be used. You would not use this directory to store standalone
233 * Our plugins are just raw .so/.dylib files; I don't know whether by
234 * "bundles" they mean application bundles (i.e., directory hierarchies)
235 * or just "bundles" in the Mach-O sense (which are an image type that
236 * can be loaded with dlopen() but not linked as libraries; our plugins
237 * are, I think, built as dylibs and can be loaded either way).
239 * And it says that the "SharedSupport" directory
241 * Contains additional non-critical resources that do not impact the
242 * ability of the application to run. You might use this directory to
243 * include things like document templates, clip art, and tutorials
244 * that your application expects to be present but that do not affect
245 * the ability of your application to run.
247 * I don't think I'd put the files that currently go under Resources/share
248 * into that category; they're not, for example, sample Lua scripts that
249 * don't actually get run by Wireshark, they're configuration/data files
250 * for Wireshark whose absence might not prevent Wireshark from running
251 * but that would affect how it behaves when run.
253 static char *appbundle_dir;
257 * TRUE if we're running from the build directory and we aren't running
258 * with special privileges.
260 static gboolean running_in_build_directory_flag = FALSE;
264 * Get the pathname of the executable using various platform-
265 * dependent mechanisms for various UN*Xes.
267 * These calls all should return something independent of the argv[0]
268 * passed to the program, so it shouldn't be fooled by an argv[0]
269 * that doesn't match the executable path.
271 * We don't use dladdr() because:
273 * not all UN*Xes necessarily have dladdr();
275 * those that do have it don't necessarily have dladdr(main)
276 * return information about the executable image;
278 * those that do have a dladdr() where dladdr(main) returns
279 * information about the executable image don't necessarily
280 * have a mechanism by which the executable image can get
281 * its own path from the kernel (either by a call or by it
282 * being handed to it along with argv[] and the environment),
283 * so they just fall back on getting it from argv[0], which we
284 * already have code to do;
286 * those that do have such a mechanism don't necessarily use
287 * it in dladdr(), and, instead, just fall back on getting it
290 * so the only places where it's worth bothering to use dladdr()
291 * are platforms where dladdr(main) return information about the
292 * executable image by getting it from the kernel rather than
293 * by looking at argv[0], and where we can't get at that information
294 * ourselves, and we haven't seen any indication that there are any
297 * In particular, some dynamic linkers supply a dladdr() such that
298 * dladdr(main) just returns something derived from argv[0], so
299 * just using dladdr(main) is the wrong thing to do if there's
300 * another mechanism that can get you a more reliable version of
301 * the executable path.
303 * So, on platforms where we know of a mechanism to get that path
304 * (where getting that path doesn't involve argv[0], which is not
305 * guaranteed to reflect the path to the binary), this routine
306 * attempsts to use that platform's mechanism. On other platforms,
307 * it just returns NULL.
309 * This is not guaranteed to return an absolute path; if it doesn't,
310 * our caller must prepend the current directory if it's a path.
312 * This is not guaranteed to return the "real path"; it might return
313 * something with symbolic links in the path. Our caller must
314 * use realpath() if they want the real thing, but that's also true of
315 * something obtained by looking at argv[0].
318 get_executable_path(void)
320 #if defined(__APPLE__)
321 char *executable_path;
322 uint32_t path_buf_size;
324 path_buf_size = PATH_MAX;
325 executable_path = (char *)g_malloc(path_buf_size);
326 if (_NSGetExecutablePath(executable_path, &path_buf_size) == -1) {
327 executable_path = (char *)g_realloc(executable_path, path_buf_size);
328 if (_NSGetExecutablePath(executable_path, &path_buf_size) == -1)
331 return executable_path;
332 #elif defined(__linux__)
334 * In older versions of GNU libc's dynamic linker, as used on Linux,
335 * dladdr(main) supplies a path based on argv[0], so we use
336 * /proc/self/exe instead; there are Linux distributions with
337 * kernels that support /proc/self/exe and those older versions
338 * of the dynamic linker, and this will get a better answer on
341 * It only works on Linux 2.2 or later, so we just give up on
344 * XXX - are there OS versions that support "exe" but not "self"?
347 static char executable_path[PATH_MAX + 1];
350 if (uname(&name) == -1)
352 if (strncmp(name.release, "1.", 2) == 0)
353 return NULL; /* Linux 1.x */
354 if (strcmp(name.release, "2.0") == 0 ||
355 strncmp(name.release, "2.0.", 4) == 0 ||
356 strcmp(name.release, "2.1") == 0 ||
357 strncmp(name.release, "2.1.", 4) == 0)
358 return NULL; /* Linux 2.0.x or 2.1.x */
359 if ((r = readlink("/proc/self/exe", executable_path, PATH_MAX)) == -1)
361 executable_path[r] = '\0';
362 return executable_path;
363 #elif defined(__FreeBSD__) && defined(KERN_PROC_PATHNAME)
365 * In older versions of FreeBSD's dynamic linker, dladdr(main)
366 * supplies a path based on argv[0], so we use the KERN_PROC_PATHNAME
367 * sysctl instead; there are, I think, versions of FreeBSD
368 * that support the sysctl that have and those older versions
369 * of the dynamic linker, and this will get a better answer on
373 char *executable_path;
374 size_t path_buf_size;
378 mib[2] = KERN_PROC_PATHNAME;
380 path_buf_size = PATH_MAX;
381 executable_path = (char *)g_malloc(path_buf_size);
382 if (sysctl(mib, 4, executable_path, &path_buf_size, NULL, 0) == -1) {
385 executable_path = (char *)g_realloc(executable_path, path_buf_size);
386 if (sysctl(mib, 4, executable_path, &path_buf_size, NULL, 0) == -1)
389 return executable_path;
390 #elif defined(__NetBSD__)
392 * In all versions of NetBSD's dynamic linker as of 2013-08-12,
393 * dladdr(main) supplies a path based on argv[0], so we use
394 * /proc/curproc/exe instead.
396 * XXX - are there OS versions that support "exe" but not "curproc"
397 * or "self"? Are there any that support "self" but not "curproc"?
399 static char executable_path[PATH_MAX + 1];
402 if ((r = readlink("/proc/curproc/exe", executable_path, PATH_MAX)) == -1)
404 executable_path[r] = '\0';
405 return executable_path;
406 #elif defined(__DragonFly__)
408 * In older versions of DragonFly BSD's dynamic linker, dladdr(main)
409 * supplies a path based on argv[0], so we use /proc/curproc/file
410 * instead; it appears to be supported by all versions of DragonFly
413 static char executable_path[PATH_MAX + 1];
416 if ((r = readlink("/proc/curproc/file", executable_path, PATH_MAX)) == -1)
418 executable_path[r] = '\0';
419 return executable_path;
420 #elif defined(HAVE_GETEXECNAME)
422 * Solaris, with getexecname().
423 * It appears that getexecname() dates back to at least Solaris 8,
424 * but /proc/{pid}/path is first documented in the Solaris 10 documentation,
425 * so we use getexecname() if available, rather than /proc/self/path/a.out
426 * (which isn't documented, but appears to be a symlink to the
427 * executable image file).
429 return getexecname();
430 #elif defined(HAVE_DLGET)
432 * HP-UX 11, with dlget(); use dlget() and dlgetname().
435 * https://web.archive.org/web/20081025174755/http://h21007.www2.hp.com/portal/site/dspp/menuitem.863c3e4cbcdc3f3515b49c108973a801?ciid=88086d6e1de021106d6e1de02110275d6e10RCRD#two
437 struct load_module_desc desc;
439 if (dlget(-2, &desc, sizeof(desc)) != NULL)
440 return dlgetname(&desc, sizeof(desc), NULL, NULL, NULL);
444 /* Fill in your favorite UN*X's code here, if there is something */
451 * Get the pathname of the directory from which the executable came,
452 * and save it for future use. Returns NULL on success, and a
453 * g_mallocated string containing an error on failure.
456 init_progfile_dir(const char *arg0
463 TCHAR prog_pathname_w[_MAX_PATH+2];
471 * Attempt to get the full pathname of the currently running
474 if (GetModuleFileName(NULL, prog_pathname_w, G_N_ELEMENTS(prog_pathname_w)) != 0 && GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
476 * XXX - Should we use g_utf16_to_utf8()?
478 prog_pathname = utf_16to8(prog_pathname_w);
480 * We got it; strip off the last component, which would be
481 * the file name of the executable, giving us the pathname
482 * of the directory where the executable resides.
484 progfile_dir = g_path_get_dirname(prog_pathname);
485 if (progfile_dir != NULL) {
486 return NULL; /* we succeeded */
489 * OK, no. What do we do now?
491 return g_strdup_printf("No \\ in executable pathname \"%s\"",
496 * Oh, well. Return an indication of the error.
498 error = GetLastError();
499 if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,
500 NULL, error, 0, (LPTSTR) &msg_w, 0, NULL) == 0) {
502 * Gak. We can't format the message.
504 return g_strdup_printf("GetModuleFileName failed: %u (FormatMessage failed: %u)",
505 error, GetLastError());
507 msg = utf_16to8(msg_w);
510 * "FormatMessage()" "helpfully" sticks CR/LF at the
511 * end of the message. Get rid of it.
513 msglen = strlen(msg);
515 msg[msglen - 1] = '\0';
516 msg[msglen - 2] = '\0';
518 return g_strdup_printf("GetModuleFileName failed: %s (%u)",
522 const char *execname;
527 const char *path_start, *path_end;
528 size_t path_component_len, path_len;
534 * Check whether WIRESHARK_RUN_FROM_BUILD_DIRECTORY is set in the
535 * environment; if so, set running_in_build_directory_flag if we
536 * weren't started with special privileges. (If we were started
537 * with special privileges, it's not safe to allow the user to point
538 * us to some other directory; running_in_build_directory_flag, when
539 * set, causes us to look for plugins and the like in the build
542 if (g_getenv("WIRESHARK_RUN_FROM_BUILD_DIRECTORY") != NULL
543 && !started_with_special_privs())
544 running_in_build_directory_flag = TRUE;
546 execname = get_executable_path();
547 if (execname == NULL) {
549 * OK, guess based on argv[0].
555 * Try to figure out the directory in which the currently running
556 * program resides, given something purporting to be the executable
557 * name (from an OS mechanism or from the argv[0] it was started with).
558 * That might be the absolute path of the program, or a path relative
559 * to the current directory of the process that started it, or
560 * just a name for the program if it was started from the command
561 * line and was searched for in $PATH. It's not guaranteed to be
562 * any of those, however, so there are no guarantees....
564 if (execname[0] == '/') {
566 * It's an absolute path.
568 prog_pathname = g_strdup(execname);
569 } else if (strchr(execname, '/') != NULL) {
571 * It's a relative path, with a directory in it.
572 * Get the current directory, and combine it
573 * with that directory.
575 path_max = pathconf(".", _PC_PATH_MAX);
576 if (path_max == -1) {
578 * We have no idea how big a buffer to
579 * allocate for the current directory.
581 return g_strdup_printf("pathconf failed: %s\n",
584 curdir = (char *)g_malloc(path_max);
585 if (getcwd(curdir, path_max) == NULL) {
587 * It failed - give up, and just stick
591 return g_strdup_printf("getcwd failed: %s\n",
594 path = g_strdup_printf("%s/%s", curdir, execname);
596 prog_pathname = path;
599 * It's just a file name.
600 * Search the path for a file with that name
603 prog_pathname = NULL; /* haven't found it yet */
604 pathstr = g_getenv("PATH");
605 path_start = pathstr;
606 if (path_start != NULL) {
607 while (*path_start != '\0') {
608 path_end = strchr(path_start, ':');
609 if (path_end == NULL)
610 path_end = path_start + strlen(path_start);
611 path_component_len = path_end - path_start;
612 path_len = path_component_len + 1
613 + strlen(execname) + 1;
614 path = (char *)g_malloc(path_len);
615 memcpy(path, path_start, path_component_len);
616 path[path_component_len] = '\0';
617 g_strlcat(path, "/", path_len);
618 g_strlcat(path, execname, path_len);
619 if (access(path, X_OK) == 0) {
623 prog_pathname = path;
628 * That's not it. If there are more
629 * path components to test, try them.
631 if (*path_end == ':')
633 path_start = path_end;
636 if (prog_pathname == NULL) {
638 * Program not found in path.
640 return g_strdup_printf("\"%s\" not found in \"%s\"",
646 * XXX - should we pick a default?
648 return g_strdup("PATH isn't set");
653 * OK, we have what we think is the pathname
656 * First, find the last "/" in the directory,
657 * as that marks the end of the directory pathname.
659 dir_end = strrchr(prog_pathname, '/');
660 if (dir_end != NULL) {
662 * Found it. Strip off the last component,
663 * as that's the path of the program.
668 * Is there a "/run" at the end?
670 dir_end = strrchr(prog_pathname, '/');
671 if (dir_end != NULL) {
672 if (!started_with_special_privs()) {
674 * Check for the CMake output directory. As people may name
675 * their directories "run" (really?), also check for the
676 * CMakeCache.txt file before assuming a CMake output dir.
678 if (strcmp(dir_end, "/run") == 0) {
680 cmake_file = g_strdup_printf("%.*s/CMakeCache.txt",
681 (int)(dir_end - prog_pathname),
683 if (file_exists(cmake_file))
684 running_in_build_directory_flag = TRUE;
690 * Scan up the path looking for a component
691 * named "Contents". If we find it, we assume
692 * we're in a bundle, and that the top-level
693 * directory of the bundle is the one containing
696 * Not all executables are in the Contents/MacOS
697 * directory, so we can't just check for those
698 * in the path and strip them off.
700 * XXX - should we assume that it's either
701 * Contents/MacOS or Resources/bin?
703 char *component_end, *p;
705 component_end = strchr(prog_pathname, '\0');
708 while (p >= prog_pathname && *p != '/')
710 if (p == prog_pathname) {
712 * We're looking at the first component of
713 * the pathname now, so we're definitely
714 * not in a bundle, even if we're in
719 if (strncmp(p, "/Contents", component_end - p) == 0) {
721 appbundle_dir = (char *)g_malloc(p - prog_pathname + 1);
722 memcpy(appbundle_dir, prog_pathname, p - prog_pathname);
723 appbundle_dir[p - prog_pathname] = '\0';
735 * OK, we have the path we want.
737 progfile_dir = prog_pathname;
741 * This "shouldn't happen"; we apparently
742 * have no "/" in the pathname.
743 * Just free up prog_pathname.
745 retstr = g_strdup_printf("No / found in \"%s\"", prog_pathname);
746 g_free(prog_pathname);
753 * Get the directory in which the program resides.
756 get_progfile_dir(void)
762 * Get the directory in which the global configuration and data files are
765 * On Windows, we use the directory in which the executable for this
768 * On macOS (when executed from an app bundle), use a directory within
771 * Otherwise, if the program was executed from the build directory, use the
772 * directory in which the executable for this process resides. In all other
773 * cases, use the DATAFILE_DIR value that was set at compile time.
775 * XXX - if we ever make libwireshark a real library, used by multiple
776 * applications (more than just TShark and versions of Wireshark with
777 * various UIs), should the configuration files belong to the library
778 * (and be shared by all those applications) or to the applications?
780 * If they belong to the library, that could be done on UNIX by the
781 * configure script, but it's trickier on Windows, as you can't just
782 * use the pathname of the executable.
784 * If they belong to the application, that could be done on Windows
785 * by using the pathname of the executable, but we'd have to have it
786 * passed in as an argument, in some call, on UNIX.
788 * Note that some of those configuration files might be used by code in
789 * libwireshark, some of them might be used by dissectors (would they
790 * belong to libwireshark, the application, or a separate library?),
791 * and some of them might be used by other code (the Wireshark preferences
792 * file includes resolver preferences that control the behavior of code
793 * in libwireshark, dissector preferences, and UI preferences, for
797 get_datafile_dir(void)
799 static const char *datafile_dir = NULL;
801 if (datafile_dir != NULL)
806 * Do we have the pathname of the program? If so, assume we're
807 * running an installed version of the program. If we fail,
808 * we don't change "datafile_dir", and thus end up using the
811 * XXX - does NSIS put the installation directory into
812 * "\HKEY_LOCAL_MACHINE\SOFTWARE\Wireshark\InstallDir"?
813 * If so, perhaps we should read that from the registry,
816 if (progfile_dir != NULL) {
818 * Yes, we do; use that.
820 datafile_dir = progfile_dir;
824 * Fall back on the default installation directory.
826 datafile_dir = "C:\\Program Files\\Wireshark\\";
830 if (g_getenv("WIRESHARK_DATA_DIR") && !started_with_special_privs()) {
832 * The user specified a different directory for data files
833 * and we aren't running with special privileges.
834 * XXX - We might be able to dispense with the priv check
836 datafile_dir = g_strdup(g_getenv("WIRESHARK_DATA_DIR"));
840 * If we're running from an app bundle and weren't started
841 * with special privileges, use the Contents/Resources/share/wireshark
842 * subdirectory of the app bundle.
844 * (appbundle_dir is not set to a non-null value if we're
845 * started with special privileges, so we need only check
846 * it; we don't need to call started_with_special_privs().)
848 else if (appbundle_dir != NULL) {
849 datafile_dir = g_strdup_printf("%s/Contents/Resources/share/wireshark",
853 else if (running_in_build_directory_flag && progfile_dir != NULL) {
855 * We're (probably) being run from the build directory and
856 * weren't started with special privileges.
858 * (running_in_build_directory_flag is never set to TRUE
859 * if we're started with special privileges, so we need
860 * only check it; we don't need to call started_with_special_privs().)
862 * Data files (console.lua, radius/, etc.) are copied to the build
863 * directory during the build which also contains executables. A special
864 * exception is macOS (when built with an app bundle).
866 datafile_dir = progfile_dir;
868 datafile_dir = DATAFILE_DIR;
876 * Find the directory where the plugins are stored.
878 * On Windows, we use the plugin\{VERSION} subdirectory of the datafile
879 * directory, where {VERSION} is the version number of this version of
884 * if we appear to be run from the build directory, we use the
885 * "plugin" subdirectory of the datafile directory;
887 * otherwise, if the WIRESHARK_PLUGIN_DIR environment variable is
888 * set and we aren't running with special privileges, we use the
889 * value of that environment variable;
891 * otherwise, if we're running from an app bundle in macOS, we
892 * use the Contents/PlugIns/wireshark subdirectory of the app bundle;
894 * otherwise, we use the PLUGIN_DIR value supplied by the
897 static char *plugin_dir = NULL;
898 static char *plugin_dir_with_version = NULL;
899 static char *plugin_pers_dir = NULL;
900 static char *plugin_pers_dir_with_version = NULL;
903 init_plugin_dir(void)
905 #if defined(HAVE_PLUGINS) || defined(HAVE_LUA)
908 * On Windows, the data file directory is the installation
909 * directory; the plugins are stored under it.
911 * Assume we're running the installed version of Wireshark;
912 * on Windows, the data file directory is the directory
913 * in which the Wireshark binary resides.
915 plugin_dir = g_build_filename(get_datafile_dir(), "plugins", (gchar *)NULL);
918 * Make sure that pathname refers to a directory.
920 if (test_for_directory(plugin_dir) != EISDIR) {
922 * Either it doesn't refer to a directory or it
923 * refers to something that doesn't exist.
925 * Assume that means we're running a version of
926 * Wireshark we've built in a build directory,
927 * in which case {datafile dir}\plugins is the
928 * top-level plugins source directory, and use
929 * that directory and set the "we're running in
930 * a build directory" flag, so the plugin
931 * scanner will check all subdirectories of that
932 * directory for plugins.
935 plugin_dir = g_build_filename(get_datafile_dir(), "plugins", (gchar *)NULL);
936 running_in_build_directory_flag = TRUE;
939 if (running_in_build_directory_flag) {
941 * We're (probably) being run from the build directory and
942 * weren't started with special privileges, so we'll use
943 * the "plugins" subdirectory of the directory where the program
944 * we're running is (that's the build directory).
946 plugin_dir = g_build_filename(get_progfile_dir(), "plugins", (gchar *)NULL);
948 if (g_getenv("WIRESHARK_PLUGIN_DIR") && !started_with_special_privs()) {
950 * The user specified a different directory for plugins
951 * and we aren't running with special privileges.
953 plugin_dir = g_strdup(g_getenv("WIRESHARK_PLUGIN_DIR"));
957 * If we're running from an app bundle and weren't started
958 * with special privileges, use the Contents/PlugIns/wireshark
959 * subdirectory of the app bundle.
961 * (appbundle_dir is not set to a non-null value if we're
962 * started with special privileges, so we need only check
963 * it; we don't need to call started_with_special_privs().)
965 else if (appbundle_dir != NULL) {
966 plugin_dir = g_build_filename(appbundle_dir, "Contents/PlugIns/wireshark", (gchar *)NULL);
970 plugin_dir = g_strdup(PLUGIN_DIR);
974 #endif /* defined(HAVE_PLUGINS) || defined(HAVE_LUA) */
978 init_plugin_pers_dir(void)
980 #if defined(HAVE_PLUGINS) || defined(HAVE_LUA)
982 plugin_pers_dir = get_persconffile_path(PLUGINS_DIR_NAME, FALSE);
984 plugin_pers_dir = g_build_filename(g_get_home_dir(), ".local/lib/wireshark/" PLUGINS_DIR_NAME, (gchar *)NULL);
986 #endif /* defined(HAVE_PLUGINS) || defined(HAVE_LUA) */
990 * Get the directory in which the plugins are stored.
993 get_plugins_dir(void)
1001 get_plugins_dir_with_version(void)
1005 if (plugin_dir && !plugin_dir_with_version)
1006 plugin_dir_with_version = g_build_filename(plugin_dir, VERSION_RELEASE, (gchar *)NULL);
1007 return plugin_dir_with_version;
1010 /* Get the personal plugin dir */
1012 get_plugins_pers_dir(void)
1014 if (!plugin_pers_dir)
1015 init_plugin_pers_dir();
1016 return plugin_pers_dir;
1020 get_plugins_pers_dir_with_version(void)
1022 if (!plugin_pers_dir)
1023 init_plugin_pers_dir();
1024 if (plugin_pers_dir && !plugin_pers_dir_with_version)
1025 plugin_pers_dir_with_version = g_build_filename(plugin_pers_dir, VERSION_RELEASE, (gchar *)NULL);
1026 return plugin_pers_dir_with_version;
1030 * Find the directory where the extcap hooks are stored.
1032 * On Windows, we use the "extcap" subdirectory of the datafile directory.
1034 * On UN*X, we use the EXTCAP_DIR value supplied by the configure
1035 * script, unless we think we're being run from the build directory,
1036 * in which case we use the "extcap" subdirectory of the datafile directory.
1038 * In both cases, we then use the subdirectory of that directory whose
1039 * name is the version number.
1041 * XXX - if we think we're being run from the build directory, perhaps we
1042 * should have the extcap code not look in the version subdirectory
1043 * of the extcap directory, but look in all of the subdirectories
1044 * of the extcap directory, so it can just fetch the extcap hooks built
1045 * as part of the build process.
1047 static char *extcap_dir = NULL;
1049 static void init_extcap_dir(void) {
1051 const char *alt_extcap_path;
1054 * On Windows, the data file directory is the installation
1055 * directory; the extcap hooks are stored under it.
1057 * Assume we're running the installed version of Wireshark;
1058 * on Windows, the data file directory is the directory
1059 * in which the Wireshark binary resides.
1061 alt_extcap_path = g_getenv("WIRESHARK_EXTCAP_DIR");
1062 if (alt_extcap_path) {
1064 * The user specified a different directory for extcap hooks.
1066 extcap_dir = g_strdup(alt_extcap_path);
1068 extcap_dir = g_build_filename(get_datafile_dir(), "extcap", (gchar *)NULL);
1071 if (running_in_build_directory_flag) {
1073 * We're (probably) being run from the build directory and
1074 * weren't started with special privileges, so we'll use
1075 * the "extcap hooks" subdirectory of the directory where the program
1076 * we're running is (that's the build directory).
1078 extcap_dir = g_build_filename(get_progfile_dir(), "extcap", (gchar *)NULL);
1080 if (g_getenv("WIRESHARK_EXTCAP_DIR") && !started_with_special_privs()) {
1082 * The user specified a different directory for extcap hooks
1083 * and we aren't running with special privileges.
1085 extcap_dir = g_strdup(g_getenv("WIRESHARK_EXTCAP_DIR"));
1089 * If we're running from an app bundle and weren't started
1090 * with special privileges, use the Contents/MacOS/extcap
1091 * subdirectory of the app bundle.
1093 * (appbundle_dir is not set to a non-null value if we're
1094 * started with special privileges, so we need only check
1095 * it; we don't need to call started_with_special_privs().)
1097 else if (appbundle_dir != NULL) {
1098 extcap_dir = g_build_filename(appbundle_dir, "Contents/MacOS/extcap", (gchar *)NULL);
1102 extcap_dir = g_strdup(EXTCAP_DIR);
1109 * Get the directory in which the extcap hooks are stored.
1113 get_extcap_dir(void)
1121 * Get the flag indicating whether we're running from a build
1125 running_in_build_directory(void)
1127 return running_in_build_directory_flag;
1131 * Get the directory in which files that, at least on UNIX, are
1132 * system files (such as "/etc/ethers") are stored; on Windows,
1133 * there's no "/etc" directory, so we get them from the global
1134 * configuration and data file directory.
1137 get_systemfile_dir(void)
1140 return get_datafile_dir();
1147 set_profile_name(const gchar *profilename)
1149 g_free (persconfprofile);
1151 if (profilename && strlen(profilename) > 0 &&
1152 strcmp(profilename, DEFAULT_PROFILE) != 0) {
1153 persconfprofile = g_strdup (profilename);
1155 /* Default Profile */
1156 persconfprofile = NULL;
1161 get_profile_name(void)
1163 if (persconfprofile) {
1164 return persconfprofile;
1166 return DEFAULT_PROFILE;
1171 is_default_profile(void)
1173 return (!persconfprofile || strcmp(persconfprofile, DEFAULT_PROFILE) == 0) ? TRUE : FALSE;
1177 has_global_profiles(void)
1181 gchar *global_dir = get_global_profiles_dir();
1183 gboolean has_global = FALSE;
1185 if ((test_for_directory(global_dir) == EISDIR) &&
1186 ((dir = ws_dir_open(global_dir, 0, NULL)) != NULL))
1188 while ((file = ws_dir_read_name(dir)) != NULL) {
1189 filename = g_strdup_printf ("%s%s%s", global_dir, G_DIR_SEPARATOR_S,
1190 ws_dir_get_name(file));
1191 if (test_for_directory(filename) == EISDIR) {
1205 profile_store_persconffiles(gboolean store)
1208 profile_files = g_hash_table_new (g_str_hash, g_str_equal);
1210 do_store_persconffiles = store;
1214 * Get the directory in which personal configuration files reside.
1216 * On Windows, it's "Wireshark", under %APPDATA% or, if %APPDATA% isn't set,
1217 * it's "%USERPROFILE%\Application Data" (which is what %APPDATA% normally
1218 * is on Windows 2000).
1220 * On UNIX-compatible systems, we first look in XDG_CONFIG_HOME/wireshark
1221 * and, if that doesn't exist, ~/.wireshark, for backwards compatibility.
1222 * If neither exists, we use XDG_CONFIG_HOME/wireshark, so that the directory
1223 * is initially created as XDG_CONFIG_HOME/wireshark. We use that regardless
1224 * of whether the user is running under an XDG desktop or not, so that
1225 * if the user's home directory is on a server and shared between
1226 * different desktop environments on different machines, they can all
1227 * share the same configuration file directory.
1229 * XXX - what about stuff that shouldn't be shared between machines,
1230 * such as plugins in the form of shared loadable images?
1233 get_persconffile_dir_no_profile(void)
1237 /* Return the cached value, if available */
1238 if (persconffile_dir != NULL)
1239 return persconffile_dir;
1242 * See if the user has selected an alternate environment.
1244 env = g_getenv(ENV_CONFIG_PATH_VAR);
1247 /* for backward compatibility */
1248 env = g_getenv("WIRESHARK_APPDATA");
1252 persconffile_dir = g_strdup(env);
1253 return persconffile_dir;
1258 * Use %APPDATA% or %USERPROFILE%, so that configuration
1259 * files are stored in the user profile, rather than in
1260 * the home directory. The Windows convention is to store
1261 * configuration information in the user profile, and doing
1262 * so means you can use Wireshark even if the home directory
1263 * is an inaccessible network drive.
1265 env = g_getenv("APPDATA");
1268 * Concatenate %APPDATA% with "\Wireshark".
1270 persconffile_dir = g_build_filename(env, "Wireshark", NULL);
1271 return persconffile_dir;
1275 * OK, %APPDATA% wasn't set, so use %USERPROFILE%\Application Data.
1277 env = g_getenv("USERPROFILE");
1279 persconffile_dir = g_build_filename(env, "Application Data", "Wireshark", NULL);
1280 return persconffile_dir;
1284 * Give up and use "C:".
1286 persconffile_dir = g_build_filename("C:", "Wireshark", NULL);
1287 return persconffile_dir;
1289 char *xdg_path, *path;
1291 const char *homedir;
1294 * Check if XDG_CONFIG_HOME/wireshark exists and is a directory.
1296 xdg_path = g_build_filename(g_get_user_config_dir(), "wireshark", NULL);
1297 if (g_file_test(xdg_path, G_FILE_TEST_IS_DIR)) {
1298 persconffile_dir = xdg_path;
1299 return persconffile_dir;
1303 * It doesn't exist, or it does but isn't a directory, so try
1306 * If $HOME is set, use that for ~.
1308 * (Note: before GLib 2.36, g_get_home_dir() didn't look at $HOME,
1309 * but we always want to do so, so we don't use g_get_home_dir().)
1311 homedir = g_getenv("HOME");
1312 if (homedir == NULL) {
1316 * Get their home directory from the password file.
1317 * If we can't even find a password file entry for them,
1320 pwd = getpwuid(getuid());
1322 homedir = pwd->pw_dir;
1327 path = g_build_filename(homedir, ".wireshark", NULL);
1328 if (g_file_test(path, G_FILE_TEST_IS_DIR)) {
1330 persconffile_dir = path;
1331 return persconffile_dir;
1335 * Neither are directories that exist; use the XDG path, so we'll
1336 * create that as necessary.
1339 persconffile_dir = xdg_path;
1340 return persconffile_dir;
1345 set_persconffile_dir(const char *p)
1347 g_free(persconffile_dir);
1348 persconffile_dir = g_strdup(p);
1352 get_profiles_dir(void)
1354 return g_strdup_printf ("%s%s%s", get_persconffile_dir_no_profile (),
1355 G_DIR_SEPARATOR_S, PROFILES_DIR);
1359 create_profiles_dir(char **pf_dir_path_return)
1365 * Create the "Default" personal configuration files directory, if necessary.
1367 if (create_persconffile_profile (NULL, pf_dir_path_return) == -1) {
1372 * Check if profiles directory exists.
1373 * If not then create it.
1375 pf_dir_path = get_profiles_dir ();
1376 if (ws_stat64(pf_dir_path, &s_buf) != 0) {
1377 if (errno != ENOENT) {
1378 /* Some other problem; give up now. */
1379 *pf_dir_path_return = pf_dir_path;
1384 * It doesn't exist; try to create it.
1386 int ret = ws_mkdir(pf_dir_path, 0755);
1388 *pf_dir_path_return = pf_dir_path;
1392 g_free(pf_dir_path);
1398 get_global_profiles_dir(void)
1400 return g_strdup_printf ("%s%s%s", get_datafile_dir(),
1401 G_DIR_SEPARATOR_S, PROFILES_DIR);
1405 get_persconffile_dir(const gchar *profilename)
1407 char *persconffile_profile_dir = NULL, *profile_dir;
1409 if (profilename && strlen(profilename) > 0 &&
1410 strcmp(profilename, DEFAULT_PROFILE) != 0) {
1411 profile_dir = get_profiles_dir();
1412 persconffile_profile_dir = g_strdup_printf ("%s%s%s", profile_dir,
1413 G_DIR_SEPARATOR_S, profilename);
1414 g_free(profile_dir);
1416 persconffile_profile_dir = g_strdup (get_persconffile_dir_no_profile ());
1419 return persconffile_profile_dir;
1423 get_profile_dir(const char *profilename, gboolean is_global)
1428 if (profilename && strlen(profilename) > 0 &&
1429 strcmp(profilename, DEFAULT_PROFILE) != 0)
1431 gchar *global_path = get_global_profiles_dir();
1432 profile_dir = g_build_filename(global_path, profilename, NULL);
1433 g_free(global_path);
1435 profile_dir = g_strdup(get_datafile_dir());
1439 * If we didn't supply a profile name, i.e. if profilename is
1440 * null, get_persconffile_dir() returns the default profile.
1442 profile_dir = get_persconffile_dir(profilename);
1449 profile_exists(const gchar *profilename, gboolean global)
1455 * If we're looking up a global profile, we must have a
1458 if (global && !profilename)
1461 path = get_profile_dir(profilename, global);
1462 exists = (test_for_directory(path) == EISDIR) ? TRUE : FALSE;
1469 delete_directory (const char *directory, char **pf_dir_path_return)
1476 if ((dir = ws_dir_open(directory, 0, NULL)) != NULL) {
1477 while ((file = ws_dir_read_name(dir)) != NULL) {
1478 filename = g_strdup_printf ("%s%s%s", directory, G_DIR_SEPARATOR_S,
1479 ws_dir_get_name(file));
1480 if (test_for_directory(filename) != EISDIR) {
1481 ret = ws_remove(filename);
1484 /* The user has manually created a directory in the profile directory */
1485 /* I do not want to delete the directory recursively yet */
1486 ret = delete_directory (filename, pf_dir_path_return);
1490 *pf_dir_path_return = filename;
1498 if (ret == 0 && (ret = ws_remove(directory)) != 0) {
1499 *pf_dir_path_return = g_strdup (directory);
1506 reset_default_profile(char **pf_dir_path_return)
1508 char *profile_dir = get_persconffile_dir(NULL);
1509 gchar *filename, *del_file;
1510 GList *files, *file;
1513 files = g_hash_table_get_keys(profile_files);
1514 file = g_list_first(files);
1516 filename = (gchar *)file->data;
1517 del_file = g_strdup_printf("%s%s%s", profile_dir, G_DIR_SEPARATOR_S, filename);
1519 if (file_exists(del_file)) {
1520 ret = ws_remove(del_file);
1522 *pf_dir_path_return = profile_dir;
1529 file = g_list_next(file);
1533 g_free(profile_dir);
1538 delete_persconffile_profile(const char *profilename, char **pf_dir_path_return)
1540 if (strcmp(profilename, DEFAULT_PROFILE) == 0) {
1541 return reset_default_profile(pf_dir_path_return);
1544 char *profile_dir = get_persconffile_dir(profilename);
1547 if (test_for_directory (profile_dir) == EISDIR) {
1548 ret = delete_directory (profile_dir, pf_dir_path_return);
1551 g_free(profile_dir);
1556 rename_persconffile_profile(const char *fromname, const char *toname,
1557 char **pf_from_dir_path_return, char **pf_to_dir_path_return)
1559 char *from_dir = get_persconffile_dir(fromname);
1560 char *to_dir = get_persconffile_dir(toname);
1563 ret = ws_rename (from_dir, to_dir);
1565 *pf_from_dir_path_return = from_dir;
1566 *pf_to_dir_path_return = to_dir;
1577 * Create the directory that holds personal configuration files, if
1578 * necessary. If we attempted to create it, and failed, return -1 and
1579 * set "*pf_dir_path_return" to the pathname of the directory we failed
1580 * to create (it's g_mallocated, so our caller should free it); otherwise,
1584 create_persconffile_profile(const char *profilename, char **pf_dir_path_return)
1588 char *pf_dir_path_copy, *pf_dir_parent_path;
1589 size_t pf_dir_parent_path_len;
1597 * Create the personal profiles directory, if necessary.
1599 if (create_profiles_dir(pf_dir_path_return) == -1) {
1604 pf_dir_path = get_persconffile_dir(profilename);
1605 if (ws_stat64(pf_dir_path, &s_buf) != 0) {
1606 if (errno != ENOENT) {
1607 /* Some other problem; give up now. */
1608 *pf_dir_path_return = pf_dir_path;
1613 * Does the parent directory of that directory
1614 * exist? %APPDATA% may not exist even though
1615 * %USERPROFILE% does.
1617 * We check for the existence of the directory
1618 * by first checking whether the parent directory
1619 * is just a drive letter and, if it's not, by
1620 * doing a "stat()" on it. If it's a drive letter,
1621 * or if the "stat()" succeeds, we assume it exists.
1623 pf_dir_path_copy = g_strdup(pf_dir_path);
1624 pf_dir_parent_path = get_dirname(pf_dir_path_copy);
1625 pf_dir_parent_path_len = strlen(pf_dir_parent_path);
1626 if (pf_dir_parent_path_len > 0
1627 && pf_dir_parent_path[pf_dir_parent_path_len - 1] != ':'
1628 && ws_stat64(pf_dir_parent_path, &s_buf) != 0) {
1630 * Not a drive letter and the stat() failed.
1632 if (errno != ENOENT) {
1633 /* Some other problem; give up now. */
1634 *pf_dir_path_return = pf_dir_path;
1636 g_free(pf_dir_path_copy);
1641 * No, it doesn't exist - make it first.
1643 ret = ws_mkdir(pf_dir_parent_path, 0755);
1645 *pf_dir_path_return = pf_dir_parent_path;
1647 g_free(pf_dir_path);
1652 g_free(pf_dir_path_copy);
1653 ret = ws_mkdir(pf_dir_path, 0755);
1655 ret = g_mkdir_with_parents(pf_dir_path, 0755);
1659 * Something with that pathname exists; if it's not
1660 * a directory, we'll get an error if we try to put
1661 * something in it, so we don't fail here, we wait
1662 * for that attempt fo fail.
1667 *pf_dir_path_return = pf_dir_path;
1669 g_free(pf_dir_path);
1675 create_persconffile_dir(char **pf_dir_path_return)
1677 return create_persconffile_profile(persconfprofile, pf_dir_path_return);
1681 copy_persconffile_profile(const char *toname, const char *fromname, gboolean from_global,
1682 char **pf_filename_return, char **pf_to_dir_path_return, char **pf_from_dir_path_return)
1685 gchar *to_dir = get_persconffile_dir(toname);
1686 gchar *filename, *from_file, *to_file;
1687 GList *files, *file;
1689 from_dir = get_profile_dir(fromname, from_global);
1691 files = g_hash_table_get_keys(profile_files);
1692 file = g_list_first(files);
1694 filename = (gchar *)file->data;
1695 from_file = g_strdup_printf ("%s%s%s", from_dir, G_DIR_SEPARATOR_S, filename);
1696 to_file = g_strdup_printf ("%s%s%s", to_dir, G_DIR_SEPARATOR_S, filename);
1698 if (file_exists(from_file) && !copy_file_binary_mode(from_file, to_file)) {
1699 *pf_filename_return = g_strdup(filename);
1700 *pf_to_dir_path_return = to_dir;
1701 *pf_from_dir_path_return = from_dir;
1710 file = g_list_next(file);
1713 g_list_free (files);
1721 * Get the (default) directory in which personal data is stored.
1723 * On Win32, this is the "My Documents" folder in the personal profile.
1724 * On UNIX this is simply the current directory.
1726 /* XXX - should this and the get_home_dir() be merged? */
1728 get_persdatafile_dir(void)
1731 TCHAR tszPath[MAX_PATH];
1733 /* Return the cached value, if available */
1734 if (persdatafile_dir != NULL)
1735 return persdatafile_dir;
1738 * Hint: SHGetFolderPath is not available on MSVC 6 - without
1741 if (SHGetSpecialFolderPath(NULL, tszPath, CSIDL_PERSONAL, FALSE)) {
1742 persdatafile_dir = g_utf16_to_utf8(tszPath, -1, NULL, NULL, NULL);
1743 return persdatafile_dir;
1753 set_persdatafile_dir(const char *p)
1755 g_free(persdatafile_dir);
1756 persdatafile_dir = g_strdup(p);
1761 * Returns the user's home directory on Win32.
1766 static const char *home = NULL;
1767 const char *homedrive, *homepath;
1771 /* Return the cached value, if available */
1776 * XXX - should we use USERPROFILE anywhere in this process?
1777 * Is there a chance that it might be set but one or more of
1778 * HOMEDRIVE or HOMEPATH isn't set?
1780 homedrive = g_getenv("HOMEDRIVE");
1781 if (homedrive != NULL) {
1782 homepath = g_getenv("HOMEPATH");
1783 if (homepath != NULL) {
1785 * This is cached, so we don't need to worry about
1786 * allocating multiple ones of them.
1788 homestring = g_strdup_printf("%s%s", homedrive, homepath);
1791 * Trim off any trailing slash or backslash.
1793 lastsep = find_last_pathname_separator(homestring);
1794 if (lastsep != NULL && *(lastsep + 1) == '\0') {
1796 * Last separator is the last character
1797 * in the string. Nuke it.
1806 * Give up and use C:.
1816 * Construct the path name of a personal configuration file, given the
1819 * On Win32, if "for_writing" is FALSE, we check whether the file exists
1820 * and, if not, construct a path name relative to the ".wireshark"
1821 * subdirectory of the user's home directory, and check whether that
1822 * exists; if it does, we return that, so that configuration files
1823 * from earlier versions can be read.
1825 * The returned file name was g_malloc()'d so it must be g_free()d when the
1826 * caller is done with it.
1829 get_persconffile_path(const char *filename, gboolean from_profile)
1831 char *path, *dir = NULL;
1833 if (do_store_persconffiles && from_profile && !g_hash_table_lookup (profile_files, filename)) {
1834 /* Store filenames so we know which filenames belongs to a configuration profile */
1835 g_hash_table_insert (profile_files, g_strdup(filename), g_strdup(filename));
1839 dir = get_persconffile_dir(persconfprofile);
1841 dir = get_persconffile_dir(NULL);
1843 path = g_build_filename(dir, filename, NULL);
1850 * Construct the path name of a global configuration file, given the
1853 * The returned file name was g_malloc()'d so it must be g_free()d when the
1854 * caller is done with it.
1857 get_datafile_path(const char *filename)
1859 if (running_in_build_directory_flag &&
1860 (!strcmp(filename, "AUTHORS-SHORT") ||
1861 !strcmp(filename, "hosts"))) {
1862 /* We're running in the build directory and the requested file is a
1863 * generated (or a test) file. Return the file name in the build
1864 * directory (not in the source/data directory).
1865 * (Oh the things we do to keep the source directory pristine...)
1867 return g_build_filename(get_progfile_dir(), filename, (char *)NULL);
1869 return g_build_filename(get_datafile_dir(), filename, (char *)NULL);
1874 * Return an error message for UNIX-style errno indications on open or
1875 * create operations.
1878 file_open_error_message(int err, gboolean for_writing)
1881 static char errmsg_errno[1024+1];
1887 errmsg = "The path to the file \"%s\" doesn't exist.";
1889 errmsg = "The file \"%s\" doesn't exist.";
1894 errmsg = "You don't have permission to create or write to the file \"%s\".";
1896 errmsg = "You don't have permission to read the file \"%s\".";
1900 errmsg = "\"%s\" is a directory (folder), not a file.";
1904 errmsg = "The file \"%s\" could not be created because there is no space left on the file system.";
1909 errmsg = "The file \"%s\" could not be created because you are too close to, or over, your disk quota.";
1914 errmsg = "The file \"%s\" could not be created because an invalid filename was specified.";
1919 /* XXX Make sure we truncate on a character boundary. */
1920 errmsg = "The file name \"%.80s" UTF8_HORIZONTAL_ELLIPSIS "\" is too long.";
1926 * The problem probably has nothing to do with how much RAM the
1927 * user has on their machine, so don't confuse them by saying
1928 * "memory". The problem is probably either virtual address
1929 * space or swap space.
1931 #if GLIB_SIZEOF_VOID_P == 4
1933 * ILP32; we probably ran out of virtual address space.
1935 #define ENOMEM_REASON "it can't be handled by a 32-bit application"
1938 * LP64 or LLP64; we probably ran out of swap space.
1942 * You need to make the pagefile bigger.
1944 #define ENOMEM_REASON "the pagefile is too small"
1945 #elif defined(__APPLE__)
1947 * dynamic_pager couldn't, or wouldn't, create more swap files.
1949 #define ENOMEM_REASON "your system ran out of swap file space"
1952 * Either you have a fixed swap partition or a fixed swap file,
1953 * and it needs to be made bigger.
1955 * This is UN*X, but it's not macOS, so we assume the user is
1958 #define ENOMEM_REASON "your system is out of swap space"
1960 #endif /* GLIB_SIZEOF_VOID_P == 4 */
1962 errmsg = "The file \"%s\" could not be created because " ENOMEM_REASON ".";
1964 errmsg = "The file \"%s\" could not be opened because " ENOMEM_REASON ".";
1968 g_snprintf(errmsg_errno, sizeof(errmsg_errno),
1969 "The file \"%%s\" could not be %s: %s.",
1970 for_writing ? "created" : "opened",
1972 errmsg = errmsg_errno;
1979 * Return an error message for UNIX-style errno indications on write
1983 file_write_error_message(int err)
1986 static char errmsg_errno[1024+1];
1991 errmsg = "The file \"%s\" could not be saved because there is no space left on the file system.";
1996 errmsg = "The file \"%s\" could not be saved because you are too close to, or over, your disk quota.";
2001 g_snprintf(errmsg_errno, sizeof(errmsg_errno),
2002 "An error occurred while writing to the file \"%%s\": %s.",
2004 errmsg = errmsg_errno;
2012 file_exists(const char *fname)
2014 ws_statb64 file_stat;
2020 if (ws_stat64(fname, &file_stat) != 0 && errno == ENOENT) {
2027 gboolean config_file_exists_with_entries(const char *fname, char comment_char)
2029 gboolean start_of_line = TRUE;
2030 gboolean has_entries = FALSE;
2038 if ((file = ws_fopen(fname, "r")) == NULL) {
2043 c = ws_getc_unlocked(file);
2044 if (start_of_line && c != comment_char && !g_ascii_isspace(c) && g_ascii_isprint(c)) {
2048 if (c == '\n' || !g_ascii_isspace(c)) {
2049 start_of_line = (c == '\n');
2058 * Check that the from file is not the same as to file
2059 * We do it here so we catch all cases ...
2060 * Unfortunately, the file requester gives us an absolute file
2061 * name and the read file name may be relative (if supplied on
2062 * the command line), so we can't just compare paths. From Joerg Mayer.
2065 files_identical(const char *fname1, const char *fname2)
2067 /* Two different implementations, because:
2069 * - _fullpath is not available on UN*X, so we can't get full
2070 * paths and compare them (which wouldn't work with hard links
2073 * - st_ino isn't filled in with a meaningful value on Windows.
2076 char full1[MAX_PATH], full2[MAX_PATH];
2079 * Get the absolute full paths of the file and compare them.
2080 * That won't work if you have hard links, but those aren't
2081 * much used on Windows, even though NTFS supports them.
2083 * XXX - will _fullpath work with UNC?
2085 if( _fullpath( full1, fname1, MAX_PATH ) == NULL ) {
2089 if( _fullpath( full2, fname2, MAX_PATH ) == NULL ) {
2093 if(strcmp(full1, full2) == 0) {
2099 ws_statb64 filestat1, filestat2;
2102 * Compare st_dev and st_ino.
2104 if (ws_stat64(fname1, &filestat1) == -1)
2105 return FALSE; /* can't get info about the first file */
2106 if (ws_stat64(fname2, &filestat2) == -1)
2107 return FALSE; /* can't get info about the second file */
2108 return (filestat1.st_dev == filestat2.st_dev &&
2109 filestat1.st_ino == filestat2.st_ino);
2114 * Copy a file in binary mode, for those operating systems that care about
2115 * such things. This should be OK for all files, even text files, as
2116 * we'll copy the raw bytes, and we don't look at the bytes as we copy
2119 * Returns TRUE on success, FALSE on failure. If a failure, it also
2120 * displays a simple dialog window with the error message.
2123 copy_file_binary_mode(const char *from_filename, const char *to_filename)
2125 int from_fd, to_fd, err;
2126 ssize_t nread, nwritten;
2129 /* Copy the raw bytes of the file. */
2130 from_fd = ws_open(from_filename, O_RDONLY | O_BINARY, 0000 /* no creation so don't matter */);
2132 report_open_failure(from_filename, errno, FALSE);
2136 /* Use open() instead of creat() so that we can pass the O_BINARY
2137 flag, which is relevant on Win32; it appears that "creat()"
2138 may open the file in text mode, not binary mode, but we want
2139 to copy the raw bytes of the file, so we need the output file
2140 to be open in binary mode. */
2141 to_fd = ws_open(to_filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644);
2143 report_open_failure(to_filename, errno, TRUE);
2148 #define FS_READ_SIZE 65536
2149 pd = (guint8 *)g_malloc(FS_READ_SIZE);
2150 while ((nread = ws_read(from_fd, pd, FS_READ_SIZE)) > 0) {
2151 nwritten = ws_write(to_fd, pd, nread);
2152 if (nwritten < nread) {
2156 err = WTAP_ERR_SHORT_WRITE;
2157 report_write_failure(to_filename, err);
2165 report_read_failure(from_filename, err);
2171 if (ws_close(to_fd) < 0) {
2172 report_write_failure(to_filename, errno);
2186 data_file_url(const gchar *filename)
2191 /* Absolute path? */
2192 if(g_path_is_absolute(filename)) {
2193 file_path = g_strdup(filename);
2194 } else if(running_in_build_directory()) {
2195 file_path = g_strdup_printf("%s/doc/%s", get_datafile_dir(), filename);
2197 file_path = g_strdup_printf("%s/%s", get_datafile_dir(), filename);
2200 /* XXX - check, if the file is really existing, otherwise display a simple_dialog about the problem */
2202 /* convert filename to uri */
2203 uri = g_filename_to_uri(file_path, NULL, NULL);
2211 g_free(persconffile_dir);
2212 persconffile_dir = NULL;
2213 g_free(persdatafile_dir);
2214 persdatafile_dir = NULL;
2215 g_free(persconfprofile);
2216 persconfprofile = NULL;
2217 g_free(progfile_dir);
2218 progfile_dir = NULL;
2219 #if defined(HAVE_PLUGINS) || defined(HAVE_LUA)
2222 g_free(plugin_dir_with_version);
2223 plugin_dir_with_version = NULL;
2224 g_free(plugin_pers_dir);
2225 plugin_pers_dir = NULL;
2226 g_free(plugin_pers_dir_with_version);
2227 plugin_pers_dir_with_version = NULL;
2239 * indent-tabs-mode: nil
2242 * ex: set shiftwidth=4 tabstop=8 expandtab:
2243 * :indentSize=4:tabSize=8:noTabs=true: