Asterisk - The Open Source Telephony Project GIT-master-5750f7c
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

int ast_language_is_prefix = 1
 The following variable controls the layout of localized sound files. If 0, use the historical layout with prefix just before the filename (i.e. digits/en/1.gsm , digits/it/1.gsm or default to digits/1.gsm), if 1 put the prefix at the beginning of the filename (i.e. en/digits/1.gsm, it/digits/1.gsm or default to digits/1.gsm). The latter permits a language to be entirely in one directory.
 
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 466 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 610 of file file.c.

610 {
611 ACTION_EXISTS = 1, /* return matching format if file exists, 0 otherwise */
612 ACTION_DELETE, /* delete file, return 0 on success, -1 on error */
613 ACTION_RENAME, /* rename file. return 0 on success, -1 on error */
615 ACTION_COPY /* copy file. return 0 on success, -1 on error */
616};
@ ACTION_OPEN
Definition file.c:614
@ ACTION_EXISTS
Definition file.c:611
@ ACTION_COPY
Definition file.c:615
@ ACTION_DELETE
Definition file.c:612
@ ACTION_RENAME
Definition file.c:613

◆ fsread_res

enum fsread_res
Enumerator
FSREAD_FAILURE 
FSREAD_SUCCESS_SCHED 
FSREAD_SUCCESS_NOSCHED 

Definition at line 1042 of file file.c.

1042 {
1046};
@ FSREAD_FAILURE
Definition file.c:1043
@ FSREAD_SUCCESS_SCHED
Definition file.c:1044
@ FSREAD_SUCCESS_NOSCHED
Definition file.c:1045

◆ wrap_fn

enum wrap_fn
Enumerator
WRAP_OPEN 
WRAP_REWRITE 

Definition at line 581 of file file.c.

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

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 1255 of file file.c.

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

137{
138 struct ast_format_def *tmp;
139
142 if (!strcasecmp(f->name, tmp->name)) {
144 ast_log(LOG_WARNING, "Tried to register '%s' format, already registered\n", f->name);
145 return -1;
146 }
147 }
148 if (!(tmp = ast_calloc(1, sizeof(*tmp)))) {
150 return -1;
151 }
152 *tmp = *f;
153 tmp->module = mod;
154 if (tmp->buf_size) {
155 /*
156 * Align buf_size properly, rounding up to the machine-specific
157 * alignment for pointers.
158 */
159 struct _test_align { void *a, *b; } p;
160 int align = (char *)&p.b - (char *)&p.a;
161 tmp->buf_size = ((f->buf_size + align - 1) / align) * align;
162 }
163
164 memset(&tmp->list, 0, sizeof(tmp->list));
165
166 /* Calculate the maximum extension length */
167 {
168 char *storage = ast_strdupa(tmp->exts);
169 char *stringp = storage;
170 const char *ext;
171
172 while ((ext = strsep(&stringp, "|"))) {
174 }
175 }
176
177 AST_RWLIST_INSERT_HEAD(&formats, tmp, list);
179 ast_verb(5, "Registered file format %s, extension(s) %s\n", f->name, f->exts);
181
182 return 0;
183}
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:134
static int publish_format_update(const struct ast_format_def *f, struct stasis_message_type *type)
Definition file.c:94
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:70
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 1156 of file file.c.

1157{
1158 s->owner = chan;
1159 return 0;
1160}
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 1210 of file file.c.

1211{
1212 /* This used to destroy the filestream, but it now just decrements a refcount.
1213 * We close the stream in order to quit queuing frames now, because we might
1214 * change the writeformat, which could result in a subsequent write error, if
1215 * the format is different. */
1216 if (f == NULL) {
1217 return 0;
1218 }
1220 ao2_ref(f, -1);
1221 return 0;
1222}
#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:472

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 225 of file file.c.

226{
227 int fd;
228
229 if (ast_asprintf(filename, "%s/%s", path, template_name) < 0) {
230 ast_log(LOG_ERROR, "Failed to set up temporary file path\n");
231 return -1;
232 }
233
234 ast_mkdir(path, 0644);
235
236 if ((fd = mkstemp(*filename)) < 0) {
237 ast_log(LOG_NOTICE, "Failed to create temporary file\n");
238 ast_free(*filename);
239 return -1;
240 }
241
242 return fd;
243}
#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 2165 of file file.c.

2166{
2171 return 0;
2172}
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:2158
static struct ast_cli_entry cli_file[]
Definition file.c:2154
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 210 of file file.c.

211{
212 FILE *p = NULL;
213 int pfd = mkstemp(template_name);
214 chmod(template_name, mode);
215 if (pfd > -1) {
216 p = fdopen(pfd, "w+");
217 if (!p) {
218 close(pfd);
219 pfd = -1;
220 }
221 }
222 return p;
223}

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 1373 of file file.c.

1374{
1375 int res;
1376
1377 errno = 0;
1378
1379#if !defined(__GLIBC__)
1381#endif
1382
1383 res = __ast_file_read_dirs(dir_name, on_file, obj, max_depth);
1384
1385#if !defined(__GLIBC__)
1387#endif
1388
1389 return res;
1390}
static ast_mutex_t read_dirs_lock
Lock to hold when iterating over directories.
Definition file.c:1370
#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 1250 of file file.c.

1251{
1252 return filehelper(filename, filename2, fmt, ACTION_COPY);
1253}
static int filehelper(const char *filename, const void *arg2, const char *fmt, const enum file_action action)
Definition file.c:629

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 1240 of file file.c.

1241{
1242 return filehelper(filename, NULL, fmt, ACTION_DELETE);
1243}

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 1228 of file file.c.

1229{
1230 char *buf;
1231 int buflen;
1232
1233 if (preflang == NULL)
1234 preflang = "";
1235 buflen = strlen(preflang) + strlen(filename) + 4; /* room for everything */
1236 buf = ast_alloca(buflen);
1237 return fileexists_core(filename, fmt, preflang, buf, buflen, NULL) ? 1 : 0;
1238}
#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:832

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 1245 of file file.c.

1246{
1247 return filehelper(filename, filename2, fmt, ACTION_RENAME);
1248}

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 185 of file file.c.

186{
187 struct ast_format_def *tmp;
188 int res = -1;
189
192 if (!strcasecmp(name, tmp->name)) {
195 ast_free(tmp);
196 res = 0;
197 }
198 }
201
202 if (!res)
203 ast_verb(5, "Unregistered format %s\n", name);
204 else
205 ast_log(LOG_WARNING, "Tried to unregister format %s, already unregistered\n", name);
206
207 return res;
208}
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 2008 of file file.c.

2009{
2010 struct ast_format_def *f;
2011 struct ast_format_def *fmts_ptr[AST_MAX_FORMATS];
2012 char *fmts_str[AST_MAX_FORMATS];
2013 char *stringp, *type;
2014 char *orig = fmts;
2015 int i, j, x, first, found = 0;
2016 int len = strlen(fmts) + 1;
2017 int res;
2018
2019 if (AST_RWLIST_RDLOCK(&formats)) {
2020 ast_log(LOG_WARNING, "Unable to lock format list\n");
2021 return NULL;
2022 }
2023
2024 stringp = ast_strdupa(fmts);
2025
2026 for (x = 0; (type = strsep(&stringp, "|")) && x < AST_MAX_FORMATS; x++) {
2028 if (exts_compare(f->exts, type)) {
2029 found = 1;
2030 break;
2031 }
2032 }
2033
2034 fmts_str[x] = type;
2035 if (found) {
2036 fmts_ptr[x] = f;
2037 } else {
2038 fmts_ptr[x] = NULL;
2039 }
2040 }
2042
2043 first = 1;
2044 for (i = 0; i < x; i++) {
2045 /* ignore invalid entries */
2046 if (!fmts_ptr[i]) {
2047 ast_log(LOG_WARNING, "ignoring unknown format '%s'\n", fmts_str[i]);
2048 continue;
2049 }
2050
2051 /* special handling for the first entry */
2052 if (first) {
2053 res = snprintf(fmts, len, "%s", fmts_str[i]);
2054 fmts += res;
2055 len -= res;
2056 first = 0;
2057 continue;
2058 }
2059
2060 found = 0;
2061 for (j = 0; j < i; j++) {
2062 /* this is a duplicate */
2063 if (fmts_ptr[j] == fmts_ptr[i]) {
2064 found = 1;
2065 break;
2066 }
2067 }
2068
2069 if (!found) {
2070 res = snprintf(fmts, len, "|%s", fmts_str[i]);
2071 fmts += res;
2072 len -= res;
2073 }
2074 }
2075
2076 if (first) {
2077 ast_log(LOG_WARNING, "no known formats found in format list (%s)\n", orig);
2078 return NULL;
2079 }
2080
2081 return orig;
2082}
struct sla_ringing_trunk * first
Definition app_sla.c:338
static const char type[]
#define exts_compare(list, type)
Definition file.c:466
#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 1098 of file file.c.

1099{
1100 struct ast_filestream *fs = (struct ast_filestream *)data;
1101 enum fsread_res res;
1102
1103 res = ast_readaudio_callback(fs);
1104
1105 if (res == FSREAD_SUCCESS_SCHED)
1106 return 1;
1107
1108 return 0;
1109}
fsread_res
Definition file.c:1042
static enum fsread_res ast_readaudio_callback(struct ast_filestream *s)
Definition file.c:1050
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 1143 of file file.c.

1144{
1145 struct ast_filestream *fs = (struct ast_filestream *)data;
1146 enum fsread_res res;
1147
1148 res = ast_readvideo_callback(fs);
1149
1150 if (res == FSREAD_SUCCESS_SCHED)
1151 return 1;
1152
1153 return 0;
1154}
static enum fsread_res ast_readvideo_callback(struct ast_filestream *s)
Definition file.c:1113

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 2133 of file file.c.

2134{
2135 struct ast_format_def *f;
2137
2138 ast_assert(buffer && capacity);
2139
2141 if (type_in_list(f->mime_types, mime_type, strcasecmp)) {
2142 size_t item_len = strcspn(f->exts, "|");
2143 size_t bytes_written = snprintf(buffer, capacity, ".%.*s", (int) item_len, f->exts);
2144 if (bytes_written < capacity) {
2145 /* Only return success if we didn't truncate */
2146 return 1;
2147 }
2148 }
2149 }
2150
2151 return 0;
2152}
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:453
#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:70
#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 2120 of file file.c.

2121{
2122 struct ast_format_def *f;
2125 if (exts_compare(f->exts, file_ext)) {
2126 return f->format;
2127 }
2128 }
2129
2130 return NULL;
2131}
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 936 of file file.c.

937{
938 return openstream_internal(chan, filename, preflang, 0, 0);
939}
static struct ast_filestream * openstream_internal(struct ast_channel *chan, const char *filename, const char *preflang, int asis, int quiet)
Definition file.c:881

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 941 of file file.c.

943{
944 return openstream_internal(chan, filename, preflang, asis, 0);
945}

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 947 of file file.c.

949{
950 /* As above, but for video. But here we don't have translators
951 * so we must enforce a format.
952 */
953 struct ast_format_cap *nativeformats, *tmp_cap;
954 char *buf;
955 int buflen;
956 int i, fd;
957
958 if (preflang == NULL) {
959 preflang = "";
960 }
961 buflen = strlen(preflang) + strlen(filename) + 4;
962 buf = ast_alloca(buflen);
963
964 ast_channel_lock(chan);
965 nativeformats = ao2_bump(ast_channel_nativeformats(chan));
966 ast_channel_unlock(chan);
967
968 /* is the channel capable of video without translation ?*/
969 if (!ast_format_cap_has_type(nativeformats, AST_MEDIA_TYPE_VIDEO)) {
970 ao2_cleanup(nativeformats);
971 return NULL;
972 }
974 ao2_cleanup(nativeformats);
975 return NULL;
976 }
977 /* Video is supported, so see what video formats exist for this file */
978 if (!fileexists_core(filename, NULL, preflang, buf, buflen, tmp_cap)) {
979 ao2_ref(tmp_cap, -1);
980 ao2_cleanup(nativeformats);
981 return NULL;
982 }
983
984 /* iterate over file formats and pick the first one compatible with the channel's native formats */
985 for (i = 0; i < ast_format_cap_count(tmp_cap); ++i) {
986 struct ast_format *format = ast_format_cap_get_format(tmp_cap, i);
987
988 if ((ast_format_get_type(format) != AST_MEDIA_TYPE_VIDEO) ||
989 !ast_format_cap_iscompatible(nativeformats, tmp_cap)) {
990 ao2_ref(format, -1);
991 continue;
992 }
993
994 fd = filehelper(buf, chan, ast_format_get_name(format), ACTION_OPEN);
995 if (fd >= 0) {
996 ao2_ref(format, -1);
997 ao2_ref(tmp_cap, -1);
998 ao2_cleanup(nativeformats);
999 return ast_channel_vstream(chan);
1000 }
1001 ast_log(LOG_WARNING, "File %s has video but couldn't be opened\n", filename);
1002 ao2_ref(format, -1);
1003 }
1004 ao2_ref(tmp_cap, -1);
1005 ao2_cleanup(nativeformats);
1006
1007 return NULL;
1008}
#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 1162 of file file.c.

1163{
1164 enum fsread_res res;
1165
1167 res = ast_readaudio_callback(s);
1168 else
1169 res = ast_readvideo_callback(s);
1170
1171 return (res == FSREAD_FAILURE) ? -1 : 0;
1172}
@ 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 1189 of file file.c.

1190{
1192}
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 1050 of file file.c.

1051{
1052 int whennext = 0;
1053
1054 while (!whennext) {
1055 struct ast_frame *fr;
1056
1057 if (s->orig_chan_name && strcasecmp(ast_channel_name(s->owner), s->orig_chan_name)) {
1058 goto return_failure;
1059 }
1060
1061 fr = read_frame(s, &whennext);
1062
1063 if (!fr /* stream complete */ || ast_write(s->owner, fr) /* error writing */) {
1064 if (fr) {
1065 ast_debug(2, "Failed to write frame\n");
1066 ast_frfree(fr);
1067 }
1068 goto return_failure;
1069 }
1070
1071 if (fr) {
1072 ast_frfree(fr);
1073 }
1074 }
1075
1076 if (whennext != s->lasttimeout) {
1077 if (ast_channel_timingfd(s->owner) > -1) {
1078 float samp_rate = (float) ast_format_get_sample_rate(s->fmt->format);
1079 unsigned int rate;
1080
1081 rate = (unsigned int) roundf(samp_rate / ((float) whennext));
1082
1084 } else {
1086 }
1087 s->lasttimeout = whennext;
1089 }
1090 return FSREAD_SUCCESS_SCHED;
1091
1092return_failure:
1094 ast_settimeout(s->owner, 0, NULL, NULL);
1095 return FSREAD_FAILURE;
1096}
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:1098
static struct ast_frame * read_frame(struct ast_filestream *s, int *whennext)
Definition file.c:1010
#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 1485 of file file.c.

1486{
1487 FILE *bfile;
1488 struct ast_format_def *f;
1489 struct ast_filestream *fs = NULL;
1490 char *fn;
1491 int format_found = 0;
1492
1494
1495 AST_RWLIST_TRAVERSE(&formats, f, list) {
1496 fs = NULL;
1497 if (!exts_compare(f->exts, type))
1498 continue;
1499 else
1500 format_found = 1;
1501
1503 if (!fn) {
1504 continue;
1505 }
1506 errno = 0;
1507 bfile = fopen(fn, "r");
1508
1509 if (!bfile || (fs = get_filestream(f, bfile)) == NULL || open_wrapper(fs) ) {
1510 ast_log(LOG_WARNING, "Unable to open %s\n", fn);
1511 if (fs) {
1512 ast_closestream(fs);
1513 }
1514 fs = NULL;
1515 bfile = NULL;
1516 ast_free(fn);
1517 break;
1518 }
1519 /* found it */
1520 fs->trans = NULL;
1521 fs->fmt = f;
1522 fs->flags = flags;
1523 fs->mode = mode;
1525 fs->vfs = NULL;
1526 ast_free(fn);
1527 break;
1528 }
1529
1531 if (!format_found)
1532 ast_log(LOG_WARNING, "No such format '%s'\n", type);
1533
1534 return fs;
1535}
#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:434
int ast_closestream(struct ast_filestream *f)
Closes a stream.
Definition file.c:1210
static int open_wrapper(struct ast_filestream *s)
Definition file.c:605
static struct ast_filestream * get_filestream(struct ast_format_def *fmt, FILE *bfile)
Definition file.c:543
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 1035 of file file.c.

1036{
1037 int whennext = 0;
1038
1039 return read_frame(s, &whennext);
1040}

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 1113 of file file.c.

1114{
1115 int whennext = 0;
1116
1117 while (!whennext) {
1118 struct ast_frame *fr = read_frame(s, &whennext);
1119
1120 if (!fr /* stream complete */ || ast_write(s->owner, fr) /* error writing */) {
1121 if (fr) {
1122 ast_debug(2, "Failed to write frame\n");
1123 ast_frfree(fr);
1124 }
1126 return FSREAD_FAILURE;
1127 }
1128
1129 if (fr) {
1130 ast_frfree(fr);
1131 }
1132 }
1133
1134 if (whennext != s->lasttimeout) {
1136 s->lasttimeout = whennext;
1138 }
1139
1140 return FSREAD_SUCCESS_SCHED;
1141}
void ast_channel_vstreamid_set(struct ast_channel *chan, int value)
static int ast_fsread_video(const void *data)
Definition file.c:1143

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 1174 of file file.c.

1175{
1176 return fs->fmt->seek(fs, sample_offset, whence);
1177}
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 245 of file file.c.

246{
247 struct ast_json * cel_event = NULL;
248
249 ast_channel_lock(tmp);
250
251 /* Stop a running stream if there is one */
252 if (ast_channel_stream(tmp)) {
255
256 cel_event = ast_json_pack("{ s: s }", "event", "FILE_STREAM_END");
257 if (cel_event) {
259 }
260
262 ast_log(LOG_WARNING, "Unable to restore format back to %s\n", ast_format_get_name(ast_channel_oldwriteformat(tmp)));
263 }
264 ast_json_unref(cel_event);
265
266 /* Stop the video stream too */
267 if (ast_channel_vstream(tmp) != NULL) {
270 }
271
273
274 return 0;
275}
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 1992 of file file.c.

