/* GStreamer
 * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
 *                    2000 Wim Taymans <wtay@chello.be>
 *
 * gstplugin.c: Plugin subsystem for loading elements, types, and libs
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

/**
 * SECTION:gstplugin
 * @short_description: Container for features loaded from a shared object module
 * @see_also: #GstPluginFeature, #GstElementFactory
 *
 * GStreamer is extensible, so #GstElement instances can be loaded at runtime.
 * A plugin system can provide one or more of the basic
 * <application>GStreamer</application> #GstPluginFeature subclasses.
 *
 * A plugin should export a symbol <symbol>gst_plugin_desc</symbol> that is a
 * struct of type #GstPluginDesc.
 * the plugin loader will check the version of the core library the plugin was
 * linked against and will create a new #GstPlugin. It will then call the
 * #GstPluginInitFunc function that was provided in the
 * <symbol>gst_plugin_desc</symbol>.
 *
 * Once you have a handle to a #GstPlugin (e.g. from the #GstRegistry), you
 * can add any object that subclasses #GstPluginFeature.
 *
 * Usually plugins are always automaticlly loaded so you don't need to call
 * gst_plugin_load() explicitly to bring it into memory. There are options to
 * statically link plugins to an app or even use GStreamer without a plugin
 * repository in which case gst_plugin_load() can be needed to bring the plugin
 * into memory.
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include "gst_private.h"

#include <glib/gstdio.h>
#include <sys/types.h>
#ifdef HAVE_DIRENT_H
#include <dirent.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <signal.h>
#include <errno.h>
#include <string.h>

#include "glib-compat-private.h"

#include <gst/gst.h>

#define GST_CAT_DEFAULT GST_CAT_PLUGIN_LOADING

static guint _num_static_plugins;       /* 0    */
static GstPluginDesc *_static_plugins;  /* NULL */
static gboolean _gst_plugin_inited;
static gchar **_plugin_loading_whitelist;       /* NULL */

/* static variables for segfault handling of plugin loading */
static char *_gst_plugin_fault_handler_filename = NULL;

/* list of valid licenses.
 * One of these must be specified or the plugin won't be loaded
 * Contact gstreamer-devel@lists.sourceforge.net if your license should be
 * added.
 *
 * GPL: http://www.gnu.org/copyleft/gpl.html
 * LGPL: http://www.gnu.org/copyleft/lesser.html
 * QPL: http://www.trolltech.com/licenses/qpl.html
 * MPL: http://www.opensource.org/licenses/mozilla1.1.php
 * MIT/X11: http://www.opensource.org/licenses/mit-license.php
 * 3-clause BSD: http://www.opensource.org/licenses/bsd-license.php
 */
static const gchar valid_licenses[] = "LGPL\000"        /* GNU Lesser General Public License */
    "GPL\000"                   /* GNU General Public License */
    "QPL\000"                   /* Trolltech Qt Public License */
    "GPL/QPL\000"               /* Combi-license of GPL + QPL */
    "MPL\000"                   /* MPL 1.1 license */
    "BSD\000"                   /* 3-clause BSD license */
    "MIT/X11\000"               /* MIT/X11 license */
    "Proprietary\000"           /* Proprietary license */
    GST_LICENSE_UNKNOWN;        /* some other license */

static const guint8 valid_licenses_idx[] = { 0, 5, 9, 13, 21, 25, 29, 37, 49 };

static GstPlugin *gst_plugin_register_func (GstPlugin * plugin,
    const GstPluginDesc * desc, gpointer user_data);
static void gst_plugin_desc_copy (GstPluginDesc * dest,
    const GstPluginDesc * src);

static void gst_plugin_ext_dep_free (GstPluginDep * dep);

G_DEFINE_TYPE (GstPlugin, gst_plugin, GST_TYPE_OBJECT);

static void
gst_plugin_init (GstPlugin * plugin)
{
  plugin->priv =
      G_TYPE_INSTANCE_GET_PRIVATE (plugin, GST_TYPE_PLUGIN, GstPluginPrivate);
}

static void
gst_plugin_finalize (GObject * object)
{
  GstPlugin *plugin = GST_PLUGIN_CAST (object);

  GST_DEBUG ("finalizing plugin %" GST_PTR_FORMAT, plugin);

  /* FIXME: make registry add a weak ref instead */
#if 0
  GstRegistry *registry = gst_registry_get ();
  GList *g;
  for (g = registry->plugins; g; g = g->next) {
    if (g->data == (gpointer) plugin) {
      g_warning ("removing plugin that is still in registry");
    }
  }
#endif

  g_free (plugin->filename);
  g_free (plugin->basename);

  g_list_foreach (plugin->priv->deps, (GFunc) gst_plugin_ext_dep_free, NULL);
  g_list_free (plugin->priv->deps);
  plugin->priv->deps = NULL;

  if (plugin->priv->cache_data) {
    gst_structure_free (plugin->priv->cache_data);
  }

  G_OBJECT_CLASS (gst_plugin_parent_class)->finalize (object);
}

static void
gst_plugin_class_init (GstPluginClass * klass)
{
  G_OBJECT_CLASS (klass)->finalize = gst_plugin_finalize;

  g_type_class_add_private (klass, sizeof (GstPluginPrivate));
}

GQuark
gst_plugin_error_quark (void)
{
  static GQuark quark = 0;

  if (!quark)
    quark = g_quark_from_static_string ("gst_plugin_error");
  return quark;
}

/**
 * gst_plugin_register_static:
 * @major_version: the major version number of the GStreamer core that the
 *     plugin was compiled for, you can just use GST_VERSION_MAJOR here
 * @minor_version: the minor version number of the GStreamer core that the
 *     plugin was compiled for, you can just use GST_VERSION_MINOR here
 * @name: a unique name of the plugin (ideally prefixed with an application- or
 *     library-specific namespace prefix in order to avoid name conflicts in
 *     case a similar plugin with the same name ever gets added to GStreamer)
 * @description: description of the plugin
 * @init_func: (scope call): pointer to the init function of this plugin.
 * @version: version string of the plugin
 * @license: effective license of plugin. Must be one of the approved licenses
 *     (see #GstPluginDesc above) or the plugin will not be registered.
 * @source: source module plugin belongs to
 * @package: shipped package plugin belongs to
 * @origin: URL to provider of plugin
 *
 * Registers a static plugin, ie. a plugin which is private to an application
 * or library and contained within the application or library (as opposed to
 * being shipped as a separate module file).
 *
 * You must make sure that GStreamer has been initialised (with gst_init() or
 * via gst_init_get_option_group()) before calling this function.
 *
 * Returns: TRUE if the plugin was registered correctly, otherwise FALSE.
 *
 * Since: 0.10.16
 */
gboolean
gst_plugin_register_static (gint major_version, gint minor_version,
    const gchar * name, const gchar * description, GstPluginInitFunc init_func,
    const gchar * version, const gchar * license, const gchar * source,
    const gchar * package, const gchar * origin)
{
  GstPluginDesc desc = { major_version, minor_version, name, description,
    init_func, version, license, source, package, origin, NULL,
  };
  GstPlugin *plugin;
  gboolean res = FALSE;

  g_return_val_if_fail (name != NULL, FALSE);
  g_return_val_if_fail (description != NULL, FALSE);
  g_return_val_if_fail (init_func != NULL, FALSE);
  g_return_val_if_fail (version != NULL, FALSE);
  g_return_val_if_fail (license != NULL, FALSE);
  g_return_val_if_fail (source != NULL, FALSE);
  g_return_val_if_fail (package != NULL, FALSE);
  g_return_val_if_fail (origin != NULL, FALSE);

  /* make sure gst_init() has been called */
  g_return_val_if_fail (_gst_plugin_inited != FALSE, FALSE);

  GST_LOG ("attempting to load static plugin \"%s\" now...", name);
  plugin = g_object_newv (GST_TYPE_PLUGIN, 0, NULL);
  if (gst_plugin_register_func (plugin, &desc, NULL) != NULL) {
    GST_INFO ("registered static plugin \"%s\"", name);
    res = gst_registry_add_plugin (gst_registry_get (), plugin);
    GST_INFO ("added static plugin \"%s\", result: %d", name, res);
  }
  return res;
}

/**
 * gst_plugin_register_static_full:
 * @major_version: the major version number of the GStreamer core that the
 *     plugin was compiled for, you can just use GST_VERSION_MAJOR here
 * @minor_version: the minor version number of the GStreamer core that the
 *     plugin was compiled for, you can just use GST_VERSION_MINOR here
 * @name: a unique name of the plugin (ideally prefixed with an application- or
 *     library-specific namespace prefix in order to avoid name conflicts in
 *     case a similar plugin with the same name ever gets added to GStreamer)
 * @description: description of the plugin
 * @init_full_func: (scope call): pointer to the init function with user data
 *     of this plugin.
 * @version: version string of the plugin
 * @license: effective license of plugin. Must be one of the approved licenses
 *     (see #GstPluginDesc above) or the plugin will not be registered.
 * @source: source module plugin belongs to
 * @package: shipped package plugin belongs to
 * @origin: URL to provider of plugin
 * @user_data: gpointer to user data
 *
 * Registers a static plugin, ie. a plugin which is private to an application
 * or library and contained within the application or library (as opposed to
 * being shipped as a separate module file) with a #GstPluginInitFullFunc
 * which allows user data to be passed to the callback function (useful
 * for bindings).
 *
 * You must make sure that GStreamer has been initialised (with gst_init() or
 * via gst_init_get_option_group()) before calling this function.
 *
 * Returns: TRUE if the plugin was registered correctly, otherwise FALSE.
 *
 * Since: 0.10.24
 *
 */
gboolean
gst_plugin_register_static_full (gint major_version, gint minor_version,
    const gchar * name, const gchar * description,
    GstPluginInitFullFunc init_full_func, const gchar * version,
    const gchar * license, const gchar * source, const gchar * package,
    const gchar * origin, gpointer user_data)
{
  GstPluginDesc desc = { major_version, minor_version, name, description,
    (GstPluginInitFunc) init_full_func, version, license, source, package,
    origin, NULL,
  };
  GstPlugin *plugin;
  gboolean res = FALSE;

  g_return_val_if_fail (name != NULL, FALSE);
  g_return_val_if_fail (description != NULL, FALSE);
  g_return_val_if_fail (init_full_func != NULL, FALSE);
  g_return_val_if_fail (version != NULL, FALSE);
  g_return_val_if_fail (license != NULL, FALSE);
  g_return_val_if_fail (source != NULL, FALSE);
  g_return_val_if_fail (package != NULL, FALSE);
  g_return_val_if_fail (origin != NULL, FALSE);

  /* make sure gst_init() has been called */
  g_return_val_if_fail (_gst_plugin_inited != FALSE, FALSE);

  GST_LOG ("attempting to load static plugin \"%s\" now...", name);
  plugin = g_object_newv (GST_TYPE_PLUGIN, 0, NULL);
  if (gst_plugin_register_func (plugin, &desc, user_data) != NULL) {
    GST_INFO ("registered static plugin \"%s\"", name);
    res = gst_registry_add_plugin (gst_registry_get (), plugin);
    GST_INFO ("added static plugin \"%s\", result: %d", name, res);
  }
  return res;
}

void
_priv_gst_plugin_initialize (void)
{
  const gchar *whitelist;
  guint i;

  _gst_plugin_inited = TRUE;

  whitelist = g_getenv ("GST_PLUGIN_LOADING_WHITELIST");
  if (whitelist != NULL && *whitelist != '\0') {
    _plugin_loading_whitelist = g_strsplit (whitelist,
        G_SEARCHPATH_SEPARATOR_S, -1);
    for (i = 0; _plugin_loading_whitelist[i] != NULL; ++i) {
      GST_INFO ("plugins whitelist entry: %s", _plugin_loading_whitelist[i]);
    }
  }

  /* now register all static plugins */
  GST_INFO ("registering %u static plugins", _num_static_plugins);
  for (i = 0; i < _num_static_plugins; ++i) {
    gst_plugin_register_static (_static_plugins[i].major_version,
        _static_plugins[i].minor_version, _static_plugins[i].name,
        _static_plugins[i].description, _static_plugins[i].plugin_init,
        _static_plugins[i].version, _static_plugins[i].license,
        _static_plugins[i].source, _static_plugins[i].package,
        _static_plugins[i].origin);
  }

  if (_static_plugins) {
    free (_static_plugins);
    _static_plugins = NULL;
    _num_static_plugins = 0;
  }
}

/* Whitelist entry format:
 *
 *   plugin1,plugin2@pathprefix or
 *   plugin1,plugin2@* or just
 *   plugin1,plugin2 or
 *   source-package@pathprefix or
 *   source-package@* or just
 *   source-package
 *
 * ie. the bit before the path will be checked against both the plugin
 * name and the plugin's source package name, to keep the format simple.
 */
static gboolean
gst_plugin_desc_matches_whitelist_entry (GstPluginDesc * desc,
    const gchar * filename, const gchar * pattern)
{
  const gchar *sep;
  gboolean ret = FALSE;
  gchar *name;

  GST_LOG ("Whitelist pattern '%s', plugin: %s of %s@%s", pattern, desc->name,
      desc->source, GST_STR_NULL (filename));

  /* do we have a path prefix? */
  sep = strchr (pattern, '@');
  if (sep != NULL && strcmp (sep, "@*") != 0 && strcmp (sep, "@") != 0) {
    /* paths are not canonicalised or treated with realpath() here. This
     * should be good enough for our use case, since we just use the paths
     * autotools uses, and those will be constructed from the same prefix. */
    if (filename != NULL && !g_str_has_prefix (filename, sep + 1))
      return FALSE;

    GST_LOG ("%s matches path prefix %s", GST_STR_NULL (filename), sep + 1);
  }

  if (sep != NULL) {
    name = g_strndup (pattern, (gsize) (sep - pattern));
  } else {
    name = g_strdup (pattern);
  }

  g_strstrip (name);
  if (!g_ascii_isalnum (*name)) {
    GST_WARNING ("Invalid whitelist pattern: %s", pattern);
    goto done;
  }

  /* now check plugin names / source package name */
  if (strchr (name, ',') == NULL) {
    /* only a single name: either a plugin name or the source package name */
    ret = (strcmp (desc->source, name) == 0 || strcmp (desc->name, name) == 0);
  } else {
    gchar **n, **names;

    /* multiple names: assume these are plugin names */
    names = g_strsplit (name, ",", -1);
    for (n = names; n != NULL && *n != NULL; ++n) {
      g_strstrip (*n);
      if (strcmp (desc->name, *n) == 0) {
        ret = TRUE;
        break;
      }
    }
    g_strfreev (names);
  }

  GST_LOG ("plugin / source package name match: %d", ret);

done:

  g_free (name);
  return ret;
}

gboolean
priv_gst_plugin_desc_is_whitelisted (GstPluginDesc * desc,
    const gchar * filename)
{
  gchar **entry;

  if (_plugin_loading_whitelist == NULL)
    return TRUE;

  for (entry = _plugin_loading_whitelist; *entry != NULL; ++entry) {
    if (gst_plugin_desc_matches_whitelist_entry (desc, filename, *entry)) {
      GST_LOG ("Plugin %s is in whitelist", filename);
      return TRUE;
    }
  }

  GST_LOG ("Plugin %s (package %s, file %s) not in whitelist", desc->name,
      desc->source, filename);
  return FALSE;
}

