~ubuntu-branches/ubuntu/maverick/vlc/maverick

« back to all changes in this revision

Viewing changes to src/modules/modules.c

  • Committer: Bazaar Package Importer
  • Author(s): Reinhard Tartler
  • Date: 2008-09-17 21:56:14 UTC
  • mfrom: (1.1.17 upstream)
  • Revision ID: james.westby@ubuntu.com-20080917215614-tj0vx8xzd57e52t8
Tags: 0.9.2-1ubuntu1
* New Upstream Release, exception granted by
    - dktrkranz, norsetto, Hobbsee (via irc). LP: #270404

Changes done in ubuntu:

* add libxul-dev to build-depends
* make sure that vlc is build against libxul in configure. This doesn't
  change anything in the package, but makes it more robust if building
  in an 'unclean' chroot or when modifying the package.
* debian/control: make Vcs-* fields point to the motumedia branch
* add libx264-dev and libass-dev to build-depends
  LP: #210354, #199870
* actually enable libass support by passing --enable-libass to configure
* enable libdca: add libdca-dev to build depends and --enable-libdca
* install the x264 plugin.

Changes already in the pkg-multimedia branch in debian:

* don't install usr/share/vlc/mozilla in debian/mozilla-plugin-vlc.install  
* new upstream .desktop file now registers flash video mimetype LP: #261567
* add Xb-Npp-Applications to mozilla-plugin-vlc
* remove duplicate entries in debian/vlc-nox.install

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*****************************************************************************
 
2
 * modules.c : Builtin and plugin modules management functions
 
3
 *****************************************************************************
 
4
 * Copyright (C) 2001-2007 the VideoLAN team
 
5
 * $Id: 9ff601b3a6aa5916a564b14758292fdc99d412df $
 
6
 *
 
7
 * Authors: Sam Hocevar <sam@zoy.org>
 
8
 *          Ethan C. Baldridge <BaldridgeE@cadmus.com>
 
9
 *          Hans-Peter Jansen <hpj@urpla.net>
 
10
 *          Gildas Bazin <gbazin@videolan.org>
 
11
 *
 
12
 * This program is free software; you can redistribute it and/or modify
 
13
 * it under the terms of the GNU General Public License as published by
 
14
 * the Free Software Foundation; either version 2 of the License, or
 
15
 * (at your option) any later version.
 
16
 *
 
17
 * This program is distributed in the hope that it will be useful,
 
18
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
19
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
20
 * GNU General Public License for more details.
 
21
 *
 
22
 * You should have received a copy of the GNU General Public License
 
23
 * along with this program; if not, write to the Free Software
 
24
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
 
25
 *****************************************************************************/
 
26
 
 
27
#ifdef HAVE_CONFIG_H
 
28
# include "config.h"
 
29
#endif
 
30
 
 
31
#include <vlc_common.h>
 
32
#include <vlc_plugin.h>
 
33
#include "libvlc.h"
 
34
 
 
35
/* Some faulty libcs have a broken struct dirent when _FILE_OFFSET_BITS
 
36
 * is set to 64. Don't try to be cleverer. */
 
37
#ifdef _FILE_OFFSET_BITS
 
38
#undef _FILE_OFFSET_BITS
 
39
#endif
 
40
 
 
41
#include <stdlib.h>                                      /* free(), strtol() */
 
42
#include <stdio.h>                                              /* sprintf() */
 
43
#include <string.h>                                              /* strdup() */
 
44
#include <assert.h>
 
45
 
 
46
#ifdef HAVE_DIRENT_H
 
47
#   include <dirent.h>
 
48
#endif
 
49
 
 
50
#ifdef HAVE_SYS_TYPES_H
 
51
#   include <sys/types.h>
 
52
#endif
 
53
#ifdef HAVE_SYS_STAT_H
 
54
#   include <sys/stat.h>
 
55
#endif
 
56
#ifdef HAVE_UNISTD_H
 
57
#   include <unistd.h>
 
58
#endif
 
59
 
 
60
#if !defined(HAVE_DYNAMIC_PLUGINS)
 
61
    /* no support for plugins */
 
62
#elif defined(HAVE_DL_DYLD)
 
63
#   if defined(HAVE_MACH_O_DYLD_H)
 
64
#       include <mach-o/dyld.h>
 
65
#   endif
 
66
#elif defined(HAVE_DL_BEOS)
 
67
#   if defined(HAVE_IMAGE_H)
 
68
#       include <image.h>
 
69
#   endif
 
70
#elif defined(HAVE_DL_WINDOWS)
 
71
#   include <windows.h>
 
72
#elif defined(HAVE_DL_DLOPEN)
 
73
#   if defined(HAVE_DLFCN_H) /* Linux, BSD, Hurd */
 
74
#       include <dlfcn.h>
 
75
#   endif
 
76
#   if defined(HAVE_SYS_DL_H)
 
77
#       include <sys/dl.h>
 
78
#   endif
 
79
#elif defined(HAVE_DL_SHL_LOAD)
 
80
#   if defined(HAVE_DL_H)
 
81
#       include <dl.h>
 
82
#   endif
 
83
#endif
 
84
 
 
85
#include "config/configuration.h"
 
86
 
 
87
#include "vlc_charset.h"
 
88
#include "vlc_arrays.h"
 
89
 
 
90
#include "modules/modules.h"
 
91
#include "modules/builtin.h"
 
92
 
 
93
/*****************************************************************************
 
94
 * Local prototypes
 
95
 *****************************************************************************/
 
96
#ifdef HAVE_DYNAMIC_PLUGINS
 
97
static void AllocateAllPlugins  ( vlc_object_t * );
 
98
static void AllocatePluginDir   ( vlc_object_t *, const char *, int );
 
99
static int  AllocatePluginFile  ( vlc_object_t *, char *, int64_t, int64_t );
 
100
static module_t * AllocatePlugin( vlc_object_t *, char * );
 
101
#endif
 
102
static int  AllocateBuiltinModule( vlc_object_t *, int ( * ) ( module_t * ) );
 
103
static void DeleteModule ( module_t *, bool );
 
104
#ifdef HAVE_DYNAMIC_PLUGINS
 
105
static void   DupModule        ( module_t * );
 
106
static void   UndupModule      ( module_t * );
 
107
#endif
 
108
 
 
109
/**
 
110
 * Init bank
 
111
 *
 
112
 * Creates a module bank structure which will be filled later
 
113
 * on with all the modules found.
 
114
 * \param p_this vlc object structure
 
115
 * \return nothing
 
116
 */
 
117
void __module_InitBank( vlc_object_t *p_this )
 
118
{
 
119
    module_bank_t *p_bank = NULL;
 
120
    libvlc_global_data_t *p_libvlc_global = vlc_global();
 
121
 
 
122
    vlc_mutex_t *lock = var_AcquireMutex( "libvlc" );
 
123
 
 
124
    if( p_libvlc_global->p_module_bank == NULL )
 
125
    {
 
126
        p_bank = vlc_custom_create( p_this, sizeof(module_bank_t),
 
127
                                    VLC_OBJECT_GENERIC, "module bank");
 
128
        p_bank->i_usage = 1;
 
129
        p_bank->i_cache = p_bank->i_loaded_cache = 0;
 
130
        p_bank->pp_cache = p_bank->pp_loaded_cache = NULL;
 
131
        p_bank->b_cache = p_bank->b_cache_dirty =
 
132
        p_bank->b_cache_delete = false;
 
133
 
 
134
        /* Everything worked, attach the object */
 
135
        p_libvlc_global->p_module_bank = p_bank;
 
136
        vlc_object_attach( p_bank, p_libvlc_global );
 
137
 
 
138
        /* Fills the module bank structure with the main module infos.
 
139
         * This is very useful as it will allow us to consider the main
 
140
         * library just as another module, and for instance the configuration
 
141
         * options of main will be available in the module bank structure just
 
142
         * as for every other module. */
 
143
        AllocateBuiltinModule( p_this, vlc_entry__main );
 
144
    }
 
145
    else
 
146
        p_libvlc_global->p_module_bank->i_usage++;
 
147
 
 
148
    vlc_mutex_unlock( lock );
 
149
}
 
150
 
 
151
 
 
152
/**
 
153
 * End bank
 
154
 *
 
155
 * Unloads all unused plugin modules and empties the module
 
156
 * bank in case of success.
 
157
 * \param p_this vlc object structure
 
158
 * \return nothing
 
159
 */
 
160
void __module_EndBank( vlc_object_t *p_this )
 
161
{
 
162
    module_t * p_next = NULL;
 
163
    libvlc_global_data_t *p_libvlc_global = vlc_global();
 
164
 
 
165
    vlc_mutex_t *lock = var_AcquireMutex( "libvlc" );
 
166
    if( !p_libvlc_global->p_module_bank )
 
167
    {
 
168
        vlc_mutex_unlock( lock );
 
169
        return;
 
170
    }
 
171
    if( --p_libvlc_global->p_module_bank->i_usage )
 
172
    {
 
173
        vlc_mutex_unlock( lock );
 
174
        return;
 
175
    }
 
176
    vlc_mutex_unlock( lock );
 
177
 
 
178
    /* Save the configuration */
 
179
    config_AutoSaveConfigFile( p_this );
 
180
 
 
181
#ifdef HAVE_DYNAMIC_PLUGINS
 
182
# define p_bank p_libvlc_global->p_module_bank
 
183
    if( p_bank->b_cache ) CacheSave( p_this );
 
184
    while( p_bank->i_loaded_cache-- )
 
185
    {
 
186
        if( p_bank->pp_loaded_cache[p_bank->i_loaded_cache] )
 
187
        {
 
188
            DeleteModule(
 
189
                    p_bank->pp_loaded_cache[p_bank->i_loaded_cache]->p_module,
 
190
                    p_bank->pp_loaded_cache[p_bank->i_loaded_cache]->b_used );
 
191
            free( p_bank->pp_loaded_cache[p_bank->i_loaded_cache]->psz_file );
 
192
            free( p_bank->pp_loaded_cache[p_bank->i_loaded_cache] );
 
193
            p_bank->pp_loaded_cache[p_bank->i_loaded_cache] = NULL;
 
194
        }
 
195
    }
 
196
    if( p_bank->pp_loaded_cache )
 
197
    {
 
198
        free( p_bank->pp_loaded_cache );
 
199
        p_bank->pp_loaded_cache = NULL;
 
200
    }
 
201
    while( p_bank->i_cache-- )
 
202
    {
 
203
        free( p_bank->pp_cache[p_bank->i_cache]->psz_file );
 
204
        free( p_bank->pp_cache[p_bank->i_cache] );
 
205
        p_bank->pp_cache[p_bank->i_cache] = NULL;
 
206
    }
 
207
    if( p_bank->pp_cache )
 
208
    {
 
209
        free( p_bank->pp_cache );
 
210
        p_bank->pp_cache = NULL;
 
211
    }
 
212
# undef p_bank
 
213
#endif
 
214
 
 
215
    vlc_object_detach( p_libvlc_global->p_module_bank );
 
216
 
 
217
    while( vlc_internals( p_libvlc_global->p_module_bank )->i_children )
 
218
    {
 
219
        p_next = (module_t *)vlc_internals( p_libvlc_global->p_module_bank )->pp_children[0];
 
220
        DeleteModule( p_next, true );
 
221
    }
 
222
 
 
223
    vlc_object_release( p_libvlc_global->p_module_bank );
 
224
    p_libvlc_global->p_module_bank = NULL;
 
225
}
 
226
 
 
227
/**
 
228
 * Load all modules which we built with.
 
229
 *
 
230
 * Fills the module bank structure with the builtin modules.
 
231
 * \param p_this vlc object structure
 
232
 * \return nothing
 
233
 */
 
234
void __module_LoadBuiltins( vlc_object_t * p_this )
 
235
{
 
236
    libvlc_global_data_t *p_libvlc_global = vlc_global();
 
237
 
 
238
    vlc_mutex_t *lock = var_AcquireMutex( "libvlc" );
 
239
    if( p_libvlc_global->p_module_bank->b_builtins )
 
240
    {
 
241
        vlc_mutex_unlock( lock );
 
242
        return;
 
243
    }
 
244
    p_libvlc_global->p_module_bank->b_builtins = true;
 
245
    vlc_mutex_unlock( lock );
 
246
 
 
247
    msg_Dbg( p_this, "checking builtin modules" );
 
248
    ALLOCATE_ALL_BUILTINS();
 
249
}
 
250
 
 
251
/**
 
252
 * Load all plugins
 
253
 *
 
254
 * Load all plugin modules we can find.
 
255
 * Fills the module bank structure with the plugin modules.
 
256
 * \param p_this vlc object structure
 
257
 * \return nothing
 
258
 */
 
259
void __module_LoadPlugins( vlc_object_t * p_this )
 
260
{
 
261
#ifdef HAVE_DYNAMIC_PLUGINS
 
262
    libvlc_global_data_t *p_libvlc_global = vlc_global();
 
263
 
 
264
    vlc_mutex_t *lock = var_AcquireMutex( "libvlc" );
 
265
    if( p_libvlc_global->p_module_bank->b_plugins )
 
266
    {
 
267
        vlc_mutex_unlock( lock );
 
268
        return;
 
269
    }
 
270
    p_libvlc_global->p_module_bank->b_plugins = true;
 
271
    vlc_mutex_unlock( lock );
 
272
 
 
273
    msg_Dbg( p_this, "checking plugin modules" );
 
274
 
 
275
    if( config_GetInt( p_this, "plugins-cache" ) )
 
276
        p_libvlc_global->p_module_bank->b_cache = true;
 
277
 
 
278
    if( p_libvlc_global->p_module_bank->b_cache ||
 
279
        p_libvlc_global->p_module_bank->b_cache_delete ) CacheLoad( p_this );
 
280
 
 
281
    AllocateAllPlugins( p_this );
 
282
#endif
 
283
}
 
284
 
 
285
/**
 
286
 * Checks whether a module implements a capability.
 
287
 *
 
288
 * \param m the module
 
289
 * \param cap the capability to check
 
290
 * \return TRUE if the module have the capability
 
291
 */
 
292
bool module_IsCapable( const module_t *m, const char *cap )
 
293
{
 
294
    return !strcmp( m->psz_capability, cap );
 
295
}
 
296
 
 
297
/**
 
298
 * Get the internal name of a module
 
299
 *
 
300
 * \param m the module
 
301
 * \return the module name
 
302
 */
 
303
const char *module_GetObjName( const module_t *m )
 
304
{
 
305
    return m->psz_object_name;
 
306
}
 
307
 
 
308
/**
 
309
 * Get the human-friendly name of a module.
 
310
 *
 
311
 * \param m the module
 
312
 * \param long_name TRUE to have the long name of the module
 
313
 * \return the short or long name of the module
 
314
 */
 
315
const char *module_GetName( const module_t *m, bool long_name )
 
316
{
 
317
    if( long_name && ( m->psz_longname != NULL) )
 
318
        return m->psz_longname;
 
319
 
 
320
    return m->psz_shortname ?: m->psz_object_name;
 
321
}
 
322
 
 
323
/**
 
324
 * Get the help for a module
 
325
 *
 
326
 * \param m the module
 
327
 * \return the help
 
328
 */
 
329
const char *module_GetHelp( const module_t *m )
 
330
{
 
331
    return m->psz_help;
 
332
}
 
333
 
 
334
/**
 
335
 * module Need
 
336
 *
 
337
 * Return the best module function, given a capability list.
 
338
 * \param p_this the vlc object
 
339
 * \param psz_capability list of capabilities needed
 
340
 * \param psz_name name of the module asked
 
341
 * \param b_strict TRUE yto use the strict mode
 
342
 * \return the module or NULL in case of a failure
 
343
 */
 
344
module_t * __module_Need( vlc_object_t *p_this, const char *psz_capability,
 
345
                          const char *psz_name, bool b_strict )
 
346
{
 
347
    typedef struct module_list_t module_list_t;
 
348
 
 
349
    stats_TimerStart( p_this, "module_Need()", STATS_TIMER_MODULE_NEED );
 
350
 
 
351
    struct module_list_t
 
352
    {
 
353
        module_t *p_module;
 
354
        int i_score;
 
355
        bool b_force;
 
356
        module_list_t *p_next;
 
357
    };
 
358
 
 
359
    module_list_t *p_list, *p_first, *p_tmp;
 
360
    vlc_list_t *p_all;
 
361
 
 
362
    int i_which_module, i_index = 0;
 
363
 
 
364
    module_t *p_module;
 
365
 
 
366
    int   i_shortcuts = 0;
 
367
    char *psz_shortcuts = NULL, *psz_var = NULL, *psz_alias = NULL;
 
368
    bool b_force_backup = p_this->b_force;
 
369
 
 
370
 
 
371
    /* Deal with variables */
 
372
    if( psz_name && psz_name[0] == '$' )
 
373
    {
 
374
        psz_name = psz_var = var_CreateGetString( p_this, psz_name + 1 );
 
375
    }
 
376
 
 
377
    /* Count how many different shortcuts were asked for */
 
378
    if( psz_name && *psz_name )
 
379
    {
 
380
        char *psz_parser, *psz_last_shortcut;
 
381
 
 
382
        /* If the user wants none, give him none. */
 
383
        if( !strcmp( psz_name, "none" ) )
 
384
        {
 
385
            free( psz_var );
 
386
            stats_TimerStop( p_this, STATS_TIMER_MODULE_NEED );
 
387
            stats_TimerDump( p_this, STATS_TIMER_MODULE_NEED );
 
388
            stats_TimerClean( p_this, STATS_TIMER_MODULE_NEED );
 
389
            return NULL;
 
390
        }
 
391
 
 
392
        i_shortcuts++;
 
393
        psz_shortcuts = psz_last_shortcut = strdup( psz_name );
 
394
 
 
395
        for( psz_parser = psz_shortcuts; *psz_parser; psz_parser++ )
 
396
        {
 
397
            if( *psz_parser == ',' )
 
398
            {
 
399
                 *psz_parser = '\0';
 
400
                 i_shortcuts++;
 
401
                 psz_last_shortcut = psz_parser + 1;
 
402
            }
 
403
        }
 
404
 
 
405
        /* Check if the user wants to override the "strict" mode */
 
406
        if( psz_last_shortcut )
 
407
        {
 
408
            if( !strcmp(psz_last_shortcut, "none") )
 
409
            {
 
410
                b_strict = true;
 
411
                i_shortcuts--;
 
412
            }
 
413
            else if( !strcmp(psz_last_shortcut, "any") )
 
414
            {
 
415
                b_strict = false;
 
416
                i_shortcuts--;
 
417
            }
 
418
        }
 
419
    }
 
420
 
 
421
    /* Sort the modules and test them */
 
422
    p_all = vlc_list_find( p_this, VLC_OBJECT_MODULE, FIND_ANYWHERE );
 
423
    p_list = malloc( p_all->i_count * sizeof( module_list_t ) );
 
424
    p_first = NULL;
 
425
    unsigned i_cpu = vlc_CPU();
 
426
 
 
427
    /* Parse the module list for capabilities and probe each of them */
 
428
    for( i_which_module = 0; i_which_module < p_all->i_count; i_which_module++ )
 
429
    {
 
430
        int i_shortcut_bonus = 0;
 
431
 
 
432
        p_module = (module_t *)p_all->p_values[i_which_module].p_object;
 
433
 
 
434
        /* Test that this module can do what we need */
 
435
        if( !module_IsCapable( p_module, psz_capability ) )
 
436
        {
 
437
            /* Don't recurse through the sub-modules because vlc_list_find()
 
438
             * will list them anyway. */
 
439
            continue;
 
440
        }
 
441
 
 
442
        /* Test if we have the required CPU */
 
443
        if( (p_module->i_cpu & i_cpu) != p_module->i_cpu )
 
444
        {
 
445
            continue;
 
446
        }
 
447
 
 
448
        /* If we required a shortcut, check this plugin provides it. */
 
449
        if( i_shortcuts > 0 )
 
450
        {
 
451
            bool b_trash;
 
452
            const char *psz_name = psz_shortcuts;
 
453
 
 
454
            /* Let's drop modules with a <= 0 score (unless they are
 
455
             * explicitly requested) */
 
456
            b_trash = p_module->i_score <= 0;
 
457
 
 
458
            for( unsigned i_short = i_shortcuts; i_short > 0; i_short-- )
 
459
            {
 
460
                for( unsigned i = 0; p_module->pp_shortcuts[i]; i++ )
 
461
                {
 
462
                    char *c;
 
463
                    if( ( c = strchr( psz_name, '@' ) )
 
464
                        ? !strncasecmp( psz_name, p_module->pp_shortcuts[i],
 
465
                                        c-psz_name )
 
466
                        : !strcasecmp( psz_name, p_module->pp_shortcuts[i] ) )
 
467
                    {
 
468
                        /* Found it */
 
469
                        if( c && c[1] )
 
470
                            psz_alias = c+1;
 
471
                        i_shortcut_bonus = i_short * 10000;
 
472
                        goto found_shortcut;
 
473
                    }
 
474
                }
 
475
 
 
476
                /* Go to the next shortcut... This is so lame! */
 
477
                psz_name += strlen( psz_name ) + 1;
 
478
            }
 
479
 
 
480
            /* If we are in "strict" mode and we couldn't
 
481
             * find the module in the list of provided shortcuts,
 
482
             * then kick the bastard out of here!!! */
 
483
            if( b_strict )
 
484
                continue;
 
485
        }
 
486
        /* If we didn't require a shortcut, trash <= 0 scored plugins */
 
487
        else if( p_module->i_score <= 0 )
 
488
        {
 
489
            continue;
 
490
        }
 
491
 
 
492
found_shortcut:
 
493
 
 
494
        /* Store this new module */
 
495
        p_list[ i_index ].p_module = p_module;
 
496
        p_list[ i_index ].i_score = p_module->i_score + i_shortcut_bonus;
 
497
        p_list[ i_index ].b_force = i_shortcut_bonus && b_strict;
 
498
 
 
499
        /* Add it to the modules-to-probe list */
 
500
        if( i_index == 0 )
 
501
        {
 
502
            p_list[ 0 ].p_next = NULL;
 
503
            p_first = p_list;
 
504
        }
 
505
        else
 
506
        {
 
507
            /* Ok, so at school you learned that quicksort is quick, and
 
508
             * bubble sort sucks raw eggs. But that's when dealing with
 
509
             * thousands of items. Here we have barely 50. */
 
510
            module_list_t *p_newlist = p_first;
 
511
 
 
512
            if( p_first->i_score < p_list[ i_index ].i_score )
 
513
            {
 
514
                p_list[ i_index ].p_next = p_first;
 
515
                p_first = &p_list[ i_index ];
 
516
            }
 
517
            else
 
518
            {
 
519
                while( p_newlist->p_next != NULL &&
 
520
                    p_newlist->p_next->i_score >= p_list[ i_index ].i_score )
 
521
                {
 
522
                    p_newlist = p_newlist->p_next;
 
523
                }
 
524
 
 
525
                p_list[ i_index ].p_next = p_newlist->p_next;
 
526
                p_newlist->p_next = &p_list[ i_index ];
 
527
            }
 
528
        }
 
529
 
 
530
        i_index++;
 
531
    }
 
532
 
 
533
    msg_Dbg( p_this, "looking for %s module: %i candidate%s", psz_capability,
 
534
                                            i_index, i_index == 1 ? "" : "s" );
 
535
 
 
536
    /* Lock all candidate modules */
 
537
    p_tmp = p_first;
 
538
    while( p_tmp != NULL )
 
539
    {
 
540
        vlc_object_yield( p_tmp->p_module );
 
541
        p_tmp = p_tmp->p_next;
 
542
    }
 
543
 
 
544
    /* We can release the list, interesting modules were yielded */
 
545
    vlc_list_release( p_all );
 
546
 
 
547
    /* Parse the linked list and use the first successful module */
 
548
    p_tmp = p_first;
 
549
    while( p_tmp != NULL )
 
550
    {
 
551
#ifdef HAVE_DYNAMIC_PLUGINS
 
552
        /* Make sure the module is loaded in mem */
 
553
        module_t *p_module = p_tmp->p_module;
 
554
        if( p_module->b_submodule )
 
555
            p_module = (module_t *)p_module->p_parent;
 
556
 
 
557
        if( !p_module->b_builtin && !p_module->b_loaded )
 
558
        {
 
559
            module_t *p_new_module =
 
560
                AllocatePlugin( p_this, p_module->psz_filename );
 
561
            if( p_new_module )
 
562
            {
 
563
                CacheMerge( p_this, p_module, p_new_module );
 
564
                vlc_object_attach( p_new_module, p_module );
 
565
                DeleteModule( p_new_module, true );
 
566
            }
 
567
        }
 
568
#endif
 
569
 
 
570
        p_this->b_force = p_tmp->b_force;
 
571
        if( p_tmp->p_module->pf_activate
 
572
             && p_tmp->p_module->pf_activate( p_this ) == VLC_SUCCESS )
 
573
        {
 
574
            break;
 
575
        }
 
576
 
 
577
        vlc_object_release( p_tmp->p_module );
 
578
        p_tmp = p_tmp->p_next;
 
579
    }
 
580
 
 
581
    /* Store the locked module value */
 
582
    if( p_tmp != NULL )
 
583
    {
 
584
        p_module = p_tmp->p_module;
 
585
        p_tmp = p_tmp->p_next;
 
586
    }
 
587
    else
 
588
    {
 
589
        p_module = NULL;
 
590
    }
 
591
 
 
592
    /* Unlock the remaining modules */
 
593
    while( p_tmp != NULL )
 
594
    {
 
595
        vlc_object_release( p_tmp->p_module );
 
596
        p_tmp = p_tmp->p_next;
 
597
    }
 
598
 
 
599
    free( p_list );
 
600
    p_this->b_force = b_force_backup;
 
601
 
 
602
    if( p_module != NULL )
 
603
    {
 
604
        msg_Dbg( p_this, "using %s module \"%s\"",
 
605
                 psz_capability, p_module->psz_object_name );
 
606
    }
 
607
    else if( p_first == NULL )
 
608
    {
 
609
        if( !strcmp( psz_capability, "access_demux" ) )
 
610
        {
 
611
            msg_Warn( p_this, "no %s module matched \"%s\"",
 
612
                 psz_capability, (psz_name && *psz_name) ? psz_name : "any" );
 
613
        }
 
614
        else
 
615
        {
 
616
            msg_Err( p_this, "no %s module matched \"%s\"",
 
617
                 psz_capability, (psz_name && *psz_name) ? psz_name : "any" );
 
618
 
 
619
            msg_StackSet( VLC_EGENERIC, "no %s module matched \"%s\"",
 
620
                 psz_capability, (psz_name && *psz_name) ? psz_name : "any" );
 
621
        }
 
622
    }
 
623
    else if( psz_name != NULL && *psz_name )
 
624
    {
 
625
        msg_Warn( p_this, "no %s module matching \"%s\" could be loaded",
 
626
                  psz_capability, (psz_name && *psz_name) ? psz_name : "any" );
 
627
    }
 
628
    else
 
629
        msg_StackSet( VLC_EGENERIC, "no suitable %s module", psz_capability );
 
630
 
 
631
    if( p_module && !p_this->psz_object_name )
 
632
    {
 
633
        /* This assumes that p_this is the object which will be using the
 
634
         * module. That's not always the case ... but it is in most cases.
 
635
         */
 
636
        if( psz_alias )
 
637
            p_this->psz_object_name = strdup( psz_alias );
 
638
        else
 
639
            p_this->psz_object_name = strdup( p_module->psz_object_name );
 
640
    }
 
641
 
 
642
    free( psz_shortcuts );
 
643
    free( psz_var );
 
644
 
 
645
    stats_TimerStop( p_this, STATS_TIMER_MODULE_NEED );
 
646
    stats_TimerDump( p_this, STATS_TIMER_MODULE_NEED );
 
647
    stats_TimerClean( p_this, STATS_TIMER_MODULE_NEED );
 
648
 
 
649
    /* Don't forget that the module is still locked */
 
650
    return p_module;
 
651
}
 