1993{
1994 int res = 0;
1995 if (!ast_strlen_zero(file)) {
1996 res = ast_streamfile(chan, file, ast_channel_language(chan));
1997 if (!res) {
1998 res = ast_waitstream(chan, digits);
1999 }
2000 }
2001 if (res == -1) {
2002 ast_stopstream(chan);
2003 }
2004
2005 return res;
2006}
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:1392
int ast_stopstream(struct ast_channel *tmp)
Stops a stream.
Definition file.c:245
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition file.c:1954
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 1194 of file file.c.

1195{
1196 return ast_seekstream(fs, ms * DEFAULT_SAMPLES_PER_MS, SEEK_CUR);
1197}
#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:1174

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 1199 of file file.c.

1200{
1201 off_t offset = ast_tellstream(fs);
1202 if (ms * DEFAULT_SAMPLES_PER_MS > offset) {
1203 /* Don't even bother asking the file format to seek to a negative offset... */
1204 ast_debug(1, "Restarting, rather than seeking to negative offset %ld\n", (long) (offset - (ms * DEFAULT_SAMPLES_PER_MS)));
1205 return ast_seekstream(fs, 0, SEEK_SET);
1206 }
1207 return ast_seekstream(fs, -ms * DEFAULT_SAMPLES_PER_MS, SEEK_CUR);
1208}
off_t ast_tellstream(struct ast_filestream *fs)
Tell where we are in a stream.
Definition file.c:1184

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 1392 of file file.c.

1394{
1395 struct ast_json * cel_event = NULL;
1396 struct ast_filestream *fs = NULL;
1397 struct ast_filestream *vfs = NULL;
1398 off_t pos;
1399 int seekattempt;
1400 int res;
1401 char custom_filename[256];
1402 char *tmp_filename;
1403
1404 /* If file with the same name exists in /var/lib/asterisk/sounds/custom directory, use that file.
1405 * Otherwise, use the original file*/
1406
1408 memset(custom_filename, 0, sizeof(custom_filename));
1409 snprintf(custom_filename, sizeof(custom_filename), "custom/%s", filename);
1410 fs = openstream_internal(chan, custom_filename, preflang, 0, 1); /* open stream, do not warn for missing files */
1411 if (fs) {
1412 tmp_filename = custom_filename;
1413 ast_debug(3, "Found file %s in custom directory\n", filename);
1414 }
1415 }
1416
1417 if (!fs) {
1418 fs = ast_openstream(chan, filename, preflang);
1419 if (!fs) {
1420 struct ast_str *codec_buf = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN);
1421 ast_channel_lock(chan);
1422 ast_log(LOG_WARNING, "Unable to open %s (format %s)\n",
1423 filename, ast_format_cap_get_names(ast_channel_nativeformats(chan), &codec_buf));
1424 ast_channel_unlock(chan);
1425 return -1;
1426 }
1427 tmp_filename = (char *)filename;
1428 }
1429
1430 /* check to see if there is any data present (not a zero length file),
1431 * done this way because there is no where for ast_openstream_full to
1432 * return the file had no data. */
1433 pos = ftello(fs->f);
1434 seekattempt = fseeko(fs->f, -1, SEEK_END);
1435 if (seekattempt) {
1436 if (errno == EINVAL) {
1437 /* Zero-length file, as opposed to a pipe */
1438 return 0;
1439 } else {
1440 ast_seekstream(fs, 0, SEEK_SET);
1441 }
1442 } else {
1443 fseeko(fs->f, pos, SEEK_SET);
1444 }
1445
1446 vfs = ast_openvstream(chan, tmp_filename, preflang);
1447 if (vfs) {
1448 ast_debug(1, "Ooh, found a video stream, too, format %s\n", ast_format_get_name(vfs->fmt->format));
1449 }
1450
1453 if (ast_applystream(chan, fs))
1454 return -1;
1455 if (vfs && ast_applystream(chan, vfs))
1456 return -1;
1457 ast_test_suite_event_notify("PLAYBACK", "Message: %s\r\nChannel: %s", tmp_filename, ast_channel_name(chan));
1458 res = ast_playstream(fs);
1459 if (!res && vfs)
1460 res = ast_playstream(vfs);
1461
1462 cel_event = ast_json_pack("{ s: s, s: {s: s, s: s, s: s}}",
1463 "event", "FILE_STREAM_BEGIN",
1464 "extra",
1465 "sound", tmp_filename,
1467 "language", preflang ? preflang : "default"
1468 );
1469 if (cel_event) {
1471 } else {
1472 ast_log(LOG_WARNING, "Unable to build extradata for sound file STREAM_BEGIN event on channel %s", ast_channel_name(chan));
1473 }
1474 ast_json_unref(cel_event);
1475
1476 if (VERBOSITY_ATLEAST(3)) {
1477 ast_channel_lock(chan);
1478 ast_verb(3, "<%s> Playing '%s.%s' (language '%s')\n", ast_channel_name(chan), tmp_filename, ast_format_get_name(ast_channel_writeformat(chan)), preflang ? preflang : "default");
1479 ast_channel_unlock(chan);
1480 }
1481
1482 return res;
1483}
@ 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:936
int ast_applystream(struct ast_channel *chan, struct ast_filestream *s)
Applies a open stream to a channel.
Definition file.c:1156
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:947
static int is_absolute_path(const char *filename)
Definition file.c:766
int ast_playstream(struct ast_filestream *s)
Play a open stream on a channel.
Definition file.c:1162
#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 ast_str_alloca(init_len)
Definition strings.h:848
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, openstream_internal(), ast_filestream::orig_chan_name, 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 1184 of file file.c.

1185{
1186 return fs->fmt->tell(fs);
1187}
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 1179 of file file.c.

1180{
1181 return fs->fmt->trunc(fs);
1182}
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 1954 of file file.c.

1955{
1956 int res;
1957
1958 res = waitstream_core(c, breakon, NULL, NULL, 0, -1, -1, NULL, NULL /* no callback */);
1959
1960 return sanitize_waitstream_return(res);
1961}
static int sanitize_waitstream_return(int return_value)
Definition file.c:1937
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:1727
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 1973 of file file.c.

1974{
1975 int res;
1976
1977 /* Waitstream, with return in the case of a valid 1 digit extension */
1978 /* in the current or specified context being pressed */
1979 if (!context)
1981 res = waitstream_core(c, NULL, NULL, NULL, 0,
1982 -1, -1, context, NULL /* no callback */);
1983
1984 return sanitize_waitstream_return(res);
1985}
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 1923 of file file.c.

1924{
1925 return waitstream_core(c, breakon, forward, reverse, ms,
1926 -1 /* no audiofd */, -1 /* no cmdfd */, NULL /* no context */, NULL /* no callback */);
1927}

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 1912 of file file.c.

1918{
1919 return waitstream_core(c, breakon, forward, reverse, ms,
1920 -1 /* no audiofd */, -1 /* no cmdfd */, NULL /* no context */, cb);
1921}

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 1537 of file file.c.

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

278{
279 int res = -1;
280 if (f->frametype == AST_FRAME_VIDEO) {
282 /* This is the audio portion. Call the video one... */
283 if (!fs->vfs && fs->filename) {
284 const char *type = ast_format_get_name(f->subclass.format);
285 fs->vfs = ast_writefile(fs->filename, type, NULL, fs->flags, 0, fs->mode);
286 ast_debug(1, "Opened video output file\n");
287 }
288 if (fs->vfs)
289 return ast_writestream(fs->vfs, f);
290 /* else ignore */
291 return 0;
292 }
293 } else if (f->frametype != AST_FRAME_VOICE) {
294 ast_log(LOG_WARNING, "Tried to write non-voice frame\n");
295 return -1;
296 }
298 res = fs->fmt->write(fs, f);
299 if (res < 0)
300 ast_log(LOG_WARNING, "Natural write failed\n");
301 else if (res > 0)
302 ast_log(LOG_WARNING, "Huh??\n");
303 } else {
304 /* XXX If they try to send us a type of frame that isn't the normal frame, and isn't
305 the one we've setup a translator for, we do the "wrong thing" XXX */
308 fs->trans = NULL;
309 }
310 if (!fs->trans) {
312 }
313 if (!fs->trans) {
314 ast_log(LOG_WARNING, "Unable to translate to format %s, source format %s\n",
316 } else {
317 struct ast_frame *trf;
319 /* Get the translated frame but don't consume the original in case they're using it on another stream */
320 if ((trf = ast_translate(fs->trans, f, 0))) {
321 struct ast_frame *cur;
322
323 /* the translator may have returned multiple frames, so process them */
324 for (cur = trf; cur; cur = AST_LIST_NEXT(cur, frame_list)) {
325 if ((res = fs->fmt->write(fs, cur))) {
326 ast_log(LOG_WARNING, "Translated frame write failed\n");
327 break;
328 }
329 }
330 ast_frfree(trf);
331 } else {
332 res = 0;
333 }
334 }
335 }
336 return res;
337}
#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:277
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:1537
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 434 of file file.c.

435{
436 char *fn = NULL;
437
438 if (filename[0] == '/') {
439 if (ast_asprintf(&fn, "%s.%s", filename, translate_extension(ext)) < 0) {
440 fn = NULL;
441 }
442 } else {
443 if (ast_asprintf(&fn, "%s/sounds/%s.%s",
445 fn = NULL;
446 }
447 }
448 return fn;
449}
static const char * translate_extension(const char *extension)
Definition file.c:419
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 389 of file file.c.

390{
391 char *fn;
392 int prefix_length;
393 int res;
394
395 if (filename[0] == '/') {
396 res = ast_asprintf(&fn, "%s.%n%*s",
397 filename, &prefix_length, maximum_extension_length, "");
398 } else {
399 res = ast_asprintf(&fn, "%s/sounds/%s.%n%*s",
401 filename, &prefix_length, maximum_extension_length, "");
402 }
403
404 if (res == -1) {
405 return NULL;
406 }
407
408 *extension_start = fn + prefix_length;
409 return fn;
410}

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 339 of file file.c.

340{
341 int ifd, ofd, len;
342 char buf[4096]; /* XXX make it larger. */
343
344 if ((ifd = open(infile, O_RDONLY)) < 0) {
345 ast_log(LOG_WARNING, "Unable to open %s in read-only mode\n", infile);
346 return -1;
347 }
348 if ((ofd = open(outfile, O_WRONLY | O_TRUNC | O_CREAT, AST_FILE_MODE)) < 0) {
349 ast_log(LOG_WARNING, "Unable to open %s in write-only mode\n", outfile);
350 close(ifd);
351 return -1;
352 }
353 while ( (len = read(ifd, buf, sizeof(buf)) ) ) {
354 int res;
355 if (len < 0) {
356 ast_log(LOG_WARNING, "Read failed on %s: %s\n", infile, strerror(errno));
357 break;
358 }
359 /* XXX handle partial writes */
360 res = write(ofd, buf, len);
361 if (res != len) {
362 ast_log(LOG_WARNING, "Write failed on %s (%d of %d): %s\n", outfile, res, len, strerror(errno));
363 len = -1; /* error marker */
364 break;
365 }
366 }
367 close(ifd);
368 close(ofd);
369 if (len < 0) {
370 unlink(outfile);
371 return -1; /* error */
372 }
373 return 0; /* success */
374}
#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 2158 of file file.c.

2159{
2163}
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 832 of file file.c.

834{
835 char *lang;
836
837 if (buf == NULL) {
838 return 0;
839 }
840
841 /* We try languages in the following order:
842 * preflang (may include dialect and style codes)
843 * lang (preflang without dialect - if any)
844 * <none>
845 * default (unless the same as preflang or lang without dialect)
846 */
847
848 lang = ast_strdupa(preflang);
849
850 /* Try preferred language, including removing any style or dialect codes */
851 while (!ast_strlen_zero(lang)) {
852 char *end;
853
854 if (fileexists_test(filename, fmt, lang, buf, buflen, result_cap)) {
855 return 1;
856 }
857
858 if ((end = strrchr(lang, '_')) != NULL) {
859 *end = '\0';
860 continue;
861 }
862
863 break;
864 }
865
866 /* Try without any language */
867 if (fileexists_test(filename, fmt, NULL, buf, buflen, result_cap)) {
868 return 1;
869 }
870
871 /* Finally try the default language unless it was already tried before */
872 if ((ast_strlen_zero(preflang) || strcmp(preflang, DEFAULT_LANGUAGE)) && (ast_strlen_zero(lang) || strcmp(lang, DEFAULT_LANGUAGE))) {
873 if ((fileexists_test(filename, fmt, DEFAULT_LANGUAGE, buf, buflen, result_cap)) > 0) {
874 return 1;
875 }
876 }
877
878 return 0;
879}
#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:782

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 782 of file file.c.

784{
785 if (buf == NULL) {
786 return 0;
787 }
788
789 if (is_remote_path(filename) && !ast_media_cache_retrieve(filename, NULL, buf, buflen)) {
790 return filehelper(buf, result_cap, NULL, ACTION_EXISTS);
791 }
792
793 if (ast_language_is_prefix && !is_absolute_path(filename)) { /* new layout */
794 if (lang) {
795 snprintf(buf, buflen, "%s/%s", lang, filename);
796 } else {
797 snprintf(buf, buflen, "%s", filename);
798 }
799 } else { /* old layout */
800 strcpy(buf, filename); /* first copy the full string */
801 if (lang) {
802 /* insert the language and suffix if needed */
803 const char *c = strrchr(filename, '/');
804 int offset = c ? c - filename + 1 : 0; /* points right after the last '/' */
805 snprintf(buf + offset, buflen - offset, "%s/%s", lang, filename + offset);
806 }
807 }
808
809 return filehelper(buf, result_cap, fmt, ACTION_EXISTS);
810}
int ast_language_is_prefix
The following variable controls the layout of localized sound files. If 0, use the historical layout ...
Definition file.c:68
static int is_remote_path(const char *filename)
Definition file.c:771
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_language_is_prefix, 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 629 of file file.c.

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

473{
474 enum ast_media_type format_type = ast_format_get_type(f->fmt->format);
475
476 if (!f->owner) {
477 return;
478 }
479
480 /* Stop a running stream if there is one */
481 switch (format_type)
482 {
486 ast_settimeout(f->owner, 0, NULL, NULL);
487 break;
491 break;
492 default:
493 ast_log(AST_LOG_WARNING, "Unable to schedule deletion of filestream with unsupported type %s\n", f->fmt->name);
494 break;
495 }
496}
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 498 of file file.c.

499{
500 struct ast_filestream *f = arg;
501 int status;
502 int pid = -1;
503
504 /* Stop a running stream if there is one */
506
507 /* destroy the translator on exit */
508 if (f->trans)
510
511 if (f->fmt->close) {
512 void (*closefn)(struct ast_filestream *) = f->fmt->close;
513 closefn(f);
514 }
515
516 if (f->f) {
517 fclose(f->f);
518 }
519
520 if (f->realfilename && f->filename) {
521 pid = ast_safe_fork(0);
522 if (!pid) {
523 execl("/bin/mv", "mv", "-f", f->filename, f->realfilename, SENTINEL);
524 _exit(1);
525 }
526 else if (pid > 0) {
527 /* Block the parent until the move is complete.*/
528 waitpid(pid, &status, 0);
529 }
530 }
531
532 ast_free(f->filename);
533 ast_free(f->realfilename);
534 if (f->vfs)
535 ast_closestream(f->vfs);
536 ast_free(f->write_buffer);
537 ast_free((void *)f->orig_chan_name);
538 ao2_cleanup(f->lastwriteformat);
539 ao2_cleanup(f->fr.subclass.format);
540 ast_module_unref(f->fmt->module);
541}
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 583 of file file.c.

584{
585 struct ast_format_def *f = s->fmt;
586 int ret = -1;
587 int (*openfn)(struct ast_filestream *s);
588
589 if (mode == WRAP_OPEN && (openfn = f->open) && openfn(s))
590 ast_log(LOG_WARNING, "Unable to open format %s\n", f->name);
591 else if (mode == WRAP_REWRITE && f->rewrite && f->rewrite(s, comment))
592 ast_log(LOG_WARNING, "Unable to rewrite format %s\n", f->name);
593 else {
594 /* preliminary checks succeed. */
595 ret = 0;
596 }
597 return ret;
598}

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 543 of file file.c.

544{
545 struct ast_filestream *s;
546 int l = sizeof(*s) + fmt->buf_size + fmt->desc_size; /* total allocation size */
547
548 if (!ast_module_running_ref(fmt->module)) {
549 return NULL;
550 }
551
553 if (!s) {
554 ast_module_unref(fmt->module);
555 return NULL;
556 }
557 s->fmt = fmt;
558 s->f = bfile;
559
560 if (fmt->desc_size)
561 s->_private = ((char *)(s + 1)) + fmt->buf_size;
562 if (fmt->buf_size)
563 s->buf = (char *)(s + 1);
564 s->fr.src = fmt->name;
565
570 }
571 s->fr.mallocd = 0;
573
574 return s;
575}
#define ao2_alloc(data_size, destructor_fn)
Definition astobj2.h:409
static void filestream_destructor(void *arg)
Definition file.c:498
#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 2084 of file file.c.

2085{
2086#define FORMAT "%-10s %-10s %-20s\n"
2087#define FORMAT2 "%-10s %-10s %-20s\n"
2088 struct ast_format_def *f;
2089 int count_fmt = 0;
2090
2091 switch (cmd) {
2092 case CLI_INIT:
2093 e->command = "core show file formats";
2094 e->usage =
2095 "Usage: core show file formats\n"
2096 " Displays currently registered file formats (if any).\n";
2097 return NULL;
2098 case CLI_GENERATE:
2099 return NULL;
2100 }
2101
2102 if (a->argc != 4)
2103 return CLI_SHOWUSAGE;
2104
2105 ast_cli(a->fd, FORMAT, "Format", "Name", "Extensions");
2106 ast_cli(a->fd, FORMAT, "------", "----", "----------");
2107
2110 ast_cli(a->fd, FORMAT2, ast_format_get_name(f->format), f->name, f->exts);
2111 count_fmt++;
2112 }
2114 ast_cli(a->fd, "%d file formats registered.\n", count_fmt);
2115 return CLI_SUCCESS;
2116#undef FORMAT
2117#undef FORMAT2
2118}
#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 766 of file file.c.

767{
768 return filename[0] == '/';
769}

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 771 of file file.c.

772{
773 return strstr(filename, "://") ? 1 : 0;
774}

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 75 of file file.c.

76{
78 char *stringp, *ext;
79
80 stringp = ast_strdupa(list); /* this is in the stack so does not need to be freed */
81 if (!array || !stringp) {
82 return NULL;
83 }
84
85 while ((ext = strsep(&stringp, sep))) {
87 return NULL;
88 }
89 }
90
91 return ast_json_ref(array);
92}
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 605 of file file.c.

606{
607 return fn_wrapper(s, NULL, WRAP_OPEN);
608}
static int fn_wrapper(struct ast_filestream *s, const char *comment, enum wrap_fn mode)
Definition file.c:583

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 881 of file file.c.

883{
884 /*
885 * Use fileexists_core() to find a file in a compatible
886 * language and format, set up a suitable translator,
887 * and open the stream.
888 */
889 struct ast_format_cap *file_fmt_cap;
890 int res;
891 int buflen;
892 char *buf;
893
894 if (!asis) {
895 /* do this first, otherwise we detect the wrong writeformat */
896 ast_stopstream(chan);
897 if (ast_channel_generator(chan))
899 }
900 if (preflang == NULL)
901 preflang = "";
902 buflen = strlen(preflang) + strlen(filename) + 4;
903 buf = ast_alloca(buflen);
904
905 if (!(file_fmt_cap = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT))) {
906 return NULL;
907 }
908 if (!fileexists_core(filename, NULL, preflang, buf, buflen, file_fmt_cap) ||
910
911 if (!quiet) {
912 ast_log(LOG_WARNING, "File %s does not exist in any format\n", filename);
913 }
914 ao2_ref(file_fmt_cap, -1);
915 return NULL;
916 }
917
918 /* Set the channel to a format we can work with and save off the previous format. */
919 ast_channel_lock(chan);
921 /* Set the channel to the best format that exists for the file. */
922 res = ast_set_write_format_from_cap(chan, file_fmt_cap);
923 ast_channel_unlock(chan);
924 /* don't need this anymore now that the channel's write format is set. */
925 ao2_ref(file_fmt_cap, -1);
926
927 if (res == -1) { /* No format available that works with this channel */
928 return NULL;
929 }
930 res = filehelper(buf, chan, NULL, ACTION_OPEN);
931 if (res >= 0)
932 return ast_channel_stream(chan);
933 return NULL;
934}
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 94 of file file.c.

95{
96 RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
97 RAII_VAR(struct ast_json_payload *, json_payload, NULL, ao2_cleanup);
98 RAII_VAR(struct ast_json *, json_object, NULL, ast_json_unref);
99
100 if (!type) {
101 return -1;
102 }
103
104 json_object = ast_json_pack("{s: s, s: o}",
105 "format", f->name,
106 "extensions", json_array_from_list(f->exts, "|"));
107 if (!json_object) {
108 return -1;
109 }
110
111 json_payload = ast_json_payload_create(json_object);
112 if (!json_payload) {
113 return -1;
114 }
115
116 msg = stasis_message_create(type, json_payload);
117 if (!msg) {
118 return -1;
119 }
120
122 return 0;
123}
static struct ast_json * json_array_from_list(const char *list, const char *sep)
Definition file.c:75
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 1010 of file file.c.

1011{
1012 struct ast_frame *fr, *new_fr;
1013
1014 if (!s || !s->fmt) {
1015 return NULL;
1016 }
1017
1018 if (!(fr = s->fmt->read(s, whennext))) {
1019 return NULL;
1020 }
1021
1022 if (!(new_fr = ast_frisolate(fr))) {
1023 ast_frfree(fr);
1024 return NULL;
1025 }
1026
1027 if (new_fr != fr) {
1028 ast_frfree(fr);
1029 fr = new_fr;
1030 }
1031
1032 return fr;
1033}
#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 600 of file file.c.

601{
602 return fn_wrapper(s, comment, WRAP_REWRITE);
603}

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 1937 of file file.c.

1938{
1939 switch (return_value) {
1943 /* Fall through and set return_value to 0 */
1944 return_value = 0;
1945 break;
1946 default:
1947 /* Do nothing */
1948 break;
1949 }
1950
1951 return return_value;
1952}
@ 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 419 of file file.c.

420{
421 /* The wav49 -> WAV translation is duplicated in apps/app_mixmonitor.c, so
422 if you change it here you need to change it there as well */
423 if (!strcmp(extension, "wav49")) {
424 return "WAV";
425 }
426 return extension;
427}
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 453 of file file.c.

454{
455 char *stringp = ast_strdupa(list), *item;
456
457 while ((item = strsep(&stringp, "|"))) {
458 if (!cmp(item, type)) {
459 return 1;
460 }
461 }
462
463 return 0;
464}
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 1685 of file file.c.

1689{
1690 switch (type)
1691 {
1693 {
1694 int eoftest;
1696 eoftest = fgetc(ast_channel_stream(c)->f);
1697 if (feof(ast_channel_stream(c)->f)) {
1699 } else {
1700 ungetc(eoftest, ast_channel_stream(c)->f);
1701 }
1702 }
1703 break;
1706 break;
1707 default:
1708 break;
1709 }
1710
1711 if (cb) {
1712 long ms_len = ast_tellstream(ast_channel_stream(c)) / (ast_format_get_sample_rate(ast_channel_stream(c)->fmt->format) / 1000);
1713 cb(c, ms_len, type);
1714 }
1715
1716 ast_test_suite_event_notify("PLAYBACK","Channel: %s\r\n"
1717 "Control: %s\r\n"
1718 "SkipMs: %d\r\n",
1720 (type == AST_WAITSTREAM_CB_FASTFORWARD) ? "FastForward" : "Rewind",
1721 skip_ms);
1722}
int ast_stream_rewind(struct ast_filestream *fs, off_t ms)
Rewind stream ms.
Definition file.c:1199
int ast_stream_fastforward(struct ast_filestream *fs, off_t ms)
Fast forward stream ms.
Definition file.c:1194
@ 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 1727 of file file.c.