gboolean
priv_gst_plugin_loading_have_whitelist (void)
{
  return (_plugin_loading_whitelist != NULL);
}

guint32
priv_gst_plugin_loading_get_whitelist_hash (void)
{
  guint32 hash = 0;

  if (_plugin_loading_whitelist != NULL) {
    gchar **w;

    for (w = _plugin_loading_whitelist; *w != NULL; ++w)
      hash = (hash << 1) ^ g_str_hash (*w);
  }

  return hash;
}

/* this function could be extended to check if the plugin license matches the
 * applications license (would require the app to register its license somehow).
 * We'll wait for someone who's interested in it to code it :)
 */
static gboolean
gst_plugin_check_license (const gchar * license)
{
  gint i;

  for (i = 0; i < G_N_ELEMENTS (valid_licenses_idx); ++i) {
    if (strcmp (license, valid_licenses + valid_licenses_idx[i]) == 0)
      return TRUE;
  }
  return FALSE;
}

static gboolean
gst_plugin_check_version (gint major, gint minor)
{
  /* return NULL if the major and minor version numbers are not compatible */
  /* with ours. */
  if (major != GST_VERSION_MAJOR || minor > GST_VERSION_MINOR)
    return FALSE;

  return TRUE;
}

static GstPlugin *
gst_plugin_register_func (GstPlugin * plugin, const GstPluginDesc * desc,
    gpointer user_data)
{
  if (!gst_plugin_check_version (desc->major_version, desc->minor_version)) {
    if (GST_CAT_DEFAULT)
      GST_WARNING ("plugin \"%s\" has incompatible version, not loading",
          plugin->filename);
    return NULL;
  }

  if (!desc->license || !desc->description || !desc->source ||
      !desc->package || !desc->origin) {
    if (GST_CAT_DEFAULT)
      GST_WARNING ("plugin \"%s\" has incorrect GstPluginDesc, not loading",
          plugin->filename);
    return NULL;
  }

  if (!gst_plugin_check_license (desc->license)) {
    if (GST_CAT_DEFAULT)
      GST_WARNING ("plugin \"%s\" has invalid license \"%s\", not loading",
          plugin->filename, desc->license);
    return NULL;
  }

  if (GST_CAT_DEFAULT)
    GST_LOG ("plugin \"%s\" looks good", GST_STR_NULL (plugin->filename));

  gst_plugin_desc_copy (&plugin->desc, desc);

  /* make resident so we're really sure it never gets unloaded again.
   * Theoretically this is not needed, but practically it doesn't hurt.
   * And we're rather safe than sorry. */
  if (plugin->module)
    g_module_make_resident (plugin->module);

  if (user_data) {
    if (!(((GstPluginInitFullFunc) (desc->plugin_init)) (plugin, user_data))) {
      if (GST_CAT_DEFAULT)
        GST_WARNING ("plugin \"%s\" failed to initialise", plugin->filename);
      return NULL;
    }
  } else {
    if (!((desc->plugin_init) (plugin))) {
      if (GST_CAT_DEFAULT)
        GST_WARNING ("plugin \"%s\" failed to initialise", plugin->filename);
      return NULL;
    }
  }

  if (GST_CAT_DEFAULT)
    GST_LOG ("plugin \"%s\" initialised", GST_STR_NULL (plugin->filename));

  return plugin;
}

#ifdef HAVE_SIGACTION
static struct sigaction oldaction;
static gboolean _gst_plugin_fault_handler_is_setup = FALSE;

/*
 * _gst_plugin_fault_handler_restore:
 * segfault handler restorer
 */
static void
_gst_plugin_fault_handler_restore (void)
{
  if (!_gst_plugin_fault_handler_is_setup)
    return;

  _gst_plugin_fault_handler_is_setup = FALSE;

  sigaction (SIGSEGV, &oldaction, NULL);
}

/*
 * _gst_plugin_fault_handler_sighandler:
 * segfault handler implementation
 */
static void
_gst_plugin_fault_handler_sighandler (int signum)
{
  /* We need to restore the fault handler or we'll keep getting it */
  _gst_plugin_fault_handler_restore ();

  switch (signum) {
    case SIGSEGV:
      g_print ("\nERROR: ");
      g_print ("Caught a segmentation fault while loading plugin file:\n");
      g_print ("%s\n\n", _gst_plugin_fault_handler_filename);
      g_print ("Please either:\n");
      g_print ("- remove it and restart.\n");
      g_print
          ("- run with --gst-disable-segtrap --gst-disable-registry-fork and debug.\n");
      exit (-1);
      break;
    default:
      g_print ("Caught unhandled signal on plugin loading\n");
      break;
  }
}

/*
 * _gst_plugin_fault_handler_setup:
 * sets up the segfault handler
 */
static void
_gst_plugin_fault_handler_setup (void)
{
  struct sigaction action;

  /* if asked to leave segfaults alone, just return */
  if (!gst_segtrap_is_enabled ())
    return;

  if (_gst_plugin_fault_handler_is_setup)
    return;

  _gst_plugin_fault_handler_is_setup = TRUE;

  memset (&action, 0, sizeof (action));
  action.sa_handler = _gst_plugin_fault_handler_sighandler;

  sigaction (SIGSEGV, &action, &oldaction);
}
#else /* !HAVE_SIGACTION */
static void
_gst_plugin_fault_handler_restore (void)
{
}

static void
_gst_plugin_fault_handler_setup (void)
{
}
#endif /* HAVE_SIGACTION */

/* g_time_val_from_iso8601() doesn't do quite what we want */
static gboolean
check_release_datetime (const gchar * date_time)
{
  guint64 val;

  /* we require YYYY-MM-DD or YYYY-MM-DDTHH:MMZ format */
  if (!g_ascii_isdigit (*date_time))
    return FALSE;

  val = g_ascii_strtoull (date_time, (gchar **) & date_time, 10);
  if (val < 2000 || val > 2100 || *date_time != '-')
    return FALSE;

  val = g_ascii_strtoull (date_time + 1, (gchar **) & date_time, 10);
  if (val == 0 || val > 12 || *date_time != '-')
    return FALSE;

  val = g_ascii_strtoull (date_time + 1, (gchar **) & date_time, 10);
  if (val == 0 || val > 32)
    return FALSE;

  /* end of string or date/time separator + HH:MMZ */
  if (*date_time == 'T' || *date_time == ' ') {
    val = g_ascii_strtoull (date_time + 1, (gchar **) & date_time, 10);
    if (val > 24 || *date_time != ':')
      return FALSE;

    val = g_ascii_strtoull (date_time + 1, (gchar **) & date_time, 10);
    if (val > 59 || *date_time != 'Z')
      return FALSE;

    ++date_time;
  }

  return (*date_time == '\0');
}

static GMutex gst_plugin_loading_mutex;

#define CHECK_PLUGIN_DESC_FIELD(desc,field,fn)                               \
  if (G_UNLIKELY ((desc)->field == NULL)) {                                  \
    GST_ERROR ("GstPluginDesc for '%s' has no %s", fn, G_STRINGIFY (field)); \
  }

/**
 * gst_plugin_load_file:
 * @filename: the plugin filename to load
 * @error: pointer to a NULL-valued GError
 *
 * Loads the given plugin and refs it.  Caller needs to unref after use.
 *
 * Returns: (transfer full): a reference to the existing loaded GstPlugin, a 
 * reference to the newly-loaded GstPlugin, or NULL if an error occurred.
 */
GstPlugin *
gst_plugin_load_file (const gchar * filename, GError ** error)
{
  GstPluginDesc *desc;
  GstPlugin *plugin;
  GModule *module;
  gboolean ret;
  gpointer ptr;
  GStatBuf file_status;
  GstRegistry *registry;
  gboolean new_plugin = TRUE;
  GModuleFlags flags;

  g_return_val_if_fail (filename != NULL, NULL);

  registry = gst_registry_get ();
  g_mutex_lock (&gst_plugin_loading_mutex);

  plugin = gst_registry_lookup (registry, filename);
  if (plugin) {
    if (plugin->module) {
      /* already loaded */
      g_mutex_unlock (&gst_plugin_loading_mutex);
      return plugin;
    } else {
      /* load plugin and update fields */
      new_plugin = FALSE;
    }
  }

  GST_CAT_DEBUG (GST_CAT_PLUGIN_LOADING, "attempt to load plugin \"%s\"",
      filename);

  if (g_module_supported () == FALSE) {
    GST_CAT_DEBUG (GST_CAT_PLUGIN_LOADING, "module loading not supported");
    g_set_error (error,
        GST_PLUGIN_ERROR,
        GST_PLUGIN_ERROR_MODULE, "Dynamic loading not supported");
    goto return_error;
  }

  if (g_stat (filename, &file_status)) {
    GST_CAT_DEBUG (GST_CAT_PLUGIN_LOADING, "problem accessing file");
    g_set_error (error,
        GST_PLUGIN_ERROR,
        GST_PLUGIN_ERROR_MODULE, "Problem accessing file %s: %s", filename,
        g_strerror (errno));
    goto return_error;
  }

  flags = G_MODULE_BIND_LOCAL;
  /* libgstpython.so is the gst-python plugin loader. It needs to be loaded with
   * G_MODULE_BIND_LAZY.
   *
   * Ideally there should be a generic way for plugins to specify that they
   * need to be loaded with _LAZY.
   * */
  if (strstr (filename, "libgstpython"))
    flags |= G_MODULE_BIND_LAZY;

  module = g_module_open (filename, flags);
  if (module == NULL) {
    GST_CAT_WARNING (GST_CAT_PLUGIN_LOADING, "module_open failed: %s",
        g_module_error ());
    g_set_error (error,
        GST_PLUGIN_ERROR, GST_PLUGIN_ERROR_MODULE, "Opening module failed: %s",
        g_module_error ());
    /* If we failed to open the shared object, then it's probably because a
     * plugin is linked against the wrong libraries. Print out an easy-to-see
     * message in this case. */
    g_warning ("Failed to load plugin '%s': %s", filename, g_module_error ());
    goto return_error;
  }

  ret = g_module_symbol (module, "gst_plugin_desc", &ptr);
  if (!ret) {
    GST_DEBUG ("Could not find plugin entry point in \"%s\"", filename);
    g_set_error (error,
        GST_PLUGIN_ERROR,
        GST_PLUGIN_ERROR_MODULE,
        "File \"%s\" is not a GStreamer plugin", filename);
    g_module_close (module);
    goto return_error;
  }

  desc = (GstPluginDesc *) ptr;

  if (priv_gst_plugin_loading_have_whitelist () &&
      !priv_gst_plugin_desc_is_whitelisted (desc, filename)) {
    GST_INFO ("Whitelist specified and plugin not in whitelist, not loading: "
        "name=%s, package=%s, file=%s", desc->name, desc->source, filename);
    g_set_error (error, GST_PLUGIN_ERROR, GST_PLUGIN_ERROR_MODULE,
        "Not loading plugin file \"%s\", not in whitelist", filename);
    g_module_close (module);
    goto return_error;
  }

  if (new_plugin) {
    plugin = g_object_newv (GST_TYPE_PLUGIN, 0, NULL);
    plugin->file_mtime = file_status.st_mtime;
    plugin->file_size = file_status.st_size;
    plugin->filename = g_strdup (filename);
    plugin->basename = g_path_get_basename (filename);
  }

  plugin->module = module;
  plugin->orig_desc = desc;

  if (new_plugin) {
    /* check plugin description: complain about bad values but accept them, to
     * maintain backwards compatibility (FIXME: 0.11) */
    CHECK_PLUGIN_DESC_FIELD (plugin->orig_desc, name, filename);
    CHECK_PLUGIN_DESC_FIELD (plugin->orig_desc, description, filename);
    CHECK_PLUGIN_DESC_FIELD (plugin->orig_desc, version, filename);
    CHECK_PLUGIN_DESC_FIELD (plugin->orig_desc, license, filename);
    CHECK_PLUGIN_DESC_FIELD (plugin->orig_desc, source, filename);
    CHECK_PLUGIN_DESC_FIELD (plugin->orig_desc, package, filename);
    CHECK_PLUGIN_DESC_FIELD (plugin->orig_desc, origin, filename);

    if (plugin->orig_desc->release_datetime != NULL &&
        !check_release_datetime (plugin->orig_desc->release_datetime)) {
      GST_ERROR ("GstPluginDesc for '%s' has invalid datetime '%s'",
          filename, plugin->orig_desc->release_datetime);
      plugin->orig_desc->release_datetime = NULL;
    }
  }

  GST_LOG ("Plugin %p for file \"%s\" prepared, calling entry function...",
      plugin, filename);

  /* this is where we load the actual .so, so let's trap SIGSEGV */
  _gst_plugin_fault_handler_setup ();
  _gst_plugin_fault_handler_filename = plugin->filename;

  GST_LOG ("Plugin %p for file \"%s\" prepared, registering...",
      plugin, filename);

  if (!gst_plugin_register_func (plugin, plugin->orig_desc, NULL)) {
    /* remove signal handler */
    _gst_plugin_fault_handler_restore ();
    GST_DEBUG ("gst_plugin_register_func failed for plugin \"%s\"", filename);
    /* plugin == NULL */
    g_set_error (error,
        GST_PLUGIN_ERROR,
        GST_PLUGIN_ERROR_MODULE,
        "File \"%s\" appears to be a GStreamer plugin, but it failed to initialize",
        filename);
    goto return_error;
  }

  /* remove signal handler */
  _gst_plugin_fault_handler_restore ();
  _gst_plugin_fault_handler_filename = NULL;
  GST_INFO ("plugin \"%s\" loaded", plugin->filename);

  if (new_plugin) {
    gst_object_ref (plugin);
    gst_registry_add_plugin (gst_registry_get (), plugin);
  }

  g_mutex_unlock (&gst_plugin_loading_mutex);
  return plugin;

return_error:
  {
    if (plugin)
      gst_object_unref (plugin);
    g_mutex_unlock (&gst_plugin_loading_mutex);
    return NULL;
  }
}

static void
gst_plugin_desc_copy (GstPluginDesc * dest, const GstPluginDesc * src)
{
  dest->major_version = src->major_version;
  dest->minor_version = src->minor_version;
  dest->name = g_intern_string (src->name);
  dest->description = g_intern_string (src->description);
  dest->plugin_init = src->plugin_init;
  dest->version = g_intern_string (src->version);
  dest->license = g_intern_string (src->license);
  dest->source = g_intern_string (src->source);
  dest->package = g_intern_string (src->package);
  dest->origin = g_intern_string (src->origin);
  dest->release_datetime = g_intern_string (src->release_datetime);
}

/**
 * gst_plugin_get_name:
 * @plugin: plugin to get the name of
 *
 * Get the short name of the plugin
 *
 * Returns: the name of the plugin
 */
const gchar *
gst_plugin_get_name (GstPlugin * plugin)
{
  g_return_val_if_fail (plugin != NULL, NULL);

  return plugin->desc.name;
}

/**
 * gst_plugin_get_description:
 * @plugin: plugin to get long name of
 *
 * Get the long descriptive name of the plugin
 *
 * Returns: the long name of the plugin
 */
const gchar *
gst_plugin_get_description (GstPlugin * plugin)
{
  g_return_val_if_fail (plugin != NULL, NULL);

  return plugin->desc.description;
}

/**
 * gst_plugin_get_filename:
 * @plugin: plugin to get the filename of
 *
 * get the filename of the plugin
 *
 * Returns: the filename of the plugin
 */
const gchar *
gst_plugin_get_filename (GstPlugin * plugin)
{
  g_return_val_if_fail (plugin != NULL, NULL);

  return plugin->filename;
}

/**
 * gst_plugin_get_version:
 * @plugin: plugin to get the version of
 *
 * get the version of the plugin
 *
 * Returns: the version of the plugin
 */
const gchar *
gst_plugin_get_version (GstPlugin * plugin)
{
  g_return_val_if_fail (plugin != NULL, NULL);

  return plugin->desc.version;
}

/**
 * gst_plugin_get_license:
 * @plugin: plugin to get the license of
 *
 * get the license of the plugin
 *
 * Returns: the license of the plugin
 */
const gchar *
gst_plugin_get_license (GstPlugin * plugin)
{
  g_return_val_if_fail (plugin != NULL, NULL);

  return plugin->desc.license;
}

/**
 * gst_plugin_get_source:
 * @plugin: plugin to get the source of
 *
 * get the source module the plugin belongs to.
 *
 * Returns: the source of the plugin
 */
const gchar *
gst_plugin_get_source (GstPlugin * plugin)
{
  g_return_val_if_fail (plugin != NULL, NULL);

  return plugin->desc.source;
}

/**
 * gst_plugin_get_package:
 * @plugin: plugin to get the package of
 *
 * get the package the plugin belongs to.
 *
 * Returns: the package of the plugin
 */
const gchar *
gst_plugin_get_package (GstPlugin * plugin)
{
  g_return_val_if_fail (plugin != NULL, NULL);

  return plugin->desc.package;
}

/**
 * gst_plugin_get_origin:
 * @plugin: plugin to get the origin of
 *
 * get the URL where the plugin comes from
 *
 * Returns: the origin of the plugin
 */
const gchar *
gst_plugin_get_origin (GstPlugin * plugin)
{
  g_return_val_if_fail (plugin != NULL, NULL);

  return plugin->desc.origin;
}

/**
 * gst_plugin_get_release_date_string:
 * @plugin: plugin to get the release date of
 *
 * Get the release date (and possibly time) in form of a string, if available.
 *
 * For normal GStreamer plugin releases this will usually just be a date in
 * the form of "YYYY-MM-DD", while pre-releases and builds from git may contain
 * a time component after the date as well, in which case the string will be
 * formatted like "YYYY-MM-DDTHH:MMZ" (e.g. "2012-04-30T09:30Z").
 *
 * There may be plugins that do not have a valid release date set on them.
 *
 * Returns: the date string of the plugin, or %NULL if not available.
 */
const gchar *
gst_plugin_get_release_date_string (GstPlugin * plugin)
{
  g_return_val_if_fail (plugin != NULL, NULL);

  return plugin->desc.release_datetime;
}

/**
 * gst_plugin_is_loaded:
 * @plugin: plugin to query
 *
 * queries if the plugin is loaded into memory
 *
 * Returns: TRUE is loaded, FALSE otherwise
 */
gboolean
gst_plugin_is_loaded (GstPlugin * plugin)
{
  g_return_val_if_fail (plugin != NULL, FALSE);

  return (plugin->module != NULL || plugin->filename == NULL);
}

/**
 * gst_plugin_get_cache_data:
 * @plugin: a plugin
 *
 * Gets the plugin specific data cache. If it is %NULL there is no cached data
 * stored. This is the case when the registry is getting rebuilt.
 *
 * Returns: (transfer none): The cached data as a #GstStructure or %NULL.
 *
 * Since: 0.10.24
 */
const GstStructure *
gst_plugin_get_cache_data (GstPlugin * plugin)
{
  g_return_val_if_fail (GST_IS_PLUGIN (plugin), NULL);

  return plugin->priv->cache_data;
}

/**
 * gst_plugin_set_cache_data:
 * @plugin: a plugin
 * @cache_data: (transfer full): a structure containing the data to cache
 *
 * Adds plugin specific data to cache. Passes the ownership of the structure to
 * the @plugin.
 *
 * The cache is flushed every time the registry is rebuilt.
 *
 * Since: 0.10.24
 */
void
gst_plugin_set_cache_data (GstPlugin * plugin, GstStructure * cache_data)
{
  g_return_if_fail (GST_IS_PLUGIN (plugin));
  g_return_if_fail (GST_IS_STRUCTURE (cache_data));

  if (plugin->priv->cache_data) {
    gst_structure_free (plugin->priv->cache_data);
  }
  plugin->priv->cache_data = cache_data;
}

#if 0
/**
 * gst_plugin_feature_list:
 * @plugin: plugin to query
 * @filter: the filter to use
 * @first: only return first match
 * @user_data: user data passed to the filter function
 *
 * Runs a filter against all plugin features and returns a GList with
 * the results. If the first flag is set, only the first match is
 * returned (as a list with a single object).
 *
 * Returns: a GList of features, g_list_free after use.
 */
GList *
gst_plugin_feature_filter (GstPlugin * plugin,
    GstPluginFeatureFilter filter, gboolean first, gpointer user_data)
{
  GList *list;
  GList *g;

  list = gst_filter_run (plugin->features, (GstFilterFunc) filter, first,
      user_data);
  for (g = list; g; g = g->next) {
    gst_object_ref (plugin);
  }

  return list;
}

typedef struct
{
  GstPluginFeatureFilter filter;
  gboolean first;
  gpointer user_data;
  GList *result;
}
FeatureFilterData;

static gboolean
_feature_filter (GstPlugin * plugin, gpointer user_data)
{
  GList *result;
  FeatureFilterData *data = (FeatureFilterData *) user_data;

  result = gst_plugin_feature_filter (plugin, data->filter, data->first,
      data->user_data);
  if (result) {
    data->result = g_list_concat (data->result, result);
    return TRUE;
  }
  return FALSE;
}

/**
 * gst_plugin_list_feature_filter:
 * @list: a #GList of plugins to query
 * @filter: the filter function to use
 * @first: only return first match
 * @user_data: user data passed to the filter function
 *
 * Runs a filter against all plugin features of the plugins in the given
 * list and returns a GList with the results.
 * If the first flag is set, only the first match is
 * returned (as a list with a single object).
 *
 * Returns: a GList of features, g_list_free after use.
 */
GList *
gst_plugin_list_feature_filter (GList * list,
    GstPluginFeatureFilter filter, gboolean first, gpointer user_data)
{
  FeatureFilterData data;
  GList *result;

  data.filter = filter;
  data.first = first;
  data.user_data = user_data;
  data.result = NULL;

  result = gst_filter_run (list, (GstFilterFunc) _feature_filter, first, &data);
  g_list_free (result);

  return data.result;
}

/**
 * gst_plugin_find_feature:
 * @plugin: plugin to get the feature from
 * @name: The name of the feature to find
 * @type: The type of the feature to find
 *
 * Find a feature of the given name and type in the given plugin.
 *
 * Returns: a GstPluginFeature or NULL if the feature was not found.
 */
