33 #include <sys/types.h>
46 static void stored_recording_dtor(
void *obj)
59 return recording->
file;
94 RAII_VAR(
char *, relative_dir, NULL, ast_free);
95 RAII_VAR(
char *, absolute_dir, NULL, ast_free);
96 RAII_VAR(
char *, real_dir, NULL, ast_std_free);
98 const char *file_portion;
105 last_slash = strrchr(relative_dir,
'/');
108 file_portion = last_slash + 1;
110 ast_config_AST_RECORDING_DIR, relative_dir);
114 *relative_dir =
'\0';
115 absolute_dir =
ast_strdup(ast_config_AST_RECORDING_DIR);
121 real_dir = realpath(absolute_dir, NULL);
128 return (*dir && *file) ? 0 : -1;
137 static int is_recording(
const char *filename)
139 const char *ext = strrchr(filename,
'.');
148 ast_debug(5,
"Recording %s: unrecognized format %s\n",
155 return ext - filename - 1;
158 static int handle_find_recording(
const char *dir_name,
const char *filename,
void *obj)
164 if (!(num = is_recording(filename))
165 || data->length != num
166 || strncmp(data->file, filename, num)) {
170 if (
ast_asprintf(&data->file_with_ext,
"%s/%s", dir_name, filename) < 0) {
188 static char *
find_recording(
const char *dir_name,
const char *file)
192 .length = strlen(file),
193 .file_with_ext = NULL
199 return data.file_with_ext;
211 recording = ao2_alloc(
sizeof(*recording), stored_recording_dtor);
225 static int recording_sort(
const void *obj_left,
const void *obj_right,
int flags)
229 const char *right_key = obj_right;
234 right_key = object_right->
name;
237 cmp = strcmp(object_left->
name, right_key);
244 cmp = strncmp(object_left->
name, right_key, strlen(right_key));
255 static int handle_scan_file(
const char *dir_name,
const char *filename,
void *obj)
259 char *dot, *filepath;
262 if (!is_recording(filename)) {
266 if (
ast_asprintf(&filepath,
"%s/%s", dir_name, filename) < 0) {
282 dot = strrchr(recording->
file,
'.');
284 recording->
format = dot + 1;
288 recording->
file + strlen(ast_config_AST_RECORDING_DIR) + 1);
309 handle_scan_file, recordings, -1);
323 RAII_VAR(
char *, dir, NULL, ast_free);
327 struct stat file_stat;
328 int prefix_len = strlen(ast_config_AST_RECORDING_DIR);
351 char *real_basedir = realpath(ast_config_AST_RECORDING_DIR, NULL);
355 ast_log(LOG_WARNING,
"Attempt to access invalid recording directory %s\n",
357 ast_std_free(real_basedir);
363 prefix_len = strlen(real_basedir);
364 ast_std_free(real_basedir);
373 if (!file_with_ext) {
383 res = stat(file_with_ext, &file_stat);
388 if (!S_ISREG(file_stat.st_mode)) {
401 RAII_VAR(
char *, full_path, NULL, ast_free);
408 format = strrchr(dst_file,
'.');
414 last_slash = strrchr(dst_file,
'/');
416 RAII_VAR(
char *, tmp_path, NULL, ast_free);
419 if (
ast_asprintf(&tmp_path,
"%s/%s", ast_config_AST_RECORDING_DIR, dst_file) < 0) {
423 tmp_path, 0777) != 0) {
428 if (
ast_asprintf(&full_path,
"%s/%s", ast_config_AST_RECORDING_DIR, dst_file) < 0) {
433 if (
ast_asprintf(&full_path,
"%s/%s", ast_config_AST_RECORDING_DIR, dst_file) < 0) {
438 ast_verb(4,
"Copying recording %s to %s (format %s)\n", src_recording->
file,
439 full_path, src_recording->
format);
463 "name", recording->
name,
464 "format", recording->
format);
int ast_filecopy(const char *oldname, const char *newname, const char *fmt)
Copies a file.
Stasis Application Recording API. See StasisApplication API" for detailed documentation.
Asterisk main include file. File version handling, generic pbx functions.
const char * stasis_app_stored_recording_get_file(struct stasis_app_stored_recording *recording)
Returns the filename for this recording, for use with streamfile.
struct ast_json * ast_json_pack(char const *format,...)
Helper for creating complex JSON values.
int stasis_app_stored_recording_delete(struct stasis_app_stored_recording *recording)
Delete a recording from disk.
static char * find_recording(const char *dir_name, const char *file)
Finds a recording in the given directory.
const ast_string_field file_with_ext
static struct stasis_app_stored_recording * recording_alloc(void)
Allocate a recording object.
#define AST_DECLARE_STRING_FIELDS(field_list)
Declare the fields needed in a structure.
#define ast_strdup(str)
A wrapper for strdup()
int ast_file_read_dirs(const char *dir_name, ast_file_on_file on_file, void *obj, int max_depth)
Recursively iterate through files and directories up to max_depth.
#define ast_asprintf(ret, fmt,...)
A wrapper for asprintf()
struct ao2_container * stasis_app_stored_recording_find_all(void)
Find all stored recordings on disk.
static struct stasis_rest_handlers recordings
REST handler for /api-docs/recordings.json.
Asterisk file paths, configured in asterisk.conf.
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
#define ast_strdupa(s)
duplicate a string in memory from the stack
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
#define AST_STRING_FIELD(name)
Declare a string field.
const char * stasis_app_stored_recording_get_extension(struct stasis_app_stored_recording *recording)
Returns the extension for this recording.
int stasis_app_stored_recording_copy(struct stasis_app_stored_recording *src_recording, const char *dst, struct stasis_app_stored_recording **dst_recording)
Copy a recording.
#define ast_debug(level,...)
Log a DEBUG message.
const char * stasis_app_stored_recording_get_filename(struct stasis_app_stored_recording *recording)
Returns the full filename, with extension, for this recording.
static int split_path(const char *path, char **dir, char **file)
Split a path into directory and file, resolving canonical directory.
const ast_string_field name
struct ast_json * stasis_app_stored_recording_to_json(struct stasis_app_stored_recording *recording)
Convert stored recording info to JSON.
int ast_safe_mkdir(const char *base_path, const char *path, int mode)
Recursively create directory path, but only if it resolves within the given base_path.
struct ast_format * ast_get_format_for_file_ext(const char *file_ext)
Get the ast_format associated with the given file extension.
#define ast_string_field_build(x, field, fmt, args...)
Set a field to a complex (built) value.
const ast_string_field file
struct stasis_app_stored_recording * stasis_app_stored_recording_find_by_name(const char *name)
Creates a stored recording object, with the given name.
Replace objects with duplicate keys in container.
static int force_inline attribute_pure ast_begins_with(const char *str, const char *prefix)
Checks whether a string begins with another.
static int recording_sort(const void *obj_left, const void *obj_right, int flags)
Abstract JSON element (object, array, string, int, ...).
#define ao2_container_alloc_rbtree(ao2_options, container_options, sort_fn, cmp_fn)
Allocate and initialize a red-black tree container.
#define ast_file_read_dir(dir_name, on_file, obj)
Iterate over each file in a given directory.
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
#define ast_string_field_free_memory(x)
free all memory - to be called before destroying the object
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
#define ao2_link(container, obj)
Add an object to a container.