Asterisk - The Open Source Telephony Project GIT-master-5aee26c
Loading...
Searching...
No Matches
Data Structures | Macros | Enumerations | Functions | Variables
file.c File Reference

Generic File Format Support. More...

#include "asterisk.h"
#include <dirent.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <math.h>
#include "asterisk/_private.h"
#include "asterisk/paths.h"
#include "asterisk/mod_format.h"
#include "asterisk/cli.h"
#include "asterisk/channel.h"
#include "asterisk/cel.h"
#include "asterisk/sched.h"
#include "asterisk/translate.h"
#include "asterisk/utils.h"
#include "asterisk/lock.h"
#include "asterisk/app.h"
#include "asterisk/pbx.h"
#include "asterisk/linkedlists.h"
#include "asterisk/module.h"
#include "asterisk/astobj2.h"
#include "asterisk/test.h"
#include "asterisk/stasis.h"
#include "asterisk/json.h"
#include "asterisk/stasis_system.h"
#include "asterisk/media_cache.h"
Include dependency graph for file.c:

Go to the source code of this file.

Data Structures

struct  formats
 

Macros

#define exts_compare(list, type)   (type_in_list((list), (type), strcmp))
 
#define FORMAT   "%-10s %-10s %-20s\n"
 
#define FORMAT2   "%-10s %-10s %-20s\n"
 

Enumerations

enum  file_action {
  ACTION_EXISTS = 1 , ACTION_DELETE , ACTION_RENAME , ACTION_OPEN ,
  ACTION_COPY
}
 
enum  fsread_res { FSREAD_FAILURE , FSREAD_SUCCESS_SCHED , FSREAD_SUCCESS_NOSCHED }
 
enum  wrap_fn { WRAP_OPEN , WRAP_REWRITE }
 

Functions

static int __ast_file_read_dirs (const char *path, ast_file_on_file on_file, void *obj, int max_depth)
 
int __ast_format_def_register (const struct ast_format_def *f, struct ast_module *mod)
 Register a new file format capability. Adds a format to Asterisk's format abilities.
 
int ast_applystream (struct ast_channel *chan, struct ast_filestream *s)
 Applies a open stream to a channel.
 
int ast_closestream (struct ast_filestream *f)
 Closes a stream.
 
int ast_file_fdtemp (const char *path, char **filename, const char *template_name)
 Create a temporary file located at path.
 
int ast_file_init (void)
 
FILE * ast_file_mkftemp (char *template_name, mode_t mode)
 same as mkstemp, but return a FILE
 
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.
 
int ast_filecopy (const char *filename, const char *filename2, const char *fmt)
 Copies a file.
 
int ast_filedelete (const char *filename, const char *fmt)
 Deletes a file.
 
int ast_fileexists (const char *filename, const char *fmt, const char *preflang)
 Checks for the existence of a given file.
 
int ast_filerename (const char *filename, const char *filename2, const char *fmt)
 Renames a file.
 
int ast_format_def_unregister (const char *name)
 Unregisters a file format.
 
char * ast_format_str_reduce (char *fmts)
 
static int ast_fsread_audio (const void *data)
 
static int ast_fsread_video (const void *data)
 
int ast_get_extension_for_mime_type (const char *mime_type, char *buffer, size_t capacity)
 Get a suitable filename extension for the given MIME type.
 
struct ast_format * ast_get_format_for_file_ext (const char *file_ext)
 Get the ast_format associated with the given file extension.
 
struct ast_filestream * ast_openstream (struct ast_channel *chan, const char *filename, const char *preflang)
 Opens stream for use in seeking, playing.
 
struct ast_filestream * ast_openstream_full (struct ast_channel *chan, const char *filename, const char *preflang, int asis)
 Opens stream for use in seeking, playing.
 
struct ast_filestream * ast_openvstream (struct ast_channel *chan, const char *filename, const char *preflang)
 Opens stream for use in seeking, playing.
 
int ast_playstream (struct ast_filestream *s)
 Play a open stream on a channel.
 
int ast_ratestream (struct ast_filestream *fs)
 Return the sample rate of the stream's format.
 
static enum fsread_res ast_readaudio_callback (struct ast_filestream *s)
 
struct ast_filestream * ast_readfile (const char *filename, const char *type, const char *comment, int flags, int check, mode_t mode)
 Starts reading from a file.
 
struct ast_frame * ast_readframe (struct ast_filestream *s)
 Read a frame from a filestream.
 
static enum fsread_res ast_readvideo_callback (struct ast_filestream *s)
 
int ast_seekstream (struct ast_filestream *fs, off_t sample_offset, int whence)
 Seeks into stream.
 
int ast_stopstream (struct ast_channel *tmp)
 Stops a stream.
 
int ast_stream_and_wait (struct ast_channel *chan, const char *file, const char *digits)
 stream file until digit If the file name is non-empty, try to play it.
 
int ast_stream_fastforward (struct ast_filestream *fs, off_t ms)
 Fast forward stream ms.
 
int ast_stream_rewind (struct ast_filestream *fs, off_t ms)
 Rewind stream ms.
 
int ast_streamfile (struct ast_channel *chan, const char *filename, const char *preflang)
 Streams a file.
 
off_t ast_tellstream (struct ast_filestream *fs)
 Tell where we are in a stream.
 
int ast_truncstream (struct ast_filestream *fs)
 Trunc stream at current location.
 
int ast_waitstream (struct ast_channel *c, const char *breakon)
 Waits for a stream to stop or digit to be pressed.
 
int ast_waitstream_exten (struct ast_channel *c, const char *context)
 Waits for a stream to stop or digit matching a valid one digit exten to be pressed.
 
int ast_waitstream_fr (struct ast_channel *c, const char *breakon, const char *forward, const char *reverse, int ms)
 Same as waitstream but allows stream to be forwarded or rewound.
 
int ast_waitstream_fr_w_cb (struct ast_channel *c, const char *breakon, const char *forward, const char *reverse, int ms, ast_waitstream_fr_cb cb)
 Same as waitstream_fr but allows a callback to be alerted when a user fastforwards or rewinds the file.
 
int ast_waitstream_full (struct ast_channel *c, const char *breakon, int audiofd, int cmdfd)
 
struct ast_filestream * ast_writefile (const char *filename, const char *type, const char *comment, int flags, int check, mode_t mode)
 Starts writing a file.
 
int ast_writestream (struct ast_filestream *fs, struct ast_frame *f)
 Writes a frame to a stream.
 
static char * build_filename (const char *filename, const char *ext)
 construct a filename. Absolute pathnames are preserved, relative names are prefixed by the sounds/ directory. Returns a malloc'ed string to be freed by the caller.
 
static char * build_filename_template (const char *filename, char **extension_start)
 
static int copy (const char *infile, const char *outfile)
 
static void file_shutdown (void)
 
static int fileexists_core (const char *filename, const char *fmt, const char *preflang, char *buf, int buflen, struct ast_format_cap *result_cap)
 helper routine to locate a file with a given format and language preference.
 
static int fileexists_test (const char *filename, const char *fmt, const char *lang, char *buf, int buflen, struct ast_format_cap *result_cap)
 test if a file exists for a given format.
 
static int filehelper (const char *filename, const void *arg2, const char *fmt, const enum file_action action)
 
static void filestream_close (struct ast_filestream *f)
 
static void filestream_destructor (void *arg)
 
static int fn_wrapper (struct ast_filestream *s, const char *comment, enum wrap_fn mode)
 
static struct ast_filestream * get_filestream (struct ast_format_def *fmt, FILE *bfile)
 
static char * handle_cli_core_show_file_formats (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static int is_absolute_path (const char *filename)
 
static int is_remote_path (const char *filename)
 
static struct ast_json * json_array_from_list (const char *list, const char *sep)
 
static int open_wrapper (struct ast_filestream *s)
 
static struct ast_filestream * openstream_internal (struct ast_channel *chan, const char *filename, const char *preflang, int asis, int quiet)
 
static int publish_format_update (const struct ast_format_def *f, struct stasis_message_type *type)
 
static struct ast_frame * read_frame (struct ast_filestream *s, int *whennext)
 
static int rewrite_wrapper (struct ast_filestream *s, const char *comment)
 
static int sanitize_waitstream_return (int return_value)
 
 STASIS_MESSAGE_TYPE_DEFN (ast_format_register_type)
 
 STASIS_MESSAGE_TYPE_DEFN (ast_format_unregister_type)
 
static const char * translate_extension (const char *extension)
 
static int type_in_list (const char *list, const char *type, int(*cmp)(const char *s1, const char *s2))
 
static void waitstream_control (struct ast_channel *c, enum ast_waitstream_fr_cb_values type, ast_waitstream_fr_cb cb, int skip_ms)
 
static int waitstream_core (struct ast_channel *c, const char *breakon, const char *forward, const char *reverse, int skip_ms, int audiofd, int cmdfd, const char *context, ast_waitstream_fr_cb cb)
 the core of all waitstream() functions
 

Variables

static struct ast_cli_entry cli_file []
 
static struct formats formats = AST_RWLIST_HEAD_INIT_VALUE
 
static unsigned maximum_extension_length
 Space required to store the longest extension from all registered file formats.
 
static ast_mutex_t read_dirs_lock = AST_MUTEX_INIT_VALUE
 Lock to hold when iterating over directories.
 

Detailed Description

Generic File Format Support.

Author
Mark Spencer marks.nosp@m.ter@.nosp@m.digiu.nosp@m.m.co.nosp@m.m

Definition in file file.c.

Macro Definition Documentation

◆ exts_compare

#define exts_compare (   list,
  type 
)    (type_in_list((list), (type), strcmp))

Definition at line 454 of file file.c.

◆ FORMAT

#define FORMAT   "%-10s %-10s %-20s\n"

◆ FORMAT2

#define FORMAT2   "%-10s %-10s %-20s\n"

Enumeration Type Documentation

◆ file_action

Enumerator
ACTION_EXISTS 
ACTION_DELETE 
ACTION_RENAME 
ACTION_OPEN 
ACTION_COPY 

Definition at line 599 of file file.c.

599 {
600 ACTION_EXISTS = 1, /* return matching format if file exists, 0 otherwise */
601 ACTION_DELETE, /* delete file, return 0 on success, -1 on error */
602 ACTION_RENAME, /* rename file. return 0 on success, -1 on error */
604 ACTION_COPY /* copy file. return 0 on success, -1 on error */
605};
@ ACTION_OPEN
Definition file.c:603
@ ACTION_EXISTS
Definition file.c:600
@ ACTION_COPY
Definition file.c:604
@ ACTION_DELETE
Definition file.c:601
@ ACTION_RENAME
Definition file.c:602

◆ fsread_res

enum fsread_res
Enumerator
FSREAD_FAILURE 
FSREAD_SUCCESS_SCHED 
FSREAD_SUCCESS_NOSCHED 

Definition at line 1032 of file file.c.

1032 {
1036};
@ FSREAD_FAILURE
Definition file.c:1033
@ FSREAD_SUCCESS_SCHED
Definition file.c:1034
@ FSREAD_SUCCESS_NOSCHED
Definition file.c:1035

◆ wrap_fn

enum wrap_fn
Enumerator
WRAP_OPEN 
WRAP_REWRITE 

Definition at line 570 of file file.c.

@ WRAP_OPEN
Definition file.c:570
@ WRAP_REWRITE
Definition file.c:570

Function Documentation

◆ __ast_file_read_dirs()

static int __ast_file_read_dirs ( const char *  path,
ast_file_on_file  on_file,
void *  obj,
int  max_depth 
)
static

Definition at line 1245 of file file.c.

1247{
1248 DIR *dir;
1249 struct dirent *entry;
1250 int res;
1251
1252 if (!(dir = opendir(path))) {
1253 ast_log(LOG_ERROR, "Error opening directory - %s: %s\n",
1254 path, strerror(errno));
1255 return -1;
1256 }
1257
1258 --max_depth;
1259
1260 res = 0;
1261
1262 while ((entry = readdir(dir)) != NULL && !errno) {
1263 int is_file = 0;
1264 int is_dir = 0;
1265 RAII_VAR(char *, full_path, NULL, ast_free);
1266
1267 if (!strcmp(entry->d_name, ".") || !strcmp(entry->d_name, "..")) {
1268 continue;
1269 }
1270
1271/*
1272 * If the dirent structure has a d_type use it to determine if we are dealing with
1273 * a file or directory. Unfortunately if it doesn't have it, or if the type is
1274 * unknown, or a link then we'll need to use the stat function instead.
1275 */
1276#ifdef _DIRENT_HAVE_D_TYPE
1277 if (entry->d_type != DT_UNKNOWN && entry->d_type != DT_LNK) {
1278 is_file = entry->d_type == DT_REG;
1279 is_dir = entry->d_type == DT_DIR;
1280 } else
1281#endif
1282 {
1283 struct stat statbuf;
1284
1285 /*
1286 * Don't use alloca or we risk blowing out the stack if recursing
1287 * into subdirectories.
1288 */
1289 full_path = ast_malloc(strlen(path) + strlen(entry->d_name) + 2);
1290 if (!full_path) {
1291 return -1;
1292 }
1293 sprintf(full_path, "%s/%s", path, entry->d_name);
1294
1295 if (stat(full_path, &statbuf)) {
1296 ast_log(LOG_ERROR, "Error reading path stats - %s: %s\n",
1297 full_path, strerror(errno));
1298 /*
1299 * Output an error, but keep going. It could just be
1300 * a broken link and other files could be fine.
1301 */
1302 continue;
1303 }
1304
1305 is_file = S_ISREG(statbuf.st_mode);
1306 is_dir = S_ISDIR(statbuf.st_mode);
1307 }
1308
1309 if (is_file) {
1310 /* If the handler returns non-zero then stop */
1311 if ((res = on_file(path, entry->d_name, obj))) {
1312 break;
1313 }
1314 /* Otherwise move on to next item in directory */
1315 continue;
1316 }
1317
1318 if (!is_dir) {
1319 ast_debug(5, "Skipping %s: not a regular file or directory\n", full_path);
1320 continue;
1321 }
1322
1323 /* Only re-curse into sub-directories if not at the max depth */
1324 if (max_depth != 0) {
1325 if (!full_path) {
1326 /* Don't use alloca. See note above. */
1327 full_path = ast_malloc(strlen(path) + strlen(entry->d_name) + 2);
1328 if (!full_path) {
1329 return -1;
1330 }
1331 sprintf(full_path, "%s/%s", path, entry->d_name);
1332 }
1333
1334 if ((res = __ast_file_read_dirs(full_path, on_file, obj, max_depth))) {
1335 break;
1336 }
1337 }
1338 }
1339
1340 closedir(dir);
1341
1342 if (!res && errno) {
1343 ast_log(LOG_ERROR, "Error while reading directories - %s: %s\n",
1344 path, strerror(errno));
1345 res = -1;
1346 }
1347
1348 return res;
1349}
#define ast_free(a)
Definition astmm.h:180
#define ast_malloc(len)
A wrapper for malloc()
Definition astmm.h:191
#define ast_log
Definition astobj2.c:42
static int __ast_file_read_dirs(const char *path, ast_file_on_file on_file, void *obj, int max_depth)
Definition file.c:1245
#define ast_debug(level,...)
Log a DEBUG message.
#define LOG_ERROR
int errno
#define NULL
Definition resample.c:96
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition utils.h:981

References __ast_file_read_dirs(), ast_debug, ast_free, ast_log, ast_malloc, errno, LOG_ERROR, NULL, and RAII_VAR.

Referenced by __ast_file_read_dirs(), and ast_file_read_dirs().

◆ __ast_format_def_register()

int __ast_format_def_register ( const struct ast_format_def *  f,
struct ast_module *  mod 
)

Register a new file format capability. Adds a format to Asterisk's format abilities.

Return values
0on success
-1on failure

Definition at line 124 of file file.c.

125{
126 struct ast_format_def *tmp;
127
130 if (!strcasecmp(f->name, tmp->name)) {
132 ast_log(LOG_WARNING, "Tried to register '%s' format, already registered\n", f->name);
133 return -1;
134 }
135 }
136 if (!(tmp = ast_calloc(1, sizeof(*tmp)))) {
138 return -1;
139 }
140 *tmp = *f;
141 tmp->module = mod;
142 if (tmp->buf_size) {
143 /*
144 * Align buf_size properly, rounding up to the machine-specific
145 * alignment for pointers.
146 */
147 struct _test_align { void *a, *b; } p;
148 int align = (char *)&p.b - (char *)&p.a;
149 tmp->buf_size = ((f->buf_size + align - 1) / align) * align;
150 }
151
152 memset(&tmp->list, 0, sizeof(tmp->list));
153
154 /* Calculate the maximum extension length */
155 {
156 char *storage = ast_strdupa(tmp->exts);
157 char *stringp = storage;
158 const char *ext;
159
160 while ((ext = strsep(&stringp, "|"))) {
162 }
163 }
164
165 AST_RWLIST_INSERT_HEAD(&formats, tmp, list);
167 ast_verb(5, "Registered file format %s, extension(s) %s\n", f->name, f->exts);
169
170 return 0;
171}
char * strsep(char **str, const char *delims)
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition astmm.h:298
#define ast_calloc(num, len)
A wrapper for calloc()
Definition astmm.h:202
static unsigned maximum_extension_length
Space required to store the longest extension from all registered file formats.
Definition file.c:122
static int publish_format_update(const struct ast_format_def *f, struct stasis_message_type *type)
Definition file.c:82
struct stasis_message_type * ast_format_register_type(void)
Get the message type used for signaling a format registration.
const char * ext
Definition http.c:151
#define ast_verb(level,...)
#define LOG_WARNING
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition linkedlists.h:52
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
#define AST_RWLIST_TRAVERSE
#define AST_RWLIST_INSERT_HEAD
Each supported file format is described by the following structure.
Definition mod_format.h:43
char name[80]
Definition mod_format.h:44
struct ast_format_def::@252 list
char exts[80]
Definition mod_format.h:45
Definition file.c:58
static struct test_val b
static struct test_val a
#define MAX(a, b)
Definition utils.h:254