652
 
 
653
/**
 
654
 * Module unneed
 
655
 *
 
656
 * This function must be called by the thread that called module_Need, to
 
657
 * decrease the reference count and allow for hiding of modules.
 
658
 * \param p_this vlc object structure
 
659
 * \param p_module the module structure
 
660
 * \return nothing
 
661
 */
 
662
void __module_Unneed( vlc_object_t * p_this, module_t * p_module )
 
663
{
 
664
    /* Use the close method */
 
665
    if( p_module->pf_deactivate )
 
666
    {
 
667
        p_module->pf_deactivate( p_this );
 
668
    }
 
669
 
 
670
    msg_Dbg( p_this, "removing module \"%s\"", p_module->psz_object_name );
 
671
 
 
672
    vlc_object_release( p_module );
 
673
}
 
674
 
 
675
/**
 
676
 * Get a pointer to a module_t given it's name.
 
677
 *
 
678
 * \param p_this vlc object structure
 
679
 * \param psz_name the name of the module
 
680
 * \return a pointer to the module or NULL in case of a failure
 
681
 */
 
682
module_t *__module_Find( vlc_object_t *p_this, const char * psz_name )
 
683
{
 
684
    vlc_list_t *p_list;
 
685
    int i;
 
686
    p_list = vlc_list_find( p_this, VLC_OBJECT_MODULE, FIND_ANYWHERE );
 
687
    for( i = 0 ; i < p_list->i_count; i++)
 
688
    {
 
689
        module_t *p_module = ((module_t *) p_list->p_values[i].p_object);
 
690
        const char *psz_module_name = p_module->psz_object_name;
 
691
        if( psz_module_name && !strcmp( psz_module_name, psz_name ) )
 
692
        {
 
693
            /* We can release the list, and return yes */
 
694
            vlc_object_yield( p_module );
 
695
            vlc_list_release( p_list );
 
696
            return p_module;
 
697
        }
 
698
    }
 
699
    vlc_list_release( p_list );
 
700
    return NULL;
 
701
}
 
702
 
 
703
 
 
704
/**
 
705
 * Release a module_t pointer from module_Find().
 
706
 *
 
707
 * \param module the module to release
 
708
 * \return nothing
 
709
 */
 
710
void module_Put( module_t *module )
 
711
{
 
712
    vlc_object_release( module );
 
713
}
 
714
 
 
715
 
 
716
/**
 
717
 * Tell if a module exists and release it in thic case
 
718
 *
 
719
 * \param p_this vlc object structure
 
720
 * \param psz_name th name of the module
 
721
 * \return TRUE if the module exists
 
722
 */
 
723
bool __module_Exists( vlc_object_t *p_this, const char * psz_name )
 
724
{
 
725
    module_t *p_module = __module_Find( p_this, psz_name );
 
726
    if( p_module )
 
727
    {
 
728
        module_Put( p_module );
 
729
        return true;
 
730
    }
 
731
    else
 
732
    {
 
733
        return false;
 
734
    }
 
735
}
 
736
 
 
737
/**
 
738
 * GetModuleNamesForCapability
 
739
 *
 
740
 * Return a NULL terminated array with the names of the modules
 
741
 * that have a certain capability.
 
742
 * Free after uses both the string and the table.
 
743
 * \param p_this vlc object structure
 
744
 * \param psz_capability the capability asked
 
745
 * \param pppsz_longname an pointer to an array of string to contain
 
746
    the long names of the modules. If set to NULL the function don't use it.
 
747
 * \return the NULL terminated array
 
748
 */
 
749
char ** __module_GetModulesNamesForCapability( vlc_object_t *p_this,
 
750
                                               const char *psz_capability,
 
751
                                               char ***pppsz_longname )
 
752
{
 
753
    vlc_list_t *p_list;
 
754
    int i, j, count = 0;
 
755
    char **psz_ret;
 
756
 
 
757
    /* Do it in two passes : count the number of modules before */
 
758
    p_list = vlc_list_find( p_this, VLC_OBJECT_MODULE, FIND_ANYWHERE );
 
759
    for( i = 0 ; i < p_list->i_count; i++)
 
760
    {
 
761
        module_t *p_module = ((module_t *) p_list->p_values[i].p_object);
 
762
        const char *psz_module_capability = p_module->psz_capability;
 
763
        if( psz_module_capability && !strcmp( psz_module_capability, psz_capability ) )
 
764
            count++;
 
765
    }
 
766
 
 
767
    psz_ret = malloc( sizeof(char*) * (count+1) );
 
768
    if( pppsz_longname )
 
769
        *pppsz_longname = malloc( sizeof(char*) * (count+1) );
 
770
    if( !psz_ret || ( pppsz_longname && *pppsz_longname == NULL ) )
 
771
    {
 
772
        free( psz_ret );
 
773
        free( *pppsz_longname );
 
774
        *pppsz_longname = NULL;
 
775
        vlc_list_release( p_list );
 
776
        return NULL;
 
777
    }
 
778
 
 
779
    j = 0;
 
780
    for( i = 0 ; i < p_list->i_count; i++)
 
781
    {
 
782
        module_t *p_module = ((module_t *) p_list->p_values[i].p_object);
 
783
        const char *psz_module_capability = p_module->psz_capability;
 
784
        if( psz_module_capability && !strcmp( psz_module_capability, psz_capability ) )
 
785
        {
 
786
            int k = -1; /* hack to handle submodules properly */
 
787
            if( p_module->b_submodule )
 
788
            {
 
789
                while( p_module->pp_shortcuts[++k] != NULL );
 
790
                k--;
 
791
            }
 
792
            psz_ret[j] = strdup( k>=0?p_module->pp_shortcuts[k]
 
793
                                     :p_module->psz_object_name );
 
794
            if( pppsz_longname )
 
795
                (*pppsz_longname)[j] = strdup( module_GetName( p_module, true ) );
 
796
            j++;
 
797
        }
 
798
    }
 
799
    psz_ret[count] = NULL;
 
800
 
 
801
    vlc_list_release( p_list );
 
802
 
 
803
    return psz_ret;
 
804
}
 
805
 
 
806
/**
 
807
 * Get the configuration of a module
 
808
 *
 
809
 * \param module the module
 
810
 * \param psize the size of the configuration returned
 
811
 * \return the configuration as an array
 
812
 */
 
813
module_config_t *module_GetConfig( const module_t *module, unsigned *restrict psize )
 
814
{
 
815
    unsigned i,j;
 
816
    unsigned size = module->confsize;
 
817
    module_config_t *config = malloc( size * sizeof( *config ) );
 
818
 
 
819
    assert( psize != NULL );
 
820
    *psize = 0;
 
821
 
 
822
    if( !config )
 
823
        return NULL;
 
824
 
 
825
    for( i = 0, j = 0; i < size; i++ )
 
826
    {
 
827
        const module_config_t *item = module->p_config + i;
 
828
        if( item->b_internal /* internal option */
 
829
         || item->b_unsaveable /* non-modifiable option */
 
830
         || item->b_removed /* removed option */ )
 
831
            continue;
 
832
 
 
833
        memcpy( config + j, item, sizeof( *config ) );
 
834
        j++;
 
835
    }
 
836
    *psize = j;
 
837
 
 
838
    return config;
 
839
}
 
840
 
 
841
/**
 
842
 * Release the configuration
 
843
 *
 
844
 * \param the configuration
 
845
 * \return nothing
 
846
 */
 
847
void module_PutConfig( module_config_t *config )
 
848
{
 
849
    free( config );
 
850
}
 
851
 
 
852
/*****************************************************************************
 
853
 * Following functions are local.
 
854
 *****************************************************************************/
 
855
 
 
856
 /*****************************************************************************
 
857
 * copy_next_paths_token: from a PATH_SEP_CHAR (a ':' or a ';') separated paths
 
858
 * return first path.
 
859
 *****************************************************************************/
 
860
static char * copy_next_paths_token( char * paths, char ** remaining_paths )
 
861
{
 
862
    char * path;
 
863
    int i, done;
 
864
    bool escaped = false;
 
865
 
 
866
    assert( paths );
 
867
 
 
868
    /* Alloc a buffer to store the path */
 
869
    path = malloc( strlen( paths ) + 1 );
 
870
    if( !path ) return NULL;
 
871
 
 
872
    /* Look for PATH_SEP_CHAR (a ':' or a ';') */
 
873
    for( i = 0, done = 0 ; paths[i]; i++ )
 
874
    {
 
875
        /* Take care of \\ and \: or \; escapement */
 
876
        if( escaped )
 
877
        {
 
878
            escaped = false;
 
879
            path[done++] = paths[i];
 
880
        }
 
881
#ifdef WIN32
 
882
        else if( paths[i] == '/' )
 
883
            escaped = true;
 
884
#else
 
885
        else if( paths[i] == '\\' )
 
886
            escaped = true;
 
887
#endif
 
888
        else if( paths[i] == PATH_SEP_CHAR )
 
889
            break;
 
890
        else
 
891
            path[done++] = paths[i];
 
892
    }
 
893
    path[done++] = 0;
 
894
 
 
895
    /* Return the remaining paths */
 
896
    if( remaining_paths ) {
 
897
        *remaining_paths = paths[i] ? &paths[i]+1 : NULL;
 
898
    }
 
899
 
 
900
    return path;
 
901
}
 
902
 
 
903
/*****************************************************************************
 
904
 * AllocateAllPlugins: load all plugin modules we can find.
 
905
 *****************************************************************************/
 
906
#ifdef HAVE_DYNAMIC_PLUGINS
 
907
static void AllocateAllPlugins( vlc_object_t *p_this )
 
908
{
 
909
    const char *vlcpath = vlc_global()->psz_vlcpath;
 
910
    int count,i;
 
911
    char * path;
 
912
    vlc_array_t *arraypaths = vlc_array_new();
 
913
 
 
914
    /* Contruct the special search path for system that have a relocatable
 
915
     * executable. Set it to <vlc path>/modules and <vlc path>/plugins. */
 
916
 
 
917
    if( vlcpath && asprintf( &path, "%s" DIR_SEP "modules", vlcpath ) != -1 )
 
918
        vlc_array_append( arraypaths, path );
 
919
    if( vlcpath && asprintf( &path, "%s" DIR_SEP "plugins", vlcpath ) != -1 )
 
920
        vlc_array_append( arraypaths, path );
 
921
#ifndef WIN32
 
922
    vlc_array_append( arraypaths, strdup( PLUGIN_PATH ) );
 
923
#endif
 
924
 
 
925
    /* If the user provided a plugin path, we add it to the list */
 
926
    char *userpaths = config_GetPsz( p_this, "plugin-path" );
 
927
    char *paths_iter;
 
928
 
 
929
    for( paths_iter = userpaths; paths_iter; )
 
930
    {
 
931
        path = copy_next_paths_token( paths_iter, &paths_iter );
 
932
        if( path )
 
933
            vlc_array_append( arraypaths, path );
 
934
    }
 
935
 
 
936
    count = vlc_array_count( arraypaths );
 
937
    for( i = 0 ; i < count ; i++ )
 
938
    {
 
939
        path = vlc_array_item_at_index( arraypaths, i );
 
940
        if( !path )
 
941
            continue;
 
942
 
 
943
        msg_Dbg( p_this, "recursively browsing `%s'", path );
 
944
 
 
945
        /* Don't go deeper than 5 subdirectories */
 
946
        AllocatePluginDir( p_this, path, 5 );
 
947
 
 
948
        free( path );
 
949
    }
 
950
 
 
951
    vlc_array_destroy( arraypaths );
 
952
    free( userpaths );
 
953
}
 
954
 
 
955
/*****************************************************************************
 
956
 * AllocatePluginDir: recursively parse a directory to look for plugins
 
957
 *****************************************************************************/
 
958
static void AllocatePluginDir( vlc_object_t *p_this, const char *psz_dir,
 
959
                               int i_maxdepth )
 
960
{
 
961
/* FIXME: Needs to be ported to wide char on ALL Windows builds */
 
962
#ifdef WIN32
 
963
# undef opendir
 
964
# undef closedir
 
965
# undef readdir
 
966
#endif
 
967
#if defined( UNDER_CE ) || defined( _MSC_VER )
 
968
#ifdef UNDER_CE
 
969
    wchar_t psz_wpath[MAX_PATH + 256];
 
970
    wchar_t psz_wdir[MAX_PATH];
 
971
#endif
 
972
    char psz_path[MAX_PATH + 256];
 
973
    WIN32_FIND_DATA finddata;
 
974
    HANDLE handle;
 
975
    int rc;
 
976
#else
 
977
    int    i_dirlen;
 
978
    DIR *  dir;
 
979
    struct dirent * file;
 
980
#endif
 
981
    char * psz_file;
 
982
 
 
983
    if( p_this->p_libvlc->b_die || i_maxdepth < 0 )
 
984
    {
 
985
        return;
 
986
    }
 
987
 
 
988
#if defined( UNDER_CE ) || defined( _MSC_VER )
 
989
#ifdef UNDER_CE
 
990
    MultiByteToWideChar( CP_ACP, 0, psz_dir, -1, psz_wdir, MAX_PATH );
 
991
 
 
992
    rc = GetFileAttributes( psz_wdir );
 
993
    if( rc<0 || !(rc&FILE_ATTRIBUTE_DIRECTORY) ) return; /* Not a directory */
 
994
 
 
995
    /* Parse all files in the directory */
 
996
    swprintf( psz_wpath, L"%ls\\*", psz_wdir );
 
997
#else
 
998
    rc = GetFileAttributes( psz_dir );
 
999
    if( rc<0 || !(rc&FILE_ATTRIBUTE_DIRECTORY) ) return; /* Not a directory */
 
1000
#endif
 
1001
 
 
1002
    /* Parse all files in the directory */
 
1003
    sprintf( psz_path, "%s\\*", psz_dir );
 
1004
 
 
1005
#ifdef UNDER_CE
 
1006
    handle = FindFirstFile( psz_wpath, &finddata );
 
1007
#else
 
1008
    handle = FindFirstFile( psz_path, &finddata );
 
1009
#endif
 
1010
    if( handle == INVALID_HANDLE_VALUE )
 
1011
    {
 
1012
        /* Empty directory */
 
1013
        return;
 
1014
    }
 
1015
 
 
1016
    /* Parse the directory and try to load all files it contains. */
 
1017
    do
 
1018
    {
 
1019
#ifdef UNDER_CE
 
1020
        unsigned int i_len = wcslen( finddata.cFileName );
 
1021
        swprintf( psz_wpath, L"%ls\\%ls", psz_wdir, finddata.cFileName );
 
1022
        sprintf( psz_path, "%s\\%ls", psz_dir, finddata.cFileName );
 
1023
#else
 
1024
        unsigned int i_len = strlen( finddata.cFileName );
 
1025
        sprintf( psz_path, "%s\\%s", psz_dir, finddata.cFileName );
 
1026
#endif
 
1027
 
 
1028
        /* Skip ".", ".." */
 
1029
        if( !*finddata.cFileName || !strcmp( finddata.cFileName, "." )
 
1030
         || !strcmp( finddata.cFileName, ".." ) )
 
1031
        {
 
1032
            if( !FindNextFile( handle, &finddata ) ) break;
 
1033
            continue;
 
1034
        }
 
1035
 
 
1036
#ifdef UNDER_CE
 
1037
        if( GetFileAttributes( psz_wpath ) & FILE_ATTRIBUTE_DIRECTORY )
 
1038
#else
 
1039
        if( GetFileAttributes( psz_path ) & FILE_ATTRIBUTE_DIRECTORY )
 
1040
#endif
 
1041
        {
 
1042
            AllocatePluginDir( p_this, psz_path, i_maxdepth - 1 );
 
1043
        }
 
1044
        else if( i_len > strlen( LIBEXT )
 
1045
                  /* We only load files ending with LIBEXT */
 
1046
                  && !strncasecmp( psz_path + strlen( psz_path)
 
1047
                                   - strlen( LIBEXT ),
 
1048
                                   LIBEXT, strlen( LIBEXT ) ) )
 
1049
        {
 
1050
            WIN32_FILE_ATTRIBUTE_DATA attrbuf;
 
1051
            int64_t i_time = 0, i_size = 0;
 
1052
 
 
1053
#ifdef UNDER_CE
 
1054
            if( GetFileAttributesEx( psz_wpath, GetFileExInfoStandard,
 
1055
                                     &attrbuf ) )
 
1056
#else
 
1057
            if( GetFileAttributesEx( psz_path, GetFileExInfoStandard,
 
1058
                                     &attrbuf ) )
 
1059
#endif
 
1060
            {
 
1061
                i_time = attrbuf.ftLastWriteTime.dwHighDateTime;
 
1062
                i_time <<= 32;
 
1063
                i_time |= attrbuf.ftLastWriteTime.dwLowDateTime;
 
1064
                i_size = attrbuf.nFileSizeHigh;
 
1065
                i_size <<= 32;
 
1066
                i_size |= attrbuf.nFileSizeLow;
 
1067
            }
 
1068
            psz_file = psz_path;
 
1069
 
 
1070
            AllocatePluginFile( p_this, psz_file, i_time, i_size );
 
1071
        }
 
1072
    }
 
1073
    while( !p_this->p_libvlc->b_die && FindNextFile( handle, &finddata ) );
 
1074
 
 
1075
    /* Close the directory */
 
1076
    FindClose( handle );
 
1077
 
 
1078
#else
 
1079
    dir = opendir( psz_dir );
 
1080
    if( !dir )
 
1081
    {
 
1082
        return;
 
1083
    }
 
1084
 
 
1085
    i_dirlen = strlen( psz_dir );
 
1086
 
 
1087
    /* Parse the directory and try to load all files it contains. */
 
1088
    while( !p_this->p_libvlc->b_die && ( file = readdir( dir ) ) )
 
1089
    {
 
1090
        struct stat statbuf;
 
1091
        unsigned int i_len;
 
1092
        int i_stat;
 
1093
 
 
1094
        /* Skip ".", ".." */
 
1095
        if( !*file->d_name || !strcmp( file->d_name, "." )
 
1096
         || !strcmp( file->d_name, ".." ) )
 
1097
        {
 
1098
            continue;
 
1099
        }
 
1100
 
 
1101
        i_len = strlen( file->d_name );
 
1102
        psz_file = malloc( i_dirlen + 1 + i_len + 1 );
 
1103
        sprintf( psz_file, "%s"DIR_SEP"%s", psz_dir, file->d_name );
 
1104
 
 
1105
        i_stat = stat( psz_file, &statbuf );
 
1106
        if( !i_stat && statbuf.st_mode & S_IFDIR )
 
1107
        {
 
1108
            AllocatePluginDir( p_this, psz_file, i_maxdepth - 1 );
 
1109
        }
 
1110
        else if( i_len > strlen( LIBEXT )
 
1111
                  /* We only load files ending with LIBEXT */
 
1112
                  && !strncasecmp( file->d_name + i_len - strlen( LIBEXT ),
 
1113
                                   LIBEXT, strlen( LIBEXT ) ) )
 
1114
        {
 
1115
            int64_t i_time = 0, i_size = 0;
 
1116
 
 
1117
            if( !i_stat )
 
1118
            {
 
1119
                i_time = statbuf.st_mtime;
 
1120
                i_size = statbuf.st_size;
 
1121
            }
 
1122
 
 
1123
            AllocatePluginFile( p_this, psz_file, i_time, i_size );
 
1124
        }
 
1125
 
 
1126
        free( psz_file );
 
1127
    }
 
1128
 
 
1129
    /* Close the directory */
 
1130
    closedir( dir );
 
1131
 
 
1132
#endif
 
1133
}
 
