initialize tree variables
[metze/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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23  */
24
25 #include "config.h"
26
27 /*
28  * Required with GNU libc to get dladdr().
29  * We define it here because <dlfcn.h> apparently gets included by
30  * one of the headers we include below.
31  */
32 #define _GNU_SOURCE
33
34 #ifdef HAVE_DIRENT_H
35 #include <dirent.h>
36 #endif
37
38 #include <stdio.h>
39 #include <ctype.h>
40 #include <stdlib.h>
41 #include <string.h>
42 #include <errno.h>
43
44 #include <glib.h>
45
46 #ifdef HAVE_UNISTD_H
47 #include <unistd.h>
48 #endif
49
50 #ifdef HAVE_FCNTL_H
51 #include <fcntl.h>
52 #endif
53
54 #ifdef HAVE_SYS_STAT_H
55 #include <sys/stat.h>
56 #endif
57
58 #ifdef _WIN32
59 #include <windows.h>
60 #include <tchar.h>
61 #include <shlobj.h>
62 #include <wsutil/unicode-utils.h>
63 #else /* _WIN32 */
64 #ifdef __APPLE__
65 #include <mach-o/dyld.h>
66 #endif
67 #ifdef __linux__
68 #include <sys/utsname.h>
69 #endif
70 #ifdef __FreeBSD__
71 #include <sys/types.h>
72 #include <sys/sysctl.h>
73 #endif
74 #ifdef HAVE_DLADDR
75 #include <dlfcn.h>
76 #endif
77 #include <pwd.h>
78 #endif /* _WIN32 */
79
80 #include "filesystem.h"
81 #include <wsutil/report_err.h>
82 #include <wsutil/privileges.h>
83 #include <wsutil/file_util.h>
84
85 #include <wiretap/wtap.h>   /* for WTAP_ERR_SHORT_WRITE */
86
87 #define PROFILES_DIR    "profiles"
88 #define PLUGINS_DIR_NAME    "plugins"
89
90 #define U3_MY_CAPTURES  "\\My Captures"
91
92 char *persconffile_dir = NULL;
93 char *persdatafile_dir = NULL;
94 char *persconfprofile = NULL;
95
96 static gboolean do_store_persconffiles = FALSE;
97 static GHashTable *profile_files = NULL;
98
99 /*
100  * Given a pathname, return a pointer to the last pathname separator
101  * character in the pathname, or NULL if the pathname contains no
102  * separators.
103  */
104 char *
105 find_last_pathname_separator(const char *path)
106 {
107     char *separator;
108
109 #ifdef _WIN32
110     char c;
111
112     /*
113      * We have to scan for '\' or '/'.
114      * Get to the end of the string.
115      */
116     separator = strchr(path, '\0');     /* points to ending '\0' */
117     while (separator > path) {
118         c = *--separator;
119         if (c == '\\' || c == '/')
120             return separator;   /* found it */
121     }
122
123     /*
124      * OK, we didn't find any, so no directories - but there might
125      * be a drive letter....
126      */
127     return strchr(path, ':');
128 #else
129     separator = strrchr(path, '/');
130     return separator;
131 #endif
132 }
133
134 /*
135  * Given a pathname, return the last component.
136  */
137 const char *
138 get_basename(const char *path)
139 {
140     const char *filename;
141
142     g_assert(path != NULL);
143     filename = find_last_pathname_separator(path);
144     if (filename == NULL) {
145         /*
146          * There're no directories, drive letters, etc. in the
147          * name; the pathname *is* the file name.
148          */
149         filename = path;
150     } else {
151         /*
152          * Skip past the pathname or drive letter separator.
153          */
154         filename++;
155     }
156     return filename;
157 }
158
159 /*
160  * Given a pathname, return a string containing everything but the
161  * last component.  NOTE: this overwrites the pathname handed into
162  * it....
163  */
164 char *
165 get_dirname(char *path)
166 {
167     char *separator;
168
169     g_assert(path != NULL);
170     separator = find_last_pathname_separator(path);
171     if (separator == NULL) {
172         /*
173          * There're no directories, drive letters, etc. in the
174          * name; there is no directory path to return.
175          */
176         return NULL;
177     }
178
179     /*
180      * Get rid of the last pathname separator and the final file
181      * name following it.
182      */
183     *separator = '\0';
184
185     /*
186      * "path" now contains the pathname of the directory containing
187      * the file/directory to which it referred.
188      */
189     return path;
190 }
191
192 /*
193  * Given a pathname, return:
194  *
195  *  the errno, if an attempt to "stat()" the file fails;
196  *
197  *  EISDIR, if the attempt succeeded and the file turned out
198  *  to be a directory;
199  *
200  *  0, if the attempt succeeded and the file turned out not
201  *  to be a directory.
202  */
203
204 /*
205  * Visual C++ on Win32 systems doesn't define these.  (Old UNIX systems don't
206  * define them either.)
207  *
208  * Visual C++ on Win32 systems doesn't define S_IFIFO, it defines _S_IFIFO.
209  */
210 #ifndef S_ISREG
211 #define S_ISREG(mode)   (((mode) & S_IFMT) == S_IFREG)
212 #endif
213 #ifndef S_IFIFO
214 #define S_IFIFO _S_IFIFO
215 #endif
216 #ifndef S_ISFIFO
217 #define S_ISFIFO(mode)  (((mode) & S_IFMT) == S_IFIFO)
218 #endif
219 #ifndef S_ISDIR
220 #define S_ISDIR(mode)   (((mode) & S_IFMT) == S_IFDIR)
221 #endif
222
223 int
224 test_for_directory(const char *path)
225 {
226     ws_statb64 statb;
227
228     if (ws_stat64(path, &statb) < 0)
229         return errno;
230
231     if (S_ISDIR(statb.st_mode))
232         return EISDIR;
233     else
234         return 0;
235 }
236
237 int
238 test_for_fifo(const char *path)
239 {
240     ws_statb64 statb;
241
242     if (ws_stat64(path, &statb) < 0)
243         return errno;
244
245     if (S_ISFIFO(statb.st_mode))
246         return ESPIPE;
247     else
248         return 0;
249 }
250
251 /*
252  * Directory from which the executable came.
253  */
254 static char *progfile_dir;
255
256 #ifdef __APPLE__
257 /*
258  * Directory of the application bundle in which we're contained,
259  * if we're contained in an application bundle.  Otherwise, NULL.
260  *
261  * Note: Table 2-5 "Subdirectories of the Contents directory" of
262  *
263  *    https://developer.apple.com/library/mac/documentation/CoreFoundation/Conceptual/CFBundles/BundleTypes/BundleTypes.html#//apple_ref/doc/uid/10000123i-CH101-SW1
264  *
265  * says that the "Frameworks" directory
266  *
267  *    Contains any private shared libraries and frameworks used by the
268  *    executable.  The frameworks in this directory are revision-locked
269  *    to the application and cannot be superseded by any other, even
270  *    newer, versions that may be available to the operating system.  In
271  *    other words, the frameworks included in this directory take precedence
272  *    over any other similarly named frameworks found in other parts of
273  *    the operating system.  For information on how to add private
274  *    frameworks to your application bundle, see Framework Programming Guide.
275  *
276  * so if we were to ship with any frameworks (e.g. Qt) we should
277  * perhaps put them in a Frameworks directory rather than under
278  * Resources.
279  *
280  * It also says that the "PlugIns" directory
281  *
282  *    Contains loadable bundles that extend the basic features of your
283  *    application. You use this directory to include code modules that
284  *    must be loaded into your applicationbs process space in order to
285  *    be used. You would not use this directory to store standalone
286  *    executables.
287  *
288  * Our plugins are just raw .so/.dylib files; I don't know whether by
289  * "bundles" they mean application bundles (i.e., directory hierarchies)
290  * or just "bundles" in the Mach-O sense (which are an image type that
291  * can be loaded with dlopen() but not linked as libraries; our plugins
292  * are, I think, built as dylibs and can be loaded either way).
293  *
294  * And it says that the "SharedSupport" directory
295  *
296  *    Contains additional non-critical resources that do not impact the
297  *    ability of the application to run. You might use this directory to
298  *    include things like document templates, clip art, and tutorials
299  *    that your application expects to be present but that do not affect
300  *    the ability of your application to run.
301  *
302  * I don't think I'd put the files that currently go under Resources/share
303  * into that category; they're not, for example, sample Lua scripts that
304  * don't actually get run by Wireshark, they're configuration/data files
305  * for Wireshark whose absence might not prevent Wireshark from running
306  * but that would affect how it behaves when run.
307  */
308 static char *appbundle_dir;
309 #endif
310
311 /*
312  * TRUE if we're running from the build directory and we aren't running
313  * with special privileges.
314  */
315 static gboolean running_in_build_directory_flag = FALSE;
316
317 #ifndef _WIN32
318 /*
319  * Get the pathname of the executable using various platform-
320  * dependent mechanisms for various UN*Xes.
321  *
322  * These calls all should return something independent of the argv[0]
323  * passed to the program, so it shouldn't be fooled by an argv[0]
324  * that doesn't match the executable path.
325  *
326  * Sadly, not all UN*Xes necessarily have dladdr(), and those that
327  * do don't necessarily have dladdr(main) return information about
328  * the executable image, and those that do aren't necessarily running
329  * on a platform wherein the executable image can get its own path
330  * from the kernel (either by a call or by it being handed to it along
331  * with argv[] and the environment), and those that can don't
332  * necessarily use that to supply the path you get from dladdr(main),
333  * so we try this first and, if that fails, use dladdr(main) if
334  * available.
335  *
336  * In particular, some dynamic linkers supply a dladdr() such that
337  * dladdr(main) just returns something derived from argv[0], so
338  * just using dladdr(main) is the wrong thing to do if there's
339  * another mechanism that can get you a more reliable version of
340  * the executable path.
341  *
342  * However, at least in newer versions of DragonFly BSD, the dynamic
343  * linker *does* get it from the aux vector passed to the program
344  * by the kernel,  readlink /proc/curproc/file - which came first?
345  *
346  * On OpenBSD, dladdr(main) returns a value derived from argv[0],
347  * and there doesn't appear to be any way to get the executable path
348  * from the kernel, so we're out of luck there.
349  *
350  * So, on platforms where some versions have a version of dladdr()
351  * that gives an argv[0]-based path and that also have a mechanism
352  * to get a more reliable version of the path, we try that.  On
353  * other platforms, we return NULL.  If our caller gets back a NULL
354  * from us, it falls back on dladdr(main) if dladdr() is available,
355  * and if that fails or is unavailable, it falls back on processing
356  * argv[0] itself.
357  *
358  * This is not guaranteed to return an absolute path; if it doesn't,
359  * our caller must prepend the current directory if it's a path.
360  *
361  * This is not guaranteed to return the "real path"; it might return
362  * something with symbolic links in the path.  Our caller must
363  * use realpath() if they want the real thing, but that's also true of
364  * something obtained by looking at argv[0].
365  */
366 const char *
367 get_executable_path(void)
368 {
369 #if defined(__APPLE__)
370     char *executable_path;
371     uint32_t path_buf_size;
372
373     path_buf_size = PATH_MAX;
374     executable_path = (char *)g_malloc(path_buf_size);
375     if (_NSGetExecutablePath(executable_path, &path_buf_size) == -1) {
376         executable_path = (char *)g_realloc(executable_path, path_buf_size);
377         if (_NSGetExecutablePath(executable_path, &path_buf_size) == -1)
378             return NULL;
379     }
380     return executable_path;
381 #elif defined(__linux__)
382     /*
383      * In older versions of GNU libc's dynamic linker, as used on Linux,
384      * dladdr(main) supplies a path based on argv[0], so we use
385      * /proc/self/exe instead; there are Linux distributions with
386      * kernels that support /proc/self/exe and those older versions
387      * of the dynamic linker, and this will get a better answer on
388      * those versions.
389      *
390      * It only works on Linux 2.2 or later, so we just give up on
391      * earlier versions.
392      *
393      * XXX - are there OS versions that support "exe" but not "self"?
394      */
395     struct utsname name;
396     static char executable_path[PATH_MAX];
397
398     if (uname(&name) == -1)
399         return NULL;
400     if (strncmp(name.release, "1.", 2) == 0)
401         return NULL; /* Linux 1.x */
402     if (strcmp(name.release, "2.0") == 0 ||
403         strncmp(name.release, "2.0.", 4) == 0 ||
404         strcmp(name.release, "2.1") == 0 ||
405         strncmp(name.release, "2.1.", 4) == 0)
406         return NULL; /* Linux 2.0.x or 2.1.x */
407     if (readlink("/proc/self/exe", executable_path, sizeof executable_path) == -1)
408         return NULL;
409     return executable_path;
410 #elif defined(__FreeBSD__) && defined(KERN_PROC_PATHNAME)
411     /*
412      * In older versions of FreeBSD's dynamic linker, dladdr(main)
413      * supplies a path based on argv[0], so we use the KERN_PROC_PATHNAME
414      * sysctl instead; there are, I think, versions of FreeBSD
415      * that support the sysctl that have and those older versions
416      * of the dynamic linker, and this will get a better answer on
417      * those versions.
418      */
419     int mib[4];
420     char *executable_path;
421     size_t path_buf_size;
422
423     mib[0] = CTL_KERN;
424     mib[1] = KERN_PROC;
425     mib[2] = KERN_PROC_PATHNAME;
426     mib[3] = -1;
427     path_buf_size = PATH_MAX;
428     executable_path = (char *)g_malloc(path_buf_size);
429     if (sysctl(mib, 4, executable_path, &path_buf_size, NULL, 0) == -1) {
430         if (errno != ENOMEM)
431             return NULL;
432         executable_path = (char *)g_realloc(executable_path, path_buf_size);
433         if (sysctl(mib, 4, executable_path, &path_buf_size, NULL, 0) == -1)
434             return NULL;
435     }
436     return executable_path;
437 #elif defined(__NetBSD__)
438     /*
439      * In all versions of NetBSD's dynamic linker as of 2013-08-12,
440      * dladdr(main) supplies a path based on argv[0], so we use
441      * /proc/curproc/exe instead.
442      *
443      * XXX - are there OS versions that support "exe" but not "curproc"
444      * or "self"?  Are there any that support "self" but not "curproc"?
445      */
446     static char executable_path[PATH_MAX];
447
448     if (readlink("/proc/curproc/exe", executable_path, sizeof executable_path) == -1)
449         return NULL;
450     return executable_path;
451 #elif defined(__DragonFly__)
452     /*
453      * In older versions of DragonFly BSD's dynamic linker, dladdr(main)
454      * supplies a path based on argv[0], so we use /proc/curproc/file
455      * instead; it appears to be supported by all versions of DragonFly
456      * BSD.
457      */
458     static char executable_path[PATH_MAX];
459
460     if (readlink("/proc/curproc/file", executable_path, sizeof executable_path) == -1)
461         return NULL;
462     return executable_path;
463 #elif (defined(sun) || defined(__sun)) && defined(HAVE_GETEXECNAME)
464     /*
465      * It appears that getexecname() dates back to at least Solaris 8,
466      * but /proc/{pid}/path is first documented in the Solaris 10 documentation,
467      * so we use getexecname() if available, rather than /proc/self/path/a.out
468      * (which isn't documented, but appears to be a symlink to the
469      * executable image file).
470      */
471     return getexecname();
472 #else
473     /* Fill in your favorite UN*X's code here, if there is something */
474     return NULL;
475 #endif
476 }
477 #endif /* _WIN32 */
478
479 /*
480  * Get the pathname of the directory from which the executable came,
481  * and save it for future use.  Returns NULL on success, and a
482  * g_mallocated string containing an error on failure.
483  */
484 char *
485 init_progfile_dir(const char *arg0
486 #ifdef _WIN32
487     _U_
488 #endif
489 , int (*main_addr)(int, char **)
490 #if defined(_WIN32) || !defined(HAVE_DLADDR)
491     _U_
492 #endif
493 )
494 {
495 #ifdef _WIN32
496     TCHAR prog_pathname_w[_MAX_PATH+2];
497     char *prog_pathname;
498     DWORD error;
499     TCHAR *msg_w;
500     guchar *msg;
501     size_t msglen;
502
503     /*
504      * Attempt to get the full pathname of the currently running
505      * program.
506      */
507     if (GetModuleFileName(NULL, prog_pathname_w, G_N_ELEMENTS(prog_pathname_w)) != 0 && GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
508         /*
509          * XXX - Should we use g_utf16_to_utf8(), as in
510          * getenv_utf8()?
511          */
512         prog_pathname = utf_16to8(prog_pathname_w);
513         /*
514          * We got it; strip off the last component, which would be
515          * the file name of the executable, giving us the pathname
516          * of the directory where the executable resides.
517          */
518         progfile_dir = g_path_get_dirname(prog_pathname);
519         if (progfile_dir != NULL) {
520             return NULL;    /* we succeeded */
521         } else {
522             /*
523              * OK, no. What do we do now?
524              */
525             return g_strdup_printf("No \\ in executable pathname \"%s\"",
526                 prog_pathname);
527         }
528     } else {
529         /*
530          * Oh, well.  Return an indication of the error.
531          */
532         error = GetLastError();
533         if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,
534             NULL, error, 0, (LPTSTR) &msg_w, 0, NULL) == 0) {
535             /*
536              * Gak.  We can't format the message.
537              */
538             return g_strdup_printf("GetModuleFileName failed: %u (FormatMessage failed: %u)",
539                 error, GetLastError());
540         }
541         msg = utf_16to8(msg_w);
542         LocalFree(msg_w);
543         /*
544          * "FormatMessage()" "helpfully" sticks CR/LF at the
545          * end of the message.  Get rid of it.
546          */
547         msglen = strlen(msg);
548         if (msglen >= 2) {
549             msg[msglen - 1] = '\0';
550             msg[msglen - 2] = '\0';
551         }
552         return g_strdup_printf("GetModuleFileName failed: %s (%u)",
553             msg, error);
554     }
555 #else
556 #ifdef HAVE_DLADDR
557     Dl_info info;
558 #endif
559     const char *execname;
560     char *prog_pathname;
561     char *curdir;
562     long path_max;
563     char *pathstr;
564     char *path_start, *path_end;
565     size_t path_component_len;
566     char *retstr;
567     char *path;
568     char *dir_end;
569
570     /*
571      * Check whether WIRESHARK_RUN_FROM_BUILD_DIRECTORY is set in the
572      * environment; if so, set running_in_build_directory_flag if we
573      * weren't started with special privileges.  (If we were started
574      * with special privileges, it's not safe to allow the user to point
575      * us to some other directory; running_in_build_directory_flag, when
576      * set, causes us to look for plugins and the like in the build
577      * directory.)
578      */
579     if (getenv("WIRESHARK_RUN_FROM_BUILD_DIRECTORY") != NULL
580         && !started_with_special_privs())
581         running_in_build_directory_flag = TRUE;
582
583     execname = get_executable_path();
584 #ifdef HAVE_DLADDR
585     if (main_addr != NULL && execname == NULL) {
586         /*
587          * Try to use dladdr() to find the pathname of the executable.
588          * dladdr() is not guaranteed to give you anything better than
589          * argv[0] (i.e., it might not contain a / at all, much less
590          * being an absolute path), and doesn't appear to do so on
591          * Linux, but on other platforms it could give you an absolute
592          * path and obviate the need for us to determine the absolute
593          * path.
594          */
595         if (dladdr((void *)main_addr, &info))
596             execname = info.dli_fname;
597     }
598 #endif
599     if (execname == NULL) {
600         /*
601          * OK, guess based on argv[0].
602          */
603         execname = arg0;
604     }
605
606     /*
607      * Try to figure out the directory in which the currently running
608      * program resides, given something purporting to be the executable
609      * name (from dladdr() or from the argv[0] it was started with.
610      * That might be the absolute path of the program, or a path relative
611      * to the current directory of the process that started it, or
612      * just a name for the program if it was started from the command
613      * line and was searched for in $PATH.  It's not guaranteed to be
614      * any of those, however, so there are no guarantees....
615      */
616     if (execname[0] == '/') {
617         /*
618          * It's an absolute path.
619          */
620         prog_pathname = g_strdup(execname);
621     } else if (strchr(execname, '/') != NULL) {
622         /*
623          * It's a relative path, with a directory in it.
624          * Get the current directory, and combine it
625          * with that directory.
626          */
627         path_max = pathconf(".", _PC_PATH_MAX);
628         if (path_max == -1) {
629             /*
630              * We have no idea how big a buffer to
631              * allocate for the current directory.
632              */
633             return g_strdup_printf("pathconf failed: %s\n",
634                 g_strerror(errno));
635         }
636         curdir = (char *)g_malloc(path_max);
637         if (getcwd(curdir, path_max) == NULL) {
638             /*
639              * It failed - give up, and just stick
640              * with DATAFILE_DIR.
641              */
642             g_free(curdir);
643             return g_strdup_printf("getcwd failed: %s\n",
644                 g_strerror(errno));
645         }
646         path = g_strdup_printf("%s/%s", curdir, execname);
647         g_free(curdir);
648         prog_pathname = path;
649     } else {
650         /*
651          * It's just a file name.
652          * Search the path for a file with that name
653          * that's executable.
654          */
655         prog_pathname = NULL;   /* haven't found it yet */
656         pathstr = getenv("PATH");
657         path_start = pathstr;
658         if (path_start != NULL) {
659             while (*path_start != '\0') {
660                 path_end = strchr(path_start, ':');
661                 if (path_end == NULL)
662                     path_end = path_start + strlen(path_start);
663                 path_component_len = path_end - path_start;
664                 path = (char *)g_malloc(path_component_len + 1
665                     + strlen(execname) + 1);
666                 memcpy(path, path_start, path_component_len);
667                 path[path_component_len] = '\0';
668                 strncat(path, "/", 2);
669                 strncat(path, execname, strlen(execname) + 1);
670                 if (access(path, X_OK) == 0) {
671                     /*
672                      * Found it!
673                      */
674                     prog_pathname = path;
675                     break;
676                 }
677
678                 /*
679                  * That's not it.  If there are more
680                  * path components to test, try them.
681                  */
682                 if (*path_end == '\0') {
683                     /*
684                      * There's nothing more to try.
685                      */
686                     break;
687                 }
688                 if (*path_end == ':')
689                     path_end++;
690                 path_start = path_end;
691                 g_free(path);
692             }
693             if (prog_pathname == NULL) {
694                 /*
695                  * Program not found in path.
696                  */
697                 return g_strdup_printf("\"%s\" not found in \"%s\"",
698                     execname, pathstr);
699             }
700         } else {
701             /*
702              * PATH isn't set.
703              * XXX - should we pick a default?
704              */
705             return g_strdup("PATH isn't set");
706         }
707     }
708
709     /*
710      * OK, we have what we think is the pathname
711      * of the program.
712      *
713      * First, find the last "/" in the directory,
714      * as that marks the end of the directory pathname.
715      */
716     dir_end = strrchr(prog_pathname, '/');
717     if (dir_end != NULL) {
718         /*
719          * Found it.  Strip off the last component,
720          * as that's the path of the program.
721          */
722         *dir_end = '\0';
723
724         /*
725          * Is there a "/.libs" at the end?
726          */
727         dir_end = strrchr(prog_pathname, '/');
728         if (dir_end != NULL) {
729             if (strcmp(dir_end, "/.libs") == 0) {
730                 /*
731                  * Yup, it's ".libs".
732                  * Strip that off; it's an
733                  * artifact of libtool.
734                  */
735                 *dir_end = '\0';
736
737                 /*
738                  * This presumably means we're run from
739                  * the libtool wrapper, which probably
740                  * means we're being run from the build
741                  * directory.  If we weren't started
742                  * with special privileges, set
743                  * running_in_build_directory_flag.
744                  *
745                  * XXX - should we check whether what
746                  * follows ".libs/" begins with "lt-"?
747                  */
748                 if (!started_with_special_privs())
749                     running_in_build_directory_flag = TRUE;
750             }
751 #ifdef __APPLE__
752             else {
753                 if (!started_with_special_privs()) {
754                     /*
755                      * Scan up the path looking for a component
756                      * named "Contents".  If we find it, we assume
757                      * we're in a bundle, and that the top-level
758                      * directory of the bundle is the one containing
759                      * "Contents".
760                      *
761                      * Not all executables are in the Contents/MacOS
762                      * directory, so we can't just check for those
763                      * in the path and strip them off.
764                      *
765                      * XXX - should we assume that it's either
766                      * Contents/MacOS or Resources/bin?
767                      */
768                     char *component_end, *p;
769
770                     component_end = strchr(prog_pathname, '\0');
771                     p = component_end;
772                     for (;;) {
773                         while (p >= prog_pathname && *p != '/')
774                             p--;
775                         if (p == prog_pathname) {
776                             /*
777                              * We're looking at the first component of
778                              * the pathname now, so we're definitely
779                              * not in a bundle, even if we're in
780                              * "/Contents".
781                              */
782                             break;
783                         }
784                         if (strncmp(p, "/Contents", component_end - p) == 0) {
785                             /* Found it. */
786                             appbundle_dir = (char *)g_malloc(p - prog_pathname + 1);
787                             memcpy(appbundle_dir, prog_pathname, p - prog_pathname);
788                             appbundle_dir[p - prog_pathname] = '\0';
789                             break;
790                         }
791                         component_end = p;
792                         p--;
793                     }
794                 }
795             }
796 #endif
797         }
798
799         /*
800          * OK, we have the path we want.
801          */
802         progfile_dir = prog_pathname;
803         return NULL;
804     } else {
805         /*
806          * This "shouldn't happen"; we apparently
807          * have no "/" in the pathname.
808          * Just free up prog_pathname.
809          */
810         retstr = g_strdup_printf("No / found in \"%s\"", prog_pathname);
811         g_free(prog_pathname);
812         return retstr;
813     }
814 #endif
815 }
816
817 /*
818  * Get the directory in which the program resides.
819  */
820 const char *
821 get_progfile_dir(void)
822 {
823     return progfile_dir;
824 }
825
826 /*
827  * Get the directory in which the global configuration and data files are
828  * stored.
829  *
830  * On Windows, we use the directory in which the executable for this
831  * process resides.
832  *
833  * On UN*X, we use the DATAFILE_DIR value supplied by the configure
834  * script, unless we think we're being run from the build directory,
835  * in which case we use the directory in which the executable for this
836  * process resides.
837  *
838  * XXX - if we ever make libwireshark a real library, used by multiple
839  * applications (more than just TShark and versions of Wireshark with
840  * various UIs), should the configuration files belong to the library
841  * (and be shared by all those applications) or to the applications?
842  *
843  * If they belong to the library, that could be done on UNIX by the
844  * configure script, but it's trickier on Windows, as you can't just
845  * use the pathname of the executable.
846  *
847  * If they belong to the application, that could be done on Windows
848  * by using the pathname of the executable, but we'd have to have it
849  * passed in as an argument, in some call, on UNIX.
850  *
851  * Note that some of those configuration files might be used by code in
852  * libwireshark, some of them might be used by dissectors (would they
853  * belong to libwireshark, the application, or a separate library?),
854  * and some of them might be used by other code (the Wireshark preferences
855  * file includes resolver preferences that control the behavior of code
856  * in libwireshark, dissector preferences, and UI preferences, for
857  * example).
858  */
859 const char *
860 get_datafile_dir(void)
861 {
862 #ifdef _WIN32
863     char *u3deviceexecpath;
864 #endif
865     static const char *datafile_dir = NULL;
866
867     if (datafile_dir != NULL)
868         return datafile_dir;
869
870 #ifdef _WIN32
871     /*
872      * See if we are running in a U3 environment.
873      */
874     u3deviceexecpath = getenv_utf8("U3_DEVICE_EXEC_PATH");
875
876     if (u3deviceexecpath != NULL) {
877         /*
878          * We are; use the U3 device executable path.
879          */
880         datafile_dir = u3deviceexecpath;
881     } else {
882         /*
883          * Do we have the pathname of the program?  If so, assume we're
884          * running an installed version of the program.  If we fail,
885          * we don't change "datafile_dir", and thus end up using the
886          * default.
887          *
888          * XXX - does NSIS put the installation directory into
889          * "\HKEY_LOCAL_MACHINE\SOFTWARE\Wireshark\InstallDir"?
890          * If so, perhaps we should read that from the registry,
891          * instead.
892          */
893         if (progfile_dir != NULL) {
894             /*
895              * Yes, we do; use that.
896              */
897             datafile_dir = progfile_dir;
898         } else {
899             /*
900              * No, we don't.
901              * Fall back on the default installation directory.
902              */
903             datafile_dir = "C:\\Program Files\\Wireshark\\";
904         }
905     }
906 #else
907     if (running_in_build_directory_flag) {
908         /*
909          * We're (probably) being run from the build directory and
910          * weren't started with special privileges.
911          *
912          * The data files we want are the ones from the source
913          * directory; to handle builds out of the source tree,
914          * we check whether WIRESHARK_SRC_DIR is set and, if so,
915          * use that as the source directory.
916          */
917         datafile_dir = getenv("WIRESHARK_SRC_DIR");
918         if (datafile_dir != NULL)
919             return datafile_dir;
920     }
921
922     /*
923      * Well, that didn't work.
924      * Check again whether we were (probably) run from the build
925      * directory and started without special privileges, and also
926      * check whether we were able to determine the directory in
927      * which the program was found.
928      *
929      * (running_in_build_directory_flag is never set to TRUE
930      * if we're started with special privileges, so we need
931      * only check it; we don't need to call started_with_special_privs().)
932      */
933     if (running_in_build_directory_flag && progfile_dir != NULL) {
934         /*
935          * We're (probably) being run from the build directory and
936          * weren't started with special privileges, and we were
937          * able to determine the directory in which the program
938          * was found.  Assume that directory is the build
939          * directory and that it's the same as the source
940          * directory.
941          */
942         datafile_dir = progfile_dir;
943     } else {
944         /*
945          * Return the directory specified when the build was
946          * configured, prepending the run path prefix if it exists.
947          */
948         if (getenv("WIRESHARK_DATA_DIR") && !started_with_special_privs()) {
949             /*
950              * The user specified a different directory for data files
951              * and we aren't running with special privileges.
952              * XXX - We might be able to dispense with the priv check
953              */
954             datafile_dir = g_strdup(getenv("WIRESHARK_DATA_DIR"));
955         }
956 #ifdef __APPLE__
957         /*
958          * If we're running from an app bundle and weren't started
959          * with special privileges, use the Contents/Resources/share/wireshark
960          * subdirectory of the app bundle.
961          *
962          * (appbundle_dir is not set to a non-null value if we're
963          * started with special privileges, so we need only check
964          * it; we don't need to call started_with_special_privs().)
965          */
966         else if (appbundle_dir != NULL) {
967             datafile_dir = g_strdup_printf("%s/Contents/Resources/share/wireshark",
968                                            appbundle_dir);
969         }
970 #endif
971         else {
972             datafile_dir = DATAFILE_DIR;
973         }
974     }
975
976 #endif
977     return datafile_dir;
978 }
979
980 #ifdef HAVE_PYTHON
981 /*
982  * Find the directory where the python dissectors are stored.
983  *
984  * On Windows, we use the "py_dissector" subdirectory of the datafile directory.
985  *
986  * On UN*X, we use the PYTHON_DIR value supplied by the configure
987  * script, unless we think we're being run from the build directory,
988  * in which case we use the "py_dissector" subdirectory of the datafile directory.
989  *
990  * In both cases, we then use the subdirectory of that directory whose
991  * name is the version number.
992  *
993  * XXX - if we think we're being run from the build directory, perhaps we
994  * should have the plugin code not look in the version subdirectory
995  * of the plugin directory, but look in all of the subdirectories
996  * of the plugin directory, so it can just fetch the plugins built
997  * as part of the build process.
998  */
999 static const char *wspython_dir = NULL;
1000
1001 static void
1002 init_wspython_dir(void)
1003 {
1004 #ifdef _WIN32
1005     /*
1006      * On Windows, the data file directory is the installation
1007      * directory; the python dissectors are stored under it.
1008      *
1009      * Assume we're running the installed version of Wireshark;
1010      * on Windows, the data file directory is the directory
1011      * in which the Wireshark binary resides.
1012      */
1013         wspython_dir = g_strdup_printf("%s\\python\\%s", get_datafile_dir(),
1014                                         VERSION);
1015
1016     /*
1017      * Make sure that pathname refers to a directory.
1018      */
1019     if (test_for_directory(wspython_dir) != EISDIR) {
1020         /*
1021          * Either it doesn't refer to a directory or it
1022          * refers to something that doesn't exist.
1023          *
1024          * Assume that means we're running a version of
1025          * Wireshark we've built in a build directory,
1026          * in which case {datafile dir}\python is the
1027          * top-level plugins source directory, and use
1028          * that directory and set the "we're running in
1029          * a build directory" flag, so the plugin
1030          * scanner will check all subdirectories of that
1031          * directory for python dissectors.
1032          */
1033         g_free( (gpointer) wspython_dir);
1034         wspython_dir = g_strdup_printf("%s\\python", get_datafile_dir());
1035         running_in_build_directory_flag = TRUE;
1036     }
1037 #else
1038     if (running_in_build_directory_flag) {
1039         /*
1040          * We're (probably) being run from the build directory and
1041          * weren't started with special privileges, so we'll use
1042          * the "python" subdirectory of the datafile directory
1043          * (the datafile directory is the build directory).
1044          */
1045         wspython_dir = g_strdup_printf("%s/epan/wspython/", get_datafile_dir());
1046     } else {
1047         if (getenv("WIRESHARK_PYTHON_DIR") && !started_with_special_privs()) {
1048             /*
1049              * The user specified a different directory for plugins
1050              * and we aren't running with special privileges.
1051              */
1052             wspython_dir = g_strdup(getenv("WIRESHARK_PYTHON_DIR"));
1053         }
1054 #ifdef __APPLE__
1055         /*
1056          * If we're running from an app bundle and weren't started
1057          * with special privileges, use the Contents/Resources/lib/wireshark/python
1058          * subdirectory of the app bundle.
1059          *
1060          * (appbundle_dir is not set to a non-null value if we're
1061          * started with special privileges, so we need only check
1062          * it; we don't need to call started_with_special_privs().)
1063          */
1064         else if (appbundle_dir != NULL) {
1065             wspython_dir = g_strdup_printf("%s/Contents/Resources/lib/wireshark/python",
1066                                            appbundle_dir);
1067         }
1068 #endif
1069         else {
1070             wspython_dir = PYTHON_DIR;
1071         }
1072     }
1073 #endif
1074 }
1075 #endif /* HAVE_PYTHON */
1076
1077 /*
1078  * Get the directory in which the python dissectors are stored.
1079  */
1080 const char *
1081 get_wspython_dir(void)
1082 {
1083 #ifdef HAVE_PYTHON
1084     if (!wspython_dir) init_wspython_dir();
1085     return wspython_dir;
1086 #else
1087     return NULL;
1088 #endif
1089 }
1090
1091
1092 #if defined(HAVE_PLUGINS) || defined(HAVE_LUA)
1093 /*
1094  * Find the directory where the plugins are stored.
1095  *
1096  * On Windows, we use the "plugin" subdirectory of the datafile directory.
1097  *
1098  * On UN*X, we use the PLUGIN_DIR value supplied by the configure
1099  * script, unless we think we're being run from the build directory,
1100  * in which case we use the "plugin" subdirectory of the datafile directory.
1101  *
1102  * In both cases, we then use the subdirectory of that directory whose
1103  * name is the version number.
1104  *
1105  * XXX - if we think we're being run from the build directory, perhaps we
1106  * should have the plugin code not look in the version subdirectory
1107  * of the plugin directory, but look in all of the subdirectories
1108  * of the plugin directory, so it can just fetch the plugins built
1109  * as part of the build process.
1110  */
1111 static const char *plugin_dir = NULL;
1112
1113 static void
1114 init_plugin_dir(void)
1115 {
1116 #ifdef _WIN32
1117     /*
1118      * On Windows, the data file directory is the installation
1119      * directory; the plugins are stored under it.
1120      *
1121      * Assume we're running the installed version of Wireshark;
1122      * on Windows, the data file directory is the directory
1123      * in which the Wireshark binary resides.
1124      */
1125     plugin_dir = g_strdup_printf("%s\\plugins\\%s", get_datafile_dir(),
1126                      VERSION);
1127
1128     /*
1129      * Make sure that pathname refers to a directory.
1130      */
1131     if (test_for_directory(plugin_dir) != EISDIR) {
1132         /*
1133          * Either it doesn't refer to a directory or it
1134          * refers to something that doesn't exist.
1135          *
1136          * Assume that means we're running a version of
1137          * Wireshark we've built in a build directory,
1138          * in which case {datafile dir}\plugins is the
1139          * top-level plugins source directory, and use
1140          * that directory and set the "we're running in
1141          * a build directory" flag, so the plugin
1142          * scanner will check all subdirectories of that
1143          * directory for plugins.
1144          */
1145         g_free( (gpointer) plugin_dir);
1146         plugin_dir = g_strdup_printf("%s\\plugins", get_datafile_dir());
1147         running_in_build_directory_flag = TRUE;
1148     }
1149 #else
1150     if (running_in_build_directory_flag) {
1151         /*
1152          * We're (probably) being run from the build directory and
1153          * weren't started with special privileges, so we'll use
1154          * the "plugins" subdirectory of the datafile directory
1155          * (the datafile directory is the build directory).
1156          */
1157         plugin_dir = g_strdup_printf("%s/plugins", get_datafile_dir());
1158     } else {
1159         if (getenv("WIRESHARK_PLUGIN_DIR") && !started_with_special_privs()) {
1160             /*
1161              * The user specified a different directory for plugins
1162              * and we aren't running with special privileges.
1163              */
1164             plugin_dir = g_strdup(getenv("WIRESHARK_PLUGIN_DIR"));
1165         }
1166 #ifdef __APPLE__
1167         /*
1168          * If we're running from an app bundle and weren't started
1169          * with special privileges, use the Contents/Resources/lib/wireshark/plugins
1170          * subdirectory of the app bundle.
1171          *
1172          * (appbundle_dir is not set to a non-null value if we're
1173          * started with special privileges, so we need only check
1174          * it; we don't need to call started_with_special_privs().)
1175          */
1176         else if (appbundle_dir != NULL) {
1177             plugin_dir = g_strdup_printf("%s/Contents/Resources/lib/wireshark/plugins",
1178                                          appbundle_dir);
1179         }
1180 #endif
1181         else {
1182             plugin_dir = PLUGIN_DIR;
1183         }
1184     }
1185 #endif
1186 }
1187 #endif /* HAVE_PLUGINS || HAVE_LUA */
1188
1189 /*
1190  * Get the directory in which the plugins are stored.
1191  */
1192 const char *
1193 get_plugin_dir(void)
1194 {
1195 #if defined(HAVE_PLUGINS) || defined(HAVE_LUA)
1196     if (!plugin_dir) init_plugin_dir();
1197     return plugin_dir;
1198 #else
1199     return NULL;
1200 #endif
1201 }
1202
1203 /*
1204  * Get the flag indicating whether we're running from a build
1205  * directory.
1206  */
1207 gboolean
1208 running_in_build_directory(void)
1209 {
1210     return running_in_build_directory_flag;
1211 }
1212
1213 /*
1214  * Get the directory in which files that, at least on UNIX, are
1215  * system files (such as "/etc/ethers") are stored; on Windows,
1216  * there's no "/etc" directory, so we get them from the global
1217  * configuration and data file directory.
1218  */
1219 const char *
1220 get_systemfile_dir(void)
1221 {
1222 #ifdef _WIN32
1223     return get_datafile_dir();
1224 #else
1225     return "/etc";
1226 #endif
1227 }
1228
1229 /*
1230  * Name of directory, under the user's home directory, in which
1231  * personal configuration files are stored.
1232  */
1233 #ifdef _WIN32
1234 #define PF_DIR "Wireshark"
1235 #else
1236 /*
1237  * XXX - should this be ".libepan"? For backwards-compatibility, I'll keep
1238  * it ".wireshark" for now.
1239  */
1240 #define PF_DIR ".wireshark"
1241 #endif
1242
1243 void
1244 set_profile_name(const gchar *profilename)
1245 {
1246     g_free (persconfprofile);
1247
1248     if (profilename && strlen(profilename) > 0 &&
1249         strcmp(profilename, DEFAULT_PROFILE) != 0) {
1250         persconfprofile = g_strdup (profilename);
1251     } else {
1252         /* Default Profile */
1253         persconfprofile = NULL;
1254     }
1255 }
1256
1257 const char *
1258 get_profile_name(void)
1259 {
1260     if (persconfprofile) {
1261         return persconfprofile;
1262     } else {
1263         return DEFAULT_PROFILE;
1264     }
1265 }
1266
1267 gboolean
1268 is_default_profile(void)
1269 {
1270     return (!persconfprofile || strcmp(persconfprofile, DEFAULT_PROFILE) == 0) ? TRUE : FALSE;
1271 }
1272
1273 gboolean
1274 has_global_profiles(void)
1275 {
1276     WS_DIR *dir;
1277     WS_DIRENT *file;
1278     const gchar *global_dir = get_global_profiles_dir();
1279     gchar *filename;
1280     gboolean has_global = FALSE;
1281
1282     if ((test_for_directory(global_dir) == EISDIR) &&
1283         ((dir = ws_dir_open(global_dir, 0, NULL)) != NULL))
1284     {
1285         while ((file = ws_dir_read_name(dir)) != NULL) {
1286             filename = g_strdup_printf ("%s%s%s", global_dir, G_DIR_SEPARATOR_S,
1287                             ws_dir_get_name(file));
1288             if (test_for_directory(filename) == EISDIR) {
1289                 has_global = TRUE;
1290                 g_free (filename);
1291                 break;
1292             }
1293             g_free (filename);
1294         }
1295         ws_dir_close(dir);
1296     }
1297
1298     return has_global;
1299 }
1300
1301 void
1302 profile_store_persconffiles(gboolean store)
1303 {
1304     if (store) {
1305         profile_files = g_hash_table_new (g_str_hash, g_str_equal);
1306     }
1307     do_store_persconffiles = store;
1308 }
1309
1310 /*
1311  * Get the directory in which personal configuration files reside;
1312  * in UNIX-compatible systems, it's ".wireshark", under the user's home
1313  * directory, and on Windows systems, it's "Wireshark", under %APPDATA%
1314  * or, if %APPDATA% isn't set, it's "%USERPROFILE%\Application Data"
1315  * (which is what %APPDATA% normally is on Windows 2000).
1316  */
1317 static const char *
1318 get_persconffile_dir_no_profile(void)
1319 {
1320 #ifdef _WIN32
1321     char *appdatadir;
1322     char *userprofiledir;
1323     char *altappdatapath;
1324 #else
1325     const char *homedir;
1326     struct passwd *pwd;
1327 #endif
1328
1329     /* Return the cached value, if available */
1330     if (persconffile_dir != NULL)
1331         return persconffile_dir;
1332
1333 #ifdef _WIN32
1334     /*
1335      * See if the user has selected an alternate environment.
1336      */
1337     altappdatapath = getenv_utf8("WIRESHARK_APPDATA");
1338     if (altappdatapath != NULL) {
1339         persconffile_dir = altappdatapath;
1340         return persconffile_dir;
1341     }
1342
1343     /*
1344      * See if we are running in a U3 environment.
1345      */
1346     altappdatapath = getenv_utf8("U3_APP_DATA_PATH");
1347     if (altappdatapath != NULL) {
1348         /*
1349          * We are; use the U3 application data path.
1350          */
1351         persconffile_dir = altappdatapath;
1352     } else {
1353         /*
1354          * Use %APPDATA% or %USERPROFILE%, so that configuration
1355          * files are stored in the user profile, rather than in
1356          * the home directory.  The Windows convention is to store
1357          * configuration information in the user profile, and doing
1358          * so means you can use Wireshark even if the home directory
1359          * is an inaccessible network drive.
1360          */
1361         appdatadir = getenv_utf8("APPDATA");
1362         if (appdatadir != NULL) {
1363             /*
1364              * Concatenate %APPDATA% with "\Wireshark".
1365              */
1366             persconffile_dir = g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s",
1367                                appdatadir, PF_DIR);
1368         } else {
1369             /*
1370              * OK, %APPDATA% wasn't set, so use
1371              * %USERPROFILE%\Application Data.
1372              */
1373             userprofiledir = getenv_utf8("USERPROFILE");
1374             if (userprofiledir != NULL) {
1375                 persconffile_dir = g_strdup_printf(
1376                     "%s" G_DIR_SEPARATOR_S "Application Data" G_DIR_SEPARATOR_S "%s",
1377                     userprofiledir, PF_DIR);
1378             } else {
1379                 /*
1380                  * Give up and use "C:".
1381                  */
1382                 persconffile_dir = g_strdup_printf("C:" G_DIR_SEPARATOR_S "%s", PF_DIR);
1383             }
1384         }
1385     }
1386 #else
1387     /*
1388      * If $HOME is set, use that.
1389      */
1390     homedir = getenv("HOME");
1391     if (homedir == NULL) {
1392         /*
1393          * Get their home directory from the password file.
1394          * If we can't even find a password file entry for them,
1395          * use "/tmp".
1396          */
1397         pwd = getpwuid(getuid());
1398         if (pwd != NULL) {
1399             homedir = pwd->pw_dir;
1400         } else {
1401             homedir = "/tmp";
1402         }
1403     }
1404     persconffile_dir = g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s", homedir, PF_DIR);
1405 #endif
1406
1407     return persconffile_dir;
1408 }
1409
1410 const char *
1411 get_profiles_dir(void)
1412 {
1413     static char *profiles_dir = NULL;
1414
1415     g_free (profiles_dir);
1416     profiles_dir = g_strdup_printf ("%s%s%s", get_persconffile_dir_no_profile (),
1417                     G_DIR_SEPARATOR_S, PROFILES_DIR);
1418
1419     return profiles_dir;
1420 }
1421
1422 const char *
1423 get_global_profiles_dir(void)
1424 {
1425     static char *global_profiles_dir = NULL;
1426
1427     if (!global_profiles_dir) {
1428         global_profiles_dir = g_strdup_printf ("%s%s%s", get_datafile_dir(),
1429                                G_DIR_SEPARATOR_S, PROFILES_DIR);
1430     }
1431
1432     return global_profiles_dir;
1433 }
1434
1435 static const char *
1436 get_persconffile_dir(const gchar *profilename)
1437 {
1438     static char *persconffile_profile_dir = NULL;
1439
1440     g_free (persconffile_profile_dir);
1441
1442     if (profilename && strlen(profilename) > 0 &&
1443         strcmp(profilename, DEFAULT_PROFILE) != 0) {
1444       persconffile_profile_dir = g_strdup_printf ("%s%s%s", get_profiles_dir (),
1445                               G_DIR_SEPARATOR_S, profilename);
1446     } else {
1447       persconffile_profile_dir = g_strdup (get_persconffile_dir_no_profile ());
1448     }
1449
1450     return persconffile_profile_dir;
1451 }
1452
1453 gboolean
1454 profile_exists(const gchar *profilename, gboolean global)
1455 {
1456     if (global) {
1457         gchar *path = g_strdup_printf ("%s%s%s", get_global_profiles_dir(),
1458                            G_DIR_SEPARATOR_S, profilename);
1459         if (test_for_directory (path) == EISDIR) {
1460             g_free (path);
1461             return TRUE;
1462         }
1463         g_free (path);
1464     } else {
1465         if (test_for_directory (get_persconffile_dir (profilename)) == EISDIR) {
1466             return TRUE;
1467         }
1468     }
1469
1470     return FALSE;
1471 }
1472
1473 static int
1474 delete_directory (const char *directory, char **pf_dir_path_return)
1475 {
1476     WS_DIR *dir;
1477     WS_DIRENT *file;
1478     gchar *filename;
1479     int ret = 0;
1480
1481     if ((dir = ws_dir_open(directory, 0, NULL)) != NULL) {
1482         while ((file = ws_dir_read_name(dir)) != NULL) {
1483             filename = g_strdup_printf ("%s%s%s", directory, G_DIR_SEPARATOR_S,
1484                             ws_dir_get_name(file));
1485             if (test_for_directory(filename) != EISDIR) {
1486                 ret = ws_remove(filename);
1487 #if 0
1488             } else {
1489                 /* The user has manually created a directory in the profile directory */
1490                 /* I do not want to delete the directory recursively yet */
1491                 ret = delete_directory (filename, pf_dir_path_return);
1492 #endif
1493             }
1494             if (ret != 0) {
1495                 *pf_dir_path_return = filename;
1496                 break;
1497             }
1498             g_free (filename);
1499         }
1500         ws_dir_close(dir);
1501     }
1502
1503     if (ret == 0 && (ret = ws_remove(directory)) != 0) {
1504         *pf_dir_path_return = g_strdup (directory);
1505     }
1506
1507     return ret;
1508 }
1509
1510 int
1511 delete_persconffile_profile(const char *profilename, char **pf_dir_path_return)
1512 {
1513     const char *profile_dir = get_persconffile_dir(profilename);
1514     int ret = 0;
1515
1516     if (test_for_directory (profile_dir) == EISDIR) {
1517         ret = delete_directory (profile_dir, pf_dir_path_return);
1518     }
1519
1520     return ret;
1521 }
1522
1523 int
1524 rename_persconffile_profile(const char *fromname, const char *toname,
1525                 char **pf_from_dir_path_return, char **pf_to_dir_path_return)
1526 {
1527     char *from_dir = g_strdup (get_persconffile_dir(fromname));
1528     char *to_dir = g_strdup (get_persconffile_dir(toname));
1529     int ret = 0;
1530
1531     ret = ws_rename (from_dir, to_dir);
1532     if (ret != 0) {
1533         *pf_from_dir_path_return = g_strdup (from_dir);
1534         *pf_to_dir_path_return = g_strdup (to_dir);
1535     }
1536
1537     g_free (from_dir);
1538     g_free (to_dir);
1539
1540     return ret;
1541 }
1542
1543 /*
1544  * Create the directory that holds personal configuration files, if
1545  * necessary.  If we attempted to create it, and failed, return -1 and
1546  * set "*pf_dir_path_return" to the pathname of the directory we failed
1547  * to create (it's g_mallocated, so our caller should free it); otherwise,
1548  * return 0.
1549  */
1550 int
1551 create_persconffile_profile(const char *profilename, char **pf_dir_path_return)
1552 {
1553     const char *pf_dir_path;
1554 #ifdef _WIN32
1555     char *pf_dir_path_copy, *pf_dir_parent_path;
1556     size_t pf_dir_parent_path_len;
1557 #endif
1558     ws_statb64 s_buf;
1559     int ret;
1560
1561     if (profilename) {
1562         /*
1563          * Create the "Default" personal configuration files directory, if necessary.
1564          */
1565         if (create_persconffile_profile (NULL, pf_dir_path_return) == -1) {
1566             return -1;
1567         }
1568
1569         /*
1570          * Check if profiles directory exists.
1571          * If not then create it.
1572          */
1573         pf_dir_path = get_profiles_dir ();
1574         if (ws_stat64(pf_dir_path, &s_buf) != 0 && errno == ENOENT) {
1575             ret = ws_mkdir(pf_dir_path, 0755);
1576             if (ret == -1) {
1577                 *pf_dir_path_return = g_strdup(pf_dir_path);
1578                 return ret;
1579             }
1580         }
1581     }
1582
1583     pf_dir_path = get_persconffile_dir(profilename);
1584     if (ws_stat64(pf_dir_path, &s_buf) != 0 && errno == ENOENT) {
1585 #ifdef _WIN32
1586         /*
1587          * Does the parent directory of that directory
1588          * exist?  %APPDATA% may not exist even though
1589          * %USERPROFILE% does.
1590          *
1591          * We check for the existence of the directory
1592          * by first checking whether the parent directory
1593          * is just a drive letter and, if it's not, by
1594          * doing a "stat()" on it.  If it's a drive letter,
1595          * or if the "stat()" succeeds, we assume it exists.
1596          */
1597         pf_dir_path_copy = g_strdup(pf_dir_path);
1598         pf_dir_parent_path = get_dirname(pf_dir_path_copy);
1599         pf_dir_parent_path_len = strlen(pf_dir_parent_path);
1600         if (pf_dir_parent_path_len > 0
1601             && pf_dir_parent_path[pf_dir_parent_path_len - 1] != ':'
1602             && ws_stat64(pf_dir_parent_path, &s_buf) != 0) {
1603             /*
1604              * No, it doesn't exist - make it first.
1605              */
1606             ret = ws_mkdir(pf_dir_parent_path, 0755);
1607             if (ret == -1) {
1608                 *pf_dir_path_return = pf_dir_parent_path;
1609                 return -1;
1610             }
1611         }
1612         g_free(pf_dir_path_copy);
1613         ret = ws_mkdir(pf_dir_path, 0755);
1614 #else
1615         ret = ws_mkdir(pf_dir_path, 0755);
1616 #endif
1617     } else {
1618         /*
1619          * Something with that pathname exists; if it's not
1620          * a directory, we'll get an error if we try to put
1621          * something in it, so we don't fail here, we wait
1622          * for that attempt fo fail.
1623          */
1624         ret = 0;
1625     }
1626     if (ret == -1)
1627         *pf_dir_path_return = g_strdup(pf_dir_path);
1628     return ret;
1629 }
1630
1631 int
1632 create_persconffile_dir(char **pf_dir_path_return)
1633 {
1634   return create_persconffile_profile(persconfprofile, pf_dir_path_return);
1635 }
1636
1637 int
1638 copy_persconffile_profile(const char *toname, const char *fromname, gboolean from_global,
1639               char **pf_filename_return, char **pf_to_dir_path_return, char **pf_from_dir_path_return)
1640 {
1641     gchar *from_dir;
1642     gchar *to_dir = g_strdup (get_persconffile_dir(toname));
1643     gchar *filename, *from_file, *to_file;
1644     GList *files, *file;
1645
1646     if (from_global) {
1647         if (strcmp(fromname, DEFAULT_PROFILE) == 0) {
1648             from_dir = g_strdup (get_global_profiles_dir());
1649         } else {
1650             from_dir = g_strdup_printf ("%s%s%s", get_global_profiles_dir(), G_DIR_SEPARATOR_S, fromname);
1651         }
1652     } else {
1653         from_dir = g_strdup (get_persconffile_dir(fromname));
1654     }
1655
1656     files = g_hash_table_get_keys(profile_files);
1657     file = g_list_first(files);
1658     while (file) {
1659         filename = (gchar *)file->data;
1660         from_file = g_strdup_printf ("%s%s%s", from_dir, G_DIR_SEPARATOR_S, filename);
1661         to_file =  g_strdup_printf ("%s%s%s", to_dir, G_DIR_SEPARATOR_S, filename);
1662
1663         if (file_exists(from_file) && !copy_file_binary_mode(from_file, to_file)) {
1664             *pf_filename_return = g_strdup(filename);
1665             *pf_to_dir_path_return = to_dir;
1666             *pf_from_dir_path_return = from_dir;
1667             g_free (from_file);
1668             g_free (to_file);
1669             return -1;
1670         }
1671
1672         g_free (from_file);
1673         g_free (to_file);
1674
1675         file = g_list_next(file);
1676     }
1677
1678     g_list_free (files);
1679     g_free (from_dir);
1680     g_free (to_dir);
1681
1682     return 0;
1683 }
1684
1685 /*
1686  * Get the (default) directory in which personal data is stored.
1687  *
1688  * On Win32, this is the "My Documents" folder in the personal profile,
1689  * except that, if we're running from a U3 device, this is the
1690  * "$U3_DEVICE_DOCUMENT_PATH\My Captures" folder.
1691  * On UNIX this is simply the current directory.
1692  */
1693 /* XXX - should this and the get_home_dir() be merged? */
1694 extern const char *
1695 get_persdatafile_dir(void)
1696 {
1697 #ifdef _WIN32
1698     char *u3devicedocumentpath;
1699     TCHAR tszPath[MAX_PATH];
1700     char *szPath;
1701     BOOL bRet;
1702
1703     /* Return the cached value, if available */
1704     if (persdatafile_dir != NULL)
1705         return persdatafile_dir;
1706
1707     /*
1708      * See if we are running in a U3 environment.
1709      */
1710     u3devicedocumentpath = getenv_utf8("U3_DEVICE_DOCUMENT_PATH");
1711
1712     if (u3devicedocumentpath != NULL) {
1713         /* the "My Captures" sub-directory is created (if it doesn't
1714            exist) by u3util.exe when the U3 Wireshark is first run */
1715
1716         szPath = g_strdup_printf("%s%s", u3devicedocumentpath, U3_MY_CAPTURES);
1717
1718         persdatafile_dir = szPath;
1719         return szPath;
1720     } else {
1721         /*
1722          * Hint: SHGetFolderPath is not available on MSVC 6 - without
1723          * Platform SDK
1724          */
1725         bRet = SHGetSpecialFolderPath(NULL, tszPath, CSIDL_PERSONAL,
1726             FALSE);
1727         if(bRet == TRUE) {
1728             szPath = utf_16to8(tszPath);
1729             persdatafile_dir = szPath;
1730             return szPath;
1731         } else {
1732             return "";
1733         }
1734     }
1735 #else
1736     return "";
1737 #endif
1738 }
1739
1740 #ifdef _WIN32
1741 /*
1742  * Returns the user's home directory on Win32.
1743  */
1744 static const char *
1745 get_home_dir(void)
1746 {
1747     static const char *home = NULL;
1748     char *homedrive, *homepath;
1749     char *homestring;
1750     char *lastsep;
1751
1752     /* Return the cached value, if available */
1753     if (home)
1754         return home;
1755
1756     /*
1757      * XXX - should we use USERPROFILE anywhere in this process?
1758      * Is there a chance that it might be set but one or more of
1759      * HOMEDRIVE or HOMEPATH isn't set?
1760      */
1761     homedrive = getenv_utf8("HOMEDRIVE");
1762     if (homedrive != NULL) {
1763         homepath = getenv_utf8("HOMEPATH");
1764         if (homepath != NULL) {
1765             /*
1766              * This is cached, so we don't need to worry about
1767              * allocating multiple ones of them.
1768              */
1769             homestring = g_strdup_printf("%s%s", homedrive, homepath);
1770
1771             /*
1772              * Trim off any trailing slash or backslash.
1773              */
1774             lastsep = find_last_pathname_separator(homestring);
1775             if (lastsep != NULL && *(lastsep + 1) == '\0') {
1776                 /*
1777                  * Last separator is the last character
1778                  * in the string.  Nuke it.
1779                  */
1780                 *lastsep = '\0';
1781             }
1782             home = homestring;
1783         } else
1784             home = homedrive;
1785     } else {
1786         /*
1787          * Give up and use C:.
1788          */
1789         home = "C:";
1790     }
1791
1792     return home;
1793 }
1794 #endif
1795
1796 /*
1797  * Construct the path name of a personal configuration file, given the
1798  * file name.
1799  *
1800  * On Win32, if "for_writing" is FALSE, we check whether the file exists
1801  * and, if not, construct a path name relative to the ".wireshark"
1802  * subdirectory of the user's home directory, and check whether that
1803  * exists; if it does, we return that, so that configuration files
1804  * from earlier versions can be read.
1805  *
1806  * The returned file name was g_malloc()'d so it must be g_free()d when the
1807  * caller is done with it.
1808  */
1809 char *
1810 get_persconffile_path(const char *filename, gboolean from_profile)
1811 {
1812     char *path;
1813     if (do_store_persconffiles && from_profile && !g_hash_table_lookup (profile_files, filename)) {
1814         /* Store filenames so we know which filenames belongs to a configuration profile */
1815         g_hash_table_insert (profile_files, g_strdup(filename), g_strdup(filename));
1816     }
1817
1818     if (from_profile) {
1819       path = g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s",
1820                  get_persconffile_dir(persconfprofile), filename);
1821     } else {
1822       path = g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s",
1823                  get_persconffile_dir(NULL), filename);
1824     }
1825
1826     return path;
1827 }
1828
1829 /*
1830  * process command line option belonging to the filesystem settings
1831  * (move this e.g. to main.c and have set_persconffile_dir() instead in this file?)
1832  */
1833 int
1834 filesystem_opt(int opt _U_, const char *optstr)
1835 {
1836     gchar *p, *colonp;
1837
1838     colonp = strchr(optstr, ':');
1839     if (colonp == NULL) {
1840         return 1;
1841     }
1842
1843     p = colonp;
1844     *p++ = '\0';
1845
1846     /*
1847     * Skip over any white space (there probably won't be any, but
1848     * as we allow it in the preferences file, we might as well
1849     * allow it here).
1850     */
1851     while (isspace((guchar)*p))
1852         p++;
1853     if (*p == '\0') {
1854         /*
1855          * Put the colon back, so if our caller uses, in an
1856          * error message, the string they passed us, the message
1857          * looks correct.
1858          */
1859         *colonp = ':';
1860         return 1;
1861     }
1862
1863     /* directory should be existing */
1864     /* XXX - is this a requirement? */
1865     if(test_for_directory(p) != EISDIR) {
1866         /*
1867          * Put the colon back, so if our caller uses, in an
1868          * error message, the string they passed us, the message
1869          * looks correct.
1870          */
1871         *colonp = ':';
1872         return 1;
1873     }
1874
1875     if (strcmp(optstr,"persconf") == 0) {
1876         persconffile_dir = p;
1877     } else if (strcmp(optstr,"persdata") == 0) {
1878         persdatafile_dir = p;
1879         /* XXX - might need to add the temp file path */
1880     } else {
1881         return 1;
1882     }
1883     *colonp = ':'; /* put the colon back */
1884     return 0;
1885 }
1886
1887 /*
1888  * Construct the path name of a global configuration file, given the
1889  * file name.
1890  *
1891  * The returned file name was g_malloc()'d so it must be g_free()d when the
1892  * caller is done with it.
1893  */
1894 char *
1895 get_datafile_path(const char *filename)
1896 {
1897
1898     return g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s", get_datafile_dir(), filename);
1899 }
1900
1901 /* Get the personal plugin dir */
1902 /* Return value is malloced so the caller should g_free() it. */
1903 char *
1904 get_plugins_pers_dir(void)
1905 {
1906     return get_persconffile_path(PLUGINS_DIR_NAME, FALSE);
1907 }
1908
1909 /* Delete a file */
1910 gboolean
1911 deletefile(const char *path)
1912 {
1913     return ws_unlink(path) == 0;
1914 }
1915
1916 /*
1917  * Construct and return the path name of a file in the
1918  * appropriate temporary file directory.
1919  */
1920 char *get_tempfile_path(const char *filename)
1921 {
1922     return g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s", g_get_tmp_dir(), filename);
1923 }
1924
1925 /*
1926  * Return an error message for UNIX-style errno indications on open or
1927  * create operations.
1928  */
1929 const char *
1930 file_open_error_message(int err, gboolean for_writing)
1931 {
1932     const char *errmsg;
1933     static char errmsg_errno[1024+1];
1934
1935     switch (err) {
1936
1937     case ENOENT:
1938         if (for_writing)
1939             errmsg = "The path to the file \"%s\" doesn't exist.";
1940         else
1941             errmsg = "The file \"%s\" doesn't exist.";
1942         break;
1943
1944     case EACCES:
1945         if (for_writing)
1946             errmsg = "You don't have permission to create or write to the file \"%s\".";
1947         else
1948             errmsg = "You don't have permission to read the file \"%s\".";
1949         break;
1950
1951     case EISDIR:
1952         errmsg = "\"%s\" is a directory (folder), not a file.";
1953         break;
1954
1955     case ENOSPC:
1956         errmsg = "The file \"%s\" could not be created because there is no space left on the file system.";
1957         break;
1958
1959 #ifdef EDQUOT
1960     case EDQUOT:
1961         errmsg = "The file \"%s\" could not be created because you are too close to, or over, your disk quota.";
1962         break;
1963 #endif
1964
1965     case EINVAL:
1966         errmsg = "The file \"%s\" could not be created because an invalid filename was specified.";
1967         break;
1968
1969     case ENOMEM:
1970         /*
1971          * The problem probably has nothing to do with how much RAM the
1972          * user has on their machine, so don't confuse them by saying
1973          * "memory".  The problem is probably either virtual address
1974          * space or swap space.
1975          */
1976 #if GLIB_SIZEOF_VOID_P == 4
1977         /*
1978          * ILP32; we probably ran out of virtual address space.
1979          */
1980 #define ENOMEM_REASON "it can't be handled by a 32-bit application"
1981 #else
1982         /*
1983          * LP64 or LLP64; we probably ran out of swap space.
1984          */
1985 #if defined(_WIN32)
1986         /*
1987          * You need to make the pagefile bigger.
1988          */
1989 #define ENOMEM_REASON "the pagefile is too small"
1990 #elif defined(__APPLE__)
1991         /*
1992          * dynamic_pager couldn't, or wouldn't, create more swap files.
1993          */
1994 #define ENOMEM_REASON "your system ran out of swap file space"
1995 #else
1996         /*
1997          * Either you have a fixed swap partition or a fixed swap file,
1998          * and it needs to be made bigger.
1999          *
2000          * This is UN*X, but it's not OS X, so we assume the user is
2001          * *somewhat* nerdy.
2002          */
2003 #define ENOMEM_REASON "your system is out of swap space"
2004 #endif
2005 #endif /* GLIB_SIZEOF_VOID_P == 4 */
2006         if (for_writing)
2007             errmsg = "The file \"%s\" could not be created because " ENOMEM_REASON ".";
2008         else
2009             errmsg = "The file \"%s\" could not be opened because " ENOMEM_REASON ".";
2010         break;
2011
2012     default:
2013         g_snprintf(errmsg_errno, sizeof(errmsg_errno),
2014                "The file \"%%s\" could not be %s: %s.",
2015                for_writing ? "created" : "opened",
2016                g_strerror(err));
2017         errmsg = errmsg_errno;
2018         break;
2019     }
2020     return errmsg;
2021 }
2022
2023 /*
2024  * Return an error message for UNIX-style errno indications on write
2025  * operations.
2026  */
2027 const char *
2028 file_write_error_message(int err)
2029 {
2030     const char *errmsg;
2031     static char errmsg_errno[1024+1];
2032
2033     switch (err) {
2034
2035     case ENOSPC:
2036         errmsg = "The file \"%s\" could not be saved because there is no space left on the file system.";
2037         break;
2038
2039 #ifdef EDQUOT
2040     case EDQUOT:
2041         errmsg = "The file \"%s\" could not be saved because you are too close to, or over, your disk quota.";
2042         break;
2043 #endif
2044
2045     default:
2046         g_snprintf(errmsg_errno, sizeof(errmsg_errno),
2047                "An error occurred while writing to the file \"%%s\": %s.",
2048                g_strerror(err));
2049         errmsg = errmsg_errno;
2050         break;
2051     }
2052     return errmsg;
2053 }
2054
2055
2056 gboolean
2057 file_exists(const char *fname)
2058 {
2059     ws_statb64 file_stat;
2060
2061     if (!fname) {
2062         return FALSE;
2063     }
2064
2065 #ifdef _WIN32
2066     /*
2067      * This is a bit tricky on win32. The st_ino field is documented as:
2068      * "The inode, and therefore st_ino, has no meaning in the FAT, ..."
2069      * but it *is* set to zero if stat() returns without an error,
2070      * so this is working, but maybe not quite the way expected. ULFL
2071      */
2072     file_stat.st_ino = 1;   /* this will make things work if an error occurred */
2073     ws_stat64(fname, &file_stat);
2074     if (file_stat.st_ino == 0) {
2075         return TRUE;
2076     } else {
2077         return FALSE;
2078     }
2079 #else
2080     if (ws_stat64(fname, &file_stat) != 0 && errno == ENOENT) {
2081         return FALSE;
2082     } else {
2083         return TRUE;
2084     }
2085 #endif
2086 }
2087
2088 /*
2089  * Check that the from file is not the same as to file
2090  * We do it here so we catch all cases ...
2091  * Unfortunately, the file requester gives us an absolute file
2092  * name and the read file name may be relative (if supplied on
2093  * the command line), so we can't just compare paths. From Joerg Mayer.
2094  */
2095 gboolean
2096 files_identical(const char *fname1, const char *fname2)
2097 {
2098     /* Two different implementations, because:
2099      *
2100      * - _fullpath is not available on UN*X, so we can't get full
2101      *   paths and compare them (which wouldn't work with hard links
2102      *   in any case);
2103      *
2104      * - st_ino isn't filled in with a meaningful value on Windows.
2105      */
2106 #ifdef _WIN32
2107     char full1[MAX_PATH], full2[MAX_PATH];
2108
2109     /*
2110      * Get the absolute full paths of the file and compare them.
2111      * That won't work if you have hard links, but those aren't
2112      * much used on Windows, even though NTFS supports them.
2113      *
2114      * XXX - will _fullpath work with UNC?
2115      */
2116     if( _fullpath( full1, fname1, MAX_PATH ) == NULL ) {
2117         return FALSE;
2118     }
2119
2120     if( _fullpath( full2, fname2, MAX_PATH ) == NULL ) {
2121         return FALSE;
2122     }
2123
2124     if(strcmp(full1, full2) == 0) {
2125         return TRUE;
2126     } else {
2127         return FALSE;
2128     }
2129 #else
2130     ws_statb64 filestat1, filestat2;
2131
2132     /*
2133      * Compare st_dev and st_ino.
2134      */
2135     if (ws_stat64(fname1, &filestat1) == -1)
2136         return FALSE;   /* can't get info about the first file */
2137     if (ws_stat64(fname2, &filestat2) == -1)
2138         return FALSE;   /* can't get info about the second file */
2139     return (filestat1.st_dev == filestat2.st_dev &&
2140         filestat1.st_ino == filestat2.st_ino);
2141 #endif
2142 }
2143
2144 /*
2145  * Copy a file in binary mode, for those operating systems that care about
2146  * such things.  This should be OK for all files, even text files, as
2147  * we'll copy the raw bytes, and we don't look at the bytes as we copy
2148  * them.
2149  *
2150  * Returns TRUE on success, FALSE on failure. If a failure, it also
2151  * displays a simple dialog window with the error message.
2152  */
2153 gboolean
2154 copy_file_binary_mode(const char *from_filename, const char *to_filename)
2155 {
2156     int           from_fd, to_fd, err;
2157     ssize_t       nread, nwritten;
2158     guint8        *pd = NULL;
2159
2160     /* Copy the raw bytes of the file. */
2161     from_fd = ws_open(from_filename, O_RDONLY | O_BINARY, 0000 /* no creation so don't matter */);
2162     if (from_fd < 0) {
2163         report_open_failure(from_filename, errno, FALSE);
2164         goto done;
2165     }
2166
2167     /* Use open() instead of creat() so that we can pass the O_BINARY
2168        flag, which is relevant on Win32; it appears that "creat()"
2169        may open the file in text mode, not binary mode, but we want
2170        to copy the raw bytes of the file, so we need the output file
2171        to be open in binary mode. */
2172     to_fd = ws_open(to_filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644);
2173     if (to_fd < 0) {
2174         report_open_failure(to_filename, errno, TRUE);
2175         ws_close(from_fd);
2176         goto done;
2177     }
2178
2179 #define FS_READ_SIZE 65536
2180     pd = (guint8 *)g_malloc(FS_READ_SIZE);
2181     while ((nread = ws_read(from_fd, pd, FS_READ_SIZE)) > 0) {
2182         nwritten = ws_write(to_fd, pd, nread);
2183         if (nwritten < nread) {
2184             if (nwritten < 0)
2185                 err = errno;
2186             else
2187                 err = WTAP_ERR_SHORT_WRITE;
2188             report_write_failure(to_filename, err);
2189             ws_close(from_fd);
2190             ws_close(to_fd);
2191             goto done;
2192         }
2193     }
2194     if (nread < 0) {
2195         err = errno;
2196         report_read_failure(from_filename, err);
2197         ws_close(from_fd);
2198         ws_close(to_fd);
2199         goto done;
2200     }
2201     ws_close(from_fd);
2202     if (ws_close(to_fd) < 0) {
2203         report_write_failure(to_filename, errno);
2204         goto done;
2205     }
2206
2207     g_free(pd);
2208     pd = NULL;
2209     return TRUE;
2210
2211 done:
2212     g_free(pd);
2213     return FALSE;
2214 }
2215
2216 /*
2217  * Editor modelines
2218  *
2219  * Local Variables:
2220  * c-basic-offset: 4
2221  * tab-width: 8
2222  * indent-tabs-mode: nil
2223  * End:
2224  *
2225  * ex: set shiftwidth=4 tabstop=8 expandtab:
2226  * :indentSize=4:tabSize=8:noTabs=true:
2227  */