References a, ast_calloc, ast_format_register_type(), ast_log, AST_RWLIST_INSERT_HEAD, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_strdupa, ast_verb, b, ast_format_def::buf_size, ext, ast_format_def::exts, ast_format_def::list, LOG_WARNING, MAX, maximum_extension_length, ast_format_def::name, publish_format_update(), and strsep().

◆ ast_applystream()

int ast_applystream ( struct ast_channel *  chan,
struct ast_filestream *  s 
)

Applies a open stream to a channel.

Parameters
chanchannel to work
sast_filestream to apply
Return values
0on success.
-1on failure.

Definition at line 1146 of file file.c.

1147{
1148 s->owner = chan;
1149 return 0;
1150}
struct ast_channel * owner
Definition mod_format.h:116

References ast_filestream::owner.

Referenced by ast_streamfile(), handle_getoption(), handle_recordfile(), handle_streamfile(), speech_streamfile(), and speech_streamfile().

◆ ast_closestream()

int ast_closestream ( struct ast_filestream *  f)

Closes a stream.

Parameters
ffilestream to close Close a playback or recording stream
Return values
0on success.
-1on failure.

Definition at line 1200 of file file.c.

1201{
1202 /* This used to destroy the filestream, but it now just decrements a refcount.
1203 * We close the stream in order to quit queuing frames now, because we might
1204 * change the writeformat, which could result in a subsequent write error, if
1205 * the format is different. */
1206 if (f == NULL) {
1207 return 0;
1208 }
1210 ao2_ref(f, -1);
1211 return 0;
1212}
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition astobj2.h:459
static void filestream_close(struct ast_filestream *f)
Definition file.c:460

References ao2_ref, ast_filestream::f, filestream_close(), and NULL.

Referenced by __ast_play_and_record(), ast_hangup(), ast_readfile(), ast_stopstream(), ast_writefile(), dictate_exec(), filehelper(), filestream_destructor(), gen_closestream(), handle_cli_file_convert(), handle_recordfile(), local_ast_moh_stop(), mixmonitor_ds_close_fs(), moh_files_next(), moh_files_release(), msg_create_from_file(), record_exec(), and recordthread().

◆ ast_file_fdtemp()

int ast_file_fdtemp ( const char *  path,
char **  filename,
const char *  template_name 
)

Create a temporary file located at path.

Note
The directory containing path will be created if it does not exist
This function assumes path does not end with a '/'
Parameters
pathThe directory path to create the file in
filenameFunction allocates memory and stores full filename (including path) here
template_namemkstemp template to use. Must end with XXXXXX.
Note
filename will need to be freed with ast_free if this function succeeds
Return values
-1on failure
Returns
file descriptor on success

Definition at line 213 of file file.c.

214{
215 int fd;
216
217 if (ast_asprintf(filename, "%s/%s", path, template_name) < 0) {
218 ast_log(LOG_ERROR, "Failed to set up temporary file path\n");
219 return -1;
220 }
221
222 ast_mkdir(path, 0644);
223
224 if ((fd = mkstemp(*filename)) < 0) {
225 ast_log(LOG_NOTICE, "Failed to create temporary file\n");
226 ast_free(*filename);
227 return -1;
228 }
229
230 return fd;
231}
#define ast_asprintf(ret, fmt,...)
A wrapper for asprintf()
Definition astmm.h:267
#define LOG_NOTICE
int ast_mkdir(const char *path, int mode)
Recursively create directory path.
Definition utils.c:2513

References ast_asprintf, ast_free, ast_log, ast_mkdir(), LOG_ERROR, and LOG_NOTICE.

◆ ast_file_init()

int ast_file_init ( void  )

Provided by file.c

Definition at line 2155 of file file.c.

2156{
2161 return 0;
2162}
int ast_register_cleanup(void(*func)(void))
Register a function to be executed before Asterisk gracefully exits.
Definition clicompat.c:19
#define ast_cli_register_multiple(e, len)
Register multiple commands.
Definition cli.h:265
static void file_shutdown(void)
Definition file.c:2148
static struct ast_cli_entry cli_file[]
Definition file.c:2144
struct stasis_message_type * ast_format_unregister_type(void)
Get the message type used for signaling a format unregistration.
#define STASIS_MESSAGE_TYPE_INIT(name)
Boiler-plate messaging macro for initializing message types.
Definition stasis.h:1524
#define ARRAY_LEN(a)
Definition utils.h:706

References ARRAY_LEN, ast_cli_register_multiple, ast_format_register_type(), ast_format_unregister_type(), ast_register_cleanup(), cli_file, file_shutdown(), and STASIS_MESSAGE_TYPE_INIT.

Referenced by asterisk_daemon().

◆ ast_file_mkftemp()

FILE * ast_file_mkftemp ( char *  template_name,
mode_t  mode 
)

same as mkstemp, but return a FILE

Parameters
template_nameThe template for the unique file name to generate. Modified in place to return the file name.
modeThe mode for file permissions
Returns
FILE handle to the temporary file on success or NULL if creation failed

Definition at line 198 of file file.c.

199{
200 FILE *p = NULL;
201 int pfd = mkstemp(template_name);
202 chmod(template_name, mode);
203 if (pfd > -1) {
204 p = fdopen(pfd, "w+");
205 if (!p) {
206 close(pfd);
207 pfd = -1;
208 }
209 }
210 return p;
211}

References ast_format_def::close, and NULL.

Referenced by AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), sendmail(), and sendpage().

◆ ast_file_read_dirs()

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.

Parameters
dir_namethe name of the directory to search
on_filecallback called on each file
objuser data object
max_depthre-curse into sub-directories up to a given maximum (-1 = infinite)
Return values
-1on failure
errnoon failure
0otherwise

Definition at line 1363 of file file.c.

1364{
1365 int res;
1366
1367 errno = 0;
1368
1369#if !defined(__GLIBC__)
1371#endif
1372
1373 res = __ast_file_read_dirs(dir_name, on_file, obj, max_depth);
1374
1375#if !defined(__GLIBC__)
1377#endif
1378
1379 return res;
1380}
static ast_mutex_t read_dirs_lock
Lock to hold when iterating over directories.
Definition file.c:1360
#define ast_mutex_unlock(a)
Definition lock.h:197
#define ast_mutex_lock(a)
Definition lock.h:196

References __ast_file_read_dirs(), ast_mutex_lock, ast_mutex_unlock, errno, and read_dirs_lock.

Referenced by _crypto_load_cert_store(), _crypto_load_crl_store(), ast_media_index_update_for_file(), AST_TEST_DEFINE(), crypto_load(), module_load_helper(), and stasis_app_stored_recording_find_all().

◆ ast_filecopy()

int ast_filecopy ( const char *  oldname,
const char *  newname,
const char *  fmt 
)

Copies a file.

Parameters
oldnamename of the file you wish to copy (minus extension)
newnamename you wish the file to be copied to (minus extension)
fmtthe format of the file Copy a given file in a given format, or if fmt is NULL, then do so for all

Definition at line 1240 of file file.c.

1241{
1242 return filehelper(filename, filename2, fmt, ACTION_COPY);
1243}
static int filehelper(const char *filename, const void *arg2, const char *fmt, const enum file_action action)
Definition file.c:618

References ACTION_COPY, filehelper(), ast_filestream::filename, and ast_filestream::fmt.

Referenced by copy_plain_file(), msg_create_from_file(), stasis_app_stored_recording_copy(), and vm_forwardoptions().

◆ ast_filedelete()

int ast_filedelete ( const char *  filename,
const char *  fmt 
)

Deletes a file.

Parameters
filenamename of the file you wish to delete (minus the extension)
fmtof the file Delete a given file in a given format, or if fmt is NULL, then do so for all

Definition at line 1230 of file file.c.

1231{
1232 return filehelper(filename, NULL, fmt, ACTION_DELETE);
1233}

References ACTION_DELETE, filehelper(), ast_filestream::filename, ast_filestream::fmt, and NULL.

Referenced by __ast_play_and_record(), announce_thread(), async_delete_name_rec(), async_delete_name_rec_task(), conf_free(), conf_rec_name(), conf_run(), confbridge_exec(), dial_exec_full(), handle_cli_file_convert(), leave_voicemail(), leave_voicemail(), mixmonitor_thread(), msg_create_from_file(), play_record_review(), record_exec(), recording_cancel(), setup_privacy_args(), vm_delete(), and vm_delete().

◆ ast_fileexists()

int ast_fileexists ( const char *  filename,
const char *  fmt,
const char *  preflang 
)

Checks for the existence of a given file.

Parameters
filenamename of the file you wish to check, minus the extension
fmtthe format you wish to check (the extension)
preflang(the preferred language you wisht to find the file in) See if a given file exists in a given format. If fmt is NULL, any format is accepted.
Return values
0The file does not exist
1The file does exist.

Definition at line 1218 of file file.c.

1219{
1220 char *buf;
1221 int buflen;
1222
1223 if (preflang == NULL)
1224 preflang = "";
1225 buflen = strlen(preflang) + strlen(filename) + 4; /* room for everything */
1226 buf = ast_alloca(buflen);
1227 return fileexists_core(filename, fmt, preflang, buf, buflen, NULL) ? 1 : 0;
1228}
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
Definition astmm.h:288
char buf[BUFSIZE]
Definition eagi_proxy.c:66
static int fileexists_core(const char *filename, const char *fmt, const char *preflang, char *buf, int buflen, struct ast_format_cap *result_cap)
helper routine to locate a file with a given format and language preference.
Definition file.c:822

References ast_alloca, buf, fileexists_core(), ast_filestream::filename, ast_filestream::fmt, and NULL.

Referenced by announce_thread(), app_exec(), ast_get_character_str(), ast_get_digit_str(), ast_get_phonetic_str(), common_exec(), conf_run(), dial_exec_full(), eivr_comm(), find_first_and(), forward_message(), get_folder(), invent_message(), invent_message(), leave_voicemail(), leave_voicemail(), meetme_menu_admin_extended(), minivm_delete_exec(), moh_files_next(), msg_create_from_file(), page_exec(), play_file(), play_message(), play_message_by_id_helper(), play_message_callerid(), readexten_exec(), record_exec(), retrydial_exec(), sayname(), setup_privacy_args(), sound_file_exists(), stasis_app_control_record(), vm_intro(), vm_msg_play(), vm_newuser_setup(), vm_options(), and vm_tempgreeting().

◆ ast_filerename()

int ast_filerename ( const char *  oldname,
const char *  newname,
const char *  fmt 
)

Renames a file.

Parameters
oldnamethe name of the file you wish to act upon (minus the extension)
newnamethe name you wish to rename the file to (minus the extension)
fmtthe format of the file Rename a given file in a given format, or if fmt is NULL, then do so for all
Return values
-1on failure

Definition at line 1235 of file file.c.

1236{
1237 return filehelper(filename, filename2, fmt, ACTION_RENAME);
1238}

References ACTION_RENAME, filehelper(), ast_filestream::filename, and ast_filestream::fmt.

Referenced by __ast_play_and_record(), forward_message(), leave_voicemail(), msg_create_from_file(), play_record_review(), rename_file(), and vm_forwardoptions().

◆ ast_format_def_unregister()

int ast_format_def_unregister ( const char *  name)

Unregisters a file format.

Parameters
namethe name of the format you wish to unregister Unregisters a format based on the name of the format.
Return values
0on success
-1on failure to unregister

Definition at line 173 of file file.c.

174{
175 struct ast_format_def *tmp;
176 int res = -1;
177
180 if (!strcasecmp(name, tmp->name)) {
183 ast_free(tmp);
184 res = 0;
185 }
186 }
189
190 if (!res)
191 ast_verb(5, "Unregistered format %s\n", name);
192 else
193 ast_log(LOG_WARNING, "Tried to unregister format %s, already unregistered\n", name);
194
195 return res;
196}
static const char name[]
Definition format_mp3.c:68
#define AST_RWLIST_REMOVE_CURRENT
#define AST_RWLIST_TRAVERSE_SAFE_BEGIN
#define AST_RWLIST_TRAVERSE_SAFE_END

References ast_format_unregister_type(), ast_free, ast_log, AST_RWLIST_REMOVE_CURRENT, AST_RWLIST_TRAVERSE_SAFE_BEGIN, AST_RWLIST_TRAVERSE_SAFE_END, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_verb, ast_format_def::list, LOG_WARNING, ast_format_def::name, name, and publish_format_update().

Referenced by unload_module(), unload_module(), unload_module(), unload_module(), unload_module(), unload_module(), unload_module(), unload_module(), unload_module(), unload_module(), unload_module(), unload_module(), unload_module(), unload_module(), unload_module(), unload_module(), unload_module(), and unload_module().

◆ ast_format_str_reduce()

char * ast_format_str_reduce ( char *  fmts)

Remove duplicate formats from a format string.

Parameters
fmtsa format string, this string will be modified
Return values
NULLerror
Returns
a pointer to the reduced format string, this is a pointer to fmts

Definition at line 1998 of file file.c.

1999{
2000 struct ast_format_def *f;
2001 struct ast_format_def *fmts_ptr[AST_MAX_FORMATS];
2002 char *fmts_str[AST_MAX_FORMATS];
2003 char *stringp, *type;
2004 char *orig = fmts;
2005 int i, j, x, first, found = 0;
2006 int len = strlen(fmts) + 1;
2007 int res;
2008
2009 if (AST_RWLIST_RDLOCK(&formats)) {
2010 ast_log(LOG_WARNING, "Unable to lock format list\n");
2011 return NULL;
2012 }
2013
2014 stringp = ast_strdupa(fmts);
2015
2016 for (x = 0; (type = strsep(&stringp, "|")) && x < AST_MAX_FORMATS; x++) {
2018 if (exts_compare(f->exts, type)) {
2019 found = 1;
2020 break;
2021 }
2022 }
2023
2024 fmts_str[x] = type;
2025 if (found) {
2026 fmts_ptr[x] = f;
2027 } else {
2028 fmts_ptr[x] = NULL;
2029 }
2030 }
2032
2033 first = 1;
2034 for (i = 0; i < x; i++) {
2035 /* ignore invalid entries */
2036 if (!fmts_ptr[i]) {
2037 ast_log(LOG_WARNING, "ignoring unknown format '%s'\n", fmts_str[i]);
2038 continue;
2039 }
2040
2041 /* special handling for the first entry */
2042 if (first) {
2043 res = snprintf(fmts, len, "%s", fmts_str[i]);
2044 fmts += res;
2045 len -= res;
2046 first = 0;
2047 continue;
2048 }
2049
2050 found = 0;
2051 for (j = 0; j < i; j++) {
2052 /* this is a duplicate */
2053 if (fmts_ptr[j] == fmts_ptr[i]) {
2054 found = 1;
2055 break;
2056 }
2057 }
2058
2059 if (!found) {
2060 res = snprintf(fmts, len, "|%s", fmts_str[i]);
2061 fmts += res;
2062 len -= res;
2063 }
2064 }
2065
2066 if (first) {
2067 ast_log(LOG_WARNING, "no known formats found in format list (%s)\n", orig);
2068 return NULL;
2069 }
2070
2071 return orig;
2072}
struct sla_ringing_trunk * first
Definition app_sla.c:338
static const char type[]
#define exts_compare(list, type)
Definition file.c:454
#define AST_MAX_FORMATS
Definition file.h:44
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
#define AST_RWLIST_RDLOCK(head)
Read locks a list.
Definition linkedlists.h:78

References ast_log, AST_MAX_FORMATS, AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_strdupa, ast_format_def::exts, exts_compare, first, len(), ast_format_def::list, LOG_WARNING, NULL, strsep(), and type.

Referenced by actual_load_config(), and AST_TEST_DEFINE().

◆ ast_fsread_audio()

static int ast_fsread_audio ( const void *  data)
static

Definition at line 1088 of file file.c.

1089{
1090 struct ast_filestream *fs = (struct ast_filestream *)data;
1091 enum fsread_res res;
1092
1093 res = ast_readaudio_callback(fs);
1094
1095 if (res == FSREAD_SUCCESS_SCHED)
1096 return 1;
1097
1098 return 0;
1099}
fsread_res
Definition file.c:1032
static enum fsread_res ast_readaudio_callback(struct ast_filestream *s)
Definition file.c:1040
This structure is allocated by file.c in one chunk, together with buf_size and desc_size bytes of mem...
Definition mod_format.h:101

References ast_readaudio_callback(), and FSREAD_SUCCESS_SCHED.

Referenced by ast_readaudio_callback().

◆ ast_fsread_video()

static int ast_fsread_video ( const void *  data)
static

Definition at line 1133 of file file.c.

1134{
1135 struct ast_filestream *fs = (struct ast_filestream *)data;
1136 enum fsread_res res;
1137
1138 res = ast_readvideo_callback(fs);
1139
1140 if (res == FSREAD_SUCCESS_SCHED)
1141 return 1;
1142
1143 return 0;
1144}
static enum fsread_res ast_readvideo_callback(struct ast_filestream *s)
Definition file.c:1103

