Win32: Restore the versioned plugin installation path.
[metze/wireshark/wip.git] / wsutil / filesystem.c
index fa292da4ce664add96df5e7beed129ad2fc97603..0b23aec1ee07df45719c89afd49955af50b79302 100644 (file)
@@ -1,8 +1,6 @@
 /* filesystem.c
  * Filesystem utility routines
  *
- * $Id$
- *
  * Wireshark - Network traffic analyzer
  * By Gerald Combs <gerald@wireshark.org>
  * Copyright 1998 Gerald Combs
  */
 #define _GNU_SOURCE
 
-#ifdef HAVE_DIRENT_H
-#include <dirent.h>
-#endif
-
 #include <stdio.h>
-#include <ctype.h>
 #include <stdlib.h>
 #include <string.h>
 #include <errno.h>
@@ -363,7 +356,7 @@ static gboolean running_in_build_directory_flag = FALSE;
  * use realpath() if they want the real thing, but that's also true of
  * something obtained by looking at argv[0].
  */
-const char *
+static const char *
 get_executable_path(void)
 {
 #if defined(__APPLE__)
@@ -486,7 +479,7 @@ init_progfile_dir(const char *arg0
 #ifdef _WIN32
     _U_
 #endif
-, int (*main_addr)(int, char **)
+, void *function_addr
 #if defined(_WIN32) || !defined(HAVE_DLADDR)
     _U_
 #endif
@@ -562,7 +555,7 @@ init_progfile_dir(const char *arg0
     long path_max;
     char *pathstr;
     char *path_start, *path_end;
-    size_t path_component_len;
+    size_t path_component_len, path_len;
     char *retstr;
     char *path;
     char *dir_end;
@@ -582,7 +575,7 @@ init_progfile_dir(const char *arg0
 
     execname = get_executable_path();
 #ifdef HAVE_DLADDR
-    if (main_addr != NULL && execname == NULL) {
+    if (function_addr != NULL && execname == NULL) {
         /*
          * Try to use dladdr() to find the pathname of the executable.
          * dladdr() is not guaranteed to give you anything better than
@@ -592,7 +585,7 @@ init_progfile_dir(const char *arg0
          * path and obviate the need for us to determine the absolute
          * path.
          */
-        if (dladdr((void *)main_addr, &info))
+        if (dladdr(function_addr, &info))
             execname = info.dli_fname;
     }
 #endif
@@ -661,12 +654,13 @@ init_progfile_dir(const char *arg0
                 if (path_end == NULL)
                     path_end = path_start + strlen(path_start);
                 path_component_len = path_end - path_start;
-                path = (char *)g_malloc(path_component_len + 1
-                    + strlen(execname) + 1);
+                path_len = path_component_len + 1
+                    + strlen(execname) + 1;
+                path = (char *)g_malloc(path_len);
                 memcpy(path, path_start, path_component_len);
                 path[path_component_len] = '\0';
-                strncat(path, "/", 2);
-                strncat(path, execname, strlen(execname) + 1);
+                g_strlcat(path, "/", path_len);
+                g_strlcat(path, execname, path_len);
                 if (access(path, X_OK) == 0) {
                     /*
                      * Found it!
@@ -952,15 +946,15 @@ get_datafile_dir(void)
     return datafile_dir;
 }
 
-#ifdef HAVE_PYTHON
+#if defined(HAVE_PLUGINS) || defined(HAVE_LUA)
 /*
- * Find the directory where the python dissectors are stored.
+ * Find the directory where the plugins are stored.
  *
- * On Windows, we use the "py_dissector" subdirectory of the datafile directory.
+ * On Windows, we use the "plugin" subdirectory of the datafile directory.
  *
- * On UN*X, we use the PYTHON_DIR value supplied by the configure
+ * On UN*X, we use the PLUGIN_INSTALL_DIR value supplied by the configure
  * script, unless we think we're being run from the build directory,
- * in which case we use the "py_dissector" subdirectory of the datafile directory.
+ * in which case we use the "plugin" subdirectory of the datafile directory.
  *
  * In both cases, we then use the subdirectory of that directory whose
  * name is the version number.
@@ -971,42 +965,42 @@ get_datafile_dir(void)
  * of the plugin directory, so it can just fetch the plugins built
  * as part of the build process.
  */
-static const char *wspython_dir = NULL;
+static const char *plugin_dir = NULL;
 
 static void
-init_wspython_dir(void)
+init_plugin_dir(void)
 {
 #ifdef _WIN32
     /*
      * On Windows, the data file directory is the installation
-     * directory; the python dissectors are stored under it.
+     * directory; the plugins are stored under it.
      *
      * Assume we're running the installed version of Wireshark;
      * on Windows, the data file directory is the directory
      * in which the Wireshark binary resides.
      */
-        wspython_dir = g_strdup_printf("%s\\python\\%s", get_datafile_dir(),
-                                        VERSION);
+    plugin_dir = g_strdup_printf("%s\\plugins\\%s", get_datafile_dir(),
+                     VERSION);
 
     /*
      * Make sure that pathname refers to a directory.
      */
-    if (test_for_directory(wspython_dir) != EISDIR) {
+    if (test_for_directory(plugin_dir) != EISDIR) {
         /*
          * Either it doesn't refer to a directory or it
          * refers to something that doesn't exist.
          *
          * Assume that means we're running a version of
          * Wireshark we've built in a build directory,
-         * in which case {datafile dir}\python is the
+         * in which case {datafile dir}\plugins is the
          * top-level plugins source directory, and use
          * that directory and set the "we're running in
          * a build directory" flag, so the plugin
          * scanner will check all subdirectories of that
-         * directory for python dissectors.
+         * directory for plugins.
          */
-        g_free( (gpointer) wspython_dir);
-        wspython_dir = g_strdup_printf("%s\\python", get_datafile_dir());
+        g_free( (gpointer) plugin_dir);
+        plugin_dir = g_strdup_printf("%s\\plugins", get_datafile_dir());
         running_in_build_directory_flag = TRUE;
     }
 #else
@@ -1014,22 +1008,22 @@ init_wspython_dir(void)
         /*
          * We're (probably) being run from the build directory and
          * weren't started with special privileges, so we'll use
-         * the "python" subdirectory of the datafile directory
-         * (the datafile directory is the build directory).
+         * the "plugins" subdirectory of the directory where the program
+         * we're running is (that's the build directory).
          */
-        wspython_dir = g_strdup_printf("%s/epan/wspython/", get_datafile_dir());
+        plugin_dir = g_strdup_printf("%s/plugins", get_progfile_dir());
     } else {
-        if (getenv("WIRESHARK_PYTHON_DIR") && !started_with_special_privs()) {
+        if (getenv("WIRESHARK_PLUGIN_DIR") && !started_with_special_privs()) {
             /*
              * The user specified a different directory for plugins
              * and we aren't running with special privileges.
              */
-            wspython_dir = g_strdup(getenv("WIRESHARK_PYTHON_DIR"));
+            plugin_dir = g_strdup(getenv("WIRESHARK_PLUGIN_DIR"));
         }
 #ifdef __APPLE__
         /*
          * If we're running from an app bundle and weren't started
-         * with special privileges, use the Contents/Resources/lib/wireshark/python
+         * with special privileges, use the Contents/PlugIns/wireshark
          * subdirectory of the app bundle.
          *
          * (appbundle_dir is not set to a non-null value if we're
@@ -1037,111 +1031,95 @@ init_wspython_dir(void)
          * it; we don't need to call started_with_special_privs().)
          */
         else if (appbundle_dir != NULL) {
-            wspython_dir = g_strdup_printf("%s/Contents/Resources/lib/wireshark/python",
-                                           appbundle_dir);
+            plugin_dir = g_strdup_printf("%s/Contents/PlugIns/wireshark",
+                                         appbundle_dir);
         }
 #endif
         else {
-            wspython_dir = PYTHON_DIR;
+            plugin_dir = PLUGIN_INSTALL_DIR;
         }
     }
 #endif
 }
-#endif /* HAVE_PYTHON */
+#endif /* HAVE_PLUGINS || HAVE_LUA */
 
 /*
- * Get the directory in which the python dissectors are stored.
+ * Get the directory in which the plugins are stored.
  */
 const char *
-get_wspython_dir(void)
+get_plugin_dir(void)
 {
-#ifdef HAVE_PYTHON
-    if (!wspython_dir) init_wspython_dir();
-    return wspython_dir;
+#if defined(HAVE_PLUGINS) || defined(HAVE_LUA)
+    if (!plugin_dir) init_plugin_dir();
+    return plugin_dir;
 #else
     return NULL;
 #endif
 }
 
-
-#if defined(HAVE_PLUGINS) || defined(HAVE_LUA)
+#if defined(HAVE_EXTCAP)
 /*
- * Find the directory where the plugins are stored.
+ * Find the directory where the extcap hooks are stored.
  *
- * On Windows, we use the "plugin" subdirectory of the datafile directory.
+ * On Windows, we use the "extcap" subdirectory of the datafile directory.
  *
- * On UN*X, we use the PLUGIN_DIR value supplied by the configure
+ * On UN*X, we use the EXTCAP_DIR value supplied by the configure
  * script, unless we think we're being run from the build directory,
- * in which case we use the "plugin" subdirectory of the datafile directory.
+ * in which case we use the "extcap" subdirectory of the datafile directory.
  *
  * In both cases, we then use the subdirectory of that directory whose
  * name is the version number.
  *
  * XXX - if we think we're being run from the build directory, perhaps we
- * should have the plugin code not look in the version subdirectory
- * of the plugin directory, but look in all of the subdirectories
- * of the plugin directory, so it can just fetch the plugins built
+ * should have the extcap code not look in the version subdirectory
+ * of the extcap directory, but look in all of the subdirectories
+ * of the extcap directory, so it can just fetch the extcap hooks built
  * as part of the build process.
  */
-static const char *plugin_dir = NULL;
+static const char *extcap_dir = NULL;
 
-static void
-init_plugin_dir(void)
-{
+static void init_extcap_dir(void) {
 #ifdef _WIN32
+    char *alt_extcap_path;
+
     /*
      * On Windows, the data file directory is the installation
-     * directory; the plugins are stored under it.
+     * directory; the extcap hooks are stored under it.
      *
      * Assume we're running the installed version of Wireshark;
      * on Windows, the data file directory is the directory
      * in which the Wireshark binary resides.
      */
-    plugin_dir = g_strdup_printf("%s\\plugins\\%s", get_datafile_dir(),
-                     VERSION);
-
-    /*
-     * Make sure that pathname refers to a directory.
-     */
-    if (test_for_directory(plugin_dir) != EISDIR) {
+    alt_extcap_path = getenv_utf8("WIRESHARK_EXTCAP_DIR");
+    if (alt_extcap_path) {
         /*
-         * Either it doesn't refer to a directory or it
-         * refers to something that doesn't exist.
-         *
-         * Assume that means we're running a version of
-         * Wireshark we've built in a build directory,
-         * in which case {datafile dir}\plugins is the
-         * top-level plugins source directory, and use
-         * that directory and set the "we're running in
-         * a build directory" flag, so the plugin
-         * scanner will check all subdirectories of that
-         * directory for plugins.
+         * The user specified a different directory for extcap hooks.
          */
-        g_free( (gpointer) plugin_dir);
-        plugin_dir = g_strdup_printf("%s\\plugins", get_datafile_dir());
-        running_in_build_directory_flag = TRUE;
+        extcap_dir = g_strdup(alt_extcap_path);
+    } else {
+        extcap_dir = g_strdup_printf("%s\\extcap", get_datafile_dir());
     }
 #else
     if (running_in_build_directory_flag) {
         /*
          * We're (probably) being run from the build directory and
          * weren't started with special privileges, so we'll use
-         * the "plugins" subdirectory of the directory where the program
+         * the "extcap hooks" subdirectory of the directory where the program
          * we're running is (that's the build directory).
          */
-        plugin_dir = g_strdup_printf("%s/plugins", get_progfile_dir());
+        extcap_dir = g_strdup_printf("%s/extcap", get_progfile_dir());
     } else {
-        if (getenv("WIRESHARK_PLUGIN_DIR") && !started_with_special_privs()) {
+        if (getenv("WIRESHARK_EXTCAP_DIR") && !started_with_special_privs()) {
             /*
-             * The user specified a different directory for plugins
+             * The user specified a different directory for extcap hooks
              * and we aren't running with special privileges.
              */
-            plugin_dir = g_strdup(getenv("WIRESHARK_PLUGIN_DIR"));
+            extcap_dir = g_strdup(getenv("WIRESHARK_EXTCAP_DIR"));
         }
 #ifdef __APPLE__
         /*
          * If we're running from an app bundle and weren't started
-         * with special privileges, use the Contents/Resources/lib/wireshark/plugins
+         * with special privileges, use the Contents/Resources/lib/wireshark/extcap
          * subdirectory of the app bundle.
          *
          * (appbundle_dir is not set to a non-null value if we're
@@ -1149,27 +1127,29 @@ init_plugin_dir(void)
          * it; we don't need to call started_with_special_privs().)
          */
         else if (appbundle_dir != NULL) {
-            plugin_dir = g_strdup_printf("%s/Contents/Resources/lib/wireshark/plugins",
+            extcap_dir = g_strdup_printf("%s/Contents/Resources/lib/wireshark/extcap",
                                          appbundle_dir);
         }
 #endif
         else {
-            plugin_dir = PLUGIN_DIR;
+            extcap_dir = EXTCAP_DIR;
         }
     }
 #endif
 }
-#endif /* HAVE_PLUGINS || HAVE_LUA */
+#endif /* HAVE_EXTCAP */
 
 /*
- * Get the directory in which the plugins are stored.
+ * Get the directory in which the extcap hooks are stored.
+ *
+ * XXX - A fix instead of HAVE_EXTCAP must be found
  */
 const char *
-get_plugin_dir(void)
-{
-#if defined(HAVE_PLUGINS) || defined(HAVE_LUA)
-    if (!plugin_dir) init_plugin_dir();
-    return plugin_dir;
+get_extcap_dir(void) {
+#if defined(HAVE_EXTCAP)
+    if (!extcap_dir)
+        init_extcap_dir();
+    return extcap_dir;
 #else
     return NULL;
 #endif
@@ -1382,6 +1362,13 @@ get_persconffile_dir_no_profile(void)
     return persconffile_dir;
 }
 
+void
+set_persconffile_dir(const char *p)
+{
+    g_free(persconffile_dir);
+    persconffile_dir = g_strdup(p);
+}
+
 const char *
 get_profiles_dir(void)
 {
@@ -1672,8 +1659,6 @@ get_persdatafile_dir(void)
 #ifdef _WIN32
     char *u3devicedocumentpath;
     TCHAR tszPath[MAX_PATH];
-    char *szPath;
-    BOOL bRet;
 
     /* Return the cached value, if available */
     if (persdatafile_dir != NULL)
@@ -1688,21 +1673,16 @@ get_persdatafile_dir(void)
         /* the "My Captures" sub-directory is created (if it doesn't
            exist) by u3util.exe when the U3 Wireshark is first run */
 
-        szPath = g_strdup_printf("%s%s", u3devicedocumentpath, U3_MY_CAPTURES);
-
-        persdatafile_dir = szPath;
-        return szPath;
+        persdatafile_dir = g_strdup_printf("%s%s", u3devicedocumentpath, U3_MY_CAPTURES);
+        return persdatafile_dir;
     } else {
         /*
          * Hint: SHGetFolderPath is not available on MSVC 6 - without
          * Platform SDK
          */
-        bRet = SHGetSpecialFolderPath(NULL, tszPath, CSIDL_PERSONAL,
-            FALSE);
-        if(bRet == TRUE) {
-            szPath = utf_16to8(tszPath);
-            persdatafile_dir = szPath;
-            return szPath;
+        if (SHGetSpecialFolderPath(NULL, tszPath, CSIDL_PERSONAL, FALSE)) {
+            persdatafile_dir = g_utf16_to_utf8(tszPath, -1, NULL, NULL, NULL);
+            return persdatafile_dir;
         } else {
             return "";
         }
@@ -1712,6 +1692,13 @@ get_persdatafile_dir(void)
 #endif
 }
 
+void
+set_persdatafile_dir(const char *p)
+{
+    g_free(persdatafile_dir);
+    persdatafile_dir = g_strdup(p);
+}
+
 #ifdef _WIN32
 /*
  * Returns the user's home directory on Win32.
@@ -1801,64 +1788,6 @@ get_persconffile_path(const char *filename, gboolean from_profile)
     return path;
 }
 
-/*
- * process command line option belonging to the filesystem settings
- * (move this e.g. to main.c and have set_persconffile_dir() instead in this file?)
- */
-int
-filesystem_opt(int opt _U_, const char *optstr)
-{
-    gchar *p, *colonp;
-
-    colonp = strchr(optstr, ':');
-    if (colonp == NULL) {
-        return 1;
-    }
-
-    p = colonp;
-    *p++ = '\0';
-
-    /*
-    * Skip over any white space (there probably won't be any, but
-    * as we allow it in the preferences file, we might as well
-    * allow it here).
-    */
-    while (isspace((guchar)*p))
-        p++;
-    if (*p == '\0') {
-        /*
-         * Put the colon back, so if our caller uses, in an
-         * error message, the string they passed us, the message
-         * looks correct.
-         */
-        *colonp = ':';
-        return 1;
-    }
-
-    /* directory should be existing */
-    /* XXX - is this a requirement? */
-    if(test_for_directory(p) != EISDIR) {
-        /*
-         * Put the colon back, so if our caller uses, in an
-         * error message, the string they passed us, the message
-         * looks correct.
-         */
-        *colonp = ':';
-        return 1;
-    }
-
-    if (strcmp(optstr,"persconf") == 0) {
-        persconffile_dir = p;
-    } else if (strcmp(optstr,"persdata") == 0) {
-        persdatafile_dir = p;
-        /* XXX - might need to add the temp file path */
-    } else {
-        return 1;
-    }
-    *colonp = ':'; /* put the colon back */
-    return 0;
-}
-
 /*
  * Construct the path name of a global configuration file, given the
  * file name.
@@ -1869,10 +1798,13 @@ filesystem_opt(int opt _U_, const char *optstr)
 char *
 get_datafile_path(const char *filename)
 {
-    if (running_in_build_directory_flag && !strcmp(filename, "AUTHORS-SHORT")) {
+    if (running_in_build_directory_flag &&
+        (!strcmp(filename, "AUTHORS-SHORT") ||
+         !strcmp(filename, "hosts"))) {
         /* We're running in the build directory and the requested file is a
-         * generated file.  Return the file name in the build directory (not
-         * in the source/data directory).
+         * generated (or a test) file.  Return the file name in the build
+         * directory (not in the source/data directory).
+         * (Oh the things we do to keep the source directory pristine...)
          */
         return g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s", get_progfile_dir(), filename);
     } else {
@@ -1888,22 +1820,6 @@ get_plugins_pers_dir(void)
     return get_persconffile_path(PLUGINS_DIR_NAME, FALSE);
 }
 
-/* Delete a file */
-gboolean
-deletefile(const char *path)
-{
-    return ws_unlink(path) == 0;
-}
-
-/*
- * Construct and return the path name of a file in the
- * appropriate temporary file directory.
- */
-char *get_tempfile_path(const char *filename)
-{
-    return g_strdup_printf("%s" G_DIR_SEPARATOR_S "%s", g_get_tmp_dir(), filename);
-}
-
 /*
  * Return an error message for UNIX-style errno indications on open or
  * create operations.