GstPluginFeature *
gst_plugin_find_feature (GstPlugin * plugin, const gchar * name, GType type)
{
  GList *walk;
  GstPluginFeature *result = NULL;
  GstTypeNameData data;

  g_return_val_if_fail (name != NULL, NULL);

  data.type = type;
  data.name = name;

  walk = gst_filter_run (plugin->features,
      (GstFilterFunc) gst_plugin_feature_type_name_filter, TRUE, &data);

  if (walk) {
    result = GST_PLUGIN_FEATURE (walk->data);

    gst_object_ref (result);
    gst_plugin_feature_list_free (walk);
  }

  return result;
}
#endif

#if 0
static gboolean
gst_plugin_feature_name_filter (GstPluginFeature * feature, const gchar * name)
{
  return !strcmp (name, GST_PLUGIN_FEATURE_NAME (feature));
}
#endif

#if 0
/**
 * gst_plugin_find_feature_by_name:
 * @plugin: plugin to get the feature from
 * @name: The name of the feature to find
 *
 * Find a feature of the given name in the given plugin.
 *
 * Returns: a GstPluginFeature or NULL if the feature was not found.
 */
GstPluginFeature *
gst_plugin_find_feature_by_name (GstPlugin * plugin, const gchar * name)
{
  GList *walk;
  GstPluginFeature *result = NULL;

  g_return_val_if_fail (name != NULL, NULL);

  walk = gst_filter_run (plugin->features,
      (GstFilterFunc) gst_plugin_feature_name_filter, TRUE, (void *) name);

  if (walk) {
    result = GST_PLUGIN_FEATURE (walk->data);

    gst_object_ref (result);
    gst_plugin_feature_list_free (walk);
  }

  return result;
}
#endif

/**
 * gst_plugin_load_by_name:
 * @name: name of plugin to load
 *
 * Load the named plugin. Refs the plugin.
 *
 * Returns: (transfer full): a reference to a loaded plugin, or NULL on error.
 */
GstPlugin *
gst_plugin_load_by_name (const gchar * name)
{
  GstPlugin *plugin, *newplugin;
  GError *error = NULL;

  GST_DEBUG ("looking up plugin %s in default registry", name);
  plugin = gst_registry_find_plugin (gst_registry_get (), name);
  if (plugin) {
    GST_DEBUG ("loading plugin %s from file %s", name, plugin->filename);
    newplugin = gst_plugin_load_file (plugin->filename, &error);
    gst_object_unref (plugin);

    if (!newplugin) {
      GST_WARNING ("load_plugin error: %s", error->message);
      g_error_free (error);
      return NULL;
    }
    /* newplugin was reffed by load_file */
    return newplugin;
  }

  GST_DEBUG ("Could not find plugin %s in registry", name);
  return NULL;
}

/**
 * gst_plugin_load:
 * @plugin: (transfer none): plugin to load
 *
 * Loads @plugin. Note that the *return value* is the loaded plugin; @plugin is
 * untouched. The normal use pattern of this function goes like this:
 *
 * <programlisting>
 * GstPlugin *loaded_plugin;
 * loaded_plugin = gst_plugin_load (plugin);
 * // presumably, we're no longer interested in the potentially-unloaded plugin
 * gst_object_unref (plugin);
 * plugin = loaded_plugin;
 * </programlisting>
 *
 * Returns: (transfer full): a reference to a loaded plugin, or NULL on error.
 */
GstPlugin *
gst_plugin_load (GstPlugin * plugin)
{
  GError *error = NULL;
  GstPlugin *newplugin;

  if (gst_plugin_is_loaded (plugin)) {
    return plugin;
  }

  if (!(newplugin = gst_plugin_load_file (plugin->filename, &error)))
    goto load_error;

  return newplugin;

load_error:
  {
    GST_WARNING ("load_plugin error: %s", error->message);
    g_error_free (error);
    return NULL;
  }
}

/**
 * gst_plugin_list_free:
 * @list: (transfer full) (element-type Gst.Plugin): list of #GstPlugin
 *
 * Unrefs each member of @list, then frees the list.
 */
void
gst_plugin_list_free (GList * list)
{
  GList *g;

  for (g = list; g; g = g->next) {
    gst_object_unref (GST_PLUGIN_CAST (g->data));
  }
  g_list_free (list);
}

/* ===== plugin dependencies ===== */

/* Scenarios:
 * ENV + xyz     where ENV can contain multiple values separated by SEPARATOR
 *               xyz may be "" (if ENV contains path to file rather than dir)
 * ENV + *xyz   same as above, but xyz acts as suffix filter
 * ENV + xyz*   same as above, but xyz acts as prefix filter (is this needed?)
 * ENV + *xyz*  same as above, but xyz acts as strstr filter (is this needed?)
 * 
 * same as above, with additional paths hard-coded at compile-time:
 *   - only check paths + ... if ENV is not set or yields not paths
 *   - always check paths + ... in addition to ENV
 *
 * When user specifies set of environment variables, he/she may also use e.g.
 * "HOME/.mystuff/plugins", and we'll expand the content of $HOME with the
 * remainder 
 */

/* we store in registry:
 *  sets of:
 *   { 
 *     - environment variables (array of strings)
 *     - last hash of env variable contents (uint) (so we can avoid doing stats
 *       if one of the env vars has changed; premature optimisation galore)
 *     - hard-coded paths (array of strings)
 *     - xyz filename/suffix/prefix strings (array of strings)
 *     - flags (int)
 *     - last hash of file/dir stats (int)
 *   }
 *   (= struct GstPluginDep)
 */

static guint
gst_plugin_ext_dep_get_env_vars_hash (GstPlugin * plugin, GstPluginDep * dep)
{
  gchar **e;
  guint hash;

  /* there's no deeper logic to what we do here; all we want to know (when
   * checking if the plugin needs to be rescanned) is whether the content of
   * one of the environment variables in the list is different from when it
   * was last scanned */
  hash = 0;
  for (e = dep->env_vars; e != NULL && *e != NULL; ++e) {
    const gchar *val;
    gchar env_var[256];

    /* order matters: "val",NULL needs to yield a different hash than
     * NULL,"val", so do a shift here whether the var is set or not */
    hash = hash << 5;

    /* want environment variable at beginning of string */
    if (!g_ascii_isalnum (**e)) {
      GST_WARNING_OBJECT (plugin, "string prefix is not a valid environment "
          "variable string: %s", *e);
      continue;
    }

    /* user is allowed to specify e.g. "HOME/.pitivi/plugins" */
    g_strlcpy (env_var, *e, sizeof (env_var));
    g_strdelimit (env_var, "/\\", '\0');

    if ((val = g_getenv (env_var)))
      hash += g_str_hash (val);
  }

  return hash;
}

gboolean
_priv_plugin_deps_env_vars_changed (GstPlugin * plugin)
{
  GList *l;

  for (l = plugin->priv->deps; l != NULL; l = l->next) {
    GstPluginDep *dep = l->data;

    if (dep->env_hash != gst_plugin_ext_dep_get_env_vars_hash (plugin, dep))
      return TRUE;
  }

  return FALSE;
}