References ast_readvideo_callback(), and FSREAD_SUCCESS_SCHED.

Referenced by ast_readvideo_callback().

◆ ast_get_extension_for_mime_type()

int ast_get_extension_for_mime_type ( const char *  mime_type,
char *  buffer,
size_t  capacity 
)

Get a suitable filename extension for the given MIME type.

Parameters
mime_typeThe MIME type for which to find extensions
bufferA pointer to a buffer to receive the extension
capacityThe size of 'buffer' in bytes
Return values
1if an extension was found for the provided MIME type
0if the MIME type was not found

Definition at line 2123 of file file.c.

2124{
2125 struct ast_format_def *f;
2127
2128 ast_assert(buffer && capacity);
2129
2131 if (type_in_list(f->mime_types, mime_type, strcasecmp)) {
2132 size_t item_len = strcspn(f->exts, "|");
2133 size_t bytes_written = snprintf(buffer, capacity, ".%.*s", (int) item_len, f->exts);
2134 if (bytes_written < capacity) {
2135 /* Only return success if we didn't truncate */
2136 return 1;
2137 }
2138 }
2139 }
2140
2141 return 0;
2142}
ast_mutex_t lock
Definition app_sla.c:337
static int type_in_list(const char *list, const char *type, int(*cmp)(const char *s1, const char *s2))
Definition file.c:441
#define SCOPED_RDLOCK(varname, lock)
scoped lock specialization for read locks
Definition lock.h:601
char mime_types[80]
Definition mod_format.h:47
ast_rwlock_t lock
Definition file.c:58
#define ast_assert(a)
Definition utils.h:779

References ast_assert, AST_RWLIST_TRAVERSE, ast_format_def::exts, ast_format_def::list, lock, formats::lock, ast_format_def::mime_types, SCOPED_RDLOCK, and type_in_list().

Referenced by derive_extension_from_mime_type().

◆ ast_get_format_for_file_ext()

struct ast_format * ast_get_format_for_file_ext ( const char *  file_ext)

Get the ast_format associated with the given file extension.

Since
12
Parameters
file_extThe file extension for which to find the format
Return values
NULLif not found
Returns
A pointer to the ast_format associated with this file extension

Definition at line 2110 of file file.c.

2111{
2112 struct ast_format_def *f;
2115 if (exts_compare(f->exts, file_ext)) {
2116 return f->format;
2117 }
2118 }
2119
2120 return NULL;
2121}
struct ast_format * format
Definition mod_format.h:48

References AST_RWLIST_TRAVERSE, ast_format_def::exts, exts_compare, ast_format_def::format, ast_format_def::list, lock, formats::lock, NULL, and SCOPED_RDLOCK.

Referenced by ast_ari_bridges_record(), ast_ari_channels_record(), ast_ari_recordings_get_stored_file(), file_extension_from_string(), is_recording(), and process_media_file().

◆ ast_openstream()

struct ast_filestream * ast_openstream ( struct ast_channel *  chan,
const char *  filename,
const char *  preflang 
)

Opens stream for use in seeking, playing.

Parameters
chanchannel to work with
filenameto use
preflangprefered language to use
Returns
a ast_filestream pointer if it opens the file.
Return values
NULLon error.

Definition at line 926 of file file.c.

927{
928 return openstream_internal(chan, filename, preflang, 0, 0);
929}
static struct ast_filestream * openstream_internal(struct ast_channel *chan, const char *filename, const char *preflang, int asis, int quiet)
Definition file.c:871

References ast_filestream::filename, and openstream_internal().

Referenced by ast_streamfile(), dictate_exec(), handle_getoption(), handle_streamfile(), speech_streamfile(), and speech_streamfile().

◆ ast_openstream_full()

struct ast_filestream * ast_openstream_full ( struct ast_channel *  chan,
const char *  filename,
const char *  preflang,
int  asis 
)

Opens stream for use in seeking, playing.

Parameters
chanchannel to work with
filenameto use
preflangprefered language to use
asisif set, don't clear generators
Return values
aast_filestream pointer if it opens the file.
NULLon error.

Definition at line 931 of file file.c.

933{
934 return openstream_internal(chan, filename, preflang, asis, 0);
935}

References ast_filestream::filename, and openstream_internal().

Referenced by gen_nextfile(), and moh_files_next().

◆ ast_openvstream()

struct ast_filestream * ast_openvstream ( struct ast_channel *  chan,
const char *  filename,
const char *  preflang 
)

Opens stream for use in seeking, playing.

Parameters
chanchannel to work with
filenameto use
preflangprefered language to use
Returns
a ast_filestream pointer if it opens the file.
Return values
NULLon error.

Definition at line 937 of file file.c.

939{
940 /* As above, but for video. But here we don't have translators
941 * so we must enforce a format.
942 */
943 struct ast_format_cap *nativeformats, *tmp_cap;
944 char *buf;
945 int buflen;
946 int i, fd;
947
948 if (preflang == NULL) {
949 preflang = "";
950 }
951 buflen = strlen(preflang) + strlen(filename) + 4;
952 buf = ast_alloca(buflen);
953
954 ast_channel_lock(chan);
955 nativeformats = ao2_bump(ast_channel_nativeformats(chan));
956 ast_channel_unlock(chan);
957
958 /* is the channel capable of video without translation ?*/
959 if (!ast_format_cap_has_type(nativeformats, AST_MEDIA_TYPE_VIDEO)) {
960 ao2_cleanup(nativeformats);
961 return NULL;
962 }
964 ao2_cleanup(nativeformats);
965 return NULL;
966 }
967 /* Video is supported, so see what video formats exist for this file */
968 if (!fileexists_core(filename, NULL, preflang, buf, buflen, tmp_cap)) {
969 ao2_ref(tmp_cap, -1);
970 ao2_cleanup(nativeformats);
971 return NULL;
972 }
973
974 /* iterate over file formats and pick the first one compatible with the channel's native formats */
975 for (i = 0; i < ast_format_cap_count(tmp_cap); ++i) {
976 struct ast_format *format = ast_format_cap_get_format(tmp_cap, i);
977
978 if ((ast_format_get_type(format) != AST_MEDIA_TYPE_VIDEO) ||
979 !ast_format_cap_iscompatible(nativeformats, tmp_cap)) {
980 ao2_ref(format, -1);
981 continue;
982 }
983
984 fd = filehelper(buf, chan, ast_format_get_name(format), ACTION_OPEN);
985 if (fd >= 0) {
986 ao2_ref(format, -1);
987 ao2_ref(tmp_cap, -1);
988 ao2_cleanup(nativeformats);
989 return ast_channel_vstream(chan);
990 }
991 ast_log(LOG_WARNING, "File %s has video but couldn't be opened\n", filename);
992 ao2_ref(format, -1);
993 }
994 ao2_ref(tmp_cap, -1);
995 ao2_cleanup(nativeformats);
996
997 return NULL;
998}
#define ao2_cleanup(obj)
Definition astobj2.h:1934
#define ao2_bump(obj)
Bump refcount on an AO2 object by one, returning the object.
Definition astobj2.h:480
#define ast_channel_lock(chan)
Definition channel.h:2983
struct ast_format_cap * ast_channel_nativeformats(const struct ast_channel *chan)
struct ast_filestream * ast_channel_vstream(const struct ast_channel *chan)
#define ast_channel_unlock(chan)
Definition channel.h:2984
@ AST_MEDIA_TYPE_VIDEO
Definition codec.h:33
enum ast_media_type ast_format_get_type(const struct ast_format *format)
Get the media type of a format.
Definition format.c:354
const char * ast_format_get_name(const struct ast_format *format)
Get the name associated with a format.
Definition format.c:334
struct ast_format * ast_format_cap_get_format(const struct ast_format_cap *cap, int position)
Get the format at a specific index.
Definition format_cap.c:408
@ AST_FORMAT_CAP_FLAG_DEFAULT
Definition format_cap.h:38
int ast_format_cap_has_type(const struct ast_format_cap *cap, enum ast_media_type type)
Find out if the capabilities structure has any formats of a specific type.
Definition format_cap.c:621
int ast_format_cap_iscompatible(const struct ast_format_cap *cap1, const struct ast_format_cap *cap2)
Determine if any joint capabilities exist between two capabilities structures.
Definition format_cap.c:661
#define ast_format_cap_alloc(flags)
Allocate a new ast_format_cap structure.
Definition format_cap.h:49
size_t ast_format_cap_count(const struct ast_format_cap *cap)
Get the number of formats present within the capabilities structure.
Definition format_cap.c:403
Format capabilities structure, holds formats + preference order + etc.
Definition format_cap.c:54
Definition of a media format.
Definition format.c:43

References ACTION_OPEN, ao2_bump, ao2_cleanup, ao2_ref, ast_alloca, ast_channel_lock, ast_channel_nativeformats(), ast_channel_unlock, ast_channel_vstream(), ast_format_cap_alloc, ast_format_cap_count(), AST_FORMAT_CAP_FLAG_DEFAULT, ast_format_cap_get_format(), ast_format_cap_has_type(), ast_format_cap_iscompatible(), ast_format_get_name(), ast_format_get_type(), ast_log, AST_MEDIA_TYPE_VIDEO, buf, fileexists_core(), filehelper(), LOG_WARNING, and NULL.

Referenced by ast_streamfile(), handle_getoption(), and handle_streamfile().

◆ ast_playstream()

int ast_playstream ( struct ast_filestream *  s)

Play a open stream on a channel.

Parameters
sfilestream to play
Return values
0on success.
-1on failure.

Definition at line 1152 of file file.c.

1153{
1154 enum fsread_res res;
1155
1157 res = ast_readaudio_callback(s);
1158 else
1159 res = ast_readvideo_callback(s);
1160
1161 return (res == FSREAD_FAILURE) ? -1 : 0;
1162}
@ AST_MEDIA_TYPE_AUDIO
Definition codec.h:32
struct ast_format_def * fmt
Definition mod_format.h:103

References ast_format_get_type(), AST_MEDIA_TYPE_AUDIO, ast_readaudio_callback(), ast_readvideo_callback(), ast_filestream::fmt, ast_format_def::format, and FSREAD_FAILURE.

Referenced by ast_streamfile(), handle_getoption(), handle_streamfile(), speech_streamfile(), and speech_streamfile().

◆ ast_ratestream()

int ast_ratestream ( struct ast_filestream *  fs)

Return the sample rate of the stream's format.

Parameters
fsfs to act on
Returns
sample rate in Hz

Definition at line 1179 of file file.c.

1180{
1182}
unsigned int ast_format_get_sample_rate(const struct ast_format *format)
Get the sample rate of a media format.
Definition format.c:379

References ast_format_get_sample_rate(), ast_filestream::fmt, and ast_format_def::format.

Referenced by msg_create_from_file().

◆ ast_readaudio_callback()

static enum fsread_res ast_readaudio_callback ( struct ast_filestream *  s)
static

Definition at line 1040 of file file.c.

1041{
1042 int whennext = 0;
1043
1044 while (!whennext) {
1045 struct ast_frame *fr;
1046
1047 if (s->orig_chan_name && strcasecmp(ast_channel_name(s->owner), s->orig_chan_name)) {
1048 goto return_failure;
1049 }
1050
1051 fr = read_frame(s, &whennext);
1052
1053 if (!fr /* stream complete */ || ast_write(s->owner, fr) /* error writing */) {
1054 if (fr) {
1055 ast_debug(2, "Failed to write frame\n");
1056 ast_frfree(fr);
1057 }
1058 goto return_failure;
1059 }
1060
1061 if (fr) {
1062 ast_frfree(fr);
1063 }
1064 }
1065
1066 if (whennext != s->lasttimeout) {
1067 if (ast_channel_timingfd(s->owner) > -1) {
1068 float samp_rate = (float) ast_format_get_sample_rate(s->fmt->format);
1069 unsigned int rate;
1070
1071 rate = (unsigned int) roundf(samp_rate / ((float) whennext));
1072
1074 } else {
1076 }
1077 s->lasttimeout = whennext;
1079 }
1080 return FSREAD_SUCCESS_SCHED;
1081
1082return_failure:
1084 ast_settimeout(s->owner, 0, NULL, NULL);
1085 return FSREAD_FAILURE;
1086}
float roundf(float x)
const char * ast_channel_name(const struct ast_channel *chan)
int ast_settimeout_full(struct ast_channel *c, unsigned int rate, int(*func)(const void *data), void *data, unsigned int is_ao2_obj)
Definition channel.c:3189
void ast_channel_streamid_set(struct ast_channel *chan, int value)
int ast_write(struct ast_channel *chan, struct ast_frame *frame)
Write a frame to a channel This function writes the given frame to the indicated channel.
Definition channel.c:5167
int ast_channel_timingfd(const struct ast_channel *chan)
int ast_settimeout(struct ast_channel *c, unsigned int rate, int(*func)(const void *data), void *data)
Enable or disable timer ticks for a channel.
Definition channel.c:3184
struct ast_sched_context * ast_channel_sched(const struct ast_channel *chan)
static int ast_fsread_audio(const void *data)
Definition file.c:1088
static struct ast_frame * read_frame(struct ast_filestream *s, int *whennext)
Definition file.c:1000
#define ast_frfree(fr)
int ast_sched_add(struct ast_sched_context *con, int when, ast_sched_cb callback, const void *data) attribute_warn_unused_result
Adds a scheduled event.
Definition sched.c:567
const char * orig_chan_name
Definition mod_format.h:125
Data structure associated with a single frame of data.

References ast_channel_name(), ast_channel_sched(), ast_channel_streamid_set(), ast_channel_timingfd(), ast_debug, ast_format_get_sample_rate(), ast_frfree, ast_fsread_audio(), ast_sched_add(), ast_settimeout(), ast_settimeout_full(), ast_write(), ast_filestream::fmt, ast_format_def::format, FSREAD_FAILURE, FSREAD_SUCCESS_NOSCHED, FSREAD_SUCCESS_SCHED, ast_filestream::lasttimeout, NULL, ast_filestream::orig_chan_name, ast_filestream::owner, read_frame(), and roundf().

Referenced by ast_fsread_audio(), and ast_playstream().

◆ ast_readfile()

struct ast_filestream * ast_readfile ( const char *  filename,
const char *  type,
const char *  comment,
int  flags,
int  check,
mode_t  mode 
)

Starts reading from a file.

Parameters
filenamethe name of the file to read from
typeformat of file you wish to read from
commentcomment to go with
flagsfile flags
check(unimplemented, hence negligible)
modeOpen mode Open an incoming file stream. flags are flags for the open() command, and if check is non-zero, then it will not read a file if there are any files that start with that name and have an extension Please note, this is a blocking function. Program execution will not return until ast_waitstream completes it's execution.
Returns
a struct ast_filestream on success.
Return values
NULLon failure.

Definition at line 1475 of file file.c.

1476{
1477 FILE *bfile;
1478 struct ast_format_def *f;
1479 struct ast_filestream *fs = NULL;
1480 char *fn;
1481 int format_found = 0;
1482
1484
1485 AST_RWLIST_TRAVERSE(&formats, f, list) {
1486 fs = NULL;
1487 if (!exts_compare(f->exts, type))
1488 continue;
1489 else
1490 format_found = 1;
1491
1493 if (!fn) {
1494 continue;
1495 }
1496 errno = 0;
1497 bfile = fopen(fn, "r");
1498
1499 if (!bfile || (fs = get_filestream(f, bfile)) == NULL || open_wrapper(fs) ) {
1500 ast_log(LOG_WARNING, "Unable to open %s\n", fn);
1501 if (fs) {
1502 ast_closestream(fs);
1503 }
1504 fs = NULL;
1505 bfile = NULL;
1506 ast_free(fn);
1507 break;
1508 }
1509 /* found it */
1510 fs->trans = NULL;
1511 fs->fmt = f;
1512 fs->flags = flags;
1513 fs->mode = mode;
1515 fs->vfs = NULL;
1516 ast_free(fn);
1517 break;
1518 }
1519
1521 if (!format_found)
1522 ast_log(LOG_WARNING, "No such format '%s'\n", type);
1523
1524 return fs;
1525}
#define ast_strdup(str)
A wrapper for strdup()
Definition astmm.h:241
static char * build_filename(const char *filename, const char *ext)
construct a filename. Absolute pathnames are preserved, relative names are prefixed by the sounds/ di...
Definition file.c:422
int ast_closestream(struct ast_filestream *f)
Closes a stream.
Definition file.c:1200
static int open_wrapper(struct ast_filestream *s)
Definition file.c:594
static struct ast_filestream * get_filestream(struct ast_format_def *fmt, FILE *bfile)
Definition file.c:532
struct ast_filestream * vfs
Definition mod_format.h:110
struct ast_trans_pvt * trans
Definition mod_format.h:112

References ast_closestream(), ast_free, ast_log, AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_strdup, build_filename(), errno, exts_compare, ast_filestream::f, ast_filestream::filename, ast_filestream::flags, ast_filestream::fmt, get_filestream(), LOG_WARNING, ast_filestream::mode, NULL, open_wrapper(), ast_filestream::trans, type, and ast_filestream::vfs.

Referenced by __ast_play_and_record(), handle_cli_file_convert(), and msg_create_from_file().

◆ ast_readframe()

struct ast_frame * ast_readframe ( struct ast_filestream *  s)

Read a frame from a filestream.

Parameters
sast_filestream to act on
Returns
a frame.
Return values
NULLif read failed.

Definition at line 1025 of file file.c.

1026{
1027 int whennext = 0;
1028
1029 return read_frame(s, &whennext);
1030}

References read_frame().

Referenced by __ast_play_and_record(), dictate_exec(), gen_readframe(), handle_cli_file_convert(), and moh_files_readframe().

◆ ast_readvideo_callback()

static enum fsread_res ast_readvideo_callback ( struct ast_filestream *  s)
static

Definition at line 1103 of file file.c.

1104{
1105 int whennext = 0;
1106
1107 while (!whennext) {
1108 struct ast_frame *fr = read_frame(s, &whennext);
1109
1110 if (!fr /* stream complete */ || ast_write(s->owner, fr) /* error writing */) {
1111 if (fr) {
1112 ast_debug(2, "Failed to write frame\n");
1113 ast_frfree(fr);
1114 }
1116 return FSREAD_FAILURE;
1117 }
1118
1119 if (fr) {
1120 ast_frfree(fr);
1121 }
1122 }
1123
1124 if (whennext != s->lasttimeout) {
1126 s->lasttimeout = whennext;
1128 }
1129
1130 return FSREAD_SUCCESS_SCHED;
1131}
void ast_channel_vstreamid_set(struct ast_channel *chan, int value)
static int ast_fsread_video(const void *data)
Definition file.c:1133

References ast_channel_sched(), ast_channel_vstreamid_set(), ast_debug, ast_format_get_sample_rate(), ast_frfree, ast_fsread_video(), ast_sched_add(), ast_write(), ast_filestream::fmt, ast_format_def::format, FSREAD_FAILURE, FSREAD_SUCCESS_NOSCHED, FSREAD_SUCCESS_SCHED, ast_filestream::lasttimeout, ast_filestream::owner, and read_frame().

Referenced by ast_fsread_video(), and ast_playstream().

◆ ast_seekstream()

int ast_seekstream ( struct ast_filestream *  fs,
off_t  sample_offset,
int  whence 
)

Seeks into stream.

Parameters
fsast_filestream to perform seek on
sample_offsetnumbers of samples to seek
whenceSEEK_SET, SEEK_CUR, SEEK_END
Return values
0on success.
-1on failure.

Definition at line 1164 of file file.c.

1165{
1166 return fs->fmt->seek(fs, sample_offset, whence);
1167}
int(* seek)(struct ast_filestream *, off_t, int)
Definition mod_format.h:68

References ast_filestream::fmt, and ast_format_def::seek.

Referenced by ast_stream_fastforward(), ast_stream_rewind(), ast_streamfile(), control_streamfile(), dictate_exec(), handle_getoption(), handle_recordfile(), handle_streamfile(), moh_files_next(), msg_create_from_file(), and speech_streamfile().

◆ ast_stopstream()

int ast_stopstream ( struct ast_channel *  c)

Stops a stream.

Parameters
cThe channel you wish to stop playback on

Stop playback of a stream

Return values
0always
Note
The channel does not need to be locked before calling this function.

Definition at line 233 of file file.c.

234{
235 struct ast_json * cel_event = NULL;
236
237 ast_channel_lock(tmp);
238
239 /* Stop a running stream if there is one */
240 if (ast_channel_stream(tmp)) {
243
244 cel_event = ast_json_pack("{ s: s }", "event", "FILE_STREAM_END");
245 if (cel_event) {
247 }
248
250 ast_log(LOG_WARNING, "Unable to restore format back to %s\n", ast_format_get_name(ast_channel_oldwriteformat(tmp)));
251 }
252 ast_json_unref(cel_event);
253
254 /* Stop the video stream too */
255 if (ast_channel_vstream(tmp) != NULL) {
258 }
259
261
262 return 0;
263}
void ast_cel_publish_event(struct ast_channel *chan, enum ast_cel_event_type event_type, struct ast_json *blob)
Publish a CEL event.
Definition cel.c:1762
@ AST_CEL_STREAM_END
A stream ended.
Definition cel.h:84
void ast_channel_stream_set(struct ast_channel *chan, struct ast_filestream *value)
struct ast_format * ast_channel_oldwriteformat(struct ast_channel *chan)
int ast_set_write_format(struct ast_channel *chan, struct ast_format *format)
Sets write format on channel chan.
Definition channel.c:5826
struct ast_filestream * ast_channel_stream(const struct ast_channel *chan)
void ast_channel_vstream_set(struct ast_channel *chan, struct ast_filestream *value)
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
Definition json.c:73
struct ast_json * ast_json_pack(char const *format,...)
Helper for creating complex JSON values.
Definition json.c:612
Abstract JSON element (object, array, string, int, ...).

References ast_cel_publish_event(), AST_CEL_STREAM_END, ast_channel_lock, ast_channel_oldwriteformat(), ast_channel_stream(), ast_channel_stream_set(), ast_channel_unlock, ast_channel_vstream(), ast_channel_vstream_set(), ast_closestream(), ast_format_get_name(), ast_json_pack(), ast_json_unref(), ast_log, ast_set_write_format(), LOG_WARNING, and NULL.

Referenced by action_playback_and_continue(), adsi_transmit_message_full(), agent_alert(), announce_to_dial(), ast_play_and_wait(), ast_readstring_full(), ast_say_enumeration_full_da(), ast_say_enumeration_full_de(), ast_say_enumeration_full_dr(), ast_say_enumeration_full_en(), ast_say_enumeration_full_he(), ast_say_enumeration_full_is(), ast_say_enumeration_full_ps(), ast_say_enumeration_full_vi(), ast_say_number_full_cs(), ast_say_number_full_da(), ast_say_number_full_de(), ast_say_number_full_dr(), ast_say_number_full_en_GB(), ast_say_number_full_es(), ast_say_number_full_fr(), ast_say_number_full_gr(), ast_say_number_full_he(), ast_say_number_full_hu(), ast_say_number_full_is(), ast_say_number_full_it(), ast_say_number_full_ja(), ast_say_number_full_ka(), ast_say_number_full_nl(), ast_say_number_full_no(), ast_say_number_full_ps(), ast_say_number_full_pt(), ast_say_number_full_ru(), ast_say_number_full_se(), ast_say_number_full_th(), ast_say_number_full_ur(), ast_say_number_full_vi(), ast_say_number_full_zh(), ast_stream_and_wait(), background_detect_exec(), conf_exec(), conf_run(), control_streamfile(), dial_exec_full(), directory_exec(), grab_transfer(), handle_getoption(), handle_speechrecognize(), handle_streamfile(), isAnsweringMachine(), ivr_dispatch(), leave_voicemail(), meetme_menu_admin(), meetme_menu_admin_extended(), minivm_greet_exec(), mp3_exec(), openstream_internal(), pbx_builtin_background(), pl_odtworz_plik(), play_file(), play_file(), play_files_helper(), play_mailbox_owner(), playback_exec(), queue_exec(), read_exec(), readexten_exec(), recordthread(), s_streamwait3(), say_filenames(), select_item_seq(), send_waveform_to_channel(), speech_background(), vm_authenticate(), vm_execmain(), wait_for_winner(), waitstream_core(), and zapateller_exec().

◆ ast_stream_and_wait()

int ast_stream_and_wait ( struct ast_channel *  chan,
const char *  file,
const char *  digits 
)

stream file until digit If the file name is non-empty, try to play it.

Note
If digits == "" then we can simply check for non-zero.
If a failure is encountered, the stream will be closed before returning.
Return values
0if success.
-1if error.
digitif interrupted by a digit.

Definition at line 1982 of file file.c.

1983{
1984 int res = 0;
1985 if (!ast_strlen_zero(file)) {
1986 res = ast_streamfile(chan, file, ast_channel_language(chan));
1987 if (!res) {
1988 res = ast_waitstream(chan, digits);
1989 }
1990 }
1991 if (res == -1) {
1992 ast_stopstream(chan);
1993 }
1994
1995 return res;
1996}
const char * ast_channel_language(const struct ast_channel *chan)
int ast_streamfile(struct ast_channel *chan, const char *filename, const char *preflang)
Streams a file.
Definition file.c:1382
int ast_stopstream(struct ast_channel *tmp)
Stops a stream.
Definition file.c:233
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition file.c:1944
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition strings.h:65

References ast_channel_language(), ast_stopstream(), ast_streamfile(), ast_strlen_zero(), and ast_waitstream().

Referenced by __ast_play_and_record(), action_playback(), action_toggle_mute_participants(), agent_alert(), agent_login_exec(), announce_user_count(), app_exec(), ast_bridge_channel_playfile(), ast_pickup_call(), ast_record_review(), bridge_features_duration_callback(), confbridge_exec(), directory_exec(), forward_message(), grab_transfer(), invent_message(), ivr_dispatch(), join_conference_bridge(), leave_voicemail(), limits_interval_playback(), mixmonitor_thread(), park_app_exec(), parked_call_app_exec(), play_file(), play_files_helper(), play_mailbox_owner(), play_message_callerid(), play_prompt_to_user(), play_record_review(), play_record_review(), playback_common(), record_exec(), sayname(), select_item_seq(), setup_mixmonitor_ds(), stream_failsound(), vm_forwardoptions(), vmsayname_exec(), and wait_file2().

◆ ast_stream_fastforward()

int ast_stream_fastforward ( struct ast_filestream *  fs,
off_t  ms 
)

Fast forward stream ms.

Parameters
fsfilestream to act on
msmilliseconds to move
Return values
0on success.
-1on failure.

Definition at line 1184 of file file.c.

1185{
1186 return ast_seekstream(fs, ms * DEFAULT_SAMPLES_PER_MS, SEEK_CUR);
1187}
#define DEFAULT_SAMPLES_PER_MS
Definition asterisk.h:49
int ast_seekstream(struct ast_filestream *fs, off_t sample_offset, int whence)
Seeks into stream.
Definition file.c:1164

References ast_seekstream(), and DEFAULT_SAMPLES_PER_MS.

Referenced by waitstream_control().

◆ ast_stream_rewind()

int ast_stream_rewind ( struct ast_filestream *  fs,
off_t  ms 
)

Rewind stream ms.

Parameters
fsfilestream to act on
msmilliseconds to move
Return values
0on success.
-1on failure.

Definition at line 1189 of file file.c.

1190{
1191 off_t offset = ast_tellstream(fs);
1192 if (ms * DEFAULT_SAMPLES_PER_MS > offset) {
1193 /* Don't even bother asking the file format to seek to a negative offset... */
1194 ast_debug(1, "Restarting, rather than seeking to negative offset %ld\n", (long) (offset - (ms * DEFAULT_SAMPLES_PER_MS)));
1195 return ast_seekstream(fs, 0, SEEK_SET);
1196 }
1197 return ast_seekstream(fs, -ms * DEFAULT_SAMPLES_PER_MS, SEEK_CUR);
1198}
off_t ast_tellstream(struct ast_filestream *fs)
Tell where we are in a stream.
Definition file.c:1174

References ast_debug, ast_seekstream(), ast_tellstream(), and DEFAULT_SAMPLES_PER_MS.

Referenced by __ast_play_and_record(), handle_recordfile(), record_exec(), and waitstream_control().

◆ ast_streamfile()

int ast_streamfile ( struct ast_channel *  c,
const char *  filename,
const char *  preflang 
)

Streams a file.

Parameters
cchannel to stream the file to
filenamethe name of the file you wish to stream, minus the extension
preflangthe preferred language you wish to have the file streamed to you in Prepares a channel for the streaming of a file. To start the stream, afterward do a ast_waitstream() on the channel Also, it will stop any existing streams on the channel.
Return values
0on success.
-1on failure.

Definition at line 1382 of file file.c.

1384{
1385 struct ast_json * cel_event = NULL;
1386 struct ast_filestream *fs = NULL;
1387 struct ast_filestream *vfs = NULL;
1388 off_t pos;
1389 int seekattempt;
1390 int res;
1391 char custom_filename[256];
1392 char *tmp_filename;
1393
1394 /* If file with the same name exists in /var/lib/asterisk/sounds/custom directory, use that file.
1395 * Otherwise, use the original file*/
1396
1398 memset(custom_filename, 0, sizeof(custom_filename));
1399 snprintf(custom_filename, sizeof(custom_filename), "custom/%s", filename);
1400 fs = openstream_internal(chan, custom_filename, preflang, 0, 1); /* open stream, do not warn for missing files */
1401 if (fs) {
1402 tmp_filename = custom_filename;
1403 ast_debug(3, "Found file %s in custom directory\n", filename);
1404 }
1405 }
1406
1407 if (!fs) {
1408 fs = ast_openstream(chan, filename, preflang);
1409 if (!fs) {
1410 struct ast_str *codec_buf = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN);
1411 ast_channel_lock(chan);
1412 ast_log(LOG_WARNING, "Unable to open %s (format %s)\n",
1413 filename, ast_format_cap_get_names(ast_channel_nativeformats(chan), &codec_buf));
1414 ast_channel_unlock(chan);
1415 return -1;
1416 }
1417 tmp_filename = (char *)filename;
1418 }
1419
1420 /* check to see if there is any data present (not a zero length file),
1421 * done this way because there is no where for ast_openstream_full to
1422 * return the file had no data. */
1423 pos = ftello(fs->f);
1424 seekattempt = fseeko(fs->f, -1, SEEK_END);
1425 if (seekattempt) {
1426 if (errno == EINVAL) {
1427 /* Zero-length file, as opposed to a pipe */
1428 return 0;
1429 } else {
1430 ast_seekstream(fs, 0, SEEK_SET);
1431 }
1432 } else {
1433 fseeko(fs->f, pos, SEEK_SET);
1434 }
1435
1436 vfs = ast_openvstream(chan, tmp_filename, preflang);
1437 if (vfs) {
1438 ast_debug(1, "Ooh, found a video stream, too, format %s\n", ast_format_get_name(vfs->fmt->format));
1439 }
1440
1443 if (ast_applystream(chan, fs))
1444 return -1;
1445 if (vfs && ast_applystream(chan, vfs))
1446 return -1;
1447 ast_test_suite_event_notify("PLAYBACK", "Message: %s\r\nChannel: %s", tmp_filename, ast_channel_name(chan));
1448 res = ast_playstream(fs);
1449 if (!res && vfs)
1450 res = ast_playstream(vfs);
1451
1452 cel_event = ast_json_pack("{ s: s, s: {s: s, s: s, s: s}}",
1453 "event", "FILE_STREAM_BEGIN",
1454 "extra",
1455 "sound", tmp_filename,
1457 "language", preflang ? preflang : "default"
1458 );
1459 if (cel_event) {
1461 } else {
1462 ast_log(LOG_WARNING, "Unable to build extradata for sound file STREAM_BEGIN event on channel %s", ast_channel_name(chan));
1463 }
1464 ast_json_unref(cel_event);
1465
1466 if (VERBOSITY_ATLEAST(3)) {
1467 ast_channel_lock(chan);
1468 ast_verb(3, "<%s> Playing '%s' (format '%s', language '%s')\n", ast_channel_name(chan), tmp_filename, S_OR(fs->open_extension, "unknown"), preflang ? preflang : "default");
1469 ast_channel_unlock(chan);
1470 }
1471
1472 return res;
1473}
@ AST_CEL_STREAM_BEGIN
A stream started.
Definition cel.h:82
@ AST_FLAG_MASQ_NOSTREAM
Definition channel.h:1034
struct ast_flags * ast_channel_flags(struct ast_channel *chan)
struct ast_format * ast_channel_writeformat(struct ast_channel *chan)
struct ast_filestream * ast_openstream(struct ast_channel *chan, const char *filename, const char *preflang)
Opens stream for use in seeking, playing.
Definition file.c:926
int ast_applystream(struct ast_channel *chan, struct ast_filestream *s)
Applies a open stream to a channel.
Definition file.c:1146
struct ast_filestream * ast_openvstream(struct ast_channel *chan, const char *filename, const char *preflang)
Opens stream for use in seeking, playing.
Definition file.c:937
static int is_absolute_path(const char *filename)
Definition file.c:756
int ast_playstream(struct ast_filestream *s)
Play a open stream on a channel.
Definition file.c:1152
#define AST_FORMAT_CAP_NAMES_LEN
Definition format_cap.h:324
const char * ast_format_cap_get_names(const struct ast_format_cap *cap, struct ast_str **buf)
Get the names of codecs of a set of formats.
Definition format_cap.c:742
#define VERBOSITY_ATLEAST(level)
#define ast_opt_sounds_search_custom
Definition options.h:148
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one.
Definition strings.h:80
#define ast_str_alloca(init_len)
Definition strings.h:848
char * open_extension
Definition mod_format.h:106
Support for dynamic strings.
Definition strings.h:623
#define ast_test_suite_event_notify(s, f,...)
Definition test.h:189
#define ast_test_flag(p, flag)
Definition utils.h:64

References ast_applystream(), ast_cel_publish_event(), AST_CEL_STREAM_BEGIN, ast_channel_flags(), ast_channel_lock, ast_channel_name(), ast_channel_nativeformats(), ast_channel_unlock, ast_channel_writeformat(), ast_debug, AST_FLAG_MASQ_NOSTREAM, ast_format_cap_get_names(), AST_FORMAT_CAP_NAMES_LEN, ast_format_get_name(), ast_json_pack(), ast_json_unref(), ast_log, ast_openstream(), ast_openvstream(), ast_opt_sounds_search_custom, ast_playstream(), ast_seekstream(), ast_str_alloca, ast_strdup, ast_test_flag, ast_test_suite_event_notify, ast_verb, errno, ast_filestream::f, ast_filestream::filename, ast_filestream::fmt, ast_format_def::format, is_absolute_path(), LOG_WARNING, NULL, ast_filestream::open_extension, openstream_internal(), ast_filestream::orig_chan_name, S_OR, VERBOSITY_ATLEAST, and ast_filestream::vfs.

Referenced by __analog_ss_thread(), action_playback_and_continue(), analog_ss_thread(), announce_thread(), announce_to_dial(), app_exec(), ast_app_getdata_full(), ast_app_getdata_terminator(), ast_play_and_wait(), ast_say_date_da(), ast_say_date_de(), ast_say_date_en(), ast_say_date_fr(), ast_say_date_gr(), ast_say_date_he(), ast_say_date_hu(), ast_say_date_is(), ast_say_date_ja(), ast_say_date_ka(), ast_say_date_nl(), ast_say_date_th(), ast_say_date_with_format_gr(), ast_say_datetime_en(), ast_say_datetime_fr(), ast_say_datetime_from_now_en(), ast_say_datetime_from_now_fr(), ast_say_datetime_from_now_he(), ast_say_datetime_from_now_ka(), ast_say_datetime_gr(), ast_say_datetime_he(), ast_say_datetime_ja(), ast_say_datetime_nl(), ast_say_datetime_pt(), ast_say_datetime_th(), ast_say_datetime_zh(), ast_say_enumeration_full_da(), ast_say_enumeration_full_de(), ast_say_enumeration_full_dr(), ast_say_enumeration_full_en(), ast_say_enumeration_full_he(), ast_say_enumeration_full_is(), ast_say_enumeration_full_ps(), ast_say_enumeration_full_vi(), ast_say_number_full_cs(), ast_say_number_full_da(), ast_say_number_full_de(), ast_say_number_full_dr(), ast_say_number_full_en_GB(), ast_say_number_full_es(), ast_say_number_full_fr(), ast_say_number_full_gr(), ast_say_number_full_he(), ast_say_number_full_hu(), ast_say_number_full_is(), ast_say_number_full_it(), ast_say_number_full_ja(), ast_say_number_full_ka(), ast_say_number_full_nl(), ast_say_number_full_no(), ast_say_number_full_ps(), ast_say_number_full_pt(), ast_say_number_full_ru(), ast_say_number_full_se(), ast_say_number_full_th(), ast_say_number_full_ur(), ast_say_number_full_vi(), ast_say_number_full_zh(), ast_say_time_de(), ast_say_time_en(), ast_say_time_fr(), ast_say_time_gr(), ast_say_time_hu(), ast_say_time_ja(), ast_say_time_ka(), ast_say_time_nl(), ast_say_time_zh(), ast_stream_and_wait(), auth_exec(), background_detect_exec(), common_exec(), conf_exec(), conf_get_pin(), conf_run(), control_streamfile(), dial_exec_full(), do_directory(), find_conf_realtime(), forward_message(), gr_say_number_female(), handle_recordfile(), invent_message(), isAnsweringMachine(), leave_voicemail(), leave_voicemail(), meetme_menu_admin(), meetme_menu_admin_extended(), meetme_menu_normal(), minivm_greet_exec(), page_exec(), pbx_builtin_background(), pl_odtworz_plik(), play_and_wait(), play_file(), play_record_review(), playback_exec(), privacy_exec(), readexten_exec(), retrydial_exec(), s_streamwait3(), say_filenames(), select_item_menu(), setup_privacy_args(), vm_authenticate(), wait_file(), wait_for_answer(), and wait_for_winner().

◆ ast_tellstream()

off_t ast_tellstream ( struct ast_filestream *  fs)

Tell where we are in a stream.

Parameters
fsfs to act on
Returns
a long as a sample offset into stream

Definition at line 1174 of file file.c.

1175{
1176 return fs->fmt->tell(fs);
1177}
off_t(* tell)(struct ast_filestream *fs)
Definition mod_format.h:70

References ast_filestream::fmt, and ast_format_def::tell.

Referenced by __ast_play_and_record(), ast_stream_rewind(), control_streamfile(), handle_getoption(), handle_recordfile(), handle_speechrecognize(), handle_streamfile(), moh_files_next(), msg_create_from_file(), waitstream_control(), and waitstream_core().

◆ ast_truncstream()

int ast_truncstream ( struct ast_filestream *  fs)

Trunc stream at current location.

Parameters
fsfilestream to act on
Return values
0on success.
-1on failure.

Definition at line 1169 of file file.c.

1170{
1171 return fs->fmt->trunc(fs);
1172}
int(* trunc)(struct ast_filestream *fs)
Definition mod_format.h:69

References ast_filestream::fmt, and ast_format_def::trunc.

Referenced by __ast_play_and_record(), handle_recordfile(), and record_exec().

◆ ast_waitstream()

int ast_waitstream ( struct ast_channel *  c,
const char *  breakon 
)

Waits for a stream to stop or digit to be pressed.

Parameters
cchannel to waitstream on
breakonstring of DTMF digits to break upon Begins playback of a stream... Wait for a stream to stop or for any one of a given digit to arrive,
Return values
0if the stream finishes
characterif it was interrupted by the channel.
-1on error

Definition at line 1944 of file file.c.

1945{
1946 int res;
1947
1948 res = waitstream_core(c, breakon, NULL, NULL, 0, -1, -1, NULL, NULL /* no callback */);
1949
1950 return sanitize_waitstream_return(res);
1951}
static int sanitize_waitstream_return(int return_value)
Definition file.c:1927
static int waitstream_core(struct ast_channel *c, const char *breakon, const char *forward, const char *reverse, int skip_ms, int audiofd, int cmdfd, const char *context, ast_waitstream_fr_cb cb)
the core of all waitstream() functions
Definition file.c:1717
static struct test_val c

References c, NULL, sanitize_waitstream_return(), and waitstream_core().

Referenced by __analog_ss_thread(), action_playback_and_continue(), analog_ss_thread(), announce_thread(), announce_to_dial(), app_exec(), ast_play_and_wait(), ast_say_date_da(), ast_say_date_de(), ast_say_date_en(), ast_say_date_fr(), ast_say_date_gr(), ast_say_date_he(), ast_say_date_hu(), ast_say_date_is(), ast_say_date_ja(), ast_say_date_ka(), ast_say_date_nl(), ast_say_date_th(), ast_say_date_with_format_gr(), ast_say_datetime_en(), ast_say_datetime_fr(), ast_say_datetime_from_now_en(), ast_say_datetime_from_now_fr(), ast_say_datetime_from_now_he(), ast_say_datetime_from_now_ka(), ast_say_datetime_gr(), ast_say_datetime_he(), ast_say_datetime_ja(), ast_say_datetime_nl(), ast_say_datetime_pt(), ast_say_datetime_th(), ast_say_datetime_zh(), ast_say_enumeration_full_da(), ast_say_enumeration_full_de(), ast_say_enumeration_full_dr(), ast_say_enumeration_full_en(), ast_say_enumeration_full_he(), ast_say_enumeration_full_is(), ast_say_enumeration_full_ps(), ast_say_enumeration_full_vi(), ast_say_number_full_cs(), ast_say_number_full_da(), ast_say_number_full_de(), ast_say_number_full_dr(), ast_say_number_full_en_GB(), ast_say_number_full_es(), ast_say_number_full_fr(), ast_say_number_full_gr(), ast_say_number_full_he(), ast_say_number_full_hu(), ast_say_number_full_is(), ast_say_number_full_it(), ast_say_number_full_ja(), ast_say_number_full_ka(), ast_say_number_full_nl(), ast_say_number_full_no(), ast_say_number_full_ps(), ast_say_number_full_pt(), ast_say_number_full_ru(), ast_say_number_full_se(), ast_say_number_full_th(), ast_say_number_full_ur(), ast_say_number_full_vi(), ast_say_number_full_zh(), ast_say_time_de(), ast_say_time_en(), ast_say_time_fr(), ast_say_time_gr(), ast_say_time_he(), ast_say_time_hu(), ast_say_time_ja(), ast_say_time_ka(), ast_say_time_nl(), ast_say_time_zh(), ast_stream_and_wait(), auth_exec(), common_exec(), conf_exec(), conf_get_pin(), conf_run(), directory_exec(), find_conf_realtime(), gr_say_number_female(), handle_recordfile(), invent_message(), leave_voicemail(), leave_voicemail(), meetme_menu_admin(), meetme_menu_admin_extended(), meetme_menu_normal(), minivm_greet_exec(), page_exec(), pbx_builtin_background(), pl_odtworz_plik(), play_and_wait(), play_file(), play_record_review(), playback_exec(), privacy_exec(), retrydial_exec(), s_streamwait3(), say_filenames(), select_item_menu(), setup_privacy_args(), vm_authenticate(), and wait_file().

◆ ast_waitstream_exten()

int ast_waitstream_exten ( struct ast_channel *  c,
const char *  context 
)

Waits for a stream to stop or digit matching a valid one digit exten to be pressed.

Parameters
cchannel to waitstream on
contextstring of context to match digits to break upon Begins playback of a stream... Wait for a stream to stop or for any one of a valid extension digit to arrive,
Return values
0if the stream finishes.
characterif it was interrupted.
-1on error.

Definition at line 1963 of file file.c.

1964{
1965 int res;
1966
1967 /* Waitstream, with return in the case of a valid 1 digit extension */
1968 /* in the current or specified context being pressed */
1969 if (!context)
1971 res = waitstream_core(c, NULL, NULL, NULL, 0,
1972 -1, -1, context, NULL /* no callback */);
1973
1974 return sanitize_waitstream_return(res);
1975}
const char * ast_channel_context(const struct ast_channel *chan)

References ast_channel_context(), c, NULL, sanitize_waitstream_return(), and waitstream_core().

Referenced by pbx_builtin_background().

◆ ast_waitstream_fr()

int ast_waitstream_fr ( struct ast_channel *  c,
const char *  breakon,
const char *  forward,
const char *  rewind,
int  ms 
)

Same as waitstream but allows stream to be forwarded or rewound.

Parameters
cchannel to waitstream on
breakonstring of DTMF digits to break upon
forwardDTMF digit to fast forward upon
rewindDTMF digit to rewind upon
msHow many miliseconds to skip forward/back Begins playback of a stream... Wait for a stream to stop or for any one of a given digit to arrive,
Return values
0if the stream finishes.
characterif it was interrupted,
Returns
the value of the control frame if it was interrupted by some other party,
Return values
-1on error.

Definition at line 1913 of file file.c.

1914{
1915 return waitstream_core(c, breakon, forward, reverse, ms,
1916 -1 /* no audiofd */, -1 /* no cmdfd */, NULL /* no context */, NULL /* no callback */);
1917}

References c, NULL, and waitstream_core().

Referenced by control_streamfile().

◆ ast_waitstream_fr_w_cb()

int ast_waitstream_fr_w_cb ( struct ast_channel *  c,
const char *  breakon,
const char *  forward,
const char *  rewind,
int  ms,
ast_waitstream_fr_cb  cb 
)

Same as waitstream_fr but allows a callback to be alerted when a user fastforwards or rewinds the file.

Parameters
cchannel to waitstream on
breakonstring of DTMF digits to break upon
forwardDTMF digit to fast forward upon
rewindDTMF digit to rewind upon
msHow many milliseconds to skip forward/back
cbto call when rewind or fastforward occurs. Begins playback of a stream... Wait for a stream to stop or for any one of a given digit to arrive,
Return values
0if the stream finishes.
characterif it was interrupted,
Returns
the value of the control frame if it was interrupted by some other party,
Return values
-1on error.

Definition at line 1902 of file file.c.

1908{
1909 return waitstream_core(c, breakon, forward, reverse, ms,
1910 -1 /* no audiofd */, -1 /* no cmdfd */, NULL /* no context */, cb);
1911}

References c, NULL, and waitstream_core().

Referenced by control_streamfile().

◆ ast_waitstream_full()

int ast_waitstream_full ( struct ast_channel *  c,
const char *  breakon,
int  audiofd,
int  monfd 
)

◆ ast_writefile()

struct ast_filestream * ast_writefile ( const char *  filename,
const char *  type,
const char *  comment,
int  flags,
int  check,
mode_t  mode 
)

Starts writing a file.

Parameters
filenamethe name of the file to write to
typeformat of file you wish to write out to
commentcomment to go with
flagsoutput file flags
check(unimplemented, hence negligible)
modeOpen mode Create an outgoing file stream. oflags are flags for the open() command, and if check is non-zero, then it will not write a file if there are any files that start with that name and have an extension Please note, this is a blocking function. Program execution will not return until ast_waitstream completes it's execution.
Returns
a struct ast_filestream on success.
Return values
NULLon failure.

Definition at line 1527 of file file.c.

1528{
1529 int fd, myflags = 0;
1530 /* compiler claims this variable can be used before initialization... */
1531 FILE *bfile = NULL;
1532 struct ast_format_def *f;
1533 struct ast_filestream *fs = NULL;
1534 char *buf = NULL;
1535 size_t size = 0;
1536 int format_found = 0;
1537
1539
1540 /* set the O_TRUNC flag if and only if there is no O_APPEND specified */
1541 /* We really can't use O_APPEND as it will break WAV header updates */
1542 if (flags & O_APPEND) {
1543 flags &= ~O_APPEND;
1544 } else {
1545 myflags = O_TRUNC;
1546 }
1547
1548 myflags |= O_WRONLY | O_CREAT;
1549
1550 /* XXX need to fix this - we should just do the fopen,
1551 * not open followed by fdopen()
1552 */
1553 AST_RWLIST_TRAVERSE(&formats, f, list) {
1554 char *fn, *orig_fn = NULL;
1555 if (fs)
1556 break;
1557
1558 if (!exts_compare(f->exts, type))
1559 continue;
1560 else
1561 format_found = 1;
1562
1564 if (!fn) {
1565 continue;
1566 }
1567 fd = open(fn, flags | myflags, mode);
1568 if (fd > -1) {
1569 /* fdopen() the resulting file stream */
1570 bfile = fdopen(fd, ((flags | myflags) & O_RDWR) ? "w+" : "w");
1571 if (!bfile) {
1572 ast_log(LOG_WARNING, "Whoa, fdopen failed: %s!\n", strerror(errno));
1573 close(fd);
1574 fd = -1;
1575 }
1576 }
1577
1578 if (ast_opt_cache_record_files && (fd > -1)) {
1579 char *c;
1580
1581 fclose(bfile); /* this also closes fd */
1582 /*
1583 We touch orig_fn just as a place-holder so other things (like vmail) see the file is there.
1584 What we are really doing is writing to record_cache_dir until we are done then we will mv the file into place.
1585 */
1586 orig_fn = ast_strdup(fn);
1587 for (c = fn; *c; c++)
1588 if (*c == '/')
1589 *c = '_';
1590
1591 size = strlen(fn) + strlen(record_cache_dir) + 2;
1592 buf = ast_malloc(size);
1593 strcpy(buf, record_cache_dir);
1594 strcat(buf, "/");
1595 strcat(buf, fn);
1596 ast_free(fn);
1597 fn = buf;
1598 fd = open(fn, flags | myflags, mode);
1599 if (fd > -1) {
1600 /* fdopen() the resulting file stream */
1601 bfile = fdopen(fd, ((flags | myflags) & O_RDWR) ? "w+" : "w");
1602 if (!bfile) {
1603 ast_log(LOG_WARNING, "Whoa, fdopen failed: %s!\n", strerror(errno));
1604 close(fd);
1605 fd = -1;
1606 }
1607 }
1608 }
1609 if (fd > -1) {
1610 errno = 0;
1611 fs = get_filestream(f, bfile);
1612 if (fs) {
1613 if ((fs->write_buffer = ast_malloc(32768))) {
1614 setvbuf(fs->f, fs->write_buffer, _IOFBF, 32768);
1615 }
1616 }
1617 if (!fs || rewrite_wrapper(fs, comment)) {
1618 ast_log(LOG_WARNING, "Unable to rewrite %s\n", fn);
1619 close(fd);
1620 if (orig_fn) {
1621 unlink(fn);
1622 unlink(orig_fn);
1623 ast_free(orig_fn);
1624 }
1625 if (fs) {
1626 ast_closestream(fs);
1627 fs = NULL;
1628 }
1629 /*
1630 * 'fn' was has either been allocated from build_filename, or that was freed
1631 * and now 'fn' points to memory allocated for 'buf'. Either way the memory
1632 * now needs to be released.
1633 */
1634 ast_free(fn);
1635 continue;
1636 }
1637 fs->trans = NULL;
1638 fs->fmt = f;
1639 fs->flags = flags;
1640 fs->mode = mode;
1641 if (orig_fn) {
1642 fs->realfilename = orig_fn;
1643 fs->filename = fn;
1644 /*
1645 * The above now manages the memory allocated for 'orig_fn' and 'fn', so
1646 * set them to NULL, so they don't get released at the end of the loop.
1647 */
1648 orig_fn = NULL;
1649 fn = NULL;
1650 } else {
1651 fs->realfilename = NULL;
1653 }
1654 fs->vfs = NULL;
1655 /* If truncated, we'll be at the beginning; if not truncated, then append */
1656 f->seek(fs, 0, SEEK_END);
1657 } else if (errno != EEXIST) {
1658 ast_log(LOG_WARNING, "Unable to open file %s: %s\n", fn, strerror(errno));
1659 if (orig_fn)
1660 unlink(orig_fn);
1661 }
1662 /* Free 'fn', or if 'fn' points to 'buf' then free 'buf' */
1663 ast_free(fn);
1664 ast_free(orig_fn);
1665 }
1666
1668
1669 if (!format_found)
1670 ast_log(LOG_WARNING, "No such format '%s'\n", type);
1671
1672 return fs;
1673}
#define comment
Definition ael_lex.c:965
static int rewrite_wrapper(struct ast_filestream *s, const char *comment)
Definition file.c:589
char record_cache_dir[AST_CACHE_DIR_LEN]
Definition options.c:97
#define ast_opt_cache_record_files
Definition options.h:130
char * realfilename
Definition mod_format.h:108
char * write_buffer
Definition mod_format.h:126

