--- 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 <dirent.h>
 #include <unistd.h>
 #include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/dir.h>
+#include <sys/param.h>
 #ifdef SOLARIS
 #include <thread.h>
 #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;

