+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.
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.
+
- 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
gsttype.c \
$(GST_TYPEFIND_SRC) \
gstutils.c \
+ gstregistry.c \
gsttimecache.c \
$(GST_PARSE_SRC) \
$(GSTARCH_SRCS) \
gsttype.h \
gsttypefind.h \
gstutils.h \
+ gstregistry.h \
gsttimecache.h \
gstparse.h \
gstversion.h \
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);
ARG_PLUGIN_SPEW,
ARG_PLUGIN_PATH,
ARG_PLUGIN_LOAD,
- ARG_SCHEDULER
+ ARG_SCHEDULER,
+ ARG_REGISTRY
};
#ifndef NUL
{"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
};
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)":" "),
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;
#include <gst/gstevent.h>
#include <gst/gstparse.h>
+#include <gst/gstregistry.h>
#include <gst/gstextratypes.h>
#ifdef __cplusplus
#include "gst_private.h"
#include "gstplugin.h"
#include "gstversion.h"
+#include "gstregistry.h"
#include "config.h"
static GModule *main_module;
/* 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);
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
#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;
!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
/**
* 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)
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);
* @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)
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 */
--- /dev/null
+/* 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;
+}
--- /dev/null
+/* 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__ */
#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"
{
xmlDocPtr doc;
xmlNodePtr node;
+ GstRegistryWrite *gst_reg;
/* Mode of the file we're saving the repository to; */
mode_t newmode;
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);
}