2 * Filesystem utility routines
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 1998 Gerald Combs
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 2
13 * of the License, or (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
30 * Required with GNU libc to get dladdr().
31 * We define it here because <dlfcn.h> apparently gets included by
32 * one of the headers we include below.
56 #ifdef HAVE_SYS_STAT_H
64 #include <wsutil/unicode-utils.h>
66 #ifdef DLADDR_FINDS_EXECUTABLE_PATH
68 #endif /* DLADDR_FINDS_EXECUTABLE_PATH */
72 #include "filesystem.h"
73 #include "report_err.h"
74 #include <wsutil/privileges.h>
75 #include <wsutil/file_util.h>
77 #include <wiretap/wtap.h> /* for WTAP_ERR_SHORT_WRITE */
79 #define PROFILES_DIR "profiles"
80 #define U3_MY_CAPTURES "\\My Captures"
82 char *persconffile_dir = NULL;
83 char *persdatafile_dir = NULL;
84 char *persconfprofile = NULL;
87 * Given a pathname, return a pointer to the last pathname separator
88 * character in the pathname, or NULL if the pathname contains no
92 find_last_pathname_separator(const char *path)
100 * We have to scan for '\' or '/'.
101 * Get to the end of the string.
103 separator = strchr(path, '\0'); /* points to ending '\0' */
104 while (separator > path) {
106 if (c == '\\' || c == '/')
107 return separator; /* found it */
111 * OK, we didn't find any, so no directories - but there might
112 * be a drive letter....
114 return strchr(path, ':');
116 separator = strrchr(path, '/');
122 * Given a pathname, return the last component.
125 get_basename(const char *path)
127 const char *filename;
129 g_assert(path != NULL);
130 filename = find_last_pathname_separator(path);
131 if (filename == NULL) {
133 * There're no directories, drive letters, etc. in the
134 * name; the pathname *is* the file name.
139 * Skip past the pathname or drive letter separator.
147 * Given a pathname, return a string containing everything but the
148 * last component. NOTE: this overwrites the pathname handed into
152 get_dirname(char *path)
156 g_assert(path != NULL);
157 separator = find_last_pathname_separator(path);
158 if (separator == NULL) {
160 * There're no directories, drive letters, etc. in the
161 * name; there is no directory path to return.
167 * Get rid of the last pathname separator and the final file
173 * "path" now contains the pathname of the directory containing
174 * the file/directory to which it referred.
180 * Given a pathname, return:
182 * the errno, if an attempt to "stat()" the file fails;
184 * EISDIR, if the attempt succeeded and the file turned out
187 * 0, if the attempt succeeded and the file turned out not
192 * Visual C++ on Win32 systems doesn't define these. (Old UNIX systems don't
193 * define them either.)
195 * Visual C++ on Win32 systems doesn't define S_IFIFO, it defines _S_IFIFO.
198 #define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG)
201 #define S_IFIFO _S_IFIFO
204 #define S_ISFIFO(mode) (((mode) & S_IFMT) == S_IFIFO)
207 #define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
211 test_for_directory(const char *path)
215 if (ws_stat(path, &statb) < 0)
218 if (S_ISDIR(statb.st_mode))
225 test_for_fifo(const char *path)
229 if (ws_stat(path, &statb) < 0)
232 if (S_ISFIFO(statb.st_mode))
239 * Directory from which the executable came.
241 static char *progfile_dir;
244 * TRUE if we're running from the build directory and we aren't running
245 * with special privileges.
247 static gboolean running_in_build_directory_flag = FALSE;
250 * Get the pathname of the directory from which the executable came,
251 * and save it for future use. Returns NULL on success, and a
252 * g_mallocated string containing an error on failure.
255 init_progfile_dir(const char *arg0
259 , int (*main_addr)(int, char **)
260 #if defined(_WIN32) || !defined(DLADDR_FINDS_EXECUTABLE_PATH)
268 TCHAR prog_pathname_w[_MAX_PATH+2];
269 size_t progfile_dir_len;
277 * Attempt to get the full pathname of the currently running
280 if (GetModuleFileName(NULL, prog_pathname_w, sizeof prog_pathname_w) != 0) {
282 * XXX - Should we use g_utf16_to_utf8(), as in
285 prog_pathname = utf_16to8(prog_pathname_w);
287 * We got it; strip off the last component, which would be
288 * the file name of the executable, giving us the pathname
289 * of the directory where the executable resies
291 * First, find the last "\" in the directory, as that
292 * marks the end of the directory pathname.
294 * XXX - Can the pathname be something such as
295 * "C:wireshark.exe"? Or is it always a full pathname
296 * beginning with "\" after the drive letter?
298 dir_end = strrchr(prog_pathname, '\\');
299 if (dir_end != NULL) {
301 * Found it - now figure out how long the program
302 * directory pathname will be.
304 progfile_dir_len = (dir_end - prog_pathname);
307 * Allocate a buffer for the program directory
308 * pathname, and construct it.
310 path = g_malloc(progfile_dir_len + 1);
311 strncpy(path, prog_pathname, progfile_dir_len);
312 path[progfile_dir_len] = '\0';
315 return NULL; /* we succeeded */
318 * OK, no \ - what do we do now?
320 return g_strdup_printf("No \\ in executable pathname \"%s\"",
325 * Oh, well. Return an indication of the error.
327 error = GetLastError();
328 if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM,
329 NULL, error, 0, (LPTSTR) &msg_w, 0, NULL) == 0) {
331 * Gak. We can't format the message.
333 return g_strdup_printf("GetModuleFileName failed: %u (FormatMessage failed: %u)",
334 error, GetLastError());
336 msg = utf_16to8(msg_w);
339 * "FormatMessage()" "helpfully" sticks CR/LF at the
340 * end of the message. Get rid of it.
342 msglen = strlen(msg);
344 msg[msglen - 1] = '\0';
345 msg[msglen - 2] = '\0';
347 return g_strdup_printf("GetModuleFileName failed: %s (%u)",
351 #ifdef DLADDR_FINDS_EXECUTABLE_PATH
358 char *path_start, *path_end;
359 size_t path_component_len;
363 * Check whether WIRESHARK_RUN_FROM_BUILD_DIRECTORY is set in the
364 * environment; if so, set running_in_build_directory_flag if we
365 * weren't started with special privileges. (If we were started
366 * with special privileges, it's not safe to allow the user to point
367 * us to some other directory; running_in_build_directory_flag, when
368 * set, causes us to look for plugins and the like in the build
371 if (getenv("WIRESHARK_RUN_FROM_BUILD_DIRECTORY") != NULL
372 && !started_with_special_privs())
373 running_in_build_directory_flag = TRUE;
375 #ifdef DLADDR_FINDS_EXECUTABLE_PATH
377 * Try to use dladdr() to find the pathname of the executable.
378 * dladdr() is not guaranteed to give you anything better than
379 * argv[0] (i.e., it might not contain a / at all, much less
380 * being an absolute path), and doesn't appear to do so on
381 * Linux, but on other platforms it could give you an absolute
382 * path and obviate the need for us to determine the absolute
385 if (dladdr((void *)main_addr, &info))
386 arg0 = info.dli_fname;
389 * Try to figure out the directory in which the currently running
390 * program resides, given something purporting to be the executable
391 * name (from dladdr() or from the argv[0] it was started with.
392 * That might be the absolute path of the program, or a path relative
393 * to the current directory of the process that started it, or
394 * just a name for the program if it was started from the command
395 * line and was searched for in $PATH. It's not guaranteed to be
396 * any of those, however, so there are no guarantees....
398 if (arg0[0] == '/') {
400 * It's an absolute path.
402 prog_pathname = g_strdup(arg0);
403 } else if (strchr(arg0, '/') != NULL) {
405 * It's a relative path, with a directory in it.
406 * Get the current directory, and combine it
407 * with that directory.
409 path_max = pathconf(".", _PC_PATH_MAX);
410 if (path_max == -1) {
412 * We have no idea how big a buffer to
413 * allocate for the current directory.
415 return g_strdup_printf("pathconf failed: %s\n",
418 curdir = g_malloc(path_max);
419 if (getcwd(curdir, path_max) == NULL) {
421 * It failed - give up, and just stick
425 return g_strdup_printf("getcwd failed: %s\n",
428 path = g_strdup_printf("%s/%s", curdir, arg0);
430 prog_pathname = path;
433 * It's just a file name.
434 * Search the path for a file with that name
437 prog_pathname = NULL; /* haven't found it yet */
438 pathstr = getenv("PATH");
439 path_start = pathstr;
440 if (path_start != NULL) {
441 while (*path_start != '\0') {
442 path_end = strchr(path_start, ':');
443 if (path_end == NULL)
444 path_end = path_start + strlen(path_start);
445 path_component_len = path_end - path_start;
446 path = g_malloc(path_component_len + 1
448 memcpy(path, path_start, path_component_len);
449 path[path_component_len] = '\0';
450 strncat(path, "/", 2);
451 strncat(path, arg0, strlen(arg0) + 1);
452 if (access(path, X_OK) == 0) {
456 prog_pathname = path;
461 * That's not it. If there are more
462 * path components to test, try them.
464 if (*path_end == '\0') {
466 * There's nothing more to try.
470 if (*path_end == ':')
472 path_start = path_end;
475 if (prog_pathname == NULL) {
477 * Program not found in path.
479 return g_strdup_printf("\"%s\" not found in \"%s\"",
485 * XXX - should we pick a default?
487 return g_strdup("PATH isn't set");
492 * OK, we have what we think is the pathname
495 * First, find the last "/" in the directory,
496 * as that marks the end of the directory pathname.
498 dir_end = strrchr(prog_pathname, '/');
499 if (dir_end != NULL) {
501 * Found it. Strip off the last component,
502 * as that's the path of the program.
507 * Is there a "/.libs" at the end?
509 dir_end = strrchr(prog_pathname, '/');
510 if (dir_end != NULL) {
511 if (strcmp(dir_end, "/.libs") == 0) {
514 * Strip that off; it's an
515 * artifact of libtool.
520 * This presumably means we're run from
521 * the libtool wrapper, which probably
522 * means we're being run from the build
523 * directory. If we weren't started
524 * with special privileges, set
525 * running_in_build_directory_flag.
527 * XXX - should we check whether what
528 * follows ".libs/" begins with "lt-"?
530 if (!started_with_special_privs())
531 running_in_build_directory_flag = TRUE;
536 * OK, we have the path we want.
538 progfile_dir = prog_pathname;
542 * This "shouldn't happen"; we apparently
543 * have no "/" in the pathname.
544 * Just free up prog_pathname.
546 retstr = g_strdup_printf("No / found in \"%s\"", prog_pathname);
547 g_free(prog_pathname);
554 * Get the directory in which the program resides.
557 get_progfile_dir(void)
563 * Get the directory in which the global configuration and data files are
566 * On Windows, we use the directory in which the executable for this
569 * On UN*X, we use the DATAFILE_DIR value supplied by the configure
570 * script, unless we think we're being run from the build directory,
571 * in which case we use the directory in which the executable for this
574 * XXX - if we ever make libwireshark a real library, used by multiple
575 * applications (more than just TShark and versions of Wireshark with
576 * various UIs), should the configuration files belong to the library
577 * (and be shared by all those applications) or to the applications?
579 * If they belong to the library, that could be done on UNIX by the
580 * configure script, but it's trickier on Windows, as you can't just
581 * use the pathname of the executable.
583 * If they belong to the application, that could be done on Windows
584 * by using the pathname of the executable, but we'd have to have it
585 * passed in as an argument, in some call, on UNIX.
587 * Note that some of those configuration files might be used by code in
588 * libwireshark, some of them might be used by dissectors (would they
589 * belong to libwireshark, the application, or a separate library?),
590 * and some of them might be used by other code (the Wireshark preferences
591 * file includes resolver preferences that control the behavior of code
592 * in libwireshark, dissector preferences, and UI preferences, for
596 get_datafile_dir(void)
599 char *u3deviceexecpath;
601 static char *datafile_dir = NULL;
603 if (datafile_dir != NULL)
608 * See if we are running in a U3 environment.
610 u3deviceexecpath = getenv_utf8("U3_DEVICE_EXEC_PATH");
612 if (u3deviceexecpath != NULL) {
614 * We are; use the U3 device executable path.
616 datafile_dir = u3deviceexecpath;
619 * Do we have the pathname of the program? If so, assume we're
620 * running an installed version of the program. If we fail,
621 * we don't change "datafile_dir", and thus end up using the
624 * XXX - does NSIS put the installation directory into
625 * "\HKEY_LOCAL_MACHINE\SOFTWARE\Wireshark\InstallDir"?
626 * If so, perhaps we should read that from the registry,
629 if (progfile_dir != NULL) {
631 * Yes, we do; use that.
633 datafile_dir = progfile_dir;
637 * Fall back on the default installation directory.
639 datafile_dir = "C:\\Program Files\\Wireshark\\";
643 if (running_in_build_directory_flag && progfile_dir != NULL) {
645 * We're (probably) being run from the build directory and
646 * weren't started with special privileges, and we were
647 * able to determine the directory in which the program
648 * was found, so use that.
650 datafile_dir = progfile_dir;
653 * Return the directory specified when the build was
654 * configured, prepending the run path prefix if it exists.
656 if (getenv("WIRESHARK_DATA_DIR") && !started_with_special_privs()) {
658 * The user specified a different directory for data files
659 * and we aren't running with special privileges.
660 * XXX - We might be able to dispense with the priv check
662 datafile_dir = g_strdup(getenv("WIRESHARK_DATA_DIR"));
664 datafile_dir = DATAFILE_DIR;
674 * Find the directory where the python dissectors are stored.
676 * On Windows, we use the "py_dissector" subdirectory of the datafile directory.
678 * On UN*X, we use the PYTHON_DIR value supplied by the configure
679 * script, unless we think we're being run from the build directory,
680 * in which case we use the "py_dissector" subdirectory of the datafile directory.
682 * In both cases, we then use the subdirectory of that directory whose
683 * name is the version number.
685 * XXX - if we think we're being run from the build directory, perhaps we
686 * should have the plugin code not look in the version subdirectory
687 * of the plugin directory, but look in all of the subdirectories
688 * of the plugin directory, so it can just fetch the plugins built
689 * as part of the build process.
691 static const char *wspython_dir = NULL;
694 init_wspython_dir(void)
698 * On Windows, the data file directory is the installation
699 * directory; the python dissectors are stored under it.
701 * Assume we're running the installed version of Wireshark;
702 * on Windows, the data file directory is the directory
703 * in which the Wireshark binary resides.
705 wspython_dir = g_strdup_printf("%s\\python\\%s", get_datafile_dir(),
709 * Make sure that pathname refers to a directory.
711 if (test_for_directory(wspython_dir) != EISDIR) {
713 * Either it doesn't refer to a directory or it
714 * refers to something that doesn't exist.
716 * Assume that means we're running a version of
717 * Wireshark we've built in a build directory,
718 * in which case {datafile dir}\python is the
719 * top-level plugins source directory, and use
720 * that directory and set the "we're running in
721 * a build directory" flag, so the plugin
722 * scanner will check all subdirectories of that
723 * directory for python dissectors.
725 g_free( (gpointer) wspython_dir);
726 wspython_dir = g_strdup_printf("%s\\python", get_datafile_dir());
727 running_in_build_directory_flag = TRUE;
730 if (running_in_build_directory_flag) {
732 * We're (probably) being run from the build directory and
733 * weren't started with special privileges, so we'll use
734 * the "python" subdirectory of the datafile directory
735 * (the datafile directory is the build directory).
737 wspython_dir = g_strdup_printf("%s/epan/wspython/", get_datafile_dir());
739 if (getenv("WIRESHARK_PYTHON_DIR") && !started_with_special_privs()) {
741 * The user specified a different directory for plugins
742 * and we aren't running with special privileges.
744 wspython_dir = g_strdup(getenv("WIRESHARK_PYTHON_DIR"));
746 wspython_dir = PYTHON_DIR;
751 #endif /* HAVE_PYTHON */
754 * Get the directory in which the python dissectors are stored.
757 get_wspython_dir(void)
760 if (!wspython_dir) init_wspython_dir();
770 * Find the directory where the plugins are stored.
772 * On Windows, we use the "plugin" subdirectory of the datafile directory.
774 * On UN*X, we use the PLUGIN_DIR value supplied by the configure
775 * script, unless we think we're being run from the build directory,
776 * in which case we use the "plugin" subdirectory of the datafile directory.
778 * In both cases, we then use the subdirectory of that directory whose
779 * name is the version number.
781 * XXX - if we think we're being run from the build directory, perhaps we
782 * should have the plugin code not look in the version subdirectory
783 * of the plugin directory, but look in all of the subdirectories
784 * of the plugin directory, so it can just fetch the plugins built
785 * as part of the build process.
787 static const char *plugin_dir = NULL;
790 init_plugin_dir(void)
794 * On Windows, the data file directory is the installation
795 * directory; the plugins are stored under it.
797 * Assume we're running the installed version of Wireshark;
798 * on Windows, the data file directory is the directory
799 * in which the Wireshark binary resides.
801 plugin_dir = g_strdup_printf("%s\\plugins\\%s", get_datafile_dir(),
805 * Make sure that pathname refers to a directory.
807 if (test_for_directory(plugin_dir) != EISDIR) {
809 * Either it doesn't refer to a directory or it
810 * refers to something that doesn't exist.
812 * Assume that means we're running a version of
813 * Wireshark we've built in a build directory,
814 * in which case {datafile dir}\plugins is the
815 * top-level plugins source directory, and use
816 * that directory and set the "we're running in
817 * a build directory" flag, so the plugin
818 * scanner will check all subdirectories of that
819 * directory for plugins.
821 g_free( (gpointer) plugin_dir);
822 plugin_dir = g_strdup_printf("%s\\plugins", get_datafile_dir());
823 running_in_build_directory_flag = TRUE;
826 if (running_in_build_directory_flag) {
828 * We're (probably) being run from the build directory and
829 * weren't started with special privileges, so we'll use
830 * the "plugins" subdirectory of the datafile directory
831 * (the datafile directory is the build directory).
833 plugin_dir = g_strdup_printf("%s/plugins", get_datafile_dir());
835 if (getenv("WIRESHARK_PLUGIN_DIR") && !started_with_special_privs()) {
837 * The user specified a different directory for plugins
838 * and we aren't running with special privileges.
840 plugin_dir = g_strdup(getenv("WIRESHARK_PLUGIN_DIR"));
842 plugin_dir = PLUGIN_DIR;
847 #endif /* HAVE_PLUGINS */
850 * Get the directory in which the plugins are stored.
856 if (!plugin_dir) init_plugin_dir();
864 * Get the flag indicating whether we're running from a build
868 running_in_build_directory(void)
870 return running_in_build_directory_flag;
874 * Get the directory in which files that, at least on UNIX, are
875 * system files (such as "/etc/ethers") are stored; on Windows,
876 * there's no "/etc" directory, so we get them from the global
877 * configuration and data file directory.
880 get_systemfile_dir(void)
883 return get_datafile_dir();
890 * Name of directory, under the user's home directory, in which
891 * personal configuration files are stored.
894 #define PF_DIR "Wireshark"
897 * XXX - should this be ".libepan"? For backwards-compatibility, I'll keep
898 * it ".wireshark" for now.
900 #define PF_DIR ".wireshark"
904 /* utf8 version of getenv, needed to get win32 filename paths */
905 char *getenv_utf8(const char *varname)
911 envvar = getenv(varname);
913 /* since GLib 2.6 we need an utf8 version of the filename */
914 #if GLIB_CHECK_VERSION(2,6,0)
915 /* using the wide char version of getenv should work under all circumstances */
917 /* convert given varname to utf16, needed by _wgetenv */
918 varnamew = g_utf8_to_utf16(varname, -1, NULL, NULL, NULL);
919 if (varnamew == NULL) {
923 /* use wide char version of getenv */
924 envvarw = _wgetenv(varnamew);
926 if (envvarw == NULL) {
930 /* convert value to utf8 */
931 envvar = g_utf16_to_utf8(envvarw, -1, NULL, NULL, NULL);
940 set_profile_name(const gchar *profilename)
942 g_free (persconfprofile);
944 if (profilename && strlen(profilename) > 0 &&
945 strcmp(profilename, DEFAULT_PROFILE) != 0) {
946 persconfprofile = g_strdup (profilename);
948 /* Default Profile */
949 persconfprofile = NULL;
954 get_profile_name(void)
956 if (persconfprofile) {
957 return persconfprofile;
959 return DEFAULT_PROFILE;
964 * Get the directory in which personal configuration files reside;
965 * in UNIX-compatible systems, it's ".wireshark", under the user's home
966 * directory, and on Windows systems, it's "Wireshark", under %APPDATA%
967 * or, if %APPDATA% isn't set, it's "%USERPROFILE%\Application Data"
968 * (which is what %APPDATA% normally is on Windows 2000).
971 get_persconffile_dir_no_profile(void)
975 char *userprofiledir;
982 /* Return the cached value, if available */
983 if (persconffile_dir != NULL)
984 return persconffile_dir;
988 * See if we are running in a U3 environment.
990 u3appdatapath = getenv_utf8("U3_APP_DATA_PATH");
991 if (u3appdatapath != NULL) {
993 * We are; use the U3 application data path.
995 persconffile_dir = u3appdatapath;
998 * Use %APPDATA% or %USERPROFILE%, so that configuration
999 * files are stored in the user profile, rather than in
1000 * the home directory. The Windows convention is to store
1001 * configuration information in the user profile, and doing
1002 * so means you can use Wireshark even if the home directory
1003 * is an inaccessible network drive.
1005 appdatadir = getenv_utf8("APPDATA");
1006 if (appdatadir != NULL) {
1008 * Concatenate %APPDATA% with "\Wireshark".
1010 persconffile_dir = g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s",
1011 appdatadir, PF_DIR);
1014 * OK, %APPDATA% wasn't set, so use
1015 * %USERPROFILE%\Application Data.
1017 userprofiledir = getenv_utf8("USERPROFILE");
1018 if (userprofiledir != NULL) {
1019 persconffile_dir = g_strdup_printf(
1020 "%s" G_DIR_SEPARATOR_S "Application Data" G_DIR_SEPARATOR_S "%s",
1021 userprofiledir, PF_DIR);
1024 * Give up and use "C:".
1026 persconffile_dir = g_strdup_printf("C:" G_DIR_SEPARATOR_S "%s", PF_DIR);
1032 * If $HOME is set, use that.
1034 homedir = getenv("HOME");
1035 if (homedir == NULL) {
1037 * Get their home directory from the password file.
1038 * If we can't even find a password file entry for them,
1041 pwd = getpwuid(getuid());
1044 * This is cached, so we don't need to worry
1045 * about allocating multiple ones of them.
1047 homedir = g_strdup(pwd->pw_dir);
1051 persconffile_dir = g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s", homedir, PF_DIR);
1054 return persconffile_dir;
1058 get_profiles_dir(void)
1060 static char *profiles_dir = NULL;
1062 g_free (profiles_dir);
1063 profiles_dir = g_strdup_printf ("%s%s%s", get_persconffile_dir_no_profile (),
1064 G_DIR_SEPARATOR_S, PROFILES_DIR);
1066 return profiles_dir;
1070 get_persconffile_dir(const gchar *profilename)
1072 static char *persconffile_profile_dir = NULL;
1074 g_free (persconffile_profile_dir);
1076 if (profilename && strlen(profilename) > 0 &&
1077 strcmp(profilename, DEFAULT_PROFILE) != 0) {
1078 persconffile_profile_dir = g_strdup_printf ("%s%s%s", get_profiles_dir (),
1079 G_DIR_SEPARATOR_S, profilename);
1081 persconffile_profile_dir = g_strdup (get_persconffile_dir_no_profile ());
1084 return persconffile_profile_dir;
1088 profile_exists(const gchar *profilename)
1090 if (test_for_directory (get_persconffile_dir (profilename)) == EISDIR) {
1098 delete_directory (const char *directory, char **pf_dir_path_return)
1105 if ((dir = ws_dir_open(directory, 0, NULL)) != NULL) {
1106 while ((file = ws_dir_read_name(dir)) != NULL) {
1107 filename = g_strdup_printf ("%s%s%s", directory, G_DIR_SEPARATOR_S,
1108 ws_dir_get_name(file));
1109 if (test_for_directory(filename) != EISDIR) {
1110 ret = ws_remove(filename);
1113 /* The user has manually created a directory in the profile directory */
1114 /* I do not want to delete the directory recursively yet */
1115 ret = delete_directory (filename, pf_dir_path_return);
1119 *pf_dir_path_return = filename;
1127 if (ret == 0 && (ret = ws_remove(directory)) != 0) {
1128 *pf_dir_path_return = g_strdup (directory);
1135 delete_persconffile_profile(const char *profilename, char **pf_dir_path_return)
1137 const char *profile_dir = get_persconffile_dir(profilename);
1140 if (test_for_directory (profile_dir) == EISDIR) {
1141 ret = delete_directory (profile_dir, pf_dir_path_return);
1148 rename_persconffile_profile(const char *fromname, const char *toname,
1149 char **pf_from_dir_path_return, char **pf_to_dir_path_return)
1151 char *from_dir = g_strdup (get_persconffile_dir(fromname));
1152 char *to_dir = g_strdup (get_persconffile_dir(toname));
1155 ret = ws_rename (from_dir, to_dir);
1157 *pf_from_dir_path_return = g_strdup (from_dir);
1158 *pf_to_dir_path_return = g_strdup (to_dir);
1168 * Create the directory that holds personal configuration files, if
1169 * necessary. If we attempted to create it, and failed, return -1 and
1170 * set "*pf_dir_path_return" to the pathname of the directory we failed
1171 * to create (it's g_mallocated, so our caller should free it); otherwise,
1175 create_persconffile_profile(const char *profilename, char **pf_dir_path_return)
1177 const char *pf_dir_path;
1179 char *pf_dir_path_copy, *pf_dir_parent_path;
1180 size_t pf_dir_parent_path_len;
1187 * Check if profiles directory exists.
1188 * If not then create it.
1190 pf_dir_path = get_profiles_dir ();
1191 if (ws_stat(pf_dir_path, &s_buf) != 0 && errno == ENOENT) {
1192 ret = ws_mkdir(pf_dir_path, 0755);
1194 *pf_dir_path_return = g_strdup(pf_dir_path);
1200 pf_dir_path = get_persconffile_dir(profilename);
1201 if (ws_stat(pf_dir_path, &s_buf) != 0 && errno == ENOENT) {
1204 * Does the parent directory of that directory
1205 * exist? %APPDATA% may not exist even though
1206 * %USERPROFILE% does.
1208 * We check for the existence of the directory
1209 * by first checking whether the parent directory
1210 * is just a drive letter and, if it's not, by
1211 * doing a "stat()" on it. If it's a drive letter,
1212 * or if the "stat()" succeeds, we assume it exists.
1214 pf_dir_path_copy = g_strdup(pf_dir_path);
1215 pf_dir_parent_path = get_dirname(pf_dir_path_copy);
1216 pf_dir_parent_path_len = strlen(pf_dir_parent_path);
1217 if (pf_dir_parent_path_len > 0
1218 && pf_dir_parent_path[pf_dir_parent_path_len - 1] != ':'
1219 && ws_stat(pf_dir_parent_path, &s_buf) != 0) {
1221 * No, it doesn't exist - make it first.
1223 ret = ws_mkdir(pf_dir_parent_path, 0755);
1225 *pf_dir_path_return = pf_dir_parent_path;
1229 g_free(pf_dir_path_copy);
1230 ret = ws_mkdir(pf_dir_path, 0755);
1232 ret = ws_mkdir(pf_dir_path, 0755);
1236 * Something with that pathname exists; if it's not
1237 * a directory, we'll get an error if we try to put
1238 * something in it, so we don't fail here, we wait
1239 * for that attempt fo fail.
1244 *pf_dir_path_return = g_strdup(pf_dir_path);
1249 create_persconffile_dir(char **pf_dir_path_return)
1251 return create_persconffile_profile(persconfprofile, pf_dir_path_return);
1255 * Get the (default) directory in which personal data is stored.
1257 * On Win32, this is the "My Documents" folder in the personal profile.
1258 * On UNIX this is simply the current directory.
1259 * On a U3 device this is "$U3_DEVICE_DOCUMENT_PATH\My Captures" folder.
1261 /* XXX - should this and the get_home_dir() be merged? */
1263 get_persdatafile_dir(void)
1266 char *u3devicedocumentpath;
1267 TCHAR tszPath[MAX_PATH];
1272 /* Return the cached value, if available */
1273 if (persdatafile_dir != NULL)
1274 return persdatafile_dir;
1277 * See if we are running in a U3 environment.
1279 u3devicedocumentpath = getenv_utf8("U3_DEVICE_DOCUMENT_PATH");
1281 if (u3devicedocumentpath != NULL) {
1283 /* the "My Captures" sub-directory is created (if it doesn't exist)
1284 by u3util.exe when the U3 Wireshark is first run */
1286 szPath = g_strdup_printf("%s%s", u3devicedocumentpath, U3_MY_CAPTURES);
1288 persdatafile_dir = szPath;
1292 /* Hint: SHGetFolderPath is not available on MSVC 6 - without Platform SDK */
1293 bRet = SHGetSpecialFolderPath(NULL, tszPath, CSIDL_PERSONAL, FALSE);
1295 szPath = utf_16to8(tszPath);
1296 persdatafile_dir = szPath;
1309 * Returns the user's home directory on Win32.
1314 static const char *home = NULL;
1315 char *homedrive, *homepath;
1319 /* Return the cached value, if available */
1324 * XXX - should we use USERPROFILE anywhere in this process?
1325 * Is there a chance that it might be set but one or more of
1326 * HOMEDRIVE or HOMEPATH isn't set?
1328 homedrive = getenv_utf8("HOMEDRIVE");
1329 if (homedrive != NULL) {
1330 homepath = getenv_utf8("HOMEPATH");
1331 if (homepath != NULL) {
1333 * This is cached, so we don't need to worry about
1334 * allocating multiple ones of them.
1336 homestring = g_strdup_printf("%s%s", homedrive, homepath);
1339 * Trim off any trailing slash or backslash.
1341 lastsep = find_last_pathname_separator(homestring);
1342 if (lastsep != NULL && *(lastsep + 1) == '\0') {
1344 * Last separator is the last character
1345 * in the string. Nuke it.
1354 * Give up and use C:.
1364 * Construct the path name of a personal configuration file, given the
1367 * On Win32, if "for_writing" is FALSE, we check whether the file exists
1368 * and, if not, construct a path name relative to the ".wireshark"
1369 * subdirectory of the user's home directory, and check whether that
1370 * exists; if it does, we return that, so that configuration files
1371 * from earlier versions can be read.
1373 * The returned file name was g_malloc()'d so it must be g_free()d when the
1374 * caller is done with it.
1377 get_persconffile_path(const char *filename, gboolean from_profile, gboolean for_writing
1390 path = g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s",
1391 get_persconffile_dir(persconfprofile), filename);
1393 path = g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s",
1394 get_persconffile_dir(NULL), filename);
1398 if (ws_stat(path, &s_buf) != 0 && errno == ENOENT) {
1400 * OK, it's not in the personal configuration file
1401 * directory; is it in the ".wireshark" subdirectory
1402 * of their home directory?
1404 old_path = g_strdup_printf(
1405 "%s" G_DIR_SEPARATOR_S ".wireshark" G_DIR_SEPARATOR_S "%s",
1406 get_home_dir(), filename);
1407 if (ws_stat(old_path, &s_buf) == 0) {
1409 * OK, it exists; return it instead.
1422 * process command line option belonging to the filesystem settings
1423 * (move this e.g. to main.c and have set_persconffile_dir() instead in this file?)
1426 filesystem_opt(int opt _U_, const char *optstr)
1430 colonp = strchr(optstr, ':');
1431 if (colonp == NULL) {
1439 * Skip over any white space (there probably won't be any, but
1440 * as we allow it in the preferences file, we might as well
1443 while (isspace((guchar)*p))
1447 * Put the colon back, so if our caller uses, in an
1448 * error message, the string they passed us, the message
1455 /* directory should be existing */
1456 /* XXX - is this a requirement? */
1457 if(test_for_directory(p) != EISDIR) {
1459 * Put the colon back, so if our caller uses, in an
1460 * error message, the string they passed us, the message
1467 if (strcmp(optstr,"persconf") == 0) {
1468 persconffile_dir = p;
1469 } else if (strcmp(optstr,"persdata") == 0) {
1470 persdatafile_dir = p;
1471 /* XXX - might need to add the temp file path */
1475 *colonp = ':'; /* put the colon back */
1480 * Construct the path name of a global configuration file, given the
1483 * The returned file name was g_malloc()'d so it must be g_free()d when the
1484 * caller is done with it.
1487 get_datafile_path(const char *filename)
1490 return g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s", get_datafile_dir(),
1496 deletefile(const char *path)
1498 return ws_unlink(path) == 0;
1502 * Construct and return the path name of a file in the
1503 * appropriate temporary file directory.
1505 char *get_tempfile_path(const char *filename)
1507 return g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s", g_get_tmp_dir(), filename);
1511 * Return an error message for UNIX-style errno indications on open or
1512 * create operations.
1515 file_open_error_message(int err, gboolean for_writing)
1518 static char errmsg_errno[1024+1];
1524 errmsg = "The path to the file \"%s\" doesn't exist.";
1526 errmsg = "The file \"%s\" doesn't exist.";
1531 errmsg = "You don't have permission to create or write to the file \"%s\".";
1533 errmsg = "You don't have permission to read the file \"%s\".";
1537 errmsg = "\"%s\" is a directory (folder), not a file.";
1541 errmsg = "The file \"%s\" could not be created because there is no space left on the file system.";
1546 errmsg = "The file \"%s\" could not be created because you are too close to, or over, your disk quota.";
1551 errmsg = "The file \"%s\" could not be created because an invalid filename was specified.";
1555 g_snprintf(errmsg_errno, sizeof(errmsg_errno),
1556 "The file \"%%s\" could not be %s: %s.",
1557 for_writing ? "created" : "opened",
1559 errmsg = errmsg_errno;
1566 * Return an error message for UNIX-style errno indications on write
1570 file_write_error_message(int err)
1573 static char errmsg_errno[1024+1];
1578 errmsg = "The file \"%s\" could not be saved because there is no space left on the file system.";
1583 errmsg = "The file \"%s\" could not be saved because you are too close to, or over, your disk quota.";
1588 g_snprintf(errmsg_errno, sizeof(errmsg_errno),
1589 "An error occurred while writing to the file \"%%s\": %s.",
1591 errmsg = errmsg_errno;
1599 file_exists(const char *fname)
1601 struct stat file_stat;
1605 * This is a bit tricky on win32. The st_ino field is documented as:
1606 * "The inode, and therefore st_ino, has no meaning in the FAT, ..."
1607 * but it *is* set to zero if stat() returns without an error,
1608 * so this is working, but maybe not quite the way expected. ULFL
1610 file_stat.st_ino = 1; /* this will make things work if an error occured */
1611 ws_stat(fname, &file_stat);
1612 if (file_stat.st_ino == 0) {
1618 if (ws_stat(fname, &file_stat) != 0 && errno == ENOENT) {
1627 * Check that the from file is not the same as to file
1628 * We do it here so we catch all cases ...
1629 * Unfortunately, the file requester gives us an absolute file
1630 * name and the read file name may be relative (if supplied on
1631 * the command line), so we can't just compare paths. From Joerg Mayer.
1634 files_identical(const char *fname1, const char *fname2)
1636 /* Two different implementations, because:
1638 * - _fullpath is not available on UN*X, so we can't get full
1639 * paths and compare them (which wouldn't work with hard links
1642 * - st_ino isn't filled in with a meaningful value on Windows.
1645 char full1[MAX_PATH], full2[MAX_PATH];
1648 * Get the absolute full paths of the file and compare them.
1649 * That won't work if you have hard links, but those aren't
1650 * much used on Windows, even though NTFS supports them.
1652 * XXX - will _fullpath work with UNC?
1654 if( _fullpath( full1, fname1, MAX_PATH ) == NULL ) {
1658 if( _fullpath( full2, fname2, MAX_PATH ) == NULL ) {
1662 if(strcmp(full1, full2) == 0) {
1668 struct stat filestat1, filestat2;
1671 * Compare st_dev and st_ino.
1673 if (ws_stat(fname1, &filestat1) == -1)
1674 return FALSE; /* can't get info about the first file */
1675 if (ws_stat(fname2, &filestat2) == -1)
1676 return FALSE; /* can't get info about the second file */
1677 return (filestat1.st_dev == filestat2.st_dev &&
1678 filestat1.st_ino == filestat2.st_ino);
1683 * Copy a file in binary mode, for those operating systems that care about
1684 * such things. This should be OK for all files, even text files, as
1685 * we'll copy the raw bytes, and we don't look at the bytes as we copy
1688 * Returns TRUE on success, FALSE on failure. If a failure, it also
1689 * displays a simple dialog window with the error message.
1692 copy_file_binary_mode(const char *from_filename, const char *to_filename)
1694 int from_fd, to_fd, nread, nwritten, err;
1697 /* Copy the raw bytes of the file. */
1698 from_fd = ws_open(from_filename, O_RDONLY | O_BINARY, 0000 /* no creation so don't matter */);
1700 report_open_failure(from_filename, errno, FALSE);
1704 /* Use open() instead of creat() so that we can pass the O_BINARY
1705 flag, which is relevant on Win32; it appears that "creat()"
1706 may open the file in text mode, not binary mode, but we want
1707 to copy the raw bytes of the file, so we need the output file
1708 to be open in binary mode. */
1709 to_fd = ws_open(to_filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644);
1711 report_open_failure(to_filename, errno, TRUE);
1716 while ((nread = ws_read(from_fd, pd, sizeof pd)) > 0) {
1717 nwritten = ws_write(to_fd, pd, nread);
1718 if (nwritten < nread) {
1722 err = WTAP_ERR_SHORT_WRITE;
1723 report_write_failure(to_filename, err);
1731 report_read_failure(from_filename, err);
1737 if (ws_close(to_fd) < 0) {
1738 report_write_failure(to_filename, errno);
1754 * indent-tabs-mode: t
1757 * ex: set shiftwidth=4 tabstop=4 noexpandtab
1758 * :indentSize=4:tabSize=4:noTabs=false: