From d9a656b89b2c5e6837759cecc406f8e01f7b56b8 Mon Sep 17 00:00:00 2001 From: Andy Wingo Date: Fri, 10 May 2002 01:13:40 +0000 Subject: [PATCH] Check to see if the registry is out of date, and if so try to rebuild it. Original commit message from CVS: Check to see if the registry is out of date, and if so try to rebuild it. WIERD THING: trying to run gst-register using system() fails. Apparently child processes can't link to libs parent processes use? It's wierd, and it could be a libtool issue. That's probably just as well, it would be better just to use -register's code from within core and not rely on another binary. --- gst/gst.c | 6 +-- gst/gstregistry.c | 3 +- gst/registries/gstxmlregistry.c | 96 ++++++++++++++++++++++++++++++++- 3 files changed, 98 insertions(+), 7 deletions(-) diff --git a/gst/gst.c b/gst/gst.c index 4fd4b04be7..6f1c3e2f82 100644 --- a/gst/gst.c +++ b/gst/gst.c @@ -81,7 +81,6 @@ enum { #define NUL '\0' #endif -/* FIXME: put in the extended mask help */ static const struct poptOption options[] = { {NULL, NUL, POPT_ARG_CALLBACK|POPT_CBFLAG_PRE|POPT_CBFLAG_POST, &init_popt_callback, 0, NULL, NULL}, {"gst-fatal-warnings", NUL, POPT_ARG_NONE|POPT_ARGFLAG_STRIP, NULL, ARG_FATAL_WARNINGS, "Make all warnings fatal", NULL}, @@ -184,8 +183,7 @@ gst_init_with_popt_table (int *argc, char **argv[], const struct poptOption *pop /* let's do this once there are 1.6.3 popt debs out *argc = poptStrippedArgv (context, *argc, *argv); */ - /* until then we'll do a very basic arg permutation - this will break gst-launch -o */ + /* until then we'll do a very basic arg permutation */ temp = *argv + 1; i = 1; nstrip = 0; @@ -279,7 +277,7 @@ init_pre (void) #ifdef PLUGINS_USE_BUILDDIR /* location libgstelements.so */ - gst_registry_add_path (_global_registry, PLUGINS_BUILDDIR "/libs"); + gst_registry_add_path (_global_registry, PLUGINS_BUILDDIR "/libs/gst"); gst_registry_add_path (_global_registry, PLUGINS_BUILDDIR "/gst/elements"); gst_registry_add_path (_global_registry, PLUGINS_BUILDDIR "/gst/types"); gst_registry_add_path (_global_registry, PLUGINS_BUILDDIR "/gst/autoplug"); diff --git a/gst/gstregistry.c b/gst/gstregistry.c index a4cabaf059..f8ab4ff046 100644 --- a/gst/gstregistry.c +++ b/gst/gstregistry.c @@ -735,7 +735,7 @@ gst_registry_write_get () GstRegistryRead * gst_registry_read_get () { - GstRegistryRead *gst_reg = g_malloc (sizeof (GstRegistryRead)); + GstRegistryRead *gst_reg = g_new0 (GstRegistryRead, 1); /* if a registry is specified on command line, use that one */ if (gst_registry_option) @@ -757,6 +757,7 @@ gst_registry_read_get () { /* it does not exist, so don't read from it */ g_free (gst_reg->local_reg); + gst_reg->local_reg = NULL; } gst_reg->global_reg = g_strdup (GLOBAL_REGISTRY_FILE); } diff --git a/gst/registries/gstxmlregistry.c b/gst/registries/gstxmlregistry.c index 37878f3aa0..2af3e638cb 100644 --- a/gst/registries/gstxmlregistry.c +++ b/gst/registries/gstxmlregistry.c @@ -182,17 +182,109 @@ gst_xml_registry_new (const gchar *name, const gchar *location) #define dirmode \ (S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) +static time_t +get_time(const char * path) +{ + struct stat statbuf; + if (stat(path, &statbuf)) return 0; + if (statbuf.st_mtime > statbuf.st_ctime) return statbuf.st_mtime; + return statbuf.st_ctime; +} + +static gboolean +plugin_times_older_than_recurse(gchar *path, time_t regtime) +{ + DIR *dir; + struct dirent *dirent; + gchar *pluginname; + + time_t pathtime = get_time(path); + + if (pathtime > regtime) { + GST_INFO (GST_CAT_PLUGIN_LOADING, + "time for %s was %ld; more recent than registry time of %ld\n", + path, (long)pathtime, (long)regtime); + return FALSE; + } + + dir = opendir(path); + if (dir) { + while ((dirent = readdir(dir))) { + /* don't want to recurse in place or backwards */ + if (strcmp(dirent->d_name,".") && strcmp(dirent->d_name,"..")) { + pluginname = g_strjoin("/",path,dirent->d_name,NULL); + if (!plugin_times_older_than_recurse(pluginname , regtime)) { + g_free (pluginname); + closedir(dir); + return FALSE; + } + g_free (pluginname); + } + } + closedir(dir); + } + return TRUE; +} + +static gboolean +plugin_times_older_than(GList *paths, time_t regtime) +{ + /* return true iff regtime is more recent than the times of all the files + * in the plugin dirs. + */ + + while (paths) { + GST_DEBUG (GST_CAT_PLUGIN_LOADING, + "comparing plugin times from %s with %ld\n", + (gchar *)paths->data, (long) regtime); + if(!plugin_times_older_than_recurse(paths->data, regtime)) + return FALSE; + paths = g_list_next(paths); + } + return TRUE; +} + static gboolean gst_xml_registry_open_func (GstXMLRegistry *registry, GstXMLRegistryMode mode) { - if (mode == GST_XML_REGISTRY_READ) + gint ret, i; + gchar *str, *plugin_paths, **plugin_pathv; + GList *l, *paths = GST_REGISTRY (registry)->paths; + + if (mode == GST_XML_REGISTRY_READ) { + if (!plugin_times_older_than (paths, get_time (registry->location))) { + plugin_pathv = g_new0 (gchar*, g_list_length (paths)); + for (l=paths, i=0; l->next; i++, l=l->next) + plugin_pathv[i] = (gchar*) l->data; + plugin_paths = g_strjoinv (":", plugin_pathv); + g_free (plugin_pathv); + + str = g_strdup_printf ("gst-register --gst-registry=%s --gst-plugin-path=%s", + registry->location, plugin_paths); + GST_INFO (GST_CAT_GST_INIT, "Registry out of date, running gst-register"); + GST_DEBUG (GST_CAT_PLUGIN_LOADING, "gst-register command line: %s", str); + + g_free (plugin_paths); + ret = system (str); + if (ret != 0) { + GST_INFO (GST_CAT_GST_INIT, "Running gst-register for registry %s failed", registry->location); + return FALSE; + } + + if (!plugin_times_older_than (paths, get_time (registry->location))) { + GST_INFO (GST_CAT_GST_INIT, "Registry still out of date, something is wrong..."); + return FALSE; + } + } + registry->regfile = fopen (registry->location, "r"); + } else if (mode == GST_XML_REGISTRY_WRITE) { /* check the dir */ struct stat filestat; char *dirname = g_strndup(registry->location, - strrchr(registry->location, '/') - registry->location); + strrchr(registry->location, '/') - registry->location); if (stat(dirname, &filestat) == -1 && errno == ENOENT) if (mkdir(dirname, dirmode) != 0) return FALSE;