[asterisk-commits] dlee: branch dlee/record r394822 - /team/dlee/record/res/stasis_recording/
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Fri Jul 19 16:23:14 CDT 2013
Author: dlee
Date: Fri Jul 19 16:23:12 2013
New Revision: 394822
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=394822
Log:
It works. I guess.
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=394822&r1=394821&r2=394822
==============================================================================
--- team/dlee/record/res/stasis_recording/stored.c (original)
+++ team/dlee/record/res/stasis_recording/stored.c Fri Jul 19 16:23:12 2013
@@ -43,7 +43,7 @@
AST_STRING_FIELD(file_with_ext); /*!< Absolute filename, with extension; for use with everything */
);
- const char *format; /*!< Format name (i.e. filename extension) */
+ char *format; /*!< Format name (i.e. filename extension) */
};
static void stored_recording_dtor(void *obj)
@@ -113,7 +113,7 @@
char *file_with_ext = NULL;
dir = opendir(dir_name);
- if (dir == NULL) {
+ if (!dir) {
return NULL;
}
@@ -216,9 +216,171 @@
"format", recording->format);
}
+static int recording_sort(const void *obj_left, const void *obj_right, int flags)
+{
+ const struct stasis_app_stored_recording *object_left = obj_left;
+ const struct stasis_app_stored_recording *object_right = obj_right;
+ const char *right_key = obj_right;
+ int cmp;
+
+ switch (flags & (OBJ_POINTER | OBJ_KEY | OBJ_PARTIAL_KEY)) {
+ case OBJ_POINTER:
+ right_key = object_right->name;
+ /* Fall through */
+ case OBJ_KEY:
+ cmp = strcmp(object_left->name, right_key);
+ break;
+ case OBJ_PARTIAL_KEY:
+ /*
+ * We could also use a partial key struct containing a length
+ * so strlen() does not get called for every comparison instead.
+ */
+ cmp = strncmp(object_left->name, right_key, strlen(right_key));
+ break;
+ default:
+ /* Sort can only work on something with a full or partial key. */
+ ast_assert(0);
+ cmp = 0;
+ break;
+ }
+ 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);
+ 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 (!dir) {
+ ast_log(LOG_WARNING, "Error reading dir '%s'\n", full_dir);
+ 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);
+
+ 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 = ao2_alloc(sizeof(*recording), stored_recording_dtor);
+ if (!recording) {
+ ast_log(LOG_WARNING, "Error allocating recording object for %s\n", file_with_ext);
+ continue;
+ }
+
+ ast_string_field_init(recording, 255);
+ 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);
+ }
+
+ return 0;
+}
+
struct ao2_container *stasis_app_stored_recording_find_all(void)
{
- return NULL;
+ RAII_VAR(struct ao2_container *, recordings, NULL, ao2_cleanup);
+ int res;
+
+ recordings = ao2_container_alloc_rbtree(AO2_ALLOC_OPT_LOCK_NOLOCK,
+ AO2_CONTAINER_ALLOC_OPT_DUPS_REPLACE, recording_sort, NULL);
+ if (!recordings) {
+ return NULL;
+ }
+
+ res = find_all_in_dir(recordings, ast_config_AST_RECORDING_DIR, "");
+ if (res != 0) {
+ return NULL;
+ }
+
+ ao2_ref(recordings, +1);
+ return recordings;
}
struct stasis_app_stored_recording *stasis_app_stored_recording_find_by_name(
More information about the asterisk-commits
mailing list