#include <stdio.h> /* sprintf() */
#include <string.h> /* strdup() */
-#include <vlc/input.h>
-
#ifdef HAVE_DIRENT_H
# include <dirent.h>
#endif
# endif
#endif
-#include "vlc_error.h"
+#include "misc/configuration.h"
#include "vlc_interface.h"
-#include "vlc_interaction.h"
-#include "intf_eject.h"
-
#include "vlc_playlist.h"
-#include "vlc_video.h"
-#include "video_output.h"
-#include "vout_synchro.h"
-#include "vlc_spu.h"
+#include "vlc_stream.h"
+#include "vlc_access.h"
+#include "vlc_demux.h"
-#include "audio_output.h"
-#include "aout_internal.h"
+#include "vlc_vout.h"
+#include "vlc_vout_synchro.h"
-#include "stream_output.h"
+#include "vlc_aout.h"
+
+#include "vlc_sout.h"
#include "vlc_httpd.h"
#include "vlc_acl.h"
#include "vlc_tls.h"
#include "vlc_url.h"
#include "iso_lang.h"
-#include "charset.h"
+#include "vlc_charset.h"
#include "vlc_block.h"
#include "vlc_strings.h"
#include "vlc_streaming.h"
+#include "modules.h"
+
#if defined( _MSC_VER ) && defined( UNDER_CE )
# include "modules_builtin_evc.h"
#elif defined( _MSC_VER )
#else
# include "modules_builtin.h"
#endif
-#include "network.h"
+#include "vlc_network.h"
#if defined( WIN32 ) || defined( UNDER_CE )
/* Avoid name collisions */
static module_t * AllocatePlugin( vlc_object_t *, char * );
#endif
static int AllocateBuiltinModule( vlc_object_t *, int ( * ) ( module_t * ) );
-static int DeleteModule ( module_t * );
+static int DeleteModule ( module_t *, vlc_bool_t );
#ifdef HAVE_DYNAMIC_PLUGINS
static void DupModule ( module_t * );
static void UndupModule ( module_t * );
#endif
#endif
+static void module_LoadMain( vlc_object_t *p_this );
+
/* Sub-version number
* (only used to avoid breakage in dev version when cache structure changes) */
*****************************************************************************/
void __module_InitBank( vlc_object_t *p_this )
{
- module_bank_t *p_bank;
+ module_bank_t *p_bank = NULL;
vlc_value_t lockval;
var_Create( p_this->p_libvlc_global, "libvlc", VLC_VAR_MUTEX );
var_Destroy( p_this->p_libvlc_global, "libvlc" );
p_bank = vlc_object_create( p_this, sizeof(module_bank_t) );
+ if( !p_bank )
+ return;
p_bank->psz_object_name = "module bank";
p_bank->i_usage = 1;
p_bank->i_cache = p_bank->i_loaded_cache = 0;
- p_bank->pp_cache = p_bank->pp_loaded_cache = 0;
+ p_bank->pp_cache = p_bank->pp_loaded_cache = NULL;
p_bank->b_cache = p_bank->b_cache_dirty =
p_bank->b_cache_delete = VLC_FALSE;
vlc_object_attach( p_bank, p_this->p_libvlc_global );
module_LoadMain( p_this );
-
- return;
}
/*****************************************************************************
*****************************************************************************/
void __module_EndBank( vlc_object_t *p_this )
{
- module_t * p_next;
+ module_t * p_next = NULL;
vlc_value_t lockval;
var_Create( p_this->p_libvlc_global, "libvlc", VLC_VAR_MUTEX );
if( p_bank->b_cache ) CacheSave( p_this );
while( p_bank->i_loaded_cache-- )
{
- free( p_bank->pp_loaded_cache[p_bank->i_loaded_cache]->psz_file );
- free( p_bank->pp_loaded_cache[p_bank->i_loaded_cache] );
+ if( p_bank->pp_loaded_cache[p_bank->i_loaded_cache] )
+ {
+ DeleteModule( p_bank->pp_loaded_cache[p_bank->i_loaded_cache]->p_module, p_bank->pp_loaded_cache[p_bank->i_loaded_cache]->b_used );
+ free( p_bank->pp_loaded_cache[p_bank->i_loaded_cache]->psz_file );
+ free( p_bank->pp_loaded_cache[p_bank->i_loaded_cache] );
+ p_bank->pp_loaded_cache[p_bank->i_loaded_cache] = NULL;
+ }
}
if( p_bank->pp_loaded_cache )
+ {
free( p_bank->pp_loaded_cache );
-
+ p_bank->pp_loaded_cache = NULL;
+ }
while( p_bank->i_cache-- )
{
free( p_bank->pp_cache[p_bank->i_cache]->psz_file );
free( p_bank->pp_cache[p_bank->i_cache] );
+ p_bank->pp_cache[p_bank->i_cache] = NULL;
}
if( p_bank->pp_cache )
+ {
free( p_bank->pp_cache );
+ p_bank->pp_cache = NULL;
+ }
#undef p_bank
#endif
{
p_next = (module_t *)p_this->p_libvlc_global->p_module_bank->pp_children[0];
- if( DeleteModule( p_next ) )
+ if( DeleteModule( p_next, VLC_TRUE ) )
{
/* Module deletion failed */
msg_Err( p_this, "module \"%s\" can't be removed, trying harder",
* as another module, and for instance the configuration options of main will
* be available in the module bank structure just as for every other module.
*****************************************************************************/
-void __module_LoadMain( vlc_object_t *p_this )
+static void module_LoadMain( vlc_object_t *p_this )
{
vlc_value_t lockval;
module_t *p_module;
int i_shortcuts = 0;
- char *psz_shortcuts = NULL, *psz_var = NULL;
+ char *psz_shortcuts = NULL, *psz_var = NULL, *psz_alias = NULL;
vlc_bool_t b_force_backup = p_this->b_force;
if( i_shortcuts > 0 )
{
vlc_bool_t b_trash;
- int i_dummy, i_short = i_shortcuts;
- char *psz_name = psz_shortcuts;
+ const char *psz_name = psz_shortcuts;
/* Let's drop modules with a <= 0 score (unless they are
* explicitly requested) */
b_trash = p_module->i_score <= 0;
- while( i_short > 0 )
+ for( unsigned i_short = i_shortcuts; i_short > 0; i_short-- )
{
- for( i_dummy = 0; p_module->pp_shortcuts[i_dummy]; i_dummy++ )
+ for( unsigned i = 0; p_module->pp_shortcuts[i]; i++ )
{
- if( !strcasecmp( psz_name,
- p_module->pp_shortcuts[i_dummy] ) )
+ char *c;
+ if( ( c = strchr( psz_name, '@' ) )
+ ? !strncasecmp( psz_name, p_module->pp_shortcuts[i],
+ c-psz_name )
+ : !strcasecmp( psz_name, p_module->pp_shortcuts[i] ) )
{
/* Found it */
- b_trash = VLC_FALSE;
+ if( c && c[1] )
+ psz_alias = c+1;
i_shortcut_bonus = i_short * 10000;
- break;
+ goto found_shortcut;
}
}
- if( i_shortcut_bonus )
- {
- /* We found it... remember ? */
- break;
- }
-
/* Go to the next shortcut... This is so lame! */
- while( *psz_name )
- {
- psz_name++;
- }
- psz_name++;
- i_short--;
+ psz_name += strlen( psz_name ) + 1;
}
/* If we are in "strict" mode and we couldn't
* find the module in the list of provided shortcuts,
* then kick the bastard out of here!!! */
- if( i_short == 0 && b_strict )
- {
- b_trash = VLC_TRUE;
- }
-
- if( b_trash )
- {
+ if( b_strict )
continue;
- }
}
/* If we didn't require a shortcut, trash <= 0 scored plugins */
else if( p_module->i_score <= 0 )
continue;
}
+found_shortcut:
+
/* Special case: test if we requested a particular intf plugin */
if( !i_shortcuts && p_module->psz_program
&& !strcmp( psz_capability, "interface" )
{
#ifdef HAVE_DYNAMIC_PLUGINS
/* Make sure the module is loaded in mem */
- module_t *p_module = p_tmp->p_module->b_submodule ?
- (module_t *)p_tmp->p_module->p_parent : p_tmp->p_module;
+ module_t *p_module = p_tmp->p_module;
+ if( p_module->b_submodule )
+ p_module = (module_t *)p_module->p_parent;
+
if( !p_module->b_builtin && !p_module->b_loaded )
{
module_t *p_new_module =
{
CacheMerge( p_this, p_module, p_new_module );
vlc_object_attach( p_new_module, p_module );
- DeleteModule( p_new_module );
+ DeleteModule( p_new_module, VLC_TRUE );
}
}
#endif
{
msg_Err( p_this, "no %s module matched \"%s\"",
psz_capability, (psz_name && *psz_name) ? psz_name : "any" );
+
+ msg_StackSet( VLC_EGENERIC, "no %s module matched \"%s\"",
+ psz_capability, (psz_name && *psz_name) ? psz_name : "any" );
}
}
else if( psz_name != NULL && *psz_name )
msg_Warn( p_this, "no %s module matching \"%s\" could be loaded",
psz_capability, (psz_name && *psz_name) ? psz_name : "any" );
}
+ else
+ msg_StackSet( VLC_EGENERIC, "no suitable %s module", psz_capability );
+
+ if( psz_alias && !p_this->psz_object_name )
+ /* This assumes that p_this is the object which will be using the
+ * module. That's not always the case ... but it is in most cases.
+ */
+ p_this->psz_object_name = strdup( psz_alias );
if( psz_shortcuts )
{
return;
}
+/*****************************************************************************
+ * module_Exists: tell if a module exists.
+ *****************************************************************************
+ * This function is a boolean function that tells if a module exist or not.
+ *****************************************************************************/
+
+vlc_bool_t __module_Exists( vlc_object_t *p_this, const char * psz_name )
+{
+ vlc_list_t *p_list;
+ int i;
+ p_list = vlc_list_find( p_this, VLC_OBJECT_MODULE, FIND_ANYWHERE );
+ for( i = 0 ; i < p_list->i_count; i++)
+ {
+ if (!strcmp(
+ ((module_t *) p_list->p_values[i].p_object)->psz_shortname ,
+ psz_name ) )
+ {
+ /* We can release the list, and return yes */
+ vlc_list_release( p_list ); return VLC_TRUE;
+ }
+ }
+ vlc_list_release( p_list ); return VLC_FALSE;
+}
+
+
/*****************************************************************************
* Following functions are local.
*****************************************************************************/
static void AllocatePluginDir( vlc_object_t *p_this, const char *psz_dir,
int i_maxdepth )
{
+/* FIXME: Needs to be ported to wide char on ALL Windows builds */
+#ifdef WIN32
+# undef opendir
+# undef closedir
+# undef readdir
+#endif
#if defined( UNDER_CE ) || defined( _MSC_VER )
#ifdef UNDER_CE
wchar_t psz_wpath[MAX_PATH + 256];
static int AllocatePluginFile( vlc_object_t * p_this, char * psz_file,
int64_t i_file_time, int64_t i_file_size )
{
- module_t * p_module;
+ module_t * p_module = NULL;
module_cache_t *p_cache_entry = NULL;
/*
}
else
{
- module_config_t *p_item;
+ module_config_t *p_item = NULL, *p_end = NULL;
p_module = p_cache_entry->p_module;
p_module->b_loaded = VLC_FALSE;
/* For now we force loading if the module's config contains
* callbacks or actions.
* Could be optimized by adding an API call.*/
- for( p_item = p_module->p_config;
- p_item->i_type != CONFIG_HINT_END; p_item++ )
+ for( p_item = p_module->p_config, p_end = p_item + p_module->confsize;
+ p_item < p_end; p_item++ )
{
if( p_item->pf_callback || p_item->i_action )
+ {
p_module = AllocatePlugin( p_this, psz_file );
+ break;
+ }
}
+ if( p_module == p_cache_entry->p_module )
+ p_cache_entry->b_used = VLC_TRUE;
}
}
p_module->psz_object_name, p_module->psz_longname ); */
vlc_object_attach( p_module, p_this->p_libvlc_global->p_module_bank );
- }
- if( !p_this->p_libvlc_global->p_module_bank->b_cache ) return 0;
+ if( !p_this->p_libvlc_global->p_module_bank->b_cache )
+ return 0;
- /* Add entry to cache */
+ /* Add entry to cache */
#define p_bank p_this->p_libvlc_global->p_module_bank
- p_bank->pp_cache =
- realloc( p_bank->pp_cache, (p_bank->i_cache + 1) * sizeof(void *) );
- p_bank->pp_cache[p_bank->i_cache] = malloc( sizeof(module_cache_t) );
- p_bank->pp_cache[p_bank->i_cache]->psz_file = strdup( psz_file );
- p_bank->pp_cache[p_bank->i_cache]->i_time = i_file_time;
- p_bank->pp_cache[p_bank->i_cache]->i_size = i_file_size;
- p_bank->pp_cache[p_bank->i_cache]->b_junk = p_module ? 0 : 1;
- p_bank->pp_cache[p_bank->i_cache]->p_module = p_module;
- p_bank->i_cache++;
+ p_bank->pp_cache =
+ realloc( p_bank->pp_cache, (p_bank->i_cache + 1) * sizeof(void *) );
+ p_bank->pp_cache[p_bank->i_cache] = malloc( sizeof(module_cache_t) );
+ if( !p_bank->pp_cache[p_bank->i_cache] )
+ return -1;
+ p_bank->pp_cache[p_bank->i_cache]->psz_file = strdup( psz_file );
+ p_bank->pp_cache[p_bank->i_cache]->i_time = i_file_time;
+ p_bank->pp_cache[p_bank->i_cache]->i_size = i_file_size;
+ p_bank->pp_cache[p_bank->i_cache]->b_junk = p_module ? 0 : 1;
+ p_bank->pp_cache[p_bank->i_cache]->b_used = VLC_TRUE;
+ p_bank->pp_cache[p_bank->i_cache]->p_module = p_module;
+ p_bank->i_cache++;
+ }
return p_module ? 0 : -1;
}
*****************************************************************************/
static module_t * AllocatePlugin( vlc_object_t * p_this, char * psz_file )
{
- module_t * p_module;
+ module_t * p_module = NULL;
module_handle_t handle;
- if( LoadModule( p_this, psz_file, &handle ) ) return NULL;
+ if( LoadModule( p_this, psz_file, &handle ) )
+ return NULL;
/* Now that we have successfully loaded the module, we can
* allocate a structure for it */
*****************************************************************************
* This function can only be called if the module isn't being used.
*****************************************************************************/
-static int DeleteModule( module_t * p_module )
+static int DeleteModule( module_t * p_module, vlc_bool_t b_detach )
{
- vlc_object_detach( p_module );
+ if( !p_module ) return VLC_EGENERIC;
+ if( b_detach )
+ vlc_object_detach( p_module );
/* We free the structures that we strdup()ed in Allocate*Module(). */
#ifdef HAVE_DYNAMIC_PLUGINS
config_Free( p_module );
vlc_object_destroy( p_module );
-
+ p_module = NULL;
return 0;
}
#define LOAD_IMMEDIATE(a) \
if( fread( (void *)&a, sizeof(char), sizeof(a), file ) != sizeof(a) ) goto error
#define LOAD_STRING(a) \
- { if( fread( &i_size, sizeof(char), sizeof(i_size), file ) \
- != sizeof(i_size) ) goto error; \
- if( i_size && i_size < 16384 ) { \
- a = malloc( i_size ); \
- if( fread( (void *)a, sizeof(char), i_size, file ) != (size_t)i_size ) \
- goto error; \
- if( a[i_size-1] ) { \
- free( (void *)a ); a = 0; \
- goto error; } \
- } else a = 0; \
- } while(0)
+{ \
+ a = NULL; \
+ if( ( fread( &i_size, sizeof(i_size), 1, file ) != 1 ) \
+ || ( i_size > 16384 ) ) \
+ goto error; \
+ if( i_size ) { \
+ char *psz = malloc( i_size ); \
+ if( fread( psz, i_size, 1, file ) != 1 ) { \
+ free( psz ); \
+ goto error; \
+ } \
+ if( psz[i_size-1] ) { \
+ free( psz ); \
+ goto error; \
+ } \
+ a = psz; \
+ } \
+}
for( i = 0; i < i_cache; i++ )
{
- int16_t i_size;
+ uint16_t i_size;
int i_submodules;
pp_cache[i] = malloc( sizeof(module_cache_t) );
LOAD_IMMEDIATE( pp_cache[i]->i_time );
LOAD_IMMEDIATE( pp_cache[i]->i_size );
LOAD_IMMEDIATE( pp_cache[i]->b_junk );
+ pp_cache[i]->b_used = VLC_FALSE;
if( pp_cache[i]->b_junk ) continue;
int CacheLoadConfig( module_t *p_module, FILE *file )
{
- int i, j, i_lines;
- int16_t i_size;
+ uint32_t i_lines;
+ uint16_t i_size;
/* Calculate the structure length */
LOAD_IMMEDIATE( p_module->i_config_items );
LOAD_IMMEDIATE( i_lines );
/* Allocate memory */
- p_module->p_config =
- (module_config_t *)malloc( sizeof(module_config_t) * (i_lines + 1));
- if( p_module->p_config == NULL )
+ if (i_lines)
{
- msg_Err( p_module, "config error: can't duplicate p_config" );
- return VLC_ENOMEM;
+ p_module->p_config =
+ (module_config_t *)calloc( i_lines, sizeof(module_config_t) );
+ if( p_module->p_config == NULL )
+ {
+ p_module->confsize = 0;
+ msg_Err( p_module, "config error: can't duplicate p_config" );
+ return VLC_ENOMEM;
+ }
}
+ p_module->confsize = i_lines;
/* Do the duplication job */
- for( i = 0; i < i_lines ; i++ )
+ for (size_t i = 0; i < i_lines; i++ )
{
LOAD_IMMEDIATE( p_module->p_config[i] );
{
if( p_module->p_config[i].ppsz_list )
{
+ int j;
p_module->p_config[i].ppsz_list =
malloc( (p_module->p_config[i].i_list+1) * sizeof(char *));
if( p_module->p_config[i].ppsz_list )
}
if( p_module->p_config[i].ppsz_list_text )
{
+ int j;
p_module->p_config[i].ppsz_list_text =
malloc( (p_module->p_config[i].i_list+1) * sizeof(char *));
if( p_module->p_config[i].ppsz_list_text )
malloc( (p_module->p_config[i].i_list + 1) * sizeof(int) );
if( p_module->p_config[i].pi_list )
{
- for( j = 0; j < p_module->p_config[i].i_list; j++ )
+ for (int j = 0; j < p_module->p_config[i].i_list; j++)
LOAD_IMMEDIATE( p_module->p_config[i].pi_list[j] );
}
}
p_module->p_config[i].ppsz_action_text =
malloc( p_module->p_config[i].i_action * sizeof(char *) );
- for( j = 0; j < p_module->p_config[i].i_action; j++ )
+ for (int j = 0; j < p_module->p_config[i].i_action; j++)
{
p_module->p_config[i].ppf_action[j] = 0;
LOAD_STRING( p_module->p_config[i].ppsz_action_text[j] );
LOAD_IMMEDIATE( p_module->p_config[i].pf_callback );
}
- p_module->p_config[i].i_type = CONFIG_HINT_END;
-
return VLC_SUCCESS;
error:
for( i = 0; i < i_cache; i++ )
{
- int16_t i_size;
- int32_t i_submodule;
+ uint16_t i_size;
+ uint32_t i_submodule;
/* Save common info */
SAVE_STRING( pp_cache[i]->psz_file );
i_submodule = pp_cache[i]->p_module->i_children;
SAVE_IMMEDIATE( i_submodule );
- for( i_submodule = 0; i_submodule < pp_cache[i]->p_module->i_children;
+ for( i_submodule = 0;
+ i_submodule < (unsigned)pp_cache[i]->p_module->i_children;
i_submodule++ )
{
module_t *p_module =
void CacheSaveConfig( module_t *p_module, FILE *file )
{
- int i, j, i_lines = 0;
- module_config_t *p_item;
- int16_t i_size;
+ uint32_t i_lines = p_module->confsize;
+ uint16_t i_size;
SAVE_IMMEDIATE( p_module->i_config_items );
SAVE_IMMEDIATE( p_module->i_bool_items );
-
- for( p_item = p_module->p_config; p_item->i_type != CONFIG_HINT_END;
- p_item++ ) i_lines++;
-
SAVE_IMMEDIATE( i_lines );
- for( i = 0; i < i_lines ; i++ )
+ for (size_t i = 0; i < i_lines ; i++)
{
SAVE_IMMEDIATE( p_module->p_config[i] );
{
if( p_module->p_config[i].ppsz_list )
{
- for( j = 0; j < p_module->p_config[i].i_list; j++ )
+ for (int j = 0; j < p_module->p_config[i].i_list; j++)
SAVE_STRING( p_module->p_config[i].ppsz_list[j] );
}
if( p_module->p_config[i].ppsz_list_text )
{
- for( j = 0; j < p_module->p_config[i].i_list; j++ )
+ for (int j = 0; j < p_module->p_config[i].i_list; j++)
SAVE_STRING( p_module->p_config[i].ppsz_list_text[j] );
}
if( p_module->p_config[i].pi_list )
{
- for( j = 0; j < p_module->p_config[i].i_list; j++ )
+ for (int j = 0; j < p_module->p_config[i].i_list; j++)
SAVE_IMMEDIATE( p_module->p_config[i].pi_list[j] );
}
}
- for( j = 0; j < p_module->p_config[i].i_action; j++ )
+ for (int j = 0; j < p_module->p_config[i].i_action; j++)
SAVE_STRING( p_module->p_config[i].ppsz_action_text[j] );
SAVE_IMMEDIATE( p_module->p_config[i].pf_callback );
}
/*****************************************************************************
- * FindPluginCache: finds the cache entry corresponding to a file
+ * CacheFind: finds the cache entry corresponding to a file
*****************************************************************************/
static module_cache_t *CacheFind( vlc_object_t *p_this, char *psz_file,
int64_t i_time, int64_t i_size )