registry handling changes read up on it in docs/random/thomasvs/registry if interested net effect should be transpare...

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.
This commit is contained in:
Thomas Vander Stichele 2002-04-12 09:53:00 +00:00
parent 70f292f601
commit e00bcd6792
10 changed files with 306 additions and 39 deletions

View file

@ -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.

8
README
View file

@ -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.

View 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

View 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 \

View file

@ -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;

View file

@ -52,6 +52,7 @@
#include <gst/gstevent.h>
#include <gst/gstparse.h>
#include <gst/gstregistry.h>
#include <gst/gstextratypes.h>
#ifdef __cplusplus

View 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)

130
gst/gstregistry.c Normal file
View file

@ -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;
}

69
gst/gstregistry.h Normal file
View file

@ -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__ */

View file

@ -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);
}