char *vlclua_find_file( vlc_object_t *p_this, const char *psz_luadirname, const char *psz_name ) { char **ppsz_dir_list = NULL; vlclua_dir_list( p_this, psz_luadirname, &ppsz_dir_list ); for( char **ppsz_dir = ppsz_dir_list; *ppsz_dir; ppsz_dir++ ) { for( const char **ppsz_ext = ppsz_lua_exts; *ppsz_ext; ppsz_ext++ ) { char *psz_filename; struct stat st; if( asprintf( &psz_filename, "%s"DIR_SEP"%s%s", *ppsz_dir, psz_name, *ppsz_ext ) < 0 ) { vlclua_dir_list_free( ppsz_dir_list ); return NULL; } if( vlc_stat( psz_filename, &st ) == 0 && S_ISREG( st.st_mode ) ) { vlclua_dir_list_free( ppsz_dir_list ); return psz_filename; } free( psz_filename ); } } vlclua_dir_list_free( ppsz_dir_list ); return NULL; }
static char *FindFile( const char *psz_name ) { char *ppsz_dir_list[] = { NULL, NULL, NULL, NULL }; char **ppsz_dir; vlclua_dir_list( "intf", ppsz_dir_list ); for( ppsz_dir = ppsz_dir_list; *ppsz_dir; ppsz_dir++ ) { char *psz_filename; FILE *fp; if( asprintf( &psz_filename, "%s"DIR_SEP"%s.lua", *ppsz_dir, psz_name ) < 0 ) { vlclua_dir_list_free( ppsz_dir_list ); return NULL; } fp = fopen( psz_filename, "r" ); if( fp ) { fclose( fp ); vlclua_dir_list_free( ppsz_dir_list ); return psz_filename; } free( psz_filename ); } vlclua_dir_list_free( ppsz_dir_list ); return NULL; }
/***************************************************************************** * Will execute func on all scripts in luadirname, and stop if func returns * success. *****************************************************************************/ int vlclua_scripts_batch_execute( vlc_object_t *p_this, const char * luadirname, int (*func)(vlc_object_t *, const char *, void *), void * user_data) { char **ppsz_dir_list = NULL; int i_ret = vlclua_dir_list( p_this, luadirname, &ppsz_dir_list ); if( i_ret != VLC_SUCCESS ) return i_ret; i_ret = VLC_EGENERIC; for( char **ppsz_dir = ppsz_dir_list; *ppsz_dir; ppsz_dir++ ) { char **ppsz_filelist; int i_files; msg_Dbg( p_this, "Trying Lua scripts in %s", *ppsz_dir ); i_files = vlc_scandir( *ppsz_dir, &ppsz_filelist, file_select, file_compare ); if( i_files < 0 ) continue; char **ppsz_file = ppsz_filelist; char **ppsz_fileend = ppsz_filelist + i_files; while( ppsz_file < ppsz_fileend ) { char *psz_filename; if( asprintf( &psz_filename, "%s" DIR_SEP "%s", *ppsz_dir, *ppsz_file ) == -1 ) psz_filename = NULL; free( *(ppsz_file++) ); if( likely(psz_filename != NULL) ) { msg_Dbg( p_this, "Trying Lua playlist script %s", psz_filename ); i_ret = func( p_this, psz_filename, user_data ); free( psz_filename ); if( i_ret == VLC_SUCCESS ) break; } } while( ppsz_file < ppsz_fileend ) free( *(ppsz_file++) ); free( ppsz_filelist ); if( i_ret == VLC_SUCCESS ) break; } vlclua_dir_list_free( ppsz_dir_list ); return i_ret; }
static int vlc_sd_probe_Open( vlc_object_t *obj ) { vlc_dictionary_t name_d; char **ppsz_dir_list; if( vlclua_dir_list( "sd", &ppsz_dir_list ) ) return VLC_ENOMEM; vlc_dictionary_init( &name_d, 32 ); for( char **ppsz_dir = ppsz_dir_list; *ppsz_dir; ppsz_dir++ ) { char **ppsz_filelist; int i_files = vlc_scandir( *ppsz_dir, &ppsz_filelist, file_select, file_compare ); if( i_files < 1 ) continue; for( char **ppsz_file = ppsz_filelist; ppsz_file < ppsz_filelist + i_files; ppsz_file++ ) { char *temp = strchr( *ppsz_file, '.' ); if( temp ) *temp = '\0'; if( vlc_dictionary_value_for_key( &name_d, *ppsz_file ) == kVLCDictionaryNotFound ) vlc_dictionary_insert( &name_d, *ppsz_file, &name_d ); free( *ppsz_file ); } free( ppsz_filelist ); } vlclua_dir_list_free( ppsz_dir_list ); int r = VLC_PROBE_CONTINUE; char **names = vlc_dictionary_all_keys( &name_d ); if( names != NULL ) { for( char **name = names; *name; ++name ) { r = vlclua_probe_sd( obj, *name ); if( r != VLC_PROBE_CONTINUE ) break; } for( char **name = names; *name; ++name ) free( *name ); free( names ); } vlc_dictionary_clear( &name_d, NULL, NULL ); return r; }
static int vlclua_datadir_list( lua_State *L ) { const char *psz_dirname = luaL_checkstring( L, 1 ); char **ppsz_dir_list = NULL; int i = 1; if( vlclua_dir_list( psz_dirname, &ppsz_dir_list ) != VLC_SUCCESS ) return 0; lua_newtable( L ); for( char **ppsz_dir = ppsz_dir_list; *ppsz_dir; ppsz_dir++ ) { lua_pushstring( L, *ppsz_dir ); lua_rawseti( L, -2, i ); i ++; } vlclua_dir_list_free( ppsz_dir_list ); return 1; }
int __vlclua_add_modules_path( vlc_object_t *obj, lua_State *L, const char *psz_filename ) { /* Setup the module search path: * * "The script's directory"/modules * * "The script's parent directory"/modules * * and so on for all the next directories in the directory list */ char *psz_path = strdup( psz_filename ); if( !psz_path ) return 1; char *psz_char = strrchr( psz_path, DIR_SEP_CHAR ); if( !psz_char ) { free( psz_path ); return 1; } *psz_char = '\0'; /* psz_path now holds the file's directory */ psz_char = strrchr( psz_path, DIR_SEP_CHAR ); if( !psz_char ) { free( psz_path ); return 1; } *psz_char = '\0'; /* Push package on stack */ int count = 0; lua_getglobal( L, "package" ); /* psz_path now holds the file's parent directory */ count += vlclua_add_modules_path_inner( L, psz_path ); *psz_char = DIR_SEP_CHAR; /* psz_path now holds the file's directory */ count += vlclua_add_modules_path_inner( L, psz_path ); char **ppsz_dir_list = NULL; vlclua_dir_list( obj, psz_char+1/* gruik? */, &ppsz_dir_list ); char **ppsz_dir = ppsz_dir_list; for( ; *ppsz_dir && strcmp( *ppsz_dir, psz_path ); ppsz_dir++ ); free( psz_path ); for( ; *ppsz_dir; ppsz_dir++ ) { psz_path = *ppsz_dir; /* FIXME: doesn't work well with meta/... modules due to the double * directory depth */ psz_char = strrchr( psz_path, DIR_SEP_CHAR ); if( !psz_char ) { vlclua_dir_list_free( ppsz_dir_list ); return 1; } *psz_char = '\0'; count += vlclua_add_modules_path_inner( L, psz_path ); *psz_char = DIR_SEP_CHAR; count += vlclua_add_modules_path_inner( L, psz_path ); } lua_getfield( L, -(count+1), "path" ); /* Get package.path */ lua_concat( L, count+1 ); /* Concat vlc module paths and package.path */ lua_setfield( L, -2, "path"); /* Set package.path */ lua_pop( L, 1 ); /* Pop the package module */ vlclua_dir_list_free( ppsz_dir_list ); return 0; }
static int vlc_sd_probe_Open( vlc_object_t *obj ) { vlc_probe_t *probe = (vlc_probe_t *)obj; char **ppsz_filelist = NULL; char **ppsz_fileend = NULL; char **ppsz_file; char *psz_name; char **ppsz_dir_list = NULL; char **ppsz_dir; lua_State *L = NULL; vlclua_dir_list( obj, "sd", &ppsz_dir_list ); for( ppsz_dir = ppsz_dir_list; *ppsz_dir; ppsz_dir++ ) { int i_files; if( ppsz_filelist ) { for( ppsz_file = ppsz_filelist; ppsz_file < ppsz_fileend; ppsz_file++ ) free( *ppsz_file ); free( ppsz_filelist ); ppsz_filelist = NULL; } i_files = vlc_scandir( *ppsz_dir, &ppsz_filelist, file_select, file_compare ); if( i_files < 1 ) continue; ppsz_fileend = ppsz_filelist + i_files; for( ppsz_file = ppsz_filelist; ppsz_file < ppsz_fileend; ppsz_file++ ) { char *psz_filename; if( asprintf( &psz_filename, "%s" DIR_SEP "%s", *ppsz_dir, *ppsz_file ) < 0 ) { goto error; } L = luaL_newstate(); if( !L ) { msg_Err( probe, "Could not create new Lua State" ); free( psz_filename ); goto error; } luaL_openlibs( L ); if( vlclua_add_modules_path( probe, L, psz_filename ) ) { msg_Err( probe, "Error while setting the module search path for %s", psz_filename ); free( psz_filename ); goto error; } if( luaL_dofile( L, psz_filename ) ) { msg_Err( probe, "Error loading script %s: %s", psz_filename, lua_tostring( L, lua_gettop( L ) ) ); lua_pop( L, 1 ); free( psz_filename ); lua_close( L ); continue; } char *psz_longname; char *temp = strchr( *ppsz_file, '.' ); if( temp ) *temp = '\0'; lua_getglobal( L, "descriptor" ); if( !lua_isfunction( L, lua_gettop( L ) ) || lua_pcall( L, 0, 1, 0 ) ) { msg_Warn( probe, "No 'descriptor' function in '%s'", psz_filename ); lua_pop( L, 1 ); if( !( psz_longname = strdup( *ppsz_file ) ) ) { free( psz_filename ); goto error; } } else { lua_getfield( L, -1, "title" ); if( !lua_isstring( L, -1 ) || !( psz_longname = strdup( lua_tostring( L, -1 ) ) ) ) { free( psz_filename ); goto error; } } char *psz_file_esc = config_StringEscape( *ppsz_file ); char *psz_longname_esc = config_StringEscape( psz_longname ); if( asprintf( &psz_name, "lua{sd='%s',longname='%s'}", psz_file_esc, psz_longname_esc ) < 0 ) { free( psz_file_esc ); free( psz_longname_esc ); free( psz_filename ); free( psz_longname ); goto error; } free( psz_file_esc ); free( psz_longname_esc ); vlc_sd_probe_Add( probe, psz_name, psz_longname, SD_CAT_INTERNET ); free( psz_name ); free( psz_longname ); free( psz_filename ); lua_close( L ); } } if( ppsz_filelist ) { for( ppsz_file = ppsz_filelist; ppsz_file < ppsz_fileend; ppsz_file++ ) free( *ppsz_file ); free( ppsz_filelist ); } vlclua_dir_list_free( ppsz_dir_list ); return VLC_PROBE_CONTINUE; error: if( ppsz_filelist ) { for( ppsz_file = ppsz_filelist; ppsz_file < ppsz_fileend; ppsz_file++ ) free( *ppsz_file ); free( ppsz_filelist ); } if( L ) lua_close( L ); vlclua_dir_list_free( ppsz_dir_list ); return VLC_ENOMEM; }