summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog9
-rw-r--r--README8
-rw-r--r--docs/random/thomasvs/registry8
-rw-r--r--gst/Makefile.am2
-rw-r--r--gst/gst.c9
-rw-r--r--gst/gst.h1
-rw-r--r--gst/gstplugin.c41
-rw-r--r--gst/gstregistry.c130
-rw-r--r--gst/gstregistry.h69
-rw-r--r--tools/gst-register.c70
10 files changed, 307 insertions, 40 deletions
diff --git a/ChangeLog b/ChangeLog
index d314a4dd65..56f615d2d6 100644
--- 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 9e760c4fa1..99fd6aceb4 100644
--- 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.
+
diff --git a/docs/random/thomasvs/registry b/docs/random/thomasvs/registry
index dde3dbea4c..5287133767 100644
--- a/docs/random/thomasvs/registry
+++ b/docs/random/thomasvs/registry
@@ -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
diff --git a/gst/Makefile.am b/gst/Makefile.am
index 31c7a88f91..3ddcf3cdad 100644
--- a/gst/Makefile.am
+++ b/gst/Makefile.am
@@ -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 \
diff --git a/gst/gst.c b/gst/gst.c
index 138efa557a..42bbab1c82 100644
--- 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;
diff --git a/gst/gst.h b/gst/gst.h
index 85d1c60a80..96607cda41 100644
--- 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
diff --git a/gst/gstplugin.c b/gst/gstplugin.c
index 6d5c59a704..761d9239fa 100644
--- a/gst/gstplugin.c
+++ b/gst/gstplugin.c
@@ -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
index 0000000000..0b13f7fa9f
--- /dev/null
+++ b/gst/gstregistry.c
@@ -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
index 0000000000..f8fcccaf29
--- /dev/null
+++ b/gst/gstregistry.h
@@ -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__ */
diff --git a/tools/gst-register.c b/tools/gst-register.c
index 56bb937d28..435b1149b1 100644
--- a/tools/gst-register.c
+++ b/tools/gst-register.c
@@ -35,22 +35,9 @@
#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);
}