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.
52 #ifdef HAVE_SYS_STAT_H
60 #include <wsutil/unicode-utils.h>
63 #include <mach-o/dyld.h>
66 #include <sys/utsname.h>
69 #include <sys/types.h>
70 #include <sys/sysctl.h>
78 #include "filesystem.h"
79 #include <wsutil/report_err.h>
80 #include <wsutil/privileges.h>
81 #include <wsutil/file_util.h>
83 #include <wiretap/wtap.h> /* for WTAP_ERR_SHORT_WRITE */
85 #define PROFILES_DIR "profiles"
86 #define PLUGINS_DIR_NAME "plugins"
88 #define U3_MY_CAPTURES "\\My Captures"
90 char *persconffile_dir = NULL;
91 char *persdatafile_dir = NULL;
92 char *persconfprofile = NULL;
94 static gboolean do_store_persconffiles = FALSE;
95 static GHashTable *profile_files = NULL;
98 * Given a pathname, return a pointer to the last pathname separator
99 * character in the pathname, or NULL if the pathname contains no
103 find_last_pathname_separator(const char *path)
111 * We have to scan for '\' or '/'.
112 * Get to the end of the string.
114 separator = strchr(path, '\0'); /* points to ending '\0' */
115 while (separator > path) {
117 if (c == '\\' || c == '/')
118 return separator; /* found it */
122 * OK, we didn't find any, so no directories - but there might
123 * be a drive letter....
125 return strchr(path, ':');
127 separator = strrchr(path, '/');
133 * Given a pathname, return the last component.
136 get_basename(const char *path)
138 const char *filename;
140 g_assert(path != NULL);
141 filename = find_last_pathname_separator(path);
142 if (filename == NULL) {
144 * There're no directories, drive letters, etc. in the
145 * name; the pathname *is* the file name.
150 * Skip past the pathname or drive letter separator.
158 * Given a pathname, return a string containing everything but the
159 * last component. NOTE: this overwrites the pathname handed into
163 get_dirname(char *path)
167 g_assert(path != NULL);
168 separator = find_last_pathname_separator(path);
169 if (separator == NULL) {
171 * There're no directories, drive letters, etc. in the
172 * name; there is no directory path to return.
178 * Get rid of the last pathname separator and the final file
184 * "path" now contains the pathname of the directory containing
185 * the file/directory to which it referred.
191 * Given a pathname, return:
193 * the errno, if an attempt to "stat()" the file fails;
195 * EISDIR, if the attempt succeeded and the file turned out
198 * 0, if the attempt succeeded and the file turned out not
203 * Visual C++ on Win32 systems doesn't define these. (Old UNIX systems don't
204 * define them either.)
206 * Visual C++ on Win32 systems doesn't define S_IFIFO, it defines _S_IFIFO.
209 #define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG)
212 #define S_IFIFO _S_IFIFO
215 #define S_ISFIFO(mode) (((mode) & S_IFMT) == S_IFIFO)
218 #define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
222 test_for_directory(const char *path)
226 if (ws_stat64(path, &statb) < 0)
229 if (S_ISDIR(statb.st_mode))
236 test_for_fifo(const char *path)
240 if (ws_stat64(path, &statb) < 0)
243 if (S_ISFIFO(statb.st_mode))
250 * Directory from which the executable came.
252 static char *progfile_dir;
256 * Directory of the application bundle in which we're contained,
257 * if we're contained in an application bundle. Otherwise, NULL.
259 * Note: Table 2-5 "Subdirectories of the Contents directory" of
261 * https://developer.apple.com/library/mac/documentation/CoreFoundation/Conceptual/CFBundles/BundleTypes/BundleTypes.html#//apple_ref/doc/uid/10000123i-CH101-SW1
263 * says that the "Frameworks" directory
265 * Contains any private shared libraries and frameworks used by the
266 * executable. The frameworks in this directory are revision-locked
267 * to the application and cannot be superseded by any other, even
268 * newer, versions that may be available to the operating system. In
269 * other words, the frameworks included in this directory take precedence
270 * over any other similarly named frameworks found in other parts of
271 * the operating system. For information on how to add private
272 * frameworks to your application bundle, see Framework Programming Guide.
274 * so if we were to ship with any frameworks (e.g. Qt) we should
275 * perhaps put them in a Frameworks directory rather than under
278 * It also says that the "PlugIns" directory
280 * Contains loadable bundles that extend the basic features of your
281 * application. You use this directory to include code modules that
282 * must be loaded into your applicationbs process space in order to
283 * be used. You would not use this directory to store standalone
286 * Our plugins are just raw .so/.dylib files; I don't know whether by
287 * "bundles" they mean application bundles (i.e., directory hierarchies)
288 * or just "bundles" in the Mach-O sense (which are an image type that
289 * can be loaded with dlopen() but not linked as libraries; our plugins
290 * are, I think, built as dylibs and can be loaded either way).
292 * And it says that the "SharedSupport" directory
294 * Contains additional non-critical resources that do not impact the
295 * ability of the application to run. You might use this directory to
296 * include things like document templates, clip art, and tutorials
297 * that your application expects to be present but that do not affect
298 * the ability of your application to run.
300 * I don't think I'd put the files that currently go under Resources/share
301 * into that category; they're not, for example, sample Lua scripts that
302 * don't actually get run by Wireshark, they're configuration/data files
303 * for Wireshark whose absence might not prevent Wireshark from running
304 * but that would affect how it behaves when run.
306 static char *appbundle_dir;
310 * TRUE if we're running from the build directory and we aren't running
311 * with special privileges.
313 static gboolean running_in_build_directory_flag = FALSE;
317 * Get the pathname of the executable using various platform-
318 * dependent mechanisms for various UN*Xes.
320 * These calls all should return something independent of the argv[0]
321 * passed to the program, so it shouldn't be fooled by an argv[0]
322 * that doesn't match the executable path.
324 * Sadly, not all UN*Xes necessarily have dladdr(), and those that
325 * do don't necessarily have dladdr(main) return information about
326 * the executable image, and those that do aren't necessarily running
327 * on a platform wherein the executable image can get its own path
328 * from the kernel (either by a call or by it being handed to it along
329 * with argv[] and the environment), and those that can don't
330 * necessarily use that to supply the path you get from dladdr(main),
331 * so we try this first and, if that fails, use dladdr(main) if
334 * In particular, some dynamic linkers supply a dladdr() such that
335 * dladdr(main) just returns something derived from argv[0], so
336 * just using dladdr(main) is the wrong thing to do if there's
337 * another mechanism that can get you a more reliable version of
338 * the executable path.
340 * However, at least in newer versions of DragonFly BSD, the dynamic
341 * linker *does* get it from the aux vector passed to the program
342 * by the kernel, readlink /proc/curproc/file - which came first?
344 * On OpenBSD, dladdr(main) returns a value derived from argv[0],
345 * and there doesn't appear to be any way to get the executable path
346 * from the kernel, so we're out of luck there.
348 * So, on platforms where some versions have a version of dladdr()
349 * that gives an argv[0]-based path and that also have a mechanism
350 * to get a more reliable version of the path, we try that. On
351 * other platforms, we return NULL. If our caller gets back a NULL
352 * from us, it falls back on dladdr(main) if dladdr() is available,
353 * and if that fails or is unavailable, it falls back on processing
356 * This is not guaranteed to return an absolute path; if it doesn't,
357 * our caller must prepend the current directory if it's a path.
359 * This is not guaranteed to return the "real path"; it might return
360 * something with symbolic links in the path. Our caller must
361 * use realpath() if they want the real thing, but that's also true of
362 * something obtained by looking at argv[0].
365 get_executable_path(void)
367 #if defined(__APPLE__)
368 char *executable_path;
369 uint32_t path_buf_size;
371 path_buf_size = PATH_MAX;
372 executable_path = (char *)g_malloc(path_buf_size);
373 if (_NSGetExecutablePath(executable_path, &path_buf_size) == -1) {
374 executable_path = (char *)g_realloc(executable_path, path_buf_size);
375 if (_NSGetExecutablePath(executable_path, &path_buf_size) == -1)
378 return executable_path;
379 #elif defined(__linux__)
381 * In older versions of GNU libc's dynamic linker, as used on Linux,
382 * dladdr(main) supplies a path based on argv[0], so we use
383 * /proc/self/exe instead; there are Linux distributions with
384 * kernels that support /proc/self/exe and those older versions
385 * of the dynamic linker, and this will get a better answer on
388 * It only works on Linux 2.2 or later, so we just give up on
391 * XXX - are there OS versions that support "exe" but not "self"?
394 static char executable_path[PATH_MAX];
396 if (uname(&name) == -1)
398 if (strncmp(name.release, "1.", 2) == 0)
399 return NULL; /* Linux 1.x */
400 if (strcmp(name.release, "2.0") == 0 ||
401 strncmp(name.release, "2.0.", 4) == 0 ||
402 strcmp(name.release, "2.1") == 0 ||
403 strncmp(name.release, "2.1.", 4) == 0)
404 return NULL; /* Linux 2.0.x or 2.1.x */
405 if (readlink("/proc/self/exe", executable_path, sizeof executable_path) == -1)
407 return executable_path;
408 #elif defined(__FreeBSD__) && defined(KERN_PROC_PATHNAME)
410 * In older versions of FreeBSD's dynamic linker, dladdr(main)
411 * supplies a path based on argv[0], so we use the KERN_PROC_PATHNAME
412 * sysctl instead; there are, I think, versions of FreeBSD
413 * that support the sysctl that have and those older versions
414 * of the dynamic linker, and this will get a better answer on
418 char *executable_path;
419 size_t path_buf_size;
423 mib[2] = KERN_PROC_PATHNAME;
425 path_buf_size = PATH_MAX;
426 executable_path = (char *)g_malloc(path_buf_size);
427 if (sysctl(mib, 4, executable_path, &path_buf_size, NULL, 0) == -1) {
430 executable_path = (char *)g_realloc(executable_path, path_buf_size);
431 if (sysctl(mib, 4, executable_path, &path_buf_size, NULL, 0) == -1)
434 return executable_path;
435 #elif defined(__NetBSD__)
437 * In all versions of NetBSD's dynamic linker as of 2013-08-12,
438 * dladdr(main) supplies a path based on argv[0], so we use
439 * /proc/curproc/exe instead.
441 * XXX - are there OS versions that support "exe" but not "curproc"
442 * or "self"? Are there any that support "self" but not "curproc"?
444 static char executable_path[PATH_MAX];
446 if (readlink("/proc/curproc/exe", executable_path, sizeof executable_path) == -1)
448 return executable_path;
449 #elif defined(__DragonFly__)
451 * In older versions of DragonFly BSD's dynamic linker, dladdr(main)
452 * supplies a path based on argv[0], so we use /proc/curproc/file
453 * instead; it appears to be supported by all versions of DragonFly
456 static char executable_path[PATH_MAX];
458 if (readlink("/proc/curproc/file", executable_path, sizeof executable_path) == -1)
460 return executable_path;
461 #elif (defined(sun) || defined(__sun)) && defined(HAVE_GETEXECNAME)
463 * It appears that getexecname() dates back to at least Solaris 8,
464 * but /proc/{pid}/path is first documented in the Solaris 10 documentation,
465 * so we use getexecname() if available, rather than /proc/self/path/a.out
466 * (which isn't documented, but appears to be a symlink to the
467 * executable image file).
469 return getexecname();
471 /* Fill in your favorite UN*X's code here, if there is something */
478 * Get the pathname of the directory from which the executable came,
479 * and save it for future use. Returns NULL on success, and a
480 * g_mallocated string containing an error on failure.
483 init_progfile_dir(const char *arg0
487 , int (*main_addr)(int, char **)
488 #if defined(_WIN32) || !defined(HAVE_DLADDR)
494 TCHAR prog_pathname_w[_MAX_PATH+2];
502 * Attempt to get the full pathname of the currently running
505 if (GetModuleFileName(NULL, prog_pathname_w, G_N_ELEMENTS(prog_pathname_w)) != 0 && GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
507 * XXX - Should we use g_utf16_to_utf8(), as in
510 prog_pathname = utf_16to8(prog_pathname_w);
512 * We got it; strip off the last component, which would be
513 * the file name of the executable, giving us the pathname
514 * of the directory where the executable resides.
516 progfile_dir = g_path_get_dirname(prog_pathname);
517 if (progfile_dir != NULL) {
518 return NULL; /* we succeeded */
521 * OK, no. What do we do now?
523 return g_strdup_printf("No \\ in executable pathname \"%s\"",
528 * Oh, well. Return an indication of the error.
530 error = GetLastError();
531 if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,
532 NULL, error, 0, (LPTSTR) &msg_w, 0, NULL) == 0) {
534 * Gak. We can't format the message.
536 return g_strdup_printf("GetModuleFileName failed: %u (FormatMessage failed: %u)",
537 error, GetLastError());
539 msg = utf_16to8(msg_w);
542 * "FormatMessage()" "helpfully" sticks CR/LF at the
543 * end of the message. Get rid of it.
545 msglen = strlen(msg);
547 msg[msglen - 1] = '\0';
548 msg[msglen - 2] = '\0';
550 return g_strdup_printf("GetModuleFileName failed: %s (%u)",
557 const char *execname;
562 char *path_start, *path_end;
563 size_t path_component_len, path_len;
569 * Check whether WIRESHARK_RUN_FROM_BUILD_DIRECTORY is set in the
570 * environment; if so, set running_in_build_directory_flag if we
571 * weren't started with special privileges. (If we were started
572 * with special privileges, it's not safe to allow the user to point
573 * us to some other directory; running_in_build_directory_flag, when
574 * set, causes us to look for plugins and the like in the build
577 if (getenv("WIRESHARK_RUN_FROM_BUILD_DIRECTORY") != NULL
578 && !started_with_special_privs())
579 running_in_build_directory_flag = TRUE;
581 execname = get_executable_path();
583 if (main_addr != NULL && execname == NULL) {
585 * Try to use dladdr() to find the pathname of the executable.
586 * dladdr() is not guaranteed to give you anything better than
587 * argv[0] (i.e., it might not contain a / at all, much less
588 * being an absolute path), and doesn't appear to do so on
589 * Linux, but on other platforms it could give you an absolute
590 * path and obviate the need for us to determine the absolute
593 if (dladdr((void *)main_addr, &info))
594 execname = info.dli_fname;
597 if (execname == NULL) {
599 * OK, guess based on argv[0].
605 * Try to figure out the directory in which the currently running
606 * program resides, given something purporting to be the executable
607 * name (from dladdr() or from the argv[0] it was started with.
608 * That might be the absolute path of the program, or a path relative
609 * to the current directory of the process that started it, or
610 * just a name for the program if it was started from the command
611 * line and was searched for in $PATH. It's not guaranteed to be
612 * any of those, however, so there are no guarantees....
614 if (execname[0] == '/') {
616 * It's an absolute path.
618 prog_pathname = g_strdup(execname);
619 } else if (strchr(execname, '/') != NULL) {
621 * It's a relative path, with a directory in it.
622 * Get the current directory, and combine it
623 * with that directory.
625 path_max = pathconf(".", _PC_PATH_MAX);
626 if (path_max == -1) {
628 * We have no idea how big a buffer to
629 * allocate for the current directory.
631 return g_strdup_printf("pathconf failed: %s\n",
634 curdir = (char *)g_malloc(path_max);
635 if (getcwd(curdir, path_max) == NULL) {
637 * It failed - give up, and just stick
641 return g_strdup_printf("getcwd failed: %s\n",
644 path = g_strdup_printf("%s/%s", curdir, execname);
646 prog_pathname = path;
649 * It's just a file name.
650 * Search the path for a file with that name
653 prog_pathname = NULL; /* haven't found it yet */
654 pathstr = getenv("PATH");
655 path_start = pathstr;
656 if (path_start != NULL) {
657 while (*path_start != '\0') {
658 path_end = strchr(path_start, ':');
659 if (path_end == NULL)
660 path_end = path_start + strlen(path_start);
661 path_component_len = path_end - path_start;
662 path_len = path_component_len + 1
663 + strlen(execname) + 1;
664 path = (char *)g_malloc(path_len);
665 memcpy(path, path_start, path_component_len);
666 path[path_component_len] = '\0';
667 g_strlcat(path, "/", path_len);
668 g_strlcat(path, execname, path_len);
669 if (access(path, X_OK) == 0) {
673 prog_pathname = path;
678 * That's not it. If there are more
679 * path components to test, try them.
681 if (*path_end == '\0') {
683 * There's nothing more to try.
687 if (*path_end == ':')
689 path_start = path_end;
692 if (prog_pathname == NULL) {
694 * Program not found in path.
696 return g_strdup_printf("\"%s\" not found in \"%s\"",
702 * XXX - should we pick a default?
704 return g_strdup("PATH isn't set");
709 * OK, we have what we think is the pathname
712 * First, find the last "/" in the directory,
713 * as that marks the end of the directory pathname.
715 dir_end = strrchr(prog_pathname, '/');
716 if (dir_end != NULL) {
718 * Found it. Strip off the last component,
719 * as that's the path of the program.
724 * Is there a "/.libs" at the end?
726 dir_end = strrchr(prog_pathname, '/');
727 if (dir_end != NULL) {
728 if (strcmp(dir_end, "/.libs") == 0) {
731 * Strip that off; it's an
732 * artifact of libtool.
737 * This presumably means we're run from
738 * the libtool wrapper, which probably
739 * means we're being run from the build
740 * directory. If we weren't started
741 * with special privileges, set
742 * running_in_build_directory_flag.
744 * XXX - should we check whether what
745 * follows ".libs/" begins with "lt-"?
747 if (!started_with_special_privs())
748 running_in_build_directory_flag = TRUE;
752 if (!started_with_special_privs()) {
754 * Scan up the path looking for a component
755 * named "Contents". If we find it, we assume
756 * we're in a bundle, and that the top-level
757 * directory of the bundle is the one containing
760 * Not all executables are in the Contents/MacOS
761 * directory, so we can't just check for those
762 * in the path and strip them off.
764 * XXX - should we assume that it's either
765 * Contents/MacOS or Resources/bin?
767 char *component_end, *p;
769 component_end = strchr(prog_pathname, '\0');
772 while (p >= prog_pathname && *p != '/')
774 if (p == prog_pathname) {
776 * We're looking at the first component of
777 * the pathname now, so we're definitely
778 * not in a bundle, even if we're in
783 if (strncmp(p, "/Contents", component_end - p) == 0) {
785 appbundle_dir = (char *)g_malloc(p - prog_pathname + 1);
786 memcpy(appbundle_dir, prog_pathname, p - prog_pathname);
787 appbundle_dir[p - prog_pathname] = '\0';
799 * OK, we have the path we want.
801 progfile_dir = prog_pathname;
805 * This "shouldn't happen"; we apparently
806 * have no "/" in the pathname.
807 * Just free up prog_pathname.
809 retstr = g_strdup_printf("No / found in \"%s\"", prog_pathname);
810 g_free(prog_pathname);
817 * Get the directory in which the program resides.
820 get_progfile_dir(void)
826 * Get the directory in which the global configuration and data files are
829 * On Windows, we use the directory in which the executable for this
832 * On UN*X, we use the DATAFILE_DIR value supplied by the configure
833 * script, unless we think we're being run from the build directory,
834 * in which case we use the directory in which the executable for this
837 * XXX - if we ever make libwireshark a real library, used by multiple
838 * applications (more than just TShark and versions of Wireshark with
839 * various UIs), should the configuration files belong to the library
840 * (and be shared by all those applications) or to the applications?
842 * If they belong to the library, that could be done on UNIX by the
843 * configure script, but it's trickier on Windows, as you can't just
844 * use the pathname of the executable.
846 * If they belong to the application, that could be done on Windows
847 * by using the pathname of the executable, but we'd have to have it
848 * passed in as an argument, in some call, on UNIX.
850 * Note that some of those configuration files might be used by code in
851 * libwireshark, some of them might be used by dissectors (would they
852 * belong to libwireshark, the application, or a separate library?),
853 * and some of them might be used by other code (the Wireshark preferences
854 * file includes resolver preferences that control the behavior of code
855 * in libwireshark, dissector preferences, and UI preferences, for
859 get_datafile_dir(void)
862 char *u3deviceexecpath;
864 static const char *datafile_dir = NULL;
866 if (datafile_dir != NULL)
871 * See if we are running in a U3 environment.
873 u3deviceexecpath = getenv_utf8("U3_DEVICE_EXEC_PATH");
875 if (u3deviceexecpath != NULL) {
877 * We are; use the U3 device executable path.
879 datafile_dir = u3deviceexecpath;
882 * Do we have the pathname of the program? If so, assume we're
883 * running an installed version of the program. If we fail,
884 * we don't change "datafile_dir", and thus end up using the
887 * XXX - does NSIS put the installation directory into
888 * "\HKEY_LOCAL_MACHINE\SOFTWARE\Wireshark\InstallDir"?
889 * If so, perhaps we should read that from the registry,
892 if (progfile_dir != NULL) {
894 * Yes, we do; use that.
896 datafile_dir = progfile_dir;
900 * Fall back on the default installation directory.
902 datafile_dir = "C:\\Program Files\\Wireshark\\";
907 if (running_in_build_directory_flag) {
909 * We're (probably) being run from the build directory and
910 * weren't started with special privileges.
912 * (running_in_build_directory_flag is never set to TRUE
913 * if we're started with special privileges, so we need
914 * only check it; we don't need to call started_with_special_privs().)
916 * Use the top-level source directory as the datafile directory
917 * because most of our data files (radius/, COPYING) are there.
919 datafile_dir = g_strdup(TOP_SRCDIR);
922 if (getenv("WIRESHARK_DATA_DIR") && !started_with_special_privs()) {
924 * The user specified a different directory for data files
925 * and we aren't running with special privileges.
926 * XXX - We might be able to dispense with the priv check
928 datafile_dir = g_strdup(getenv("WIRESHARK_DATA_DIR"));
932 * If we're running from an app bundle and weren't started
933 * with special privileges, use the Contents/Resources/share/wireshark
934 * subdirectory of the app bundle.
936 * (appbundle_dir is not set to a non-null value if we're
937 * started with special privileges, so we need only check
938 * it; we don't need to call started_with_special_privs().)
940 else if (appbundle_dir != NULL) {
941 datafile_dir = g_strdup_printf("%s/Contents/Resources/share/wireshark",
946 datafile_dir = DATAFILE_DIR;
956 * Find the directory where the python dissectors are stored.
958 * On Windows, we use the "py_dissector" subdirectory of the datafile directory.
960 * On UN*X, we use the PYTHON_DIR value supplied by the configure
961 * script, unless we think we're being run from the build directory,
962 * in which case we use the "py_dissector" subdirectory of the datafile directory.
964 * In both cases, we then use the subdirectory of that directory whose
965 * name is the version number.
967 * XXX - if we think we're being run from the build directory, perhaps we
968 * should have the plugin code not look in the version subdirectory
969 * of the plugin directory, but look in all of the subdirectories
970 * of the plugin directory, so it can just fetch the plugins built
971 * as part of the build process.
973 static const char *wspython_dir = NULL;
976 init_wspython_dir(void)
980 * On Windows, the data file directory is the installation
981 * directory; the python dissectors are stored under it.
983 * Assume we're running the installed version of Wireshark;
984 * on Windows, the data file directory is the directory
985 * in which the Wireshark binary resides.
987 wspython_dir = g_strdup_printf("%s\\python\\%s", get_datafile_dir(),
991 * Make sure that pathname refers to a directory.
993 if (test_for_directory(wspython_dir) != EISDIR) {
995 * Either it doesn't refer to a directory or it
996 * refers to something that doesn't exist.
998 * Assume that means we're running a version of
999 * Wireshark we've built in a build directory,
1000 * in which case {datafile dir}\python is the
1001 * top-level plugins source directory, and use
1002 * that directory and set the "we're running in
1003 * a build directory" flag, so the plugin
1004 * scanner will check all subdirectories of that
1005 * directory for python dissectors.
1007 g_free( (gpointer) wspython_dir);
1008 wspython_dir = g_strdup_printf("%s\\python", get_datafile_dir());
1009 running_in_build_directory_flag = TRUE;
1012 if (running_in_build_directory_flag) {
1014 * We're (probably) being run from the build directory and
1015 * weren't started with special privileges, so we'll use
1016 * the "python" subdirectory of the datafile directory
1017 * (the datafile directory is the build directory).
1019 wspython_dir = g_strdup_printf("%s/epan/wspython/", get_datafile_dir());
1021 if (getenv("WIRESHARK_PYTHON_DIR") && !started_with_special_privs()) {
1023 * The user specified a different directory for plugins
1024 * and we aren't running with special privileges.
1026 wspython_dir = g_strdup(getenv("WIRESHARK_PYTHON_DIR"));
1030 * If we're running from an app bundle and weren't started
1031 * with special privileges, use the Contents/Resources/lib/wireshark/python
1032 * subdirectory of the app bundle.
1034 * (appbundle_dir is not set to a non-null value if we're
1035 * started with special privileges, so we need only check
1036 * it; we don't need to call started_with_special_privs().)
1038 else if (appbundle_dir != NULL) {
1039 wspython_dir = g_strdup_printf("%s/Contents/Resources/lib/wireshark/python",
1044 wspython_dir = PYTHON_DIR;
1049 #endif /* HAVE_PYTHON */
1052 * Get the directory in which the python dissectors are stored.
1055 get_wspython_dir(void)
1058 if (!wspython_dir) init_wspython_dir();
1059 return wspython_dir;
1066 #if defined(HAVE_PLUGINS) || defined(HAVE_LUA)
1068 * Find the directory where the plugins are stored.
1070 * On Windows, we use the "plugin" subdirectory of the datafile directory.
1072 * On UN*X, we use the PLUGIN_DIR value supplied by the configure
1073 * script, unless we think we're being run from the build directory,
1074 * in which case we use the "plugin" subdirectory of the datafile directory.
1076 * In both cases, we then use the subdirectory of that directory whose
1077 * name is the version number.
1079 * XXX - if we think we're being run from the build directory, perhaps we
1080 * should have the plugin code not look in the version subdirectory
1081 * of the plugin directory, but look in all of the subdirectories
1082 * of the plugin directory, so it can just fetch the plugins built
1083 * as part of the build process.
1085 static const char *plugin_dir = NULL;
1088 init_plugin_dir(void)
1092 * On Windows, the data file directory is the installation
1093 * directory; the plugins are stored under it.
1095 * Assume we're running the installed version of Wireshark;
1096 * on Windows, the data file directory is the directory
1097 * in which the Wireshark binary resides.
1099 plugin_dir = g_strdup_printf("%s\\plugins\\%s", get_datafile_dir(),
1103 * Make sure that pathname refers to a directory.
1105 if (test_for_directory(plugin_dir) != EISDIR) {
1107 * Either it doesn't refer to a directory or it
1108 * refers to something that doesn't exist.
1110 * Assume that means we're running a version of
1111 * Wireshark we've built in a build directory,
1112 * in which case {datafile dir}\plugins is the
1113 * top-level plugins source directory, and use
1114 * that directory and set the "we're running in
1115 * a build directory" flag, so the plugin
1116 * scanner will check all subdirectories of that
1117 * directory for plugins.
1119 g_free( (gpointer) plugin_dir);
1120 plugin_dir = g_strdup_printf("%s\\plugins", get_datafile_dir());
1121 running_in_build_directory_flag = TRUE;
1124 if (running_in_build_directory_flag) {
1126 * We're (probably) being run from the build directory and
1127 * weren't started with special privileges, so we'll use
1128 * the "plugins" subdirectory of the directory where the program
1129 * we're running is (that's the build directory).
1131 plugin_dir = g_strdup_printf("%s/plugins", get_progfile_dir());
1133 if (getenv("WIRESHARK_PLUGIN_DIR") && !started_with_special_privs()) {
1135 * The user specified a different directory for plugins
1136 * and we aren't running with special privileges.
1138 plugin_dir = g_strdup(getenv("WIRESHARK_PLUGIN_DIR"));
1142 * If we're running from an app bundle and weren't started
1143 * with special privileges, use the Contents/Resources/lib/wireshark/plugins
1144 * subdirectory of the app bundle.
1146 * (appbundle_dir is not set to a non-null value if we're
1147 * started with special privileges, so we need only check
1148 * it; we don't need to call started_with_special_privs().)
1150 else if (appbundle_dir != NULL) {
1151 plugin_dir = g_strdup_printf("%s/Contents/Resources/lib/wireshark/plugins",
1156 plugin_dir = PLUGIN_DIR;
1161 #endif /* HAVE_PLUGINS || HAVE_LUA */
1164 * Get the directory in which the plugins are stored.
1167 get_plugin_dir(void)
1169 #if defined(HAVE_PLUGINS) || defined(HAVE_LUA)
1170 if (!plugin_dir) init_plugin_dir();
1178 * Get the flag indicating whether we're running from a build
1182 running_in_build_directory(void)
1184 return running_in_build_directory_flag;
1188 * Get the directory in which files that, at least on UNIX, are
1189 * system files (such as "/etc/ethers") are stored; on Windows,
1190 * there's no "/etc" directory, so we get them from the global
1191 * configuration and data file directory.
1194 get_systemfile_dir(void)
1197 return get_datafile_dir();
1204 * Name of directory, under the user's home directory, in which
1205 * personal configuration files are stored.
1208 #define PF_DIR "Wireshark"
1211 * XXX - should this be ".libepan"? For backwards-compatibility, I'll keep
1212 * it ".wireshark" for now.
1214 #define PF_DIR ".wireshark"
1218 set_profile_name(const gchar *profilename)
1220 g_free (persconfprofile);
1222 if (profilename && strlen(profilename) > 0 &&
1223 strcmp(profilename, DEFAULT_PROFILE) != 0) {
1224 persconfprofile = g_strdup (profilename);
1226 /* Default Profile */
1227 persconfprofile = NULL;
1232 get_profile_name(void)
1234 if (persconfprofile) {
1235 return persconfprofile;
1237 return DEFAULT_PROFILE;
1242 is_default_profile(void)
1244 return (!persconfprofile || strcmp(persconfprofile, DEFAULT_PROFILE) == 0) ? TRUE : FALSE;
1248 has_global_profiles(void)
1252 const gchar *global_dir = get_global_profiles_dir();
1254 gboolean has_global = FALSE;
1256 if ((test_for_directory(global_dir) == EISDIR) &&
1257 ((dir = ws_dir_open(global_dir, 0, NULL)) != NULL))
1259 while ((file = ws_dir_read_name(dir)) != NULL) {
1260 filename = g_strdup_printf ("%s%s%s", global_dir, G_DIR_SEPARATOR_S,
1261 ws_dir_get_name(file));
1262 if (test_for_directory(filename) == EISDIR) {
1276 profile_store_persconffiles(gboolean store)
1279 profile_files = g_hash_table_new (g_str_hash, g_str_equal);
1281 do_store_persconffiles = store;
1285 * Get the directory in which personal configuration files reside;
1286 * in UNIX-compatible systems, it's ".wireshark", under the user's home
1287 * directory, and on Windows systems, it's "Wireshark", under %APPDATA%
1288 * or, if %APPDATA% isn't set, it's "%USERPROFILE%\Application Data"
1289 * (which is what %APPDATA% normally is on Windows 2000).
1292 get_persconffile_dir_no_profile(void)
1296 char *userprofiledir;
1297 char *altappdatapath;
1299 const char *homedir;
1303 /* Return the cached value, if available */
1304 if (persconffile_dir != NULL)
1305 return persconffile_dir;
1309 * See if the user has selected an alternate environment.
1311 altappdatapath = getenv_utf8("WIRESHARK_APPDATA");
1312 if (altappdatapath != NULL) {
1313 persconffile_dir = altappdatapath;
1314 return persconffile_dir;
1318 * See if we are running in a U3 environment.
1320 altappdatapath = getenv_utf8("U3_APP_DATA_PATH");
1321 if (altappdatapath != NULL) {
1323 * We are; use the U3 application data path.
1325 persconffile_dir = altappdatapath;
1328 * Use %APPDATA% or %USERPROFILE%, so that configuration
1329 * files are stored in the user profile, rather than in
1330 * the home directory. The Windows convention is to store
1331 * configuration information in the user profile, and doing
1332 * so means you can use Wireshark even if the home directory
1333 * is an inaccessible network drive.
1335 appdatadir = getenv_utf8("APPDATA");
1336 if (appdatadir != NULL) {
1338 * Concatenate %APPDATA% with "\Wireshark".
1340 persconffile_dir = g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s",
1341 appdatadir, PF_DIR);
1344 * OK, %APPDATA% wasn't set, so use
1345 * %USERPROFILE%\Application Data.
1347 userprofiledir = getenv_utf8("USERPROFILE");
1348 if (userprofiledir != NULL) {
1349 persconffile_dir = g_strdup_printf(
1350 "%s" G_DIR_SEPARATOR_S "Application Data" G_DIR_SEPARATOR_S "%s",
1351 userprofiledir, PF_DIR);
1354 * Give up and use "C:".
1356 persconffile_dir = g_strdup_printf("C:" G_DIR_SEPARATOR_S "%s", PF_DIR);
1362 * If $HOME is set, use that.
1364 homedir = getenv("HOME");
1365 if (homedir == NULL) {
1367 * Get their home directory from the password file.
1368 * If we can't even find a password file entry for them,
1371 pwd = getpwuid(getuid());
1373 homedir = pwd->pw_dir;
1378 persconffile_dir = g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s", homedir, PF_DIR);
1381 return persconffile_dir;
1385 set_persconffile_dir(const char *p)
1387 g_free(persconffile_dir);
1388 persconffile_dir = g_strdup(p);
1392 get_profiles_dir(void)
1394 static char *profiles_dir = NULL;
1396 g_free (profiles_dir);
1397 profiles_dir = g_strdup_printf ("%s%s%s", get_persconffile_dir_no_profile (),
1398 G_DIR_SEPARATOR_S, PROFILES_DIR);
1400 return profiles_dir;
1404 get_global_profiles_dir(void)
1406 static char *global_profiles_dir = NULL;
1408 if (!global_profiles_dir) {
1409 global_profiles_dir = g_strdup_printf ("%s%s%s", get_datafile_dir(),
1410 G_DIR_SEPARATOR_S, PROFILES_DIR);
1413 return global_profiles_dir;
1417 get_persconffile_dir(const gchar *profilename)
1419 static char *persconffile_profile_dir = NULL;
1421 g_free (persconffile_profile_dir);
1423 if (profilename && strlen(profilename) > 0 &&
1424 strcmp(profilename, DEFAULT_PROFILE) != 0) {
1425 persconffile_profile_dir = g_strdup_printf ("%s%s%s", get_profiles_dir (),
1426 G_DIR_SEPARATOR_S, profilename);
1428 persconffile_profile_dir = g_strdup (get_persconffile_dir_no_profile ());
1431 return persconffile_profile_dir;
1435 profile_exists(const gchar *profilename, gboolean global)
1438 gchar *path = g_strdup_printf ("%s%s%s", get_global_profiles_dir(),
1439 G_DIR_SEPARATOR_S, profilename);
1440 if (test_for_directory (path) == EISDIR) {
1446 if (test_for_directory (get_persconffile_dir (profilename)) == EISDIR) {
1455 delete_directory (const char *directory, char **pf_dir_path_return)
1462 if ((dir = ws_dir_open(directory, 0, NULL)) != NULL) {
1463 while ((file = ws_dir_read_name(dir)) != NULL) {
1464 filename = g_strdup_printf ("%s%s%s", directory, G_DIR_SEPARATOR_S,
1465 ws_dir_get_name(file));
1466 if (test_for_directory(filename) != EISDIR) {
1467 ret = ws_remove(filename);
1470 /* The user has manually created a directory in the profile directory */
1471 /* I do not want to delete the directory recursively yet */
1472 ret = delete_directory (filename, pf_dir_path_return);
1476 *pf_dir_path_return = filename;
1484 if (ret == 0 && (ret = ws_remove(directory)) != 0) {
1485 *pf_dir_path_return = g_strdup (directory);
1492 delete_persconffile_profile(const char *profilename, char **pf_dir_path_return)
1494 const char *profile_dir = get_persconffile_dir(profilename);
1497 if (test_for_directory (profile_dir) == EISDIR) {
1498 ret = delete_directory (profile_dir, pf_dir_path_return);
1505 rename_persconffile_profile(const char *fromname, const char *toname,
1506 char **pf_from_dir_path_return, char **pf_to_dir_path_return)
1508 char *from_dir = g_strdup (get_persconffile_dir(fromname));
1509 char *to_dir = g_strdup (get_persconffile_dir(toname));
1512 ret = ws_rename (from_dir, to_dir);
1514 *pf_from_dir_path_return = g_strdup (from_dir);
1515 *pf_to_dir_path_return = g_strdup (to_dir);
1525 * Create the directory that holds personal configuration files, if
1526 * necessary. If we attempted to create it, and failed, return -1 and
1527 * set "*pf_dir_path_return" to the pathname of the directory we failed
1528 * to create (it's g_mallocated, so our caller should free it); otherwise,
1532 create_persconffile_profile(const char *profilename, char **pf_dir_path_return)
1534 const char *pf_dir_path;
1536 char *pf_dir_path_copy, *pf_dir_parent_path;
1537 size_t pf_dir_parent_path_len;
1544 * Create the "Default" personal configuration files directory, if necessary.
1546 if (create_persconffile_profile (NULL, pf_dir_path_return) == -1) {
1551 * Check if profiles directory exists.
1552 * If not then create it.
1554 pf_dir_path = get_profiles_dir ();
1555 if (ws_stat64(pf_dir_path, &s_buf) != 0 && errno == ENOENT) {
1556 ret = ws_mkdir(pf_dir_path, 0755);
1558 *pf_dir_path_return = g_strdup(pf_dir_path);
1564 pf_dir_path = get_persconffile_dir(profilename);
1565 if (ws_stat64(pf_dir_path, &s_buf) != 0 && errno == ENOENT) {
1568 * Does the parent directory of that directory
1569 * exist? %APPDATA% may not exist even though
1570 * %USERPROFILE% does.
1572 * We check for the existence of the directory
1573 * by first checking whether the parent directory
1574 * is just a drive letter and, if it's not, by
1575 * doing a "stat()" on it. If it's a drive letter,
1576 * or if the "stat()" succeeds, we assume it exists.
1578 pf_dir_path_copy = g_strdup(pf_dir_path);
1579 pf_dir_parent_path = get_dirname(pf_dir_path_copy);
1580 pf_dir_parent_path_len = strlen(pf_dir_parent_path);
1581 if (pf_dir_parent_path_len > 0
1582 && pf_dir_parent_path[pf_dir_parent_path_len - 1] != ':'
1583 && ws_stat64(pf_dir_parent_path, &s_buf) != 0) {
1585 * No, it doesn't exist - make it first.
1587 ret = ws_mkdir(pf_dir_parent_path, 0755);
1589 *pf_dir_path_return = pf_dir_parent_path;
1593 g_free(pf_dir_path_copy);
1594 ret = ws_mkdir(pf_dir_path, 0755);
1596 ret = ws_mkdir(pf_dir_path, 0755);
1600 * Something with that pathname exists; if it's not
1601 * a directory, we'll get an error if we try to put
1602 * something in it, so we don't fail here, we wait
1603 * for that attempt fo fail.
1608 *pf_dir_path_return = g_strdup(pf_dir_path);
1613 create_persconffile_dir(char **pf_dir_path_return)
1615 return create_persconffile_profile(persconfprofile, pf_dir_path_return);
1619 copy_persconffile_profile(const char *toname, const char *fromname, gboolean from_global,
1620 char **pf_filename_return, char **pf_to_dir_path_return, char **pf_from_dir_path_return)
1623 gchar *to_dir = g_strdup (get_persconffile_dir(toname));
1624 gchar *filename, *from_file, *to_file;
1625 GList *files, *file;
1628 if (strcmp(fromname, DEFAULT_PROFILE) == 0) {
1629 from_dir = g_strdup (get_global_profiles_dir());
1631 from_dir = g_strdup_printf ("%s%s%s", get_global_profiles_dir(), G_DIR_SEPARATOR_S, fromname);
1634 from_dir = g_strdup (get_persconffile_dir(fromname));
1637 files = g_hash_table_get_keys(profile_files);
1638 file = g_list_first(files);
1640 filename = (gchar *)file->data;
1641 from_file = g_strdup_printf ("%s%s%s", from_dir, G_DIR_SEPARATOR_S, filename);
1642 to_file = g_strdup_printf ("%s%s%s", to_dir, G_DIR_SEPARATOR_S, filename);
1644 if (file_exists(from_file) && !copy_file_binary_mode(from_file, to_file)) {
1645 *pf_filename_return = g_strdup(filename);
1646 *pf_to_dir_path_return = to_dir;
1647 *pf_from_dir_path_return = from_dir;
1656 file = g_list_next(file);
1659 g_list_free (files);
1667 * Get the (default) directory in which personal data is stored.
1669 * On Win32, this is the "My Documents" folder in the personal profile,
1670 * except that, if we're running from a U3 device, this is the
1671 * "$U3_DEVICE_DOCUMENT_PATH\My Captures" folder.
1672 * On UNIX this is simply the current directory.
1674 /* XXX - should this and the get_home_dir() be merged? */
1676 get_persdatafile_dir(void)
1679 char *u3devicedocumentpath;
1680 TCHAR tszPath[MAX_PATH];
1682 /* Return the cached value, if available */
1683 if (persdatafile_dir != NULL)
1684 return persdatafile_dir;
1687 * See if we are running in a U3 environment.
1689 u3devicedocumentpath = getenv_utf8("U3_DEVICE_DOCUMENT_PATH");
1691 if (u3devicedocumentpath != NULL) {
1692 /* the "My Captures" sub-directory is created (if it doesn't
1693 exist) by u3util.exe when the U3 Wireshark is first run */
1695 persdatafile_dir = g_strdup_printf("%s%s", u3devicedocumentpath, U3_MY_CAPTURES);
1696 return persdatafile_dir;
1699 * Hint: SHGetFolderPath is not available on MSVC 6 - without
1702 if (SHGetSpecialFolderPath(NULL, tszPath, CSIDL_PERSONAL, FALSE)) {
1703 persdatafile_dir = g_utf16_to_utf8(tszPath, -1, NULL, NULL, NULL);
1704 return persdatafile_dir;
1715 set_persdatafile_dir(const char *p)
1717 g_free(persdatafile_dir);
1718 persdatafile_dir = g_strdup(p);
1723 * Returns the user's home directory on Win32.
1728 static const char *home = NULL;
1729 char *homedrive, *homepath;
1733 /* Return the cached value, if available */
1738 * XXX - should we use USERPROFILE anywhere in this process?
1739 * Is there a chance that it might be set but one or more of
1740 * HOMEDRIVE or HOMEPATH isn't set?
1742 homedrive = getenv_utf8("HOMEDRIVE");
1743 if (homedrive != NULL) {
1744 homepath = getenv_utf8("HOMEPATH");
1745 if (homepath != NULL) {
1747 * This is cached, so we don't need to worry about
1748 * allocating multiple ones of them.
1750 homestring = g_strdup_printf("%s%s", homedrive, homepath);
1753 * Trim off any trailing slash or backslash.
1755 lastsep = find_last_pathname_separator(homestring);
1756 if (lastsep != NULL && *(lastsep + 1) == '\0') {
1758 * Last separator is the last character
1759 * in the string. Nuke it.
1768 * Give up and use C:.
1778 * Construct the path name of a personal configuration file, given the
1781 * On Win32, if "for_writing" is FALSE, we check whether the file exists
1782 * and, if not, construct a path name relative to the ".wireshark"
1783 * subdirectory of the user's home directory, and check whether that
1784 * exists; if it does, we return that, so that configuration files
1785 * from earlier versions can be read.
1787 * The returned file name was g_malloc()'d so it must be g_free()d when the
1788 * caller is done with it.
1791 get_persconffile_path(const char *filename, gboolean from_profile)
1794 if (do_store_persconffiles && from_profile && !g_hash_table_lookup (profile_files, filename)) {
1795 /* Store filenames so we know which filenames belongs to a configuration profile */
1796 g_hash_table_insert (profile_files, g_strdup(filename), g_strdup(filename));
1800 path = g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s",
1801 get_persconffile_dir(persconfprofile), filename);
1803 path = g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s",
1804 get_persconffile_dir(NULL), filename);
1811 * Construct the path name of a global configuration file, given the
1814 * The returned file name was g_malloc()'d so it must be g_free()d when the
1815 * caller is done with it.
1818 get_datafile_path(const char *filename)
1820 if (running_in_build_directory_flag && !strcmp(filename, "AUTHORS-SHORT")) {
1821 /* We're running in the build directory and the requested file is a
1822 * generated file. Return the file name in the build directory (not
1823 * in the source/data directory).
1825 return g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s", get_progfile_dir(), filename);
1827 return g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s", get_datafile_dir(), filename);
1831 /* Get the personal plugin dir */
1832 /* Return value is malloced so the caller should g_free() it. */
1834 get_plugins_pers_dir(void)
1836 return get_persconffile_path(PLUGINS_DIR_NAME, FALSE);
1840 * Return an error message for UNIX-style errno indications on open or
1841 * create operations.
1844 file_open_error_message(int err, gboolean for_writing)
1847 static char errmsg_errno[1024+1];
1853 errmsg = "The path to the file \"%s\" doesn't exist.";
1855 errmsg = "The file \"%s\" doesn't exist.";
1860 errmsg = "You don't have permission to create or write to the file \"%s\".";
1862 errmsg = "You don't have permission to read the file \"%s\".";
1866 errmsg = "\"%s\" is a directory (folder), not a file.";
1870 errmsg = "The file \"%s\" could not be created because there is no space left on the file system.";
1875 errmsg = "The file \"%s\" could not be created because you are too close to, or over, your disk quota.";
1880 errmsg = "The file \"%s\" could not be created because an invalid filename was specified.";
1885 * The problem probably has nothing to do with how much RAM the
1886 * user has on their machine, so don't confuse them by saying
1887 * "memory". The problem is probably either virtual address
1888 * space or swap space.
1890 #if GLIB_SIZEOF_VOID_P == 4
1892 * ILP32; we probably ran out of virtual address space.
1894 #define ENOMEM_REASON "it can't be handled by a 32-bit application"
1897 * LP64 or LLP64; we probably ran out of swap space.
1901 * You need to make the pagefile bigger.
1903 #define ENOMEM_REASON "the pagefile is too small"
1904 #elif defined(__APPLE__)
1906 * dynamic_pager couldn't, or wouldn't, create more swap files.
1908 #define ENOMEM_REASON "your system ran out of swap file space"
1911 * Either you have a fixed swap partition or a fixed swap file,
1912 * and it needs to be made bigger.
1914 * This is UN*X, but it's not OS X, so we assume the user is
1917 #define ENOMEM_REASON "your system is out of swap space"
1919 #endif /* GLIB_SIZEOF_VOID_P == 4 */
1921 errmsg = "The file \"%s\" could not be created because " ENOMEM_REASON ".";
1923 errmsg = "The file \"%s\" could not be opened because " ENOMEM_REASON ".";
1927 g_snprintf(errmsg_errno, sizeof(errmsg_errno),
1928 "The file \"%%s\" could not be %s: %s.",
1929 for_writing ? "created" : "opened",
1931 errmsg = errmsg_errno;
1938 * Return an error message for UNIX-style errno indications on write
1942 file_write_error_message(int err)
1945 static char errmsg_errno[1024+1];
1950 errmsg = "The file \"%s\" could not be saved because there is no space left on the file system.";
1955 errmsg = "The file \"%s\" could not be saved because you are too close to, or over, your disk quota.";
1960 g_snprintf(errmsg_errno, sizeof(errmsg_errno),
1961 "An error occurred while writing to the file \"%%s\": %s.",
1963 errmsg = errmsg_errno;
1971 file_exists(const char *fname)
1973 ws_statb64 file_stat;
1981 * This is a bit tricky on win32. The st_ino field is documented as:
1982 * "The inode, and therefore st_ino, has no meaning in the FAT, ..."
1983 * but it *is* set to zero if stat() returns without an error,
1984 * so this is working, but maybe not quite the way expected. ULFL
1986 file_stat.st_ino = 1; /* this will make things work if an error occurred */
1987 ws_stat64(fname, &file_stat);
1988 if (file_stat.st_ino == 0) {
1994 if (ws_stat64(fname, &file_stat) != 0 && errno == ENOENT) {
2003 * Check that the from file is not the same as to file
2004 * We do it here so we catch all cases ...
2005 * Unfortunately, the file requester gives us an absolute file
2006 * name and the read file name may be relative (if supplied on
2007 * the command line), so we can't just compare paths. From Joerg Mayer.
2010 files_identical(const char *fname1, const char *fname2)
2012 /* Two different implementations, because:
2014 * - _fullpath is not available on UN*X, so we can't get full
2015 * paths and compare them (which wouldn't work with hard links
2018 * - st_ino isn't filled in with a meaningful value on Windows.
2021 char full1[MAX_PATH], full2[MAX_PATH];
2024 * Get the absolute full paths of the file and compare them.
2025 * That won't work if you have hard links, but those aren't
2026 * much used on Windows, even though NTFS supports them.
2028 * XXX - will _fullpath work with UNC?
2030 if( _fullpath( full1, fname1, MAX_PATH ) == NULL ) {
2034 if( _fullpath( full2, fname2, MAX_PATH ) == NULL ) {
2038 if(strcmp(full1, full2) == 0) {
2044 ws_statb64 filestat1, filestat2;
2047 * Compare st_dev and st_ino.
2049 if (ws_stat64(fname1, &filestat1) == -1)
2050 return FALSE; /* can't get info about the first file */
2051 if (ws_stat64(fname2, &filestat2) == -1)
2052 return FALSE; /* can't get info about the second file */
2053 return (filestat1.st_dev == filestat2.st_dev &&
2054 filestat1.st_ino == filestat2.st_ino);
2059 * Copy a file in binary mode, for those operating systems that care about
2060 * such things. This should be OK for all files, even text files, as
2061 * we'll copy the raw bytes, and we don't look at the bytes as we copy
2064 * Returns TRUE on success, FALSE on failure. If a failure, it also
2065 * displays a simple dialog window with the error message.
2068 copy_file_binary_mode(const char *from_filename, const char *to_filename)
2070 int from_fd, to_fd, err;
2071 ssize_t nread, nwritten;
2074 /* Copy the raw bytes of the file. */
2075 from_fd = ws_open(from_filename, O_RDONLY | O_BINARY, 0000 /* no creation so don't matter */);
2077 report_open_failure(from_filename, errno, FALSE);
2081 /* Use open() instead of creat() so that we can pass the O_BINARY
2082 flag, which is relevant on Win32; it appears that "creat()"
2083 may open the file in text mode, not binary mode, but we want
2084 to copy the raw bytes of the file, so we need the output file
2085 to be open in binary mode. */
2086 to_fd = ws_open(to_filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644);
2088 report_open_failure(to_filename, errno, TRUE);
2093 #define FS_READ_SIZE 65536
2094 pd = (guint8 *)g_malloc(FS_READ_SIZE);
2095 while ((nread = ws_read(from_fd, pd, FS_READ_SIZE)) > 0) {
2096 nwritten = ws_write(to_fd, pd, nread);
2097 if (nwritten < nread) {
2101 err = WTAP_ERR_SHORT_WRITE;
2102 report_write_failure(to_filename, err);
2110 report_read_failure(from_filename, err);
2116 if (ws_close(to_fd) < 0) {
2117 report_write_failure(to_filename, errno);
2136 * indent-tabs-mode: nil
2139 * ex: set shiftwidth=4 tabstop=8 expandtab:
2140 * :indentSize=4:tabSize=8:noTabs=true: