[svn-commits] dlee: branch dlee/record r395100 - /team/dlee/record/res/stasis_recording/

SVN commits to the Digium repositories svn-commits at lists.digium.com
Mon Jul 22 21:51:04 CDT 2013


Author: dlee
Date: Mon Jul 22 21:51:02 2013
New Revision: 395100

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=395100
Log:
Code's starting to look respectable

Modified:
    team/dlee/record/res/stasis_recording/stored.c

Modified: team/dlee/record/res/stasis_recording/stored.c
URL: http://svnview.digium.com/svn/asterisk/team/dlee/record/res/stasis_recording/stored.c?view=diff&rev=395100&r1=395099&r2=395100
==============================================================================
--- team/dlee/record/res/stasis_recording/stored.c (original)
+++ team/dlee/record/res/stasis_recording/stored.c Mon Jul 22 21:51:02 2013
@@ -104,6 +104,14 @@
 	return 0;
 }
 
+static void safe_closedir(DIR *dirp)
+{
+	if (!dirp) {
+		return;
+	}
+	closedir(dirp);
+}
+
 /*!
  * \brief Finds a recording in the given directory.
  *
@@ -117,7 +125,7 @@
  */
 static char *find_recording(const char *dir_name, const char *file)
 {
-	RAII_VAR(DIR *, dir, NULL, closedir);
+	RAII_VAR(DIR *, dir, NULL, safe_closedir);
 	struct dirent entry = {};
 	struct dirent *result = NULL;
 	char *ext = NULL;
@@ -212,130 +220,133 @@
 	return cmp;
 }
 
-static int find_all_in_dir(struct ao2_container *recordings,
-	const char *base_dir, const char *dir_name)
-{
-	RAII_VAR(char *, full_dir, NULL, ast_free);
-	RAII_VAR(DIR *, dir, NULL, closedir);
+static int scan(struct ao2_container *recordings,
+	const char *base_dir, const char *subdir, struct dirent *entry);
+
+static int scan_file(struct ao2_container *recordings,
+	const char *base_dir, const char *subdir, const char *filename,
+	const char *path)
+{
+	RAII_VAR(struct stasis_app_stored_recording *, recording, NULL,
+		ao2_cleanup);
+	const char *ext;
+
+	ext = strrchr(filename, '.');
+
+	if (!ext) {
+		ast_verb(4, "  Ignore file without extension: %s\n",
+			filename);
+		/* No file extension; not us */
+		return 0;
+	}
+	++ext;
+
+	if (!ast_get_format_for_file_ext(ext)) {
+		ast_verb(4, "  Not a media file: %s\n", filename);
+		/* Not a media file */
+		return 0;
+	}
+
+	recording = recording_alloc();
+	if (!recording) {
+		return -1;
+	}
+
+	ast_string_field_set(recording, file_with_ext, path);
+
+	/* Build file and format from full path */
+	ast_string_field_set(recording, file, path);
+	recording->format = strrchr(recording->file, '.');
+	*(recording->format++) = '\0';
+
+	/* Build recurding name */
+	if (!ast_strlen_zero(subdir)) {
+		ast_string_field_build(recording, name, "/%s", subdir);
+	}
+	if (!ast_strlen_zero(filename)) {
+		ast_string_field_build(recording, name, "/%s", filename);
+	}
+
+	/* Add it to the recordings container */
+	ao2_link(recordings, recording);
+
+	return 0;
+}
+
+static int scan_dir(struct ao2_container *recordings,
+	const char *base_dir, const char *subdir, const char *dirname,
+	const char *path)
+{
+	RAII_VAR(DIR *, dir, NULL, safe_closedir);
+	RAII_VAR(struct ast_str *, rel_dirname, NULL, ast_free);
 	struct dirent entry = {};
 	struct dirent *result = NULL;
 
-	ast_verb(4, "Finding recordings in '%s'\n", dir_name);
-
-	if (ast_strlen_zero(dir_name)) {
-		full_dir = ast_strdup(base_dir);
-	} else {
-		ast_asprintf(&full_dir, "%s/%s", base_dir, dir_name);
-	}
-	if (!full_dir) {
-		ast_log(LOG_WARNING, "Error reading recording dir '%s'\n", dir_name);
-		return -1;
-	}
-
-	dir = opendir(full_dir);
+	if (strcmp(dirname, ".") == 0 ||
+		strcmp(dirname, "..") == 0) {
+		ast_verb(4, "  Ignoring self/parent dir\n");
+		return 0;
+	}
+
+	/* Build relative dirname */
+	rel_dirname = ast_str_create(80);
+	if (!rel_dirname) {
+		return -1;
+	}
+	if (!ast_strlen_zero(subdir)) {
+		ast_str_append(&rel_dirname, 0, "/%s", subdir);
+	}
+	if (!ast_strlen_zero(dirname)) {
+		ast_str_append(&rel_dirname, 0, "/%s", dirname);
+	}
+
+	dir = opendir(path);
 	if (!dir) {
-		ast_log(LOG_WARNING, "Error reading dir '%s'\n", full_dir);
+		ast_log(LOG_WARNING, "Error reading dir '%s'\n", path);
 		return -1;
 	}
 
 	while (readdir_r(dir, &entry, &result) == 0 && result != NULL) {
-		RAII_VAR(struct stasis_app_stored_recording *, recording, NULL,
-			ao2_cleanup);
-		RAII_VAR(char *, file_with_ext, NULL, ast_free);
-		char *ext;
-		struct stat file_stat;
-		int res;
-
-		ast_verb(4, "Scanning '%s'\n", result->d_name);
-
-		if (strcmp(result->d_name, ".") == 0 ||
-			strcmp(result->d_name, "..") == 0) {
-			ast_verb(4, "  Ignore self/parent dir\n");
-			continue;
-		}
-
-		ast_asprintf(&file_with_ext, "%s/%s", full_dir, result->d_name);
-		if (!file_with_ext) {
-			ast_log(LOG_WARNING, "Error determining recording path\n");
-			continue;
-		}
-
-		res = stat(file_with_ext, &file_stat);
-		if (res != 0) {
-			ast_log(LOG_WARNING, "Error getting file info: %s\n", file_with_ext);
-			continue;
-		}
-
-		if (S_ISDIR(file_stat.st_mode)) {
-			/* process subdirectory */
-			RAII_VAR(char *, sub_dir, NULL, ast_free);
-
-			/* symlinks to directories cause weirdness; ignore */
-			res = lstat(file_with_ext, &file_stat);
-			if (res != 0) {
-				ast_log(LOG_WARNING, "Error getting file info: %s\n", file_with_ext);
-				continue;
-			}
-
-			if (S_ISLNK(file_stat.st_mode)) {
-				ast_log(LOG_WARNING, "Ignoring symlink %s\n",
-					result->d_name);
-				continue;
-			}
-
-			if (ast_strlen_zero(dir_name)) {
-				sub_dir = ast_strdup(result->d_name);
-			} else {
-				ast_asprintf(&sub_dir, "%s/%s", dir_name, result->d_name);
-			}
-			if (!sub_dir) {
-				ast_log(LOG_WARNING, "Error determining subdir path\n");
-				continue;
-
-			}
-			find_all_in_dir(recordings, base_dir, sub_dir);
-			continue;
-		}
-
-		if (!S_ISREG(file_stat.st_mode)) {
-			ast_log(LOG_WARNING,
-				"Skipping recording %s: not a regular file\n",
-				file_with_ext);
-			continue;
-		}
-
-		ext = strrchr(result->d_name, '.');
-
-		if (!ext) {
-			ast_verb(4, "  Ignore file without extension\n");
-			/* No file extension; not us */
-			continue;
-		}
-		++ext;
-
-		if (!ast_get_format_for_file_ext(ext)) {
-			ast_verb(4, "  Not a media file\n");
-			/* Not a media file */
-			continue;
-		}
-
-		recording = recording_alloc();
-		if (!recording) {
-			ast_log(LOG_WARNING, "Error allocating recording object for %s\n", file_with_ext);
-			continue;
-		}
-
-		ast_string_field_set(recording, file_with_ext, file_with_ext);
-
-		/* Build file and format from file_with_ext */
-		ast_string_field_set(recording, file, file_with_ext);
-		recording->format = strrchr(recording->file, '.');
-		*(recording->format++) = '\0';
-
-		/* Build name from file */
-		ast_string_field_set(recording, name,
-			recording->file + strlen(ast_config_AST_RECORDING_DIR) + 1);
-		ao2_link(recordings, recording);
+		scan(recordings, base_dir, ast_str_buffer(rel_dirname), result);
+	}
+
+	return 0;
+}
+
+static int scan(struct ao2_container *recordings,
+	const char *base_dir, const char *subdir, struct dirent *entry)
+{
+	RAII_VAR(struct ast_str *, path, NULL, ast_free);
+
+	path = ast_str_create(255);
+	if (!path) {
+		return -1;
+	}
+
+	/* Build file path */
+	ast_str_append(&path, 0, "%s", base_dir);
+	if (!ast_strlen_zero(subdir)) {
+		ast_str_append(&path, 0, "/%s", subdir);
+	}
+	if (entry) {
+		ast_str_append(&path, 0, "/%s", entry->d_name);
+	}
+	ast_verb(4, "Scanning '%s'\n", ast_str_buffer(path));
+
+	/* Handle this file */
+	switch (entry->d_type) {
+	case DT_REG:
+		scan_file(recordings, base_dir, subdir, entry->d_name,
+			ast_str_buffer(path));
+		break;
+	case DT_DIR:
+		scan_dir(recordings, base_dir, subdir, entry->d_name,
+			ast_str_buffer(path));
+		break;
+	default:
+		ast_log(LOG_WARNING, "Skipping %s: not a regular file\n",
+			ast_str_buffer(path));
+		break;
 	}
 
 	return 0;
@@ -352,7 +363,8 @@
 		return NULL;
 	}
 
-	res = find_all_in_dir(recordings, ast_config_AST_RECORDING_DIR, "");
+	res = scan_dir(recordings, ast_config_AST_RECORDING_DIR, NULL, "",
+		ast_config_AST_RECORDING_DIR);
 	if (res != 0) {
 		return NULL;
 	}




More information about the svn-commits mailing list