References ast_closestream(), ast_free, ast_log, ast_malloc, ast_opt_cache_record_files, AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_strdup, buf, build_filename(), c, comment, errno, exts_compare, ast_filestream::f, ast_filestream::filename, ast_filestream::flags, ast_filestream::fmt, get_filestream(), LOG_WARNING, ast_filestream::mode, NULL, ast_filestream::realfilename, record_cache_dir, rewrite_wrapper(), ast_filestream::trans, type, ast_filestream::vfs, and ast_filestream::write_buffer.

Referenced by __ast_play_and_record(), ast_writestream(), dictate_exec(), handle_cli_file_convert(), handle_recordfile(), mixmonitor_save_prep(), record_exec(), and recordthread().

◆ ast_writestream()

int ast_writestream ( struct ast_filestream *  fs,
struct ast_frame *  f 
)

Writes a frame to a stream.

Parameters
fsfilestream to write to
fframe to write to the filestream Send a frame to a filestream – note: does NOT free the frame, call ast_frfree manually
Return values
0on success.
-1on failure.

Definition at line 265 of file file.c.

266{
267 int res = -1;
268 if (f->frametype == AST_FRAME_VIDEO) {
270 /* This is the audio portion. Call the video one... */
271 if (!fs->vfs && fs->filename) {
272 const char *type = ast_format_get_name(f->subclass.format);
273 fs->vfs = ast_writefile(fs->filename, type, NULL, fs->flags, 0, fs->mode);
274 ast_debug(1, "Opened video output file\n");
275 }
276 if (fs->vfs)
277 return ast_writestream(fs->vfs, f);
278 /* else ignore */
279 return 0;
280 }
281 } else if (f->frametype != AST_FRAME_VOICE) {
282 ast_log(LOG_WARNING, "Tried to write non-voice frame\n");
283 return -1;
284 }
286 res = fs->fmt->write(fs, f);
287 if (res < 0)
288 ast_log(LOG_WARNING, "Natural write failed\n");
289 else if (res > 0)
290 ast_log(LOG_WARNING, "Huh??\n");
291 } else {
292 /* XXX If they try to send us a type of frame that isn't the normal frame, and isn't
293 the one we've setup a translator for, we do the "wrong thing" XXX */
296 fs->trans = NULL;
297 }
298 if (!fs->trans) {
300 }
301 if (!fs->trans) {
302 ast_log(LOG_WARNING, "Unable to translate to format %s, source format %s\n",
304 } else {
305 struct ast_frame *trf;
307 /* Get the translated frame but don't consume the original in case they're using it on another stream */
308 if ((trf = ast_translate(fs->trans, f, 0))) {
309 struct ast_frame *cur;
310
311 /* the translator may have returned multiple frames, so process them */
312 for (cur = trf; cur; cur = AST_LIST_NEXT(cur, frame_list)) {
313 if ((res = fs->fmt->write(fs, cur))) {
314 ast_log(LOG_WARNING, "Translated frame write failed\n");
315 break;
316 }
317 }
318 ast_frfree(trf);
319 } else {
320 res = 0;
321 }
322 }
323 }
324 return res;
325}
#define ao2_replace(dst, src)
Replace one object reference with another cleaning up the original.
Definition astobj2.h:501
int ast_writestream(struct ast_filestream *fs, struct ast_frame *f)
Writes a frame to a stream.
Definition file.c:265
struct ast_filestream * ast_writefile(const char *filename, const char *type, const char *comment, int flags, int check, mode_t mode)
Starts writing a file.
Definition file.c:1527
enum ast_format_cmp_res ast_format_cmp(const struct ast_format *format1, const struct ast_format *format2)
Compare two formats.
Definition format.c:201
@ AST_FORMAT_CMP_EQUAL
Definition format.h:36
@ AST_FORMAT_CMP_NOT_EQUAL
Definition format.h:38
#define AST_LIST_NEXT(elm, field)
Returns the next entry in the list after the given entry.
struct ast_format * lastwriteformat
Definition mod_format.h:114
int(* write)(struct ast_filestream *, struct ast_frame *)
Definition mod_format.h:66
struct ast_format * format
struct ast_frame_subclass subclass
enum ast_frame_type frametype
struct ast_frame * ast_translate(struct ast_trans_pvt *tr, struct ast_frame *f, int consume)
translates one or more frames Apply an input frame into the translator and receive zero or one output...
Definition translate.c:623
void ast_translator_free_path(struct ast_trans_pvt *tr)
Frees a translator path Frees the given translator path structure.
Definition translate.c:533
struct ast_trans_pvt * ast_translator_build_path(struct ast_format *dest, struct ast_format *source)
Builds a translator path Build a path (possibly NULL) from source to dest.
Definition translate.c:543

References ao2_replace, ast_debug, ast_format_cmp(), AST_FORMAT_CMP_EQUAL, AST_FORMAT_CMP_NOT_EQUAL, ast_format_get_name(), ast_format_get_type(), AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_frfree, AST_LIST_NEXT, ast_log, AST_MEDIA_TYPE_AUDIO, ast_translate(), ast_translator_build_path(), ast_translator_free_path(), ast_writefile(), ast_writestream(), ast_filestream::filename, ast_filestream::flags, ast_filestream::fmt, ast_frame_subclass::format, ast_format_def::format, ast_frame::frametype, ast_filestream::lastwriteformat, LOG_WARNING, ast_filestream::mode, ast_format_def::name, NULL, ast_frame::subclass, ast_filestream::trans, type, ast_filestream::vfs, and ast_format_def::write.

Referenced by __ast_play_and_record(), ast_writestream(), dictate_exec(), handle_cli_file_convert(), handle_recordfile(), mixmonitor_thread(), record_exec(), and recordthread().

◆ build_filename()

static char * build_filename ( const char *  filename,
const char *  ext 
)
static

construct a filename. Absolute pathnames are preserved, relative names are prefixed by the sounds/ directory. Returns a malloc'ed string to be freed by the caller.

Definition at line 422 of file file.c.

423{
424 char *fn = NULL;
425
426 if (filename[0] == '/') {
427 if (ast_asprintf(&fn, "%s.%s", filename, translate_extension(ext)) < 0) {
428 fn = NULL;
429 }
430 } else {
431 if (ast_asprintf(&fn, "%s/sounds/%s.%s",
433 fn = NULL;
434 }
435 }
436 return fn;
437}
static const char * translate_extension(const char *extension)
Definition file.c:407
const char * ast_config_AST_DATA_DIR
Definition options.c:159

References ast_asprintf, ast_config_AST_DATA_DIR, ext, NULL, and translate_extension().

Referenced by ast_readfile(), ast_writefile(), and filehelper().

◆ build_filename_template()

static char * build_filename_template ( const char *  filename,
char **  extension_start 
)
static

Definition at line 377 of file file.c.

378{
379 char *fn;
380 int prefix_length;
381 int res;
382
383 if (filename[0] == '/') {
384 res = ast_asprintf(&fn, "%s.%n%*s",
385 filename, &prefix_length, maximum_extension_length, "");
386 } else {
387 res = ast_asprintf(&fn, "%s/sounds/%s.%n%*s",
389 filename, &prefix_length, maximum_extension_length, "");
390 }
391
392 if (res == -1) {
393 return NULL;
394 }
395
396 *extension_start = fn + prefix_length;
397 return fn;
398}

References ast_asprintf, ast_config_AST_DATA_DIR, maximum_extension_length, and NULL.

Referenced by filehelper().

◆ copy()

static int copy ( const char *  infile,
const char *  outfile 
)
static

Definition at line 327 of file file.c.

328{
329 int ifd, ofd, len;
330 char buf[4096]; /* XXX make it larger. */
331
332 if ((ifd = open(infile, O_RDONLY)) < 0) {
333 ast_log(LOG_WARNING, "Unable to open %s in read-only mode\n", infile);
334 return -1;
335 }
336 if ((ofd = open(outfile, O_WRONLY | O_TRUNC | O_CREAT, AST_FILE_MODE)) < 0) {
337 ast_log(LOG_WARNING, "Unable to open %s in write-only mode\n", outfile);
338 close(ifd);
339 return -1;
340 }
341 while ( (len = read(ifd, buf, sizeof(buf)) ) ) {
342 int res;
343 if (len < 0) {
344 ast_log(LOG_WARNING, "Read failed on %s: %s\n", infile, strerror(errno));
345 break;
346 }
347 /* XXX handle partial writes */
348 res = write(ofd, buf, len);
349 if (res != len) {
350 ast_log(LOG_WARNING, "Write failed on %s (%d of %d): %s\n", outfile, res, len, strerror(errno));
351 len = -1; /* error marker */
352 break;
353 }
354 }
355 close(ifd);
356 close(ofd);
357 if (len < 0) {
358 unlink(outfile);
359 return -1; /* error */
360 }
361 return 0; /* success */
362}
#define AST_FILE_MODE
Definition asterisk.h:32

References AST_FILE_MODE, ast_log, buf, errno, len(), and LOG_WARNING.

Referenced by filehelper().

◆ file_shutdown()

static void file_shutdown ( void  )
static

Definition at line 2148 of file file.c.

2149{
2153}
void ast_cli_unregister_multiple(void)
Definition ael_main.c:408
#define STASIS_MESSAGE_TYPE_CLEANUP(name)
Boiler-plate messaging macro for cleaning up message types.
Definition stasis.h:1546

References ARRAY_LEN, ast_cli_unregister_multiple(), ast_format_register_type(), ast_format_unregister_type(), cli_file, and STASIS_MESSAGE_TYPE_CLEANUP.

Referenced by ast_file_init().

◆ fileexists_core()

static int fileexists_core ( const char *  filename,
const char *  fmt,
const char *  preflang,
char *  buf,
int  buflen,
struct ast_format_cap *  result_cap 
)
static

helper routine to locate a file with a given format and language preference.

Note
Try preflang, preflang with stripped '_' suffices, or NULL.
The last parameter(s) point to a buffer of sufficient size, which on success is filled with the matching filename.
Parameters
filenameName of the file.
fmtFormat to look for the file in. OPTIONAL
preflangThe preferred language
bufReturns the matching filename
buflenSize of the buf
result_capOPTIONAL format capabilities result structure returns what formats the file was found in.
Return values
1true. file exists and result format is set
0false. file does not exist.

Definition at line 822 of file file.c.

824{
825 char *lang;
826
827 if (buf == NULL) {
828 return 0;
829 }
830
831 /* We try languages in the following order:
832 * preflang (may include dialect and style codes)
833 * lang (preflang without dialect - if any)
834 * <none>
835 * default (unless the same as preflang or lang without dialect)
836 */
837
838 lang = ast_strdupa(preflang);
839
840 /* Try preferred language, including removing any style or dialect codes */
841 while (!ast_strlen_zero(lang)) {
842 char *end;
843
844 if (fileexists_test(filename, fmt, lang, buf, buflen, result_cap)) {
845 return 1;
846 }
847
848 if ((end = strrchr(lang, '_')) != NULL) {
849 *end = '\0';
850 continue;
851 }
852
853 break;
854 }
855
856 /* Try without any language */
857 if (fileexists_test(filename, fmt, NULL, buf, buflen, result_cap)) {
858 return 1;
859 }
860
861 /* Finally try the default language unless it was already tried before */
862 if ((ast_strlen_zero(preflang) || strcmp(preflang, DEFAULT_LANGUAGE)) && (ast_strlen_zero(lang) || strcmp(lang, DEFAULT_LANGUAGE))) {
863 if ((fileexists_test(filename, fmt, DEFAULT_LANGUAGE, buf, buflen, result_cap)) > 0) {
864 return 1;
865 }
866 }
867
868 return 0;
869}
#define DEFAULT_LANGUAGE
Definition asterisk.h:46
char * end
Definition eagi_proxy.c:73
static int fileexists_test(const char *filename, const char *fmt, const char *lang, char *buf, int buflen, struct ast_format_cap *result_cap)
test if a file exists for a given format.
Definition file.c:772

References ast_strdupa, ast_strlen_zero(), buf, DEFAULT_LANGUAGE, end, fileexists_test(), ast_filestream::filename, ast_filestream::fmt, and NULL.

Referenced by ast_fileexists(), ast_openvstream(), and openstream_internal().

◆ fileexists_test()

static int fileexists_test ( const char *  filename,
const char *  fmt,
const char *  lang,
char *  buf,
int  buflen,
struct ast_format_cap *  result_cap 
)
static

test if a file exists for a given format.

Note
result_cap is OPTIONAL
Return values
1true and result_cap represents format capabilities file exists in.
0false

Definition at line 772 of file file.c.

774{
775 if (buf == NULL) {
776 return 0;
777 }
778
779 if (is_remote_path(filename) && !ast_media_cache_retrieve(filename, NULL, buf, buflen)) {
780 return filehelper(buf, result_cap, NULL, ACTION_EXISTS);
781 }
782
783 if (!is_absolute_path(filename)) {
784 if (lang) {
785 snprintf(buf, buflen, "%s/%s", lang, filename);
786 } else {
787 snprintf(buf, buflen, "%s", filename);
788 }
789 } else {
790 strcpy(buf, filename); /* first copy the full string */
791 if (lang) {
792 /* insert the language and suffix if needed */
793 const char *c = strrchr(filename, '/');
794 int offset = c ? c - filename + 1 : 0; /* points right after the last '/' */
795 snprintf(buf + offset, buflen - offset, "%s/%s", lang, filename + offset);
796 }
797 }
798
799 return filehelper(buf, result_cap, fmt, ACTION_EXISTS);
800}
static int is_remote_path(const char *filename)
Definition file.c:761
int ast_media_cache_retrieve(const char *uri, const char *preferred_file_name, char *file_path, size_t len)
Retrieve an item from the cache.

References ACTION_EXISTS, ast_media_cache_retrieve(), buf, c, filehelper(), ast_filestream::filename, ast_filestream::fmt, is_absolute_path(), is_remote_path(), and NULL.

Referenced by fileexists_core().

◆ filehelper()

static int filehelper ( const char *  filename,
const void *  arg2,
const char *  fmt,
const enum file_action  action 
)
static

Definition at line 618 of file file.c.

619{
620 struct ast_format_def *f;
621 int res = (action == ACTION_EXISTS) ? 0 : -1;
622
623 char *extension_start;
624 char *fn;
625
627
628 fn = build_filename_template(filename, &extension_start);
629 if (!fn) {
631 return res;
632 }
633
634 /* Check for a specific format */
636 char *ext = NULL;
637 char storage[strlen(f->exts) + 1];
638 char *stringp;
639
640 if (fmt && !exts_compare(f->exts, fmt))
641 continue;
642
643 /* Look for a file matching the supported extensions.
644 * The file must exist, and for OPEN, must match
645 * one of the formats supported by the channel.
646 */
647 strcpy(storage, f->exts); /* safe - this is in the stack so does not need to be freed */
648 stringp = storage;
649 while ( (ext = strsep(&stringp, "|")) ) {
650 struct stat st;
651
652 /* Append the extension to our template */
653 strcpy(extension_start, translate_extension(ext));
654
655 if ( stat(fn, &st) ) { /* file not existent */
656 continue;
657 }
658 /* for 'OPEN' we need to be sure that the format matches
659 * what the channel can process
660 */
661 if (action == ACTION_OPEN) {
662 struct ast_channel *chan = (struct ast_channel *)arg2;
663 FILE *bfile;
664 struct ast_filestream *s;
665
667 !(((ast_format_get_type(f->format) == AST_MEDIA_TYPE_AUDIO) && fmt) ||
668 ((ast_format_get_type(f->format) == AST_MEDIA_TYPE_VIDEO) && fmt))) {
669 ast_debug(3, "File %s format is not compatible with the channel\n", fn);
670 continue; /* not a supported format */
671 }
672 if ( (bfile = fopen(fn, "r")) == NULL) {
673 ast_log(LOG_WARNING, "Failed to open file %s due to: %s\n", fn, strerror(errno));
674 continue; /* cannot open file */
675 }
676 s = get_filestream(f, bfile);
677 if (!s) {
678 ast_log(LOG_WARNING, "Failed to open file %s due to: file stream creation failure\n", fn);
679 fclose(bfile);
680 continue; /* cannot allocate descriptor */
681 }
682 if (open_wrapper(s)) {
684 continue; /* cannot run open on file */
685 }
686 if (st.st_size == 0) {
687 ast_log(LOG_WARNING, "File %s detected to have zero size.\n", fn);
688 }
689 /* ok this is good for OPEN */
690 res = 1; /* found */
691 s->lasttimeout = -1;
692 s->fmt = f;
693 s->trans = NULL;
694 s->filename = NULL;
697 if (ast_channel_stream(chan))
699 ast_channel_stream_set(chan, s);
700 } else {
701 if (ast_channel_vstream(chan))
704 }
705 break;
706 }
707 switch (action) {
708 case ACTION_OPEN:
709 break; /* will never get here */
710
711 case ACTION_EXISTS: /* return the matching format */
712 /* if arg2 is present, it is a format capabilities structure.
713 * Add this format to the set of formats this file can be played in */
714 if (arg2) {
715 ast_format_cap_append((struct ast_format_cap *) arg2, f->format, 0);
716 }
717 res = 1; /* file does exist and format it exists in is returned in arg2 */
718 break;
719
720 case ACTION_DELETE:
721 if ( (res = unlink(fn)) )
722 ast_log(LOG_WARNING, "unlink(%s) failed: %s\n", fn, strerror(errno));
723 break;
724
725 case ACTION_RENAME:
726 case ACTION_COPY: {
727 char *nfn = build_filename((const char *)arg2, ext);
728 if (!nfn)
729 ast_log(LOG_WARNING, "Out of memory\n");
730 else {
731 res = action == ACTION_COPY ? copy(fn, nfn) : rename(fn, nfn);
732 if (res)
733 ast_log(LOG_WARNING, "%s(%s,%s) failed: %s\n",
734 action == ACTION_COPY ? "copy" : "rename",
735 fn, nfn, strerror(errno));
736 ast_free(nfn);
737 }
738 }
739 break;
740
741 default:
742 ast_log(LOG_WARNING, "Unknown helper %u\n", action);
743 }
744 }
745
746 /* If we have successfully opened a file, we are done. */
747 if (action == ACTION_OPEN && res == 1) {
748 break;
749 }
750 }
752 ast_free(fn);
753 return res;
754}
static char * build_filename_template(const char *filename, char **extension_start)
Definition file.c:377
static int copy(const char *infile, const char *outfile)
Definition file.c:327
#define ast_format_cap_append(cap, format, framing)
Add format capability to capabilities structure.
Definition format_cap.h:99
Main Channel structure associated with a channel.

