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 PLUGINS_DIR_NAME "plugins"
82 #define U3_MY_CAPTURES "\\My Captures"
84 char *persconffile_dir = NULL;
85 char *persdatafile_dir = NULL;
86 char *persconfprofile = NULL;
88 static gboolean do_store_persconffiles = FALSE;
89 static GHashTable *profile_files = NULL;
92 * Given a pathname, return a pointer to the last pathname separator
93 * character in the pathname, or NULL if the pathname contains no
97 find_last_pathname_separator(const char *path)
105 * We have to scan for '\' or '/'.
106 * Get to the end of the string.
108 separator = strchr(path, '\0'); /* points to ending '\0' */
109 while (separator > path) {
111 if (c == '\\' || c == '/')
112 return separator; /* found it */
116 * OK, we didn't find any, so no directories - but there might
117 * be a drive letter....
119 return strchr(path, ':');
121 separator = strrchr(path, '/');
127 * Given a pathname, return the last component.
130 get_basename(const char *path)
132 const char *filename;
134 g_assert(path != NULL);
135 filename = find_last_pathname_separator(path);
136 if (filename == NULL) {
138 * There're no directories, drive letters, etc. in the
139 * name; the pathname *is* the file name.
144 * Skip past the pathname or drive letter separator.
152 * Given a pathname, return a string containing everything but the
153 * last component. NOTE: this overwrites the pathname handed into
157 get_dirname(char *path)
161 g_assert(path != NULL);
162 separator = find_last_pathname_separator(path);
163 if (separator == NULL) {
165 * There're no directories, drive letters, etc. in the
166 * name; there is no directory path to return.
172 * Get rid of the last pathname separator and the final file
178 * "path" now contains the pathname of the directory containing
179 * the file/directory to which it referred.
185 * Given a pathname, return:
187 * the errno, if an attempt to "stat()" the file fails;
189 * EISDIR, if the attempt succeeded and the file turned out
192 * 0, if the attempt succeeded and the file turned out not
197 * Visual C++ on Win32 systems doesn't define these. (Old UNIX systems don't
198 * define them either.)
200 * Visual C++ on Win32 systems doesn't define S_IFIFO, it defines _S_IFIFO.
203 #define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG)
206 #define S_IFIFO _S_IFIFO
209 #define S_ISFIFO(mode) (((mode) & S_IFMT) == S_IFIFO)
212 #define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
216 test_for_directory(const char *path)
220 if (ws_stat(path, &statb) < 0)
223 if (S_ISDIR(statb.st_mode))
230 test_for_fifo(const char *path)
234 if (ws_stat(path, &statb) < 0)
237 if (S_ISFIFO(statb.st_mode))
244 * Directory from which the executable came.
246 static char *progfile_dir;
249 * TRUE if we're running from the build directory and we aren't running
250 * with special privileges.
252 static gboolean running_in_build_directory_flag = FALSE;
255 * Get the pathname of the directory from which the executable came,
256 * and save it for future use. Returns NULL on success, and a
257 * g_mallocated string containing an error on failure.
260 init_progfile_dir(const char *arg0
264 , int (*main_addr)(int, char **)
265 #if defined(_WIN32) || !defined(DLADDR_FINDS_EXECUTABLE_PATH)
273 TCHAR prog_pathname_w[_MAX_PATH+2];
274 size_t progfile_dir_len;
282 * Attempt to get the full pathname of the currently running
285 if (GetModuleFileName(NULL, prog_pathname_w, G_N_ELEMENTS(prog_pathname_w)) != 0) {
287 * XXX - Should we use g_utf16_to_utf8(), as in
290 prog_pathname = utf_16to8(prog_pathname_w);
292 * We got it; strip off the last component, which would be
293 * the file name of the executable, giving us the pathname
294 * of the directory where the executable resies
296 * First, find the last "\" in the directory, as that
297 * marks the end of the directory pathname.
299 * XXX - Can the pathname be something such as
300 * "C:wireshark.exe"? Or is it always a full pathname
301 * beginning with "\" after the drive letter?
303 dir_end = strrchr(prog_pathname, '\\');
304 if (dir_end != NULL) {
306 * Found it - now figure out how long the program
307 * directory pathname will be.
309 progfile_dir_len = (dir_end - prog_pathname);
312 * Allocate a buffer for the program directory
313 * pathname, and construct it.
315 path = g_malloc(progfile_dir_len + 1);
316 strncpy(path, prog_pathname, progfile_dir_len);
317 path[progfile_dir_len] = '\0';
320 return NULL; /* we succeeded */
323 * OK, no \ - what do we do now?
325 return g_strdup_printf("No \\ in executable pathname \"%s\"",
330 * Oh, well. Return an indication of the error.
332 error = GetLastError();
333 if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM,
334 NULL, error, 0, (LPTSTR) &msg_w, 0, NULL) == 0) {
336 * Gak. We can't format the message.
338 return g_strdup_printf("GetModuleFileName failed: %u (FormatMessage failed: %u)",
339 error, GetLastError());
341 msg = utf_16to8(msg_w);
344 * "FormatMessage()" "helpfully" sticks CR/LF at the
345 * end of the message. Get rid of it.
347 msglen = strlen(msg);
349 msg[msglen - 1] = '\0';
350 msg[msglen - 2] = '\0';
352 return g_strdup_printf("GetModuleFileName failed: %s (%u)",
356 #ifdef DLADDR_FINDS_EXECUTABLE_PATH
363 char *path_start, *path_end;
364 size_t path_component_len;
368 * Check whether WIRESHARK_RUN_FROM_BUILD_DIRECTORY is set in the
369 * environment; if so, set running_in_build_directory_flag if we
370 * weren't started with special privileges. (If we were started
371 * with special privileges, it's not safe to allow the user to point
372 * us to some other directory; running_in_build_directory_flag, when
373 * set, causes us to look for plugins and the like in the build
376 if (getenv("WIRESHARK_RUN_FROM_BUILD_DIRECTORY") != NULL
377 && !started_with_special_privs())
378 running_in_build_directory_flag = TRUE;
380 #ifdef DLADDR_FINDS_EXECUTABLE_PATH
382 * Try to use dladdr() to find the pathname of the executable.
383 * dladdr() is not guaranteed to give you anything better than
384 * argv[0] (i.e., it might not contain a / at all, much less
385 * being an absolute path), and doesn't appear to do so on
386 * Linux, but on other platforms it could give you an absolute
387 * path and obviate the need for us to determine the absolute
390 if (dladdr((void *)main_addr, &info))
391 arg0 = info.dli_fname;
394 * Try to figure out the directory in which the currently running
395 * program resides, given something purporting to be the executable
396 * name (from dladdr() or from the argv[0] it was started with.
397 * That might be the absolute path of the program, or a path relative
398 * to the current directory of the process that started it, or
399 * just a name for the program if it was started from the command
400 * line and was searched for in $PATH. It's not guaranteed to be
401 * any of those, however, so there are no guarantees....
403 if (arg0[0] == '/') {
405 * It's an absolute path.
407 prog_pathname = g_strdup(arg0);
408 } else if (strchr(arg0, '/') != NULL) {
410 * It's a relative path, with a directory in it.
411 * Get the current directory, and combine it
412 * with that directory.
414 path_max = pathconf(".", _PC_PATH_MAX);
415 if (path_max == -1) {
417 * We have no idea how big a buffer to
418 * allocate for the current directory.
420 return g_strdup_printf("pathconf failed: %s\n",
423 curdir = (char *)g_malloc(path_max);
424 if (getcwd(curdir, path_max) == NULL) {
426 * It failed - give up, and just stick
430 return g_strdup_printf("getcwd failed: %s\n",
433 path = g_strdup_printf("%s/%s", curdir, arg0);
435 prog_pathname = path;
438 * It's just a file name.
439 * Search the path for a file with that name
442 prog_pathname = NULL; /* haven't found it yet */
443 pathstr = getenv("PATH");
444 path_start = pathstr;
445 if (path_start != NULL) {
446 while (*path_start != '\0') {
447 path_end = strchr(path_start, ':');
448 if (path_end == NULL)
449 path_end = path_start + strlen(path_start);
450 path_component_len = path_end - path_start;
451 path = (char *)g_malloc(path_component_len + 1
453 memcpy(path, path_start, path_component_len);
454 path[path_component_len] = '\0';
455 strncat(path, "/", 2);
456 strncat(path, arg0, strlen(arg0) + 1);
457 if (access(path, X_OK) == 0) {
461 prog_pathname = path;
466 * That's not it. If there are more
467 * path components to test, try them.
469 if (*path_end == '\0') {
471 * There's nothing more to try.
475 if (*path_end == ':')
477 path_start = path_end;
480 if (prog_pathname == NULL) {
482 * Program not found in path.
484 return g_strdup_printf("\"%s\" not found in \"%s\"",
490 * XXX - should we pick a default?
492 return g_strdup("PATH isn't set");
497 * OK, we have what we think is the pathname
500 * First, find the last "/" in the directory,
501 * as that marks the end of the directory pathname.
503 dir_end = strrchr(prog_pathname, '/');
504 if (dir_end != NULL) {
506 * Found it. Strip off the last component,
507 * as that's the path of the program.
512 * Is there a "/.libs" at the end?
514 dir_end = strrchr(prog_pathname, '/');
515 if (dir_end != NULL) {
516 if (strcmp(dir_end, "/.libs") == 0) {
519 * Strip that off; it's an
520 * artifact of libtool.
525 * This presumably means we're run from
526 * the libtool wrapper, which probably
527 * means we're being run from the build
528 * directory. If we weren't started
529 * with special privileges, set
530 * running_in_build_directory_flag.
532 * XXX - should we check whether what
533 * follows ".libs/" begins with "lt-"?
535 if (!started_with_special_privs())
536 running_in_build_directory_flag = TRUE;
541 * OK, we have the path we want.
543 progfile_dir = prog_pathname;
547 * This "shouldn't happen"; we apparently
548 * have no "/" in the pathname.
549 * Just free up prog_pathname.
551 retstr = g_strdup_printf("No / found in \"%s\"", prog_pathname);
552 g_free(prog_pathname);
559 * Get the directory in which the program resides.
562 get_progfile_dir(void)
568 * Get the directory in which the global configuration and data files are
571 * On Windows, we use the directory in which the executable for this
574 * On UN*X, we use the DATAFILE_DIR value supplied by the configure
575 * script, unless we think we're being run from the build directory,
576 * in which case we use the directory in which the executable for this
579 * XXX - if we ever make libwireshark a real library, used by multiple
580 * applications (more than just TShark and versions of Wireshark with
581 * various UIs), should the configuration files belong to the library
582 * (and be shared by all those applications) or to the applications?
584 * If they belong to the library, that could be done on UNIX by the
585 * configure script, but it's trickier on Windows, as you can't just
586 * use the pathname of the executable.
588 * If they belong to the application, that could be done on Windows
589 * by using the pathname of the executable, but we'd have to have it
590 * passed in as an argument, in some call, on UNIX.
592 * Note that some of those configuration files might be used by code in
593 * libwireshark, some of them might be used by dissectors (would they
594 * belong to libwireshark, the application, or a separate library?),
595 * and some of them might be used by other code (the Wireshark preferences
596 * file includes resolver preferences that control the behavior of code
597 * in libwireshark, dissector preferences, and UI preferences, for
601 get_datafile_dir(void)
604 char *u3deviceexecpath;
606 static const char *datafile_dir = NULL;
608 if (datafile_dir != NULL)
613 * See if we are running in a U3 environment.
615 u3deviceexecpath = getenv_utf8("U3_DEVICE_EXEC_PATH");
617 if (u3deviceexecpath != NULL) {
619 * We are; use the U3 device executable path.
621 datafile_dir = u3deviceexecpath;
624 * Do we have the pathname of the program? If so, assume we're
625 * running an installed version of the program. If we fail,
626 * we don't change "datafile_dir", and thus end up using the
629 * XXX - does NSIS put the installation directory into
630 * "\HKEY_LOCAL_MACHINE\SOFTWARE\Wireshark\InstallDir"?
631 * If so, perhaps we should read that from the registry,
634 if (progfile_dir != NULL) {
636 * Yes, we do; use that.
638 datafile_dir = progfile_dir;
642 * Fall back on the default installation directory.
644 datafile_dir = "C:\\Program Files\\Wireshark\\";
648 if (running_in_build_directory_flag && progfile_dir != NULL) {
650 * We're (probably) being run from the build directory and
651 * weren't started with special privileges, and we were
652 * able to determine the directory in which the program
653 * was found, so use that.
655 datafile_dir = progfile_dir;
658 * Return the directory specified when the build was
659 * configured, prepending the run path prefix if it exists.
661 if (getenv("WIRESHARK_DATA_DIR") && !started_with_special_privs()) {
663 * The user specified a different directory for data files
664 * and we aren't running with special privileges.
665 * XXX - We might be able to dispense with the priv check
667 datafile_dir = g_strdup(getenv("WIRESHARK_DATA_DIR"));
669 datafile_dir = DATAFILE_DIR;
679 * Find the directory where the python dissectors are stored.
681 * On Windows, we use the "py_dissector" subdirectory of the datafile directory.
683 * On UN*X, we use the PYTHON_DIR value supplied by the configure
684 * script, unless we think we're being run from the build directory,
685 * in which case we use the "py_dissector" subdirectory of the datafile directory.
687 * In both cases, we then use the subdirectory of that directory whose
688 * name is the version number.
690 * XXX - if we think we're being run from the build directory, perhaps we
691 * should have the plugin code not look in the version subdirectory
692 * of the plugin directory, but look in all of the subdirectories
693 * of the plugin directory, so it can just fetch the plugins built
694 * as part of the build process.
696 static const char *wspython_dir = NULL;
699 init_wspython_dir(void)
703 * On Windows, the data file directory is the installation
704 * directory; the python dissectors are stored under it.
706 * Assume we're running the installed version of Wireshark;
707 * on Windows, the data file directory is the directory
708 * in which the Wireshark binary resides.
710 wspython_dir = g_strdup_printf("%s\\python\\%s", get_datafile_dir(),
714 * Make sure that pathname refers to a directory.
716 if (test_for_directory(wspython_dir) != EISDIR) {
718 * Either it doesn't refer to a directory or it
719 * refers to something that doesn't exist.
721 * Assume that means we're running a version of
722 * Wireshark we've built in a build directory,
723 * in which case {datafile dir}\python is the
724 * top-level plugins source directory, and use
725 * that directory and set the "we're running in
726 * a build directory" flag, so the plugin
727 * scanner will check all subdirectories of that
728 * directory for python dissectors.
730 g_free( (gpointer) wspython_dir);
731 wspython_dir = g_strdup_printf("%s\\python", get_datafile_dir());
732 running_in_build_directory_flag = TRUE;
735 if (running_in_build_directory_flag) {
737 * We're (probably) being run from the build directory and
738 * weren't started with special privileges, so we'll use
739 * the "python" subdirectory of the datafile directory
740 * (the datafile directory is the build directory).
742 wspython_dir = g_strdup_printf("%s/epan/wspython/", get_datafile_dir());
744 if (getenv("WIRESHARK_PYTHON_DIR") && !started_with_special_privs()) {
746 * The user specified a different directory for plugins
747 * and we aren't running with special privileges.
749 wspython_dir = g_strdup(getenv("WIRESHARK_PYTHON_DIR"));
751 wspython_dir = PYTHON_DIR;
756 #endif /* HAVE_PYTHON */
759 * Get the directory in which the python dissectors are stored.
762 get_wspython_dir(void)
765 if (!wspython_dir) init_wspython_dir();
773 #if defined(HAVE_PLUGINS) || defined(HAVE_LUA_5_1)
775 * Find the directory where the plugins are stored.
777 * On Windows, we use the "plugin" subdirectory of the datafile directory.
779 * On UN*X, we use the PLUGIN_DIR value supplied by the configure
780 * script, unless we think we're being run from the build directory,
781 * in which case we use the "plugin" subdirectory of the datafile directory.
783 * In both cases, we then use the subdirectory of that directory whose
784 * name is the version number.
786 * XXX - if we think we're being run from the build directory, perhaps we
787 * should have the plugin code not look in the version subdirectory
788 * of the plugin directory, but look in all of the subdirectories
789 * of the plugin directory, so it can just fetch the plugins built
790 * as part of the build process.
792 static const char *plugin_dir = NULL;
795 init_plugin_dir(void)
799 * On Windows, the data file directory is the installation
800 * directory; the plugins are stored under it.
802 * Assume we're running the installed version of Wireshark;
803 * on Windows, the data file directory is the directory
804 * in which the Wireshark binary resides.
806 plugin_dir = g_strdup_printf("%s\\plugins\\%s", get_datafile_dir(),
810 * Make sure that pathname refers to a directory.
812 if (test_for_directory(plugin_dir) != EISDIR) {
814 * Either it doesn't refer to a directory or it
815 * refers to something that doesn't exist.
817 * Assume that means we're running a version of
818 * Wireshark we've built in a build directory,
819 * in which case {datafile dir}\plugins is the
820 * top-level plugins source directory, and use
821 * that directory and set the "we're running in
822 * a build directory" flag, so the plugin
823 * scanner will check all subdirectories of that
824 * directory for plugins.
826 g_free( (gpointer) plugin_dir);
827 plugin_dir = g_strdup_printf("%s\\plugins", get_datafile_dir());
828 running_in_build_directory_flag = TRUE;
831 if (running_in_build_directory_flag) {
833 * We're (probably) being run from the build directory and
834 * weren't started with special privileges, so we'll use
835 * the "plugins" subdirectory of the datafile directory
836 * (the datafile directory is the build directory).
838 plugin_dir = g_strdup_printf("%s/plugins", get_datafile_dir());
840 if (getenv("WIRESHARK_PLUGIN_DIR") && !started_with_special_privs()) {
842 * The user specified a different directory for plugins
843 * and we aren't running with special privileges.
845 plugin_dir = g_strdup(getenv("WIRESHARK_PLUGIN_DIR"));
847 plugin_dir = PLUGIN_DIR;
852 #endif /* HAVE_PLUGINS || HAVE_LUA_5_1 */
855 * Get the directory in which the plugins are stored.
860 #if defined(HAVE_PLUGINS) || defined(HAVE_LUA_5_1)
861 if (!plugin_dir) init_plugin_dir();
869 * Get the flag indicating whether we're running from a build
873 running_in_build_directory(void)
875 return running_in_build_directory_flag;
879 * Get the directory in which files that, at least on UNIX, are
880 * system files (such as "/etc/ethers") are stored; on Windows,
881 * there's no "/etc" directory, so we get them from the global
882 * configuration and data file directory.
885 get_systemfile_dir(void)
888 return get_datafile_dir();
895 * Name of directory, under the user's home directory, in which
896 * personal configuration files are stored.
899 #define PF_DIR "Wireshark"
902 * XXX - should this be ".libepan"? For backwards-compatibility, I'll keep
903 * it ".wireshark" for now.
905 #define PF_DIR ".wireshark"
909 /* utf8 version of getenv, needed to get win32 filename paths */
910 char *getenv_utf8(const char *varname)
916 envvar = getenv(varname);
918 /* since GLib 2.6 we need an utf8 version of the filename */
919 #if GLIB_CHECK_VERSION(2,6,0)
920 /* using the wide char version of getenv should work under all circumstances */
922 /* convert given varname to utf16, needed by _wgetenv */
923 varnamew = g_utf8_to_utf16(varname, -1, NULL, NULL, NULL);
924 if (varnamew == NULL) {
928 /* use wide char version of getenv */
929 envvarw = _wgetenv(varnamew);
931 if (envvarw == NULL) {
935 /* convert value to utf8 */
936 envvar = g_utf16_to_utf8(envvarw, -1, NULL, NULL, NULL);
945 set_profile_name(const gchar *profilename)
947 g_free (persconfprofile);
949 if (profilename && strlen(profilename) > 0 &&
950 strcmp(profilename, DEFAULT_PROFILE) != 0) {
951 persconfprofile = g_strdup (profilename);
953 /* Default Profile */
954 persconfprofile = NULL;
959 get_profile_name(void)
961 if (persconfprofile) {
962 return persconfprofile;
964 return DEFAULT_PROFILE;
969 profile_store_persconffiles(gboolean store)
972 profile_files = g_hash_table_new (g_str_hash, g_str_equal);
974 do_store_persconffiles = store;
978 * Get the directory in which personal configuration files reside;
979 * in UNIX-compatible systems, it's ".wireshark", under the user's home
980 * directory, and on Windows systems, it's "Wireshark", under %APPDATA%
981 * or, if %APPDATA% isn't set, it's "%USERPROFILE%\Application Data"
982 * (which is what %APPDATA% normally is on Windows 2000).
985 get_persconffile_dir_no_profile(void)
989 char *userprofiledir;
996 /* Return the cached value, if available */
997 if (persconffile_dir != NULL)
998 return persconffile_dir;
1002 * See if we are running in a U3 environment.
1004 u3appdatapath = getenv_utf8("U3_APP_DATA_PATH");
1005 if (u3appdatapath != NULL) {
1007 * We are; use the U3 application data path.
1009 persconffile_dir = u3appdatapath;
1012 * Use %APPDATA% or %USERPROFILE%, so that configuration
1013 * files are stored in the user profile, rather than in
1014 * the home directory. The Windows convention is to store
1015 * configuration information in the user profile, and doing
1016 * so means you can use Wireshark even if the home directory
1017 * is an inaccessible network drive.
1019 appdatadir = getenv_utf8("APPDATA");
1020 if (appdatadir != NULL) {
1022 * Concatenate %APPDATA% with "\Wireshark".
1024 persconffile_dir = g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s",
1025 appdatadir, PF_DIR);
1028 * OK, %APPDATA% wasn't set, so use
1029 * %USERPROFILE%\Application Data.
1031 userprofiledir = getenv_utf8("USERPROFILE");
1032 if (userprofiledir != NULL) {
1033 persconffile_dir = g_strdup_printf(
1034 "%s" G_DIR_SEPARATOR_S "Application Data" G_DIR_SEPARATOR_S "%s",
1035 userprofiledir, PF_DIR);
1038 * Give up and use "C:".
1040 persconffile_dir = g_strdup_printf("C:" G_DIR_SEPARATOR_S "%s", PF_DIR);
1046 * If $HOME is set, use that.
1048 homedir = getenv("HOME");
1049 if (homedir == NULL) {
1051 * Get their home directory from the password file.
1052 * If we can't even find a password file entry for them,
1055 pwd = getpwuid(getuid());
1058 * This is cached, so we don't need to worry
1059 * about allocating multiple ones of them.
1061 homedir = g_strdup(pwd->pw_dir);
1065 persconffile_dir = g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s", homedir, PF_DIR);
1068 return persconffile_dir;
1072 get_profiles_dir(void)
1074 static char *profiles_dir = NULL;
1076 g_free (profiles_dir);
1077 profiles_dir = g_strdup_printf ("%s%s%s", get_persconffile_dir_no_profile (),
1078 G_DIR_SEPARATOR_S, PROFILES_DIR);
1080 return profiles_dir;
1084 get_persconffile_dir(const gchar *profilename)
1086 static char *persconffile_profile_dir = NULL;
1088 g_free (persconffile_profile_dir);
1090 if (profilename && strlen(profilename) > 0 &&
1091 strcmp(profilename, DEFAULT_PROFILE) != 0) {
1092 persconffile_profile_dir = g_strdup_printf ("%s%s%s", get_profiles_dir (),
1093 G_DIR_SEPARATOR_S, profilename);
1095 persconffile_profile_dir = g_strdup (get_persconffile_dir_no_profile ());
1098 return persconffile_profile_dir;
1102 profile_exists(const gchar *profilename)
1104 if (test_for_directory (get_persconffile_dir (profilename)) == EISDIR) {
1112 delete_directory (const char *directory, char **pf_dir_path_return)
1119 if ((dir = ws_dir_open(directory, 0, NULL)) != NULL) {
1120 while ((file = ws_dir_read_name(dir)) != NULL) {
1121 filename = g_strdup_printf ("%s%s%s", directory, G_DIR_SEPARATOR_S,
1122 ws_dir_get_name(file));
1123 if (test_for_directory(filename) != EISDIR) {
1124 ret = ws_remove(filename);
1127 /* The user has manually created a directory in the profile directory */
1128 /* I do not want to delete the directory recursively yet */
1129 ret = delete_directory (filename, pf_dir_path_return);
1133 *pf_dir_path_return = filename;
1141 if (ret == 0 && (ret = ws_remove(directory)) != 0) {
1142 *pf_dir_path_return = g_strdup (directory);
1149 delete_persconffile_profile(const char *profilename, char **pf_dir_path_return)
1151 const char *profile_dir = get_persconffile_dir(profilename);
1154 if (test_for_directory (profile_dir) == EISDIR) {
1155 ret = delete_directory (profile_dir, pf_dir_path_return);
1162 rename_persconffile_profile(const char *fromname, const char *toname,
1163 char **pf_from_dir_path_return, char **pf_to_dir_path_return)
1165 char *from_dir = g_strdup (get_persconffile_dir(fromname));
1166 char *to_dir = g_strdup (get_persconffile_dir(toname));
1169 ret = ws_rename (from_dir, to_dir);
1171 *pf_from_dir_path_return = g_strdup (from_dir);
1172 *pf_to_dir_path_return = g_strdup (to_dir);
1182 * Create the directory that holds personal configuration files, if
1183 * necessary. If we attempted to create it, and failed, return -1 and
1184 * set "*pf_dir_path_return" to the pathname of the directory we failed
1185 * to create (it's g_mallocated, so our caller should free it); otherwise,
1189 create_persconffile_profile(const char *profilename, char **pf_dir_path_return)
1191 const char *pf_dir_path;
1193 char *pf_dir_path_copy, *pf_dir_parent_path;
1194 size_t pf_dir_parent_path_len;
1201 * Check if profiles directory exists.
1202 * If not then create it.
1204 pf_dir_path = get_profiles_dir ();
1205 if (ws_stat(pf_dir_path, &s_buf) != 0 && errno == ENOENT) {
1206 ret = ws_mkdir(pf_dir_path, 0755);
1208 *pf_dir_path_return = g_strdup(pf_dir_path);
1214 pf_dir_path = get_persconffile_dir(profilename);
1215 if (ws_stat(pf_dir_path, &s_buf) != 0 && errno == ENOENT) {
1218 * Does the parent directory of that directory
1219 * exist? %APPDATA% may not exist even though
1220 * %USERPROFILE% does.
1222 * We check for the existence of the directory
1223 * by first checking whether the parent directory
1224 * is just a drive letter and, if it's not, by
1225 * doing a "stat()" on it. If it's a drive letter,
1226 * or if the "stat()" succeeds, we assume it exists.
1228 pf_dir_path_copy = g_strdup(pf_dir_path);
1229 pf_dir_parent_path = get_dirname(pf_dir_path_copy);
1230 pf_dir_parent_path_len = strlen(pf_dir_parent_path);
1231 if (pf_dir_parent_path_len > 0
1232 && pf_dir_parent_path[pf_dir_parent_path_len - 1] != ':'
1233 && ws_stat(pf_dir_parent_path, &s_buf) != 0) {
1235 * No, it doesn't exist - make it first.
1237 ret = ws_mkdir(pf_dir_parent_path, 0755);
1239 *pf_dir_path_return = pf_dir_parent_path;
1243 g_free(pf_dir_path_copy);
1244 ret = ws_mkdir(pf_dir_path, 0755);
1246 ret = ws_mkdir(pf_dir_path, 0755);
1250 * Something with that pathname exists; if it's not
1251 * a directory, we'll get an error if we try to put
1252 * something in it, so we don't fail here, we wait
1253 * for that attempt fo fail.
1258 *pf_dir_path_return = g_strdup(pf_dir_path);
1263 create_persconffile_dir(char **pf_dir_path_return)
1265 return create_persconffile_profile(persconfprofile, pf_dir_path_return);
1268 #if ! GLIB_CHECK_VERSION(2,14,0)
1270 hash_table_get_keys(gpointer key, gpointer value _U_, gpointer user_data)
1272 GList **files = ((GList **)user_data);
1273 *files = g_list_append (*files, key);
1278 copy_persconffile_profile(const char *toname, const char *fromname, char **pf_filename_return,
1279 char **pf_to_dir_path_return, char **pf_from_dir_path_return)
1281 gchar *from_dir = g_strdup (get_persconffile_dir(fromname));
1282 gchar *to_dir = g_strdup (get_persconffile_dir(toname));
1283 gchar *filename, *from_file, *to_file;
1284 GList *files, *file;
1286 #if GLIB_CHECK_VERSION(2,14,0)
1287 files = g_hash_table_get_keys(profile_files);
1290 g_hash_table_foreach(profile_files, hash_table_get_keys, &files);
1293 file = g_list_first(files);
1295 filename = (gchar *)file->data;
1296 from_file = g_strdup_printf ("%s%s%s", from_dir, G_DIR_SEPARATOR_S, filename);
1297 to_file = g_strdup_printf ("%s%s%s", to_dir, G_DIR_SEPARATOR_S, filename);
1299 if (file_exists(from_file) && !copy_file_binary_mode(from_file, to_file)) {
1300 *pf_filename_return = g_strdup(filename);
1301 *pf_to_dir_path_return = to_dir;
1302 *pf_from_dir_path_return = from_dir;
1311 file = g_list_next(file);
1314 g_list_free (files);
1322 * Get the (default) directory in which personal data is stored.
1324 * On Win32, this is the "My Documents" folder in the personal profile,
1325 * except that, if we're running from a U3 device, this is the
1326 * "$U3_DEVICE_DOCUMENT_PATH\My Captures" folder.
1327 * On UNIX this is simply the current directory.
1329 /* XXX - should this and the get_home_dir() be merged? */
1331 get_persdatafile_dir(void)
1334 char *u3devicedocumentpath;
1335 TCHAR tszPath[MAX_PATH];
1339 /* Return the cached value, if available */
1340 if (persdatafile_dir != NULL)
1341 return persdatafile_dir;
1344 * See if we are running in a U3 environment.
1346 u3devicedocumentpath = getenv_utf8("U3_DEVICE_DOCUMENT_PATH");
1348 if (u3devicedocumentpath != NULL) {
1349 /* the "My Captures" sub-directory is created (if it doesn't
1350 exist) by u3util.exe when the U3 Wireshark is first run */
1352 szPath = g_strdup_printf("%s%s", u3devicedocumentpath, U3_MY_CAPTURES);
1354 persdatafile_dir = szPath;
1358 * Hint: SHGetFolderPath is not available on MSVC 6 - without
1361 bRet = SHGetSpecialFolderPath(NULL, tszPath, CSIDL_PERSONAL,
1364 szPath = utf_16to8(tszPath);
1365 persdatafile_dir = szPath;
1378 * Returns the user's home directory on Win32.
1383 static const char *home = NULL;
1384 char *homedrive, *homepath;
1388 /* Return the cached value, if available */
1393 * XXX - should we use USERPROFILE anywhere in this process?
1394 * Is there a chance that it might be set but one or more of
1395 * HOMEDRIVE or HOMEPATH isn't set?
1397 homedrive = getenv_utf8("HOMEDRIVE");
1398 if (homedrive != NULL) {
1399 homepath = getenv_utf8("HOMEPATH");
1400 if (homepath != NULL) {
1402 * This is cached, so we don't need to worry about
1403 * allocating multiple ones of them.
1405 homestring = g_strdup_printf("%s%s", homedrive, homepath);
1408 * Trim off any trailing slash or backslash.
1410 lastsep = find_last_pathname_separator(homestring);
1411 if (lastsep != NULL && *(lastsep + 1) == '\0') {
1413 * Last separator is the last character
1414 * in the string. Nuke it.
1423 * Give up and use C:.
1433 * Construct the path name of a personal configuration file, given the
1436 * On Win32, if "for_writing" is FALSE, we check whether the file exists
1437 * and, if not, construct a path name relative to the ".wireshark"
1438 * subdirectory of the user's home directory, and check whether that
1439 * exists; if it does, we return that, so that configuration files
1440 * from earlier versions can be read.
1442 * The returned file name was g_malloc()'d so it must be g_free()d when the
1443 * caller is done with it.
1446 get_persconffile_path(const char *filename, gboolean from_profile, gboolean for_writing
1457 if (do_store_persconffiles && from_profile && !g_hash_table_lookup (profile_files, filename)) {
1458 /* Store filenames so we know which filenames belongs to a configuration profile */
1459 g_hash_table_insert (profile_files, g_strdup(filename), g_strdup(filename));
1463 path = g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s",
1464 get_persconffile_dir(persconfprofile), filename);
1466 path = g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s",
1467 get_persconffile_dir(NULL), filename);
1471 if (ws_stat(path, &s_buf) != 0 && errno == ENOENT) {
1473 * OK, it's not in the personal configuration file
1474 * directory; is it in the ".wireshark" subdirectory
1475 * of their home directory?
1477 old_path = g_strdup_printf(
1478 "%s" G_DIR_SEPARATOR_S ".wireshark" G_DIR_SEPARATOR_S "%s",
1479 get_home_dir(), filename);
1480 if (ws_stat(old_path, &s_buf) == 0) {
1482 * OK, it exists; return it instead.
1495 * process command line option belonging to the filesystem settings
1496 * (move this e.g. to main.c and have set_persconffile_dir() instead in this file?)
1499 filesystem_opt(int opt _U_, const char *optstr)
1503 colonp = strchr(optstr, ':');
1504 if (colonp == NULL) {
1512 * Skip over any white space (there probably won't be any, but
1513 * as we allow it in the preferences file, we might as well
1516 while (isspace((guchar)*p))
1520 * Put the colon back, so if our caller uses, in an
1521 * error message, the string they passed us, the message
1528 /* directory should be existing */
1529 /* XXX - is this a requirement? */
1530 if(test_for_directory(p) != EISDIR) {
1532 * Put the colon back, so if our caller uses, in an
1533 * error message, the string they passed us, the message
1540 if (strcmp(optstr,"persconf") == 0) {
1541 persconffile_dir = p;
1542 } else if (strcmp(optstr,"persdata") == 0) {
1543 persdatafile_dir = p;
1544 /* XXX - might need to add the temp file path */
1548 *colonp = ':'; /* put the colon back */
1553 * Construct the path name of a global configuration file, given the
1556 * The returned file name was g_malloc()'d so it must be g_free()d when the
1557 * caller is done with it.
1560 get_datafile_path(const char *filename)
1563 return g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s", get_datafile_dir(),
1567 /* Get the personal plugin dir */
1568 /* Return value is malloced so the caller should g_free() it. */
1570 get_plugins_pers_dir(void)
1572 return get_persconffile_path(PLUGINS_DIR_NAME, FALSE, FALSE);
1577 deletefile(const char *path)
1579 return ws_unlink(path) == 0;
1583 * Construct and return the path name of a file in the
1584 * appropriate temporary file directory.
1586 char *get_tempfile_path(const char *filename)
1588 return g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s", g_get_tmp_dir(), filename);
1592 * Return an error message for UNIX-style errno indications on open or
1593 * create operations.
1596 file_open_error_message(int err, gboolean for_writing)
1599 static char errmsg_errno[1024+1];
1605 errmsg = "The path to the file \"%s\" doesn't exist.";
1607 errmsg = "The file \"%s\" doesn't exist.";
1612 errmsg = "You don't have permission to create or write to the file \"%s\".";
1614 errmsg = "You don't have permission to read the file \"%s\".";
1618 errmsg = "\"%s\" is a directory (folder), not a file.";
1622 errmsg = "The file \"%s\" could not be created because there is no space left on the file system.";
1627 errmsg = "The file \"%s\" could not be created because you are too close to, or over, your disk quota.";
1632 errmsg = "The file \"%s\" could not be created because an invalid filename was specified.";
1636 g_snprintf(errmsg_errno, sizeof(errmsg_errno),
1637 "The file \"%%s\" could not be %s: %s.",
1638 for_writing ? "created" : "opened",
1640 errmsg = errmsg_errno;
1647 * Return an error message for UNIX-style errno indications on write
1651 file_write_error_message(int err)
1654 static char errmsg_errno[1024+1];
1659 errmsg = "The file \"%s\" could not be saved because there is no space left on the file system.";
1664 errmsg = "The file \"%s\" could not be saved because you are too close to, or over, your disk quota.";
1669 g_snprintf(errmsg_errno, sizeof(errmsg_errno),
1670 "An error occurred while writing to the file \"%%s\": %s.",
1672 errmsg = errmsg_errno;
1680 file_exists(const char *fname)
1682 struct stat file_stat;
1686 * This is a bit tricky on win32. The st_ino field is documented as:
1687 * "The inode, and therefore st_ino, has no meaning in the FAT, ..."
1688 * but it *is* set to zero if stat() returns without an error,
1689 * so this is working, but maybe not quite the way expected. ULFL
1691 file_stat.st_ino = 1; /* this will make things work if an error occured */
1692 ws_stat(fname, &file_stat);
1693 if (file_stat.st_ino == 0) {
1699 if (ws_stat(fname, &file_stat) != 0 && errno == ENOENT) {
1708 * Check that the from file is not the same as to file
1709 * We do it here so we catch all cases ...
1710 * Unfortunately, the file requester gives us an absolute file
1711 * name and the read file name may be relative (if supplied on
1712 * the command line), so we can't just compare paths. From Joerg Mayer.
1715 files_identical(const char *fname1, const char *fname2)
1717 /* Two different implementations, because:
1719 * - _fullpath is not available on UN*X, so we can't get full
1720 * paths and compare them (which wouldn't work with hard links
1723 * - st_ino isn't filled in with a meaningful value on Windows.
1726 char full1[MAX_PATH], full2[MAX_PATH];
1729 * Get the absolute full paths of the file and compare them.
1730 * That won't work if you have hard links, but those aren't
1731 * much used on Windows, even though NTFS supports them.
1733 * XXX - will _fullpath work with UNC?
1735 if( _fullpath( full1, fname1, MAX_PATH ) == NULL ) {
1739 if( _fullpath( full2, fname2, MAX_PATH ) == NULL ) {
1743 if(strcmp(full1, full2) == 0) {
1749 struct stat filestat1, filestat2;
1752 * Compare st_dev and st_ino.
1754 if (ws_stat(fname1, &filestat1) == -1)
1755 return FALSE; /* can't get info about the first file */
1756 if (ws_stat(fname2, &filestat2) == -1)
1757 return FALSE; /* can't get info about the second file */
1758 return (filestat1.st_dev == filestat2.st_dev &&
1759 filestat1.st_ino == filestat2.st_ino);
1764 * Copy a file in binary mode, for those operating systems that care about
1765 * such things. This should be OK for all files, even text files, as
1766 * we'll copy the raw bytes, and we don't look at the bytes as we copy
1769 * Returns TRUE on success, FALSE on failure. If a failure, it also
1770 * displays a simple dialog window with the error message.
1773 copy_file_binary_mode(const char *from_filename, const char *to_filename)
1775 int from_fd, to_fd, nread, nwritten, err;
1778 /* Copy the raw bytes of the file. */
1779 from_fd = ws_open(from_filename, O_RDONLY | O_BINARY, 0000 /* no creation so don't matter */);
1781 report_open_failure(from_filename, errno, FALSE);
1785 /* Use open() instead of creat() so that we can pass the O_BINARY
1786 flag, which is relevant on Win32; it appears that "creat()"
1787 may open the file in text mode, not binary mode, but we want
1788 to copy the raw bytes of the file, so we need the output file
1789 to be open in binary mode. */
1790 to_fd = ws_open(to_filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644);
1792 report_open_failure(to_filename, errno, TRUE);
1797 while ((nread = ws_read(from_fd, pd, sizeof pd)) > 0) {
1798 nwritten = ws_write(to_fd, pd, nread);
1799 if (nwritten < nread) {
1803 err = WTAP_ERR_SHORT_WRITE;
1804 report_write_failure(to_filename, err);
1812 report_read_failure(from_filename, err);
1818 if (ws_close(to_fd) < 0) {
1819 report_write_failure(to_filename, errno);
1835 * indent-tabs-mode: t
1838 * ex: set shiftwidth=4 tabstop=4 noexpandtab
1839 * :indentSize=4:tabSize=4:noTabs=false: