--- asterisk-1.4.21.2/res/res_musiconhold.c 2008-05-06 15:34:58.000000000 -0400 +++ asterisk-1.4.21.2-new/res/res_musiconhold.c 2009-09-04 14:14:31.000000000 -0400 @@ -48,6 +48,9 @@ #include #include #include +#include +#include +#include #ifdef SOLARIS #include #endif @@ -797,51 +800,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; + struct direct **files; + + /* free the current file list */ + for (i = 0; i < class->total_files; i++) + free(class->filearray[i]); - files_DIR = opendir(class->dir); - if (!files_DIR) { + /* reset the file count */ + class->total_files = 0; + + /* 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(%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; } - for (i = 0; i < class->total_files; i++) - free(class->filearray[i]); + /* loop through the files */ + for (j=1; j < file_count+1; ++j) { - class->total_files = 0; - dirnamelen = strlen(class->dir) + 2; - getcwd(path, sizeof(path)); - chdir(class->dir); - while ((files_dirent = readdir(files_DIR))) { /* 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++; @@ -849,17 +890,29 @@ /* 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); - chdir(path); + /* go back where we came from */ + if (chdir(path) < 0) { + ast_log(LOG_WARNING, "chdir(%s) failed: %s\n", path, strerror(errno)); + return -1; + } return class->total_files; }