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_stat64(path, &statb) < 0)
223 if (S_ISDIR(statb.st_mode))
230 test_for_fifo(const char *path)
234 if (ws_stat64(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)
271 TCHAR prog_pathname_w[_MAX_PATH+2];
279 * Attempt to get the full pathname of the currently running
282 if (GetModuleFileName(NULL, prog_pathname_w, G_N_ELEMENTS(prog_pathname_w)) != 0 && GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
284 * XXX - Should we use g_utf16_to_utf8(), as in
287 prog_pathname = utf_16to8(prog_pathname_w);
289 * We got it; strip off the last component, which would be
290 * the file name of the executable, giving us the pathname
291 * of the directory where the executable resides.
293 progfile_dir = g_path_get_dirname(prog_pathname);
294 if (progfile_dir != NULL) {
295 return NULL; /* we succeeded */
298 * OK, no. What do we do now?
300 return g_strdup_printf("No \\ in executable pathname \"%s\"",
305 * Oh, well. Return an indication of the error.
307 error = GetLastError();
308 if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM,
309 NULL, error, 0, (LPTSTR) &msg_w, 0, NULL) == 0) {
311 * Gak. We can't format the message.
313 return g_strdup_printf("GetModuleFileName failed: %u (FormatMessage failed: %u)",
314 error, GetLastError());
316 msg = utf_16to8(msg_w);
319 * "FormatMessage()" "helpfully" sticks CR/LF at the
320 * end of the message. Get rid of it.
322 msglen = strlen(msg);
324 msg[msglen - 1] = '\0';
325 msg[msglen - 2] = '\0';
327 return g_strdup_printf("GetModuleFileName failed: %s (%u)",
331 #ifdef DLADDR_FINDS_EXECUTABLE_PATH
338 char *path_start, *path_end;
339 size_t path_component_len;
345 * Check whether WIRESHARK_RUN_FROM_BUILD_DIRECTORY is set in the
346 * environment; if so, set running_in_build_directory_flag if we
347 * weren't started with special privileges. (If we were started
348 * with special privileges, it's not safe to allow the user to point
349 * us to some other directory; running_in_build_directory_flag, when
350 * set, causes us to look for plugins and the like in the build
353 if (getenv("WIRESHARK_RUN_FROM_BUILD_DIRECTORY") != NULL
354 && !started_with_special_privs())
355 running_in_build_directory_flag = TRUE;
357 #ifdef DLADDR_FINDS_EXECUTABLE_PATH
359 * Try to use dladdr() to find the pathname of the executable.
360 * dladdr() is not guaranteed to give you anything better than
361 * argv[0] (i.e., it might not contain a / at all, much less
362 * being an absolute path), and doesn't appear to do so on
363 * Linux, but on other platforms it could give you an absolute
364 * path and obviate the need for us to determine the absolute
367 if (dladdr((void *)main_addr, &info))
368 arg0 = info.dli_fname;
371 * Try to figure out the directory in which the currently running
372 * program resides, given something purporting to be the executable
373 * name (from dladdr() or from the argv[0] it was started with.
374 * That might be the absolute path of the program, or a path relative
375 * to the current directory of the process that started it, or
376 * just a name for the program if it was started from the command
377 * line and was searched for in $PATH. It's not guaranteed to be
378 * any of those, however, so there are no guarantees....
380 if (arg0[0] == '/') {
382 * It's an absolute path.
384 prog_pathname = g_strdup(arg0);
385 } else if (strchr(arg0, '/') != NULL) {
387 * It's a relative path, with a directory in it.
388 * Get the current directory, and combine it
389 * with that directory.
391 path_max = pathconf(".", _PC_PATH_MAX);
392 if (path_max == -1) {
394 * We have no idea how big a buffer to
395 * allocate for the current directory.
397 return g_strdup_printf("pathconf failed: %s\n",
400 curdir = (char *)g_malloc(path_max);
401 if (getcwd(curdir, path_max) == NULL) {
403 * It failed - give up, and just stick
407 return g_strdup_printf("getcwd failed: %s\n",
410 path = g_strdup_printf("%s/%s", curdir, arg0);
412 prog_pathname = path;
415 * It's just a file name.
416 * Search the path for a file with that name
419 prog_pathname = NULL; /* haven't found it yet */
420 pathstr = getenv("PATH");
421 path_start = pathstr;
422 if (path_start != NULL) {
423 while (*path_start != '\0') {
424 path_end = strchr(path_start, ':');
425 if (path_end == NULL)
426 path_end = path_start + strlen(path_start);
427 path_component_len = path_end - path_start;
428 path = (char *)g_malloc(path_component_len + 1
430 memcpy(path, path_start, path_component_len);
431 path[path_component_len] = '\0';
432 strncat(path, "/", 2);
433 strncat(path, arg0, strlen(arg0) + 1);
434 if (access(path, X_OK) == 0) {
438 prog_pathname = path;
443 * That's not it. If there are more
444 * path components to test, try them.
446 if (*path_end == '\0') {
448 * There's nothing more to try.
452 if (*path_end == ':')
454 path_start = path_end;
457 if (prog_pathname == NULL) {
459 * Program not found in path.
461 return g_strdup_printf("\"%s\" not found in \"%s\"",
467 * XXX - should we pick a default?
469 return g_strdup("PATH isn't set");
474 * OK, we have what we think is the pathname
477 * First, find the last "/" in the directory,
478 * as that marks the end of the directory pathname.
480 dir_end = strrchr(prog_pathname, '/');
481 if (dir_end != NULL) {
483 * Found it. Strip off the last component,
484 * as that's the path of the program.
489 * Is there a "/.libs" at the end?
491 dir_end = strrchr(prog_pathname, '/');
492 if (dir_end != NULL) {
493 if (strcmp(dir_end, "/.libs") == 0) {
496 * Strip that off; it's an
497 * artifact of libtool.
502 * This presumably means we're run from
503 * the libtool wrapper, which probably
504 * means we're being run from the build
505 * directory. If we weren't started
506 * with special privileges, set
507 * running_in_build_directory_flag.
509 * XXX - should we check whether what
510 * follows ".libs/" begins with "lt-"?
512 if (!started_with_special_privs())
513 running_in_build_directory_flag = TRUE;
518 * OK, we have the path we want.
520 progfile_dir = prog_pathname;
524 * This "shouldn't happen"; we apparently
525 * have no "/" in the pathname.
526 * Just free up prog_pathname.
528 retstr = g_strdup_printf("No / found in \"%s\"", prog_pathname);
529 g_free(prog_pathname);
536 * Get the directory in which the program resides.
539 get_progfile_dir(void)
545 * Get the directory in which the global configuration and data files are
548 * On Windows, we use the directory in which the executable for this
551 * On UN*X, we use the DATAFILE_DIR value supplied by the configure
552 * script, unless we think we're being run from the build directory,
553 * in which case we use the directory in which the executable for this
556 * XXX - if we ever make libwireshark a real library, used by multiple
557 * applications (more than just TShark and versions of Wireshark with
558 * various UIs), should the configuration files belong to the library
559 * (and be shared by all those applications) or to the applications?
561 * If they belong to the library, that could be done on UNIX by the
562 * configure script, but it's trickier on Windows, as you can't just
563 * use the pathname of the executable.
565 * If they belong to the application, that could be done on Windows
566 * by using the pathname of the executable, but we'd have to have it
567 * passed in as an argument, in some call, on UNIX.
569 * Note that some of those configuration files might be used by code in
570 * libwireshark, some of them might be used by dissectors (would they
571 * belong to libwireshark, the application, or a separate library?),
572 * and some of them might be used by other code (the Wireshark preferences
573 * file includes resolver preferences that control the behavior of code
574 * in libwireshark, dissector preferences, and UI preferences, for
578 get_datafile_dir(void)
581 char *u3deviceexecpath;
583 static const char *datafile_dir = NULL;
585 if (datafile_dir != NULL)
590 * See if we are running in a U3 environment.
592 u3deviceexecpath = getenv_utf8("U3_DEVICE_EXEC_PATH");
594 if (u3deviceexecpath != NULL) {
596 * We are; use the U3 device executable path.
598 datafile_dir = u3deviceexecpath;
601 * Do we have the pathname of the program? If so, assume we're
602 * running an installed version of the program. If we fail,
603 * we don't change "datafile_dir", and thus end up using the
606 * XXX - does NSIS put the installation directory into
607 * "\HKEY_LOCAL_MACHINE\SOFTWARE\Wireshark\InstallDir"?
608 * If so, perhaps we should read that from the registry,
611 if (progfile_dir != NULL) {
613 * Yes, we do; use that.
615 datafile_dir = progfile_dir;
619 * Fall back on the default installation directory.
621 datafile_dir = "C:\\Program Files\\Wireshark\\";
625 if (running_in_build_directory_flag) {
627 * We're (probably) being run from the build directory and
628 * weren't started with special privileges.
630 * The data files we want are the ones from the source
631 * directory; to handle builds out of the source tree,
632 * we check whether WIRESHARK_SRC_DIR is set and, if so,
633 * use that as the source directory.
635 datafile_dir = getenv("WIRESHARK_SRC_DIR");
636 if (datafile_dir != NULL)
641 * Well, that didn't work.
642 * Check again whether we were (probably) run from the build
643 * directory and started without special privileges, and also
644 * check whether we were able to determine the directory in
645 * which the program was found.
647 if (running_in_build_directory_flag && progfile_dir != NULL) {
649 * We're (probably) being run from the build directory and
650 * weren't started with special privileges, and we were
651 * able to determine the directory in which the program
652 * was found. Assume that directory is the build
653 * directory and that it's the same as the source
656 datafile_dir = progfile_dir;
659 * Return the directory specified when the build was
660 * configured, prepending the run path prefix if it exists.
662 if (getenv("WIRESHARK_DATA_DIR") && !started_with_special_privs()) {
664 * The user specified a different directory for data files
665 * and we aren't running with special privileges.
666 * XXX - We might be able to dispense with the priv check
668 datafile_dir = g_strdup(getenv("WIRESHARK_DATA_DIR"));
670 datafile_dir = DATAFILE_DIR;
680 * Find the directory where the python dissectors are stored.
682 * On Windows, we use the "py_dissector" subdirectory of the datafile directory.
684 * On UN*X, we use the PYTHON_DIR value supplied by the configure
685 * script, unless we think we're being run from the build directory,
686 * in which case we use the "py_dissector" subdirectory of the datafile directory.
688 * In both cases, we then use the subdirectory of that directory whose
689 * name is the version number.
691 * XXX - if we think we're being run from the build directory, perhaps we
692 * should have the plugin code not look in the version subdirectory
693 * of the plugin directory, but look in all of the subdirectories
694 * of the plugin directory, so it can just fetch the plugins built
695 * as part of the build process.
697 static const char *wspython_dir = NULL;
700 init_wspython_dir(void)
704 * On Windows, the data file directory is the installation
705 * directory; the python dissectors are stored under it.
707 * Assume we're running the installed version of Wireshark;
708 * on Windows, the data file directory is the directory
709 * in which the Wireshark binary resides.
711 wspython_dir = g_strdup_printf("%s\\python\\%s", get_datafile_dir(),
715 * Make sure that pathname refers to a directory.
717 if (test_for_directory(wspython_dir) != EISDIR) {
719 * Either it doesn't refer to a directory or it
720 * refers to something that doesn't exist.
722 * Assume that means we're running a version of
723 * Wireshark we've built in a build directory,
724 * in which case {datafile dir}\python is the
725 * top-level plugins source directory, and use
726 * that directory and set the "we're running in
727 * a build directory" flag, so the plugin
728 * scanner will check all subdirectories of that
729 * directory for python dissectors.
731 g_free( (gpointer) wspython_dir);
732 wspython_dir = g_strdup_printf("%s\\python", get_datafile_dir());
733 running_in_build_directory_flag = TRUE;
736 if (running_in_build_directory_flag) {
738 * We're (probably) being run from the build directory and
739 * weren't started with special privileges, so we'll use
740 * the "python" subdirectory of the datafile directory
741 * (the datafile directory is the build directory).
743 wspython_dir = g_strdup_printf("%s/epan/wspython/", get_datafile_dir());
745 if (getenv("WIRESHARK_PYTHON_DIR") && !started_with_special_privs()) {
747 * The user specified a different directory for plugins
748 * and we aren't running with special privileges.
750 wspython_dir = g_strdup(getenv("WIRESHARK_PYTHON_DIR"));
752 wspython_dir = PYTHON_DIR;
757 #endif /* HAVE_PYTHON */
760 * Get the directory in which the python dissectors are stored.
763 get_wspython_dir(void)
766 if (!wspython_dir) init_wspython_dir();
774 #if defined(HAVE_PLUGINS) || defined(HAVE_LUA_5_1)
776 * Find the directory where the plugins are stored.
778 * On Windows, we use the "plugin" subdirectory of the datafile directory.
780 * On UN*X, we use the PLUGIN_DIR value supplied by the configure
781 * script, unless we think we're being run from the build directory,
782 * in which case we use the "plugin" subdirectory of the datafile directory.
784 * In both cases, we then use the subdirectory of that directory whose
785 * name is the version number.
787 * XXX - if we think we're being run from the build directory, perhaps we
788 * should have the plugin code not look in the version subdirectory
789 * of the plugin directory, but look in all of the subdirectories
790 * of the plugin directory, so it can just fetch the plugins built
791 * as part of the build process.
793 static const char *plugin_dir = NULL;
796 init_plugin_dir(void)
800 * On Windows, the data file directory is the installation
801 * directory; the plugins are stored under it.
803 * Assume we're running the installed version of Wireshark;
804 * on Windows, the data file directory is the directory
805 * in which the Wireshark binary resides.
807 plugin_dir = g_strdup_printf("%s\\plugins\\%s", get_datafile_dir(),
811 * Make sure that pathname refers to a directory.
813 if (test_for_directory(plugin_dir) != EISDIR) {
815 * Either it doesn't refer to a directory or it
816 * refers to something that doesn't exist.
818 * Assume that means we're running a version of
819 * Wireshark we've built in a build directory,
820 * in which case {datafile dir}\plugins is the
821 * top-level plugins source directory, and use
822 * that directory and set the "we're running in
823 * a build directory" flag, so the plugin
824 * scanner will check all subdirectories of that
825 * directory for plugins.
827 g_free( (gpointer) plugin_dir);
828 plugin_dir = g_strdup_printf("%s\\plugins", get_datafile_dir());
829 running_in_build_directory_flag = TRUE;
832 if (running_in_build_directory_flag) {
834 * We're (probably) being run from the build directory and
835 * weren't started with special privileges, so we'll use
836 * the "plugins" subdirectory of the datafile directory
837 * (the datafile directory is the build directory).
839 plugin_dir = g_strdup_printf("%s/plugins", get_datafile_dir());
841 if (getenv("WIRESHARK_PLUGIN_DIR") && !started_with_special_privs()) {
843 * The user specified a different directory for plugins
844 * and we aren't running with special privileges.
846 plugin_dir = g_strdup(getenv("WIRESHARK_PLUGIN_DIR"));
848 plugin_dir = PLUGIN_DIR;
853 #endif /* HAVE_PLUGINS || HAVE_LUA_5_1 */
856 * Get the directory in which the plugins are stored.
861 #if defined(HAVE_PLUGINS) || defined(HAVE_LUA_5_1)
862 if (!plugin_dir) init_plugin_dir();
870 * Get the flag indicating whether we're running from a build
874 running_in_build_directory(void)
876 return running_in_build_directory_flag;
880 * Get the directory in which files that, at least on UNIX, are
881 * system files (such as "/etc/ethers") are stored; on Windows,
882 * there's no "/etc" directory, so we get them from the global
883 * configuration and data file directory.
886 get_systemfile_dir(void)
889 return get_datafile_dir();
896 * Name of directory, under the user's home directory, in which
897 * personal configuration files are stored.
900 #define PF_DIR "Wireshark"
903 * XXX - should this be ".libepan"? For backwards-compatibility, I'll keep
904 * it ".wireshark" for now.
906 #define PF_DIR ".wireshark"
910 set_profile_name(const gchar *profilename)
912 g_free (persconfprofile);
914 if (profilename && strlen(profilename) > 0 &&
915 strcmp(profilename, DEFAULT_PROFILE) != 0) {
916 persconfprofile = g_strdup (profilename);
918 /* Default Profile */
919 persconfprofile = NULL;
924 get_profile_name(void)
926 if (persconfprofile) {
927 return persconfprofile;
929 return DEFAULT_PROFILE;
934 is_default_profile(void)
936 return (!persconfprofile || strcmp(persconfprofile, DEFAULT_PROFILE) == 0) ? TRUE : FALSE;
940 has_global_profiles(void)
944 const gchar *global_dir = get_global_profiles_dir();
946 gboolean has_global = FALSE;
948 if ((test_for_directory(global_dir) == EISDIR) &&
949 ((dir = ws_dir_open(global_dir, 0, NULL)) != NULL))
951 while ((file = ws_dir_read_name(dir)) != NULL) {
952 filename = g_strdup_printf ("%s%s%s", global_dir, G_DIR_SEPARATOR_S,
953 ws_dir_get_name(file));
954 if (test_for_directory(filename) == EISDIR) {
968 profile_store_persconffiles(gboolean store)
971 profile_files = g_hash_table_new (g_str_hash, g_str_equal);
973 do_store_persconffiles = store;
977 * Get the directory in which personal configuration files reside;
978 * in UNIX-compatible systems, it's ".wireshark", under the user's home
979 * directory, and on Windows systems, it's "Wireshark", under %APPDATA%
980 * or, if %APPDATA% isn't set, it's "%USERPROFILE%\Application Data"
981 * (which is what %APPDATA% normally is on Windows 2000).
984 get_persconffile_dir_no_profile(void)
988 char *userprofiledir;
995 /* Return the cached value, if available */
996 if (persconffile_dir != NULL)
997 return persconffile_dir;
1001 * See if we are running in a U3 environment.
1003 u3appdatapath = getenv_utf8("U3_APP_DATA_PATH");
1004 if (u3appdatapath != NULL) {
1006 * We are; use the U3 application data path.
1008 persconffile_dir = u3appdatapath;
1011 * Use %APPDATA% or %USERPROFILE%, so that configuration
1012 * files are stored in the user profile, rather than in
1013 * the home directory. The Windows convention is to store
1014 * configuration information in the user profile, and doing
1015 * so means you can use Wireshark even if the home directory
1016 * is an inaccessible network drive.
1018 appdatadir = getenv_utf8("APPDATA");
1019 if (appdatadir != NULL) {
1021 * Concatenate %APPDATA% with "\Wireshark".
1023 persconffile_dir = g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s",
1024 appdatadir, PF_DIR);
1027 * OK, %APPDATA% wasn't set, so use
1028 * %USERPROFILE%\Application Data.
1030 userprofiledir = getenv_utf8("USERPROFILE");
1031 if (userprofiledir != NULL) {
1032 persconffile_dir = g_strdup_printf(
1033 "%s" G_DIR_SEPARATOR_S "Application Data" G_DIR_SEPARATOR_S "%s",
1034 userprofiledir, PF_DIR);
1037 * Give up and use "C:".
1039 persconffile_dir = g_strdup_printf("C:" G_DIR_SEPARATOR_S "%s", PF_DIR);
1045 * If $HOME is set, use that.
1047 homedir = getenv("HOME");
1048 if (homedir == NULL) {
1050 * Get their home directory from the password file.
1051 * If we can't even find a password file entry for them,
1054 pwd = getpwuid(getuid());
1057 * This is cached, so we don't need to worry
1058 * about allocating multiple ones of them.
1060 homedir = g_strdup(pwd->pw_dir);
1064 persconffile_dir = g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s", homedir, PF_DIR);
1067 return persconffile_dir;
1071 get_profiles_dir(void)
1073 static char *profiles_dir = NULL;
1075 g_free (profiles_dir);
1076 profiles_dir = g_strdup_printf ("%s%s%s", get_persconffile_dir_no_profile (),
1077 G_DIR_SEPARATOR_S, PROFILES_DIR);
1079 return profiles_dir;
1083 get_global_profiles_dir(void)
1085 static char *global_profiles_dir = NULL;
1087 if (!global_profiles_dir) {
1088 global_profiles_dir = g_strdup_printf ("%s%s%s", get_datafile_dir(),
1089 G_DIR_SEPARATOR_S, PROFILES_DIR);
1092 return global_profiles_dir;
1096 get_persconffile_dir(const gchar *profilename)
1098 static char *persconffile_profile_dir = NULL;
1100 g_free (persconffile_profile_dir);
1102 if (profilename && strlen(profilename) > 0 &&
1103 strcmp(profilename, DEFAULT_PROFILE) != 0) {
1104 persconffile_profile_dir = g_strdup_printf ("%s%s%s", get_profiles_dir (),
1105 G_DIR_SEPARATOR_S, profilename);
1107 persconffile_profile_dir = g_strdup (get_persconffile_dir_no_profile ());
1110 return persconffile_profile_dir;
1114 profile_exists(const gchar *profilename, gboolean global)
1117 gchar *path = g_strdup_printf ("%s%s%s", get_global_profiles_dir(),
1118 G_DIR_SEPARATOR_S, profilename);
1119 if (test_for_directory (path) == EISDIR) {
1125 if (test_for_directory (get_persconffile_dir (profilename)) == EISDIR) {
1134 delete_directory (const char *directory, char **pf_dir_path_return)
1141 if ((dir = ws_dir_open(directory, 0, NULL)) != NULL) {
1142 while ((file = ws_dir_read_name(dir)) != NULL) {
1143 filename = g_strdup_printf ("%s%s%s", directory, G_DIR_SEPARATOR_S,
1144 ws_dir_get_name(file));
1145 if (test_for_directory(filename) != EISDIR) {
1146 ret = ws_remove(filename);
1149 /* The user has manually created a directory in the profile directory */
1150 /* I do not want to delete the directory recursively yet */
1151 ret = delete_directory (filename, pf_dir_path_return);
1155 *pf_dir_path_return = filename;
1163 if (ret == 0 && (ret = ws_remove(directory)) != 0) {
1164 *pf_dir_path_return = g_strdup (directory);
1171 delete_persconffile_profile(const char *profilename, char **pf_dir_path_return)
1173 const char *profile_dir = get_persconffile_dir(profilename);
1176 if (test_for_directory (profile_dir) == EISDIR) {
1177 ret = delete_directory (profile_dir, pf_dir_path_return);
1184 rename_persconffile_profile(const char *fromname, const char *toname,
1185 char **pf_from_dir_path_return, char **pf_to_dir_path_return)
1187 char *from_dir = g_strdup (get_persconffile_dir(fromname));
1188 char *to_dir = g_strdup (get_persconffile_dir(toname));
1191 ret = ws_rename (from_dir, to_dir);
1193 *pf_from_dir_path_return = g_strdup (from_dir);
1194 *pf_to_dir_path_return = g_strdup (to_dir);
1204 * Create the directory that holds personal configuration files, if
1205 * necessary. If we attempted to create it, and failed, return -1 and
1206 * set "*pf_dir_path_return" to the pathname of the directory we failed
1207 * to create (it's g_mallocated, so our caller should free it); otherwise,
1211 create_persconffile_profile(const char *profilename, char **pf_dir_path_return)
1213 const char *pf_dir_path;
1215 char *pf_dir_path_copy, *pf_dir_parent_path;
1216 size_t pf_dir_parent_path_len;
1223 * Create the "Default" personal configuration files directory, if necessary.
1225 if (create_persconffile_profile (NULL, pf_dir_path_return) == -1) {
1230 * Check if profiles directory exists.
1231 * If not then create it.
1233 pf_dir_path = get_profiles_dir ();
1234 if (ws_stat64(pf_dir_path, &s_buf) != 0 && errno == ENOENT) {
1235 ret = ws_mkdir(pf_dir_path, 0755);
1237 *pf_dir_path_return = g_strdup(pf_dir_path);
1243 pf_dir_path = get_persconffile_dir(profilename);
1244 if (ws_stat64(pf_dir_path, &s_buf) != 0 && errno == ENOENT) {
1247 * Does the parent directory of that directory
1248 * exist? %APPDATA% may not exist even though
1249 * %USERPROFILE% does.
1251 * We check for the existence of the directory
1252 * by first checking whether the parent directory
1253 * is just a drive letter and, if it's not, by
1254 * doing a "stat()" on it. If it's a drive letter,
1255 * or if the "stat()" succeeds, we assume it exists.
1257 pf_dir_path_copy = g_strdup(pf_dir_path);
1258 pf_dir_parent_path = get_dirname(pf_dir_path_copy);
1259 pf_dir_parent_path_len = strlen(pf_dir_parent_path);
1260 if (pf_dir_parent_path_len > 0
1261 && pf_dir_parent_path[pf_dir_parent_path_len - 1] != ':'
1262 && ws_stat64(pf_dir_parent_path, &s_buf) != 0) {
1264 * No, it doesn't exist - make it first.
1266 ret = ws_mkdir(pf_dir_parent_path, 0755);
1268 *pf_dir_path_return = pf_dir_parent_path;
1272 g_free(pf_dir_path_copy);
1273 ret = ws_mkdir(pf_dir_path, 0755);
1275 ret = ws_mkdir(pf_dir_path, 0755);
1279 * Something with that pathname exists; if it's not
1280 * a directory, we'll get an error if we try to put
1281 * something in it, so we don't fail here, we wait
1282 * for that attempt fo fail.
1287 *pf_dir_path_return = g_strdup(pf_dir_path);
1292 create_persconffile_dir(char **pf_dir_path_return)
1294 return create_persconffile_profile(persconfprofile, pf_dir_path_return);
1298 copy_persconffile_profile(const char *toname, const char *fromname, gboolean from_global,
1299 char **pf_filename_return, char **pf_to_dir_path_return, char **pf_from_dir_path_return)
1302 gchar *to_dir = g_strdup (get_persconffile_dir(toname));
1303 gchar *filename, *from_file, *to_file;
1304 GList *files, *file;
1307 if (strcmp(fromname, DEFAULT_PROFILE) == 0) {
1308 from_dir = g_strdup (get_global_profiles_dir());
1310 from_dir = g_strdup_printf ("%s%s%s", get_global_profiles_dir(), G_DIR_SEPARATOR_S, fromname);
1313 from_dir = g_strdup (get_persconffile_dir(fromname));
1316 files = g_hash_table_get_keys(profile_files);
1317 file = g_list_first(files);
1319 filename = (gchar *)file->data;
1320 from_file = g_strdup_printf ("%s%s%s", from_dir, G_DIR_SEPARATOR_S, filename);
1321 to_file = g_strdup_printf ("%s%s%s", to_dir, G_DIR_SEPARATOR_S, filename);
1323 if (file_exists(from_file) && !copy_file_binary_mode(from_file, to_file)) {
1324 *pf_filename_return = g_strdup(filename);
1325 *pf_to_dir_path_return = to_dir;
1326 *pf_from_dir_path_return = from_dir;
1335 file = g_list_next(file);
1338 g_list_free (files);
1346 * Get the (default) directory in which personal data is stored.
1348 * On Win32, this is the "My Documents" folder in the personal profile,
1349 * except that, if we're running from a U3 device, this is the
1350 * "$U3_DEVICE_DOCUMENT_PATH\My Captures" folder.
1351 * On UNIX this is simply the current directory.
1353 /* XXX - should this and the get_home_dir() be merged? */
1355 get_persdatafile_dir(void)
1358 char *u3devicedocumentpath;
1359 TCHAR tszPath[MAX_PATH];
1363 /* Return the cached value, if available */
1364 if (persdatafile_dir != NULL)
1365 return persdatafile_dir;
1368 * See if we are running in a U3 environment.
1370 u3devicedocumentpath = getenv_utf8("U3_DEVICE_DOCUMENT_PATH");
1372 if (u3devicedocumentpath != NULL) {
1373 /* the "My Captures" sub-directory is created (if it doesn't
1374 exist) by u3util.exe when the U3 Wireshark is first run */
1376 szPath = g_strdup_printf("%s%s", u3devicedocumentpath, U3_MY_CAPTURES);
1378 persdatafile_dir = szPath;
1382 * Hint: SHGetFolderPath is not available on MSVC 6 - without
1385 bRet = SHGetSpecialFolderPath(NULL, tszPath, CSIDL_PERSONAL,
1388 szPath = utf_16to8(tszPath);
1389 persdatafile_dir = szPath;
1402 * Returns the user's home directory on Win32.
1407 static const char *home = NULL;
1408 char *homedrive, *homepath;
1412 /* Return the cached value, if available */
1417 * XXX - should we use USERPROFILE anywhere in this process?
1418 * Is there a chance that it might be set but one or more of
1419 * HOMEDRIVE or HOMEPATH isn't set?
1421 homedrive = getenv_utf8("HOMEDRIVE");
1422 if (homedrive != NULL) {
1423 homepath = getenv_utf8("HOMEPATH");
1424 if (homepath != NULL) {
1426 * This is cached, so we don't need to worry about
1427 * allocating multiple ones of them.
1429 homestring = g_strdup_printf("%s%s", homedrive, homepath);
1432 * Trim off any trailing slash or backslash.
1434 lastsep = find_last_pathname_separator(homestring);
1435 if (lastsep != NULL && *(lastsep + 1) == '\0') {
1437 * Last separator is the last character
1438 * in the string. Nuke it.
1447 * Give up and use C:.
1457 * Construct the path name of a personal configuration file, given the
1460 * On Win32, if "for_writing" is FALSE, we check whether the file exists
1461 * and, if not, construct a path name relative to the ".wireshark"
1462 * subdirectory of the user's home directory, and check whether that
1463 * exists; if it does, we return that, so that configuration files
1464 * from earlier versions can be read.
1466 * The returned file name was g_malloc()'d so it must be g_free()d when the
1467 * caller is done with it.
1470 get_persconffile_path(const char *filename, gboolean from_profile, gboolean for_writing
1481 if (do_store_persconffiles && from_profile && !g_hash_table_lookup (profile_files, filename)) {
1482 /* Store filenames so we know which filenames belongs to a configuration profile */
1483 g_hash_table_insert (profile_files, g_strdup(filename), g_strdup(filename));
1487 path = g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s",
1488 get_persconffile_dir(persconfprofile), filename);
1490 path = g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s",
1491 get_persconffile_dir(NULL), filename);
1495 if (ws_stat64(path, &s_buf) != 0 && errno == ENOENT) {
1497 * OK, it's not in the personal configuration file
1498 * directory; is it in the ".wireshark" subdirectory
1499 * of their home directory?
1501 old_path = g_strdup_printf(
1502 "%s" G_DIR_SEPARATOR_S ".wireshark" G_DIR_SEPARATOR_S "%s",
1503 get_home_dir(), filename);
1504 if (ws_stat64(old_path, &s_buf) == 0) {
1506 * OK, it exists; return it instead.
1519 * process command line option belonging to the filesystem settings
1520 * (move this e.g. to main.c and have set_persconffile_dir() instead in this file?)
1523 filesystem_opt(int opt _U_, const char *optstr)
1527 colonp = strchr(optstr, ':');
1528 if (colonp == NULL) {
1536 * Skip over any white space (there probably won't be any, but
1537 * as we allow it in the preferences file, we might as well
1540 while (isspace((guchar)*p))
1544 * Put the colon back, so if our caller uses, in an
1545 * error message, the string they passed us, the message
1552 /* directory should be existing */
1553 /* XXX - is this a requirement? */
1554 if(test_for_directory(p) != EISDIR) {
1556 * Put the colon back, so if our caller uses, in an
1557 * error message, the string they passed us, the message
1564 if (strcmp(optstr,"persconf") == 0) {
1565 persconffile_dir = p;
1566 } else if (strcmp(optstr,"persdata") == 0) {
1567 persdatafile_dir = p;
1568 /* XXX - might need to add the temp file path */
1572 *colonp = ':'; /* put the colon back */
1577 * Construct the path name of a global configuration file, given the
1580 * The returned file name was g_malloc()'d so it must be g_free()d when the
1581 * caller is done with it.
1584 get_datafile_path(const char *filename)
1587 return g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s", get_datafile_dir(), filename);
1590 /* Get the personal plugin dir */
1591 /* Return value is malloced so the caller should g_free() it. */
1593 get_plugins_pers_dir(void)
1595 return get_persconffile_path(PLUGINS_DIR_NAME, FALSE, FALSE);
1600 deletefile(const char *path)
1602 return ws_unlink(path) == 0;
1606 * Construct and return the path name of a file in the
1607 * appropriate temporary file directory.
1609 char *get_tempfile_path(const char *filename)
1611 return g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s", g_get_tmp_dir(), filename);
1615 * Return an error message for UNIX-style errno indications on open or
1616 * create operations.
1619 file_open_error_message(int err, gboolean for_writing)
1622 static char errmsg_errno[1024+1];
1628 errmsg = "The path to the file \"%s\" doesn't exist.";
1630 errmsg = "The file \"%s\" doesn't exist.";
1635 errmsg = "You don't have permission to create or write to the file \"%s\".";
1637 errmsg = "You don't have permission to read the file \"%s\".";
1641 errmsg = "\"%s\" is a directory (folder), not a file.";
1645 errmsg = "The file \"%s\" could not be created because there is no space left on the file system.";
1650 errmsg = "The file \"%s\" could not be created because you are too close to, or over, your disk quota.";
1655 errmsg = "The file \"%s\" could not be created because an invalid filename was specified.";
1659 g_snprintf(errmsg_errno, sizeof(errmsg_errno),
1660 "The file \"%%s\" could not be %s: %s.",
1661 for_writing ? "created" : "opened",
1663 errmsg = errmsg_errno;
1670 * Return an error message for UNIX-style errno indications on write
1674 file_write_error_message(int err)
1677 static char errmsg_errno[1024+1];
1682 errmsg = "The file \"%s\" could not be saved because there is no space left on the file system.";
1687 errmsg = "The file \"%s\" could not be saved because you are too close to, or over, your disk quota.";
1692 g_snprintf(errmsg_errno, sizeof(errmsg_errno),
1693 "An error occurred while writing to the file \"%%s\": %s.",
1695 errmsg = errmsg_errno;
1703 file_exists(const char *fname)
1705 ws_statb64 file_stat;
1713 * This is a bit tricky on win32. The st_ino field is documented as:
1714 * "The inode, and therefore st_ino, has no meaning in the FAT, ..."
1715 * but it *is* set to zero if stat() returns without an error,
1716 * so this is working, but maybe not quite the way expected. ULFL
1718 file_stat.st_ino = 1; /* this will make things work if an error occured */
1719 ws_stat64(fname, &file_stat);
1720 if (file_stat.st_ino == 0) {
1726 if (ws_stat64(fname, &file_stat) != 0 && errno == ENOENT) {
1735 * Check that the from file is not the same as to file
1736 * We do it here so we catch all cases ...
1737 * Unfortunately, the file requester gives us an absolute file
1738 * name and the read file name may be relative (if supplied on
1739 * the command line), so we can't just compare paths. From Joerg Mayer.
1742 files_identical(const char *fname1, const char *fname2)
1744 /* Two different implementations, because:
1746 * - _fullpath is not available on UN*X, so we can't get full
1747 * paths and compare them (which wouldn't work with hard links
1750 * - st_ino isn't filled in with a meaningful value on Windows.
1753 char full1[MAX_PATH], full2[MAX_PATH];
1756 * Get the absolute full paths of the file and compare them.
1757 * That won't work if you have hard links, but those aren't
1758 * much used on Windows, even though NTFS supports them.
1760 * XXX - will _fullpath work with UNC?
1762 if( _fullpath( full1, fname1, MAX_PATH ) == NULL ) {
1766 if( _fullpath( full2, fname2, MAX_PATH ) == NULL ) {
1770 if(strcmp(full1, full2) == 0) {
1776 ws_statb64 filestat1, filestat2;
1779 * Compare st_dev and st_ino.
1781 if (ws_stat64(fname1, &filestat1) == -1)
1782 return FALSE; /* can't get info about the first file */
1783 if (ws_stat64(fname2, &filestat2) == -1)
1784 return FALSE; /* can't get info about the second file */
1785 return (filestat1.st_dev == filestat2.st_dev &&
1786 filestat1.st_ino == filestat2.st_ino);
1791 * Copy a file in binary mode, for those operating systems that care about
1792 * such things. This should be OK for all files, even text files, as
1793 * we'll copy the raw bytes, and we don't look at the bytes as we copy
1796 * Returns TRUE on success, FALSE on failure. If a failure, it also
1797 * displays a simple dialog window with the error message.
1800 copy_file_binary_mode(const char *from_filename, const char *to_filename)
1802 int from_fd, to_fd, nread, nwritten, err;
1805 /* Copy the raw bytes of the file. */
1806 from_fd = ws_open(from_filename, O_RDONLY | O_BINARY, 0000 /* no creation so don't matter */);
1808 report_open_failure(from_filename, errno, FALSE);
1812 /* Use open() instead of creat() so that we can pass the O_BINARY
1813 flag, which is relevant on Win32; it appears that "creat()"
1814 may open the file in text mode, not binary mode, but we want
1815 to copy the raw bytes of the file, so we need the output file
1816 to be open in binary mode. */
1817 to_fd = ws_open(to_filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644);
1819 report_open_failure(to_filename, errno, TRUE);
1824 #define FS_READ_SIZE 65536
1825 pd = g_malloc(FS_READ_SIZE);
1826 while ((nread = ws_read(from_fd, pd, FS_READ_SIZE)) > 0) {
1827 nwritten = ws_write(to_fd, pd, nread);
1828 if (nwritten < nread) {
1832 err = WTAP_ERR_SHORT_WRITE;
1833 report_write_failure(to_filename, err);
1841 report_read_failure(from_filename, err);
1847 if (ws_close(to_fd) < 0) {
1848 report_write_failure(to_filename, errno);
1867 * indent-tabs-mode: nil
1870 * ex: set shiftwidth=4 tabstop=8 expandtab:
1871 * :indentSize=4:tabSize=8:noTabs=true: