registry handling changes read up on it in docs/random/thomasvs/registry if intereste...
authorThomas Vander Stichele <thomas@apestaart.org>
Fri, 12 Apr 2002 09:53:00 +0000 (09:53 +0000)
committerThomas Vander Stichele <thomas@apestaart.org>
Fri, 12 Apr 2002 09:53:00 +0000 (09:53 +0000)
Original commit message from CVS:
registry handling changes
read up on it in docs/random/thomasvs/registry if interested
net effect should be transparent; ie. it will keep on working, but will
be more flexible than before.  Testing with garnome seems to work now.
Should probably be rewritten completely, together with plugin loading, but
only after we spec it out ;) It's a bit messy.

ChangeLog
README
docs/random/thomasvs/registry
gst/Makefile.am
gst/gst.c
gst/gst.h
gst/gstplugin.c
gst/gstregistry.c [new file with mode: 0644]
gst/gstregistry.h [new file with mode: 0644]
tools/gst-register.c

index d314a4d..56f615d 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2002-04-12  Thomas Vander Stichele <thomas@apestaart.org>
+
+       * gst/gst*.[ch]: commited GUAD3C code review comments (marked CR1)
+
+       * gst/gstregistry.[ch]: added to handle registry stuff
+         gst/gst.c: changed to use new --gst-registry option
+         tools/gst-register.c: use new registry functions
+          for more info, check docs/random/thomasvs/registry
+
 2002-03-01  Michael Meeks  <michael@ximian.com>                                
        * docs/manual/Makefile.am: use $(wildcard) instead of                   
        strange shell stuff.                                                    
diff --git a/README b/README
index 9e760c4..99fd6ac 100644 (file)
--- a/README
+++ b/README
@@ -22,3 +22,11 @@ ATM, most of us have at least these versions :
 
 autogen.sh will check for these versions and complain if you don't have 
 them.  
+
+Check autogen.sh options by running autogen.sh --help
+
+autogen.sh can pass on arguments to configure - you just need to separate them
+from autogen.sh with -- between the two.
+prefix has been added to autogen.sh but will be passed on to configure because
+some build scripts like that.
+
index dde3dbe..5287133 100644 (file)
@@ -31,8 +31,6 @@ Reviewing the registry (thomasvs, April 8 2002)
   - use gst_registry_read_get to get a GstRegistryRead struct back
     listing the path of global and local file to read
 
-* QUESTIONS
-  - maybe it's better to try the global registry first (if unspecified),
-    and see if you have write permissions ? Because if you do, you might
-    as well do it there - the system gave you the permission.
-    useful for doing garnome installs as a user
+* gst-register signals it's going to write to the registry (causing it to
+  be unlinked before the read in post_init ()) by setting a global variable,
+  _gst_init_write_registry
index 31c7a88..3ddcf3c 100644 (file)
@@ -77,6 +77,7 @@ libgstreamer_la_SOURCES =             \
        gsttype.c               \
        $(GST_TYPEFIND_SRC)     \
        gstutils.c              \
+       gstregistry.c           \
        gsttimecache.c          \
        $(GST_PARSE_SRC)        \
        $(GSTARCH_SRCS)         \
@@ -136,6 +137,7 @@ libgstreamerinclude_HEADERS =               \
        gsttype.h               \
        gsttypefind.h           \
        gstutils.h              \
+       gstregistry.h           \
        gsttimecache.h          \
        gstparse.h              \
        gstversion.h            \
index 138efa5..42bbab1 100644 (file)
--- a/gst/gst.c
+++ b/gst/gst.c
@@ -40,7 +40,6 @@ gchar *_gst_progname;
 extern gint _gst_trace_on;
 extern gboolean _gst_plugin_spew;
 
-
 static void            load_plugin_func        (gpointer data, gpointer user_data);
 static void            init_popt_callback      (poptContext context, enum poptCallbackReason reason,
                                                  const struct poptOption *option, const char *arg, void *data);
@@ -70,7 +69,8 @@ enum {
   ARG_PLUGIN_SPEW,
   ARG_PLUGIN_PATH,
   ARG_PLUGIN_LOAD,
-  ARG_SCHEDULER
+  ARG_SCHEDULER,
+  ARG_REGISTRY
 };
 
 #ifndef NUL
@@ -88,6 +88,7 @@ static const struct poptOption options[] = {
   {"gst-plugin-path", NUL, POPT_ARG_STRING|POPT_ARGFLAG_STRIP, NULL, ARG_PLUGIN_PATH, "'" G_SEARCHPATH_SEPARATOR_S "'--separated path list for loading plugins", "PATHS"},
   {"gst-plugin-load", NUL, POPT_ARG_STRING|POPT_ARGFLAG_STRIP, NULL, ARG_PLUGIN_LOAD, "comma-separated list of plugins to preload in addition to the list stored in env variable GST_PLUGIN_PATH", "PLUGINS"},
   {"gst-scheduler",   NUL, POPT_ARG_STRING|POPT_ARGFLAG_STRIP, NULL, ARG_SCHEDULER,   "scheduler to use ('basic' is the default)", "SCHEDULER"},
+  {"gst-registry",   NUL, POPT_ARG_STRING|POPT_ARGFLAG_STRIP, NULL, ARG_REGISTRY,   "registry to use" , "REGISTRY"},
   POPT_TABLEEND
 };
 
@@ -339,6 +340,7 @@ gst_mask_help (void)
   
   for (i = 0; i<GST_CAT_MAX_CATEGORY; i++) {
     if (gst_get_category_name(i)) {
+
 #if GST_DEBUG_COLOR
       g_print ("   0x%08x     %s%s     \033[%sm%s\033[00m\n", 1<<i, 
                (gst_info_get_categories() & (1<<i)?"(enabled)":"         "),
@@ -395,6 +397,9 @@ init_popt_callback (poptContext context, enum poptCallbackReason reason,
     case ARG_SCHEDULER:
       gst_scheduler_factory_set_default_name (arg);
       break;
+    case ARG_REGISTRY:
+      gst_registry_option_set (arg);
+      break;
     default:
       g_warning ("option %d not recognized", option->val);
       break;
index 85d1c60..96607cd 100644 (file)
--- a/gst/gst.h
+++ b/gst/gst.h
@@ -52,6 +52,7 @@
 #include <gst/gstevent.h>
 
 #include <gst/gstparse.h>
+#include <gst/gstregistry.h>
 #include <gst/gstextratypes.h>
 
 #ifdef __cplusplus
index 6d5c59a..761d923 100644 (file)
@@ -28,6 +28,7 @@
 #include "gst_private.h"
 #include "gstplugin.h"
 #include "gstversion.h"
+#include "gstregistry.h"
 #include "config.h"
 
 static GModule *main_module;
@@ -49,6 +50,8 @@ gboolean _gst_plugin_spew = FALSE;
 /* whether or not to warn if registry needs rebuild (gst-register sets
  * this to false.) */
 gboolean _gst_warn_old_registry = TRUE;
+/* whether or not the main app will be writing to the registry */
+gboolean _gst_init_registry_write = FALSE;
 
 #ifndef GST_DISABLE_REGISTRY
 static gboolean        plugin_times_older_than         (time_t regtime);
@@ -57,13 +60,14 @@ static time_t               get_time                        (const char * path);
 static void            gst_plugin_register_statics     (GModule *module);
 static GstPlugin*      gst_plugin_register_func        (GstPluginDesc *desc, GstPlugin *plugin, 
                                                         GModule *module);
-
 void
 _gst_plugin_initialize (void)
 {
   GList *gst_plugin_default_paths = NULL;
   struct stat stat_buf;
 #ifndef GST_DISABLE_REGISTRY
+  GstRegistryRead *gst_reg;
+  gchar *gst_registry;
   xmlDocPtr doc = NULL;
 #endif
 
@@ -86,8 +90,27 @@ _gst_plugin_initialize (void)
 #endif /* PLUGINS_USE_BUILDDIR */
 
 #ifndef GST_DISABLE_REGISTRY
-  if (stat (GST_CONFIG_DIR"/reg.xml", &stat_buf) == 0)
-    doc = xmlParseFile (GST_CONFIG_DIR"/reg.xml");
+  /* FIXME:
+   * we want to check both the global and the local registry here
+   * at first, we check if there is a local one, and if there is only use
+   * that one.
+   * Later, we would like to read the global one first, then have each
+   * plugin also in the local one override the global one.
+   */
+  
+  gst_reg = gst_registry_read_get ();
+  if (gst_reg->local_reg)
+    gst_registry = gst_reg->local_reg;
+  else
+    gst_registry = gst_reg->global_reg;
+  
+  if (_gst_init_registry_write)
+  {
+    /* delete it before writing */
+    unlink (gst_registry);
+  }
+  if (stat (gst_registry, &stat_buf) == 0)
+    doc = xmlParseFile (gst_registry);
   else
     doc = NULL;
 
@@ -95,9 +118,10 @@ _gst_plugin_initialize (void)
       !doc->xmlRootNode ||
       doc->xmlRootNode->name == 0 ||
       strcmp (doc->xmlRootNode->name, "GST-PluginRegistry") ||
-      !plugin_times_older_than(get_time(GST_CONFIG_DIR"/reg.xml"))) 
+      !plugin_times_older_than(get_time(gst_registry))) 
   {
-    if (_gst_warn_old_registry)
+    if (_gst_warn_old_registry &&
+       !plugin_times_older_than(get_time(gst_registry))) 
        g_warning ("gstplugin: registry needs rebuild: run gst-register\n");
     _gst_plugin_paths = g_list_concat (_gst_plugin_paths, gst_plugin_default_paths);
 #ifdef PLUGINS_USE_BUILDDIR
@@ -269,7 +293,7 @@ gst_plugin_load_recurse (gchar *directory, gchar *name)
 /**
  * gst_plugin_load_all:
  *
- * Load all plugins in the path.
+ * Load all plugins in the path (in the global GList* _gst_plugin_paths).
  */
 void
 gst_plugin_load_all (void)
@@ -277,6 +301,7 @@ gst_plugin_load_all (void)
   GList *path;
 
   path = _gst_plugin_paths;
+  if (path == NULL) { g_warning ("gst_plugin_load_all: path is NULL !"); }
   while (path != NULL) {
     GST_DEBUG (GST_CAT_PLUGIN_LOADING,"loading plugins from %s",(gchar *)path->data);
     gst_plugin_load_recurse(path->data,NULL);
@@ -718,6 +743,8 @@ gst_plugin_find_feature (const gchar *name, GType type)
  * @feature: feature to add
  *
  * Add feature to the list of those provided by the plugin.
+ * There is a separate namespace for each plugin feature type.
+ * See #gst_plugin_get_feature_list
  */
 void
 gst_plugin_add_feature (GstPlugin *plugin, GstPluginFeature *feature)
@@ -872,7 +899,7 @@ gst_plugin_load_thyself (xmlNodePtr parent)
     
     kinderen = kinderen->next;
   }
-  GST_INFO (GST_CAT_PLUGIN_LOADING, "added %d features ", featurecount);
+  GST_INFO (GST_CAT_PLUGIN_LOADING, " added %d features ", featurecount);
 }
 #endif /* GST_DISABLE_REGISTRY */
 
diff --git a/gst/gstregistry.c b/gst/gstregistry.c
new file mode 100644 (file)
index 0000000..0b13f7f
--- /dev/null
@@ -0,0 +1,130 @@
+/* GStreamer
+ * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
+ *                    2000 Wim Taymans <wtay@chello.be>
+ *
+ * gstregistry.c: handle registry
+ * 
+ * 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.
+ */
+
+#include <glib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "gstinfo.h"
+#include "gstregistry.h"
+
+static gchar *gst_registry_option = NULL;
+
+/* save the registry specified as an option */
+void
+gst_registry_option_set (const gchar *registry)
+{
+  gst_registry_option = g_strdup (registry);
+  return;
+}
+
+/* decide if we're going to use the global registry or not 
+ * - if root, use global
+ * - if not root :
+ *   - if user can write to global, use global
+ *   - else use local
+ */
+gboolean
+gst_registry_use_global (void)
+{
+  //struct stat reg_stat;
+  FILE *reg;
+  
+  if (getuid () == 0) return TRUE;     /* root always uses global */
+
+  /* check if we can write to the global registry somehow */
+  reg = fopen (GLOBAL_REGISTRY_FILE, "a");
+  if (reg == NULL) { return FALSE; }
+  else
+  {
+    /* we can write to it, do so for kicks */
+    fclose (reg);
+  }
+  
+  /* we can write to it, so now see if we can write in the dir as well */ 
+  if (access (GLOBAL_REGISTRY_DIR, W_OK) == 0) return TRUE;
+
+  return FALSE;
+}
+
+/* get the data that tells us where we can write the registry
+ * Allocate, fill in the GstRegistryWrite struct according to 
+ * current situation, and return it */
+GstRegistryWrite *
+gst_registry_write_get ()
+{
+  GstRegistryWrite *gst_reg = g_malloc (sizeof (GstRegistryWrite));
+  
+  /* if a registry is specified on command line, use that one */
+  if (gst_registry_option)
+  {
+    /* FIXME: maybe parse the dir from file ? */
+    gst_reg->dir = NULL;
+    gst_reg->file = gst_registry_option;
+    /* we cannot use the temp dir since the move needs to be on same device */
+    gst_reg->tmp_file = g_strdup_printf ("%s.tmp", gst_registry_option);
+  }
+  else
+  {
+    if (gst_registry_use_global ())
+    {
+      gst_reg->dir      = g_strdup (GLOBAL_REGISTRY_DIR);
+      gst_reg->file     = g_strdup (GLOBAL_REGISTRY_FILE);
+      gst_reg->tmp_file = g_strdup (GLOBAL_REGISTRY_FILE_TMP);
+    }
+    else
+    {
+      gchar *homedir = (gchar *) g_get_home_dir ();
+      
+      gst_reg->dir = g_strjoin ("/", homedir, LOCAL_REGISTRY_DIR, NULL);
+      gst_reg->file = g_strjoin ("/", homedir, LOCAL_REGISTRY_FILE, NULL);
+      gst_reg->tmp_file = g_strjoin ("/", homedir, LOCAL_REGISTRY_FILE_TMP, NULL);
+    }
+  } 
+  return gst_reg;
+}
+
+/* fill in the GstRegistryRead struct according to current situation */
+GstRegistryRead *
+gst_registry_read_get ()
+{
+  GstRegistryRead *gst_reg = g_malloc (sizeof (GstRegistryRead));
+  
+  /* if a registry is specified on command line, use that one */
+  if (gst_registry_option)
+  {
+    /* FIXME: maybe parse the dir from file ? */
+    gst_reg->local_reg = NULL;
+    gst_reg->global_reg = gst_registry_option;
+  }
+  else
+  {
+    gchar *homedir = (gchar *) g_get_home_dir ();
+    gst_reg->local_reg = g_strjoin ("/", homedir, LOCAL_REGISTRY_FILE, NULL);
+    gst_reg->global_reg = g_strdup (GLOBAL_REGISTRY_FILE);
+  }
+  return gst_reg;
+}
diff --git a/gst/gstregistry.h b/gst/gstregistry.h
new file mode 100644 (file)
index 0000000..f8fccca
--- /dev/null
@@ -0,0 +1,69 @@
+/* GStreamer
+ * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
+ *                    2000 Wim Taymans <wim.taymans@chello.be>
+ *
+ * gstregistry.h: Header for registry handling
+ *
+ * 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.
+ */
+
+
+#ifndef __GST_REGISTRY_H__
+#define __GST_REGISTRY_H__
+
+#define GLOBAL_REGISTRY_DIR      GST_CONFIG_DIR
+#define GLOBAL_REGISTRY_FILE     GLOBAL_REGISTRY_DIR"/reg.xml"
+#define GLOBAL_REGISTRY_FILE_TMP GLOBAL_REGISTRY_DIR"/.reg.xml.tmp"
+
+#define LOCAL_REGISTRY_DIR       ".gstreamer"
+#define LOCAL_REGISTRY_FILE      LOCAL_REGISTRY_DIR"/reg.xml"
+#define LOCAL_REGISTRY_FILE_TMP  LOCAL_REGISTRY_DIR"/.reg.xml.tmp"
+
+#define REGISTRY_DIR_PERMS (S_ISGID | \
+                            S_IRUSR | S_IWUSR | S_IXUSR | \
+                           S_IRGRP | S_IXGRP | \
+                           S_IROTH | S_IXOTH)
+#define REGISTRY_TMPFILE_PERMS (S_IRUSR | S_IWUSR)
+#define REGISTRY_FILE_PERMS (S_IRUSR | S_IWUSR | \
+                             S_IRGRP | S_IWGRP | \
+                            S_IROTH | S_IWOTH)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+typedef struct _GstRegistryWrite GstRegistryWrite;
+struct _GstRegistryWrite {
+  gchar *dir;
+  gchar *file;
+  gchar *tmp_file;
+};
+
+typedef struct _GstRegistryRead GstRegistryRead;
+struct _GstRegistryRead {
+  gchar *global_reg;
+  gchar *local_reg;
+};
+
+GstRegistryWrite       *gst_registry_write_get         (void);
+GstRegistryRead        *gst_registry_read_get          (void);
+void                   gst_registry_option_set         (const gchar *registry);
+  
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __GST_REGISTRY_H__ */
index 56bb937..435b114 100644 (file)
 
 #include "config.h"
 
-#define GLOBAL_REGISTRY_DIR      GST_CONFIG_DIR
-#define GLOBAL_REGISTRY_FILE     GLOBAL_REGISTRY_DIR"/reg.xml"
-#define GLOBAL_REGISTRY_FILE_TMP GLOBAL_REGISTRY_DIR"/.reg.xml.tmp"
-
-#define REGISTRY_DIR_PERMS (S_ISGID | \
-                           S_IRUSR | S_IWUSR | S_IXUSR | \
-                           S_IRGRP | S_IXGRP | \
-                           S_IROTH | S_IXOTH)
-#define REGISTRY_TMPFILE_PERMS (S_IRUSR | S_IWUSR)
-#define REGISTRY_FILE_PERMS (S_IRUSR | S_IWUSR | \
-                            S_IRGRP | S_IWGRP | \
-                            S_IROTH | S_IWOTH)
-
-
 extern gboolean _gst_plugin_spew;
 extern gboolean _gst_warn_old_registry;
+extern gboolean _gst_init_registry_write; /* we ask post_init to be delayed */
 
 static void error_perm() {
     g_print("\n(%s)\n"
@@ -184,6 +171,7 @@ int main(int argc,char *argv[])
 {
     xmlDocPtr doc;
     xmlNodePtr node;
+    GstRegistryWrite *gst_reg;
 
     /* Mode of the file we're saving the repository to; */
     mode_t newmode;
@@ -195,35 +183,65 @@ int main(int argc,char *argv[])
        newmode = REGISTRY_FILE_PERMS & ~ theumask;
     }
 
-    /* remove the old registry file first
-       If this fails, we simply ignore it since we'll overwrite it later
-        anyway. */
-    unlink(GLOBAL_REGISTRY_FILE);
-
     /* Init gst */
     _gst_plugin_spew = TRUE;
     _gst_warn_old_registry = FALSE;
     gst_info_enable_category(GST_CAT_PLUGIN_LOADING);
+    _gst_init_registry_write = TRUE; /* signal that we're writing registry */
     gst_init(&argc,&argv);
 
+    /* remove the old registry file first
+     * if a local is returned, then do that, else remove the global one
+     * If this fails, we simply ignore it since we'll overwrite it later
+     * anyway */
+    gst_reg = gst_registry_write_get ();
+    unlink (gst_reg->file);
+
+    GST_INFO (GST_CAT_PLUGIN_LOADING, " Writing to registry %s", gst_reg->file);
+
     /* Check args */
     if (argc != 1) usage(argv[0]);
 
-    /* Check that directory for config exists */
-    check_dir(GLOBAL_REGISTRY_DIR);
-    
     /* Read the plugins */
     doc = xmlNewDoc("1.0");
     node = xmlNewDocNode(doc, NULL, "GST-PluginRegistry", NULL);
     xmlDocSetRootElement (doc, node);
     gst_plugin_save_thyself(doc->xmlRootNode);
-
+    
+    if (gst_reg->dir)
+      check_dir(gst_reg->dir);
+    
     /* Save the registry to a tmp file. */
-    save_registry(GLOBAL_REGISTRY_FILE_TMP, &doc);
+    save_registry(gst_reg->tmp_file, &doc);
 
     /* Make the tmp file live. */
-    move_file(GLOBAL_REGISTRY_FILE_TMP, GLOBAL_REGISTRY_FILE, &newmode);
-
+    move_file(gst_reg->tmp_file, gst_reg->file, &newmode);
+#ifdef THOMAS
+    }
+    else
+    {
+      gchar *homedir;
+      gchar *reg_dir, *reg_file_tmp, *reg_file;
+
+      homedir = (gchar *) g_get_home_dir ();
+      reg_dir      = g_strjoin ("/", homedir, LOCAL_REGISTRY_DIR,      NULL);
+      reg_file_tmp = g_strjoin ("/", homedir, LOCAL_REGISTRY_FILE_TMP, NULL);
+      reg_file     = g_strjoin ("/", homedir, LOCAL_REGISTRY_FILE,     NULL);
+
+      /* try to make the dir; we'll find out if it fails anyway */
+      mkdir(reg_dir, S_IRWXU);
+      g_free(reg_dir);
+
+      /* Save the registry to a tmp file. */
+      save_registry(reg_file_tmp, &doc);
+
+      /* Make the tmp file live. */
+      move_file(reg_file_tmp, reg_file, &newmode);
+      g_free(reg_file_tmp);
+      g_free(reg_file);
+    }
+#endif
+    g_free (gst_reg);
     return(0);
 }