static void
gst_plugin_ext_dep_extract_env_vars_paths (GstPlugin * plugin,
    GstPluginDep * dep, GQueue * paths)
{
  gchar **evars;

  for (evars = dep->env_vars; evars != NULL && *evars != NULL; ++evars) {
    const gchar *e;
    gchar **components;

    /* want environment variable at beginning of string */
    if (!g_ascii_isalnum (**evars)) {
      GST_WARNING_OBJECT (plugin, "string prefix is not a valid environment "
          "variable string: %s", *evars);
      continue;
    }

    /* user is allowed to specify e.g. "HOME/.pitivi/plugins", which we want to
     * split into the env_var name component and the path component */
    components = g_strsplit_set (*evars, "/\\", 2);
    g_assert (components != NULL);

    e = g_getenv (components[0]);
    GST_LOG_OBJECT (plugin, "expanding %s = '%s' (path suffix: %s)",
        components[0], GST_STR_NULL (e), GST_STR_NULL (components[1]));

    if (components[1] != NULL) {
      g_strdelimit (components[1], "/\\", G_DIR_SEPARATOR);
    }

    if (e != NULL && *e != '\0') {
      gchar **arr;
      guint i;

      arr = g_strsplit (e, G_SEARCHPATH_SEPARATOR_S, -1);

      for (i = 0; arr != NULL && arr[i] != NULL; ++i) {
        gchar *full_path;

        if (!g_path_is_absolute (arr[i])) {
          GST_INFO_OBJECT (plugin, "ignoring environment variable content '%s'"
              ": either not an absolute path or not a path at all", arr[i]);
          continue;
        }

        if (components[1] != NULL) {
          full_path = g_build_filename (arr[i], components[1], NULL);
        } else {
          full_path = g_strdup (arr[i]);
        }

        if (!g_queue_find_custom (paths, full_path, (GCompareFunc) strcmp)) {
          GST_LOG_OBJECT (plugin, "path: '%s'", full_path);
          g_queue_push_tail (paths, full_path);
          full_path = NULL;
        } else {
          GST_LOG_OBJECT (plugin, "path: '%s' (duplicate,ignoring)", full_path);
          g_free (full_path);
        }
      }

      g_strfreev (arr);
    }

    g_strfreev (components);
  }

  GST_LOG_OBJECT (plugin, "Extracted %d paths from environment", paths->length);
}

static guint
gst_plugin_ext_dep_get_hash_from_stat_entry (GStatBuf * s)
{
  if (!(s->st_mode & (S_IFDIR | S_IFREG)))
    return (guint) - 1;

  /* completely random formula */
  return ((s->st_size << 3) + (s->st_mtime << 5)) ^ s->st_ctime;
}

static gboolean
gst_plugin_ext_dep_direntry_matches (GstPlugin * plugin, const gchar * entry,
    const gchar ** filenames, GstPluginDependencyFlags flags)
{
  /* no filenames specified, match all entries for now (could probably
   * optimise by just taking the dir stat hash or so) */
  if (filenames == NULL || *filenames == NULL || **filenames == '\0')
    return TRUE;

  while (*filenames != NULL) {
    /* suffix match? */
    if (((flags & GST_PLUGIN_DEPENDENCY_FLAG_FILE_NAME_IS_SUFFIX)) &&
        g_str_has_suffix (entry, *filenames)) {
      return TRUE;
      /* else it's an exact match that's needed */
    } else if (strcmp (entry, *filenames) == 0) {
      return TRUE;
    }
    GST_LOG ("%s does not match %s, flags=0x%04x", entry, *filenames, flags);
    ++filenames;
  }
  return FALSE;
}

static guint
gst_plugin_ext_dep_scan_dir_and_match_names (GstPlugin * plugin,
    const gchar * path, const gchar ** filenames,
    GstPluginDependencyFlags flags, int depth)
{
  const gchar *entry;
  gboolean recurse_dirs;
  GError *err = NULL;
  GDir *dir;
  guint hash = 0;

  recurse_dirs = ! !(flags & GST_PLUGIN_DEPENDENCY_FLAG_RECURSE);

  dir = g_dir_open (path, 0, &err);
  if (dir == NULL) {
    GST_DEBUG_OBJECT (plugin, "g_dir_open(%s) failed: %s", path, err->message);
    g_error_free (err);
    return (guint) - 1;
  }

  /* FIXME: we're assuming here that we always get the directory entries in
   * the same order, and not in a random order */
  while ((entry = g_dir_read_name (dir))) {
    gboolean have_match;
    GStatBuf s;
    gchar *full_path;
    guint fhash;

    have_match =
        gst_plugin_ext_dep_direntry_matches (plugin, entry, filenames, flags);

    /* avoid the stat if possible */
    if (!have_match && !recurse_dirs)
      continue;

    full_path = g_build_filename (path, entry, NULL);
    if (g_stat (full_path, &s) < 0) {
      fhash = (guint) - 1;
      GST_LOG_OBJECT (plugin, "stat: %s (error: %s)", full_path,
          g_strerror (errno));
    } else if (have_match) {
      fhash = gst_plugin_ext_dep_get_hash_from_stat_entry (&s);
      GST_LOG_OBJECT (plugin, "stat: %s (result: %u)", full_path, fhash);
    } else if ((s.st_mode & (S_IFDIR))) {
      fhash = gst_plugin_ext_dep_scan_dir_and_match_names (plugin, full_path,
          filenames, flags, depth + 1);
    } else {
      /* it's not a name match, we want to recurse, but it's not a directory */
      g_free (full_path);
      continue;
    }

    hash = (hash + fhash) << 1;
    g_free (full_path);
  }

  g_dir_close (dir);
  return hash;
}

static guint
gst_plugin_ext_dep_scan_path_with_filenames (GstPlugin * plugin,
    const gchar * path, const gchar ** filenames,
    GstPluginDependencyFlags flags)
{
  const gchar *empty_filenames[] = { "", NULL };
  gboolean recurse_into_dirs, partial_names;
  guint i, hash = 0;

  /* to avoid special-casing below (FIXME?) */
  if (filenames == NULL || *filenames == NULL)
    filenames = empty_filenames;

  recurse_into_dirs = ! !(flags & GST_PLUGIN_DEPENDENCY_FLAG_RECURSE);
  partial_names = ! !(flags & GST_PLUGIN_DEPENDENCY_FLAG_FILE_NAME_IS_SUFFIX);

  /* if we can construct the exact paths to check with the data we have, just
   * stat them one by one; this is more efficient than opening the directory
   * and going through each entry to see if it matches one of our filenames. */
  if (!recurse_into_dirs && !partial_names) {
    for (i = 0; filenames[i] != NULL; ++i) {
      GStatBuf s;
      gchar *full_path;
      guint fhash;

      full_path = g_build_filename (path, filenames[i], NULL);
      if (g_stat (full_path, &s) < 0) {
        fhash = (guint) - 1;
        GST_LOG_OBJECT (plugin, "stat: %s (error: %s)", full_path,
            g_strerror (errno));
      } else {
        fhash = gst_plugin_ext_dep_get_hash_from_stat_entry (&s);
        GST_LOG_OBJECT (plugin, "stat: %s (result: %08x)", full_path, fhash);
      }
      hash = (hash + fhash) << 1;
      g_free (full_path);
    }
  } else {
    hash = gst_plugin_ext_dep_scan_dir_and_match_names (plugin, path,
        filenames, flags, 0);
  }

  return hash;
}

static guint
gst_plugin_ext_dep_get_stat_hash (GstPlugin * plugin, GstPluginDep * dep)
{
  gboolean paths_are_default_only;
  GQueue scan_paths = G_QUEUE_INIT;
  guint scan_hash = 0;
  gchar *path;

  GST_LOG_OBJECT (plugin, "start");

  paths_are_default_only =
      dep->flags & GST_PLUGIN_DEPENDENCY_FLAG_PATHS_ARE_DEFAULT_ONLY;

  gst_plugin_ext_dep_extract_env_vars_paths (plugin, dep, &scan_paths);

  if (g_queue_is_empty (&scan_paths) || !paths_are_default_only) {
    gchar **paths;

    for (paths = dep->paths; paths != NULL && *paths != NULL; ++paths) {
      const gchar *path = *paths;

      if (!g_queue_find_custom (&scan_paths, path, (GCompareFunc) strcmp)) {
        GST_LOG_OBJECT (plugin, "path: '%s'", path);
        g_queue_push_tail (&scan_paths, g_strdup (path));
      } else {
        GST_LOG_OBJECT (plugin, "path: '%s' (duplicate, ignoring)", path);
      }
    }
  }

  while ((path = g_queue_pop_head (&scan_paths))) {
    scan_hash += gst_plugin_ext_dep_scan_path_with_filenames (plugin, path,
        (const gchar **) dep->names, dep->flags);
    scan_hash = scan_hash << 1;
    g_free (path);
  }

  GST_LOG_OBJECT (plugin, "done, scan_hash: %08x", scan_hash);
  return scan_hash;
}

gboolean
_priv_plugin_deps_files_changed (GstPlugin * plugin)
{
  GList *l;

  for (l = plugin->priv->deps; l != NULL; l = l->next) {
    GstPluginDep *dep = l->data;

    if (dep->stat_hash != gst_plugin_ext_dep_get_stat_hash (plugin, dep))
      return TRUE;
  }

  return FALSE;
}

static void
gst_plugin_ext_dep_free (GstPluginDep * dep)
{
  g_strfreev (dep->env_vars);
  g_strfreev (dep->paths);
  g_strfreev (dep->names);
  g_slice_free (GstPluginDep, dep);
}

static gboolean
gst_plugin_ext_dep_strv_equal (gchar ** arr1, gchar ** arr2)
{
  if (arr1 == arr2)
    return TRUE;
  if (arr1 == NULL || arr2 == NULL)
    return FALSE;
  for (; *arr1 != NULL && *arr2 != NULL; ++arr1, ++arr2) {
    if (strcmp (*arr1, *arr2) != 0)
      return FALSE;
  }
  return (*arr1 == *arr2);
}

static gboolean
gst_plugin_ext_dep_equals (GstPluginDep * dep, const gchar ** env_vars,
    const gchar ** paths, const gchar ** names, GstPluginDependencyFlags flags)
{
  if (dep->flags != flags)
    return FALSE;

  return gst_plugin_ext_dep_strv_equal (dep->env_vars, (gchar **) env_vars) &&
      gst_plugin_ext_dep_strv_equal (dep->paths, (gchar **) paths) &&
      gst_plugin_ext_dep_strv_equal (dep->names, (gchar **) names);
}

/**
 * gst_plugin_add_dependency:
 * @plugin: a #GstPlugin
 * @env_vars: NULL-terminated array of environment variables affecting the
 *     feature set of the plugin (e.g. an environment variable containing
 *     paths where to look for additional modules/plugins of a library),
 *     or NULL. Environment variable names may be followed by a path component
 *      which will be added to the content of the environment variable, e.g.
 *      "HOME/.mystuff/plugins".
 * @paths: NULL-terminated array of directories/paths where dependent files
 *     may be.
 * @names: NULL-terminated array of file names (or file name suffixes,
 *     depending on @flags) to be used in combination with the paths from
 *     @paths and/or the paths extracted from the environment variables in
 *     @env_vars, or NULL.
 * @flags: optional flags, or #GST_PLUGIN_DEPENDENCY_FLAG_NONE
 *
 * Make GStreamer aware of external dependencies which affect the feature
 * set of this plugin (ie. the elements or typefinders associated with it).
 *
 * GStreamer will re-inspect plugins with external dependencies whenever any
 * of the external dependencies change. This is useful for plugins which wrap
 * other plugin systems, e.g. a plugin which wraps a plugin-based visualisation
 * library and makes visualisations available as GStreamer elements, or a
 * codec loader which exposes elements and/or caps dependent on what external
 * codec libraries are currently installed.
 *
 * Since: 0.10.22
 */
void
gst_plugin_add_dependency (GstPlugin * plugin, const gchar ** env_vars,
    const gchar ** paths, const gchar ** names, GstPluginDependencyFlags flags)
{
  GstPluginDep *dep;
  GList *l;

  g_return_if_fail (GST_IS_PLUGIN (plugin));

  if ((env_vars == NULL || env_vars[0] == NULL) &&
      (paths == NULL || paths[0] == NULL)) {
    GST_DEBUG_OBJECT (plugin,
        "plugin registered empty dependency set. Ignoring");
    return;
  }

  for (l = plugin->priv->deps; l != NULL; l = l->next) {
    if (gst_plugin_ext_dep_equals (l->data, env_vars, paths, names, flags)) {
      GST_LOG_OBJECT (plugin, "dependency already registered");
      return;
    }
  }

  dep = g_slice_new (GstPluginDep);

  dep->env_vars = g_strdupv ((gchar **) env_vars);
  dep->paths = g_strdupv ((gchar **) paths);
  dep->names = g_strdupv ((gchar **) names);
  dep->flags = flags;

  dep->env_hash = gst_plugin_ext_dep_get_env_vars_hash (plugin, dep);
  dep->stat_hash = gst_plugin_ext_dep_get_stat_hash (plugin, dep);

  plugin->priv->deps = g_list_append (plugin->priv->deps, dep);

  GST_DEBUG_OBJECT (plugin, "added dependency:");
  for (; env_vars != NULL && *env_vars != NULL; ++env_vars)
    GST_DEBUG_OBJECT (plugin, " evar: %s", *env_vars);
  for (; paths != NULL && *paths != NULL; ++paths)
    GST_DEBUG_OBJECT (plugin, " path: %s", *paths);
  for (; names != NULL && *names != NULL; ++names)
    GST_DEBUG_OBJECT (plugin, " name: %s", *names);
}

/**
 * gst_plugin_add_dependency_simple:
 * @plugin: the #GstPlugin
 * @env_vars: one or more environment variables (separated by ':', ';' or ','),
 *      or NULL. Environment variable names may be followed by a path component
 *      which will be added to the content of the environment variable, e.g.
 *      "HOME/.mystuff/plugins:MYSTUFF_PLUGINS_PATH"
 * @paths: one ore more directory paths (separated by ':' or ';' or ','),
 *      or NULL. Example: "/usr/lib/mystuff/plugins"
 * @names: one or more file names or file name suffixes (separated by commas),
 *   or NULL
 * @flags: optional flags, or #GST_PLUGIN_DEPENDENCY_FLAG_NONE
 *
 * Make GStreamer aware of external dependencies which affect the feature
 * set of this plugin (ie. the elements or typefinders associated with it).
 *
 * GStreamer will re-inspect plugins with external dependencies whenever any
 * of the external dependencies change. This is useful for plugins which wrap
 * other plugin systems, e.g. a plugin which wraps a plugin-based visualisation
 * library and makes visualisations available as GStreamer elements, or a
 * codec loader which exposes elements and/or caps dependent on what external
 * codec libraries are currently installed.
 *
 * Convenience wrapper function for gst_plugin_add_dependency() which
 * takes simple strings as arguments instead of string arrays, with multiple
 * arguments separated by predefined delimiters (see above).
 *
 * Since: 0.10.22
 */
void
gst_plugin_add_dependency_simple (GstPlugin * plugin,
    const gchar * env_vars, const gchar * paths, const gchar * names,
    GstPluginDependencyFlags flags)
{
  gchar **a_evars = NULL;
  gchar **a_paths = NULL;
  gchar **a_names = NULL;

  if (env_vars)
    a_evars = g_strsplit_set (env_vars, ":;,", -1);
  if (paths)
    a_paths = g_strsplit_set (paths, ":;,", -1);
  if (names)
    a_names = g_strsplit_set (names, ",", -1);

  gst_plugin_add_dependency (plugin, (const gchar **) a_evars,
      (const gchar **) a_paths, (const gchar **) a_names, flags);

  if (a_evars)
    g_strfreev (a_evars);
  if (a_paths)
    g_strfreev (a_paths);
  if (a_names)
    g_strfreev (a_names);
}
