2 * Filesystem utility routines
4 * Wireshark - Network traffic analyzer
5 * By Gerald Combs <gerald@wireshark.org>
6 * Copyright 1998 Gerald Combs
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
26 * Required with GNU libc to get dladdr().
27 * We define it here because <dlfcn.h> apparently gets included by
28 * one of the headers we include below.
51 #ifdef HAVE_SYS_STAT_H
59 #include <wsutil/unicode-utils.h>
62 #include <mach-o/dyld.h>
65 #include <sys/utsname.h>
68 #include <sys/types.h>
69 #include <sys/sysctl.h>
77 #include "filesystem.h"
78 #include <wsutil/report_err.h>
79 #include <wsutil/privileges.h>
80 #include <wsutil/file_util.h>
82 #include <wiretap/wtap.h> /* for WTAP_ERR_SHORT_WRITE */
84 #define PROFILES_DIR "profiles"
85 #define PLUGINS_DIR_NAME "plugins"
87 #define U3_MY_CAPTURES "\\My Captures"
89 char *persconffile_dir = NULL;
90 char *persdatafile_dir = NULL;
91 char *persconfprofile = NULL;
93 static gboolean do_store_persconffiles = FALSE;
94 static GHashTable *profile_files = NULL;
97 * Given a pathname, return a pointer to the last pathname separator
98 * character in the pathname, or NULL if the pathname contains no
102 find_last_pathname_separator(const char *path)
110 * We have to scan for '\' or '/'.
111 * Get to the end of the string.
113 separator = strchr(path, '\0'); /* points to ending '\0' */
114 while (separator > path) {
116 if (c == '\\' || c == '/')
117 return separator; /* found it */
121 * OK, we didn't find any, so no directories - but there might
122 * be a drive letter....
124 return strchr(path, ':');
126 separator = strrchr(path, '/');
132 * Given a pathname, return the last component.
135 get_basename(const char *path)
137 const char *filename;
139 g_assert(path != NULL);
140 filename = find_last_pathname_separator(path);
141 if (filename == NULL) {
143 * There're no directories, drive letters, etc. in the
144 * name; the pathname *is* the file name.
149 * Skip past the pathname or drive letter separator.
157 * Given a pathname, return a string containing everything but the
158 * last component. NOTE: this overwrites the pathname handed into
162 get_dirname(char *path)
166 g_assert(path != NULL);
167 separator = find_last_pathname_separator(path);
168 if (separator == NULL) {
170 * There're no directories, drive letters, etc. in the
171 * name; there is no directory path to return.
177 * Get rid of the last pathname separator and the final file
183 * "path" now contains the pathname of the directory containing
184 * the file/directory to which it referred.
190 * Given a pathname, return:
192 * the errno, if an attempt to "stat()" the file fails;
194 * EISDIR, if the attempt succeeded and the file turned out
197 * 0, if the attempt succeeded and the file turned out not
202 * Visual C++ on Win32 systems doesn't define these. (Old UNIX systems don't
203 * define them either.)
205 * Visual C++ on Win32 systems doesn't define S_IFIFO, it defines _S_IFIFO.
208 #define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG)
211 #define S_IFIFO _S_IFIFO
214 #define S_ISFIFO(mode) (((mode) & S_IFMT) == S_IFIFO)
217 #define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
221 test_for_directory(const char *path)
225 if (ws_stat64(path, &statb) < 0)
228 if (S_ISDIR(statb.st_mode))
235 test_for_fifo(const char *path)
239 if (ws_stat64(path, &statb) < 0)
242 if (S_ISFIFO(statb.st_mode))
249 * Directory from which the executable came.
251 static char *progfile_dir;
255 * Directory of the application bundle in which we're contained,
256 * if we're contained in an application bundle. Otherwise, NULL.
258 * Note: Table 2-5 "Subdirectories of the Contents directory" of
260 * https://developer.apple.com/library/mac/documentation/CoreFoundation/Conceptual/CFBundles/BundleTypes/BundleTypes.html#//apple_ref/doc/uid/10000123i-CH101-SW1
262 * says that the "Frameworks" directory
264 * Contains any private shared libraries and frameworks used by the
265 * executable. The frameworks in this directory are revision-locked
266 * to the application and cannot be superseded by any other, even
267 * newer, versions that may be available to the operating system. In
268 * other words, the frameworks included in this directory take precedence
269 * over any other similarly named frameworks found in other parts of
270 * the operating system. For information on how to add private
271 * frameworks to your application bundle, see Framework Programming Guide.
273 * so if we were to ship with any frameworks (e.g. Qt) we should
274 * perhaps put them in a Frameworks directory rather than under
277 * It also says that the "PlugIns" directory
279 * Contains loadable bundles that extend the basic features of your
280 * application. You use this directory to include code modules that
281 * must be loaded into your applicationbs process space in order to
282 * be used. You would not use this directory to store standalone
285 * Our plugins are just raw .so/.dylib files; I don't know whether by
286 * "bundles" they mean application bundles (i.e., directory hierarchies)
287 * or just "bundles" in the Mach-O sense (which are an image type that
288 * can be loaded with dlopen() but not linked as libraries; our plugins
289 * are, I think, built as dylibs and can be loaded either way).
291 * And it says that the "SharedSupport" directory
293 * Contains additional non-critical resources that do not impact the
294 * ability of the application to run. You might use this directory to
295 * include things like document templates, clip art, and tutorials
296 * that your application expects to be present but that do not affect
297 * the ability of your application to run.
299 * I don't think I'd put the files that currently go under Resources/share
300 * into that category; they're not, for example, sample Lua scripts that
301 * don't actually get run by Wireshark, they're configuration/data files
302 * for Wireshark whose absence might not prevent Wireshark from running
303 * but that would affect how it behaves when run.
305 static char *appbundle_dir;
309 * TRUE if we're running from the build directory and we aren't running
310 * with special privileges.
312 static gboolean running_in_build_directory_flag = FALSE;
316 * Get the pathname of the executable using various platform-
317 * dependent mechanisms for various UN*Xes.
319 * These calls all should return something independent of the argv[0]
320 * passed to the program, so it shouldn't be fooled by an argv[0]
321 * that doesn't match the executable path.
323 * Sadly, not all UN*Xes necessarily have dladdr(), and those that
324 * do don't necessarily have dladdr(main) return information about
325 * the executable image, and those that do aren't necessarily running
326 * on a platform wherein the executable image can get its own path
327 * from the kernel (either by a call or by it being handed to it along
328 * with argv[] and the environment), and those that can don't
329 * necessarily use that to supply the path you get from dladdr(main),
330 * so we try this first and, if that fails, use dladdr(main) if
333 * In particular, some dynamic linkers supply a dladdr() such that
334 * dladdr(main) just returns something derived from argv[0], so
335 * just using dladdr(main) is the wrong thing to do if there's
336 * another mechanism that can get you a more reliable version of
337 * the executable path.
339 * However, at least in newer versions of DragonFly BSD, the dynamic
340 * linker *does* get it from the aux vector passed to the program
341 * by the kernel, readlink /proc/curproc/file - which came first?
343 * On OpenBSD, dladdr(main) returns a value derived from argv[0],
344 * and there doesn't appear to be any way to get the executable path
345 * from the kernel, so we're out of luck there.
347 * So, on platforms where some versions have a version of dladdr()
348 * that gives an argv[0]-based path and that also have a mechanism
349 * to get a more reliable version of the path, we try that. On
350 * other platforms, we return NULL. If our caller gets back a NULL
351 * from us, it falls back on dladdr(main) if dladdr() is available,
352 * and if that fails or is unavailable, it falls back on processing
355 * This is not guaranteed to return an absolute path; if it doesn't,
356 * our caller must prepend the current directory if it's a path.
358 * This is not guaranteed to return the "real path"; it might return
359 * something with symbolic links in the path. Our caller must
360 * use realpath() if they want the real thing, but that's also true of
361 * something obtained by looking at argv[0].
364 get_executable_path(void)
366 #if defined(__APPLE__)
367 char *executable_path;
368 uint32_t path_buf_size;
370 path_buf_size = PATH_MAX;
371 executable_path = (char *)g_malloc(path_buf_size);
372 if (_NSGetExecutablePath(executable_path, &path_buf_size) == -1) {
373 executable_path = (char *)g_realloc(executable_path, path_buf_size);
374 if (_NSGetExecutablePath(executable_path, &path_buf_size) == -1)
377 return executable_path;
378 #elif defined(__linux__)
380 * In older versions of GNU libc's dynamic linker, as used on Linux,
381 * dladdr(main) supplies a path based on argv[0], so we use
382 * /proc/self/exe instead; there are Linux distributions with
383 * kernels that support /proc/self/exe and those older versions
384 * of the dynamic linker, and this will get a better answer on
387 * It only works on Linux 2.2 or later, so we just give up on
390 * XXX - are there OS versions that support "exe" but not "self"?
393 static char executable_path[PATH_MAX];
395 if (uname(&name) == -1)
397 if (strncmp(name.release, "1.", 2) == 0)
398 return NULL; /* Linux 1.x */
399 if (strcmp(name.release, "2.0") == 0 ||
400 strncmp(name.release, "2.0.", 4) == 0 ||
401 strcmp(name.release, "2.1") == 0 ||
402 strncmp(name.release, "2.1.", 4) == 0)
403 return NULL; /* Linux 2.0.x or 2.1.x */
404 if (readlink("/proc/self/exe", executable_path, sizeof executable_path) == -1)
406 return executable_path;
407 #elif defined(__FreeBSD__) && defined(KERN_PROC_PATHNAME)
409 * In older versions of FreeBSD's dynamic linker, dladdr(main)
410 * supplies a path based on argv[0], so we use the KERN_PROC_PATHNAME
411 * sysctl instead; there are, I think, versions of FreeBSD
412 * that support the sysctl that have and those older versions
413 * of the dynamic linker, and this will get a better answer on
417 char *executable_path;
418 size_t path_buf_size;
422 mib[2] = KERN_PROC_PATHNAME;
424 path_buf_size = PATH_MAX;
425 executable_path = (char *)g_malloc(path_buf_size);
426 if (sysctl(mib, 4, executable_path, &path_buf_size, NULL, 0) == -1) {
429 executable_path = (char *)g_realloc(executable_path, path_buf_size);
430 if (sysctl(mib, 4, executable_path, &path_buf_size, NULL, 0) == -1)
433 return executable_path;
434 #elif defined(__NetBSD__)
436 * In all versions of NetBSD's dynamic linker as of 2013-08-12,
437 * dladdr(main) supplies a path based on argv[0], so we use
438 * /proc/curproc/exe instead.
440 * XXX - are there OS versions that support "exe" but not "curproc"
441 * or "self"? Are there any that support "self" but not "curproc"?
443 static char executable_path[PATH_MAX];
445 if (readlink("/proc/curproc/exe", executable_path, sizeof executable_path) == -1)
447 return executable_path;
448 #elif defined(__DragonFly__)
450 * In older versions of DragonFly BSD's dynamic linker, dladdr(main)
451 * supplies a path based on argv[0], so we use /proc/curproc/file
452 * instead; it appears to be supported by all versions of DragonFly
455 static char executable_path[PATH_MAX];
457 if (readlink("/proc/curproc/file", executable_path, sizeof executable_path) == -1)
459 return executable_path;
460 #elif (defined(sun) || defined(__sun)) && defined(HAVE_GETEXECNAME)
462 * It appears that getexecname() dates back to at least Solaris 8,
463 * but /proc/{pid}/path is first documented in the Solaris 10 documentation,
464 * so we use getexecname() if available, rather than /proc/self/path/a.out
465 * (which isn't documented, but appears to be a symlink to the
466 * executable image file).
468 return getexecname();
470 /* Fill in your favorite UN*X's code here, if there is something */
477 * Get the pathname of the directory from which the executable came,
478 * and save it for future use. Returns NULL on success, and a
479 * g_mallocated string containing an error on failure.
482 init_progfile_dir(const char *arg0
486 , int (*main_addr)(int, char **)
487 #if defined(_WIN32) || !defined(HAVE_DLADDR)
493 TCHAR prog_pathname_w[_MAX_PATH+2];
501 * Attempt to get the full pathname of the currently running
504 if (GetModuleFileName(NULL, prog_pathname_w, G_N_ELEMENTS(prog_pathname_w)) != 0 && GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
506 * XXX - Should we use g_utf16_to_utf8(), as in
509 prog_pathname = utf_16to8(prog_pathname_w);
511 * We got it; strip off the last component, which would be
512 * the file name of the executable, giving us the pathname
513 * of the directory where the executable resides.
515 progfile_dir = g_path_get_dirname(prog_pathname);
516 if (progfile_dir != NULL) {
517 return NULL; /* we succeeded */
520 * OK, no. What do we do now?
522 return g_strdup_printf("No \\ in executable pathname \"%s\"",
527 * Oh, well. Return an indication of the error.
529 error = GetLastError();
530 if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,
531 NULL, error, 0, (LPTSTR) &msg_w, 0, NULL) == 0) {
533 * Gak. We can't format the message.
535 return g_strdup_printf("GetModuleFileName failed: %u (FormatMessage failed: %u)",
536 error, GetLastError());
538 msg = utf_16to8(msg_w);
541 * "FormatMessage()" "helpfully" sticks CR/LF at the
542 * end of the message. Get rid of it.
544 msglen = strlen(msg);
546 msg[msglen - 1] = '\0';
547 msg[msglen - 2] = '\0';
549 return g_strdup_printf("GetModuleFileName failed: %s (%u)",
556 const char *execname;
561 char *path_start, *path_end;
562 size_t path_component_len, path_len;
568 * Check whether WIRESHARK_RUN_FROM_BUILD_DIRECTORY is set in the
569 * environment; if so, set running_in_build_directory_flag if we
570 * weren't started with special privileges. (If we were started
571 * with special privileges, it's not safe to allow the user to point
572 * us to some other directory; running_in_build_directory_flag, when
573 * set, causes us to look for plugins and the like in the build
576 if (getenv("WIRESHARK_RUN_FROM_BUILD_DIRECTORY") != NULL
577 && !started_with_special_privs())
578 running_in_build_directory_flag = TRUE;
580 execname = get_executable_path();
582 if (main_addr != NULL && execname == NULL) {
584 * Try to use dladdr() to find the pathname of the executable.
585 * dladdr() is not guaranteed to give you anything better than
586 * argv[0] (i.e., it might not contain a / at all, much less
587 * being an absolute path), and doesn't appear to do so on
588 * Linux, but on other platforms it could give you an absolute
589 * path and obviate the need for us to determine the absolute
592 if (dladdr((void *)main_addr, &info))
593 execname = info.dli_fname;
596 if (execname == NULL) {
598 * OK, guess based on argv[0].
604 * Try to figure out the directory in which the currently running
605 * program resides, given something purporting to be the executable
606 * name (from dladdr() or from the argv[0] it was started with.
607 * That might be the absolute path of the program, or a path relative
608 * to the current directory of the process that started it, or
609 * just a name for the program if it was started from the command
610 * line and was searched for in $PATH. It's not guaranteed to be
611 * any of those, however, so there are no guarantees....
613 if (execname[0] == '/') {
615 * It's an absolute path.
617 prog_pathname = g_strdup(execname);
618 } else if (strchr(execname, '/') != NULL) {
620 * It's a relative path, with a directory in it.
621 * Get the current directory, and combine it
622 * with that directory.
624 path_max = pathconf(".", _PC_PATH_MAX);
625 if (path_max == -1) {
627 * We have no idea how big a buffer to
628 * allocate for the current directory.
630 return g_strdup_printf("pathconf failed: %s\n",
633 curdir = (char *)g_malloc(path_max);
634 if (getcwd(curdir, path_max) == NULL) {
636 * It failed - give up, and just stick
640 return g_strdup_printf("getcwd failed: %s\n",
643 path = g_strdup_printf("%s/%s", curdir, execname);
645 prog_pathname = path;
648 * It's just a file name.
649 * Search the path for a file with that name
652 prog_pathname = NULL; /* haven't found it yet */
653 pathstr = getenv("PATH");
654 path_start = pathstr;
655 if (path_start != NULL) {
656 while (*path_start != '\0') {
657 path_end = strchr(path_start, ':');
658 if (path_end == NULL)
659 path_end = path_start + strlen(path_start);
660 path_component_len = path_end - path_start;
661 path_len = path_component_len + 1
662 + strlen(execname) + 1;
663 path = (char *)g_malloc(path_len);
664 memcpy(path, path_start, path_component_len);
665 path[path_component_len] = '\0';
666 g_strlcat(path, "/", path_len);
667 g_strlcat(path, execname, path_len);
668 if (access(path, X_OK) == 0) {
672 prog_pathname = path;
677 * That's not it. If there are more
678 * path components to test, try them.
680 if (*path_end == '\0') {
682 * There's nothing more to try.
686 if (*path_end == ':')
688 path_start = path_end;
691 if (prog_pathname == NULL) {
693 * Program not found in path.
695 return g_strdup_printf("\"%s\" not found in \"%s\"",
701 * XXX - should we pick a default?
703 return g_strdup("PATH isn't set");
708 * OK, we have what we think is the pathname
711 * First, find the last "/" in the directory,
712 * as that marks the end of the directory pathname.
714 dir_end = strrchr(prog_pathname, '/');
715 if (dir_end != NULL) {
717 * Found it. Strip off the last component,
718 * as that's the path of the program.
723 * Is there a "/.libs" at the end?
725 dir_end = strrchr(prog_pathname, '/');
726 if (dir_end != NULL) {
727 if (strcmp(dir_end, "/.libs") == 0) {
730 * Strip that off; it's an
731 * artifact of libtool.
736 * This presumably means we're run from
737 * the libtool wrapper, which probably
738 * means we're being run from the build
739 * directory. If we weren't started
740 * with special privileges, set
741 * running_in_build_directory_flag.
743 * XXX - should we check whether what
744 * follows ".libs/" begins with "lt-"?
746 if (!started_with_special_privs())
747 running_in_build_directory_flag = TRUE;
751 if (!started_with_special_privs()) {
753 * Scan up the path looking for a component
754 * named "Contents". If we find it, we assume
755 * we're in a bundle, and that the top-level
756 * directory of the bundle is the one containing
759 * Not all executables are in the Contents/MacOS
760 * directory, so we can't just check for those
761 * in the path and strip them off.
763 * XXX - should we assume that it's either
764 * Contents/MacOS or Resources/bin?
766 char *component_end, *p;
768 component_end = strchr(prog_pathname, '\0');
771 while (p >= prog_pathname && *p != '/')
773 if (p == prog_pathname) {
775 * We're looking at the first component of
776 * the pathname now, so we're definitely
777 * not in a bundle, even if we're in
782 if (strncmp(p, "/Contents", component_end - p) == 0) {
784 appbundle_dir = (char *)g_malloc(p - prog_pathname + 1);
785 memcpy(appbundle_dir, prog_pathname, p - prog_pathname);
786 appbundle_dir[p - prog_pathname] = '\0';
798 * OK, we have the path we want.
800 progfile_dir = prog_pathname;
804 * This "shouldn't happen"; we apparently
805 * have no "/" in the pathname.
806 * Just free up prog_pathname.
808 retstr = g_strdup_printf("No / found in \"%s\"", prog_pathname);
809 g_free(prog_pathname);
816 * Get the directory in which the program resides.
819 get_progfile_dir(void)
825 * Get the directory in which the global configuration and data files are
828 * On Windows, we use the directory in which the executable for this
831 * On UN*X, we use the DATAFILE_DIR value supplied by the configure
832 * script, unless we think we're being run from the build directory,
833 * in which case we use the directory in which the executable for this
836 * XXX - if we ever make libwireshark a real library, used by multiple
837 * applications (more than just TShark and versions of Wireshark with
838 * various UIs), should the configuration files belong to the library
839 * (and be shared by all those applications) or to the applications?
841 * If they belong to the library, that could be done on UNIX by the
842 * configure script, but it's trickier on Windows, as you can't just
843 * use the pathname of the executable.
845 * If they belong to the application, that could be done on Windows
846 * by using the pathname of the executable, but we'd have to have it
847 * passed in as an argument, in some call, on UNIX.
849 * Note that some of those configuration files might be used by code in
850 * libwireshark, some of them might be used by dissectors (would they
851 * belong to libwireshark, the application, or a separate library?),
852 * and some of them might be used by other code (the Wireshark preferences
853 * file includes resolver preferences that control the behavior of code
854 * in libwireshark, dissector preferences, and UI preferences, for
858 get_datafile_dir(void)
861 char *u3deviceexecpath;
863 static const char *datafile_dir = NULL;
865 if (datafile_dir != NULL)
870 * See if we are running in a U3 environment.
872 u3deviceexecpath = getenv_utf8("U3_DEVICE_EXEC_PATH");
874 if (u3deviceexecpath != NULL) {
876 * We are; use the U3 device executable path.
878 datafile_dir = u3deviceexecpath;
881 * Do we have the pathname of the program? If so, assume we're
882 * running an installed version of the program. If we fail,
883 * we don't change "datafile_dir", and thus end up using the
886 * XXX - does NSIS put the installation directory into
887 * "\HKEY_LOCAL_MACHINE\SOFTWARE\Wireshark\InstallDir"?
888 * If so, perhaps we should read that from the registry,
891 if (progfile_dir != NULL) {
893 * Yes, we do; use that.
895 datafile_dir = progfile_dir;
899 * Fall back on the default installation directory.
901 datafile_dir = "C:\\Program Files\\Wireshark\\";
906 if (running_in_build_directory_flag) {
908 * We're (probably) being run from the build directory and
909 * weren't started with special privileges.
911 * (running_in_build_directory_flag is never set to TRUE
912 * if we're started with special privileges, so we need
913 * only check it; we don't need to call started_with_special_privs().)
915 * Use the top-level source directory as the datafile directory
916 * because most of our data files (radius/, COPYING) are there.
918 datafile_dir = g_strdup(TOP_SRCDIR);
921 if (getenv("WIRESHARK_DATA_DIR") && !started_with_special_privs()) {
923 * The user specified a different directory for data files
924 * and we aren't running with special privileges.
925 * XXX - We might be able to dispense with the priv check
927 datafile_dir = g_strdup(getenv("WIRESHARK_DATA_DIR"));
931 * If we're running from an app bundle and weren't started
932 * with special privileges, use the Contents/Resources/share/wireshark
933 * subdirectory of the app bundle.
935 * (appbundle_dir is not set to a non-null value if we're
936 * started with special privileges, so we need only check
937 * it; we don't need to call started_with_special_privs().)
939 else if (appbundle_dir != NULL) {
940 datafile_dir = g_strdup_printf("%s/Contents/Resources/share/wireshark",
945 datafile_dir = DATAFILE_DIR;
953 #if defined(HAVE_PLUGINS) || defined(HAVE_LUA)
955 * Find the directory where the plugins are stored.
957 * On Windows, we use the "plugin" subdirectory of the datafile directory.
959 * On UN*X, we use the PLUGIN_INSTALL_DIR value supplied by the configure
960 * script, unless we think we're being run from the build directory,
961 * in which case we use the "plugin" subdirectory of the datafile directory.
963 * In both cases, we then use the subdirectory of that directory whose
964 * name is the version number.
966 * XXX - if we think we're being run from the build directory, perhaps we
967 * should have the plugin code not look in the version subdirectory
968 * of the plugin directory, but look in all of the subdirectories
969 * of the plugin directory, so it can just fetch the plugins built
970 * as part of the build process.
972 static const char *plugin_dir = NULL;
975 init_plugin_dir(void)
979 * On Windows, the data file directory is the installation
980 * directory; the plugins are stored under it.
982 * Assume we're running the installed version of Wireshark;
983 * on Windows, the data file directory is the directory
984 * in which the Wireshark binary resides.
986 plugin_dir = g_strdup_printf("%s\\plugins\\%s", get_datafile_dir(),
990 * Make sure that pathname refers to a directory.
992 if (test_for_directory(plugin_dir) != EISDIR) {
994 * Either it doesn't refer to a directory or it
995 * refers to something that doesn't exist.
997 * Assume that means we're running a version of
998 * Wireshark we've built in a build directory,
999 * in which case {datafile dir}\plugins is the
1000 * top-level plugins source directory, and use
1001 * that directory and set the "we're running in
1002 * a build directory" flag, so the plugin
1003 * scanner will check all subdirectories of that
1004 * directory for plugins.
1006 g_free( (gpointer) plugin_dir);
1007 plugin_dir = g_strdup_printf("%s\\plugins", get_datafile_dir());
1008 running_in_build_directory_flag = TRUE;
1011 if (running_in_build_directory_flag) {
1013 * We're (probably) being run from the build directory and
1014 * weren't started with special privileges, so we'll use
1015 * the "plugins" subdirectory of the directory where the program
1016 * we're running is (that's the build directory).
1018 plugin_dir = g_strdup_printf("%s/plugins", get_progfile_dir());
1020 if (getenv("WIRESHARK_PLUGIN_DIR") && !started_with_special_privs()) {
1022 * The user specified a different directory for plugins
1023 * and we aren't running with special privileges.
1025 plugin_dir = g_strdup(getenv("WIRESHARK_PLUGIN_DIR"));
1029 * If we're running from an app bundle and weren't started
1030 * with special privileges, use the Contents/PlugIns/wireshark
1031 * subdirectory of the app bundle.
1033 * (appbundle_dir is not set to a non-null value if we're
1034 * started with special privileges, so we need only check
1035 * it; we don't need to call started_with_special_privs().)
1037 else if (appbundle_dir != NULL) {
1038 plugin_dir = g_strdup_printf("%s/Contents/PlugIns/wireshark",
1043 plugin_dir = PLUGIN_INSTALL_DIR;
1048 #endif /* HAVE_PLUGINS || HAVE_LUA */
1051 * Get the directory in which the plugins are stored.
1054 get_plugin_dir(void)
1056 #if defined(HAVE_PLUGINS) || defined(HAVE_LUA)
1057 if (!plugin_dir) init_plugin_dir();
1064 #if defined(HAVE_EXTCAP)
1066 * Find the directory where the extcap hooks are stored.
1068 * On Windows, we use the "extcap" subdirectory of the datafile directory.
1070 * On UN*X, we use the EXTCAP_DIR value supplied by the configure
1071 * script, unless we think we're being run from the build directory,
1072 * in which case we use the "extcap" subdirectory of the datafile directory.
1074 * In both cases, we then use the subdirectory of that directory whose
1075 * name is the version number.
1077 * XXX - if we think we're being run from the build directory, perhaps we
1078 * should have the extcap code not look in the version subdirectory
1079 * of the extcap directory, but look in all of the subdirectories
1080 * of the extcap directory, so it can just fetch the extcap hooks built
1081 * as part of the build process.
1083 static const char *extcap_dir = NULL;
1085 static void init_extcap_dir(void) {
1088 * On Windows, the data file directory is the installation
1089 * directory; the extcap hooks are stored under it.
1091 * Assume we're running the installed version of Wireshark;
1092 * on Windows, the data file directory is the directory
1093 * in which the Wireshark binary resides.
1095 extcap_dir = g_strdup_printf("%s\\extcap\\%s", get_datafile_dir(),
1099 * Make sure that pathname refers to a directory.
1101 if (test_for_directory(extcap_dir) != EISDIR) {
1103 * Either it doesn't refer to a directory or it
1104 * refers to something that doesn't exist.
1106 * Assume that means we're running a version of
1107 * Wireshark we've built in a build directory,
1108 * in which case {datafile dir}\plugins is the
1109 * top-level extcap hooks source directory, and use
1110 * that directory and set the "we're running in
1111 * a build directory" flag, so the plugin
1112 * scanner will check all subdirectories of that
1113 * directory for extcap hooks.
1115 g_free( (gpointer) extcap_dir);
1116 extcap_dir = g_strdup_printf("%s\\extcap", get_datafile_dir());
1117 running_in_build_directory_flag = TRUE;
1120 if (running_in_build_directory_flag) {
1122 * We're (probably) being run from the build directory and
1123 * weren't started with special privileges, so we'll use
1124 * the "extcap hooks" subdirectory of the directory where the program
1125 * we're running is (that's the build directory).
1127 extcap_dir = g_strdup_printf("%s/extcap", get_progfile_dir());
1129 if (getenv("WIRESHARK_EXTCAP_DIR") && !started_with_special_privs()) {
1131 * The user specified a different directory for extcap hooks
1132 * and we aren't running with special privileges.
1134 extcap_dir = g_strdup(getenv("WIRESHARK_EXTCAP_DIR"));
1138 * If we're running from an app bundle and weren't started
1139 * with special privileges, use the Contents/Resources/lib/wireshark/extcap
1140 * subdirectory of the app bundle.
1142 * (appbundle_dir is not set to a non-null value if we're
1143 * started with special privileges, so we need only check
1144 * it; we don't need to call started_with_special_privs().)
1146 else if (appbundle_dir != NULL) {
1147 extcap_dir = g_strdup_printf("%s/Contents/Resources/lib/wireshark/extcap",
1152 extcap_dir = EXTCAP_DIR;
1157 #endif /* HAVE_EXTCAP */
1160 * Get the directory in which the extcap hooks are stored.
1162 * XXX - A fix instead of HAVE_EXTCAP must be found
1165 get_extcap_dir(void) {
1166 #if defined(HAVE_EXTCAP)
1176 * Get the flag indicating whether we're running from a build
1180 running_in_build_directory(void)
1182 return running_in_build_directory_flag;
1186 * Get the directory in which files that, at least on UNIX, are
1187 * system files (such as "/etc/ethers") are stored; on Windows,
1188 * there's no "/etc" directory, so we get them from the global
1189 * configuration and data file directory.
1192 get_systemfile_dir(void)
1195 return get_datafile_dir();
1202 * Name of directory, under the user's home directory, in which
1203 * personal configuration files are stored.
1206 #define PF_DIR "Wireshark"
1209 * XXX - should this be ".libepan"? For backwards-compatibility, I'll keep
1210 * it ".wireshark" for now.
1212 #define PF_DIR ".wireshark"
1216 set_profile_name(const gchar *profilename)
1218 g_free (persconfprofile);
1220 if (profilename && strlen(profilename) > 0 &&
1221 strcmp(profilename, DEFAULT_PROFILE) != 0) {
1222 persconfprofile = g_strdup (profilename);
1224 /* Default Profile */
1225 persconfprofile = NULL;
1230 get_profile_name(void)
1232 if (persconfprofile) {
1233 return persconfprofile;
1235 return DEFAULT_PROFILE;
1240 is_default_profile(void)
1242 return (!persconfprofile || strcmp(persconfprofile, DEFAULT_PROFILE) == 0) ? TRUE : FALSE;
1246 has_global_profiles(void)
1250 const gchar *global_dir = get_global_profiles_dir();
1252 gboolean has_global = FALSE;
1254 if ((test_for_directory(global_dir) == EISDIR) &&
1255 ((dir = ws_dir_open(global_dir, 0, NULL)) != NULL))
1257 while ((file = ws_dir_read_name(dir)) != NULL) {
1258 filename = g_strdup_printf ("%s%s%s", global_dir, G_DIR_SEPARATOR_S,
1259 ws_dir_get_name(file));
1260 if (test_for_directory(filename) == EISDIR) {
1274 profile_store_persconffiles(gboolean store)
1277 profile_files = g_hash_table_new (g_str_hash, g_str_equal);
1279 do_store_persconffiles = store;
1283 * Get the directory in which personal configuration files reside;
1284 * in UNIX-compatible systems, it's ".wireshark", under the user's home
1285 * directory, and on Windows systems, it's "Wireshark", under %APPDATA%
1286 * or, if %APPDATA% isn't set, it's "%USERPROFILE%\Application Data"
1287 * (which is what %APPDATA% normally is on Windows 2000).
1290 get_persconffile_dir_no_profile(void)
1294 char *userprofiledir;
1295 char *altappdatapath;
1297 const char *homedir;
1301 /* Return the cached value, if available */
1302 if (persconffile_dir != NULL)
1303 return persconffile_dir;
1307 * See if the user has selected an alternate environment.
1309 altappdatapath = getenv_utf8("WIRESHARK_APPDATA");
1310 if (altappdatapath != NULL) {
1311 persconffile_dir = altappdatapath;
1312 return persconffile_dir;
1316 * See if we are running in a U3 environment.
1318 altappdatapath = getenv_utf8("U3_APP_DATA_PATH");
1319 if (altappdatapath != NULL) {
1321 * We are; use the U3 application data path.
1323 persconffile_dir = altappdatapath;
1326 * Use %APPDATA% or %USERPROFILE%, so that configuration
1327 * files are stored in the user profile, rather than in
1328 * the home directory. The Windows convention is to store
1329 * configuration information in the user profile, and doing
1330 * so means you can use Wireshark even if the home directory
1331 * is an inaccessible network drive.
1333 appdatadir = getenv_utf8("APPDATA");
1334 if (appdatadir != NULL) {
1336 * Concatenate %APPDATA% with "\Wireshark".
1338 persconffile_dir = g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s",
1339 appdatadir, PF_DIR);
1342 * OK, %APPDATA% wasn't set, so use
1343 * %USERPROFILE%\Application Data.
1345 userprofiledir = getenv_utf8("USERPROFILE");
1346 if (userprofiledir != NULL) {
1347 persconffile_dir = g_strdup_printf(
1348 "%s" G_DIR_SEPARATOR_S "Application Data" G_DIR_SEPARATOR_S "%s",
1349 userprofiledir, PF_DIR);
1352 * Give up and use "C:".
1354 persconffile_dir = g_strdup_printf("C:" G_DIR_SEPARATOR_S "%s", PF_DIR);
1360 * If $HOME is set, use that.
1362 homedir = getenv("HOME");
1363 if (homedir == NULL) {
1365 * Get their home directory from the password file.
1366 * If we can't even find a password file entry for them,
1369 pwd = getpwuid(getuid());
1371 homedir = pwd->pw_dir;
1376 persconffile_dir = g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s", homedir, PF_DIR);
1379 return persconffile_dir;
1383 set_persconffile_dir(const char *p)
1385 g_free(persconffile_dir);
1386 persconffile_dir = g_strdup(p);
1390 get_profiles_dir(void)
1392 static char *profiles_dir = NULL;
1394 g_free (profiles_dir);
1395 profiles_dir = g_strdup_printf ("%s%s%s", get_persconffile_dir_no_profile (),
1396 G_DIR_SEPARATOR_S, PROFILES_DIR);
1398 return profiles_dir;
1402 get_global_profiles_dir(void)
1404 static char *global_profiles_dir = NULL;
1406 if (!global_profiles_dir) {
1407 global_profiles_dir = g_strdup_printf ("%s%s%s", get_datafile_dir(),
1408 G_DIR_SEPARATOR_S, PROFILES_DIR);
1411 return global_profiles_dir;
1415 get_persconffile_dir(const gchar *profilename)
1417 static char *persconffile_profile_dir = NULL;
1419 g_free (persconffile_profile_dir);
1421 if (profilename && strlen(profilename) > 0 &&
1422 strcmp(profilename, DEFAULT_PROFILE) != 0) {
1423 persconffile_profile_dir = g_strdup_printf ("%s%s%s", get_profiles_dir (),
1424 G_DIR_SEPARATOR_S, profilename);
1426 persconffile_profile_dir = g_strdup (get_persconffile_dir_no_profile ());
1429 return persconffile_profile_dir;
1433 profile_exists(const gchar *profilename, gboolean global)
1436 gchar *path = g_strdup_printf ("%s%s%s", get_global_profiles_dir(),
1437 G_DIR_SEPARATOR_S, profilename);
1438 if (test_for_directory (path) == EISDIR) {
1444 if (test_for_directory (get_persconffile_dir (profilename)) == EISDIR) {
1453 delete_directory (const char *directory, char **pf_dir_path_return)
1460 if ((dir = ws_dir_open(directory, 0, NULL)) != NULL) {
1461 while ((file = ws_dir_read_name(dir)) != NULL) {
1462 filename = g_strdup_printf ("%s%s%s", directory, G_DIR_SEPARATOR_S,
1463 ws_dir_get_name(file));
1464 if (test_for_directory(filename) != EISDIR) {
1465 ret = ws_remove(filename);
1468 /* The user has manually created a directory in the profile directory */
1469 /* I do not want to delete the directory recursively yet */
1470 ret = delete_directory (filename, pf_dir_path_return);
1474 *pf_dir_path_return = filename;
1482 if (ret == 0 && (ret = ws_remove(directory)) != 0) {
1483 *pf_dir_path_return = g_strdup (directory);
1490 delete_persconffile_profile(const char *profilename, char **pf_dir_path_return)
1492 const char *profile_dir = get_persconffile_dir(profilename);
1495 if (test_for_directory (profile_dir) == EISDIR) {
1496 ret = delete_directory (profile_dir, pf_dir_path_return);
1503 rename_persconffile_profile(const char *fromname, const char *toname,
1504 char **pf_from_dir_path_return, char **pf_to_dir_path_return)
1506 char *from_dir = g_strdup (get_persconffile_dir(fromname));
1507 char *to_dir = g_strdup (get_persconffile_dir(toname));
1510 ret = ws_rename (from_dir, to_dir);
1512 *pf_from_dir_path_return = g_strdup (from_dir);
1513 *pf_to_dir_path_return = g_strdup (to_dir);
1523 * Create the directory that holds personal configuration files, if
1524 * necessary. If we attempted to create it, and failed, return -1 and
1525 * set "*pf_dir_path_return" to the pathname of the directory we failed
1526 * to create (it's g_mallocated, so our caller should free it); otherwise,
1530 create_persconffile_profile(const char *profilename, char **pf_dir_path_return)
1532 const char *pf_dir_path;
1534 char *pf_dir_path_copy, *pf_dir_parent_path;
1535 size_t pf_dir_parent_path_len;
1542 * Create the "Default" personal configuration files directory, if necessary.
1544 if (create_persconffile_profile (NULL, pf_dir_path_return) == -1) {
1549 * Check if profiles directory exists.
1550 * If not then create it.
1552 pf_dir_path = get_profiles_dir ();
1553 if (ws_stat64(pf_dir_path, &s_buf) != 0 && errno == ENOENT) {
1554 ret = ws_mkdir(pf_dir_path, 0755);
1556 *pf_dir_path_return = g_strdup(pf_dir_path);
1562 pf_dir_path = get_persconffile_dir(profilename);
1563 if (ws_stat64(pf_dir_path, &s_buf) != 0 && errno == ENOENT) {
1566 * Does the parent directory of that directory
1567 * exist? %APPDATA% may not exist even though
1568 * %USERPROFILE% does.
1570 * We check for the existence of the directory
1571 * by first checking whether the parent directory
1572 * is just a drive letter and, if it's not, by
1573 * doing a "stat()" on it. If it's a drive letter,
1574 * or if the "stat()" succeeds, we assume it exists.
1576 pf_dir_path_copy = g_strdup(pf_dir_path);
1577 pf_dir_parent_path = get_dirname(pf_dir_path_copy);
1578 pf_dir_parent_path_len = strlen(pf_dir_parent_path);
1579 if (pf_dir_parent_path_len > 0
1580 && pf_dir_parent_path[pf_dir_parent_path_len - 1] != ':'
1581 && ws_stat64(pf_dir_parent_path, &s_buf) != 0) {
1583 * No, it doesn't exist - make it first.
1585 ret = ws_mkdir(pf_dir_parent_path, 0755);
1587 *pf_dir_path_return = pf_dir_parent_path;
1591 g_free(pf_dir_path_copy);
1592 ret = ws_mkdir(pf_dir_path, 0755);
1594 ret = ws_mkdir(pf_dir_path, 0755);
1598 * Something with that pathname exists; if it's not
1599 * a directory, we'll get an error if we try to put
1600 * something in it, so we don't fail here, we wait
1601 * for that attempt fo fail.
1606 *pf_dir_path_return = g_strdup(pf_dir_path);
1611 create_persconffile_dir(char **pf_dir_path_return)
1613 return create_persconffile_profile(persconfprofile, pf_dir_path_return);
1617 copy_persconffile_profile(const char *toname, const char *fromname, gboolean from_global,
1618 char **pf_filename_return, char **pf_to_dir_path_return, char **pf_from_dir_path_return)
1621 gchar *to_dir = g_strdup (get_persconffile_dir(toname));
1622 gchar *filename, *from_file, *to_file;
1623 GList *files, *file;
1626 if (strcmp(fromname, DEFAULT_PROFILE) == 0) {
1627 from_dir = g_strdup (get_global_profiles_dir());
1629 from_dir = g_strdup_printf ("%s%s%s", get_global_profiles_dir(), G_DIR_SEPARATOR_S, fromname);
1632 from_dir = g_strdup (get_persconffile_dir(fromname));
1635 files = g_hash_table_get_keys(profile_files);
1636 file = g_list_first(files);
1638 filename = (gchar *)file->data;
1639 from_file = g_strdup_printf ("%s%s%s", from_dir, G_DIR_SEPARATOR_S, filename);
1640 to_file = g_strdup_printf ("%s%s%s", to_dir, G_DIR_SEPARATOR_S, filename);
1642 if (file_exists(from_file) && !copy_file_binary_mode(from_file, to_file)) {
1643 *pf_filename_return = g_strdup(filename);
1644 *pf_to_dir_path_return = to_dir;
1645 *pf_from_dir_path_return = from_dir;
1654 file = g_list_next(file);
1657 g_list_free (files);
1665 * Get the (default) directory in which personal data is stored.
1667 * On Win32, this is the "My Documents" folder in the personal profile,
1668 * except that, if we're running from a U3 device, this is the
1669 * "$U3_DEVICE_DOCUMENT_PATH\My Captures" folder.
1670 * On UNIX this is simply the current directory.
1672 /* XXX - should this and the get_home_dir() be merged? */
1674 get_persdatafile_dir(void)
1677 char *u3devicedocumentpath;
1678 TCHAR tszPath[MAX_PATH];
1680 /* Return the cached value, if available */
1681 if (persdatafile_dir != NULL)
1682 return persdatafile_dir;
1685 * See if we are running in a U3 environment.
1687 u3devicedocumentpath = getenv_utf8("U3_DEVICE_DOCUMENT_PATH");
1689 if (u3devicedocumentpath != NULL) {
1690 /* the "My Captures" sub-directory is created (if it doesn't
1691 exist) by u3util.exe when the U3 Wireshark is first run */
1693 persdatafile_dir = g_strdup_printf("%s%s", u3devicedocumentpath, U3_MY_CAPTURES);
1694 return persdatafile_dir;
1697 * Hint: SHGetFolderPath is not available on MSVC 6 - without
1700 if (SHGetSpecialFolderPath(NULL, tszPath, CSIDL_PERSONAL, FALSE)) {
1701 persdatafile_dir = g_utf16_to_utf8(tszPath, -1, NULL, NULL, NULL);
1702 return persdatafile_dir;
1713 set_persdatafile_dir(const char *p)
1715 g_free(persdatafile_dir);
1716 persdatafile_dir = g_strdup(p);
1721 * Returns the user's home directory on Win32.
1726 static const char *home = NULL;
1727 char *homedrive, *homepath;
1731 /* Return the cached value, if available */
1736 * XXX - should we use USERPROFILE anywhere in this process?
1737 * Is there a chance that it might be set but one or more of
1738 * HOMEDRIVE or HOMEPATH isn't set?
1740 homedrive = getenv_utf8("HOMEDRIVE");
1741 if (homedrive != NULL) {
1742 homepath = getenv_utf8("HOMEPATH");
1743 if (homepath != NULL) {
1745 * This is cached, so we don't need to worry about
1746 * allocating multiple ones of them.
1748 homestring = g_strdup_printf("%s%s", homedrive, homepath);
1751 * Trim off any trailing slash or backslash.
1753 lastsep = find_last_pathname_separator(homestring);
1754 if (lastsep != NULL && *(lastsep + 1) == '\0') {
1756 * Last separator is the last character
1757 * in the string. Nuke it.
1766 * Give up and use C:.
1776 * Construct the path name of a personal configuration file, given the
1779 * On Win32, if "for_writing" is FALSE, we check whether the file exists
1780 * and, if not, construct a path name relative to the ".wireshark"
1781 * subdirectory of the user's home directory, and check whether that
1782 * exists; if it does, we return that, so that configuration files
1783 * from earlier versions can be read.
1785 * The returned file name was g_malloc()'d so it must be g_free()d when the
1786 * caller is done with it.
1789 get_persconffile_path(const char *filename, gboolean from_profile)
1792 if (do_store_persconffiles && from_profile && !g_hash_table_lookup (profile_files, filename)) {
1793 /* Store filenames so we know which filenames belongs to a configuration profile */
1794 g_hash_table_insert (profile_files, g_strdup(filename), g_strdup(filename));
1798 path = g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s",
1799 get_persconffile_dir(persconfprofile), filename);
1801 path = g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s",
1802 get_persconffile_dir(NULL), filename);
1809 * Construct the path name of a global configuration file, given the
1812 * The returned file name was g_malloc()'d so it must be g_free()d when the
1813 * caller is done with it.
1816 get_datafile_path(const char *filename)
1818 if (running_in_build_directory_flag &&
1819 (!strcmp(filename, "AUTHORS-SHORT") ||
1820 !strcmp(filename, "hosts"))) {
1821 /* We're running in the build directory and the requested file is a
1822 * generated (or a test) file. Return the file name in the build
1823 * directory (not in the source/data directory).
1824 * (Oh the things we do to keep the source directory pristine...)
1826 return g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s", get_progfile_dir(), filename);
1828 return g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s", get_datafile_dir(), filename);
1832 /* Get the personal plugin dir */
1833 /* Return value is malloced so the caller should g_free() it. */
1835 get_plugins_pers_dir(void)
1837 return get_persconffile_path(PLUGINS_DIR_NAME, FALSE);
1841 * Return an error message for UNIX-style errno indications on open or
1842 * create operations.
1845 file_open_error_message(int err, gboolean for_writing)
1848 static char errmsg_errno[1024+1];
1854 errmsg = "The path to the file \"%s\" doesn't exist.";
1856 errmsg = "The file \"%s\" doesn't exist.";
1861 errmsg = "You don't have permission to create or write to the file \"%s\".";
1863 errmsg = "You don't have permission to read the file \"%s\".";
1867 errmsg = "\"%s\" is a directory (folder), not a file.";
1871 errmsg = "The file \"%s\" could not be created because there is no space left on the file system.";
1876 errmsg = "The file \"%s\" could not be created because you are too close to, or over, your disk quota.";
1881 errmsg = "The file \"%s\" could not be created because an invalid filename was specified.";
1886 * The problem probably has nothing to do with how much RAM the
1887 * user has on their machine, so don't confuse them by saying
1888 * "memory". The problem is probably either virtual address
1889 * space or swap space.
1891 #if GLIB_SIZEOF_VOID_P == 4
1893 * ILP32; we probably ran out of virtual address space.
1895 #define ENOMEM_REASON "it can't be handled by a 32-bit application"
1898 * LP64 or LLP64; we probably ran out of swap space.
1902 * You need to make the pagefile bigger.
1904 #define ENOMEM_REASON "the pagefile is too small"
1905 #elif defined(__APPLE__)
1907 * dynamic_pager couldn't, or wouldn't, create more swap files.
1909 #define ENOMEM_REASON "your system ran out of swap file space"
1912 * Either you have a fixed swap partition or a fixed swap file,
1913 * and it needs to be made bigger.
1915 * This is UN*X, but it's not OS X, so we assume the user is
1918 #define ENOMEM_REASON "your system is out of swap space"
1920 #endif /* GLIB_SIZEOF_VOID_P == 4 */
1922 errmsg = "The file \"%s\" could not be created because " ENOMEM_REASON ".";
1924 errmsg = "The file \"%s\" could not be opened because " ENOMEM_REASON ".";
1928 g_snprintf(errmsg_errno, sizeof(errmsg_errno),
1929 "The file \"%%s\" could not be %s: %s.",
1930 for_writing ? "created" : "opened",
1932 errmsg = errmsg_errno;
1939 * Return an error message for UNIX-style errno indications on write
1943 file_write_error_message(int err)
1946 static char errmsg_errno[1024+1];
1951 errmsg = "The file \"%s\" could not be saved because there is no space left on the file system.";
1956 errmsg = "The file \"%s\" could not be saved because you are too close to, or over, your disk quota.";
1961 g_snprintf(errmsg_errno, sizeof(errmsg_errno),
1962 "An error occurred while writing to the file \"%%s\": %s.",
1964 errmsg = errmsg_errno;
1972 file_exists(const char *fname)
1974 ws_statb64 file_stat;
1982 * This is a bit tricky on win32. The st_ino field is documented as:
1983 * "The inode, and therefore st_ino, has no meaning in the FAT, ..."
1984 * but it *is* set to zero if stat() returns without an error,
1985 * so this is working, but maybe not quite the way expected. ULFL
1987 file_stat.st_ino = 1; /* this will make things work if an error occurred */
1988 ws_stat64(fname, &file_stat);
1989 if (file_stat.st_ino == 0) {
1995 if (ws_stat64(fname, &file_stat) != 0 && errno == ENOENT) {
2004 * Check that the from file is not the same as to file
2005 * We do it here so we catch all cases ...
2006 * Unfortunately, the file requester gives us an absolute file
2007 * name and the read file name may be relative (if supplied on
2008 * the command line), so we can't just compare paths. From Joerg Mayer.
2011 files_identical(const char *fname1, const char *fname2)
2013 /* Two different implementations, because:
2015 * - _fullpath is not available on UN*X, so we can't get full
2016 * paths and compare them (which wouldn't work with hard links
2019 * - st_ino isn't filled in with a meaningful value on Windows.
2022 char full1[MAX_PATH], full2[MAX_PATH];
2025 * Get the absolute full paths of the file and compare them.
2026 * That won't work if you have hard links, but those aren't
2027 * much used on Windows, even though NTFS supports them.
2029 * XXX - will _fullpath work with UNC?
2031 if( _fullpath( full1, fname1, MAX_PATH ) == NULL ) {
2035 if( _fullpath( full2, fname2, MAX_PATH ) == NULL ) {
2039 if(strcmp(full1, full2) == 0) {
2045 ws_statb64 filestat1, filestat2;
2048 * Compare st_dev and st_ino.
2050 if (ws_stat64(fname1, &filestat1) == -1)
2051 return FALSE; /* can't get info about the first file */
2052 if (ws_stat64(fname2, &filestat2) == -1)
2053 return FALSE; /* can't get info about the second file */
2054 return (filestat1.st_dev == filestat2.st_dev &&
2055 filestat1.st_ino == filestat2.st_ino);
2060 * Copy a file in binary mode, for those operating systems that care about
2061 * such things. This should be OK for all files, even text files, as
2062 * we'll copy the raw bytes, and we don't look at the bytes as we copy
2065 * Returns TRUE on success, FALSE on failure. If a failure, it also
2066 * displays a simple dialog window with the error message.
2069 copy_file_binary_mode(const char *from_filename, const char *to_filename)
2071 int from_fd, to_fd, err;
2072 ssize_t nread, nwritten;
2075 /* Copy the raw bytes of the file. */
2076 from_fd = ws_open(from_filename, O_RDONLY | O_BINARY, 0000 /* no creation so don't matter */);
2078 report_open_failure(from_filename, errno, FALSE);
2082 /* Use open() instead of creat() so that we can pass the O_BINARY
2083 flag, which is relevant on Win32; it appears that "creat()"
2084 may open the file in text mode, not binary mode, but we want
2085 to copy the raw bytes of the file, so we need the output file
2086 to be open in binary mode. */
2087 to_fd = ws_open(to_filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644);
2089 report_open_failure(to_filename, errno, TRUE);
2094 #define FS_READ_SIZE 65536
2095 pd = (guint8 *)g_malloc(FS_READ_SIZE);
2096 while ((nread = ws_read(from_fd, pd, FS_READ_SIZE)) > 0) {
2097 nwritten = ws_write(to_fd, pd, nread);
2098 if (nwritten < nread) {
2102 err = WTAP_ERR_SHORT_WRITE;
2103 report_write_failure(to_filename, err);
2111 report_read_failure(from_filename, err);
2117 if (ws_close(to_fd) < 0) {
2118 report_write_failure(to_filename, errno);
2137 * indent-tabs-mode: nil
2140 * ex: set shiftwidth=4 tabstop=8 expandtab:
2141 * :indentSize=4:tabSize=8:noTabs=true: