1 /*****************************************************************************
2 * cache.c: Plugins cache
3 *****************************************************************************
4 * Copyright (C) 2001-2007 the VideoLAN team
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>
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.
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.
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 *****************************************************************************/
31 #include <vlc_common.h>
34 #include <stdlib.h> /* free(), strtol() */
35 #include <stdio.h> /* sprintf() */
36 #include <string.h> /* strdup() */
37 #include <vlc_plugin.h>
39 #ifdef HAVE_SYS_TYPES_H
40 # include <sys/types.h>
46 #if !defined(HAVE_DYNAMIC_PLUGINS)
47 /* no support for plugins */
48 #elif defined(HAVE_DL_DYLD)
49 # if defined(HAVE_MACH_O_DYLD_H)
50 # include <mach-o/dyld.h>
52 #elif defined(HAVE_DL_BEOS)
53 # if defined(HAVE_IMAGE_H)
56 #elif defined(HAVE_DL_WINDOWS)
58 #elif defined(HAVE_DL_DLOPEN)
59 # if defined(HAVE_DLFCN_H) /* Linux, BSD, Hurd */
62 # if defined(HAVE_SYS_DL_H)
65 #elif defined(HAVE_DL_SHL_LOAD)
66 # if defined(HAVE_DL_H)
71 #include "config/configuration.h"
73 #include "vlc_charset.h"
75 #include "modules/modules.h"
78 /*****************************************************************************
80 *****************************************************************************/
81 #ifdef HAVE_DYNAMIC_PLUGINS
82 static int CacheLoadConfig ( module_t
*, FILE * );
83 static int CacheSaveConfig ( module_t
*, FILE * );
86 * (only used to avoid breakage in dev version when cache structure changes) */
87 #define CACHE_SUBVERSION_NUM 3
89 /* Format string for the cache filename */
90 #define CACHENAME_FORMAT \
91 "plugins-%.2zx%.2zx%.2"PRIx8".dat"
92 /* Magic for the cache filename */
93 #define CACHENAME_VALUES \
94 sizeof(int), sizeof(void *), *(uint8_t *)&(uint16_t){ 0xbe1e }
97 /*****************************************************************************
98 * LoadPluginsCache: loads the plugins cache file
99 *****************************************************************************
100 * This function will load the plugin cache if present and valid. This cache
101 * will in turn be queried by AllocateAllPlugins() to see if it needs to
102 * actually load the dynamically loadable module.
103 * This allows us to only fully load plugins when they are actually used.
104 *****************************************************************************/
105 void CacheLoad( vlc_object_t
*p_this
, module_bank_t
*p_bank
, bool b_delete
)
107 char *psz_filename
, *psz_cachedir
= config_GetCacheDir();
109 int i
, j
, i_size
, i_read
;
110 char p_cachestring
[sizeof("cache " COPYRIGHT_MESSAGE
)];
111 char p_cachelang
[6], p_lang
[6];
113 module_cache_t
**pp_cache
= 0;
114 int32_t i_file_size
, i_marker
;
116 if( !psz_cachedir
) /* XXX: this should never happen */
118 msg_Err( p_this
, "Unable to get cache directory" );
122 if( asprintf( &psz_filename
, "%s"DIR_SEP CACHENAME_FORMAT
,
123 psz_cachedir
, CACHENAME_VALUES
) == -1 )
125 free( psz_cachedir
);
128 free( psz_cachedir
);
132 #if !defined( UNDER_CE )
133 unlink( psz_filename
);
135 wchar_t psz_wf
[MAX_PATH
];
136 MultiByteToWideChar( CP_ACP
, 0, psz_filename
, -1, psz_wf
, MAX_PATH
);
137 DeleteFile( psz_wf
);
139 msg_Dbg( p_this
, "removing plugins cache file %s", psz_filename
);
140 free( psz_filename
);
144 msg_Dbg( p_this
, "loading plugins cache file %s", psz_filename
);
146 file
= utf8_fopen( psz_filename
, "rb" );
149 msg_Warn( p_this
, "could not open plugins cache file %s for reading",
151 free( psz_filename
);
154 free( psz_filename
);
156 /* Check the file size */
157 i_read
= fread( &i_file_size
, 1, sizeof(i_file_size
), file
);
158 if( i_read
!= sizeof(i_file_size
) )
160 msg_Warn( p_this
, "This doesn't look like a valid plugins cache "
166 fseek( file
, 0, SEEK_END
);
167 if( ftell( file
) != i_file_size
)
169 msg_Warn( p_this
, "This doesn't look like a valid plugins cache "
170 "(corrupted size)" );
174 fseek( file
, sizeof(i_file_size
), SEEK_SET
);
176 /* Check the file is a plugins cache */
177 i_size
= sizeof("cache " COPYRIGHT_MESSAGE
) - 1;
178 i_read
= fread( p_cachestring
, 1, i_size
, file
);
179 if( i_read
!= i_size
||
180 memcmp( p_cachestring
, "cache " COPYRIGHT_MESSAGE
, i_size
) )
182 msg_Warn( p_this
, "This doesn't look like a valid plugins cache" );
187 #ifdef DISTRO_VERSION
188 /* Check for distribution specific version */
189 char p_distrostring
[sizeof( DISTRO_VERSION
)];
190 i_size
= sizeof( DISTRO_VERSION
) - 1;
191 i_read
= fread( p_distrostring
, 1, i_size
, file
);
192 if( i_read
!= i_size
||
193 memcmp( p_distrostring
, DISTRO_VERSION
, i_size
) )
195 msg_Warn( p_this
, "This doesn't look like a valid plugins cache" );
201 /* Check Sub-version number */
202 i_read
= fread( &i_marker
, 1, sizeof(i_marker
), file
);
203 if( i_read
!= sizeof(i_marker
) || i_marker
!= CACHE_SUBVERSION_NUM
)
205 msg_Warn( p_this
, "This doesn't look like a valid plugins cache "
206 "(corrupted header)" );
211 /* Check the language hasn't changed */
212 sprintf( p_lang
, "%5.5s", _("C") ); i_size
= 5;
213 i_read
= fread( p_cachelang
, 1, i_size
, file
);
214 if( i_read
!= i_size
|| memcmp( p_cachelang
, p_lang
, i_size
) )
216 msg_Warn( p_this
, "This doesn't look like a valid plugins cache "
217 "(language changed)" );
222 /* Check header marker */
223 i_read
= fread( &i_marker
, 1, sizeof(i_marker
), file
);
224 if( i_read
!= sizeof(i_marker
) ||
225 i_marker
!= ftell( file
) - (int)sizeof(i_marker
) )
227 msg_Warn( p_this
, "This doesn't look like a valid plugins cache "
228 "(corrupted header)" );
233 p_bank
->i_loaded_cache
= 0;
234 if (fread( &i_cache
, 1, sizeof(i_cache
), file
) != sizeof(i_cache
) )
236 msg_Warn( p_this
, "This doesn't look like a valid plugins cache "
237 "(file too short)" );
243 pp_cache
= p_bank
->pp_loaded_cache
=
244 malloc( i_cache
* sizeof(void *) );
246 #define LOAD_IMMEDIATE(a) \
247 if( fread( (void *)&a, sizeof(char), sizeof(a), file ) != sizeof(a) ) goto error
248 #define LOAD_STRING(a) \
251 if( ( fread( &i_size, sizeof(i_size), 1, file ) != 1 ) \
252 || ( i_size > 16384 ) ) \
255 char *psz = malloc( i_size ); \
256 if( fread( psz, i_size, 1, file ) != 1 ) { \
260 if( psz[i_size-1] ) { \
268 for( i
= 0; i
< i_cache
; i
++ )
273 pp_cache
[i
] = malloc( sizeof(module_cache_t
) );
274 p_bank
->i_loaded_cache
++;
276 /* Load common info */
277 LOAD_STRING( pp_cache
[i
]->psz_file
);
278 LOAD_IMMEDIATE( pp_cache
[i
]->i_time
);
279 LOAD_IMMEDIATE( pp_cache
[i
]->i_size
);
280 LOAD_IMMEDIATE( pp_cache
[i
]->b_junk
);
281 pp_cache
[i
]->b_used
= false;
283 if( pp_cache
[i
]->b_junk
) continue;
285 pp_cache
[i
]->p_module
= vlc_module_create( p_this
);
287 /* Load additional infos */
288 free( pp_cache
[i
]->p_module
->psz_object_name
);
289 LOAD_STRING( pp_cache
[i
]->p_module
->psz_object_name
);
290 LOAD_STRING( pp_cache
[i
]->p_module
->psz_shortname
);
291 LOAD_STRING( pp_cache
[i
]->p_module
->psz_longname
);
292 LOAD_STRING( pp_cache
[i
]->p_module
->psz_help
);
293 for( j
= 0; j
< MODULE_SHORTCUT_MAX
; j
++ )
295 LOAD_STRING( pp_cache
[i
]->p_module
->pp_shortcuts
[j
] ); // FIX
297 LOAD_STRING( pp_cache
[i
]->p_module
->psz_capability
);
298 LOAD_IMMEDIATE( pp_cache
[i
]->p_module
->i_score
);
299 LOAD_IMMEDIATE( pp_cache
[i
]->p_module
->i_cpu
);
300 LOAD_IMMEDIATE( pp_cache
[i
]->p_module
->b_unloadable
);
301 LOAD_IMMEDIATE( pp_cache
[i
]->p_module
->b_reentrant
);
302 LOAD_IMMEDIATE( pp_cache
[i
]->p_module
->b_submodule
);
305 if( CacheLoadConfig( pp_cache
[i
]->p_module
, file
) != VLC_SUCCESS
)
308 LOAD_STRING( pp_cache
[i
]->p_module
->psz_filename
);
310 LOAD_IMMEDIATE( i_submodules
);
312 while( i_submodules
-- )
314 module_t
*p_module
= vlc_submodule_create( pp_cache
[i
]->p_module
);
315 free( p_module
->psz_object_name
);
316 LOAD_STRING( p_module
->psz_object_name
);
317 LOAD_STRING( p_module
->psz_shortname
);
318 LOAD_STRING( p_module
->psz_longname
);
319 LOAD_STRING( p_module
->psz_help
);
320 for( j
= 0; j
< MODULE_SHORTCUT_MAX
; j
++ )
322 LOAD_STRING( p_module
->pp_shortcuts
[j
] ); // FIX
324 LOAD_STRING( p_module
->psz_capability
);
325 LOAD_IMMEDIATE( p_module
->i_score
);
326 LOAD_IMMEDIATE( p_module
->i_cpu
);
327 LOAD_IMMEDIATE( p_module
->b_unloadable
);
328 LOAD_IMMEDIATE( p_module
->b_reentrant
);
337 msg_Warn( p_this
, "plugins cache not loaded (corrupted)" );
340 p_bank
->i_loaded_cache
= 0;
347 static int CacheLoadConfig( module_t
*p_module
, FILE *file
)
352 /* Calculate the structure length */
353 LOAD_IMMEDIATE( p_module
->i_config_items
);
354 LOAD_IMMEDIATE( p_module
->i_bool_items
);
356 LOAD_IMMEDIATE( i_lines
);
358 /* Allocate memory */
362 (module_config_t
*)calloc( i_lines
, sizeof(module_config_t
) );
363 if( p_module
->p_config
== NULL
)
365 p_module
->confsize
= 0;
369 p_module
->confsize
= i_lines
;
371 /* Do the duplication job */
372 for (size_t i
= 0; i
< i_lines
; i
++ )
374 LOAD_IMMEDIATE( p_module
->p_config
[i
] );
376 LOAD_STRING( p_module
->p_config
[i
].psz_type
);
377 LOAD_STRING( p_module
->p_config
[i
].psz_name
);
378 LOAD_STRING( p_module
->p_config
[i
].psz_text
);
379 LOAD_STRING( p_module
->p_config
[i
].psz_longtext
);
380 LOAD_STRING( p_module
->p_config
[i
].psz_oldname
);
381 LOAD_IMMEDIATE( p_module
->p_config
[i
].b_removed
);
383 if (IsConfigStringType (p_module
->p_config
[i
].i_type
))
385 LOAD_STRING (p_module
->p_config
[i
].orig
.psz
);
386 p_module
->p_config
[i
].value
.psz
=
387 (p_module
->p_config
[i
].orig
.psz
!= NULL
)
388 ? strdup (p_module
->p_config
[i
].orig
.psz
) : NULL
;
389 p_module
->p_config
[i
].saved
.psz
= NULL
;
393 memcpy (&p_module
->p_config
[i
].value
, &p_module
->p_config
[i
].orig
,
394 sizeof (p_module
->p_config
[i
].value
));
395 memcpy (&p_module
->p_config
[i
].saved
, &p_module
->p_config
[i
].orig
,
396 sizeof (p_module
->p_config
[i
].saved
));
399 p_module
->p_config
[i
].b_dirty
= false;
401 p_module
->p_config
[i
].p_lock
= &p_module
->lock
;
403 if( p_module
->p_config
[i
].i_list
)
405 if( p_module
->p_config
[i
].ppsz_list
)
408 p_module
->p_config
[i
].ppsz_list
=
409 malloc( (p_module
->p_config
[i
].i_list
+1) * sizeof(char *));
410 if( p_module
->p_config
[i
].ppsz_list
)
412 for( j
= 0; j
< p_module
->p_config
[i
].i_list
; j
++ )
413 LOAD_STRING( p_module
->p_config
[i
].ppsz_list
[j
] );
414 p_module
->p_config
[i
].ppsz_list
[j
] = NULL
;
417 if( p_module
->p_config
[i
].ppsz_list_text
)
420 p_module
->p_config
[i
].ppsz_list_text
=
421 malloc( (p_module
->p_config
[i
].i_list
+1) * sizeof(char *));
422 if( p_module
->p_config
[i
].ppsz_list_text
)
424 for( j
= 0; j
< p_module
->p_config
[i
].i_list
; j
++ )
425 LOAD_STRING( p_module
->p_config
[i
].ppsz_list_text
[j
] );
426 p_module
->p_config
[i
].ppsz_list_text
[j
] = NULL
;
429 if( p_module
->p_config
[i
].pi_list
)
431 p_module
->p_config
[i
].pi_list
=
432 malloc( (p_module
->p_config
[i
].i_list
+ 1) * sizeof(int) );
433 if( p_module
->p_config
[i
].pi_list
)
435 for (int j
= 0; j
< p_module
->p_config
[i
].i_list
; j
++)
436 LOAD_IMMEDIATE( p_module
->p_config
[i
].pi_list
[j
] );
441 if( p_module
->p_config
[i
].i_action
)
443 p_module
->p_config
[i
].ppf_action
=
444 malloc( p_module
->p_config
[i
].i_action
* sizeof(void *) );
445 p_module
->p_config
[i
].ppsz_action_text
=
446 malloc( p_module
->p_config
[i
].i_action
* sizeof(char *) );
448 for (int j
= 0; j
< p_module
->p_config
[i
].i_action
; j
++)
450 p_module
->p_config
[i
].ppf_action
[j
] = 0;
451 LOAD_STRING( p_module
->p_config
[i
].ppsz_action_text
[j
] );
455 LOAD_IMMEDIATE( p_module
->p_config
[i
].pf_callback
);
465 static int CacheSaveSubmodule( FILE *file
, module_t
*p_module
);
467 /*****************************************************************************
468 * SavePluginsCache: saves the plugins cache to a file
469 *****************************************************************************/
470 void CacheSave( vlc_object_t
*p_this
, module_bank_t
*p_bank
)
472 static char const psz_tag
[] =
473 "Signature: 8a477f597d28d172789f06886806bc55\r\n"
474 "# This file is a cache directory tag created by VLC.\r\n"
475 "# For information about cache directory tags, see:\r\n"
476 "# http://www.brynosaurus.com/cachedir/\r\n";
478 char *psz_cachedir
= config_GetCacheDir();
481 module_cache_t
**pp_cache
;
482 uint32_t i_file_size
= 0;
484 if( !psz_cachedir
) /* XXX: this should never happen */
486 msg_Err( p_this
, "unable to get cache directory" );
490 char psz_filename
[sizeof(DIR_SEP
) + 32 + strlen(psz_cachedir
)];
491 config_CreateDir( p_this
, psz_cachedir
);
493 snprintf( psz_filename
, sizeof( psz_filename
),
494 "%s"DIR_SEP
"CACHEDIR.TAG", psz_cachedir
);
495 file
= utf8_fopen( psz_filename
, "wb" );
498 if (fwrite (psz_tag
, 1, sizeof (psz_tag
) - 1, file
) != 1)
499 clearerr (file
); /* what else can we do? */
503 snprintf( psz_filename
, sizeof( psz_filename
),
504 "%s"DIR_SEP CACHENAME_FORMAT
, psz_cachedir
,
506 free( psz_cachedir
);
507 msg_Dbg( p_this
, "writing plugins cache %s", psz_filename
);
509 file
= utf8_fopen( psz_filename
, "wb" );
513 /* Empty space for file size */
514 if (fwrite (&i_file_size
, sizeof (i_file_size
), 1, file
) != 1)
517 /* Contains version number */
518 if (fputs ("cache "COPYRIGHT_MESSAGE
, file
) == EOF
)
520 #ifdef DISTRO_VERSION
521 /* Allow binary maintaner to pass a string to detect new binary version*/
522 if (fputs( DISTRO_VERSION
, file
) == EOF
)
525 /* Sub-version number (to avoid breakage in the dev version when cache
526 * structure changes) */
527 i_file_size
= CACHE_SUBVERSION_NUM
;
528 if (fwrite (&i_file_size
, sizeof (i_file_size
), 1, file
) != 1 )
532 if (fprintf (file
, "%5.5s", _("C")) == EOF
)
536 i_file_size
= ftell( file
);
537 if (fwrite (&i_file_size
, sizeof (i_file_size
), 1, file
) != 1)
540 i_cache
= p_bank
->i_cache
;
541 pp_cache
= p_bank
->pp_cache
;
543 if (fwrite( &i_cache
, sizeof (i_cache
), 1, file
) != 1)
546 #define SAVE_IMMEDIATE( a ) \
547 if (fwrite (&a, sizeof(a), 1, file) != 1) \
549 #define SAVE_STRING( a ) \
551 uint16_t i_size = (a != NULL) ? (strlen (a) + 1) : 0; \
552 if ((fwrite (&i_size, sizeof (i_size), 1, file) != 1) \
553 || (a && (fwrite (a, 1, i_size, file) != i_size))) \
557 for( i
= 0; i
< i_cache
; i
++ )
559 uint32_t i_submodule
;
561 /* Save common info */
562 SAVE_STRING( pp_cache
[i
]->psz_file
);
563 SAVE_IMMEDIATE( pp_cache
[i
]->i_time
);
564 SAVE_IMMEDIATE( pp_cache
[i
]->i_size
);
565 SAVE_IMMEDIATE( pp_cache
[i
]->b_junk
);
567 if( pp_cache
[i
]->b_junk
) continue;
569 /* Save additional infos */
570 SAVE_STRING( pp_cache
[i
]->p_module
->psz_object_name
);
571 SAVE_STRING( pp_cache
[i
]->p_module
->psz_shortname
);
572 SAVE_STRING( pp_cache
[i
]->p_module
->psz_longname
);
573 SAVE_STRING( pp_cache
[i
]->p_module
->psz_help
);
574 for( j
= 0; j
< MODULE_SHORTCUT_MAX
; j
++ )
576 SAVE_STRING( pp_cache
[i
]->p_module
->pp_shortcuts
[j
] ); // FIX
578 SAVE_STRING( pp_cache
[i
]->p_module
->psz_capability
);
579 SAVE_IMMEDIATE( pp_cache
[i
]->p_module
->i_score
);
580 SAVE_IMMEDIATE( pp_cache
[i
]->p_module
->i_cpu
);
581 SAVE_IMMEDIATE( pp_cache
[i
]->p_module
->b_unloadable
);
582 SAVE_IMMEDIATE( pp_cache
[i
]->p_module
->b_reentrant
);
583 SAVE_IMMEDIATE( pp_cache
[i
]->p_module
->b_submodule
);
586 if (CacheSaveConfig (pp_cache
[i
]->p_module
, file
))
589 SAVE_STRING( pp_cache
[i
]->p_module
->psz_filename
);
591 i_submodule
= pp_cache
[i
]->p_module
->submodule_count
;
592 SAVE_IMMEDIATE( i_submodule
);
593 if( CacheSaveSubmodule( file
, pp_cache
[i
]->p_module
->submodule
) )
597 /* Fill-up file size */
598 i_file_size
= ftell( file
);
599 fseek( file
, 0, SEEK_SET
);
600 if (fwrite (&i_file_size
, sizeof (i_file_size
), 1, file
) != 1)
603 if (fclose (file
) == 0)
604 return; /* success! */
608 msg_Warn (p_this
, "could not write plugins cache %s (%m)",
617 static int CacheSaveSubmodule( FILE *file
, module_t
*p_module
)
621 if( CacheSaveSubmodule( file
, p_module
->next
) )
624 SAVE_STRING( p_module
->psz_object_name
);
625 SAVE_STRING( p_module
->psz_shortname
);
626 SAVE_STRING( p_module
->psz_longname
);
627 SAVE_STRING( p_module
->psz_help
);
628 for( unsigned j
= 0; j
< MODULE_SHORTCUT_MAX
; j
++ )
629 SAVE_STRING( p_module
->pp_shortcuts
[j
] ); // FIXME
631 SAVE_STRING( p_module
->psz_capability
);
632 SAVE_IMMEDIATE( p_module
->i_score
);
633 SAVE_IMMEDIATE( p_module
->i_cpu
);
634 SAVE_IMMEDIATE( p_module
->b_unloadable
);
635 SAVE_IMMEDIATE( p_module
->b_reentrant
);
643 static int CacheSaveConfig( module_t
*p_module
, FILE *file
)
645 uint32_t i_lines
= p_module
->confsize
;
647 SAVE_IMMEDIATE( p_module
->i_config_items
);
648 SAVE_IMMEDIATE( p_module
->i_bool_items
);
649 SAVE_IMMEDIATE( i_lines
);
651 for (size_t i
= 0; i
< i_lines
; i
++)
653 SAVE_IMMEDIATE( p_module
->p_config
[i
] );
655 SAVE_STRING( p_module
->p_config
[i
].psz_type
);
656 SAVE_STRING( p_module
->p_config
[i
].psz_name
);
657 SAVE_STRING( p_module
->p_config
[i
].psz_text
);
658 SAVE_STRING( p_module
->p_config
[i
].psz_longtext
);
659 SAVE_STRING( p_module
->p_config
[i
].psz_oldname
);
660 SAVE_IMMEDIATE( p_module
->p_config
[i
].b_removed
);
662 if (IsConfigStringType (p_module
->p_config
[i
].i_type
))
663 SAVE_STRING( p_module
->p_config
[i
].orig
.psz
);
665 if( p_module
->p_config
[i
].i_list
)
667 if( p_module
->p_config
[i
].ppsz_list
)
669 for (int j
= 0; j
< p_module
->p_config
[i
].i_list
; j
++)
670 SAVE_STRING( p_module
->p_config
[i
].ppsz_list
[j
] );
673 if( p_module
->p_config
[i
].ppsz_list_text
)
675 for (int j
= 0; j
< p_module
->p_config
[i
].i_list
; j
++)
676 SAVE_STRING( p_module
->p_config
[i
].ppsz_list_text
[j
] );
678 if( p_module
->p_config
[i
].pi_list
)
680 for (int j
= 0; j
< p_module
->p_config
[i
].i_list
; j
++)
681 SAVE_IMMEDIATE( p_module
->p_config
[i
].pi_list
[j
] );
685 for (int j
= 0; j
< p_module
->p_config
[i
].i_action
; j
++)
686 SAVE_STRING( p_module
->p_config
[i
].ppsz_action_text
[j
] );
688 SAVE_IMMEDIATE( p_module
->p_config
[i
].pf_callback
);
696 /*****************************************************************************
697 * CacheMerge: Merge a cache module descriptor with a full module descriptor.
698 *****************************************************************************/
699 void CacheMerge( vlc_object_t
*p_this
, module_t
*p_cache
, module_t
*p_module
)
703 p_cache
->pf_activate
= p_module
->pf_activate
;
704 p_cache
->pf_deactivate
= p_module
->pf_deactivate
;
705 p_cache
->handle
= p_module
->handle
;
707 /* FIXME: This looks too simplistic an algorithm to me. What if the module
708 * file was altered such that the number of order of submodules was
709 * altered... after VLC started -- Courmisch, 09/2008 */
710 module_t
*p_child
= p_module
->submodule
,
711 *p_cchild
= p_cache
->submodule
;
712 while( p_child
&& p_cchild
)
714 p_cchild
->pf_activate
= p_child
->pf_activate
;
715 p_cchild
->pf_deactivate
= p_child
->pf_deactivate
;
716 p_child
= p_child
->next
;
717 p_cchild
= p_cchild
->next
;
720 p_cache
->b_loaded
= true;
721 p_module
->b_loaded
= false;
724 /*****************************************************************************
725 * CacheFind: finds the cache entry corresponding to a file
726 *****************************************************************************/
727 module_cache_t
*CacheFind( module_bank_t
*p_bank
, const char *psz_file
,
728 int64_t i_time
, int64_t i_size
)
730 module_cache_t
**pp_cache
;
733 pp_cache
= p_bank
->pp_loaded_cache
;
734 i_cache
= p_bank
->i_loaded_cache
;
736 for( i
= 0; i
< i_cache
; i
++ )
738 if( !strcmp( pp_cache
[i
]->psz_file
, psz_file
) &&
739 pp_cache
[i
]->i_time
== i_time
&&
740 pp_cache
[i
]->i_size
== i_size
) return pp_cache
[i
];
746 #endif /* HAVE_DYNAMIC_PLUGINS */