Get rid of ber_last_created_item().
[obnox/wireshark/wip.git] / epan / filesystem.c
1 /* filesystem.c
2  * Filesystem utility routines
3  *
4  * $Id$
5  *
6  * Wireshark - Network traffic analyzer
7  * By Gerald Combs <gerald@wireshark.org>
8  * Copyright 1998 Gerald Combs
9  *
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.
14  *
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.
19  *
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.
23  */
24
25 #ifdef HAVE_CONFIG_H
26 # include "config.h"
27 #endif
28
29 #include <stdio.h>
30 #include <ctype.h>
31 #include <stdlib.h>
32 #include <string.h>
33 #include <errno.h>
34
35 #include <glib.h>
36
37 #ifdef HAVE_UNISTD_H
38 #include <unistd.h>
39 #endif
40
41 #ifdef HAVE_SYS_STAT_H
42 #include <sys/stat.h>
43 #endif
44
45 #ifdef _WIN32
46 #include <windows.h>
47 #include <tchar.h>
48 #include <shlobj.h>
49 #include "epan/unicode-utils.h"
50 #else
51 #include <pwd.h>
52 #endif
53
54 #include "filesystem.h"
55 #include "privileges.h"
56 #include <wiretap/file_util.h>
57
58 #define U3_MY_CAPTURES  "\\My Captures"
59
60 char *persconffile_dir = NULL;
61 char *persdatafile_dir = NULL;
62
63 /*
64  * Given a pathname, return a pointer to the last pathname separator
65  * character in the pathname, or NULL if the pathname contains no
66  * separators.
67  */
68 static char *
69 find_last_pathname_separator(const char *path)
70 {
71         char *separator;
72
73 #ifdef _WIN32
74         char c;
75
76         /*
77          * We have to scan for '\' or '/'.
78          * Get to the end of the string.
79          */
80         separator = strchr(path, '\0');         /* points to ending '\0' */
81         while (separator > path) {
82                 c = *--separator;
83                 if (c == '\\' || c == '/')
84                         return separator;       /* found it */
85         }
86
87         /*
88          * OK, we didn't find any, so no directories - but there might
89          * be a drive letter....
90          */
91         return strchr(path, ':');
92 #else
93         separator = strrchr(path, '/');
94 #endif
95         return separator;
96 }
97
98 /*
99  * Given a pathname, return the last component.
100  */
101 const char *
102 get_basename(const char *path)
103 {
104         const char *filename;
105
106         g_assert(path != NULL);
107         filename = find_last_pathname_separator(path);
108         if (filename == NULL) {
109                 /*
110                  * There're no directories, drive letters, etc. in the
111                  * name; the pathname *is* the file name.
112                  */
113                 filename = path;
114         } else {
115                 /*
116                  * Skip past the pathname or drive letter separator.
117                  */
118                 filename++;
119         }
120         return filename;
121 }
122
123 /*
124  * Given a pathname, return a string containing everything but the
125  * last component.  NOTE: this overwrites the pathname handed into
126  * it....
127  */
128 char *
129 get_dirname(char *path)
130 {
131         char *separator;
132
133         g_assert(path != NULL);
134         separator = find_last_pathname_separator(path);
135         if (separator == NULL) {
136                 /*
137                  * There're no directories, drive letters, etc. in the
138                  * name; there is no directory path to return.
139                  */
140                 return NULL;
141         }
142
143         /*
144          * Get rid of the last pathname separator and the final file
145          * name following it.
146          */
147         *separator = '\0';
148
149         /*
150          * "path" now contains the pathname of the directory containing
151          * the file/directory to which it referred.
152          */
153         return path;
154 }
155
156 /*
157  * Given a pathname, return:
158  *
159  *      the errno, if an attempt to "stat()" the file fails;
160  *
161  *      EISDIR, if the attempt succeeded and the file turned out
162  *      to be a directory;
163  *
164  *      0, if the attempt succeeded and the file turned out not
165  *      to be a directory.
166  */
167
168 /*
169  * Visual C++ on Win32 systems doesn't define these.  (Old UNIX systems don't
170  * define them either.)
171  *
172  * Visual C++ on Win32 systems doesn't define S_IFIFO, it defines _S_IFIFO.
173  */
174 #ifndef S_ISREG
175 #define S_ISREG(mode)   (((mode) & S_IFMT) == S_IFREG)
176 #endif
177 #ifndef S_IFIFO
178 #define S_IFIFO _S_IFIFO
179 #endif
180 #ifndef S_ISFIFO
181 #define S_ISFIFO(mode)  (((mode) & S_IFMT) == S_IFIFO)
182 #endif
183 #ifndef S_ISDIR
184 #define S_ISDIR(mode)   (((mode) & S_IFMT) == S_IFDIR)
185 #endif
186
187 int
188 test_for_directory(const char *path)
189 {
190         struct stat statb;
191
192         if (eth_stat(path, &statb) < 0)
193                 return errno;
194
195         if (S_ISDIR(statb.st_mode))
196                 return EISDIR;
197         else
198                 return 0;
199 }
200
201 int
202 test_for_fifo(const char *path)
203 {
204         struct stat statb;
205
206         if (eth_stat(path, &statb) < 0)
207                 return errno;
208
209         if (S_ISFIFO(statb.st_mode))
210                 return ESPIPE;
211         else
212                 return 0;
213 }
214
215 /*
216  * Directory from which the executable came.
217  */
218 static char *progfile_dir;
219
220 /*
221  * TRUE if we're running from the build directory.
222  */
223 static gboolean running_in_build_directory_flag = FALSE;
224
225 /*
226  * Get the pathname of the directory from which the executable came,
227  * and save it for future use.  Returns NULL on success, and a
228  * g_mallocated string containing an error on failure.
229  */
230 char *
231 init_progfile_dir(const char *arg0
232 #ifdef _WIN32
233         _U_
234 #endif
235 )
236 {
237         char *dir_end;
238         char *path;
239 #ifdef _WIN32
240         TCHAR prog_pathname_w[_MAX_PATH+2];
241         size_t progfile_dir_len;
242         char *prog_pathname;
243         DWORD error;
244         TCHAR *msg_w;
245         guchar *msg;
246         size_t msglen;
247
248         /*
249          * Attempt to get the full pathname of the currently running
250          * program.
251          */
252         if (GetModuleFileName(NULL, prog_pathname_w, sizeof prog_pathname_w) != 0) {
253                 /*
254                  * XXX - Should we use g_utf16_to_utf8(), as in
255                  * getenv_utf8()?
256                  */
257                 prog_pathname = utf_16to8(prog_pathname_w);
258                 /*
259                  * We got it; strip off the last component, which would be
260                  * the file name of the executable, giving us the pathname
261                  * of the directory where the executable resies
262                  *
263                  * First, find the last "\" in the directory, as that
264                  * marks the end of the directory pathname.
265                  *
266                  * XXX - Can the pathname be something such as
267                  * "C:wireshark.exe"?  Or is it always a full pathname
268                  * beginning with "\" after the drive letter?
269                  */
270                 dir_end = strrchr(prog_pathname, '\\');
271                 if (dir_end != NULL) {
272                         /*
273                          * Found it - now figure out how long the program
274                          * directory pathname will be.
275                          */
276                         progfile_dir_len = (dir_end - prog_pathname);
277
278                         /*
279                          * Allocate a buffer for the program directory
280                          * pathname, and construct it.
281                          */
282                         path = g_malloc(progfile_dir_len + 1);
283                         strncpy(path, prog_pathname, progfile_dir_len);
284                         path[progfile_dir_len] = '\0';
285                         progfile_dir = path;
286
287                         return NULL;    /* we succeeded */
288                 } else {
289                         /*
290                          * OK, no \ - what do we do now?
291                          */
292                         return g_strdup_printf("No \\ in executable pathname \"%s\"",
293                             prog_pathname);
294                 }
295         } else {
296                 /*
297                  * Oh, well.  Return an indication of the error.
298                  */
299                 error = GetLastError();
300                 if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM,
301                     NULL, error, 0, (LPTSTR) &msg_w, 0, NULL) == 0) {
302                         /*
303                          * Gak.  We can't format the message.
304                          */
305                         return g_strdup_printf("GetModuleFileName failed: %u (FormatMessage failed: %u)",
306                             error, GetLastError());
307                 }
308                 msg = utf_16to8(msg_w);
309                 LocalFree(msg_w);
310                 /*
311                  * "FormatMessage()" "helpfully" sticks CR/LF at the
312                  * end of the message.  Get rid of it.
313                  */
314                 msglen = strlen(msg);
315                 if (msglen >= 2) {
316                         msg[msglen - 1] = '\0';
317                         msg[msglen - 2] = '\0';
318                 }
319                 return g_strdup_printf("GetModuleFileName failed: %s (%u)",
320                     msg, error);
321         }
322 #else
323         char *prog_pathname;
324         char *curdir;
325         long path_max;
326         char *pathstr;
327         char *path_start, *path_end;
328         size_t path_component_len;
329         char *retstr;
330
331         /*
332          * Check whether WIRESHARK_RUN_FROM_BUILD_DIRECTORY is set in the
333          * environment; if so, set running_in_build_directory_flag if we
334          * weren't started with special privileges.  (If we were started
335          * with special privileges, it's not safe to allow the user to point
336          * us to some other directory; running_in_build_directory_flag, when
337          * set, causes us to look for plugins and the like in the build
338          * directory.)
339          */
340         if (getenv("WIRESHARK_RUN_FROM_BUILD_DIRECTORY") != NULL
341             && !started_with_special_privs())
342                 running_in_build_directory_flag = TRUE;
343
344         /*
345          * Try to figure out the directory in which the currently running
346          * program resides, given the argv[0] it was started with.  That
347          * might be the absolute path of the program, or a path relative
348          * to the current directory of the process that started it, or
349          * just a name for the program if it was started from the command
350          * line and was searched for in $PATH.  It's not guaranteed to be
351          * any of those, however, so there are no guarantees....
352          */
353         if (arg0[0] == '/') {
354                 /*
355                  * It's an absolute path.
356                  */
357                 prog_pathname = g_strdup(arg0);
358         } else if (strchr(arg0, '/') != NULL) {
359                 /*
360                  * It's a relative path, with a directory in it.
361                  * Get the current directory, and combine it
362                  * with that directory.
363                  */
364                 path_max = pathconf(".", _PC_PATH_MAX);
365                 if (path_max == -1) {
366                         /*
367                          * We have no idea how big a buffer to
368                          * allocate for the current directory.
369                          */
370                         return g_strdup_printf("pathconf failed: %s\n",
371                             strerror(errno));
372                 }
373                 curdir = g_malloc(path_max);
374                 if (getcwd(curdir, path_max) == NULL) {
375                         /*
376                          * It failed - give up, and just stick
377                          * with DATAFILE_DIR.
378                          */
379                         g_free(curdir);
380                         return g_strdup_printf("getcwd failed: %s\n",
381                             strerror(errno));
382                 }
383                 path = g_malloc(strlen(curdir) + 1 + strlen(arg0) + 1);
384                 strcpy(path, curdir);
385                 strcat(path, "/");
386                 strcat(path, arg0);
387                 g_free(curdir);
388                 prog_pathname = path;
389         } else {
390                 /*
391                  * It's just a file name.
392                  * Search the path for a file with that name
393                  * that's executable.
394                  */
395                 prog_pathname = NULL;   /* haven't found it yet */
396                 pathstr = getenv("PATH");
397                 path_start = pathstr;
398                 if (path_start != NULL) {
399                         while (*path_start != '\0') {
400                                 path_end = strchr(path_start, ':');
401                                 if (path_end == NULL)
402                                         path_end = path_start + strlen(path_start);
403                                 path_component_len = path_end - path_start;
404                                 path = g_malloc(path_component_len + 1
405                                     + strlen(arg0) + 1);
406                                 memcpy(path, path_start, path_component_len);
407                                 path[path_component_len] = '\0';
408                                 strcat(path, "/");
409                                 strcat(path, arg0);
410                                 if (access(path, X_OK) == 0) {
411                                         /*
412                                          * Found it!
413                                          */
414                                         prog_pathname = path;
415                                         break;
416                                 }
417
418                                 /*
419                                  * That's not it.  If there are more
420                                  * path components to test, try them.
421                                  */
422                                 if (*path_end == '\0') {
423                                         /*
424                                          * There's nothing more to try.
425                                          */
426                                         break;
427                                 }
428                                 if (*path_end == ':')
429                                         path_end++;
430                                 path_start = path_end;
431                                 g_free(path);
432                         }
433                         if (prog_pathname == NULL) {
434                                 /*
435                                  * Program not found in path.
436                                  */
437                                 return g_strdup_printf("\"%s\" not found in \"%s\"",
438                                     arg0, pathstr);
439                         }
440                 } else {
441                         /*
442                          * PATH isn't set.
443                          * XXX - should we pick a default?
444                          */
445                         return g_strdup("PATH isn't set");
446                 }
447         }
448
449         /*
450          * OK, we have what we think is the pathname
451          * of the program.
452          *
453          * First, find the last "/" in the directory,
454          * as that marks the end of the directory pathname.
455          */
456         dir_end = strrchr(prog_pathname, '/');
457         if (dir_end != NULL) {
458                 /*
459                  * Found it.  Strip off the last component,
460                  * as that's the path of the program.
461                  */
462                 *dir_end = '\0';
463
464                 /*
465                  * Is there a "/.libs" at the end?
466                  */
467                 dir_end = strrchr(prog_pathname, '/');
468                 if (dir_end != NULL) {
469                         if (strcmp(dir_end, "/.libs") == 0) {
470                                 /*
471                                  * Yup, it's ".libs".
472                                  * Strip that off; it's an
473                                  * artifact of libtool.
474                                  */
475                                 *dir_end = '\0';
476
477                                 /*
478                                  * This presumably means we're run from
479                                  * the libtool wrapper, which probably
480                                  * means we're being run from the build
481                                  * directory.  If we weren't started
482                                  * with special privileges, set
483                                  * running_in_build_directory_flag.
484                                  *
485                                  * XXX - should we check whether what
486                                  * follows ".libs/" begins with "lt-"?
487                                  */
488                                 if (!started_with_special_privs())
489                                         running_in_build_directory_flag = TRUE;
490                         }
491                 }
492
493                 /*
494                  * OK, we have the path we want.
495                  */
496                 progfile_dir = prog_pathname;
497                 return NULL;
498         } else {
499                 /*
500                  * This "shouldn't happen"; we apparently
501                  * have no "/" in the pathname.
502                  * Just free up prog_pathname.
503                  */
504                 retstr = g_strdup_printf("No / found in \"%s\"", prog_pathname);
505                 g_free(prog_pathname);
506                 return retstr;
507         }
508 #endif
509 }
510
511 /*
512  * Get the directory in which the program resides.
513  */
514 const char *
515 get_progfile_dir(void)
516 {
517         return progfile_dir;
518 }
519
520 /*
521  * Get the directory in which the global configuration and data files are
522  * stored.
523  *
524  * On Windows, we use the directory in which the executable for this
525  * process resides.
526  *
527  * On UN*X, we use the DATAFILE_DIR value supplied by the configure
528  * script, unless we think we're being run from the build directory,
529  * in which case we use the directory in which the executable for this
530  * process resides.
531  *
532  * XXX - if we ever make libwireshark a real library, used by multiple
533  * applications (more than just TShark and versions of Wireshark with
534  * various UIs), should the configuration files belong to the library
535  * (and be shared by all those applications) or to the applications?
536  *
537  * If they belong to the library, that could be done on UNIX by the
538  * configure script, but it's trickier on Windows, as you can't just
539  * use the pathname of the executable.
540  *
541  * If they belong to the application, that could be done on Windows
542  * by using the pathname of the executable, but we'd have to have it
543  * passed in as an argument, in some call, on UNIX.
544  *
545  * Note that some of those configuration files might be used by code in
546  * libwireshark, some of them might be used by dissectors (would they
547  * belong to libwireshark, the application, or a separate library?),
548  * and some of them might be used by other code (the Wireshark preferences
549  * file includes resolver preferences that control the behavior of code
550  * in libwireshark, dissector preferences, and UI preferences, for
551  * example).
552  */
553 const char *
554 get_datafile_dir(void)
555 {
556 #ifdef _WIN32
557         char *u3deviceexecpath;
558 #endif
559         static char *datafile_dir = NULL;
560
561         if (datafile_dir != NULL)
562                 return datafile_dir;
563
564 #ifdef _WIN32
565         /*
566          * See if we are running in a U3 environment.
567          */
568         u3deviceexecpath = getenv_utf8("U3_DEVICE_EXEC_PATH");
569
570         if (u3deviceexecpath != NULL) {
571                 /*
572                  * We are; use the U3 device executable path.
573                  */
574                 datafile_dir = u3deviceexecpath;
575         } else {
576                 /*
577                  * Do we have the pathname of the program?  If so, assume we're
578                  * running an installed version of the program.  If we fail,
579                  * we don't change "datafile_dir", and thus end up using the
580                  * default.
581                  *
582                  * XXX - does NSIS put the installation directory into
583                  * "\HKEY_LOCAL_MACHINE\SOFTWARE\Wireshark\InstallDir"?
584                  * If so, perhaps we should read that from the registry,
585                  * instead.
586                  */
587                 if (progfile_dir != NULL) {
588                         /*
589                          * Yes, we do; use that.
590                          */
591                         datafile_dir = progfile_dir;
592                 } else {
593                         /*
594                          * No, we don't.
595                          * Fall back on the default installation directory.
596                          */
597                         datafile_dir = "C:\\Program Files\\Wireshark\\";
598                 }
599         }
600 #else
601         if (running_in_build_directory_flag && progfile_dir != NULL) {
602                 /*
603                  * We're (probably) being run from the build directory and
604                  * weren't started with special privileges, and we were
605                  * able to determine the directory in which the program
606                  * was found, so use that.
607                  */
608                 datafile_dir = progfile_dir;
609         } else {
610                 /*
611                  * Return the directory specified when the build
612                  * was configured.
613                  */
614                 datafile_dir = DATAFILE_DIR;
615         }
616
617 #endif
618         return datafile_dir;
619 }
620
621 #ifdef HAVE_PLUGINS
622 /*
623  * Find the directory where the plugins are stored.
624  *
625  * On Windows, we use the "plugin" subdirectory of the datafile directory.
626  *
627  * On UN*X, we use the PLUGIN_DIR value supplied by the configure
628  * script, unless we think we're being run from the build directory,
629  * in which case we use the "plugin" subdirectory of the datafile directory.
630  *
631  * In both cases, we then use the subdirectory of that directory whose
632  * name is the version number.
633  *
634  * XXX - if we think we're being run from the build directory, perhaps we
635  * should have the plugin code not look in the version subdirectory
636  * of the plugin directory, but look in all of the subdirectories
637  * of the plugin directory, so it can just fetch the plugins built
638  * as part of the build process.
639  */
640 static const char *plugin_dir = NULL;
641
642 static void
643 init_plugin_dir(void)
644 {
645 #ifdef _WIN32
646         /*
647          * On Windows, the data file directory is the installation
648          * directory; the plugins are stored under it.
649          *
650          * Assume we're running the installed version of Wireshark;
651          * on Windows, the data file directory is the directory
652          * in which the Wireshark binary resides.
653          */
654         plugin_dir = g_strdup_printf("%s\\plugins\\%s", get_datafile_dir(),
655             VERSION);
656
657         /*
658          * Make sure that pathname refers to a directory.
659          */
660         if (test_for_directory(plugin_dir) != EISDIR) {
661                 /*
662                  * Either it doesn't refer to a directory or it
663                  * refers to something that doesn't exist.
664                  *
665                  * Assume that means we're running a version of
666                  * Wireshark we've built in a build directory,
667                  * in which case {datafile dir}\plugins is the
668                  * top-level plugins source directory, and use
669                  * that directory and set the "we're running in
670                  * a build directory" flag, so the plugin
671                  * scanner will check all subdirectories of that
672                  * directory for plugins.
673                  */
674                 g_free( (gpointer) plugin_dir);
675                 plugin_dir = g_strdup_printf("%s\\plugins", get_datafile_dir());
676                 running_in_build_directory_flag = TRUE;
677         }
678 #else
679         if (running_in_build_directory_flag) {
680                 /*
681                  * We're (probably) being run from the build directory and
682                  * weren't started with special privileges, so we'll use
683                  * the "plugins" subdirectory of the datafile directory
684                  * (the datafile directory is the build directory).
685                  */
686                 plugin_dir = g_strdup_printf("%s/plugins", get_datafile_dir());
687         } else
688                 plugin_dir = PLUGIN_DIR;
689 #endif
690 }
691 #endif /* HAVE_PLUGINS */
692
693 /*
694  * Get the directory in which the plugins are stored.
695  */
696 const char *
697 get_plugin_dir(void)
698 {
699 #ifdef HAVE_PLUGINS
700         if (!plugin_dir) init_plugin_dir();
701         return plugin_dir;
702 #else
703         return NULL;
704 #endif
705 }
706
707 /*
708  * Get the flag indicating whether we're running from a build
709  * directory.
710  */
711 gboolean
712 running_in_build_directory(void)
713 {
714         return running_in_build_directory_flag;
715 }
716
717 /*
718  * Get the directory in which files that, at least on UNIX, are
719  * system files (such as "/etc/ethers") are stored; on Windows,
720  * there's no "/etc" directory, so we get them from the global
721  * configuration and data file directory.
722  */
723 const char *
724 get_systemfile_dir(void)
725 {
726 #ifdef _WIN32
727         return get_datafile_dir();
728 #else
729         return "/etc";
730 #endif
731 }
732
733 /*
734  * Name of directory, under the user's home directory, in which
735  * personal configuration files are stored.
736  */
737 #ifdef _WIN32
738 #define PF_DIR "Wireshark"
739 #else
740 /*
741  * XXX - should this be ".libepan"? For backwards-compatibility, I'll keep
742  * it ".wireshark" for now.
743  */
744 #define PF_DIR ".wireshark"
745 #endif
746
747 #ifdef _WIN32
748 /* utf8 version of getenv, needed to get win32 filename paths */
749 char *getenv_utf8(const char *varname)
750 {
751         char *envvar;
752         wchar_t *envvarw;
753         wchar_t *varnamew;
754
755         envvar = getenv(varname);
756
757         /* since GLib 2.6 we need an utf8 version of the filename */
758 #if (GLIB_MAJOR_VERSION > 2 || (GLIB_MAJOR_VERSION == 2 && GLIB_MINOR_VERSION >= 6))
759         /* using the wide char version of getenv should work under all circumstances */
760
761         /* convert given varname to utf16, needed by _wgetenv */
762         varnamew = g_utf8_to_utf16(varname, -1, NULL, NULL, NULL);
763         if (varnamew == NULL) {
764                 return envvar;
765         }
766
767         /* use wide char version of getenv */
768         envvarw = _wgetenv(varnamew);
769         g_free(varnamew);
770         if (envvarw == NULL) {
771                 return envvar;
772         }
773
774         /* convert value to utf8 */
775         envvar = g_utf16_to_utf8(envvarw, -1, NULL, NULL, NULL);
776         /* XXX - memleak */
777 #endif
778
779         return envvar;
780 }
781 #endif
782
783 /*
784  * Get the directory in which personal configuration files reside;
785  * in UNIX-compatible systems, it's ".wireshark", under the user's home
786  * directory, and on Windows systems, it's "Wireshark", under %APPDATA%
787  * or, if %APPDATA% isn't set, it's "%USERPROFILE%\Application Data"
788  * (which is what %APPDATA% normally is on Windows 2000).
789  */
790 static const char *
791 get_persconffile_dir(void)
792 {
793 #ifdef _WIN32
794         char *appdatadir;
795         char *userprofiledir;
796         char *u3appdatapath;
797 #else
798         const char *homedir;
799         struct passwd *pwd;
800 #endif
801
802         /* Return the cached value, if available */
803         if (persconffile_dir != NULL)
804                 return persconffile_dir;
805
806 #ifdef _WIN32
807         /*
808          * See if we are running in a U3 environment.
809          */
810         u3appdatapath = getenv_utf8("U3_APP_DATA_PATH");
811         if (u3appdatapath != NULL) {
812                 /*
813                  * We are; use the U3 application data path.
814                  */
815                 persconffile_dir = u3appdatapath;
816         } else {
817                 /*
818                  * Use %APPDATA% or %USERPROFILE%, so that configuration
819                  * files are stored in the user profile, rather than in
820                  * the home directory.  The Windows convention is to store
821                  * configuration information in the user profile, and doing
822                  * so means you can use Wireshark even if the home directory
823                  * is an inaccessible network drive.
824                  */
825                 appdatadir = getenv_utf8("APPDATA");
826                 if (appdatadir != NULL) {
827                         /*
828                          * Concatenate %APPDATA% with "\Wireshark".
829                          */
830                         persconffile_dir = g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s",
831                             appdatadir, PF_DIR);
832                 } else {
833                         /*
834                          * OK, %APPDATA% wasn't set, so use
835                          * %USERPROFILE%\Application Data.
836                          */
837                         userprofiledir = getenv_utf8("USERPROFILE");
838                         if (userprofiledir != NULL) {
839                                 persconffile_dir = g_strdup_printf(
840                                     "%s" G_DIR_SEPARATOR_S "Application Data" G_DIR_SEPARATOR_S "%s",
841                                     userprofiledir, PF_DIR);
842                         } else {
843                                 /*
844                                  * Give up and use "C:".
845                                  */
846                                 persconffile_dir = g_strdup_printf("C:" G_DIR_SEPARATOR_S "%s", PF_DIR);
847                         }
848                 }
849         }
850 #else
851         /*
852          * If $HOME is set, use that.
853          */
854         homedir = getenv("HOME");
855         if (homedir == NULL) {
856                 /*
857                  * Get their home directory from the password file.
858                  * If we can't even find a password file entry for them,
859                  * use "/tmp".
860                  */
861                 pwd = getpwuid(getuid());
862                 if (pwd != NULL) {
863                         /*
864                          * This is cached, so we don't need to worry
865                          * about allocating multiple ones of them.
866                          */
867                         homedir = g_strdup(pwd->pw_dir);
868                 } else
869                         homedir = "/tmp";
870         }
871         persconffile_dir = g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s", homedir, PF_DIR);
872 #endif
873
874         return persconffile_dir;
875 }
876
877 /*
878  * Create the directory that holds personal configuration files, if
879  * necessary.  If we attempted to create it, and failed, return -1 and
880  * set "*pf_dir_path_return" to the pathname of the directory we failed
881  * to create (it's g_mallocated, so our caller should free it); otherwise,
882  * return 0.
883  */
884 int
885 create_persconffile_dir(char **pf_dir_path_return)
886 {
887         const char *pf_dir_path;
888 #ifdef _WIN32
889         char *pf_dir_path_copy, *pf_dir_parent_path;
890         size_t pf_dir_parent_path_len;
891 #endif
892         struct stat s_buf;
893         int ret;
894
895         pf_dir_path = get_persconffile_dir();
896         if (eth_stat(pf_dir_path, &s_buf) != 0 && errno == ENOENT) {
897 #ifdef _WIN32
898                 /*
899                  * Does the parent directory of that directory
900                  * exist?  %APPDATA% may not exist even though
901                  * %USERPROFILE% does.
902                  *
903                  * We check for the existence of the directory
904                  * by first checking whether the parent directory
905                  * is just a drive letter and, if it's not, by
906                  * doing a "stat()" on it.  If it's a drive letter,
907                  * or if the "stat()" succeeds, we assume it exists.
908                  */
909                 pf_dir_path_copy = g_strdup(pf_dir_path);
910                 pf_dir_parent_path = get_dirname(pf_dir_path_copy);
911                 pf_dir_parent_path_len = strlen(pf_dir_parent_path);
912                 if (pf_dir_parent_path_len > 0
913                     && pf_dir_parent_path[pf_dir_parent_path_len - 1] != ':'
914                     && eth_stat(pf_dir_parent_path, &s_buf) != 0) {
915                         /*
916                          * No, it doesn't exist - make it first.
917                          */
918                         ret = eth_mkdir(pf_dir_parent_path, 0755);
919                         if (ret == -1) {
920                                 *pf_dir_path_return = pf_dir_parent_path;
921                                 return -1;
922                         }
923                 }
924                 g_free(pf_dir_path_copy);
925                 ret = eth_mkdir(pf_dir_path, 0755);
926 #else
927                 ret = eth_mkdir(pf_dir_path, 0755);
928 #endif
929         } else {
930                 /*
931                  * Something with that pathname exists; if it's not
932                  * a directory, we'll get an error if we try to put
933                  * something in it, so we don't fail here, we wait
934                  * for that attempt fo fail.
935                  */
936                 ret = 0;
937         }
938         if (ret == -1)
939                 *pf_dir_path_return = g_strdup(pf_dir_path);
940         return ret;
941 }
942
943 /*
944  * Get the (default) directory in which personal data is stored.
945  *
946  * On Win32, this is the "My Documents" folder in the personal profile.
947  * On UNIX this is simply the current directory.
948  * On a U3 device this is "$U3_DEVICE_DOCUMENT_PATH\My Captures" folder.
949  */
950 /* XXX - should this and the get_home_dir() be merged? */
951 extern char *
952 get_persdatafile_dir(void)
953 {
954 #ifdef _WIN32
955     char *u3devicedocumentpath;
956     TCHAR tszPath[MAX_PATH];
957         char *szPath;
958         BOOL bRet;
959
960
961         /* Return the cached value, if available */
962         if (persdatafile_dir != NULL)
963                 return persdatafile_dir;
964
965         /*
966          * See if we are running in a U3 environment.
967          */
968         u3devicedocumentpath = getenv_utf8("U3_DEVICE_DOCUMENT_PATH");
969
970         if (u3devicedocumentpath != NULL) {
971           
972           /* the "My Captures" sub-directory is created (if it doesn't exist) 
973              by u3util.exe when the U3 Wireshark is first run */
974           
975           szPath = g_malloc(strlen(u3devicedocumentpath) + strlen(U3_MY_CAPTURES) + 1);
976           strcpy(szPath, u3devicedocumentpath);
977           strcat(szPath, U3_MY_CAPTURES);
978
979           persdatafile_dir = szPath;
980           return szPath;
981
982         } else {
983         /* Hint: SHGetFolderPath is not available on MSVC 6 - without Platform SDK */
984         bRet = SHGetSpecialFolderPath(NULL, tszPath, CSIDL_PERSONAL, FALSE);
985         if(bRet == TRUE) {
986                 szPath = utf_16to8(tszPath);
987                 persdatafile_dir = szPath;
988                 return szPath;
989         } else {
990                 return "";
991         }
992  }
993 #else
994   return "";
995 #endif
996 }
997
998 #ifdef _WIN32
999 /*
1000  * Returns the user's home directory on Win32.
1001  */
1002 static const char *
1003 get_home_dir(void)
1004 {
1005         static const char *home = NULL;
1006         char *homedrive, *homepath;
1007         char *homestring;
1008         char *lastsep;
1009
1010         /* Return the cached value, if available */
1011         if (home)
1012                 return home;
1013
1014         /*
1015          * XXX - should we use USERPROFILE anywhere in this process?
1016          * Is there a chance that it might be set but one or more of
1017          * HOMEDRIVE or HOMEPATH isn't set?
1018          */
1019         homedrive = getenv_utf8("HOMEDRIVE");
1020         if (homedrive != NULL) {
1021                 homepath = getenv_utf8("HOMEPATH");
1022                 if (homepath != NULL) {
1023                         /*
1024                          * This is cached, so we don't need to worry about
1025                          * allocating multiple ones of them.
1026                          */
1027                         homestring =
1028                             g_malloc(strlen(homedrive) + strlen(homepath) + 1);
1029                         strcpy(homestring, homedrive);
1030                         strcat(homestring, homepath);
1031
1032                         /*
1033                          * Trim off any trailing slash or backslash.
1034                          */
1035                         lastsep = find_last_pathname_separator(homestring);
1036                         if (lastsep != NULL && *(lastsep + 1) == '\0') {
1037                                 /*
1038                                  * Last separator is the last character
1039                                  * in the string.  Nuke it.
1040                                  */
1041                                 *lastsep = '\0';
1042                         }
1043                         home = homestring;
1044                 } else
1045                         home = homedrive;
1046         } else {
1047                 /*
1048                  * Give up and use C:.
1049                  */
1050                 home = "C:";
1051         }
1052
1053         return home;
1054 }
1055 #endif
1056
1057 /*
1058  * Construct the path name of a personal configuration file, given the
1059  * file name.
1060  *
1061  * On Win32, if "for_writing" is FALSE, we check whether the file exists
1062  * and, if not, construct a path name relative to the ".wireshark"
1063  * subdirectory of the user's home directory, and check whether that
1064  * exists; if it does, we return that, so that configuration files
1065  * from earlier versions can be read.
1066  */
1067 char *
1068 get_persconffile_path(const char *filename, gboolean for_writing
1069 #ifndef _WIN32
1070         _U_
1071 #endif
1072 )
1073 {
1074         char *path;
1075 #ifdef _WIN32
1076         struct stat s_buf;
1077         char *old_path;
1078 #endif
1079
1080         path = g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s", get_persconffile_dir(),
1081             filename);
1082 #ifdef _WIN32
1083         if (!for_writing) {
1084                 if (eth_stat(path, &s_buf) != 0 && errno == ENOENT) {
1085                         /*
1086                          * OK, it's not in the personal configuration file
1087                          * directory; is it in the ".wireshark" subdirectory
1088                          * of their home directory?
1089                          */
1090                         old_path = g_strdup_printf(
1091                             "%s" G_DIR_SEPARATOR_S ".wireshark" G_DIR_SEPARATOR_S "%s",
1092                             get_home_dir(), filename);
1093                         if (eth_stat(old_path, &s_buf) == 0) {
1094                                 /*
1095                                  * OK, it exists; return it instead.
1096                                  */
1097                                 g_free(path);
1098                                 path = old_path;
1099                         }
1100                 }
1101         }
1102 #endif
1103
1104         return path;
1105 }
1106
1107 /* 
1108  * process command line option belonging to the filesystem settings
1109  * (move this e.g. to main.c and have set_persconffile_dir() instead in this file?)
1110  */
1111 int
1112 filesystem_opt(int opt _U_, const char *optarg)
1113 {
1114   gchar *p, *colonp;
1115
1116   colonp = strchr(optarg, ':');
1117   if (colonp == NULL) {
1118     return 1;
1119   }
1120
1121   p = colonp;
1122   *p++ = '\0';
1123
1124   /*
1125    * Skip over any white space (there probably won't be any, but
1126    * as we allow it in the preferences file, we might as well
1127    * allow it here).
1128    */
1129   while (isspace((guchar)*p))
1130     p++;
1131   if (*p == '\0') {
1132     /*
1133      * Put the colon back, so if our caller uses, in an
1134      * error message, the string they passed us, the message
1135      * looks correct.
1136      */
1137     *colonp = ':';
1138     return 1;
1139   }
1140
1141   /* directory should be existing */
1142   /* XXX - is this a requirement? */
1143   if(test_for_directory(p) != EISDIR) {
1144     /*
1145      * Put the colon back, so if our caller uses, in an
1146      * error message, the string they passed us, the message
1147      * looks correct.
1148      */
1149     *colonp = ':';
1150     return 1;
1151   }
1152
1153   if (strcmp(optarg,"persconf") == 0) {
1154     persconffile_dir = p;
1155   } else if (strcmp(optarg,"persdata") == 0) {
1156     persdatafile_dir = p;
1157   /* XXX - might need to add the temp file path */
1158   } else {
1159     return 1;
1160   }
1161   *colonp = ':'; /* put the colon back */
1162   return 0;
1163 }
1164
1165 /*
1166  * Construct the path name of a global configuration file, given the
1167  * file name.
1168  */
1169 char *
1170 get_datafile_path(const char *filename)
1171 {
1172
1173         return g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s", get_datafile_dir(),
1174             filename);
1175 }
1176
1177 /* Delete a file */
1178 gboolean
1179 deletefile(const char *path)
1180 {
1181         return eth_unlink(path) == 0;
1182 }
1183
1184 /*
1185  * Construct and return the path name of a file in the
1186  * appropriate temporary file directory.
1187  */
1188 char *get_tempfile_path(const char *filename)
1189 {
1190
1191         return g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s", g_get_tmp_dir(), filename);
1192 }
1193
1194 /*
1195  * Return an error message for UNIX-style errno indications on open or
1196  * create operations.
1197  */
1198 const char *
1199 file_open_error_message(int err, gboolean for_writing)
1200 {
1201         const char *errmsg;
1202         static char errmsg_errno[1024+1];
1203
1204         switch (err) {
1205
1206         case ENOENT:
1207                 if (for_writing)
1208                         errmsg = "The path to the file \"%s\" doesn't exist.";
1209                 else
1210                         errmsg = "The file \"%s\" doesn't exist.";
1211                 break;
1212
1213         case EACCES:
1214                 if (for_writing)
1215                         errmsg = "You don't have permission to create or write to the file \"%s\".";
1216                 else
1217                         errmsg = "You don't have permission to read the file \"%s\".";
1218                 break;
1219
1220         case EISDIR:
1221                 errmsg = "\"%s\" is a directory (folder), not a file.";
1222                 break;
1223
1224         case ENOSPC:
1225                 errmsg = "The file \"%s\" could not be created because there is no space left on the file system.";
1226                 break;
1227
1228 #ifdef EDQUOT
1229         case EDQUOT:
1230                 errmsg = "The file \"%s\" could not be created because you are too close to, or over, your disk quota.";
1231                 break;
1232 #endif
1233
1234         case EINVAL:
1235                 errmsg = "The file \"%s\" could not be created because an invalid filename was specified.";
1236                 break;
1237
1238         default:
1239                 g_snprintf(errmsg_errno, sizeof(errmsg_errno),
1240                                 "The file \"%%s\" could not be %s: %s.",
1241                                 for_writing ? "created" : "opened",
1242                                 strerror(err));
1243                 errmsg = errmsg_errno;
1244                 break;
1245         }
1246         return errmsg;
1247 }
1248
1249 /*
1250  * Return an error message for UNIX-style errno indications on write
1251  * operations.
1252  */
1253 const char *
1254 file_write_error_message(int err)
1255 {
1256         const char *errmsg;
1257         static char errmsg_errno[1024+1];
1258
1259         switch (err) {
1260
1261         case ENOSPC:
1262                 errmsg = "The file \"%s\" could not be saved because there is no space left on the file system.";
1263                 break;
1264
1265 #ifdef EDQUOT
1266         case EDQUOT:
1267                 errmsg = "The file \"%s\" could not be saved because you are too close to, or over, your disk quota.";
1268                 break;
1269 #endif
1270
1271         default:
1272                 g_snprintf(errmsg_errno, sizeof(errmsg_errno),
1273                     "An error occurred while writing to the file \"%%s\": %s.",
1274                     strerror(err));
1275                 errmsg = errmsg_errno;
1276                 break;
1277         }
1278         return errmsg;
1279 }
1280
1281
1282 gboolean
1283 file_exists(const char *fname)
1284 {
1285   struct stat   file_stat;
1286
1287
1288 #ifdef _WIN32
1289   /*
1290    * This is a bit tricky on win32. The st_ino field is documented as:
1291    * "The inode, and therefore st_ino, has no meaning in the FAT, ..."
1292    * but it *is* set to zero if stat() returns without an error,
1293    * so this is working, but maybe not quite the way expected. ULFL
1294    */
1295    file_stat.st_ino = 1;   /* this will make things work if an error occured */
1296    eth_stat(fname, &file_stat);
1297    if (file_stat.st_ino == 0) {
1298        return TRUE;
1299    } else {
1300        return FALSE;
1301    }
1302 #else
1303    if (eth_stat(fname, &file_stat) != 0 && errno == ENOENT) {
1304        return FALSE;
1305    } else {
1306        return TRUE;
1307    }
1308 #endif
1309
1310 }
1311
1312 /*
1313  * Check that the from file is not the same as to file
1314  * We do it here so we catch all cases ...
1315  * Unfortunately, the file requester gives us an absolute file
1316  * name and the read file name may be relative (if supplied on
1317  * the command line), so we can't just compare paths. From Joerg Mayer.
1318  */
1319 gboolean
1320 files_identical(const char *fname1, const char *fname2)
1321 {
1322     /* Two different implementations, because:
1323      *
1324      * - _fullpath is not available on UN*X, so we can't get full
1325      *   paths and compare them (which wouldn't work with hard links
1326      *   in any case);
1327      *
1328      * - st_ino isn't filled in with a meaningful value on Windows.
1329      */
1330 #ifdef _WIN32
1331     char full1[MAX_PATH], full2[MAX_PATH];
1332
1333     /*
1334      * Get the absolute full paths of the file and compare them.
1335      * That won't work if you have hard links, but those aren't
1336      * much used on Windows, even though NTFS supports them.
1337      *
1338      * XXX - will _fullpath work with UNC?
1339      */
1340     if( _fullpath( full1, fname1, MAX_PATH ) == NULL ) {
1341         return FALSE;
1342     }
1343
1344     if( _fullpath( full2, fname2, MAX_PATH ) == NULL ) {
1345         return FALSE;
1346     }
1347
1348     if(strcmp(full1, full2) == 0) {
1349         return TRUE;
1350     } else {
1351         return FALSE;
1352     }
1353 #else
1354   struct stat   filestat1, filestat2;
1355
1356    /*
1357     * Compare st_dev and st_ino.
1358     */
1359    if (eth_stat(fname1, &filestat1) == -1)
1360        return FALSE;    /* can't get info about the first file */
1361    if (eth_stat(fname2, &filestat2) == -1)
1362        return FALSE;    /* can't get info about the second file */
1363    return (filestat1.st_dev == filestat2.st_dev &&
1364            filestat1.st_ino == filestat2.st_ino);
1365 #endif
1366 }
1367