--- asterisk-1.4.26.2/res/res_musiconhold.c 2009-06-18 11:24:31.000000000 -0400 +++ asterisk-1.4.26.2-new/res/res_musiconhold.c 2009-09-04 14:26:08.000000000 -0400 @@ -50,6 +50,9 @@ #include #include #include +#include +#include +#include #ifdef SOLARIS #include #endif @@ -807,57 +810,89 @@ return 0; } -static int moh_scan_files(struct mohclass *class) { - - DIR *files_DIR; - struct dirent *files_dirent; +static int moh_scan_files(struct mohclass *class) +{ + int file_count; + int i, j; char path[PATH_MAX]; char filepath[PATH_MAX]; char *ext; struct stat statbuf; - int dirnamelen; - int i; - - files_DIR = opendir(class->dir); - if (!files_DIR) { - ast_log(LOG_WARNING, "Cannot open dir %s or dir does not exist\n", class->dir); - return -1; - } + struct direct **files; + /* free the current file list */ for (i = 0; i < class->total_files; i++) free(class->filearray[i]); + /* reset the file count */ class->total_files = 0; - dirnamelen = strlen(class->dir) + 2; + + /* save the current directory */ if (!getcwd(path, sizeof(path))) { ast_log(LOG_WARNING, "getcwd() failed: %s\n", strerror(errno)); return -1; } + + /* go to the directory in question*/ if (chdir(class->dir) < 0) { - ast_log(LOG_WARNING, "chdir() failed: %s\n", strerror(errno)); + ast_log(LOG_WARNING, "chdir(%s) failed: %s\n", class->dir, strerror(errno)); + return -1; + } + + if (option_verbose > 2) + ast_verbose(VERBOSE_PREFIX_3 "Loading musiconhold files from directory '%s'\n",class->dir); + + /* get the file listing for the directory and sort it alphabetically */ + file_count = scandir(class->dir, &files, NULL, alphasort); + + /* scandir returned and error */ + if (file_count <= -1) { + ast_log(LOG_WARNING, "Cannot open dir %s or dir does not exist\n", class->dir); return -1; } - while ((files_dirent = readdir(files_DIR))) { + + /* loop through the files */ + for (j=1; j < file_count+1; ++j) { + /* The file name must be at least long enough to have the file type extension */ - if ((strlen(files_dirent->d_name) < 4)) + if ((strlen(files[j-1]->d_name) < 4)) { + if (option_verbose > 2) + ast_verbose(VERBOSE_PREFIX_3 "Skipping file '%s'. Filename is too short to have an acceptable extension.\n", files[j-1]->d_name); continue; + } /* Skip files that starts with a dot */ - if (files_dirent->d_name[0] == '.') + if (files[j-1]->d_name[0] == '.') { + if (option_verbose > 2) + ast_verbose(VERBOSE_PREFIX_3 "Skipping file '%s'. Filename begins with a dot.\n", files[j-1]->d_name); continue; + } /* Skip files without extensions... they are not audio */ - if (!strchr(files_dirent->d_name, '.')) + if (!strchr(files[j-1]->d_name, '.')) { + if (option_verbose > 2) + ast_verbose(VERBOSE_PREFIX_3 "Skipping file '%s'. Filename has no extension.\n", files[j-1]->d_name); continue; + } - snprintf(filepath, sizeof(filepath), "%s/%s", class->dir, files_dirent->d_name); + /* get the full path to the file */ + snprintf(filepath, sizeof(filepath), "%s/%s", class->dir, files[j-1]->d_name); - if (stat(filepath, &statbuf)) + /* if we cannot stat the file skip it */ + if (stat(filepath, &statbuf)) { + if (option_verbose > 2) + ast_verbose(VERBOSE_PREFIX_3 "Skipping file '%s'. Cannot stat the file.\n", files[j-1]->d_name); continue; + } - if (!S_ISREG(statbuf.st_mode)) + /* if the file is not a regular file skip it */ + if (!S_ISREG(statbuf.st_mode)) { + if (option_verbose > 2) + ast_verbose(VERBOSE_PREFIX_3 "Skipping file '%s'. File is not a regular file.\n", files[j-1]->d_name); continue; + } + /* remove the file extension */ if ((ext = strrchr(filepath, '.'))) { *ext = '\0'; ext++; @@ -865,18 +900,27 @@ /* if the file is present in multiple formats, ensure we only put it into the list once */ for (i = 0; i < class->total_files; i++) - if (!strcmp(filepath, class->filearray[i])) + if (!strcmp(filepath, class->filearray[i])) { + if (option_verbose > 2) + ast_verbose(VERBOSE_PREFIX_3 "Skipping file '%s'. Base filename already exists from another format.\n", files[j-1]->d_name); break; + } + /* add the file */ if (i == class->total_files) { - if (moh_add_file(class, filepath)) + if (moh_add_file(class, filepath)) { + ast_log(LOG_WARNING, "Unable to add file %s.", filepath); break; + } else { + if (option_verbose > 2) + ast_verbose(VERBOSE_PREFIX_3 "Adding file '%s' as '%s'.\n", files[j-1]->d_name, filepath); + } } } - closedir(files_DIR); + /* go back where we came from */ if (chdir(path) < 0) { - ast_log(LOG_WARNING, "chdir() failed: %s\n", strerror(errno)); + ast_log(LOG_WARNING, "chdir(%s) failed: %s\n", path, strerror(errno)); return -1; } return class->total_files;