| 1332 | | |
|---|
| 1333 | | #ifdef HAVE_DYNAMIC_PLUGINS |
|---|
| 1334 | | /***************************************************************************** |
|---|
| 1335 | | * CallEntry: call an entry point. |
|---|
| 1336 | | ***************************************************************************** |
|---|
| 1337 | | * This function calls a symbol given its name and a module structure. The |
|---|
| 1338 | | * symbol MUST refer to a function returning int and taking a module_t* as |
|---|
| 1339 | | * an argument. |
|---|
| 1340 | | *****************************************************************************/ |
|---|
| 1341 | | static int CallEntry( module_t * p_module ) |
|---|
| 1342 | | { |
|---|
| 1343 | | static const char psz_name[] = "vlc_entry" MODULE_SUFFIX; |
|---|
| 1344 | | int (* pf_symbol) ( module_t * p_module ); |
|---|
| 1345 | | |
|---|
| 1346 | | /* Try to resolve the symbol */ |
|---|
| 1347 | | pf_symbol = (int (*)(module_t *)) GetSymbol( p_module->handle, psz_name ); |
|---|
| 1348 | | |
|---|
| 1349 | | if( pf_symbol == NULL ) |
|---|
| 1350 | | { |
|---|
| 1351 | | #if defined(HAVE_DL_DYLD) || defined(HAVE_DL_BEOS) |
|---|
| 1352 | | msg_Warn( p_module, "cannot find symbol \"%s\" in file `%s'", |
|---|
| 1353 | | psz_name, p_module->psz_filename ); |
|---|
| 1354 | | #elif defined(HAVE_DL_WINDOWS) |
|---|
| 1355 | | char *psz_error = GetWindowsError(); |
|---|
| 1356 | | msg_Warn( p_module, "cannot find symbol \"%s\" in file `%s' (%s)", |
|---|
| 1357 | | psz_name, p_module->psz_filename, psz_error ); |
|---|
| 1358 | | free( psz_error ); |
|---|
| 1359 | | #elif defined(HAVE_DL_DLOPEN) |
|---|
| 1360 | | msg_Warn( p_module, "cannot find symbol \"%s\" in file `%s' (%s)", |
|---|
| 1361 | | psz_name, p_module->psz_filename, dlerror() ); |
|---|
| 1362 | | #elif defined(HAVE_DL_SHL_LOAD) |
|---|
| 1363 | | msg_Warn( p_module, "cannot find symbol \"%s\" in file `%s' (%m)", |
|---|
| 1364 | | psz_name, p_module->psz_filename ); |
|---|
| 1365 | | #else |
|---|
| 1366 | | # error "Something is wrong in modules.c" |
|---|
| 1367 | | #endif |
|---|
| 1368 | | return -1; |
|---|
| 1369 | | } |
|---|
| 1370 | | |
|---|
| 1371 | | /* We can now try to call the symbol */ |
|---|
| 1372 | | if( pf_symbol( p_module ) != 0 ) |
|---|
| 1373 | | { |
|---|
| 1374 | | /* With a well-written module we shouldn't have to print an |
|---|
| 1375 | | * additional error message here, but just make sure. */ |
|---|
| 1376 | | msg_Err( p_module, "Failed to call symbol \"%s\" in file `%s'", |
|---|
| 1377 | | psz_name, p_module->psz_filename ); |
|---|
| 1378 | | return -1; |
|---|
| 1379 | | } |
|---|
| 1380 | | |
|---|
| 1381 | | /* Everything worked fine, we can return */ |
|---|
| 1382 | | return 0; |
|---|
| 1383 | | } |
|---|
| 1384 | | |
|---|
| 1385 | | /***************************************************************************** |
|---|
| 1386 | | * LoadModule: loads a dynamic library |
|---|
| 1387 | | ***************************************************************************** |
|---|
| 1388 | | * This function loads a dynamically linked library using a system dependant |
|---|
| 1389 | | * method. Will return 0 on success as well as the module handle. |
|---|
| 1390 | | *****************************************************************************/ |
|---|
| 1391 | | static int LoadModule( vlc_object_t *p_this, char *psz_file, |
|---|
| 1392 | | module_handle_t *p_handle ) |
|---|
| 1393 | | { |
|---|
| 1394 | | module_handle_t handle; |
|---|
| 1395 | | |
|---|
| 1396 | | #if defined(HAVE_DL_DYLD) |
|---|
| 1397 | | NSObjectFileImage image; |
|---|
| 1398 | | NSObjectFileImageReturnCode ret; |
|---|
| 1399 | | |
|---|
| 1400 | | ret = NSCreateObjectFileImageFromFile( psz_file, &image ); |
|---|
| 1401 | | |
|---|
| 1402 | | if( ret != NSObjectFileImageSuccess ) |
|---|
| 1403 | | { |
|---|
| 1404 | | msg_Warn( p_this, "cannot create image from `%s'", psz_file ); |
|---|
| 1405 | | return -1; |
|---|
| 1406 | | } |
|---|
| 1407 | | |
|---|
| 1408 | | /* Open the dynamic module */ |
|---|
| 1409 | | handle = NSLinkModule( image, psz_file, |
|---|
| 1410 | | NSLINKMODULE_OPTION_RETURN_ON_ERROR ); |
|---|
| 1411 | | |
|---|
| 1412 | | if( !handle ) |
|---|
| 1413 | | { |
|---|
| 1414 | | NSLinkEditErrors errors; |
|---|
| 1415 | | const char *psz_file, *psz_err; |
|---|
| 1416 | | int i_errnum; |
|---|
| 1417 | | NSLinkEditError( &errors, &i_errnum, &psz_file, &psz_err ); |
|---|
| 1418 | | msg_Warn( p_this, "cannot link module `%s' (%s)", psz_file, psz_err ); |
|---|
| 1419 | | NSDestroyObjectFileImage( image ); |
|---|
| 1420 | | return -1; |
|---|
| 1421 | | } |
|---|
| 1422 | | |
|---|
| 1423 | | /* Destroy our image, we won't need it */ |
|---|
| 1424 | | NSDestroyObjectFileImage( image ); |
|---|
| 1425 | | |
|---|
| 1426 | | #elif defined(HAVE_DL_BEOS) |
|---|
| 1427 | | handle = load_add_on( psz_file ); |
|---|
| 1428 | | if( handle < 0 ) |
|---|
| 1429 | | { |
|---|
| 1430 | | msg_Warn( p_this, "cannot load module `%s'", psz_file ); |
|---|
| 1431 | | return -1; |
|---|
| 1432 | | } |
|---|
| 1433 | | |
|---|
| 1434 | | #elif defined(HAVE_DL_WINDOWS) |
|---|
| 1435 | | #ifdef UNDER_CE |
|---|
| 1436 | | { |
|---|
| 1437 | | wchar_t psz_wfile[MAX_PATH]; |
|---|
| 1438 | | MultiByteToWideChar( CP_ACP, 0, psz_file, -1, psz_wfile, MAX_PATH ); |
|---|
| 1439 | | handle = LoadLibrary( psz_wfile ); |
|---|
| 1440 | | } |
|---|
| 1441 | | #else |
|---|
| 1442 | | handle = LoadLibrary( psz_file ); |
|---|
| 1443 | | #endif |
|---|
| 1444 | | if( handle == NULL ) |
|---|
| 1445 | | { |
|---|
| 1446 | | char *psz_err = GetWindowsError(); |
|---|
| 1447 | | msg_Warn( p_this, "cannot load module `%s' (%s)", psz_file, psz_err ); |
|---|
| 1448 | | free( psz_err ); |
|---|
| 1449 | | return -1; |
|---|
| 1450 | | } |
|---|
| 1451 | | |
|---|
| 1452 | | #elif defined(HAVE_DL_DLOPEN) && defined(RTLD_NOW) |
|---|
| 1453 | | /* static is OK, we are called atomically */ |
|---|
| 1454 | | handle = dlopen( psz_file, RTLD_NOW ); |
|---|
| 1455 | | if( handle == NULL ) |
|---|
| 1456 | | { |
|---|
| 1457 | | msg_Warn( p_this, "cannot load module `%s' (%s)", |
|---|
| 1458 | | psz_file, dlerror() ); |
|---|
| 1459 | | return -1; |
|---|
| 1460 | | } |
|---|
| 1461 | | |
|---|
| 1462 | | #elif defined(HAVE_DL_DLOPEN) |
|---|
| 1463 | | # if defined(DL_LAZY) |
|---|
| 1464 | | handle = dlopen( psz_file, DL_LAZY ); |
|---|
| 1465 | | # else |
|---|
| 1466 | | handle = dlopen( psz_file, 0 ); |
|---|
| 1467 | | # endif |
|---|
| 1468 | | if( handle == NULL ) |
|---|
| 1469 | | { |
|---|
| 1470 | | msg_Warn( p_this, "cannot load module `%s' (%s)", |
|---|
| 1471 | | psz_file, dlerror() ); |
|---|
| 1472 | | return -1; |
|---|
| 1473 | | } |
|---|
| 1474 | | |
|---|
| 1475 | | #elif defined(HAVE_DL_SHL_LOAD) |
|---|
| 1476 | | handle = shl_load( psz_file, BIND_IMMEDIATE | BIND_NONFATAL, NULL ); |
|---|
| 1477 | | if( handle == NULL ) |
|---|
| 1478 | | { |
|---|
| 1479 | | msg_Warn( p_this, "cannot load module `%s' (%m)", psz_file ); |
|---|
| 1480 | | return -1; |
|---|
| 1481 | | } |
|---|
| 1482 | | |
|---|
| 1483 | | #else |
|---|
| 1484 | | # error "Something is wrong in modules.c" |
|---|
| 1485 | | |
|---|
| 1486 | | #endif |
|---|
| 1487 | | |
|---|
| 1488 | | *p_handle = handle; |
|---|
| 1489 | | return 0; |
|---|
| 1490 | | } |
|---|
| 1491 | | |
|---|
| 1492 | | /***************************************************************************** |
|---|
| 1493 | | * CloseModule: unload a dynamic library |
|---|
| 1494 | | ***************************************************************************** |
|---|
| 1495 | | * This function unloads a previously opened dynamically linked library |
|---|
| 1496 | | * using a system dependant method. No return value is taken in consideration, |
|---|
| 1497 | | * since some libraries sometimes refuse to close properly. |
|---|
| 1498 | | *****************************************************************************/ |
|---|
| 1499 | | static void CloseModule( module_handle_t handle ) |
|---|
| 1500 | | { |
|---|
| 1501 | | #if defined(HAVE_DL_DYLD) |
|---|
| 1502 | | NSUnLinkModule( handle, FALSE ); |
|---|
| 1503 | | |
|---|
| 1504 | | #elif defined(HAVE_DL_BEOS) |
|---|
| 1505 | | unload_add_on( handle ); |
|---|
| 1506 | | |
|---|
| 1507 | | #elif defined(HAVE_DL_WINDOWS) |
|---|
| 1508 | | FreeLibrary( handle ); |
|---|
| 1509 | | |
|---|
| 1510 | | #elif defined(HAVE_DL_DLOPEN) |
|---|
| 1511 | | # ifdef NDEBUG |
|---|
| 1512 | | dlclose( handle ); |
|---|
| 1513 | | # endif |
|---|
| 1514 | | |
|---|
| 1515 | | #elif defined(HAVE_DL_SHL_LOAD) |
|---|
| 1516 | | shl_unload( handle ); |
|---|
| 1517 | | |
|---|
| 1518 | | #endif |
|---|
| 1519 | | return; |
|---|
| 1520 | | } |
|---|
| 1521 | | |
|---|
| 1522 | | /***************************************************************************** |
|---|
| 1523 | | * GetSymbol: get a symbol from a dynamic library |
|---|
| 1524 | | ***************************************************************************** |
|---|
| 1525 | | * This function queries a loaded library for a symbol specified in a |
|---|
| 1526 | | * string, and returns a pointer to it. We don't check for dlerror() or |
|---|
| 1527 | | * similar functions, since we want a non-NULL symbol anyway. |
|---|
| 1528 | | *****************************************************************************/ |
|---|
| 1529 | | static void * _module_getsymbol( module_handle_t, const char * ); |
|---|
| 1530 | | |
|---|
| 1531 | | static void * GetSymbol( module_handle_t handle, const char * psz_function ) |
|---|
| 1532 | | { |
|---|
| 1533 | | void * p_symbol = _module_getsymbol( handle, psz_function ); |
|---|
| 1534 | | |
|---|
| 1535 | | /* MacOS X dl library expects symbols to begin with "_". So do |
|---|
| 1536 | | * some other operating systems. That's really lame, but hey, what |
|---|
| 1537 | | * can we do ? */ |
|---|
| 1538 | | if( p_symbol == NULL ) |
|---|
| 1539 | | { |
|---|
| 1540 | | char psz_call[strlen( psz_function ) + 2]; |
|---|
| 1541 | | |
|---|
| 1542 | | psz_call[ 0 ] = '_'; |
|---|
| 1543 | | memcpy( psz_call + 1, psz_function, sizeof (psz_call) - 1 ); |
|---|
| 1544 | | p_symbol = _module_getsymbol( handle, psz_call ); |
|---|
| 1545 | | } |
|---|
| 1546 | | |
|---|
| 1547 | | return p_symbol; |
|---|
| 1548 | | } |
|---|
| 1549 | | |
|---|
| 1550 | | static void * _module_getsymbol( module_handle_t handle, |
|---|
| 1551 | | const char * psz_function ) |
|---|
| 1552 | | { |
|---|
| 1553 | | #if defined(HAVE_DL_DYLD) |
|---|
| 1554 | | NSSymbol sym = NSLookupSymbolInModule( handle, psz_function ); |
|---|
| 1555 | | return NSAddressOfSymbol( sym ); |
|---|
| 1556 | | |
|---|
| 1557 | | #elif defined(HAVE_DL_BEOS) |
|---|
| 1558 | | void * p_symbol; |
|---|
| 1559 | | if( B_OK == get_image_symbol( handle, psz_function, |
|---|
| 1560 | | B_SYMBOL_TYPE_TEXT, &p_symbol ) ) |
|---|
| 1561 | | { |
|---|
| 1562 | | return p_symbol; |
|---|
| 1563 | | } |
|---|
| 1564 | | else |
|---|
| 1565 | | { |
|---|
| 1566 | | return NULL; |
|---|
| 1567 | | } |
|---|
| 1568 | | |
|---|
| 1569 | | #elif defined(HAVE_DL_WINDOWS) && defined(UNDER_CE) |
|---|
| 1570 | | wchar_t psz_real[256]; |
|---|
| 1571 | | MultiByteToWideChar( CP_ACP, 0, psz_function, -1, psz_real, 256 ); |
|---|
| 1572 | | |
|---|
| 1573 | | return (void *)GetProcAddress( handle, psz_real ); |
|---|
| 1574 | | |
|---|
| 1575 | | #elif defined(HAVE_DL_WINDOWS) && defined(WIN32) |
|---|
| 1576 | | return (void *)GetProcAddress( handle, (char *)psz_function ); |
|---|
| 1577 | | |
|---|
| 1578 | | #elif defined(HAVE_DL_DLOPEN) |
|---|
| 1579 | | return dlsym( handle, psz_function ); |
|---|
| 1580 | | |
|---|
| 1581 | | #elif defined(HAVE_DL_SHL_LOAD) |
|---|
| 1582 | | void *p_sym; |
|---|
| 1583 | | shl_findsym( &handle, psz_function, TYPE_UNDEFINED, &p_sym ); |
|---|
| 1584 | | return p_sym; |
|---|
| 1585 | | |
|---|
| 1586 | | #endif |
|---|
| 1587 | | } |
|---|
| 1588 | | |
|---|
| 1589 | | #if defined(HAVE_DL_WINDOWS) |
|---|
| 1590 | | static char * GetWindowsError( void ) |
|---|
| 1591 | | { |
|---|
| 1592 | | #if defined(UNDER_CE) |
|---|
| 1593 | | wchar_t psz_tmp[MAX_PATH]; |
|---|
| 1594 | | char * psz_buffer = malloc( MAX_PATH ); |
|---|
| 1595 | | #else |
|---|
| 1596 | | char * psz_tmp = malloc( MAX_PATH ); |
|---|
| 1597 | | #endif |
|---|
| 1598 | | int i = 0, i_error = GetLastError(); |
|---|
| 1599 | | |
|---|
| 1600 | | FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, |
|---|
| 1601 | | NULL, i_error, MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), |
|---|
| 1602 | | (LPTSTR)psz_tmp, MAX_PATH, NULL ); |
|---|
| 1603 | | |
|---|
| 1604 | | /* Go to the end of the string */ |
|---|
| 1605 | | while( psz_tmp[i] && psz_tmp[i] != _T('\r') && psz_tmp[i] != _T('\n') ) |
|---|
| 1606 | | { |
|---|
| 1607 | | i++; |
|---|
| 1608 | | } |
|---|
| 1609 | | |
|---|
| 1610 | | if( psz_tmp[i] ) |
|---|
| 1611 | | { |
|---|
| 1612 | | #if defined(UNDER_CE) |
|---|
| 1613 | | swprintf( psz_tmp + i, L" (error %i)", i_error ); |
|---|
| 1614 | | psz_tmp[ 255 ] = L'\0'; |
|---|
| 1615 | | #else |
|---|
| 1616 | | snprintf( psz_tmp + i, 256 - i, " (error %i)", i_error ); |
|---|
| 1617 | | psz_tmp[ 255 ] = '\0'; |
|---|
| 1618 | | #endif |
|---|
| 1619 | | } |
|---|
| 1620 | | |
|---|
| 1621 | | #if defined(UNDER_CE) |
|---|
| 1622 | | wcstombs( psz_buffer, psz_tmp, MAX_PATH ); |
|---|
| 1623 | | return psz_buffer; |
|---|
| 1624 | | #else |
|---|
| 1625 | | return psz_tmp; |
|---|
| 1626 | | #endif |
|---|
| 1627 | | } |
|---|
| 1628 | | #endif /* HAVE_DL_WINDOWS */ |
|---|
| 1629 | | |
|---|
| 1630 | | /***************************************************************************** |
|---|
| 1631 | | * LoadPluginsCache: loads the plugins cache file |
|---|
| 1632 | | ***************************************************************************** |
|---|
| 1633 | | * This function will load the plugin cache if present and valid. This cache |
|---|
| 1634 | | * will in turn be queried by AllocateAllPlugins() to see if it needs to |
|---|
| 1635 | | * actually load the dynamically loadable module. |
|---|
| 1636 | | * This allows us to only fully load plugins when they are actually used. |
|---|
| 1637 | | *****************************************************************************/ |
|---|
| 1638 | | static void CacheLoad( vlc_object_t *p_this ) |
|---|
| 1639 | | { |
|---|
| 1640 | | char *psz_filename, *psz_cachedir; |
|---|
| 1641 | | FILE *file; |
|---|
| 1642 | | int i, j, i_size, i_read; |
|---|
| 1643 | | char p_cachestring[sizeof("cache " COPYRIGHT_MESSAGE)]; |
|---|
| 1644 | | char p_cachelang[6], p_lang[6]; |
|---|
| 1645 | | int i_cache; |
|---|
| 1646 | | module_cache_t **pp_cache = 0; |
|---|
| 1647 | | int32_t i_file_size, i_marker; |
|---|
| 1648 | | libvlc_global_data_t *p_libvlc_global = vlc_global(); |
|---|
| 1649 | | |
|---|
| 1650 | | psz_cachedir = p_this->p_libvlc->psz_cachedir; |
|---|
| 1651 | | if( !psz_cachedir ) /* XXX: this should never happen */ |
|---|
| 1652 | | { |
|---|
| 1653 | | msg_Err( p_this, "Unable to get cache directory" ); |
|---|
| 1654 | | return; |
|---|
| 1655 | | } |
|---|
| 1656 | | |
|---|
| 1657 | | i_size = asprintf( &psz_filename, "%s"DIR_SEP"%s", |
|---|
| 1658 | | psz_cachedir, CacheName() ); |
|---|
| 1659 | | if( i_size <= 0 ) |
|---|
| 1660 | | { |
|---|
| 1661 | | msg_Err( p_this, "out of memory" ); |
|---|
| 1662 | | return; |
|---|
| 1663 | | } |
|---|
| 1664 | | |
|---|
| 1665 | | if( p_libvlc_global->p_module_bank->b_cache_delete ) |
|---|
| 1666 | | { |
|---|
| 1667 | | #if !defined( UNDER_CE ) |
|---|
| 1668 | | unlink( psz_filename ); |
|---|
| 1669 | | #else |
|---|
| 1670 | | wchar_t psz_wf[MAX_PATH]; |
|---|
| 1671 | | MultiByteToWideChar( CP_ACP, 0, psz_filename, -1, psz_wf, MAX_PATH ); |
|---|
| 1672 | | DeleteFile( psz_wf ); |
|---|
| 1673 | | #endif |
|---|
| 1674 | | msg_Dbg( p_this, "removing plugins cache file %s", psz_filename ); |
|---|
| 1675 | | free( psz_filename ); |
|---|
| 1676 | | return; |
|---|
| 1677 | | } |
|---|
| 1678 | | |
|---|
| 1679 | | msg_Dbg( p_this, "loading plugins cache file %s", psz_filename ); |
|---|
| 1680 | | |
|---|
| 1681 | | file = utf8_fopen( psz_filename, "rb" ); |
|---|
| 1682 | | if( !file ) |
|---|
| 1683 | | { |
|---|
| 1684 | | msg_Warn( p_this, "could not open plugins cache file %s for reading", |
|---|
| 1685 | | psz_filename ); |
|---|
| 1686 | | free( psz_filename ); |
|---|
| 1687 | | return; |
|---|
| 1688 | | } |
|---|
| 1689 | | free( psz_filename ); |
|---|
| 1690 | | |
|---|
| 1691 | | /* Check the file size */ |
|---|
| 1692 | | i_read = fread( &i_file_size, 1, sizeof(i_file_size), file ); |
|---|
| 1693 | | if( i_read != sizeof(i_file_size) ) |
|---|
| 1694 | | { |
|---|
| 1695 | | msg_Warn( p_this, "This doesn't look like a valid plugins cache " |
|---|
| 1696 | | "(too short)" ); |
|---|
| 1697 | | fclose( file ); |
|---|
| 1698 | | return; |
|---|
| 1699 | | } |
|---|
| 1700 | | |
|---|
| 1701 | | fseek( file, 0, SEEK_END ); |
|---|
| 1702 | | if( ftell( file ) != i_file_size ) |
|---|
| 1703 | | { |
|---|
| 1704 | | msg_Warn( p_this, "This doesn't look like a valid plugins cache " |
|---|
| 1705 | | "(corrupted size)" ); |
|---|
| 1706 | | fclose( file ); |
|---|
| 1707 | | return; |
|---|
| 1708 | | } |
|---|
| 1709 | | fseek( file, sizeof(i_file_size), SEEK_SET ); |
|---|
| 1710 | | |
|---|
| 1711 | | /* Check the file is a plugins cache */ |
|---|
| 1712 | | i_size = sizeof("cache " COPYRIGHT_MESSAGE) - 1; |
|---|
| 1713 | | i_read = fread( p_cachestring, 1, i_size, file ); |
|---|
| 1714 | | if( i_read != i_size || |
|---|
| 1715 | | memcmp( p_cachestring, "cache " COPYRIGHT_MESSAGE, i_size ) ) |
|---|
| 1716 | | { |
|---|
| 1717 | | msg_Warn( p_this, "This doesn't look like a valid plugins cache" ); |
|---|
| 1718 | | fclose( file ); |
|---|
| 1719 | | return; |
|---|
| 1720 | | } |
|---|
| 1721 | | |
|---|
| 1722 | | /* Check Sub-version number */ |
|---|
| 1723 | | i_read = fread( &i_marker, 1, sizeof(i_marker), file ); |
|---|
| 1724 | | if( i_read != sizeof(i_marker) || i_marker != CACHE_SUBVERSION_NUM ) |
|---|
| 1725 | | { |
|---|
| 1726 | | msg_Warn( p_this, "This doesn't look like a valid plugins cache " |
|---|
| 1727 | | "(corrupted header)" ); |
|---|
| 1728 | | fclose( file ); |
|---|
| 1729 | | return; |
|---|
| 1730 | | } |
|---|
| 1731 | | |
|---|
| 1732 | | /* Check the language hasn't changed */ |
|---|
| 1733 | | sprintf( p_lang, "%5.5s", _("C") ); i_size = 5; |
|---|
| 1734 | | i_read = fread( p_cachelang, 1, i_size, file ); |
|---|
| 1735 | | if( i_read != i_size || memcmp( p_cachelang, p_lang, i_size ) ) |
|---|
| 1736 | | { |
|---|
| 1737 | | msg_Warn( p_this, "This doesn't look like a valid plugins cache " |
|---|
| 1738 | | "(language changed)" ); |
|---|
| 1739 | | fclose( file ); |
|---|
| 1740 | | return; |
|---|
| 1741 | | } |
|---|
| 1742 | | |
|---|
| 1743 | | /* Check header marker */ |
|---|
| 1744 | | i_read = fread( &i_marker, 1, sizeof(i_marker), file ); |
|---|
| 1745 | | if( i_read != sizeof(i_marker) || |
|---|
| 1746 | | i_marker != ftell( file ) - (int)sizeof(i_marker) ) |
|---|
| 1747 | | { |
|---|
| 1748 | | msg_Warn( p_this, "This doesn't look like a valid plugins cache " |
|---|
| 1749 | | "(corrupted header)" ); |
|---|
| 1750 | | fclose( file ); |
|---|
| 1751 | | return; |
|---|
| 1752 | | } |
|---|
| 1753 | | |
|---|
| 1754 | | p_libvlc_global->p_module_bank->i_loaded_cache = 0; |
|---|
| 1755 | | if (fread( &i_cache, 1, sizeof(i_cache), file ) != sizeof(i_cache) ) |
|---|
| 1756 | | { |
|---|
| 1757 | | msg_Warn( p_this, "This doesn't look like a valid plugins cache " |
|---|
| 1758 | | "(file too short)" ); |
|---|
| 1759 | | fclose( file ); |
|---|
| 1760 | | return; |
|---|
| 1761 | | } |
|---|
| 1762 | | |
|---|
| 1763 | | if( i_cache ) |
|---|
| 1764 | | pp_cache = p_libvlc_global->p_module_bank->pp_loaded_cache = |
|---|
| 1765 | | malloc( i_cache * sizeof(void *) ); |
|---|
| 1766 | | |
|---|
| 1767 | | #define LOAD_IMMEDIATE(a) \ |
|---|
| 1768 | | if( fread( (void *)&a, sizeof(char), sizeof(a), file ) != sizeof(a) ) goto error |
|---|
| 1769 | | #define LOAD_STRING(a) \ |
|---|
| 1770 | | { \ |
|---|
| 1771 | | a = NULL; \ |
|---|
| 1772 | | if( ( fread( &i_size, sizeof(i_size), 1, file ) != 1 ) \ |
|---|
| 1773 | | || ( i_size > 16384 ) ) \ |
|---|
| 1774 | | goto error; \ |
|---|
| 1775 | | if( i_size ) { \ |
|---|
| 1776 | | char *psz = malloc( i_size ); \ |
|---|
| 1777 | | if( fread( psz, i_size, 1, file ) != 1 ) { \ |
|---|
| 1778 | | free( psz ); \ |
|---|
| 1779 | | goto error; \ |
|---|
| 1780 | | } \ |
|---|
| 1781 | | if( psz[i_size-1] ) { \ |
|---|
| 1782 | | free( psz ); \ |
|---|
| 1783 | | goto error; \ |
|---|
| 1784 | | } \ |
|---|
| 1785 | | a = psz; \ |
|---|
| 1786 | | } \ |
|---|
| 1787 | | } |
|---|
| 1788 | | |
|---|
| 1789 | | for( i = 0; i < i_cache; i++ ) |
|---|
| 1790 | | { |
|---|
| 1791 | | uint16_t i_size; |
|---|
| 1792 | | int i_submodules; |
|---|
| 1793 | | |
|---|
| 1794 | | pp_cache[i] = malloc( sizeof(module_cache_t) ); |
|---|
| 1795 | | p_libvlc_global->p_module_bank->i_loaded_cache++; |
|---|
| 1796 | | |
|---|
| 1797 | | /* Load common info */ |
|---|
| 1798 | | LOAD_STRING( pp_cache[i]->psz_file ); |
|---|
| 1799 | | LOAD_IMMEDIATE( pp_cache[i]->i_time ); |
|---|
| 1800 | | LOAD_IMMEDIATE( pp_cache[i]->i_size ); |
|---|
| 1801 | | LOAD_IMMEDIATE( pp_cache[i]->b_junk ); |
|---|
| 1802 | | pp_cache[i]->b_used = VLC_FALSE; |
|---|
| 1803 | | |
|---|
| 1804 | | if( pp_cache[i]->b_junk ) continue; |
|---|
| 1805 | | |
|---|
| 1806 | | pp_cache[i]->p_module = vlc_module_create( p_this ); |
|---|
| 1807 | | |
|---|
| 1808 | | /* Load additional infos */ |
|---|
| 1809 | | LOAD_STRING( pp_cache[i]->p_module->psz_object_name ); |
|---|
| 1810 | | LOAD_STRING( pp_cache[i]->p_module->psz_shortname ); |
|---|
| 1811 | | LOAD_STRING( pp_cache[i]->p_module->psz_longname ); |
|---|
| 1812 | | LOAD_STRING( pp_cache[i]->p_module->psz_help ); |
|---|
| 1813 | | for( j = 0; j < MODULE_SHORTCUT_MAX; j++ ) |
|---|
| 1814 | | { |
|---|
| 1815 | | LOAD_STRING( pp_cache[i]->p_module->pp_shortcuts[j] ); // FIX |
|---|
| 1816 | | } |
|---|
| 1817 | | LOAD_STRING( pp_cache[i]->p_module->psz_capability ); |
|---|
| 1818 | | LOAD_IMMEDIATE( pp_cache[i]->p_module->i_score ); |
|---|
| 1819 | | LOAD_IMMEDIATE( pp_cache[i]->p_module->i_cpu ); |
|---|
| 1820 | | LOAD_IMMEDIATE( pp_cache[i]->p_module->b_unloadable ); |
|---|
| 1821 | | LOAD_IMMEDIATE( pp_cache[i]->p_module->b_reentrant ); |
|---|
| 1822 | | LOAD_IMMEDIATE( pp_cache[i]->p_module->b_submodule ); |
|---|
| 1823 | | |
|---|
| 1824 | | /* Config stuff */ |
|---|
| 1825 | | if( CacheLoadConfig( pp_cache[i]->p_module, file ) != VLC_SUCCESS ) |
|---|
| 1826 | | goto error; |
|---|
| 1827 | | |
|---|
| 1828 | | LOAD_STRING( pp_cache[i]->p_module->psz_filename ); |
|---|
| 1829 | | |
|---|
| 1830 | | LOAD_IMMEDIATE( i_submodules ); |
|---|
| 1831 | | |
|---|
| 1832 | | while( i_submodules-- ) |
|---|
| 1833 | | { |
|---|
| 1834 | | module_t *p_module = vlc_submodule_create( pp_cache[i]->p_module ); |
|---|
| 1835 | | LOAD_STRING( p_module->psz_object_name ); |
|---|
| 1836 | | LOAD_STRING( p_module->psz_shortname ); |
|---|
| 1837 | | LOAD_STRING( p_module->psz_longname ); |
|---|
| 1838 | | LOAD_STRING( p_module->psz_help ); |
|---|
| 1839 | | for( j = 0; j < MODULE_SHORTCUT_MAX; j++ ) |
|---|
| 1840 | | { |
|---|
| 1841 | | LOAD_STRING( p_module->pp_shortcuts[j] ); // FIX |
|---|
| 1842 | | } |
|---|
| 1843 | | LOAD_STRING( p_module->psz_capability ); |
|---|
| 1844 | | LOAD_IMMEDIATE( p_module->i_score ); |
|---|
| 1845 | | LOAD_IMMEDIATE( p_module->i_cpu ); |
|---|
| 1846 | | LOAD_IMMEDIATE( p_module->b_unloadable ); |
|---|
| 1847 | | LOAD_IMMEDIATE( p_module->b_reentrant ); |
|---|
| 1848 | | } |
|---|
| 1849 | | } |
|---|
| 1850 | | |
|---|
| 1851 | | fclose( file ); |
|---|
| 1852 | | return; |
|---|
| 1853 | | |
|---|
| 1854 | | error: |
|---|
| 1855 | | |
|---|
| 1856 | | msg_Warn( p_this, "plugins cache not loaded (corrupted)" ); |
|---|
| 1857 | | |
|---|
| 1858 | | /* TODO: cleanup */ |
|---|
| 1859 | | p_libvlc_global->p_module_bank->i_loaded_cache = 0; |
|---|
| 1860 | | |
|---|
| 1861 | | fclose( file ); |
|---|
| 1862 | | return; |
|---|
| 1863 | | } |
|---|
| 1864 | | |
|---|
| 1865 | | |
|---|
| 1866 | | int CacheLoadConfig( module_t *p_module, FILE *file ) |
|---|
| 1867 | | { |
|---|
| 1868 | | uint32_t i_lines; |
|---|
| 1869 | | uint16_t i_size; |
|---|
| 1870 | | |
|---|
| 1871 | | /* Calculate the structure length */ |
|---|
| 1872 | | LOAD_IMMEDIATE( p_module->i_config_items ); |
|---|
| 1873 | | LOAD_IMMEDIATE( p_module->i_bool_items ); |
|---|
| 1874 | | |
|---|
| 1875 | | LOAD_IMMEDIATE( i_lines ); |
|---|
| 1876 | | |
|---|
| 1877 | | /* Allocate memory */ |
|---|
| 1878 | | if (i_lines) |
|---|
| 1879 | | { |
|---|
| 1880 | | p_module->p_config = |
|---|
| 1881 | | (module_config_t *)calloc( i_lines, sizeof(module_config_t) ); |
|---|
| 1882 | | if( p_module->p_config == NULL ) |
|---|
| 1883 | | { |
|---|
| 1884 | | p_module->confsize = 0; |
|---|
| 1885 | | msg_Err( p_module, "config error: can't duplicate p_config" ); |
|---|
| 1886 | | return VLC_ENOMEM; |
|---|
| 1887 | | } |
|---|
| 1888 | | } |
|---|
| 1889 | | p_module->confsize = i_lines; |
|---|
| 1890 | | |
|---|
| 1891 | | /* Do the duplication job */ |
|---|
| 1892 | | for (size_t i = 0; i < i_lines; i++ ) |
|---|
| 1893 | | { |
|---|
| 1894 | | LOAD_IMMEDIATE( p_module->p_config[i] ); |
|---|
| 1895 | | |
|---|
| 1896 | | LOAD_STRING( p_module->p_config[i].psz_type ); |
|---|
| 1897 | | LOAD_STRING( p_module->p_config[i].psz_name ); |
|---|
| 1898 | | LOAD_STRING( p_module->p_config[i].psz_text ); |
|---|
| 1899 | | LOAD_STRING( p_module->p_config[i].psz_longtext ); |
|---|
| 1900 | | LOAD_STRING( p_module->p_config[i].psz_current ); |
|---|
| 1901 | | |
|---|
| 1902 | | if (IsConfigStringType (p_module->p_config[i].i_type)) |
|---|
| 1903 | | { |
|---|
| 1904 | | LOAD_STRING (p_module->p_config[i].orig.psz); |
|---|
| 1905 | | p_module->p_config[i].value.psz = |
|---|
| 1906 | | (p_module->p_config[i].orig.psz != NULL) |
|---|
| 1907 | | ? strdup (p_module->p_config[i].orig.psz) : NULL; |
|---|
| 1908 | | p_module->p_config[i].saved.psz = NULL; |
|---|
| 1909 | | } |
|---|
| 1910 | | else |
|---|
| 1911 | | { |
|---|
| 1912 | | memcpy (&p_module->p_config[i].value, &p_module->p_config[i].orig, |
|---|
| 1913 | | sizeof (p_module->p_config[i].value)); |
|---|
| 1914 | | memcpy (&p_module->p_config[i].saved, &p_module->p_config[i].orig, |
|---|
| 1915 | | sizeof (p_module->p_config[i].saved)); |
|---|
| 1916 | | } |
|---|
| 1917 | | |
|---|
| 1918 | | p_module->p_config[i].b_dirty = VLC_FALSE; |
|---|
| 1919 | | |
|---|
| 1920 | | p_module->p_config[i].p_lock = &p_module->object_lock; |
|---|
| 1921 | | |
|---|
| 1922 | | if( p_module->p_config[i].i_list ) |
|---|
| 1923 | | { |
|---|
| 1924 | | if( p_module->p_config[i].ppsz_list ) |
|---|
| 1925 | | { |
|---|
| 1926 | | int j; |
|---|
| 1927 | | p_module->p_config[i].ppsz_list = |
|---|
| 1928 | | malloc( (p_module->p_config[i].i_list+1) * sizeof(char *)); |
|---|
| 1929 | | if( p_module->p_config[i].ppsz_list ) |
|---|
| 1930 | | { |
|---|
| 1931 | | for( j = 0; j < p_module->p_config[i].i_list; j++ ) |
|---|
| 1932 | | LOAD_STRING( p_module->p_config[i].ppsz_list[j] ); |
|---|
| 1933 | | p_module->p_config[i].ppsz_list[j] = NULL; |
|---|
| 1934 | | } |
|---|
| 1935 | | } |
|---|
| 1936 | | if( p_module->p_config[i].ppsz_list_text ) |
|---|
| 1937 | | { |
|---|
| 1938 | | int j; |
|---|
| 1939 | | p_module->p_config[i].ppsz_list_text = |
|---|
| 1940 | | malloc( (p_module->p_config[i].i_list+1) * sizeof(char *)); |
|---|
| 1941 | | if( p_module->p_config[i].ppsz_list_text ) |
|---|
| 1942 | | { |
|---|
| 1943 | | for( j = 0; j < p_module->p_config[i].i_list; j++ ) |
|---|
| 1944 | | LOAD_STRING( p_module->p_config[i].ppsz_list_text[j] ); |
|---|
| 1945 | | p_module->p_config[i].ppsz_list_text[j] = NULL; |
|---|
| 1946 | | } |
|---|
| 1947 | | } |
|---|
| 1948 | | if( p_module->p_config[i].pi_list ) |
|---|
| 1949 | | { |
|---|
| 1950 | | p_module->p_config[i].pi_list = |
|---|
| 1951 | | malloc( (p_module->p_config[i].i_list + 1) * sizeof(int) ); |
|---|
| 1952 | | if( p_module->p_config[i].pi_list ) |
|---|
| 1953 | | { |
|---|
| 1954 | | for (int j = 0; j < p_module->p_config[i].i_list; j++) |
|---|
| 1955 | | LOAD_IMMEDIATE( p_module->p_config[i].pi_list[j] ); |
|---|
| 1956 | | } |
|---|
| 1957 | | } |
|---|
| 1958 | | } |
|---|
| 1959 | | |
|---|
| 1960 | | if( p_module->p_config[i].i_action ) |
|---|
| 1961 | | { |
|---|
| 1962 | | p_module->p_config[i].ppf_action = |
|---|
| 1963 | | malloc( p_module->p_config[i].i_action * sizeof(void *) ); |
|---|
| 1964 | | p_module->p_config[i].ppsz_action_text = |
|---|
| 1965 | | malloc( p_module->p_config[i].i_action * sizeof(char *) ); |
|---|
| 1966 | | |
|---|
| 1967 | | for (int j = 0; j < p_module->p_config[i].i_action; j++) |
|---|
| 1968 | | { |
|---|
| 1969 | | p_module->p_config[i].ppf_action[j] = 0; |
|---|
| 1970 | | LOAD_STRING( p_module->p_config[i].ppsz_action_text[j] ); |
|---|
| 1971 | | } |
|---|
| 1972 | | } |
|---|
| 1973 | | |
|---|
| 1974 | | LOAD_IMMEDIATE( p_module->p_config[i].pf_callback ); |
|---|
| 1975 | | } |
|---|
| 1976 | | |
|---|
| 1977 | | return VLC_SUCCESS; |
|---|
| 1978 | | |
|---|
| 1979 | | error: |
|---|
| 1980 | | |
|---|
| 1981 | | return VLC_EGENERIC; |
|---|
| 1982 | | } |
|---|
| 1983 | | |
|---|
| 1984 | | /***************************************************************************** |
|---|
| 1985 | | * SavePluginsCache: saves the plugins cache to a file |
|---|
| 1986 | | *****************************************************************************/ |
|---|
| 1987 | | static void CacheSave( vlc_object_t *p_this ) |
|---|
| 1988 | | { |
|---|
| 1989 | | static char const psz_tag[] = |
|---|
| 1990 | | "Signature: 8a477f597d28d172789f06886806bc55\r\n" |
|---|
| 1991 | | "# This file is a cache directory tag created by VLC.\r\n" |
|---|
| 1992 | | "# For information about cache directory tags, see:\r\n" |
|---|
| 1993 | | "# http://www.brynosaurus.com/cachedir/\r\n"; |
|---|
| 1994 | | |
|---|
| 1995 | | char *psz_cachedir; |
|---|
| 1996 | | size_t i_len = 0; |
|---|
| 1997 | | FILE *file; |
|---|
| 1998 | | int i, j, i_cache; |
|---|
| 1999 | | module_cache_t **pp_cache; |
|---|
| 2000 | | int32_t i_file_size = 0; |
|---|
| 2001 | | libvlc_global_data_t *p_libvlc_global = vlc_global(); |
|---|
| 2002 | | |
|---|
| 2003 | | psz_cachedir = p_this->p_libvlc->psz_cachedir; |
|---|
| 2004 | | if( !psz_cachedir ) /* XXX: this should never happen */ |
|---|
| 2005 | | { |
|---|
| 2006 | | msg_Err( p_this, "Unable to get cache directory" ); |
|---|
| 2007 | | return; |
|---|
| 2008 | | } |
|---|
| 2009 | | |
|---|
| 2010 | | char psz_filename[sizeof(DIR_SEP) + 32 + strlen(psz_cachedir)]; |
|---|
| 2011 | | config_CreateDir( p_this, psz_cachedir ); |
|---|
| 2012 | | |
|---|
| 2013 | | snprintf( psz_filename, sizeof( psz_filename ), |
|---|
| 2014 | | "%s"DIR_SEP"CACHEDIR.TAG", psz_cachedir ); |
|---|
| 2015 | | file = utf8_fopen( psz_filename, "wb" ); |
|---|
| 2016 | | if( file ) |
|---|
| 2017 | | { |
|---|
| 2018 | | fwrite( psz_tag, 1, strlen(psz_tag), file ); |
|---|
| 2019 | | fclose( file ); |
|---|
| 2020 | | } |
|---|
| 2021 | | |
|---|
| 2022 | | snprintf( psz_filename, sizeof( psz_filename ), |
|---|
| 2023 | | "%s"DIR_SEP"%s", psz_cachedir, CacheName() ); |
|---|
| 2024 | | msg_Dbg( p_this, "saving plugins cache file %s", psz_filename ); |
|---|
| 2025 | | |
|---|
| 2026 | | file = utf8_fopen( psz_filename, "wb" ); |
|---|
| 2027 | | if( !file ) |
|---|
| 2028 | | { |
|---|
| 2029 | | msg_Warn( p_this, "could not open plugins cache file %s for writing", |
|---|
| 2030 | | psz_filename ); |
|---|
| 2031 | | return; |
|---|
| 2032 | | } |
|---|
| 2033 | | |
|---|
| 2034 | | /* Empty space for file size */ |
|---|
| 2035 | | fwrite( &i_file_size, sizeof(char), sizeof(i_file_size), file ); |
|---|
| 2036 | | |
|---|
| 2037 | | /* Contains version number */ |
|---|
| 2038 | | fprintf( file, "%s", "cache " COPYRIGHT_MESSAGE ); |
|---|
| 2039 | | |
|---|
| 2040 | | /* Sub-version number (to avoid breakage in the dev version when cache |
|---|
| 2041 | | * structure changes) */ |
|---|
| 2042 | | i_file_size = CACHE_SUBVERSION_NUM; |
|---|
| 2043 | | fwrite( &i_file_size, sizeof(char), sizeof(i_file_size), file ); |
|---|
| 2044 | | |
|---|
| 2045 | | /* Language */ |
|---|
| 2046 | | fprintf( file, "%5.5s", _("C") ); |
|---|
| 2047 | | |
|---|
| 2048 | | /* Header marker */ |
|---|
| 2049 | | i_file_size = ftell( file ); |
|---|
| 2050 | | fwrite( &i_file_size, sizeof(char), sizeof(i_file_size), file ); |
|---|
| 2051 | | |
|---|
| 2052 | | i_cache = p_libvlc_global->p_module_bank->i_cache; |
|---|
| 2053 | | pp_cache = p_libvlc_global->p_module_bank->pp_cache; |
|---|
| 2054 | | |
|---|
| 2055 | | fwrite( &i_cache, sizeof(char), sizeof(i_cache), file ); |
|---|
| 2056 | | |
|---|
| 2057 | | #define SAVE_IMMEDIATE(a) \ |
|---|
| 2058 | | fwrite( &a, sizeof(char), sizeof(a), file ) |
|---|
| 2059 | | #define SAVE_STRING(a) \ |
|---|
| 2060 | | { i_size = a ? strlen( a ) + 1 : 0; \ |
|---|
| 2061 | | fwrite( &i_size, sizeof(char), sizeof(i_size), file ); \ |
|---|
| 2062 | | if( a ) fwrite( a, sizeof(char), i_size, file ); \ |
|---|
| 2063 | | } while(0) |
|---|
| 2064 | | |
|---|
| 2065 | | for( i = 0; i < i_cache; i++ ) |
|---|
| 2066 | | { |
|---|
| 2067 | | uint16_t i_size; |
|---|
| 2068 | | uint32_t i_submodule; |
|---|
| 2069 | | |
|---|
| 2070 | | /* Save common info */ |
|---|
| 2071 | | SAVE_STRING( pp_cache[i]->psz_file ); |
|---|
| 2072 | | SAVE_IMMEDIATE( pp_cache[i]->i_time ); |
|---|
| 2073 | | SAVE_IMMEDIATE( pp_cache[i]->i_size ); |
|---|
| 2074 | | SAVE_IMMEDIATE( pp_cache[i]->b_junk ); |
|---|
| 2075 | | |
|---|
| 2076 | | if( pp_cache[i]->b_junk ) continue; |
|---|
| 2077 | | |
|---|
| 2078 | | /* Save additional infos */ |
|---|
| 2079 | | SAVE_STRING( pp_cache[i]->p_module->psz_object_name ); |
|---|
| 2080 | | SAVE_STRING( pp_cache[i]->p_module->psz_shortname ); |
|---|
| 2081 | | SAVE_STRING( pp_cache[i]->p_module->psz_longname ); |
|---|
| 2082 | | SAVE_STRING( pp_cache[i]->p_module->psz_help ); |
|---|
| 2083 | | for( j = 0; j < MODULE_SHORTCUT_MAX; j++ ) |
|---|
| 2084 | | { |
|---|
| 2085 | | SAVE_STRING( pp_cache[i]->p_module->pp_shortcuts[j] ); // FIX |
|---|
| 2086 | | } |
|---|
| 2087 | | SAVE_STRING( pp_cache[i]->p_module->psz_capability ); |
|---|
| 2088 | | SAVE_IMMEDIATE( pp_cache[i]->p_module->i_score ); |
|---|
| 2089 | | SAVE_IMMEDIATE( pp_cache[i]->p_module->i_cpu ); |
|---|
| 2090 | | SAVE_IMMEDIATE( pp_cache[i]->p_module->b_unloadable ); |
|---|
| 2091 | | SAVE_IMMEDIATE( pp_cache[i]->p_module->b_reentrant ); |
|---|
| 2092 | | SAVE_IMMEDIATE( pp_cache[i]->p_module->b_submodule ); |
|---|
| 2093 | | |
|---|
| 2094 | | /* Config stuff */ |
|---|
| 2095 | | CacheSaveConfig( pp_cache[i]->p_module, file ); |
|---|
| 2096 | | |
|---|
| 2097 | | SAVE_STRING( pp_cache[i]->p_module->psz_filename ); |
|---|
| 2098 | | |
|---|
| 2099 | | i_submodule = pp_cache[i]->p_module->i_children; |
|---|
| 2100 | | SAVE_IMMEDIATE( i_submodule ); |
|---|
| 2101 | | for( i_submodule = 0; |
|---|
| 2102 | | i_submodule < (unsigned)pp_cache[i]->p_module->i_children; |
|---|
| 2103 | | i_submodule++ ) |
|---|
| 2104 | | { |
|---|
| 2105 | | module_t *p_module = |
|---|
| 2106 | | (module_t *)pp_cache[i]->p_module->pp_children[i_submodule]; |
|---|
| 2107 | | |
|---|
| 2108 | | SAVE_STRING( p_module->psz_object_name ); |
|---|
| 2109 | | SAVE_STRING( p_module->psz_shortname ); |
|---|
| 2110 | | SAVE_STRING( p_module->psz_longname ); |
|---|
| 2111 | | SAVE_STRING( p_module->psz_help ); |
|---|
| 2112 | | for( j = 0; j < MODULE_SHORTCUT_MAX; j++ ) |
|---|
| 2113 | | { |
|---|
| 2114 | | SAVE_STRING( p_module->pp_shortcuts[j] ); // FIX |
|---|
| 2115 | | } |
|---|
| 2116 | | SAVE_STRING( p_module->psz_capability ); |
|---|
| 2117 | | SAVE_IMMEDIATE( p_module->i_score ); |
|---|
| 2118 | | SAVE_IMMEDIATE( p_module->i_cpu ); |
|---|
| 2119 | | SAVE_IMMEDIATE( p_module->b_unloadable ); |
|---|
| 2120 | | SAVE_IMMEDIATE( p_module->b_reentrant ); |
|---|
| 2121 | | } |
|---|
| 2122 | | } |
|---|
| 2123 | | |
|---|
| 2124 | | /* Fill-up file size */ |
|---|
| 2125 | | i_file_size = ftell( file ); |
|---|
| 2126 | | fseek( file, 0, SEEK_SET ); |
|---|
| 2127 | | fwrite( &i_file_size, sizeof(char), sizeof(i_file_size), file ); |
|---|
| 2128 | | |
|---|
| 2129 | | fclose( file ); |
|---|
| 2130 | | } |
|---|
| 2131 | | |
|---|
| 2132 | | void CacheSaveConfig( module_t *p_module, FILE *file ) |
|---|
| 2133 | | { |
|---|
| 2134 | | uint32_t i_lines = p_module->confsize; |
|---|
| 2135 | | uint16_t i_size; |
|---|
| 2136 | | |
|---|
| 2137 | | SAVE_IMMEDIATE( p_module->i_config_items ); |
|---|
| 2138 | | SAVE_IMMEDIATE( p_module->i_bool_items ); |
|---|
| 2139 | | SAVE_IMMEDIATE( i_lines ); |
|---|
| 2140 | | |
|---|
| 2141 | | for (size_t i = 0; i < i_lines ; i++) |
|---|
| 2142 | | { |
|---|
| 2143 | | SAVE_IMMEDIATE( p_module->p_config[i] ); |
|---|
| 2144 | | |
|---|
| 2145 | | SAVE_STRING( p_module->p_config[i].psz_type ); |
|---|
| 2146 | | SAVE_STRING( p_module->p_config[i].psz_name ); |
|---|
| 2147 | | SAVE_STRING( p_module->p_config[i].psz_text ); |
|---|
| 2148 | | SAVE_STRING( p_module->p_config[i].psz_longtext ); |
|---|
| 2149 | | SAVE_STRING( p_module->p_config[i].psz_current ); |
|---|
| 2150 | | if (IsConfigStringType (p_module->p_config[i].i_type)) |
|---|
| 2151 | | SAVE_STRING( p_module->p_config[i].orig.psz ); |
|---|
| 2152 | | |
|---|
| 2153 | | if( p_module->p_config[i].i_list ) |
|---|
| 2154 | | { |
|---|
| 2155 | | if( p_module->p_config[i].ppsz_list ) |
|---|
| 2156 | | { |
|---|
| 2157 | | for (int j = 0; j < p_module->p_config[i].i_list; j++) |
|---|
| 2158 | | SAVE_STRING( p_module->p_config[i].ppsz_list[j] ); |
|---|
| 2159 | | } |
|---|
| 2160 | | |
|---|
| 2161 | | if( p_module->p_config[i].ppsz_list_text ) |
|---|
| 2162 | | { |
|---|
| 2163 | | for (int j = 0; j < p_module->p_config[i].i_list; j++) |
|---|
| 2164 | | SAVE_STRING( p_module->p_config[i].ppsz_list_text[j] ); |
|---|
| 2165 | | } |
|---|
| 2166 | | if( p_module->p_config[i].pi_list ) |
|---|
| 2167 | | { |
|---|
| 2168 | | for (int j = 0; j < p_module->p_config[i].i_list; j++) |
|---|
| 2169 | | SAVE_IMMEDIATE( p_module->p_config[i].pi_list[j] ); |
|---|
| 2170 | | } |
|---|
| 2171 | | } |
|---|
| 2172 | | |
|---|
| 2173 | | for (int j = 0; j < p_module->p_config[i].i_action; j++) |
|---|
| 2174 | | SAVE_STRING( p_module->p_config[i].ppsz_action_text[j] ); |
|---|
| 2175 | | |
|---|
| 2176 | | SAVE_IMMEDIATE( p_module->p_config[i].pf_callback ); |
|---|
| 2177 | | } |
|---|
| 2178 | | } |
|---|
| 2179 | | |
|---|
| 2180 | | /***************************************************************************** |
|---|
| 2181 | | * CacheName: Return the cache file name for this platform. |
|---|
| 2182 | | *****************************************************************************/ |
|---|
| 2183 | | static char *CacheName( void ) |
|---|
| 2184 | | { |
|---|
| 2185 | | static char psz_cachename[32]; |
|---|
| 2186 | | |
|---|
| 2187 | | /* Code int size, pointer size and endianness in the filename */ |
|---|
| 2188 | | int32_t x = 0xbe00001e; |
|---|
| 2189 | | sprintf( psz_cachename, "plugins-%.2x%.2x%.2x.dat", (int)sizeof(int), |
|---|
| 2190 | | (int)sizeof(void *), (unsigned int)((unsigned char *)&x)[0] ); |
|---|
| 2191 | | return psz_cachename; |
|---|
| 2192 | | } |
|---|
| 2193 | | |
|---|
| 2194 | | /***************************************************************************** |
|---|
| 2195 | | * CacheMerge: Merge a cache module descriptor with a full module descriptor. |
|---|
| 2196 | | *****************************************************************************/ |
|---|
| 2197 | | static void CacheMerge( vlc_object_t *p_this, module_t *p_cache, |
|---|
| 2198 | | module_t *p_module ) |
|---|
| 2199 | | { |
|---|
| 2200 | | int i_submodule; |
|---|
| 2201 | | (void)p_this; |
|---|
| 2202 | | |
|---|
| 2203 | | p_cache->pf_activate = p_module->pf_activate; |
|---|
| 2204 | | p_cache->pf_deactivate = p_module->pf_deactivate; |
|---|
| 2205 | | p_cache->handle = p_module->handle; |
|---|
| 2206 | | |
|---|
| 2207 | | for( i_submodule = 0; i_submodule < p_module->i_children; i_submodule++ ) |
|---|
| 2208 | | { |
|---|
| 2209 | | module_t *p_child = (module_t*)p_module->pp_children[i_submodule]; |
|---|
| 2210 | | module_t *p_cchild = (module_t*)p_cache->pp_children[i_submodule]; |
|---|
| 2211 | | p_cchild->pf_activate = p_child->pf_activate; |
|---|
| 2212 | | p_cchild->pf_deactivate = p_child->pf_deactivate; |
|---|
| 2213 | | } |
|---|
| 2214 | | |
|---|
| 2215 | | p_cache->b_loaded = VLC_TRUE; |
|---|
| 2216 | | p_module->b_loaded = VLC_FALSE; |
|---|
| 2217 | | } |
|---|
| 2218 | | |
|---|
| 2219 | | /***************************************************************************** |
|---|
| 2220 | | * CacheFind: finds the cache entry corresponding to a file |
|---|
| 2221 | | ********************* |
|---|