1134
 
 
1135
/*****************************************************************************
 
1136
 * AllocatePluginFile: load a module into memory and initialize it.
 
1137
 *****************************************************************************
 
1138
 * This function loads a dynamically loadable module and allocates a structure
 
1139
 * for its information data. The module can then be handled by module_Need
 
1140
 * and module_Unneed. It can be removed by DeleteModule.
 
1141
 *****************************************************************************/
 
1142
static int AllocatePluginFile( vlc_object_t * p_this, char * psz_file,
 
1143
                               int64_t i_file_time, int64_t i_file_size )
 
1144
{
 
1145
    module_t * p_module = NULL;
 
1146
    module_cache_t *p_cache_entry = NULL;
 
1147
 
 
1148
    /*
 
1149
     * Check our plugins cache first then load plugin if needed
 
1150
     */
 
1151
    p_cache_entry =
 
1152
        CacheFind( psz_file, i_file_time, i_file_size );
 
1153
 
 
1154
    if( !p_cache_entry )
 
1155
    {
 
1156
        p_module = AllocatePlugin( p_this, psz_file );
 
1157
    }
 
1158
    else
 
1159
    {
 
1160
        /* If junk dll, don't try to load it */
 
1161
        if( p_cache_entry->b_junk )
 
1162
        {
 
1163
            p_module = NULL;
 
1164
        }
 
1165
        else
 
1166
        {
 
1167
            module_config_t *p_item = NULL, *p_end = NULL;
 
1168
 
 
1169
            p_module = p_cache_entry->p_module;
 
1170
            p_module->b_loaded = false;
 
1171
 
 
1172
            /* For now we force loading if the module's config contains
 
1173
             * callbacks or actions.
 
1174
             * Could be optimized by adding an API call.*/
 
1175
            for( p_item = p_module->p_config, p_end = p_item + p_module->confsize;
 
1176
                 p_item < p_end; p_item++ )
 
1177
            {
 
1178
                if( p_item->pf_callback || p_item->i_action )
 
1179
                {
 
1180
                    p_module = AllocatePlugin( p_this, psz_file );
 
1181
                    break;
 
1182
                }
 
1183
            }
 
1184
            if( p_module == p_cache_entry->p_module )
 
1185
                p_cache_entry->b_used = true;
 
1186
        }
 
1187
    }
 
1188
 
 
1189
    if( p_module )
 
1190
    {
 
1191
        libvlc_global_data_t *p_libvlc_global = vlc_global();
 
1192
 
 
1193
        /* Everything worked fine !
 
1194
         * The module is ready to be added to the list. */
 
1195
        p_module->b_builtin = false;
 
1196
 
 
1197
        /* msg_Dbg( p_this, "plugin \"%s\", %s",
 
1198
                    p_module->psz_object_name, p_module->psz_longname ); */
 
1199
 
 
1200
        vlc_object_attach( p_module, p_libvlc_global->p_module_bank );
 
1201
 
 
1202
        if( !p_libvlc_global->p_module_bank->b_cache )
 
1203
            return 0;
 
1204
 
 
1205
#define p_bank p_libvlc_global->p_module_bank
 
1206
        /* Add entry to cache */
 
1207
        p_bank->pp_cache =
 
1208
            realloc( p_bank->pp_cache, (p_bank->i_cache + 1) * sizeof(void *) );
 
1209
        p_bank->pp_cache[p_bank->i_cache] = malloc( sizeof(module_cache_t) );
 
1210
        if( !p_bank->pp_cache[p_bank->i_cache] )
 
1211
            return -1;
 
1212
        p_bank->pp_cache[p_bank->i_cache]->psz_file = strdup( psz_file );
 
1213
        p_bank->pp_cache[p_bank->i_cache]->i_time = i_file_time;
 
1214
        p_bank->pp_cache[p_bank->i_cache]->i_size = i_file_size;
 
1215
        p_bank->pp_cache[p_bank->i_cache]->b_junk = p_module ? 0 : 1;
 
1216
        p_bank->pp_cache[p_bank->i_cache]->b_used = true;
 
1217
        p_bank->pp_cache[p_bank->i_cache]->p_module = p_module;
 
1218
        p_bank->i_cache++;
 
1219
#undef p_bank
 
1220
    }
 
1221
 
 
1222
    return p_module ? 0 : -1;
 
1223
}
 
1224
 
 
1225
/*****************************************************************************
 
1226
 * AllocatePlugin: load a module into memory and initialize it.
 
1227
 *****************************************************************************
 
1228
 * This function loads a dynamically loadable module and allocates a structure
 
1229
 * for its information data. The module can then be handled by module_Need
 
1230
 * and module_Unneed. It can be removed by DeleteModule.
 
1231
 *****************************************************************************/
 
1232
static module_t * AllocatePlugin( vlc_object_t * p_this, char * psz_file )
 
