| 1 |
|
|---|
| 2 |
|
|---|
| 3 |
|
|---|
| 4 |
|
|---|
| 5 |
|
|---|
| 6 |
|
|---|
| 7 |
|
|---|
| 8 |
|
|---|
| 9 |
|
|---|
| 10 |
|
|---|
| 11 |
|
|---|
| 12 |
|
|---|
| 13 |
|
|---|
| 14 |
|
|---|
| 15 |
|
|---|
| 16 |
|
|---|
| 17 |
|
|---|
| 18 |
|
|---|
| 19 |
|
|---|
| 20 |
|
|---|
| 21 |
|
|---|
| 22 |
|
|---|
| 23 |
|
|---|
| 24 |
|
|---|
| 25 |
|
|---|
| 26 |
|
|---|
| 27 |
#ifdef HAVE_CONFIG_H |
|---|
| 28 |
# include "config.h" |
|---|
| 29 |
#endif |
|---|
| 30 |
|
|---|
| 31 |
#include <vlc_common.h> |
|---|
| 32 |
#include "libvlc.h" |
|---|
| 33 |
|
|---|
| 34 |
#include <stdlib.h> |
|---|
| 35 |
#include <stdio.h> |
|---|
| 36 |
#include <string.h> |
|---|
| 37 |
#include <vlc_plugin.h> |
|---|
| 38 |
|
|---|
| 39 |
#ifdef HAVE_SYS_TYPES_H |
|---|
| 40 |
# include <sys/types.h> |
|---|
| 41 |
#endif |
|---|
| 42 |
#ifdef HAVE_UNISTD_H |
|---|
| 43 |
# include <unistd.h> |
|---|
| 44 |
#endif |
|---|
| 45 |
|
|---|
| 46 |
#if !defined(HAVE_DYNAMIC_PLUGINS) |
|---|
| 47 |
|
|---|
| 48 |
#elif defined(HAVE_DL_DYLD) |
|---|
| 49 |
# if defined(HAVE_MACH_O_DYLD_H) |
|---|
| 50 |
# include <mach-o/dyld.h> |
|---|
| 51 |
# endif |
|---|
| 52 |
#elif defined(HAVE_DL_BEOS) |
|---|
| 53 |
# if defined(HAVE_IMAGE_H) |
|---|
| 54 |
# include <image.h> |
|---|
| 55 |
# endif |
|---|
| 56 |
#elif defined(HAVE_DL_WINDOWS) |
|---|
| 57 |
# include <windows.h> |
|---|
| 58 |
#elif defined(HAVE_DL_DLOPEN) |
|---|
| 59 |
# if defined(HAVE_DLFCN_H) |
|---|
| 60 |
# include <dlfcn.h> |
|---|
| 61 |
# endif |
|---|
| 62 |
# if defined(HAVE_SYS_DL_H) |
|---|
| 63 |
# include <sys/dl.h> |
|---|
| 64 |
# endif |
|---|
| 65 |
#elif defined(HAVE_DL_SHL_LOAD) |
|---|
| 66 |
# if defined(HAVE_DL_H) |
|---|
| 67 |
# include <dl.h> |
|---|
| 68 |
# endif |
|---|
| 69 |
#endif |
|---|
| 70 |
|
|---|
| 71 |
#include "config/configuration.h" |
|---|
| 72 |
|
|---|
| 73 |
#include "vlc_charset.h" |
|---|
| 74 |
|
|---|
| 75 |
#include "modules/modules.h" |
|---|
| 76 |
|
|---|
| 77 |
|
|---|
| 78 |
|
|---|
| 79 |
|
|---|
| 80 |
|
|---|
| 81 |
#ifdef HAVE_DYNAMIC_PLUGINS |
|---|
| 82 |
static int CacheLoadConfig ( module_t *, FILE * ); |
|---|
| 83 |
static int CacheSaveConfig ( module_t *, FILE * ); |
|---|
| 84 |
static char * CacheName ( void ); |
|---|
| 85 |
|
|---|
| 86 |
|
|---|
| 87 |
|
|---|
| 88 |
#define CACHE_SUBVERSION_NUM 3 |
|---|
| 89 |
|
|---|
| 90 |
|
|---|
| 91 |
|
|---|
| 92 |
|
|---|
| 93 |
|
|---|
| 94 |
|
|---|
| 95 |
|
|---|
| 96 |
|
|---|
| 97 |
|
|---|
| 98 |
void CacheLoad( vlc_object_t *p_this ) |
|---|
| 99 |
{ |
|---|
| 100 |
char *psz_filename, *psz_cachedir = config_GetCacheDir(); |
|---|
| 101 |
FILE *file; |
|---|
| 102 |
int i, j, i_size, i_read; |
|---|
| 103 |
char p_cachestring[sizeof("cache " COPYRIGHT_MESSAGE)]; |
|---|
| 104 |
char p_cachelang[6], p_lang[6]; |
|---|
| 105 |
int i_cache; |
|---|
| 106 |
module_cache_t **pp_cache = 0; |
|---|
| 107 |
int32_t i_file_size, i_marker; |
|---|
| 108 |
libvlc_global_data_t *p_libvlc_global = vlc_global(); |
|---|
| 109 |
|
|---|
| 110 |
if( !psz_cachedir ) |
|---|
| 111 |
{ |
|---|
| 112 |
msg_Err( p_this, "Unable to get cache directory" ); |
|---|
| 113 |
return; |
|---|
| 114 |
} |
|---|
| 115 |
|
|---|
| 116 |
if( asprintf( &psz_filename, "%s"DIR_SEP"%s", |
|---|
| 117 |
psz_cachedir, CacheName() ) == -1 ) |
|---|
| 118 |
{ |
|---|
| 119 |
free( psz_cachedir ); |
|---|
| 120 |
return; |
|---|
| 121 |
} |
|---|
| 122 |
free( psz_cachedir ); |
|---|
| 123 |
|
|---|
| 124 |
if( p_libvlc_global->p_module_bank->b_cache_delete ) |
|---|
| 125 |
{ |
|---|
| 126 |
#if !defined( UNDER_CE ) |
|---|
| 127 |
unlink( psz_filename ); |
|---|
| 128 |
#else |
|---|
| 129 |
wchar_t psz_wf[MAX_PATH]; |
|---|
| 130 |
MultiByteToWideChar( CP_ACP, 0, psz_filename, -1, psz_wf, MAX_PATH ); |
|---|
| 131 |
DeleteFile( psz_wf ); |
|---|
| 132 |
#endif |
|---|
| 133 |
msg_Dbg( p_this, "removing plugins cache file %s", psz_filename ); |
|---|
| 134 |
free( psz_filename ); |
|---|
| 135 |
return; |
|---|
| 136 |
} |
|---|
| 137 |
|
|---|
| 138 |
msg_Dbg( p_this, "loading plugins cache file %s", psz_filename ); |
|---|
| 139 |
|
|---|
| 140 |
file = utf8_fopen( psz_filename, "rb" ); |
|---|
| 141 |
if( !file ) |
|---|
| 142 |
{ |
|---|
| 143 |
msg_Warn( p_this, "could not open plugins cache file %s for reading", |
|---|
| 144 |
psz_filename ); |
|---|
| 145 |
free( psz_filename ); |
|---|
| 146 |
return; |
|---|
| 147 |
} |
|---|
| 148 |
free( psz_filename ); |
|---|
| 149 |
|
|---|
| 150 |
|
|---|
| 151 |
i_read = fread( &i_file_size, 1, sizeof(i_file_size), file ); |
|---|
| 152 |
if( i_read != sizeof(i_file_size) ) |
|---|
| 153 |
{ |
|---|
| 154 |
msg_Warn( p_this, "This doesn't look like a valid plugins cache " |
|---|
| 155 |
"(too short)" ); |
|---|
| 156 |
fclose( file ); |
|---|
| 157 |
return; |
|---|
| 158 |
} |
|---|
| 159 |
|
|---|
| 160 |
fseek( file, 0, SEEK_END ); |
|---|
| 161 |
if( ftell( file ) != i_file_size ) |
|---|
| 162 |
{ |
|---|
| 163 |
msg_Warn( p_this, "This doesn't look like a valid plugins cache " |
|---|
| 164 |
"(corrupted size)" ); |
|---|
| 165 |
fclose( file ); |
|---|
| 166 |
return; |
|---|
| 167 |
} |
|---|
| 168 |
fseek( file, sizeof(i_file_size), SEEK_SET ); |
|---|
| 169 |
|
|---|
| 170 |
|
|---|
| 171 |
i_size = sizeof("cache " COPYRIGHT_MESSAGE) - 1; |
|---|
| 172 |
i_read = fread( p_cachestring, 1, i_size, file ); |
|---|
| 173 |
if( i_read != i_size || |
|---|
| 174 |
memcmp( p_cachestring, "cache " COPYRIGHT_MESSAGE, i_size ) ) |
|---|
| 175 |
{ |
|---|
| 176 |
msg_Warn( p_this, "This doesn't look like a valid plugins cache" ); |
|---|
| 177 |
fclose( file ); |
|---|
| 178 |
return; |
|---|
| 179 |
} |
|---|
| 180 |
|
|---|
| 181 |
#ifdef DISTRO_VERSION |
|---|
| 182 |
|
|---|
| 183 |
char p_distrostring[sizeof( DISTRO_VERSION )]; |
|---|
| 184 |
i_size = sizeof( DISTRO_VERSION ) - 1; |
|---|
| 185 |
i_read = fread( p_distrostring, 1, i_size, file ); |
|---|
| 186 |
if( i_read != i_size || |
|---|
| 187 |
memcmp( p_distrostring, DISTRO_VERSION, i_size ) ) |
|---|
| 188 |
{ |
|---|
| 189 |
msg_Warn( p_this, "This doesn't look like a valid plugins cache" ); |
|---|
| 190 |
fclose( file ); |
|---|
| 191 |
return; |
|---|
| 192 |
} |
|---|
| 193 |
#endif |
|---|
| 194 |
|
|---|
| 195 |
|
|---|
| 196 |
i_read = fread( &i_marker, 1, sizeof(i_marker), file ); |
|---|
| 197 |
if( i_read != sizeof(i_marker) || i_marker != CACHE_SUBVERSION_NUM ) |
|---|
| 198 |
{ |
|---|
| 199 |
msg_Warn( p_this, "This doesn't look like a valid plugins cache " |
|---|
| 200 |
"(corrupted header)" ); |
|---|
| 201 |
fclose( file ); |
|---|
| 202 |
return; |
|---|
| 203 |
} |
|---|
| 204 |
|
|---|
| 205 |
|
|---|
| 206 |
sprintf( p_lang, "%5.5s", _("C") ); i_size = 5; |
|---|
| 207 |
i_read = fread( p_cachelang, 1, i_size, file ); |
|---|
| 208 |
if( i_read != i_size || memcmp( p_cachelang, p_lang, i_size ) ) |
|---|
| 209 |
{ |
|---|
| 210 |
msg_Warn( p_this, "This doesn't look like a valid plugins cache " |
|---|
| 211 |
"(language changed)" ); |
|---|
| 212 |
fclose( file ); |
|---|
| 213 |
return; |
|---|
| 214 |
} |
|---|
| 215 |
|
|---|
| 216 |
|
|---|
| 217 |
i_read = fread( &i_marker, 1, sizeof(i_marker), file ); |
|---|
| 218 |
if( i_read != sizeof(i_marker) || |
|---|
| 219 |
i_marker != ftell( file ) - (int)sizeof(i_marker) ) |
|---|
| 220 |
{ |
|---|
| 221 |
msg_Warn( p_this, "This doesn't look like a valid plugins cache " |
|---|
| 222 |
"(corrupted header)" ); |
|---|
| 223 |
fclose( file ); |
|---|
| 224 |
return; |
|---|
| 225 |
} |
|---|
| 226 |
|
|---|
| 227 |
p_libvlc_global->p_module_bank->i_loaded_cache = 0; |
|---|
| 228 |
if (fread( &i_cache, 1, sizeof(i_cache), file ) != sizeof(i_cache) ) |
|---|
| 229 |
{ |
|---|
| 230 |
msg_Warn( p_this, "This doesn't look like a valid plugins cache " |
|---|
| 231 |
"(file too short)" ); |
|---|
| 232 |
fclose( file ); |
|---|
| 233 |
return; |
|---|
| 234 |
} |
|---|
| 235 |
|
|---|
| 236 |
if( i_cache ) |
|---|
| 237 |
pp_cache = p_libvlc_global->p_module_bank->pp_loaded_cache = |
|---|
| 238 |
malloc( i_cache * sizeof(void *) ); |
|---|
| 239 |
|
|---|
| 240 |
#define LOAD_IMMEDIATE(a) \ |
|---|
| 241 |
if( fread( (void *)&a, sizeof(char), sizeof(a), file ) != sizeof(a) ) goto error |
|---|
| 242 |
#define LOAD_STRING(a) \ |
|---|
| 243 |
{ \ |
|---|
| 244 |
a = NULL; \ |
|---|
| 245 |
if( ( fread( &i_size, sizeof(i_size), 1, file ) != 1 ) \ |
|---|
| 246 |
|| ( i_size > 16384 ) ) \ |
|---|
| 247 |
goto error; \ |
|---|
| 248 |
if( i_size ) { \ |
|---|
| 249 |
char *psz = malloc( i_size ); \ |
|---|
| 250 |
if( fread( psz, i_size, 1, file ) != 1 ) { \ |
|---|
| 251 |
free( psz ); \ |
|---|
| 252 |
goto error; \ |
|---|
| 253 |
} \ |
|---|
| 254 |
if( psz[i_size-1] ) { \ |
|---|
| 255 |
free( psz ); \ |
|---|
| 256 |
goto error; \ |
|---|
| 257 |
} \ |
|---|
| 258 |
a = psz; \ |
|---|
| 259 |
} \ |
|---|
| 260 |
} |
|---|
| 261 |
|
|---|
| 262 |
for( i = 0; i < i_cache; i++ ) |
|---|
| 263 |
{ |
|---|
| 264 |
uint16_t i_size; |
|---|
| 265 |
int i_submodules; |
|---|
| 266 |
|
|---|
| 267 |
pp_cache[i] = malloc( sizeof(module_cache_t) ); |
|---|
| 268 |
p_libvlc_global->p_module_bank->i_loaded_cache++; |
|---|
| 269 |
|
|---|
| 270 |
|
|---|
| 271 |
LOAD_STRING( pp_cache[i]->psz_file ); |
|---|
| 272 |
LOAD_IMMEDIATE( pp_cache[i]->i_time ); |
|---|
| 273 |
LOAD_IMMEDIATE( pp_cache[i]->i_size ); |
|---|
| 274 |
LOAD_IMMEDIATE( pp_cache[i]->b_junk ); |
|---|
| 275 |
pp_cache[i]->b_used = false; |
|---|
| 276 |
|
|---|
| 277 |
if( pp_cache[i]->b_junk ) continue; |
|---|
| 278 |
|
|---|
| 279 |
pp_cache[i]->p_module = vlc_module_create( p_this ); |
|---|
| 280 |
|
|---|
| 281 |
|
|---|
| 282 |
free( pp_cache[i]->p_module->psz_object_name ); |
|---|
| 283 |
LOAD_STRING( pp_cache[i]->p_module->psz_object_name ); |
|---|
| 284 |
LOAD_STRING( pp_cache[i]->p_module->psz_shortname ); |
|---|
| 285 |
LOAD_STRING( pp_cache[i]->p_module->psz_longname ); |
|---|
| 286 |
LOAD_STRING( pp_cache[i]->p_module->psz_help ); |
|---|
| 287 |
for( j = 0; j < MODULE_SHORTCUT_MAX; j++ ) |
|---|
| 288 |
{ |
|---|
| 289 |
LOAD_STRING( pp_cache[i]->p_module->pp_shortcuts[j] ); |
|---|
| 290 |
} |
|---|
| 291 |
LOAD_STRING( pp_cache[i]->p_module->psz_capability ); |
|---|
| 292 |
LOAD_IMMEDIATE( pp_cache[i]->p_module->i_score ); |
|---|
| 293 |
LOAD_IMMEDIATE( pp_cache[i]->p_module->i_cpu ); |
|---|
| 294 |
LOAD_IMMEDIATE( pp_cache[i]->p_module->b_unloadable ); |
|---|
| 295 |
LOAD_IMMEDIATE( pp_cache[i]->p_module->b_reentrant ); |
|---|
| 296 |
LOAD_IMMEDIATE( pp_cache[i]->p_module->b_submodule ); |
|---|
| 297 |
|
|---|
| 298 |
|
|---|
| 299 |
if( CacheLoadConfig( pp_cache[i]->p_module, file ) != VLC_SUCCESS ) |
|---|
| 300 |
goto error; |
|---|
| 301 |
|
|---|
| 302 |
LOAD_STRING( pp_cache[i]->p_module->psz_filename ); |
|---|
| 303 |
|
|---|
| 304 |
LOAD_IMMEDIATE( i_submodules ); |
|---|
| 305 |
|
|---|
| 306 |
while( i_submodules-- ) |
|---|
| 307 |
{ |
|---|
| 308 |
module_t *p_module = vlc_submodule_create( pp_cache[i]->p_module ); |
|---|
| 309 |
free( p_module->psz_object_name ); |
|---|
| 310 |
LOAD_STRING( p_module->psz_object_name ); |
|---|
| 311 |
LOAD_STRING( p_module->psz_shortname ); |
|---|
| 312 |
LOAD_STRING( p_module->psz_longname ); |
|---|
| 313 |
LOAD_STRING( p_module->psz_help ); |
|---|
| 314 |
for( j = 0; j < MODULE_SHORTCUT_MAX; j++ ) |
|---|
| 315 |
{ |
|---|
| 316 |
LOAD_STRING( p_module->pp_shortcuts[j] ); |
|---|
| 317 |
} |
|---|
| 318 |
LOAD_STRING( p_module->psz_capability ); |
|---|
| 319 |
LOAD_IMMEDIATE( p_module->i_score ); |
|---|
| 320 |
LOAD_IMMEDIATE( p_module->i_cpu ); |
|---|
| 321 |
LOAD_IMMEDIATE( p_module->b_unloadable ); |
|---|
| 322 |
LOAD_IMMEDIATE( p_module->b_reentrant ); |
|---|
| 323 |
} |
|---|
| 324 |
} |
|---|
| 325 |
|
|---|
| 326 |
fclose( file ); |
|---|
| 327 |
return; |
|---|
| 328 |
|
|---|
| 329 |
error: |
|---|
| 330 |
|
|---|
| 331 |
msg_Warn( p_this, "plugins cache not loaded (corrupted)" ); |
|---|
| 332 |
|
|---|
| 333 |
|
|---|
| 334 |
p_libvlc_global->p_module_bank->i_loaded_cache = 0; |
|---|
| 335 |
|
|---|
| 336 |
fclose( file ); |
|---|
| 337 |
return; |
|---|
| 338 |
} |
|---|
| 339 |
|
|---|
| 340 |
|
|---|
| 341 |
static int CacheLoadConfig( module_t *p_module, FILE *file ) |
|---|
| 342 |
{ |
|---|
| 343 |
uint32_t i_lines; |
|---|
| 344 |
uint16_t i_size; |
|---|
| 345 |
|
|---|
| 346 |
|
|---|
| 347 |
LOAD_IMMEDIATE( p_module->i_config_items ); |
|---|
| 348 |
LOAD_IMMEDIATE( p_module->i_bool_items ); |
|---|
| 349 |
|
|---|
| 350 |
LOAD_IMMEDIATE( i_lines ); |
|---|
| 351 |
|
|---|
| 352 |
|
|---|
| 353 |
if (i_lines) |
|---|
| 354 |
{ |
|---|
| 355 |
p_module->p_config = |
|---|
| 356 |
(module_config_t *)calloc( i_lines, sizeof(module_config_t) ); |
|---|
| 357 |
if( p_module->p_config == NULL ) |
|---|
| 358 |
{ |
|---|
| 359 |
p_module->confsize = 0; |
|---|
| 360 |
msg_Err( p_module, "config error: can't duplicate p_config" ); |
|---|
| 361 |
return VLC_ENOMEM; |
|---|
| 362 |
} |
|---|
| 363 |
} |
|---|
| 364 |
p_module->confsize = i_lines; |
|---|
| 365 |
|
|---|
| 366 |
|
|---|
| 367 |
for (size_t i = 0; i < i_lines; i++ ) |
|---|
| 368 |
{ |
|---|
| 369 |
LOAD_IMMEDIATE( p_module->p_config[i] ); |
|---|
| 370 |
|
|---|
| 371 |
LOAD_STRING( p_module->p_config[i].psz_type ); |
|---|
| 372 |
LOAD_STRING( p_module->p_config[i].psz_name ); |
|---|
| 373 |
LOAD_STRING( p_module->p_config[i].psz_text ); |
|---|
| 374 |
LOAD_STRING( p_module->p_config[i].psz_longtext ); |
|---|
| 375 |
LOAD_STRING( p_module->p_config[i].psz_oldname ); |
|---|
| 376 |
LOAD_IMMEDIATE( p_module->p_config[i].b_removed ); |
|---|
| 377 |
|
|---|
| 378 |
if (IsConfigStringType (p_module->p_config[i].i_type)) |
|---|
| 379 |
{ |
|---|
| 380 |
LOAD_STRING (p_module->p_config[i].orig.psz); |
|---|
| 381 |
p_module->p_config[i].value.psz = |
|---|
| 382 |
(p_module->p_config[i].orig.psz != NULL) |
|---|
| 383 |
? strdup (p_module->p_config[i].orig.psz) : NULL; |
|---|
| 384 |
p_module->p_config[i].saved.psz = NULL; |
|---|
| 385 |
} |
|---|
| 386 |
else |
|---|
| 387 |
{ |
|---|
| 388 |
memcpy (&p_module->p_config[i].value, &p_module->p_config[i].orig, |
|---|
| 389 |
sizeof (p_module->p_config[i].value)); |
|---|
| 390 |
memcpy (&p_module->p_config[i].saved, &p_module->p_config[i].orig, |
|---|
| 391 |
sizeof (p_module->p_config[i].saved)); |
|---|
| 392 |
} |
|---|
| 393 |
|
|---|
| 394 |
p_module->p_config[i].b_dirty = false; |
|---|
| 395 |
|
|---|
| 396 |
p_module->p_config[i].p_lock = &(vlc_internals(p_module)->lock); |
|---|
| 397 |
|
|---|
| 398 |
if( p_module->p_config[i].i_list ) |
|---|
| 399 |
{ |
|---|
| 400 |
if( p_module->p_config[i].ppsz_list ) |
|---|
| 401 |
{ |
|---|
| 402 |
int j; |
|---|
| 403 |
p_module->p_config[i].ppsz_list = |
|---|
| 404 |
malloc( (p_module->p_config[i].i_list+1) * sizeof(char *)); |
|---|
| 405 |
if( p_module->p_config[i].ppsz_list ) |
|---|
| 406 |
{ |
|---|
| 407 |
for( j = 0; j < p_module->p_config[i].i_list; j++ ) |
|---|
| 408 |
LOAD_STRING( p_module->p_config[i].ppsz_list[j] ); |
|---|
| 409 |
p_module->p_config[i].ppsz_list[j] = NULL; |
|---|
| 410 |
} |
|---|
| 411 |
} |
|---|
| 412 |
if( p_module->p_config[i].ppsz_list_text ) |
|---|
| 413 |
{ |
|---|
| 414 |
int j; |
|---|
| 415 |
p_module->p_config[i].ppsz_list_text = |
|---|
| 416 |
malloc( (p_module->p_config[i].i_list+1) * sizeof(char *)); |
|---|
| 417 |
if( p_module->p_config[i].ppsz_list_text ) |
|---|
| 418 |
{ |
|---|
| 419 |
for( j = 0; j < p_module->p_config[i].i_list; j++ ) |
|---|
| 420 |
LOAD_STRING( p_module->p_config[i].ppsz_list_text[j] ); |
|---|
| 421 |
p_module->p_config[i].ppsz_list_text[j] = NULL; |
|---|
| 422 |
} |
|---|
| 423 |
} |
|---|
| 424 |
if( p_module->p_config[i].pi_list ) |
|---|
| 425 |
{ |
|---|
| 426 |
p_module->p_config[i].pi_list = |
|---|
| 427 |
malloc( (p_module->p_config[i].i_list + 1) * sizeof(int) ); |
|---|
| 428 |
if( p_module->p_config[i].pi_list ) |
|---|
| 429 |
{ |
|---|
| 430 |
for (int j = 0; j < p_module->p_config[i].i_list; j++) |
|---|
| 431 |
LOAD_IMMEDIATE( p_module->p_config[i].pi_list[j] ); |
|---|
| 432 |
} |
|---|
| 433 |
} |
|---|
| 434 |
} |
|---|
| 435 |
|
|---|
| 436 |
if( p_module->p_config[i].i_action ) |
|---|
| 437 |
{ |
|---|
| 438 |
p_module->p_config[i].ppf_action = |
|---|
| 439 |
malloc( p_module->p_config[i].i_action * sizeof(void *) ); |
|---|
| 440 |
p_module->p_config[i].ppsz_action_text = |
|---|
| 441 |
malloc( p_module->p_config[i].i_action * sizeof(char *) ); |
|---|
| 442 |
|
|---|
| 443 |
for (int j = 0; j < p_module->p_config[i].i_action; j++) |
|---|
| 444 |
{ |
|---|
| 445 |
p_module->p_config[i].ppf_action[j] = 0; |
|---|
| 446 |
LOAD_STRING( p_module->p_config[i].ppsz_action_text[j] ); |
|---|
| 447 |
} |
|---|
| 448 |
} |
|---|
| 449 |
|
|---|
| 450 |
LOAD_IMMEDIATE( p_module->p_config[i].pf_callback ); |
|---|
| 451 |
} |
|---|
| 452 |
|
|---|
| 453 |
return VLC_SUCCESS; |
|---|
| 454 |
|
|---|
| 455 |
error: |
|---|
| 456 |
|
|---|
| 457 |
return VLC_EGENERIC; |
|---|
| 458 |
} |
|---|
| 459 |
|
|---|
| 460 |
|
|---|
| 461 |
|
|---|
| 462 |
|
|---|
| 463 |
void CacheSave( vlc_object_t *p_this ) |
|---|
| 464 |
{ |
|---|
| 465 |
static char const psz_tag[] = |
|---|
| 466 |
"Signature: 8a477f597d28d172789f06886806bc55\r\n" |
|---|
| 467 |
"# This file is a cache directory tag created by VLC.\r\n" |
|---|
| 468 |
"# For information about cache directory tags, see:\r\n" |
|---|
| 469 |
"# http://www.brynosaurus.com/cachedir/\r\n"; |
|---|
| 470 |
|
|---|
| 471 |
char *psz_cachedir = config_GetCacheDir(); |
|---|
| 472 |
FILE *file; |
|---|
| 473 |
int i, j, i_cache; |
|---|
| 474 |
module_cache_t **pp_cache; |
|---|
| 475 |
uint32_t i_file_size = 0; |
|---|
| 476 |
libvlc_global_data_t *p_libvlc_global = vlc_global(); |
|---|
| 477 |
|
|---|
| 478 |
if( !psz_cachedir ) |
|---|
| 479 |
{ |
|---|
| 480 |
msg_Err( p_this, "unable to get cache directory" ); |
|---|
| 481 |
return; |
|---|
| 482 |
} |
|---|
| 483 |
|
|---|
| 484 |
char psz_filename[sizeof(DIR_SEP) + 32 + strlen(psz_cachedir)]; |
|---|
| 485 |
config_CreateDir( p_this, psz_cachedir ); |
|---|
| 486 |
|
|---|
| 487 |
snprintf( psz_filename, sizeof( psz_filename ), |
|---|
| 488 |
"%s"DIR_SEP"CACHEDIR.TAG", psz_cachedir ); |
|---|
| 489 |
file = utf8_fopen( psz_filename, "wb" ); |
|---|
| 490 |
if (file != NULL) |
|---|
| 491 |
{ |
|---|
| 492 |
if (fwrite (psz_tag, 1, sizeof (psz_tag) - 1, file) != 1) |
|---|
| 493 |
clearerr (file); |
|---|
| 494 |
fclose( file ); |
|---|
| 495 |
} |
|---|
| 496 |
|
|---|
| 497 |
snprintf( psz_filename, sizeof( psz_filename ), |
|---|
| 498 |
"%s"DIR_SEP"%s", psz_cachedir, CacheName() ); |
|---|
| 499 |
free( psz_cachedir ); |
|---|
| 500 |
msg_Dbg( p_this, "writing plugins cache %s", psz_filename ); |
|---|
| 501 |
|
|---|
| 502 |
file = utf8_fopen( psz_filename, "wb" ); |
|---|
| 503 |
if (file == NULL) |
|---|
| 504 |
goto error; |
|---|
| 505 |
|
|---|
| 506 |
|
|---|
| 507 |
if (fwrite (&i_file_size, sizeof (i_file_size), 1, file) != 1) |
|---|
| 508 |
goto error; |
|---|
| 509 |
|
|---|
| 510 |
|
|---|
| 511 |
if (fputs ("cache "COPYRIGHT_MESSAGE, file) == EOF) |
|---|
| 512 |
goto error; |
|---|
| 513 |
#ifdef DISTRO_VERSION |
|---|
| 514 |
|
|---|
| 515 |
if (fputs( DISTRO_VERSION, file ) == EOF) |
|---|
| 516 |
goto error; |
|---|
| 517 |
#endif |
|---|
| 518 |
|
|---|
| 519 |
|
|---|
| 520 |
i_file_size = CACHE_SUBVERSION_NUM; |
|---|
| 521 |
if (fwrite (&i_file_size, sizeof (i_file_size), 1, file) != 1 ) |
|---|
| 522 |
goto error; |
|---|
| 523 |
|
|---|
| 524 |
|
|---|
| 525 |
if (fprintf (file, "%5.5s", _("C")) == EOF) |
|---|
| 526 |
goto error; |
|---|
| 527 |
|
|---|
| 528 |
|
|---|
| 529 |
i_file_size = ftell( file ); |
|---|
| 530 |
if (fwrite (&i_file_size, sizeof (i_file_size), 1, file) != 1) |
|---|
| 531 |
goto error; |
|---|
| 532 |
|
|---|
| 533 |
i_cache = p_libvlc_global->p_module_bank->i_cache; |
|---|
| 534 |
pp_cache = p_libvlc_global->p_module_bank->pp_cache; |
|---|
| 535 |
|
|---|
| 536 |
if (fwrite( &i_cache, sizeof (i_cache), 1, file) != 1) |
|---|
| 537 |
goto error; |
|---|
| 538 |
|
|---|
| 539 |
#define SAVE_IMMEDIATE( a ) \ |
|---|
| 540 |
if (fwrite (&a, sizeof(a), 1, file) != 1) \ |
|---|
| 541 |
goto error |
|---|
| 542 |
#define SAVE_STRING( a ) \ |
|---|
| 543 |
{ \ |
|---|
| 544 |
uint16_t i_size = (a != NULL) ? (strlen (a) + 1) : 0; \ |
|---|
| 545 |
if ((fwrite (&i_size, sizeof (i_size), 1, file) != 1) \ |
|---|
| 546 |
|| (a && (fwrite (a, 1, i_size, file) != i_size))) \ |
|---|
| 547 |
goto error; \ |
|---|
| 548 |
} while(0) |
|---|
| 549 |
|
|---|
| 550 |
for( i = 0; i < i_cache; i++ ) |
|---|
| 551 |
{ |
|---|
| 552 |
uint32_t i_submodule; |
|---|
| 553 |
|
|---|
| 554 |
|
|---|
| 555 |
SAVE_STRING( pp_cache[i]->psz_file ); |
|---|
| 556 |
SAVE_IMMEDIATE( pp_cache[i]->i_time ); |
|---|
| 557 |
SAVE_IMMEDIATE( pp_cache[i]->i_size ); |
|---|
| 558 |
SAVE_IMMEDIATE( pp_cache[i]->b_junk ); |
|---|
| 559 |
|
|---|
| 560 |
if( pp_cache[i]->b_junk ) continue; |
|---|
| 561 |
|
|---|
| 562 |
|
|---|
| 563 |
SAVE_STRING( pp_cache[i]->p_module->psz_object_name ); |
|---|
| 564 |
SAVE_STRING( pp_cache[i]->p_module->psz_shortname ); |
|---|
| 565 |
SAVE_STRING( pp_cache[i]->p_module->psz_longname ); |
|---|
| 566 |
SAVE_STRING( pp_cache[i]->p_module->psz_help ); |
|---|
| 567 |
for( j = 0; j < MODULE_SHORTCUT_MAX; j++ ) |
|---|
| 568 |
{ |
|---|
| 569 |
SAVE_STRING( pp_cache[i]->p_module->pp_shortcuts[j] ); |
|---|
| 570 |
} |
|---|
| 571 |
SAVE_STRING( pp_cache[i]->p_module->psz_capability ); |
|---|
| 572 |
SAVE_IMMEDIATE( pp_cache[i]->p_module->i_score ); |
|---|
| 573 |
SAVE_IMMEDIATE( pp_cache[i]->p_module->i_cpu ); |
|---|
| 574 |
SAVE_IMMEDIATE( pp_cache[i]->p_module->b_unloadable ); |
|---|
| 575 |
SAVE_IMMEDIATE( pp_cache[i]->p_module->b_reentrant ); |
|---|
| 576 |
SAVE_IMMEDIATE( pp_cache[i]->p_module->b_submodule ); |
|---|
| 577 |
|
|---|
| 578 |
|
|---|
| 579 |
if (CacheSaveConfig (pp_cache[i]->p_module, file)) |
|---|
| 580 |
goto error; |
|---|
| 581 |
|
|---|
| 582 |
SAVE_STRING( pp_cache[i]->p_module->psz_filename ); |
|---|
| 583 |
|
|---|
| 584 |
i_submodule = vlc_internals( pp_cache[i]->p_module )->i_children; |
|---|
| 585 |
SAVE_IMMEDIATE( i_submodule ); |
|---|
| 586 |
for( i_submodule = 0; |
|---|
| 587 |
i_submodule < (unsigned)vlc_internals( pp_cache[i]->p_module)->i_children; |
|---|
| 588 |
i_submodule++ ) |
|---|
| 589 |
{ |
|---|
| 590 |
module_t *p_module = |
|---|
| 591 |
(module_t *)vlc_internals( pp_cache[i]->p_module )->pp_children[i_submodule]; |
|---|
| 592 |
|
|---|
| 593 |
SAVE_STRING( p_module->psz_object_name ); |
|---|
| 594 |
SAVE_STRING( p_module->psz_shortname ); |
|---|
| 595 |
SAVE_STRING( p_module->psz_longname ); |
|---|
| 596 |
SAVE_STRING( p_module->psz_help ); |
|---|
| 597 |
for( j = 0; j < MODULE_SHORTCUT_MAX; j++ ) |
|---|
| 598 |
{ |
|---|
| 599 |
SAVE_STRING( p_module->pp_shortcuts[j] ); |
|---|
| 600 |
} |
|---|
| 601 |
SAVE_STRING( p_module->psz_capability ); |
|---|
| 602 |
SAVE_IMMEDIATE( p_module->i_score ); |
|---|
| 603 |
SAVE_IMMEDIATE( p_module->i_cpu ); |
|---|
| 604 |
SAVE_IMMEDIATE( p_module->b_unloadable ); |
|---|
| 605 |
SAVE_IMMEDIATE( p_module->b_reentrant ); |
|---|
| 606 |
} |
|---|
| 607 |
} |
|---|
| 608 |
|
|---|
| 609 |
|
|---|
| 610 |
i_file_size = ftell( file ); |
|---|
| 611 |
fseek( file, 0, SEEK_SET ); |
|---|
| 612 |
if (fwrite (&i_file_size, sizeof (i_file_size), 1, file) != 1) |
|---|
| 613 |
goto error; |
|---|
| 614 |
|
|---|
| 615 |
if (fclose (file) == 0) |
|---|
| 616 |
return; |
|---|
| 617 |
|
|---|
| 618 |
file = NULL; |
|---|
| 619 |
error: |
|---|
| 620 |
msg_Warn (p_this, "could not write plugins cache %s (%m)", |
|---|
| 621 |
psz_filename); |
|---|
| 622 |
if (file != NULL) |
|---|
| 623 |
{ |
|---|
| 624 |
clearerr (file); |
|---|
| 625 |
fclose (file); |
|---|
| 626 |
} |
|---|
| 627 |
} |
|---|
| 628 |
|
|---|
| 629 |
static int CacheSaveConfig( module_t *p_module, FILE *file ) |
|---|
| 630 |
{ |
|---|
| 631 |
uint32_t i_lines = p_module->confsize; |
|---|
| 632 |
|
|---|
| 633 |
SAVE_IMMEDIATE( p_module->i_config_items ); |
|---|
| 634 |
SAVE_IMMEDIATE( p_module->i_bool_items ); |
|---|
| 635 |
SAVE_IMMEDIATE( i_lines ); |
|---|
| 636 |
|
|---|
| 637 |
for (size_t i = 0; i < i_lines ; i++) |
|---|
| 638 |
{ |
|---|
| 639 |
SAVE_IMMEDIATE( p_module->p_config[i] ); |
|---|
| 640 |
|
|---|
| 641 |
SAVE_STRING( p_module->p_config[i].psz_type ); |
|---|
| 642 |
SAVE_STRING( p_module->p_config[i].psz_name ); |
|---|
| 643 |
SAVE_STRING( p_module->p_config[i].psz_text ); |
|---|
| 644 |
SAVE_STRING( p_module->p_config[i].psz_longtext ); |
|---|
| 645 |
SAVE_STRING( p_module->p_config[i].psz_oldname ); |
|---|
| 646 |
SAVE_IMMEDIATE( p_module->p_config[i].b_removed ); |
|---|
| 647 |
|
|---|
| 648 |
if (IsConfigStringType (p_module->p_config[i].i_type)) |
|---|
| 649 |
SAVE_STRING( p_module->p_config[i].orig.psz ); |
|---|
| 650 |
|
|---|
| 651 |
if( p_module->p_config[i].i_list ) |
|---|
| 652 |
{ |
|---|
| 653 |
if( p_module->p_config[i].ppsz_list ) |
|---|
| 654 |
{ |
|---|
| 655 |
for (int j = 0; j < p_module->p_config[i].i_list; j++) |
|---|
| 656 |
SAVE_STRING( p_module->p_config[i].ppsz_list[j] ); |
|---|
| 657 |
} |
|---|
| 658 |
|
|---|
| 659 |
if( p_module->p_config[i].ppsz_list_text ) |
|---|
| 660 |
{ |
|---|
| 661 |
for (int j = 0; j < p_module->p_config[i].i_list; j++) |
|---|
| 662 |
SAVE_STRING( p_module->p_config[i].ppsz_list_text[j] ); |
|---|
| 663 |
} |
|---|
| 664 |
if( p_module->p_config[i].pi_list ) |
|---|
| 665 |
{ |
|---|
| 666 |
for (int j = 0; j < p_module->p_config[i].i_list; j++) |
|---|
| 667 |
SAVE_IMMEDIATE( p_module->p_config[i].pi_list[j] ); |
|---|
| 668 |
} |
|---|
| 669 |
} |
|---|
| 670 |
|
|---|
| 671 |
for (int j = 0; j < p_module->p_config[i].i_action; j++) |
|---|
| 672 |
SAVE_STRING( p_module->p_config[i].ppsz_action_text[j] ); |
|---|
| 673 |
|
|---|
| 674 |
SAVE_IMMEDIATE( p_module->p_config[i].pf_callback ); |
|---|
| 675 |
} |
|---|
| 676 |
return 0; |
|---|
| 677 |
|
|---|
| 678 |
error: |
|---|
| 679 |
return -1; |
|---|
| 680 |
} |
|---|
| 681 |
|
|---|
| 682 |
|
|---|
| 683 |
|
|---|
| 684 |
|
|---|
| 685 |
static char *CacheName( void ) |
|---|
| 686 |
{ |
|---|
| 687 |
static char psz_cachename[32]; |
|---|
| 688 |
|
|---|
| 689 |
|
|---|
| 690 |
int32_t x = 0xbe00001e; |
|---|
| 691 |
sprintf( psz_cachename, "plugins-%.2x%.2x%.2x.dat", (int)sizeof(int), |
|---|
| 692 |
(int)sizeof(void *), (unsigned int)((unsigned char *)&x)[0] ); |
|---|
| 693 |
return psz_cachename; |
|---|
| 694 |
} |
|---|
| 695 |
|
|---|
| 696 |
|
|---|
| 697 |
|
|---|
| 698 |
|
|---|
| 699 |
void CacheMerge( vlc_object_t *p_this, module_t *p_cache, module_t *p_module ) |
|---|
| 700 |
{ |
|---|
| 701 |
int i_submodule; |
|---|
| 702 |
(void)p_this; |
|---|
| 703 |
|
|---|
| 704 |
p_cache->pf_activate = p_module->pf_activate; |
|---|
| 705 |
p_cache->pf_deactivate = p_module->pf_deactivate; |
|---|
| 706 |
p_cache->handle = p_module->handle; |
|---|
| 707 |
|
|---|
| 708 |
for( i_submodule = 0; i_submodule < vlc_internals( p_module )->i_children; i_submodule++ ) |
|---|
| 709 |
{ |
|---|
| 710 |
module_t *p_child = (module_t*)vlc_internals( p_module )->pp_children[i_submodule]; |
|---|
| 711 |
module_t *p_cchild = (module_t*)vlc_internals( p_cache )->pp_children[i_submodule]; |
|---|
| 712 |
p_cchild->pf_activate = p_child->pf_activate; |
|---|
| 713 |
p_cchild->pf_deactivate = p_child->pf_deactivate; |
|---|
| 714 |
} |
|---|
| 715 |
|
|---|
| 716 |
p_cache->b_loaded = true; |
|---|
| 717 |
p_module->b_loaded = false; |
|---|
| 718 |
} |
|---|
| 719 |
|
|---|
| 720 |
|
|---|
| 721 |
|
|---|
| 722 |
|
|---|
| 723 |
module_cache_t *CacheFind( const char *psz_file, |
|---|
| 724 |
int64_t i_time, int64_t i_size ) |
|---|
| 725 |
{ |
|---|
| 726 |
module_cache_t **pp_cache; |
|---|
| 727 |
int i_cache, i; |
|---|
| 728 |
libvlc_global_data_t *p_libvlc_global = vlc_global(); |
|---|
| 729 |
|
|---|
| 730 |
pp_cache = p_libvlc_global->p_module_bank->pp_loaded_cache; |
|---|
| 731 |
i_cache = p_libvlc_global->p_module_bank->i_loaded_cache; |
|---|
| 732 |
|
|---|
| 733 |
for( i = 0; i < i_cache; i++ ) |
|---|
| 734 |
{ |
|---|
| 735 |
if( !strcmp( pp_cache[i]->psz_file, psz_file ) && |
|---|
| 736 |
pp_cache[i]->i_time == i_time && |
|---|
| 737 |
pp_cache[i]->i_size == i_size ) return pp_cache[i]; |
|---|
| 738 |
} |
|---|
| 739 |
|
|---|
| 740 |
return NULL; |
|---|
| 741 |
} |
|---|
| 742 |
|
|---|
| 743 |
#endif |
|---|