@ -1208,84 +1208,95 @@ static void moh_parse_options(struct ast_variable *var, struct mohclass *mohclas
}
}
static int moh_scan_files ( struct mohclass * class ) {
DIR * files_DIR ;
struct dirent * files_dirent ;
char dir_path [ PATH_MAX - sizeof ( class - > dir ) ] ;
char filepath [ PATH_MAX ] ;
char * ext ;
struct stat statbuf ;
int res ;
struct ast_vector_string * files ;
static int on_moh_file ( const char * directory , const char * filename , void * obj )
{
struct ast_vector_string * files = obj ;
char * full_path ;
char * extension ;
if ( class - > dir [ 0 ] ! = ' / ' ) {
snprintf ( dir_path , sizeof ( dir_path ) , " %s/%s " , ast_config_AST_DATA_DIR , class - > dir ) ;
} else {
ast_copy_string ( dir_path , class - > dir , sizeof ( dir_path ) ) ;
}
ast_debug ( 4 , " Scanning '%s' for files for class '%s' \n " , dir_path , class - > name ) ;
files_DIR = opendir ( dir_path ) ;
if ( ! files_DIR ) {
ast_log ( LOG_WARNING , " Cannot open dir %s or dir does not exist \n " , dir_path ) ;
return - 1 ;
/* Skip files that starts with a dot */
if ( * filename = = ' . ' ) {
ast_debug ( 4 , " Skipping '%s/%s' because it starts with a dot \n " ,
directory , filename ) ;
return 0 ;
}
files = moh_file_vector_alloc ( 16 ) ; /* 16 seems like a reasonable default */
if ( ! files ) {
closedir ( files_DIR ) ;
return - 1 ;
/* We can't do anything with files that don't have an extension,
* so check that first and punt if we can ' t find something */
extension = strrchr ( filename , ' . ' ) ;
if ( ! extension ) {
ast_debug ( 4 , " Skipping '%s/%s' because it doesn't have an extension \n " ,
directory , filename ) ;
return 0 ;
}
while ( ( files_dirent = readdir ( files_DIR ) ) ) {
char * filepath_copy ;
/* The extension needs at least two characters (after the .) to be useful */
if ( strlen ( extension ) < 3 ) {
ast_debug ( 4 , " Skipping '%s/%s' because it doesn't have at least a two "
" character extension \n " , directory , filename ) ;
return 0 ;
}
/* The file name must be at least long enough to have the file type extension */
if ( ( strlen ( files_dirent - > d_name ) < 4 ) )
continue ;
/* Build the full path (excluding the extension) */
if ( ast_asprintf ( & full_path , " %s/%.*s " ,
directory ,
( int ) ( extension - filename ) , filename ) < 0 ) {
/* If we don't have enough memory to build this path, there is no
* point in continuing */
return 1 ;
}
/* Skip files that starts with a dot */
if ( files_dirent - > d_name [ 0 ] = = ' . ' )
continue ;
/* If the file is present in multiple formats, ensure we only put it
* into the list once . Pretty sure this is O ( n ^ 2 ) . */
if ( AST_VECTOR_GET_CMP ( files , & full_path [ 0 ] , ! strcmp ) ) {
ast_free ( full_path ) ;
return 0 ;
}
/* Skip files without extensions... they are not audio */
if ( ! strchr ( files_dirent - > d_name , ' . ' ) )
continue ;
if ( AST_VECTOR_APPEND ( files , full_path ) ) {
/* AST_VECTOR_APPEND() can only fail on allocation failure, so
* we stop iterating */
ast_free ( full_path ) ;
return 1 ;
}
snprintf ( filepath , sizeof ( filepath ) , " %s/%s " , dir_path , files_dirent - > d_name ) ;
return 0 ;
}
if ( stat ( filepath , & statbuf ) )
continue ;
static int moh_filename_strcasecmp ( const void * a , const void * b )
{
const char * * s1 = ( const char * * ) a ;
const char * * s2 = ( const char * * ) b ;
return strcasecmp ( * s1 , * s2 ) ;
}
if ( ! S_ISREG ( statbuf . st_mode ) )
continue ;
static int moh_scan_files ( struct mohclass * class ) {
if ( ( ext = strrchr ( filepath , ' . ' ) ) )
* ext = ' \0 ' ;
char dir_path [ PATH_MAX - sizeof ( class - > dir ) ] ;
struct ast_vector_string * files ;
/* if the file is present in multiple formats, ensure we only put it into the list once */
if ( AST_VECTOR_GET_CMP ( files , & filepath [ 0 ] , ! strcmp ) ) {
continue ;
}
if ( class - > dir [ 0 ] ! = ' / ' ) {
snprintf ( dir_path , sizeof ( dir_path ) , " %s/%s " , ast_config_AST_DATA_DIR , class - > dir ) ;
} else {
ast_copy_string ( dir_path , class - > dir , sizeof ( dir_path ) ) ;
}
filepath_copy = ast_strdup ( filepath ) ;
if ( ! filepath_copy ) {
break ;
}
ast_debug ( 4 , " Scanning '%s' for files for class '%s' \n " , dir_path , class - > name ) ;
if ( ast_test_flag ( class , MOH_SORTALPHA ) ) {
res = AST_VECTOR_ADD_SORTED ( files , filepath_copy , strcasecmp ) ;
} else {
res = AST_VECTOR_APPEND ( files , filepath_copy ) ;
}
/* 16 seems like a reasonable default */
files = moh_file_vector_alloc ( 16 ) ;
if ( ! files ) {
return - 1 ;
}
if ( res ) {
ast_free ( filepath_copy ) ;
break ;
}
if ( ast_file_read_dir ( dir_path , on_moh_file , files ) ) {
ao2_ref ( files , - 1 ) ;
return - 1 ;
}
closedir ( files_DIR ) ;
if ( ast_test_flag ( class , MOH_SORTALPHA ) ) {
AST_VECTOR_SORT ( files , moh_filename_strcasecmp ) ;
}
AST_VECTOR_COMPACT ( files ) ;