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