1233
{
 
1234
    module_t * p_module = NULL;
 
1235
    module_handle_t handle;
 
1236
 
 
1237
    if( module_Load( p_this, psz_file, &handle ) )
 
1238
        return NULL;
 
1239
 
 
1240
    /* Now that we have successfully loaded the module, we can
 
1241
     * allocate a structure for it */
 
1242
    p_module = vlc_module_create( p_this );
 
1243
    if( p_module == NULL )
 
1244
    {
 
1245
        module_Unload( handle );
 
1246
        return NULL;
 
1247
    }
 
1248
 
 
1249
    /* We need to fill these since they may be needed by module_Call() */
 
1250
    p_module->psz_filename = psz_file;
 
1251
    p_module->handle = handle;
 
1252
    p_module->b_loaded = true;
 
1253
 
 
1254
    /* Initialize the module: fill p_module, default config */
 
1255
    if( module_Call( p_module ) != 0 )
 
1256
    {
 
1257
        /* We couldn't call module_init() */
 
1258
        vlc_object_release( p_module );
 
1259
        module_Unload( handle );
 
1260
        return NULL;
 
1261
    }
 
1262
 
 
1263
    DupModule( p_module );
 
1264
    p_module->psz_filename = strdup( p_module->psz_filename );
 
1265
 
 
1266
    /* Everything worked fine ! The module is ready to be added to the list. */
 
1267
    p_module->b_builtin = false;
 
1268
 
 
1269
    return p_module;
 
1270
}
 
1271
 
 
1272
/*****************************************************************************
 
1273
 * DupModule: make a plugin module standalone.
 
1274
 *****************************************************************************
 
1275
 * This function duplicates all strings in the module, so that the dynamic
 
1276
 * object can be unloaded. It acts recursively on submodules.
 
1277
 *****************************************************************************/
 
1278
static void DupModule( module_t *p_module )
 
1279
{
 
1280
    char **pp_shortcut;
 
1281
    int i_submodule;
 
1282
 
 
1283
    for( pp_shortcut = p_module->pp_shortcuts ; *pp_shortcut ; pp_shortcut++ )
 
1284
    {
 
1285
        *pp_shortcut = strdup( *pp_shortcut );
 
1286
    }
 
1287
 
 
1288
    /* We strdup() these entries so that they are still valid when the
 
1289
     * module is unloaded. */
 
1290
    p_module->psz_capability = strdup( p_module->psz_capability );
 
1291
    p_module->psz_shortname = p_module->psz_shortname ?
 
1292
                                 strdup( p_module->psz_shortname ) : NULL;
 
1293
    p_module->psz_longname = strdup( p_module->psz_longname );
 
1294
    p_module->psz_help = p_module->psz_help ? strdup( p_module->psz_help )
 
1295
                                            : NULL;
 
1296
 
 
1297
    for( i_submodule = 0; i_submodule < vlc_internals( p_module )->i_children; i_submodule++ )
 
1298
    {
 
1299
        DupModule( (module_t*)vlc_internals( p_module )->pp_children[ i_submodule ] );
 
1300
    }
 
1301
}
 
1302
 
 
1303
/*****************************************************************************
 
1304
 * UndupModule: free a duplicated module.
 
1305
 *****************************************************************************
 
1306
 * This function frees the allocations done in DupModule().
 
1307
 *****************************************************************************/
 
1308
static void UndupModule( module_t *p_module )
 
1309
{
 
1310
    char **pp_shortcut;
 
1311
    int i_submodule;
 
1312
 
 
1313
    for( i_submodule = 0; i_submodule < vlc_internals( p_module )->i_children; i_submodule++ )
 
1314
    {
 
1315
        UndupModule( (module_t*)vlc_internals( p_module )->pp_children[ i_submodule ] );
 
1316
    }
 
1317
 
 
1318
    for( pp_shortcut = p_module->pp_shortcuts ; *pp_shortcut ; pp_shortcut++ )
 
1319
    {
 
1320
        free( *pp_shortcut );
 
1321
    }
 
1322
 
 
1323
    FREENULL( p_module->psz_object_name );
 
1324
    free( p_module->psz_capability );
 
1325
    free( p_module->psz_shortname );
 
1326
    free( p_module->psz_longname );
 
1327
    free( p_module->psz_help );
 
1328
}
 
1329
 
 
1330
#endif /* HAVE_DYNAMIC_PLUGINS */
 
1331
 
 
1332
/*****************************************************************************
 
1333
 * AllocateBuiltinModule: initialize a builtin module.
 
1334
 *****************************************************************************
 
1335
 * This function registers a builtin module and allocates a structure
 
1336
 * for its information data. The module can then be handled by module_Need
 
1337
 * and module_Unneed. It can be removed by DeleteModule.
 
1338
 *****************************************************************************/
 
1339
static int AllocateBuiltinModule( vlc_object_t * p_this,
 
1340
                                  int ( *pf_entry ) ( module_t * ) )
 
1341
{
 
1342
    module_t * p_module;
 
1343
 
 
1344
    /* Now that we have successfully loaded the module, we can
 
1345
     * allocate a structure for it */
 
1346
    p_module = vlc_module_create( p_this );
 
1347
    if( p_module == NULL )
 
1348
        return -1;
 
1349
 
 
1350
    /* Initialize the module : fill p_module->psz_object_name, etc. */
 
1351
    if( pf_entry( p_module ) != 0 )
 
1352
    {
 
1353
        /* With a well-written module we shouldn't have to print an
 
1354
         * additional error message here, but just make sure. */
 
1355
        msg_Err( p_this, "failed calling entry point in builtin module" );
 
1356
        vlc_object_release( p_module );
 
1357
        return -1;
 
1358
    }
 
1359
 
 
1360
    /* Everything worked fine ! The module is ready to be added to the list. */
 
1361
    p_module->b_builtin = true;
 
1362
 
 
1363
    /* msg_Dbg( p_this, "builtin \"%s\", %s",
 
1364
                p_module->psz_object_name, p_module->psz_longname ); */
 
1365
 
 
1366
    vlc_object_attach( p_module, vlc_global()->p_module_bank );
 
1367
 
 
1368
    return 0;
 
1369
}
 
1370
 
 
1371
/*****************************************************************************
 
1372
 * DeleteModule: delete a module and its structure.
 
1373
 *****************************************************************************
 
1374
 * This function can only be called if the module isn't being used.
 
1375
 *****************************************************************************/
 
1376
static void DeleteModule( module_t * p_module, bool b_detach )
 
1377
{
 
1378
    assert( p_module );
 
1379
 
 
1380
    if( b_detach )
 
1381
        vlc_object_detach( p_module );
 
1382
 
 
1383
    /* We free the structures that we strdup()ed in Allocate*Module(). */
 
1384
#ifdef HAVE_DYNAMIC_PLUGINS
 
1385
    if( !p_module->b_builtin )
 
1386
    {
 
1387
        if( p_module->b_loaded && p_module->b_unloadable )
 
1388
        {
 
1389
            module_Unload( p_module->handle );
 
1390
        }
 
1391
        UndupModule( p_module );
 
1392
        free( p_module->psz_filename );
 
1393
    }
 
1394
#endif
 
1395
 
 
1396
    /* Free and detach the object's children */
 
1397
    while( vlc_internals( p_module )->i_children )
 
1398
    {
 
1399
        vlc_object_t *p_this = vlc_internals( p_module )->pp_children[0];
 
1400
        vlc_object_detach( p_this );
 
1401
        vlc_object_release( p_this );
 
1402
    }
 
1403
 
 
1404
    config_Free( p_module );
 
1405
    vlc_object_release( p_module );
 
1406
}