1736{
1737 const char *orig_chan_name = NULL;
1738
1739 int err = 0;
1740
1741 if (!breakon)
1742 breakon = "";
1743 if (!forward)
1744 forward = "";
1745 if (!reverse)
1746 reverse = "";
1747
1748 /* Switch the channel to end DTMF frame only. waitstream_core doesn't care about the start of DTMF. */
1750
1752 orig_chan_name = ast_strdupa(ast_channel_name(c));
1753
1754 if (ast_channel_stream(c) && cb) {
1755 long ms_len = ast_tellstream(ast_channel_stream(c)) / (ast_format_get_sample_rate(ast_channel_stream(c)->fmt->format) / 1000);
1756 cb(c, ms_len, AST_WAITSTREAM_CB_START);
1757 }
1758
1759 while (ast_channel_stream(c)) {
1760 int res;
1761 int ms;
1762
1763 if (orig_chan_name && strcasecmp(orig_chan_name, ast_channel_name(c))) {
1765 err = 1;
1766 break;
1767 }
1768
1770
1771 if (ms < 0 && !ast_channel_timingfunc(c)) {
1773 break;
1774 }
1775 if (ms < 0)
1776 ms = 1000;
1777 if (cmdfd < 0) {
1778 res = ast_waitfor(c, ms);
1779 if (res < 0) {
1780 ast_log(LOG_WARNING, "Select failed (%s)\n", strerror(errno));
1782 return res;
1783 }
1784 } else {
1785 int outfd;
1786 struct ast_channel *rchan = ast_waitfor_nandfds(&c, 1, &cmdfd, (cmdfd > -1) ? 1 : 0, NULL, &outfd, &ms);
1787 if (!rchan && (outfd < 0) && (ms)) {
1788 /* Continue */
1789 if (errno == EINTR)
1790 continue;
1791 ast_log(LOG_WARNING, "Wait failed (%s)\n", strerror(errno));
1793 return -1;
1794 } else if (outfd > -1) { /* this requires cmdfd set */
1795 /* The FD we were watching has something waiting */
1797 return 1;
1798 }
1799 /* if rchan is set, it is 'c' */
1800 res = rchan ? 1 : 0; /* map into 'res' values */
1801 }
1802 if (res > 0) {
1803 struct ast_frame *fr = ast_read(c);
1804 if (!fr) {
1806 return -1;
1807 }
1808 switch (fr->frametype) {
1809 case AST_FRAME_DTMF_END:
1810 if (context) {
1811 const char exten[2] = { fr->subclass.integer, '\0' };
1812 if (ast_exists_extension(c, context, exten, 1,
1813 S_COR(ast_channel_caller(c)->id.number.valid, ast_channel_caller(c)->id.number.str, NULL))) {
1814 res = fr->subclass.integer;
1815 ast_frfree(fr);
1817 return res;
1818 }
1819 } else {
1820 res = fr->subclass.integer;
1821 if (strchr(forward, res)) {
1823 } else if (strchr(reverse, res)) {
1825 } else if (strchr(breakon, res)) {
1826 ast_test_suite_event_notify("PLAYBACK","Channel: %s\r\n"
1827 "Control: %s\r\n",
1829 "Break");
1830
1831 ast_frfree(fr);
1833 return res;
1834 }
1835 }
1836 break;
1837 case AST_FRAME_CONTROL:
1838 switch (fr->subclass.integer) {
1842 /* Fall-through and break out */
1843 ast_test_suite_event_notify("PLAYBACK","Channel: %s\r\n"
1844 "Control: %s\r\n",
1846 "Break");
1847 res = fr->subclass.integer;
1848 ast_frfree(fr);
1850 return res;
1852 if (!skip_ms) {
1853 skip_ms = 3000;
1854 }
1856 break;
1858 if (!skip_ms) {
1859 skip_ms = 3000;
1860 }
1862 break;
1863 case AST_CONTROL_HANGUP:
1864 case AST_CONTROL_BUSY:
1866 ast_frfree(fr);
1868 return -1;
1871 case AST_CONTROL_ANSWER:
1875 case AST_CONTROL_HOLD:
1876 case AST_CONTROL_UNHOLD:
1879 case AST_CONTROL_AOC:
1882 case AST_CONTROL_FLASH:
1883 case AST_CONTROL_WINK:
1884 case -1:
1885 /* Unimportant */
1886 break;
1887 default:
1888 ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", fr->subclass.integer);
1889 }
1890 break;
1891 case AST_FRAME_VOICE:
1892 /* Write audio if appropriate */
1893 if (audiofd > -1) {
1894 if (write(audiofd, fr->data.ptr, fr->datalen) < 0) {
1895 ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
1896 }
1897 }
1898 default:
1899 /* Ignore all others */
1900 break;
1901 }
1902 ast_frfree(fr);
1903 }
1905 }
1906
1908
1909 return (err || ast_channel_softhangup_internal_flag(c)) ? -1 : 0;
1910}
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:1685
@ 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

◆ ast_language_is_prefix

int ast_language_is_prefix = 1

The following variable controls the layout of localized sound files. If 0, use the historical layout with prefix just before the filename (i.e. digits/en/1.gsm , digits/it/1.gsm or default to digits/1.gsm), if 1 put the prefix at the beginning of the filename (i.e. en/digits/1.gsm, it/digits/1.gsm or default to digits/1.gsm). The latter permits a language to be entirely in one directory.

This is settable in asterisk.conf.

Definition at line 68 of file file.c.

Referenced by fileexists_test(), handle_show_settings(), load_asterisk_conf(), and main().

◆ 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:2084

Definition at line 2154 of file file.c.

2154 {
2155 AST_CLI_DEFINE(handle_cli_core_show_file_formats, "Displays file formats")
2156};
#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 134 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 1370 of file file.c.

Referenced by ast_file_read_dirs().