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