References ACTION_COPY, ACTION_DELETE, ACTION_EXISTS, ACTION_OPEN, ACTION_RENAME, ast_channel_stream(), ast_channel_stream_set(), ast_channel_vstream(), ast_channel_vstream_set(), ast_channel_writeformat(), ast_closestream(), ast_debug, ast_format_cap_append, ast_format_cmp(), AST_FORMAT_CMP_NOT_EQUAL, ast_format_get_type(), ast_free, ast_log, AST_MEDIA_TYPE_AUDIO, AST_MEDIA_TYPE_VIDEO, AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_strdup, build_filename(), build_filename_template(), copy(), errno, ext, ast_format_def::exts, exts_compare, ast_filestream::f, ast_filestream::filename, ast_filestream::fmt, ast_format_def::format, get_filestream(), ast_filestream::lasttimeout, ast_format_def::list, LOG_WARNING, NULL, ast_filestream::open_extension, open_wrapper(), strsep(), ast_filestream::trans, and translate_extension().

Referenced by ast_filecopy(), ast_filedelete(), ast_filerename(), ast_openvstream(), fileexists_test(), and openstream_internal().

◆ filestream_close()

static void filestream_close ( struct ast_filestream *  f)
static

Definition at line 460 of file file.c.

461{
462 enum ast_media_type format_type = ast_format_get_type(f->fmt->format);
463
464 if (!f->owner) {
465 return;
466 }
467
468 /* Stop a running stream if there is one */
469 switch (format_type)
470 {
474 ast_settimeout(f->owner, 0, NULL, NULL);
475 break;
479 break;
480 default:
481 ast_log(AST_LOG_WARNING, "Unable to schedule deletion of filestream with unsupported type %s\n", f->fmt->name);
482 break;
483 }
484}
int ast_channel_vstreamid(const struct ast_channel *chan)
int ast_channel_streamid(const struct ast_channel *chan)
ast_media_type
Types of media.
Definition codec.h:30
#define AST_LOG_WARNING
#define AST_SCHED_DEL_ACCESSOR(sched, obj, getter, setter)
Definition sched.h:59

References ast_channel_sched(), ast_channel_stream_set(), ast_channel_streamid(), ast_channel_streamid_set(), ast_channel_vstream_set(), ast_channel_vstreamid(), ast_channel_vstreamid_set(), ast_format_get_type(), ast_log, AST_LOG_WARNING, AST_MEDIA_TYPE_AUDIO, AST_MEDIA_TYPE_VIDEO, AST_SCHED_DEL_ACCESSOR, ast_settimeout(), ast_filestream::fmt, ast_format_def::format, ast_format_def::name, NULL, and ast_filestream::owner.

Referenced by ast_closestream(), and filestream_destructor().

◆ filestream_destructor()

static void filestream_destructor ( void *  arg)
static

Definition at line 486 of file file.c.

487{
488 struct ast_filestream *f = arg;
489 int status;
490 int pid = -1;
491
492 /* Stop a running stream if there is one */
494
495 /* destroy the translator on exit */
496 if (f->trans)
498
499 if (f->fmt->close) {
500 void (*closefn)(struct ast_filestream *) = f->fmt->close;
501 closefn(f);
502 }
503
504 if (f->f) {
505 fclose(f->f);
506 }
507
508 if (f->realfilename && f->filename) {
509 pid = ast_safe_fork(0);
510 if (!pid) {
511 execl("/bin/mv", "mv", "-f", f->filename, f->realfilename, SENTINEL);
512 _exit(1);
513 }
514 else if (pid > 0) {
515 /* Block the parent until the move is complete.*/
516 waitpid(pid, &status, 0);
517 }
518 }
519
520 ast_free(f->filename);
521 ast_free(f->realfilename);
522 ast_free(f->open_extension);
523 if (f->vfs)
524 ast_closestream(f->vfs);
525 ast_free(f->write_buffer);
526 ast_free((void *)f->orig_chan_name);
527 ao2_cleanup(f->lastwriteformat);
528 ao2_cleanup(f->fr.subclass.format);
529 ast_module_unref(f->fmt->module);
530}
jack_status_t status
Definition app_jack.c:149
#define SENTINEL
Definition compiler.h:87
int ast_safe_fork(int stop_reaper)
Common routine to safely fork without a chance of a signal handler firing badly in the child.
Definition main/app.c:3208
#define ast_module_unref(mod)
Release a reference to the module.
Definition module.h:483

References ao2_cleanup, ast_closestream(), ast_free, ast_module_unref, ast_safe_fork(), ast_translator_free_path(), ast_filestream::f, filestream_close(), SENTINEL, and status.

Referenced by get_filestream().

◆ fn_wrapper()

static int fn_wrapper ( struct ast_filestream *  s,
const char *  comment,
enum wrap_fn  mode 
)
static

Definition at line 572 of file file.c.

573{
574 struct ast_format_def *f = s->fmt;
575 int ret = -1;
576 int (*openfn)(struct ast_filestream *s);
577
578 if (mode == WRAP_OPEN && (openfn = f->open) && openfn(s))
579 ast_log(LOG_WARNING, "Unable to open format %s\n", f->name);
580 else if (mode == WRAP_REWRITE && f->rewrite && f->rewrite(s, comment))
581 ast_log(LOG_WARNING, "Unable to rewrite format %s\n", f->name);
582 else {
583 /* preliminary checks succeed. */
584 ret = 0;
585 }
586 return ret;
587}

References ast_log, comment, ast_filestream::f, ast_filestream::fmt, LOG_WARNING, ast_filestream::mode, WRAP_OPEN, and WRAP_REWRITE.

Referenced by open_wrapper(), and rewrite_wrapper().

◆ get_filestream()

static struct ast_filestream * get_filestream ( struct ast_format_def *  fmt,
FILE *  bfile 
)
static

Definition at line 532 of file file.c.

533{
534 struct ast_filestream *s;
535 int l = sizeof(*s) + fmt->buf_size + fmt->desc_size; /* total allocation size */
536
537 if (!ast_module_running_ref(fmt->module)) {
538 return NULL;
539 }
540
542 if (!s) {
543 ast_module_unref(fmt->module);
544 return NULL;
545 }
546 s->fmt = fmt;
547 s->f = bfile;
548
549 if (fmt->desc_size)
550 s->_private = ((char *)(s + 1)) + fmt->buf_size;
551 if (fmt->buf_size)
552 s->buf = (char *)(s + 1);
553 s->fr.src = fmt->name;
554
559 }
560 s->fr.mallocd = 0;
562
563 return s;
564}
#define ao2_alloc(data_size, destructor_fn)
Definition astobj2.h:409
static void filestream_destructor(void *arg)
Definition file.c:486
#define ast_module_running_ref(mod)
Hold a reference to the module if it is running.
Definition module.h:469
struct ast_frame fr
frame produced by read, typically
Definition mod_format.h:122

References ast_filestream::_private, ao2_alloc, ao2_bump, ast_format_get_type(), AST_FRAME_VIDEO, AST_FRAME_VOICE, AST_MEDIA_TYPE_AUDIO, AST_MEDIA_TYPE_VIDEO, ast_module_running_ref, ast_module_unref, ast_filestream::buf, ast_format_def::buf_size, ast_format_def::desc_size, ast_filestream::f, filestream_destructor(), ast_filestream::fmt, ast_frame_subclass::format, ast_format_def::format, ast_filestream::fr, ast_frame::frametype, ast_frame::mallocd, ast_format_def::name, NULL, ast_frame::src, and ast_frame::subclass.

Referenced by ast_readfile(), ast_writefile(), and filehelper().

◆ handle_cli_core_show_file_formats()

static char * handle_cli_core_show_file_formats ( struct ast_cli_entry *  e,
int  cmd,
struct ast_cli_args *  a 
)
static

Definition at line 2074 of file file.c.

2075{
2076#define FORMAT "%-10s %-10s %-20s\n"
2077#define FORMAT2 "%-10s %-10s %-20s\n"
2078 struct ast_format_def *f;
2079 int count_fmt = 0;
2080
2081 switch (cmd) {
2082 case CLI_INIT:
2083 e->command = "core show file formats";
2084 e->usage =
2085 "Usage: core show file formats\n"
2086 " Displays currently registered file formats (if any).\n";
2087 return NULL;
2088 case CLI_GENERATE:
2089 return NULL;
2090 }
2091
2092 if (a->argc != 4)
2093 return CLI_SHOWUSAGE;
2094
2095 ast_cli(a->fd, FORMAT, "Format", "Name", "Extensions");
2096 ast_cli(a->fd, FORMAT, "------", "----", "----------");
2097
2100 ast_cli(a->fd, FORMAT2, ast_format_get_name(f->format), f->name, f->exts);
2101 count_fmt++;
2102 }
2104 ast_cli(a->fd, "%d file formats registered.\n", count_fmt);
2105 return CLI_SUCCESS;
2106#undef FORMAT
2107#undef FORMAT2
2108}
#define CLI_SHOWUSAGE
Definition cli.h:45
#define CLI_SUCCESS
Definition cli.h:44
void ast_cli(int fd, const char *fmt,...)
Definition clicompat.c:6
@ CLI_INIT
Definition cli.h:152
@ CLI_GENERATE
Definition cli.h:153
#define FORMAT
#define FORMAT2
char * command
Definition cli.h:186
const char * usage
Definition cli.h:177

References a, ast_cli(), ast_format_get_name(), AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_format_def::exts, ast_format_def::format, FORMAT, FORMAT2, ast_format_def::list, ast_format_def::name, NULL, and ast_cli_entry::usage.

◆ is_absolute_path()

static int is_absolute_path ( const char *  filename)
static

Definition at line 756 of file file.c.

757{
758 return filename[0] == '/';
759}

References ast_filestream::filename.

Referenced by ast_streamfile(), and fileexists_test().

◆ is_remote_path()

static int is_remote_path ( const char *  filename)
static

Definition at line 761 of file file.c.

762{
763 return strstr(filename, "://") ? 1 : 0;
764}

References ast_filestream::filename.

Referenced by fileexists_test().

◆ json_array_from_list()

static struct ast_json * json_array_from_list ( const char *  list,
const char *  sep 
)
static

Definition at line 63 of file file.c.

64{
66 char *stringp, *ext;
67
68 stringp = ast_strdupa(list); /* this is in the stack so does not need to be freed */
69 if (!array || !stringp) {
70 return NULL;
71 }
72
73 while ((ext = strsep(&stringp, sep))) {
75 return NULL;
76 }
77 }
78
79 return ast_json_ref(array);
80}
static int array(struct ast_channel *chan, const char *cmd, char *var, const char *value)
struct ast_json * ast_json_string_create(const char *value)
Construct a JSON string from value.
Definition json.c:278
int ast_json_array_append(struct ast_json *array, struct ast_json *value)
Append to an array.
Definition json.c:378
struct ast_json * ast_json_array_create(void)
Create a empty JSON array.
Definition json.c:362
struct ast_json * ast_json_ref(struct ast_json *value)
Increase refcount on value.
Definition json.c:67

References array(), ast_json_array_append(), ast_json_array_create(), ast_json_ref(), ast_json_string_create(), ast_json_unref(), ast_strdupa, ext, NULL, RAII_VAR, and strsep().

Referenced by publish_format_update().

◆ open_wrapper()

static int open_wrapper ( struct ast_filestream *  s)
static

Definition at line 594 of file file.c.

595{
596 return fn_wrapper(s, NULL, WRAP_OPEN);
597}
static int fn_wrapper(struct ast_filestream *s, const char *comment, enum wrap_fn mode)
Definition file.c:572

References fn_wrapper(), NULL, and WRAP_OPEN.

Referenced by ast_readfile(), and filehelper().

◆ openstream_internal()

static struct ast_filestream * openstream_internal ( struct ast_channel *  chan,
const char *  filename,
const char *  preflang,
int  asis,
int  quiet 
)
static

Definition at line 871 of file file.c.

873{
874 /*
875 * Use fileexists_core() to find a file in a compatible
876 * language and format, set up a suitable translator,
877 * and open the stream.
878 */
879 struct ast_format_cap *file_fmt_cap;
880 int res;
881 int buflen;
882 char *buf;
883
884 if (!asis) {
885 /* do this first, otherwise we detect the wrong writeformat */
886 ast_stopstream(chan);
887 if (ast_channel_generator(chan))
889 }
890 if (preflang == NULL)
891 preflang = "";
892 buflen = strlen(preflang) + strlen(filename) + 4;
893 buf = ast_alloca(buflen);
894
895 if (!(file_fmt_cap = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT))) {
896 return NULL;
897 }
898 if (!fileexists_core(filename, NULL, preflang, buf, buflen, file_fmt_cap) ||
900
901 if (!quiet) {
902 ast_log(LOG_WARNING, "File %s does not exist in any format\n", filename);
903 }
904 ao2_ref(file_fmt_cap, -1);
905 return NULL;
906 }
907
908 /* Set the channel to a format we can work with and save off the previous format. */
909 ast_channel_lock(chan);
911 /* Set the channel to the best format that exists for the file. */
912 res = ast_set_write_format_from_cap(chan, file_fmt_cap);
913 ast_channel_unlock(chan);
914 /* don't need this anymore now that the channel's write format is set. */
915 ao2_ref(file_fmt_cap, -1);
916
917 if (res == -1) { /* No format available that works with this channel */
918 return NULL;
919 }
920 res = filehelper(buf, chan, NULL, ACTION_OPEN);
921 if (res >= 0)
922 return ast_channel_stream(chan);
923 return NULL;
924}
static int quiet
Definition ael_main.c:123
void ast_channel_set_oldwriteformat(struct ast_channel *chan, struct ast_format *format)
void ast_deactivate_generator(struct ast_channel *chan)
Definition channel.c:2892
struct ast_generator * ast_channel_generator(const struct ast_channel *chan)
int ast_set_write_format_from_cap(struct ast_channel *chan, struct ast_format_cap *formats)
Sets write format on channel chan Set write format for channel to whichever component of "format" is ...
Definition channel.c:5844

References ACTION_OPEN, ao2_ref, ast_alloca, ast_channel_generator(), ast_channel_lock, ast_channel_set_oldwriteformat(), ast_channel_stream(), ast_channel_unlock, ast_channel_writeformat(), ast_deactivate_generator(), ast_format_cap_alloc, AST_FORMAT_CAP_FLAG_DEFAULT, ast_format_cap_has_type(), ast_log, AST_MEDIA_TYPE_AUDIO, ast_set_write_format_from_cap(), ast_stopstream(), buf, fileexists_core(), filehelper(), LOG_WARNING, NULL, and quiet.

Referenced by ast_openstream(), ast_openstream_full(), and ast_streamfile().

◆ publish_format_update()

static int publish_format_update ( const struct ast_format_def *  f,
struct stasis_message_type *  type 
)
static

Definition at line 82 of file file.c.

83{
84 RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
85 RAII_VAR(struct ast_json_payload *, json_payload, NULL, ao2_cleanup);
86 RAII_VAR(struct ast_json *, json_object, NULL, ast_json_unref);
87
88 if (!type) {
89 return -1;
90 }
91
92 json_object = ast_json_pack("{s: s, s: o}",
93 "format", f->name,
94 "extensions", json_array_from_list(f->exts, "|"));
95 if (!json_object) {
96 return -1;
97 }
98
99 json_payload = ast_json_payload_create(json_object);
100 if (!json_payload) {
101 return -1;
102 }
103
104 msg = stasis_message_create(type, json_payload);
105 if (!msg) {
106 return -1;
107 }
108
110 return 0;
111}
static struct ast_json * json_array_from_list(const char *list, const char *sep)
Definition file.c:63
struct ast_json_payload * ast_json_payload_create(struct ast_json *json)
Create an ao2 object to pass json blobs as data payloads for stasis.
Definition json.c:756
struct stasis_message * stasis_message_create(struct stasis_message_type *type, void *data)
Create a new message.
void stasis_publish(struct stasis_topic *topic, struct stasis_message *message)
Publish a message to a topic's subscribers.
Definition stasis.c:1589
struct stasis_topic * ast_system_topic(void)
A Stasis Message Bus API topic which publishes messages regarding system changes.

References ao2_cleanup, ast_json_pack(), ast_json_payload_create(), ast_json_unref(), ast_system_topic(), ast_format_def::exts, json_array_from_list(), ast_format_def::name, NULL, RAII_VAR, stasis_message_create(), stasis_publish(), and type.

Referenced by __ast_format_def_register(), and ast_format_def_unregister().

◆ read_frame()

static struct ast_frame * read_frame ( struct ast_filestream *  s,
int *  whennext 
)
static

Definition at line 1000 of file file.c.

1001{
1002 struct ast_frame *fr, *new_fr;
1003
1004 if (!s || !s->fmt) {
1005 return NULL;
1006 }
1007
1008 if (!(fr = s->fmt->read(s, whennext))) {
1009 return NULL;
1010 }
1011
1012 if (!(new_fr = ast_frisolate(fr))) {
1013 ast_frfree(fr);
1014 return NULL;
1015 }
1016
1017 if (new_fr != fr) {
1018 ast_frfree(fr);
1019 fr = new_fr;
1020 }
1021
1022 return fr;
1023}
#define ast_frisolate(fr)
Makes a frame independent of any static storage.
struct ast_frame *(* read)(struct ast_filestream *, int *whennext)
Definition mod_format.h:74

References ast_frfree, ast_frisolate, ast_filestream::fmt, NULL, and ast_format_def::read.

Referenced by ast_audiohook_read_frame_all(), ast_readaudio_callback(), ast_readframe(), ast_readvideo_callback(), and audiohook_read_frame_helper().

◆ rewrite_wrapper()

static int rewrite_wrapper ( struct ast_filestream *  s,
const char *  comment 
)
static

Definition at line 589 of file file.c.

590{
591 return fn_wrapper(s, comment, WRAP_REWRITE);
592}

References comment, fn_wrapper(), and WRAP_REWRITE.

Referenced by ast_writefile().

◆ sanitize_waitstream_return()

static int sanitize_waitstream_return ( int  return_value)
static

Definition at line 1927 of file file.c.

1928{
1929 switch (return_value) {
1933 /* Fall through and set return_value to 0 */
1934 return_value = 0;
1935 break;
1936 default:
1937 /* Do nothing */
1938 break;
1939 }
1940
1941 return return_value;
1942}
@ AST_CONTROL_STREAM_RESTART
@ AST_CONTROL_STREAM_SUSPEND
@ AST_CONTROL_STREAM_STOP

References AST_CONTROL_STREAM_RESTART, AST_CONTROL_STREAM_STOP, and AST_CONTROL_STREAM_SUSPEND.

Referenced by ast_waitstream(), ast_waitstream_exten(), and ast_waitstream_full().

◆ STASIS_MESSAGE_TYPE_DEFN() [1/2]

STASIS_MESSAGE_TYPE_DEFN ( ast_format_register_type  )

◆ STASIS_MESSAGE_TYPE_DEFN() [2/2]

STASIS_MESSAGE_TYPE_DEFN ( ast_format_unregister_type  )

◆ translate_extension()

static const char * translate_extension ( const char *  extension)
static

Definition at line 407 of file file.c.

408{
409 /* The wav49 -> WAV translation is duplicated in apps/app_mixmonitor.c, so
410 if you change it here you need to change it there as well */
411 if (!strcmp(extension, "wav49")) {
412 return "WAV";
413 }
414 return extension;
415}
structure to hold extensions

Referenced by build_filename(), and filehelper().

◆ type_in_list()

static int type_in_list ( const char *  list,
const char *  type,
int(*)(const char *s1, const char *s2)  cmp 
)
static

Definition at line 441 of file file.c.

442{
443 char *stringp = ast_strdupa(list), *item;
444
445 while ((item = strsep(&stringp, "|"))) {
446 if (!cmp(item, type)) {
447 return 1;
448 }
449 }
450
451 return 0;
452}
static struct aco_type item

References ast_strdupa, item, strsep(), and type.

Referenced by ast_get_extension_for_mime_type().

◆ waitstream_control()

static void waitstream_control ( struct ast_channel *  c,
enum ast_waitstream_fr_cb_values  type,
ast_waitstream_fr_cb  cb,
int  skip_ms 
)
static

Definition at line 1675 of file file.c.

1679{
1680 switch (type)
1681 {
1683 {
1684 int eoftest;
1686 eoftest = fgetc(ast_channel_stream(c)->f);
1687 if (feof(ast_channel_stream(c)->f)) {
1689 } else {
1690 ungetc(eoftest, ast_channel_stream(c)->f);
1691 }
1692 }
1693 break;
1696 break;
1697 default:
1698 break;
1699 }
1700
1701 if (cb) {
1702 long ms_len = ast_tellstream(ast_channel_stream(c)) / (ast_format_get_sample_rate(ast_channel_stream(c)->fmt->format) / 1000);
1703 cb(c, ms_len, type);
1704 }
1705
1706 ast_test_suite_event_notify("PLAYBACK","Channel: %s\r\n"
1707 "Control: %s\r\n"
1708 "SkipMs: %d\r\n",
1710 (type == AST_WAITSTREAM_CB_FASTFORWARD) ? "FastForward" : "Rewind",
1711 skip_ms);
1712}
int ast_stream_rewind(struct ast_filestream *fs, off_t ms)
Rewind stream ms.
Definition file.c:1189
int ast_stream_fastforward(struct ast_filestream *fs, off_t ms)
Fast forward stream ms.
Definition file.c:1184
@ AST_WAITSTREAM_CB_FASTFORWARD
Definition file.h:56
@ AST_WAITSTREAM_CB_REWIND
Definition file.h:55

References ast_channel_name(), ast_channel_stream(), ast_format_get_sample_rate(), ast_stream_fastforward(), ast_stream_rewind(), ast_tellstream(), ast_test_suite_event_notify, AST_WAITSTREAM_CB_FASTFORWARD, AST_WAITSTREAM_CB_REWIND, c, ast_filestream::f, ast_filestream::fmt, ast_format_def::format, and type.

Referenced by waitstream_core().

◆ waitstream_core()

static int waitstream_core ( struct ast_channel *  c,
const char *  breakon,
const char *  forward,
const char *  reverse,
int  skip_ms,
int  audiofd,
int  cmdfd,
const char *  context,
ast_waitstream_fr_cb  cb 
)
static

the core of all waitstream() functions

Definition at line 1717 of file file.c.

1726{
1727 const char *orig_chan_name = NULL;
1728
1729 int err = 0;
1730
1731 if (!breakon)
1732 breakon = "";
1733 if (!forward)
1734 forward = "";
1735 if (!reverse)
1736 reverse = "";
1737
1738 /* Switch the channel to end DTMF frame only. waitstream_core doesn't care about the start of DTMF. */
1740
1742 orig_chan_name = ast_strdupa(ast_channel_name(c));
1743
1744 if (ast_channel_stream(c) && cb) {
1745 long ms_len = ast_tellstream(ast_channel_stream(c)) / (ast_format_get_sample_rate(ast_channel_stream(c)->fmt->format) / 1000);
1746 cb(c, ms_len, AST_WAITSTREAM_CB_START);
1747 }
1748
1749 while (ast_channel_stream(c)) {
1750 int res;
1751 int ms;
1752
1753 if (orig_chan_name && strcasecmp(orig_chan_name, ast_channel_name(c))) {
1755 err = 1;
1756 break;
1757 }
1758
1760
1761 if (ms < 0 && !ast_channel_timingfunc(c)) {
1763 break;
1764 }
1765 if (ms < 0)
1766 ms = 1000;
1767 if (cmdfd < 0) {
1768 res = ast_waitfor(c, ms);
1769 if (res < 0) {
1770 ast_log(LOG_WARNING, "Select failed (%s)\n", strerror(errno));
1772 return res;
1773 }
1774 } else {
1775 int outfd;
1776 struct ast_channel *rchan = ast_waitfor_nandfds(&c, 1, &cmdfd, (cmdfd > -1) ? 1 : 0, NULL, &outfd, &ms);
1777 if (!rchan && (outfd < 0) && (ms)) {
1778 /* Continue */
1779 if (errno == EINTR)
1780 continue;
1781 ast_log(LOG_WARNING, "Wait failed (%s)\n", strerror(errno));
1783 return -1;
1784 } else if (outfd > -1) { /* this requires cmdfd set */
1785 /* The FD we were watching has something waiting */
1787 return 1;
1788 }
1789 /* if rchan is set, it is 'c' */
1790 res = rchan ? 1 : 0; /* map into 'res' values */
1791 }
1792 if (res > 0) {
1793 struct ast_frame *fr = ast_read(c);
1794 if (!fr) {
1796 return -1;
1797 }
1798 switch (fr->frametype) {
1799 case AST_FRAME_DTMF_END:
1800 if (context) {
1801 const char exten[2] = { fr->subclass.integer, '\0' };
1802 if (ast_exists_extension(c, context, exten, 1,
1803 S_COR(ast_channel_caller(c)->id.number.valid, ast_channel_caller(c)->id.number.str, NULL))) {
1804 res = fr->subclass.integer;
1805 ast_frfree(fr);
1807 return res;
1808 }
1809 } else {
1810 res = fr->subclass.integer;
1811 if (strchr(forward, res)) {
1813 } else if (strchr(reverse, res)) {
1815 } else if (strchr(breakon, res)) {
1816 ast_test_suite_event_notify("PLAYBACK","Channel: %s\r\n"
1817 "Control: %s\r\n",
1819 "Break");
1820
1821 ast_frfree(fr);
1823 return res;
1824 }
1825 }
1826 break;
1827 case AST_FRAME_CONTROL:
1828 switch (fr->subclass.integer) {
1832 /* Fall-through and break out */
1833 ast_test_suite_event_notify("PLAYBACK","Channel: %s\r\n"
1834 "Control: %s\r\n",
1836 "Break");
1837 res = fr->subclass.integer;
1838 ast_frfree(fr);
1840 return res;
1842 if (!skip_ms) {
1843 skip_ms = 3000;
1844 }
1846 break;
1848 if (!skip_ms) {
1849 skip_ms = 3000;
1850 }
1852 break;
1853 case AST_CONTROL_HANGUP:
1854 case AST_CONTROL_BUSY:
1856 ast_frfree(fr);
1858 return -1;
1861 case AST_CONTROL_ANSWER:
1865 case AST_CONTROL_HOLD:
1866 case AST_CONTROL_UNHOLD:
1869 case AST_CONTROL_AOC:
1872 case AST_CONTROL_FLASH:
1873 case AST_CONTROL_WINK:
1874 case -1:
1875 /* Unimportant */
1876 break;
1877 default:
1878 ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", fr->subclass.integer);
1879 }
1880 break;
1881 case AST_FRAME_VOICE:
1882 /* Write audio if appropriate */
1883 if (audiofd > -1) {
1884 if (write(audiofd, fr->data.ptr, fr->datalen) < 0) {
1885 ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
1886 }
1887 }
1888 default:
1889 /* Ignore all others */
1890 break;
1891 }
1892 ast_frfree(fr);
1893 }
1895 }
1896
1898
1899 return (err || ast_channel_softhangup_internal_flag(c)) ? -1 : 0;
1900}
struct ast_channel * ast_waitfor_nandfds(struct ast_channel **c, int n, int *fds, int nfds, int *exception, int *outfd, int *ms)
Waits for activity on a group of channels.
Definition channel.c:2992
void ast_channel_clear_flag(struct ast_channel *chan, unsigned int flag)
Clear a flag on a channel.
Definition channel.c:11214
@ AST_FLAG_END_DTMF_ONLY
Definition channel.h:1027
int ast_waitfor(struct ast_channel *chan, int ms)
Wait for input on a channel.
Definition channel.c:3166
struct ast_frame * ast_read(struct ast_channel *chan)
Reads a frame.
Definition channel.c:4278
void ast_channel_set_flag(struct ast_channel *chan, unsigned int flag)
Set a flag on a channel.
Definition channel.c:11207
ast_timing_func_t ast_channel_timingfunc(const struct ast_channel *chan)
int ast_channel_softhangup_internal_flag(struct ast_channel *chan)
struct ast_party_caller * ast_channel_caller(struct ast_channel *chan)
static void waitstream_control(struct ast_channel *c, enum ast_waitstream_fr_cb_values type, ast_waitstream_fr_cb cb, int skip_ms)
Definition file.c:1675
@ AST_WAITSTREAM_CB_START
Definition file.h:57
@ AST_FRAME_DTMF_END
@ AST_FRAME_CONTROL
@ AST_CONTROL_SRCUPDATE
@ AST_CONTROL_PROGRESS
@ AST_CONTROL_UNHOLD
@ AST_CONTROL_VIDUPDATE
@ AST_CONTROL_STREAM_REVERSE
@ AST_CONTROL_REDIRECTING
@ AST_CONTROL_CONGESTION
@ AST_CONTROL_ANSWER
@ AST_CONTROL_RINGING
@ AST_CONTROL_HANGUP
@ AST_CONTROL_CONNECTED_LINE
@ AST_CONTROL_STREAM_FORWARD
@ AST_CONTROL_FLASH
@ AST_CONTROL_SRCCHANGE
@ AST_CONTROL_PVT_CAUSE_CODE
@ AST_CONTROL_UPDATE_RTP_PEER
int ast_exists_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Determine whether an extension exists.
Definition pbx.c:2735
int ast_sched_runq(struct ast_sched_context *con)
Runs the queue.
Definition sched.c:786
int ast_sched_wait(struct ast_sched_context *con) attribute_warn_unused_result
Determines number of seconds until the next outstanding event to take place.
Definition sched.c:433
#define S_COR(a, b, c)
returns the equivalent of logic or for strings, with an additional boolean check: second one if not e...
Definition strings.h:87
union ast_frame::@237 data
Number structure.

References ast_channel_caller(), ast_channel_clear_flag(), ast_channel_flags(), ast_channel_name(), ast_channel_sched(), ast_channel_set_flag(), ast_channel_softhangup_internal_flag(), ast_channel_stream(), ast_channel_timingfunc(), AST_CONTROL_ANSWER, AST_CONTROL_AOC, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_CONNECTED_LINE, AST_CONTROL_FLASH, AST_CONTROL_HANGUP, AST_CONTROL_HOLD, AST_CONTROL_PROGRESS, AST_CONTROL_PVT_CAUSE_CODE, AST_CONTROL_REDIRECTING, AST_CONTROL_RINGING, AST_CONTROL_SRCCHANGE, AST_CONTROL_SRCUPDATE, AST_CONTROL_STREAM_FORWARD, AST_CONTROL_STREAM_RESTART, AST_CONTROL_STREAM_REVERSE, AST_CONTROL_STREAM_STOP, AST_CONTROL_STREAM_SUSPEND, AST_CONTROL_UNHOLD, AST_CONTROL_UPDATE_RTP_PEER, AST_CONTROL_VIDUPDATE, AST_CONTROL_WINK, ast_exists_extension(), AST_FLAG_END_DTMF_ONLY, AST_FLAG_MASQ_NOSTREAM, ast_format_get_sample_rate(), AST_FRAME_CONTROL, AST_FRAME_DTMF_END, AST_FRAME_VOICE, ast_frfree, ast_log, ast_read(), ast_sched_runq(), ast_sched_wait(), ast_stopstream(), ast_strdupa, ast_tellstream(), ast_test_flag, ast_test_suite_event_notify, ast_waitfor(), ast_waitfor_nandfds(), AST_WAITSTREAM_CB_FASTFORWARD, AST_WAITSTREAM_CB_REWIND, AST_WAITSTREAM_CB_START, c, ast_frame::data, ast_frame::datalen, errno, ast_filestream::fmt, ast_format_def::format, ast_frame::frametype, ast_frame_subclass::integer, LOG_WARNING, NULL, ast_filestream::orig_chan_name, ast_frame::ptr, S_COR, ast_frame::subclass, and waitstream_control().

Referenced by ast_waitstream(), ast_waitstream_exten(), ast_waitstream_fr(), ast_waitstream_fr_w_cb(), and ast_waitstream_full().

Variable Documentation

◆ cli_file

struct ast_cli_entry cli_file[]
static
Initial value:
= {
{ .handler = handle_cli_core_show_file_formats , .summary = "Displays file formats" ,}
}
static char * handle_cli_core_show_file_formats(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
Definition file.c:2074

Definition at line 2144 of file file.c.

2144 {
2145 AST_CLI_DEFINE(handle_cli_core_show_file_formats, "Displays file formats")
2146};
#define AST_CLI_DEFINE(fn, txt,...)
Definition cli.h:197

Referenced by ast_file_init(), and file_shutdown().

◆ formats

◆ maximum_extension_length

unsigned maximum_extension_length
static

Space required to store the longest extension from all registered file formats.

Stores the length, in bytes, of the longest extension from all registered file formats (struct ast_format_def). This is only updated during registration because it was easier to implement this way and only wastes a few bytes in the worst case.

Note
Protected by the formats list lock.

Definition at line 122 of file file.c.

Referenced by __ast_format_def_register(), and build_filename_template().

◆ read_dirs_lock

ast_mutex_t read_dirs_lock = AST_MUTEX_INIT_VALUE
static

Lock to hold when iterating over directories.

Currently, 'readdir' is not required to be thread-safe. In most modern implementations it should be safe to make concurrent calls into 'readdir' that specify different directory streams (glibc would be one of these). However, since it is potentially unsafe for some implementations we'll use our own locking in order to achieve synchronization for those.

Definition at line 1360 of file file.c.

Referenced by ast_file_read_dirs().