/***************************************************************************** * Run a lua entry point function *****************************************************************************/ static int run( vlc_object_t *p_this, const char * psz_filename, lua_State * L, const char *luafunction, const luabatch_context_t *p_context ) { /* Ugly hack to delete previous versions of the fetchart() * functions. */ lua_pushnil( L ); lua_setglobal( L, luafunction ); /* Load and run the script(s) */ if( vlclua_dofile( p_this, L, psz_filename ) ) { msg_Warn( p_this, "Error loading script %s: %s", psz_filename, lua_tostring( L, lua_gettop( L ) ) ); goto error; } meta_fetcher_scope_t e_scope = FETCHER_SCOPE_NETWORK; /* default to restricted one */ lua_getglobal( L, "descriptor" ); if( lua_isfunction( L, lua_gettop( L ) ) && !lua_pcall( L, 0, 1, 0 ) ) { lua_getfield( L, -1, "scope" ); char *psz_scope = luaL_strdupornull( L, -1 ); if ( psz_scope && !strcmp( psz_scope, "local" ) ) e_scope = FETCHER_SCOPE_LOCAL; free( psz_scope ); lua_pop( L, 1 ); } lua_pop( L, 1 ); if ( p_context && p_context->pf_validator && !p_context->pf_validator( p_context, e_scope ) ) { msg_Dbg( p_this, "skipping script (unmatched scope) %s", psz_filename ); goto error; } lua_getglobal( L, luafunction ); if( !lua_isfunction( L, lua_gettop( L ) ) ) { msg_Warn( p_this, "Error while running script %s, " "function %s() not found", psz_filename, luafunction ); goto error; } if( lua_pcall( L, 0, 1, 0 ) ) { msg_Warn( p_this, "Error while running script %s, " "function %s(): %s", psz_filename, luafunction, lua_tostring( L, lua_gettop( L ) ) ); goto error; } return VLC_SUCCESS; error: lua_pop( L, 1 ); return VLC_EGENERIC; }
/***************************************************************************** * FillDescriptor: call the descriptor function and fill the structure ****************************************************************************/ static int FillDescriptor( services_discovery_t *p_sd, services_discovery_descriptor_t *p_desc ) { services_discovery_sys_t *p_sys = p_sd->p_sys; int i_ret = VLC_EGENERIC; /* Create a new lua thread */ lua_State *L = luaL_newstate(); if( vlclua_dofile( VLC_OBJECT(p_sd), L, p_sys->psz_filename ) ) { msg_Err( p_sd, "Error loading script %s: %s", p_sys->psz_filename, lua_tostring( L, -1 ) ); goto end; } /* Call the "descriptor" function */ lua_getglobal( L, "descriptor" ); if( !lua_isfunction( L, -1 ) || lua_pcall( L, 0, 1, 0 ) ) { msg_Warn( p_sd, "Error getting the descriptor in '%s': %s", p_sys->psz_filename, lua_tostring( L, -1 ) ); goto end; } /* Get the different fields of the returned table */ lua_getfield( L, -1, "short_description" ); p_desc->psz_short_desc = luaL_strdupornull( L, -1 ); lua_pop( L, 1 ); lua_getfield( L, -1, "icon" ); p_desc->psz_icon_url = luaL_strdupornull( L, -1 ); lua_pop( L, 1 ); lua_getfield( L, -1, "url" ); p_desc->psz_url = luaL_strdupornull( L, -1 ); lua_pop( L, 1 ); lua_getfield( L, -1, "capabilities" ); p_desc->i_capabilities = 0; if( lua_istable( L, -1 ) ) { /* List all table entries */ lua_pushnil( L ); while( lua_next( L, -2 ) != 0 ) { /* Key is at index -2 and value at index -1 */ const char *psz_cap = luaL_checkstring( L, -1 ); int i_cap = 0; const char *psz_iter; for( psz_iter = *ppsz_capabilities; psz_iter; psz_iter = ppsz_capabilities[ ++i_cap ] ) { if( !strcmp( psz_iter, psz_cap ) ) { p_desc->i_capabilities |= 1 << i_cap; break; } } lua_pop( L, 1 ); if( !psz_iter ) msg_Warn( p_sd, "Services discovery capability '%s' unknown in " "script '%s'", psz_cap, p_sys->psz_filename ); } } lua_pop( L, 1 ); i_ret = VLC_SUCCESS; end: lua_close( L ); return i_ret; }