Asterisk - The Open Source Telephony Project GIT-master-0a46be9
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. More...
 
int ast_applystream (struct ast_channel *chan, struct ast_filestream *s)
 Applies a open stream to a channel. More...
 
int ast_closestream (struct ast_filestream *f)
 Closes a stream. More...
 
int ast_file_fdtemp (const char *path, char **filename, const char *template_name)
 Create a temporary file located at path. More...
 
int ast_file_init (void)
 
FILE * ast_file_mkftemp (char *template_name, mode_t mode)
 same as mkstemp, but return a FILE More...
 
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. More...
 
int ast_filecopy (const char *filename, const char *filename2, const char *fmt)
 Copies a file. More...
 
int ast_filedelete (const char *filename, const char *fmt)
 Deletes a file. More...
 
int ast_fileexists (const char *filename, const char *fmt, const char *preflang)
 Checks for the existence of a given file. More...
 
int ast_filerename (const char *filename, const char *filename2, const char *fmt)
 Renames a file. More...
 
int ast_format_def_unregister (const char *name)
 Unregisters a file format. More...
 
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. More...
 
struct ast_formatast_get_format_for_file_ext (const char *file_ext)
 Get the ast_format associated with the given file extension. More...
 
struct ast_filestreamast_openstream (struct ast_channel *chan, const char *filename, const char *preflang)
 Opens stream for use in seeking, playing. More...
 
struct ast_filestreamast_openstream_full (struct ast_channel *chan, const char *filename, const char *preflang, int asis)
 Opens stream for use in seeking, playing. More...
 
struct ast_filestreamast_openvstream (struct ast_channel *chan, const char *filename, const char *preflang)
 Opens stream for use in seeking, playing. More...
 
int ast_playstream (struct ast_filestream *s)
 Play a open stream on a channel. More...
 
int ast_ratestream (struct ast_filestream *fs)
 Return the sample rate of the stream's format. More...
 
static enum fsread_res ast_readaudio_callback (struct ast_filestream *s)
 
struct ast_filestreamast_readfile (const char *filename, const char *type, const char *comment, int flags, int check, mode_t mode)
 Starts reading from a file. More...
 
struct ast_frameast_readframe (struct ast_filestream *s)
 Read a frame from a filestream. More...
 
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. More...
 
int ast_stopstream (struct ast_channel *tmp)
 Stops a stream. More...
 
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. More...
 
int ast_stream_fastforward (struct ast_filestream *fs, off_t ms)
 Fast forward stream ms. More...
 
int ast_stream_rewind (struct ast_filestream *fs, off_t ms)
 Rewind stream ms. More...
 
int ast_streamfile (struct ast_channel *chan, const char *filename, const char *preflang)
 Streams a file. More...
 
off_t ast_tellstream (struct ast_filestream *fs)
 Tell where we are in a stream. More...
 
int ast_truncstream (struct ast_filestream *fs)
 Trunc stream at current location. More...
 
int ast_waitstream (struct ast_channel *c, const char *breakon)
 Waits for a stream to stop or digit to be pressed. More...
 
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. More...
 
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. More...
 
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. More...
 
int ast_waitstream_full (struct ast_channel *c, const char *breakon, int audiofd, int cmdfd)
 
struct ast_filestreamast_writefile (const char *filename, const char *type, const char *comment, int flags, int check, mode_t mode)
 Starts writing a file. More...
 
int ast_writestream (struct ast_filestream *fs, struct ast_frame *f)
 Writes a frame to a stream. More...
 
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. The wav49 suffix is replaced by 'WAV'. Returns a malloc'ed string to be freed by the caller. More...
 
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. More...
 
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. More...
 
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_filestreamget_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_jsonjson_array_from_list (const char *list, const char *sep)
 
static int open_wrapper (struct ast_filestream *s)
 
static struct ast_filestreamopenstream_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_frameread_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 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 More...
 

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. More...
 
static struct ast_cli_entry cli_file []
 
static struct formats formats = { .first = NULL, .last = NULL, .lock = { PTHREAD_RWLOCK_INITIALIZER , NULL, {1, 0} } , }
 
static ast_mutex_t read_dirs_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} }
 Lock to hold when iterating over directories. More...
 

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

541 {
542 ACTION_EXISTS = 1, /* return matching format if file exists, 0 otherwise */
543 ACTION_DELETE, /* delete file, return 0 on success, -1 on error */
544 ACTION_RENAME, /* rename file. return 0 on success, -1 on error */
546 ACTION_COPY /* copy file. return 0 on success, -1 on error */
547};
@ ACTION_OPEN
Definition: file.c:545
@ ACTION_EXISTS
Definition: file.c:542
@ ACTION_COPY
Definition: file.c:546
@ ACTION_DELETE
Definition: file.c:543
@ ACTION_RENAME
Definition: file.c:544

◆ fsread_res

enum fsread_res
Enumerator
FSREAD_FAILURE 
FSREAD_SUCCESS_SCHED 
FSREAD_SUCCESS_NOSCHED 

Definition at line 962 of file file.c.

962 {
966};
@ FSREAD_FAILURE
Definition: file.c:963
@ FSREAD_SUCCESS_SCHED
Definition: file.c:964
@ FSREAD_SUCCESS_NOSCHED
Definition: file.c:965

◆ wrap_fn

enum wrap_fn
Enumerator
WRAP_OPEN 
WRAP_REWRITE 

Definition at line 512 of file file.c.

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

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

1177{
1178 DIR *dir;
1179 struct dirent *entry;
1180 int res;
1181
1182 if (!(dir = opendir(path))) {
1183 ast_log(LOG_ERROR, "Error opening directory - %s: %s\n",
1184 path, strerror(errno));
1185 return -1;
1186 }
1187
1188 --max_depth;
1189
1190 res = 0;
1191
1192 while ((entry = readdir(dir)) != NULL && !errno) {
1193 int is_file = 0;
1194 int is_dir = 0;
1195 RAII_VAR(char *, full_path, NULL, ast_free);
1196
1197 if (!strcmp(entry->d_name, ".") || !strcmp(entry->d_name, "..")) {
1198 continue;
1199 }
1200
1201/*
1202 * If the dirent structure has a d_type use it to determine if we are dealing with
1203 * a file or directory. Unfortunately if it doesn't have it, or if the type is
1204 * unknown, or a link then we'll need to use the stat function instead.
1205 */
1206#ifdef _DIRENT_HAVE_D_TYPE
1207 if (entry->d_type != DT_UNKNOWN && entry->d_type != DT_LNK) {
1208 is_file = entry->d_type == DT_REG;
1209 is_dir = entry->d_type == DT_DIR;
1210 } else
1211#endif
1212 {
1213 struct stat statbuf;
1214
1215 /*
1216 * Don't use alloca or we risk blowing out the stack if recursing
1217 * into subdirectories.
1218 */
1219 full_path = ast_malloc(strlen(path) + strlen(entry->d_name) + 2);
1220 if (!full_path) {
1221 return -1;
1222 }
1223 sprintf(full_path, "%s/%s", path, entry->d_name);
1224
1225 if (stat(full_path, &statbuf)) {
1226 ast_log(LOG_ERROR, "Error reading path stats - %s: %s\n",
1227 full_path, strerror(errno));
1228 /*
1229 * Output an error, but keep going. It could just be
1230 * a broken link and other files could be fine.
1231 */
1232 continue;
1233 }
1234
1235 is_file = S_ISREG(statbuf.st_mode);
1236 is_dir = S_ISDIR(statbuf.st_mode);
1237 }
1238
1239 if (is_file) {
1240 /* If the handler returns non-zero then stop */
1241 if ((res = on_file(path, entry->d_name, obj))) {
1242 break;
1243 }
1244 /* Otherwise move on to next item in directory */
1245 continue;
1246 }
1247
1248 if (!is_dir) {
1249 ast_debug(5, "Skipping %s: not a regular file or directory\n", full_path);
1250 continue;
1251 }
1252
1253 /* Only re-curse into sub-directories if not at the max depth */
1254 if (max_depth != 0) {
1255 if (!full_path) {
1256 /* Don't use alloca. See note above. */
1257 full_path = ast_malloc(strlen(path) + strlen(entry->d_name) + 2);
1258 if (!full_path) {
1259 return -1;
1260 }
1261 sprintf(full_path, "%s/%s", path, entry->d_name);
1262 }
1263
1264 if ((res = __ast_file_read_dirs(full_path, on_file, obj, max_depth))) {
1265 break;
1266 }
1267 }
1268 }
1269
1270 closedir(dir);
1271
1272 if (!res && errno) {
1273 ast_log(LOG_ERROR, "Error while reading directories - %s: %s\n",
1274 path, strerror(errno));
1275 res = -1;
1276 }
1277
1278 return res;
1279}
#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:1175
#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:978

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

126{
127 struct ast_format_def *tmp;
128
131 if (!strcasecmp(f->name, tmp->name)) {
133 ast_log(LOG_WARNING, "Tried to register '%s' format, already registered\n", f->name);
134 return -1;
135 }
136 }
137 if (!(tmp = ast_calloc(1, sizeof(*tmp)))) {
139 return -1;
140 }
141 *tmp = *f;
142 tmp->module = mod;
143 if (tmp->buf_size) {
144 /*
145 * Align buf_size properly, rounding up to the machine-specific
146 * alignment for pointers.
147 */
148 struct _test_align { void *a, *b; } p;
149 int align = (char *)&p.b - (char *)&p.a;
150 tmp->buf_size = ((f->buf_size + align - 1) / align) * align;
151 }
152
153 memset(&tmp->list, 0, sizeof(tmp->list));
154
155 AST_RWLIST_INSERT_HEAD(&formats, tmp, list);
157 ast_verb(5, "Registered file format %s, extension(s) %s\n", f->name, f->exts);
159
160 return 0;
161}
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:202
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.
#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.
Definition: linkedlists.h:151
#define AST_RWLIST_TRAVERSE
Definition: linkedlists.h:494
#define AST_RWLIST_INSERT_HEAD
Definition: linkedlists.h:718
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::@244 list
struct ast_module * module
Definition: mod_format.h:93
char exts[80]
Definition: mod_format.h:45
Definition: file.c:70
static struct test_val b
static struct test_val a

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

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

1077{
1078 s->owner = chan;
1079 return 0;
1080}
struct ast_channel * owner
Definition: mod_format.h:116

References ast_filestream::owner.

Referenced by ast_streamfile(), handle_getoption(), handle_recordfile(), handle_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 1130 of file file.c.

1131{
1132 /* This used to destroy the filestream, but it now just decrements a refcount.
1133 * We close the stream in order to quit queuing frames now, because we might
1134 * change the writeformat, which could result in a subsequent write error, if
1135 * the format is different. */
1136 if (f == NULL) {
1137 return 0;
1138 }
1140 ao2_ref(f, -1);
1141 return 0;
1142}
#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:403

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

204{
205 int fd;
206
207 if (ast_asprintf(filename, "%s/%s", path, template_name) < 0) {
208 ast_log(LOG_ERROR, "Failed to set up temporary file path\n");
209 return -1;
210 }
211
212 ast_mkdir(path, 0644);
213
214 if ((fd = mkstemp(*filename)) < 0) {
215 ast_log(LOG_NOTICE, "Failed to create temporary file\n");
216 ast_free(*filename);
217 return -1;
218 }
219
220 return fd;
221}
#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:2515

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

2086{
2091 return 0;
2092}
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:2078
static struct ast_cli_entry cli_file[]
Definition: file.c:2074
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:1493
#define ARRAY_LEN(a)
Definition: utils.h:703

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

189{
190 FILE *p = NULL;
191 int pfd = mkstemp(template_name);
192 chmod(template_name, mode);
193 if (pfd > -1) {
194 p = fdopen(pfd, "w+");
195 if (!p) {
196 close(pfd);
197 pfd = -1;
198 }
199 }
200 return p;
201}

References ast_format_def::close, and NULL.

Referenced by 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 1293 of file file.c.

1294{
1295 int res;
1296
1297 errno = 0;
1298
1299#if !defined(__GLIBC__)
1301#endif
1302
1303 res = __ast_file_read_dirs(dir_name, on_file, obj, max_depth);
1304
1305#if !defined(__GLIBC__)
1307#endif
1308
1309 return res;
1310}
static ast_mutex_t read_dirs_lock
Lock to hold when iterating over directories.
Definition: file.c:1290
#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 1170 of file file.c.

1171{
1172 return filehelper(filename, filename2, fmt, ACTION_COPY);
1173}
static int filehelper(const char *filename, const void *arg2, const char *fmt, const enum file_action action)
Definition: file.c:560

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

1161{
1162 return filehelper(filename, NULL, fmt, ACTION_DELETE);
1163}

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

Referenced by __ast_play_and_record(), announce_thread(), async_delete_name_rec_task(), conf_free(), conf_rec_name(), conf_run(), confbridge_exec(), dial_exec_full(), handle_cli_file_convert(), leave_voicemail(), mixmonitor_thread(), msg_create_from_file(), play_record_review(), record_exec(), recording_cancel(), setup_privacy_args(), 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 1148 of file file.c.

1149{
1150 char *buf;
1151 int buflen;
1152
1153 if (preflang == NULL)
1154 preflang = "";
1155 buflen = strlen(preflang) + strlen(filename) + 4; /* room for everything */
1156 buf = ast_alloca(buflen);
1157 return fileexists_core(filename, fmt, preflang, buf, buflen, NULL) ? 1 : 0;
1158}
#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:752

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(), forward_message(), get_folder(), invent_message(), 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 1165 of file file.c.

1166{
1167 return filehelper(filename, filename2, fmt, ACTION_RENAME);
1168}

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

164{
165 struct ast_format_def *tmp;
166 int res = -1;
167
170 if (!strcasecmp(name, tmp->name)) {
173 ast_free(tmp);
174 res = 0;
175 }
176 }
179
180 if (!res)
181 ast_verb(5, "Unregistered format %s\n", name);
182 else
183 ast_log(LOG_WARNING, "Tried to unregister format %s, already unregistered\n", name);
184
185 return res;
186}
static const char name[]
Definition: format_mp3.c:68
#define AST_RWLIST_REMOVE_CURRENT
Definition: linkedlists.h:570
#define AST_RWLIST_TRAVERSE_SAFE_BEGIN
Definition: linkedlists.h:545
#define AST_RWLIST_TRAVERSE_SAFE_END
Definition: linkedlists.h:617

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().

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

1929{
1930 struct ast_format_def *f;
1931 struct ast_format_def *fmts_ptr[AST_MAX_FORMATS];
1932 char *fmts_str[AST_MAX_FORMATS];
1933 char *stringp, *type;
1934 char *orig = fmts;
1935 int i, j, x, first, found = 0;
1936 int len = strlen(fmts) + 1;
1937 int res;
1938
1939 if (AST_RWLIST_RDLOCK(&formats)) {
1940 ast_log(LOG_WARNING, "Unable to lock format list\n");
1941 return NULL;
1942 }
1943
1944 stringp = ast_strdupa(fmts);
1945
1946 for (x = 0; (type = strsep(&stringp, "|")) && x < AST_MAX_FORMATS; x++) {
1948 if (exts_compare(f->exts, type)) {
1949 found = 1;
1950 break;
1951 }
1952 }
1953
1954 fmts_str[x] = type;
1955 if (found) {
1956 fmts_ptr[x] = f;
1957 } else {
1958 fmts_ptr[x] = NULL;
1959 }
1960 }
1962
1963 first = 1;
1964 for (i = 0; i < x; i++) {
1965 /* ignore invalid entries */
1966 if (!fmts_ptr[i]) {
1967 ast_log(LOG_WARNING, "ignoring unknown format '%s'\n", fmts_str[i]);
1968 continue;
1969 }
1970
1971 /* special handling for the first entry */
1972 if (first) {
1973 res = snprintf(fmts, len, "%s", fmts_str[i]);
1974 fmts += res;
1975 len -= res;
1976 first = 0;
1977 continue;
1978 }
1979
1980 found = 0;
1981 for (j = 0; j < i; j++) {
1982 /* this is a duplicate */
1983 if (fmts_ptr[j] == fmts_ptr[i]) {
1984 found = 1;
1985 break;
1986 }
1987 }
1988
1989 if (!found) {
1990 res = snprintf(fmts, len, "|%s", fmts_str[i]);
1991 fmts += res;
1992 len -= res;
1993 }
1994 }
1995
1996 if (first) {
1997 ast_log(LOG_WARNING, "no known formats found in format list (%s)\n", orig);
1998 return NULL;
1999 }
2000
2001 return orig;
2002}
struct sla_ringing_trunk * first
Definition: app_sla.c:338
char * strsep(char **str, const char *delims)
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:298
static const char type[]
Definition: chan_ooh323.c:109
#define exts_compare(list, type)
Definition: file.c:397
#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 1018 of file file.c.

1019{
1020 struct ast_filestream *fs = (struct ast_filestream *)data;
1021 enum fsread_res res;
1022
1023 res = ast_readaudio_callback(fs);
1024
1025 if (res == FSREAD_SUCCESS_SCHED)
1026 return 1;
1027
1028 return 0;
1029}
fsread_res
Definition: file.c:962
static enum fsread_res ast_readaudio_callback(struct ast_filestream *s)
Definition: file.c:970
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 1063 of file file.c.

1064{
1065 struct ast_filestream *fs = (struct ast_filestream *)data;
1066 enum fsread_res res;
1067
1068 res = ast_readvideo_callback(fs);
1069
1070 if (res == FSREAD_SUCCESS_SCHED)
1071 return 1;
1072
1073 return 0;
1074}
static enum fsread_res ast_readvideo_callback(struct ast_filestream *s)
Definition: file.c:1033

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

2054{
2055 struct ast_format_def *f;
2057
2058 ast_assert(buffer && capacity);
2059
2061 if (type_in_list(f->mime_types, mime_type, strcasecmp)) {
2062 size_t item_len = strcspn(f->exts, "|");
2063 size_t bytes_written = snprintf(buffer, capacity, ".%.*s", (int) item_len, f->exts);
2064 if (bytes_written < capacity) {
2065 /* Only return success if we didn't truncate */
2066 return 1;
2067 }
2068 }
2069 }
2070
2071 return 0;
2072}
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:384
#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:776

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

2041{
2042 struct ast_format_def *f;
2045 if (exts_compare(f->exts, file_ext)) {
2046 return f->format;
2047 }
2048 }
2049
2050 return NULL;
2051}
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 856 of file file.c.

857{
858 return openstream_internal(chan, filename, preflang, 0, 0);
859}
static struct ast_filestream * openstream_internal(struct ast_channel *chan, const char *filename, const char *preflang, int asis, int quiet)
Definition: file.c:801

References ast_filestream::filename, and openstream_internal().

Referenced by ast_streamfile(), dictate_exec(), handle_getoption(), handle_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 861 of file file.c.

863{
864 return openstream_internal(chan, filename, preflang, asis, 0);
865}

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

869{
870 /* As above, but for video. But here we don't have translators
871 * so we must enforce a format.
872 */
873 struct ast_format_cap *nativeformats, *tmp_cap;
874 char *buf;
875 int buflen;
876 int i, fd;
877
878 if (preflang == NULL) {
879 preflang = "";
880 }
881 buflen = strlen(preflang) + strlen(filename) + 4;
882 buf = ast_alloca(buflen);
883
884 ast_channel_lock(chan);
885 nativeformats = ao2_bump(ast_channel_nativeformats(chan));
886 ast_channel_unlock(chan);
887
888 /* is the channel capable of video without translation ?*/
889 if (!ast_format_cap_has_type(nativeformats, AST_MEDIA_TYPE_VIDEO)) {
890 ao2_cleanup(nativeformats);
891 return NULL;
892 }
894 ao2_cleanup(nativeformats);
895 return NULL;
896 }
897 /* Video is supported, so see what video formats exist for this file */
898 if (!fileexists_core(filename, NULL, preflang, buf, buflen, tmp_cap)) {
899 ao2_ref(tmp_cap, -1);
900 ao2_cleanup(nativeformats);
901 return NULL;
902 }
903
904 /* iterate over file formats and pick the first one compatible with the channel's native formats */
905 for (i = 0; i < ast_format_cap_count(tmp_cap); ++i) {
906 struct ast_format *format = ast_format_cap_get_format(tmp_cap, i);
907
908 if ((ast_format_get_type(format) != AST_MEDIA_TYPE_VIDEO) ||
909 !ast_format_cap_iscompatible(nativeformats, tmp_cap)) {
910 ao2_ref(format, -1);
911 continue;
912 }
913
914 fd = filehelper(buf, chan, ast_format_get_name(format), ACTION_OPEN);
915 if (fd >= 0) {
916 ao2_ref(format, -1);
917 ao2_ref(tmp_cap, -1);
918 ao2_cleanup(nativeformats);
919 return ast_channel_vstream(chan);
920 }
921 ast_log(LOG_WARNING, "File %s has video but couldn't be opened\n", filename);
922 ao2_ref(format, -1);
923 }
924 ao2_ref(tmp_cap, -1);
925 ao2_cleanup(nativeformats);
926
927 return NULL;
928}
#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:2972
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:2973
@ 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:400
@ 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:613
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:653
#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:395
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 1082 of file file.c.

1083{
1084 enum fsread_res res;
1085
1087 res = ast_readaudio_callback(s);
1088 else
1089 res = ast_readvideo_callback(s);
1090
1091 return (res == FSREAD_FAILURE) ? -1 : 0;
1092}
@ 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(), 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 1109 of file file.c.

1110{
1112}
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 970 of file file.c.

971{
972 int whennext = 0;
973
974 while (!whennext) {
975 struct ast_frame *fr;
976
977 if (s->orig_chan_name && strcasecmp(ast_channel_name(s->owner), s->orig_chan_name)) {
978 goto return_failure;
979 }
980
981 fr = read_frame(s, &whennext);
982
983 if (!fr /* stream complete */ || ast_write(s->owner, fr) /* error writing */) {
984 if (fr) {
985 ast_debug(2, "Failed to write frame\n");
986 ast_frfree(fr);
987 }
988 goto return_failure;
989 }
990
991 if (fr) {
992 ast_frfree(fr);
993 }
994 }
995
996 if (whennext != s->lasttimeout) {
997 if (ast_channel_timingfd(s->owner) > -1) {
998 float samp_rate = (float) ast_format_get_sample_rate(s->fmt->format);
999 unsigned int rate;
1000
1001 rate = (unsigned int) roundf(samp_rate / ((float) whennext));
1002
1004 } else {
1006 }
1007 s->lasttimeout = whennext;
1009 }
1010 return FSREAD_SUCCESS_SCHED;
1011
1012return_failure:
1014 ast_settimeout(s->owner, 0, NULL, NULL);
1015 return FSREAD_FAILURE;
1016}
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:3155
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:5112
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:3150
struct ast_sched_context * ast_channel_sched(const struct ast_channel *chan)
static int ast_fsread_audio(const void *data)
Definition: file.c:1018
static struct ast_frame * read_frame(struct ast_filestream *s, int *whennext)
Definition: file.c:930
#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 1405 of file file.c.

1406{
1407 FILE *bfile;
1408 struct ast_format_def *f;
1409 struct ast_filestream *fs = NULL;
1410 char *fn;
1411 int format_found = 0;
1412
1414
1415 AST_RWLIST_TRAVERSE(&formats, f, list) {
1416 fs = NULL;
1417 if (!exts_compare(f->exts, type))
1418 continue;
1419 else
1420 format_found = 1;
1421
1423 if (!fn) {
1424 continue;
1425 }
1426 errno = 0;
1427 bfile = fopen(fn, "r");
1428
1429 if (!bfile || (fs = get_filestream(f, bfile)) == NULL || open_wrapper(fs) ) {
1430 ast_log(LOG_WARNING, "Unable to open %s\n", fn);
1431 if (fs) {
1432 ast_closestream(fs);
1433 }
1434 fs = NULL;
1435 bfile = NULL;
1436 ast_free(fn);
1437 break;
1438 }
1439 /* found it */
1440 fs->trans = NULL;
1441 fs->fmt = f;
1442 fs->flags = flags;
1443 fs->mode = mode;
1445 fs->vfs = NULL;
1446 ast_free(fn);
1447 break;
1448 }
1449
1451 if (!format_found)
1452 ast_log(LOG_WARNING, "No such format '%s'\n", type);
1453
1454 return fs;
1455}
#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:360
int ast_closestream(struct ast_filestream *f)
Closes a stream.
Definition: file.c:1130
static int open_wrapper(struct ast_filestream *s)
Definition: file.c:536
static struct ast_filestream * get_filestream(struct ast_format_def *fmt, FILE *bfile)
Definition: file.c:474
struct ast_filestream * vfs
Definition: mod_format.h:110
struct ast_trans_pvt * trans
Definition: mod_format.h:112
char * filename
Definition: mod_format.h:107

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

956{
957 int whennext = 0;
958
959 return read_frame(s, &whennext);
960}

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

1034{
1035 int whennext = 0;
1036
1037 while (!whennext) {
1038 struct ast_frame *fr = read_frame(s, &whennext);
1039
1040 if (!fr /* stream complete */ || ast_write(s->owner, fr) /* error writing */) {
1041 if (fr) {
1042 ast_debug(2, "Failed to write frame\n");
1043 ast_frfree(fr);
1044 }
1046 return FSREAD_FAILURE;
1047 }
1048
1049 if (fr) {
1050 ast_frfree(fr);
1051 }
1052 }
1053
1054 if (whennext != s->lasttimeout) {
1056 s->lasttimeout = whennext;
1058 }
1059
1060 return FSREAD_SUCCESS_SCHED;
1061}
void ast_channel_vstreamid_set(struct ast_channel *chan, int value)
static int ast_fsread_video(const void *data)
Definition: file.c:1063

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

1095{
1096 return fs->fmt->seek(fs, sample_offset, whence);
1097}
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 223 of file file.c.

224{
225 struct ast_json * cel_event = NULL;
226
227 ast_channel_lock(tmp);
228
229 /* Stop a running stream if there is one */
230 if (ast_channel_stream(tmp)) {
233
234 cel_event = ast_json_pack("{ s: s }", "event", "FILE_STREAM_END");
235 if (cel_event) {
237 }
238
240 ast_log(LOG_WARNING, "Unable to restore format back to %s\n", ast_format_get_name(ast_channel_oldwriteformat(tmp)));
241 }
242 ast_json_unref(cel_event);
243
244 /* Stop the video stream too */
245 if (ast_channel_vstream(tmp) != NULL) {
248 }
249
251
252 return 0;
253}
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:1735
@ AST_CEL_STREAM_END
A stream ended.
Definition: cel.h:83
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:5771
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_en(), ast_say_enumeration_full_he(), ast_say_enumeration_full_is(), ast_say_enumeration_full_vi(), ast_say_number_full_cs(), ast_say_number_full_da(), ast_say_number_full_de(), 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_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_files_helper(), play_mailbox_owner(), playback_exec(), queue_exec(), read_exec(), readexten_exec(), record_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 1912 of file file.c.

1913{
1914 int res = 0;
1915 if (!ast_strlen_zero(file)) {
1916 res = ast_streamfile(chan, file, ast_channel_language(chan));
1917 if (!res) {
1918 res = ast_waitstream(chan, digits);
1919 }
1920 }
1921 if (res == -1) {
1922 ast_stopstream(chan);
1923 }
1924
1925 return res;
1926}
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:1312
int ast_stopstream(struct ast_channel *tmp)
Stops a stream.
Definition: file.c:223
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1874
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(), ast_waitstream(), and make_ari_stubs::file.

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(), playback_common(), 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 1114 of file file.c.

1115{
1116 return ast_seekstream(fs, ms * DEFAULT_SAMPLES_PER_MS, SEEK_CUR);
1117}
#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:1094

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

1120{
1121 off_t offset = ast_tellstream(fs);
1122 if (ms * DEFAULT_SAMPLES_PER_MS > offset) {
1123 /* Don't even bother asking the file format to seek to a negative offset... */
1124 ast_debug(1, "Restarting, rather than seeking to negative offset %ld\n", (long) (offset - (ms * DEFAULT_SAMPLES_PER_MS)));
1125 return ast_seekstream(fs, 0, SEEK_SET);
1126 }
1127 return ast_seekstream(fs, -ms * DEFAULT_SAMPLES_PER_MS, SEEK_CUR);
1128}
off_t ast_tellstream(struct ast_filestream *fs)
Tell where we are in a stream.
Definition: file.c:1104

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

1314{
1315 struct ast_json * cel_event = NULL;
1316 struct ast_filestream *fs = NULL;
1317 struct ast_filestream *vfs = NULL;
1318 off_t pos;
1319 int seekattempt;
1320 int res;
1321 char custom_filename[256];
1322 char *tmp_filename;
1323
1324 /* If file with the same name exists in /var/lib/asterisk/sounds/custom directory, use that file.
1325 * Otherwise, use the original file*/
1326
1328 memset(custom_filename, 0, sizeof(custom_filename));
1329 snprintf(custom_filename, sizeof(custom_filename), "custom/%s", filename);
1330 fs = openstream_internal(chan, custom_filename, preflang, 0, 1); /* open stream, do not warn for missing files */
1331 if (fs) {
1332 tmp_filename = custom_filename;
1333 ast_debug(3, "Found file %s in custom directory\n", filename);
1334 }
1335 }
1336
1337 if (!fs) {
1338 fs = ast_openstream(chan, filename, preflang);
1339 if (!fs) {
1340 struct ast_str *codec_buf = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN);
1341 ast_channel_lock(chan);
1342 ast_log(LOG_WARNING, "Unable to open %s (format %s): %s\n",
1343 filename, ast_format_cap_get_names(ast_channel_nativeformats(chan), &codec_buf), strerror(errno));
1344 ast_channel_unlock(chan);
1345 return -1;
1346 }
1347 tmp_filename = (char *)filename;
1348 }
1349
1350 /* check to see if there is any data present (not a zero length file),
1351 * done this way because there is no where for ast_openstream_full to
1352 * return the file had no data. */
1353 pos = ftello(fs->f);
1354 seekattempt = fseeko(fs->f, -1, SEEK_END);
1355 if (seekattempt) {
1356 if (errno == EINVAL) {
1357 /* Zero-length file, as opposed to a pipe */
1358 return 0;
1359 } else {
1360 ast_seekstream(fs, 0, SEEK_SET);
1361 }
1362 } else {
1363 fseeko(fs->f, pos, SEEK_SET);
1364 }
1365
1366 vfs = ast_openvstream(chan, tmp_filename, preflang);
1367 if (vfs) {
1368 ast_debug(1, "Ooh, found a video stream, too, format %s\n", ast_format_get_name(vfs->fmt->format));
1369 }
1370
1373 if (ast_applystream(chan, fs))
1374 return -1;
1375 if (vfs && ast_applystream(chan, vfs))
1376 return -1;
1377 ast_test_suite_event_notify("PLAYBACK", "Message: %s\r\nChannel: %s", tmp_filename, ast_channel_name(chan));
1378 res = ast_playstream(fs);
1379 if (!res && vfs)
1380 res = ast_playstream(vfs);
1381
1382 cel_event = ast_json_pack("{ s: s, s: {s: s, s: s, s: s}}",
1383 "event", "FILE_STREAM_BEGIN",
1384 "extra",
1385 "sound", tmp_filename,
1387 "language", preflang ? preflang : "default"
1388 );
1389 if (cel_event) {
1391 } else {
1392 ast_log(LOG_WARNING, "Unable to build extradata for sound file STREAM_BEGIN event on channel %s", ast_channel_name(chan));
1393 }
1394 ast_json_unref(cel_event);
1395
1396 if (VERBOSITY_ATLEAST(3)) {
1397 ast_channel_lock(chan);
1398 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");
1399 ast_channel_unlock(chan);
1400 }
1401
1402 return res;
1403}
@ AST_CEL_STREAM_BEGIN
A stream started.
Definition: cel.h:81
struct ast_flags * ast_channel_flags(struct ast_channel *chan)
@ AST_FLAG_MASQ_NOSTREAM
Definition: channel.h:1034
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:856
int ast_applystream(struct ast_channel *chan, struct ast_filestream *s)
Applies a open stream to a channel.
Definition: file.c:1076
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:867
static int is_absolute_path(const char *filename)
Definition: file.c:686
int ast_playstream(struct ast_filestream *s)
Play a open stream on a channel.
Definition: file.c:1082
#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:734
#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:63

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_en(), ast_say_enumeration_full_he(), ast_say_enumeration_full_is(), ast_say_enumeration_full_vi(), ast_say_number_full_cs(), ast_say_number_full_da(), ast_say_number_full_de(), 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_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(), 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(), record_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 1104 of file file.c.

1105{
1106 return fs->fmt->tell(fs);
1107}
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 1099 of file file.c.

1100{
1101 return fs->fmt->trunc(fs);
1102}
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 1874 of file file.c.

1875{
1876 int res;
1877
1878 res = waitstream_core(c, breakon, NULL, NULL, 0, -1, -1, NULL, NULL /* no callback */);
1879
1880 return sanitize_waitstream_return(res);
1881}
static int sanitize_waitstream_return(int return_value)
Definition: file.c:1857
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:1647
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_en(), ast_say_enumeration_full_he(), ast_say_enumeration_full_is(), ast_say_enumeration_full_vi(), ast_say_number_full_cs(), ast_say_number_full_da(), ast_say_number_full_de(), 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_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(), 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(), record_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 1893 of file file.c.

1894{
1895 int res;
1896
1897 /* Waitstream, with return in the case of a valid 1 digit extension */
1898 /* in the current or specified context being pressed */
1899 if (!context)
1901 res = waitstream_core(c, NULL, NULL, NULL, 0,
1902 -1, -1, context, NULL /* no callback */);
1903
1904 return sanitize_waitstream_return(res);
1905}
const char * ast_channel_context(const struct ast_channel *chan)

References ast_channel_context(), c, voicemailpwcheck::context, 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 1843 of file file.c.

1844{
1845 return waitstream_core(c, breakon, forward, reverse, ms,
1846 -1 /* no audiofd */, -1 /* no cmdfd */, NULL /* no context */, NULL /* no callback */);
1847}

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

1838{
1839 return waitstream_core(c, breakon, forward, reverse, ms,
1840 -1 /* no audiofd */, -1 /* no cmdfd */, NULL /* no context */, cb);
1841}

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

1458{
1459 int fd, myflags = 0;
1460 /* compiler claims this variable can be used before initialization... */
1461 FILE *bfile = NULL;
1462 struct ast_format_def *f;
1463 struct ast_filestream *fs = NULL;
1464 char *buf = NULL;
1465 size_t size = 0;
1466 int format_found = 0;
1467
1469
1470 /* set the O_TRUNC flag if and only if there is no O_APPEND specified */
1471 /* We really can't use O_APPEND as it will break WAV header updates */
1472 if (flags & O_APPEND) {
1473 flags &= ~O_APPEND;
1474 } else {
1475 myflags = O_TRUNC;
1476 }
1477
1478 myflags |= O_WRONLY | O_CREAT;
1479
1480 /* XXX need to fix this - we should just do the fopen,
1481 * not open followed by fdopen()
1482 */
1483 AST_RWLIST_TRAVERSE(&formats, f, list) {
1484 char *fn, *orig_fn = NULL;
1485 if (fs)
1486 break;
1487
1488 if (!exts_compare(f->exts, type))
1489 continue;
1490 else
1491 format_found = 1;
1492
1494 if (!fn) {
1495 continue;
1496 }
1497 fd = open(fn, flags | myflags, mode);
1498 if (fd > -1) {
1499 /* fdopen() the resulting file stream */
1500 bfile = fdopen(fd, ((flags | myflags) & O_RDWR) ? "w+" : "w");
1501 if (!bfile) {
1502 ast_log(LOG_WARNING, "Whoa, fdopen failed: %s!\n", strerror(errno));
1503 close(fd);
1504 fd = -1;
1505 }
1506 }
1507
1508 if (ast_opt_cache_record_files && (fd > -1)) {
1509 char *c;
1510
1511 fclose(bfile); /* this also closes fd */
1512 /*
1513 We touch orig_fn just as a place-holder so other things (like vmail) see the file is there.
1514 What we are really doing is writing to record_cache_dir until we are done then we will mv the file into place.
1515 */
1516 orig_fn = ast_strdup(fn);
1517 for (c = fn; *c; c++)
1518 if (*c == '/')
1519 *c = '_';
1520
1521 size = strlen(fn) + strlen(record_cache_dir) + 2;
1522 buf = ast_malloc(size);
1523 strcpy(buf, record_cache_dir);
1524 strcat(buf, "/");
1525 strcat(buf, fn);
1526 ast_free(fn);
1527 fn = buf;
1528 fd = open(fn, flags | myflags, mode);
1529 if (fd > -1) {
1530 /* fdopen() the resulting file stream */
1531 bfile = fdopen(fd, ((flags | myflags) & O_RDWR) ? "w+" : "w");
1532 if (!bfile) {
1533 ast_log(LOG_WARNING, "Whoa, fdopen failed: %s!\n", strerror(errno));
1534 close(fd);
1535 fd = -1;
1536 }
1537 }
1538 }
1539 if (fd > -1) {
1540 errno = 0;
1541 fs = get_filestream(f, bfile);
1542 if (fs) {
1543 if ((fs->write_buffer = ast_malloc(32768))) {
1544 setvbuf(fs->f, fs->write_buffer, _IOFBF, 32768);
1545 }
1546 }
1547 if (!fs || rewrite_wrapper(fs, comment)) {
1548 ast_log(LOG_WARNING, "Unable to rewrite %s\n", fn);
1549 close(fd);
1550 if (orig_fn) {
1551 unlink(fn);
1552 unlink(orig_fn);
1553 ast_free(orig_fn);
1554 }
1555 if (fs) {
1556 ast_closestream(fs);
1557 fs = NULL;
1558 }
1559 /*
1560 * 'fn' was has either been allocated from build_filename, or that was freed
1561 * and now 'fn' points to memory allocated for 'buf'. Either way the memory
1562 * now needs to be released.
1563 */
1564 ast_free(fn);
1565 continue;
1566 }
1567 fs->trans = NULL;
1568 fs->fmt = f;
1569 fs->flags = flags;
1570 fs->mode = mode;
1571 if (orig_fn) {
1572 fs->realfilename = orig_fn;
1573 fs->filename = fn;
1574 /*
1575 * The above now manages the memory allocated for 'orig_fn' and 'fn', so
1576 * set them to NULL, so they don't get released at the end of the loop.
1577 */
1578 orig_fn = NULL;
1579 fn = NULL;
1580 } else {
1581 fs->realfilename = NULL;
1583 }
1584 fs->vfs = NULL;
1585 /* If truncated, we'll be at the beginning; if not truncated, then append */
1586 f->seek(fs, 0, SEEK_END);
1587 } else if (errno != EEXIST) {
1588 ast_log(LOG_WARNING, "Unable to open file %s: %s\n", fn, strerror(errno));
1589 if (orig_fn)
1590 unlink(orig_fn);
1591 }
1592 /* Free 'fn', or if 'fn' points to 'buf' then free 'buf' */
1593 ast_free(fn);
1594 ast_free(orig_fn);
1595 }
1596
1598
1599 if (!format_found)
1600 ast_log(LOG_WARNING, "No such format '%s'\n", type);
1601
1602 return fs;
1603}
#define comment
Definition: ael_lex.c:965
static int rewrite_wrapper(struct ast_filestream *s, const char *comment)
Definition: file.c:531
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 255 of file file.c.

256{
257 int res = -1;
258 if (f->frametype == AST_FRAME_VIDEO) {
260 /* This is the audio portion. Call the video one... */
261 if (!fs->vfs && fs->filename) {
262 const char *type = ast_format_get_name(f->subclass.format);
263 fs->vfs = ast_writefile(fs->filename, type, NULL, fs->flags, 0, fs->mode);
264 ast_debug(1, "Opened video output file\n");
265 }
266 if (fs->vfs)
267 return ast_writestream(fs->vfs, f);
268 /* else ignore */
269 return 0;
270 }
271 } else if (f->frametype != AST_FRAME_VOICE) {
272 ast_log(LOG_WARNING, "Tried to write non-voice frame\n");
273 return -1;
274 }
276 res = fs->fmt->write(fs, f);
277 if (res < 0)
278 ast_log(LOG_WARNING, "Natural write failed\n");
279 else if (res > 0)
280 ast_log(LOG_WARNING, "Huh??\n");
281 } else {
282 /* XXX If they try to send us a type of frame that isn't the normal frame, and isn't
283 the one we've setup a translator for, we do the "wrong thing" XXX */
286 fs->trans = NULL;
287 }
288 if (!fs->trans) {
290 }
291 if (!fs->trans) {
292 ast_log(LOG_WARNING, "Unable to translate to format %s, source format %s\n",
294 } else {
295 struct ast_frame *trf;
297 /* Get the translated frame but don't consume the original in case they're using it on another stream */
298 if ((trf = ast_translate(fs->trans, f, 0))) {
299 struct ast_frame *cur;
300
301 /* the translator may have returned multiple frames, so process them */
302 for (cur = trf; cur; cur = AST_LIST_NEXT(cur, frame_list)) {
303 if ((res = fs->fmt->write(fs, trf))) {
304 ast_log(LOG_WARNING, "Translated frame write failed\n");
305 break;
306 }
307 }
308 ast_frfree(trf);
309 } else {
310 res = 0;
311 }
312 }
313 }
314 return res;
315}
#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:255
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:1457
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
@ AST_FRAME_VIDEO
@ AST_FRAME_VOICE
#define AST_LIST_NEXT(elm, field)
Returns the next entry in the list after the given entry.
Definition: linkedlists.h:439
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:566
void ast_translator_free_path(struct ast_trans_pvt *tr)
Frees a translator path Frees the given translator path structure.
Definition: translate.c:476
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:486

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. The wav49 suffix is replaced by 'WAV'. Returns a malloc'ed string to be freed by the caller.

Definition at line 360 of file file.c.

361{
362 char *fn = NULL;
363
364 /* The wav49 -> WAV translation is duplicated in apps/app_mixmonitor.c, so
365 if you change it here you need to change it there as well */
366 if (!strcmp(ext, "wav49"))
367 ext = "WAV";
368
369 if (filename[0] == '/') {
370 if (ast_asprintf(&fn, "%s.%s", filename, ext) < 0) {
371 fn = NULL;
372 }
373 } else {
374 if (ast_asprintf(&fn, "%s/sounds/%s.%s",
375 ast_config_AST_DATA_DIR, filename, ext) < 0) {
376 fn = NULL;
377 }
378 }
379 return fn;
380}
const char * ext
Definition: http.c:150
const char * ast_config_AST_DATA_DIR
Definition: options.c:159

References ast_asprintf, ast_config_AST_DATA_DIR, ext, and NULL.

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

◆ copy()

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

Definition at line 317 of file file.c.

318{
319 int ifd, ofd, len;
320 char buf[4096]; /* XXX make it larger. */
321
322 if ((ifd = open(infile, O_RDONLY)) < 0) {
323 ast_log(LOG_WARNING, "Unable to open %s in read-only mode\n", infile);
324 return -1;
325 }
326 if ((ofd = open(outfile, O_WRONLY | O_TRUNC | O_CREAT, AST_FILE_MODE)) < 0) {
327 ast_log(LOG_WARNING, "Unable to open %s in write-only mode\n", outfile);
328 close(ifd);
329 return -1;
330 }
331 while ( (len = read(ifd, buf, sizeof(buf)) ) ) {
332 int res;
333 if (len < 0) {
334 ast_log(LOG_WARNING, "Read failed on %s: %s\n", infile, strerror(errno));
335 break;
336 }
337 /* XXX handle partial writes */
338 res = write(ofd, buf, len);
339 if (res != len) {
340 ast_log(LOG_WARNING, "Write failed on %s (%d of %d): %s\n", outfile, res, len, strerror(errno));
341 len = -1; /* error marker */
342 break;
343 }
344 }
345 close(ifd);
346 close(ofd);
347 if (len < 0) {
348 unlink(outfile);
349 return -1; /* error */
350 }
351 return 0; /* success */
352}
#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 2078 of file file.c.

2079{
2083}
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
Definition: clicompat.c:30
#define STASIS_MESSAGE_TYPE_CLEANUP(name)
Boiler-plate messaging macro for cleaning up message types.
Definition: stasis.h:1515

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

754{
755 char *lang;
756
757 if (buf == NULL) {
758 return 0;
759 }
760
761 /* We try languages in the following order:
762 * preflang (may include dialect and style codes)
763 * lang (preflang without dialect - if any)
764 * <none>
765 * default (unless the same as preflang or lang without dialect)
766 */
767
768 lang = ast_strdupa(preflang);
769
770 /* Try preferred language, including removing any style or dialect codes */
771 while (!ast_strlen_zero(lang)) {
772 char *end;
773
774 if (fileexists_test(filename, fmt, lang, buf, buflen, result_cap)) {
775 return 1;
776 }
777
778 if ((end = strrchr(lang, '_')) != NULL) {
779 *end = '\0';
780 continue;
781 }
782
783 break;
784 }
785
786 /* Try without any language */
787 if (fileexists_test(filename, fmt, NULL, buf, buflen, result_cap)) {
788 return 1;
789 }
790
791 /* Finally try the default language unless it was already tried before */
792 if ((ast_strlen_zero(preflang) || strcmp(preflang, DEFAULT_LANGUAGE)) && (ast_strlen_zero(lang) || strcmp(lang, DEFAULT_LANGUAGE))) {
793 if ((fileexists_test(filename, fmt, DEFAULT_LANGUAGE, buf, buflen, result_cap)) > 0) {
794 return 1;
795 }
796 }
797
798 return 0;
799}
#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:702

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

704{
705 if (buf == NULL) {
706 return 0;
707 }
708
709 if (is_remote_path(filename) && !ast_media_cache_retrieve(filename, NULL, buf, buflen)) {
710 return filehelper(buf, result_cap, NULL, ACTION_EXISTS);
711 }
712
713 if (ast_language_is_prefix && !is_absolute_path(filename)) { /* new layout */
714 if (lang) {
715 snprintf(buf, buflen, "%s/%s", lang, filename);
716 } else {
717 snprintf(buf, buflen, "%s", filename);
718 }
719 } else { /* old layout */
720 strcpy(buf, filename); /* first copy the full string */
721 if (lang) {
722 /* insert the language and suffix if needed */
723 const char *c = strrchr(filename, '/');
724 int offset = c ? c - filename + 1 : 0; /* points right after the last '/' */
725 snprintf(buf + offset, buflen - offset, "%s/%s", lang, filename + offset);
726 }
727 }
728
729 return filehelper(buf, result_cap, fmt, ACTION_EXISTS);
730}
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:691
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.
Definition: media_cache.c:157

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

561{
562 struct ast_format_def *f;
563 int res = (action == ACTION_EXISTS) ? 0 : -1;
564
566 /* Check for a specific format */
568 char *ext = NULL;
569 char storage[strlen(f->exts) + 1];
570 char *stringp;
571
572 if (fmt && !exts_compare(f->exts, fmt))
573 continue;
574
575 /* Look for a file matching the supported extensions.
576 * The file must exist, and for OPEN, must match
577 * one of the formats supported by the channel.
578 */
579 strcpy(storage, f->exts); /* safe - this is in the stack so does not need to be freed */
580 stringp = storage;
581 while ( (ext = strsep(&stringp, "|")) ) {
582 struct stat st;
583 char *fn = build_filename(filename, ext);
584
585 if (fn == NULL)
586 continue;
587
588 if ( stat(fn, &st) ) { /* file not existent */
589 ast_free(fn);
590 continue;
591 }
592 /* for 'OPEN' we need to be sure that the format matches
593 * what the channel can process
594 */
595 if (action == ACTION_OPEN) {
596 struct ast_channel *chan = (struct ast_channel *)arg2;
597 FILE *bfile;
598 struct ast_filestream *s;
599
601 !(((ast_format_get_type(f->format) == AST_MEDIA_TYPE_AUDIO) && fmt) ||
602 ((ast_format_get_type(f->format) == AST_MEDIA_TYPE_VIDEO) && fmt))) {
603 ast_free(fn);
604 continue; /* not a supported format */
605 }
606 if ( (bfile = fopen(fn, "r")) == NULL) {
607 ast_free(fn);
608 continue; /* cannot open file */
609 }
610 s = get_filestream(f, bfile);
611 if (!s) {
612 fclose(bfile);
613 ast_free(fn); /* cannot allocate descriptor */
614 continue;
615 }
616 if (open_wrapper(s)) {
617 ast_free(fn);
619 continue; /* cannot run open on file */
620 }
621 if (st.st_size == 0) {
622 ast_log(LOG_WARNING, "File %s detected to have zero size.\n", fn);
623 }
624 /* ok this is good for OPEN */
625 res = 1; /* found */
626 s->lasttimeout = -1;
627 s->fmt = f;
628 s->trans = NULL;
629 s->filename = NULL;
631 if (ast_channel_stream(chan))
633 ast_channel_stream_set(chan, s);
634 } else {
635 if (ast_channel_vstream(chan))
638 }
639 ast_free(fn);
640 break;
641 }
642 switch (action) {
643 case ACTION_OPEN:
644 break; /* will never get here */
645
646 case ACTION_EXISTS: /* return the matching format */
647 /* if arg2 is present, it is a format capabilities structure.
648 * Add this format to the set of formats this file can be played in */
649 if (arg2) {
650 ast_format_cap_append((struct ast_format_cap *) arg2, f->format, 0);
651 }
652 res = 1; /* file does exist and format it exists in is returned in arg2 */
653 break;
654
655 case ACTION_DELETE:
656 if ( (res = unlink(fn)) )
657 ast_log(LOG_WARNING, "unlink(%s) failed: %s\n", fn, strerror(errno));
658 break;
659
660 case ACTION_RENAME:
661 case ACTION_COPY: {
662 char *nfn = build_filename((const char *)arg2, ext);
663 if (!nfn)
664 ast_log(LOG_WARNING, "Out of memory\n");
665 else {
666 res = action == ACTION_COPY ? copy(fn, nfn) : rename(fn, nfn);
667 if (res)
668 ast_log(LOG_WARNING, "%s(%s,%s) failed: %s\n",
669 action == ACTION_COPY ? "copy" : "rename",
670 fn, nfn, strerror(errno));
671 ast_free(nfn);
672 }
673 }
674 break;
675
676 default:
677 ast_log(LOG_WARNING, "Unknown helper %u\n", action);
678 }
679 ast_free(fn);
680 }
681 }
683 return res;
684}
static int copy(const char *infile, const char *outfile)
Definition: file.c:317
#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_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(), 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(), and ast_filestream::trans.

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

404{
405 enum ast_media_type format_type = ast_format_get_type(f->fmt->format);
406
407 if (!f->owner) {
408 return;
409 }
410
411 /* Stop a running stream if there is one */
412 switch (format_type)
413 {
417 ast_settimeout(f->owner, 0, NULL, NULL);
418 break;
422 break;
423 default:
424 ast_log(AST_LOG_WARNING, "Unable to schedule deletion of filestream with unsupported type %s\n", f->fmt->name);
425 break;
426 }
427}
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 429 of file file.c.

430{
431 struct ast_filestream *f = arg;
432 int status;
433 int pid = -1;
434
435 /* Stop a running stream if there is one */
437
438 /* destroy the translator on exit */
439 if (f->trans)
441
442 if (f->fmt->close) {
443 void (*closefn)(struct ast_filestream *) = f->fmt->close;
444 closefn(f);
445 }
446
447 if (f->f) {
448 fclose(f->f);
449 }
450
451 if (f->realfilename && f->filename) {
452 pid = ast_safe_fork(0);
453 if (!pid) {
454 execl("/bin/mv", "mv", "-f", f->filename, f->realfilename, SENTINEL);
455 _exit(1);
456 }
457 else if (pid > 0) {
458 /* Block the parent until the move is complete.*/
459 waitpid(pid, &status, 0);
460 }
461 }
462
463 ast_free(f->filename);
464 ast_free(f->realfilename);
465 if (f->vfs)
466 ast_closestream(f->vfs);
467 ast_free(f->write_buffer);
468 ast_free((void *)f->orig_chan_name);
469 ao2_cleanup(f->lastwriteformat);
470 ao2_cleanup(f->fr.subclass.format);
471 ast_module_unref(f->fmt->module);
472}
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:3207
#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 514 of file file.c.

515{
516 struct ast_format_def *f = s->fmt;
517 int ret = -1;
518 int (*openfn)(struct ast_filestream *s);
519
520 if (mode == WRAP_OPEN && (openfn = f->open) && openfn(s))
521 ast_log(LOG_WARNING, "Unable to open format %s\n", f->name);
522 else if (mode == WRAP_REWRITE && f->rewrite && f->rewrite(s, comment))
523 ast_log(LOG_WARNING, "Unable to rewrite format %s\n", f->name);
524 else {
525 /* preliminary checks succeed. */
526 ret = 0;
527 }
528 return ret;
529}

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

475{
476 struct ast_filestream *s;
477 int l = sizeof(*s) + fmt->buf_size + fmt->desc_size; /* total allocation size */
478
480 return NULL;
481 }
482
484 if (!s) {
486 return NULL;
487 }
488 s->fmt = fmt;
489 s->f = bfile;
490
491 if (fmt->desc_size)
492 s->_private = ((char *)(s + 1)) + fmt->buf_size;
493 if (fmt->buf_size)
494 s->buf = (char *)(s + 1);
495 s->fr.src = fmt->name;
496
501 }
502 s->fr.mallocd = 0;
504
505 return s;
506}
if(!yyg->yy_init)
Definition: ast_expr2f.c:854
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:409
static void filestream_destructor(void *arg)
Definition: file.c:429
#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
void * _private
Definition: mod_format.h:124
const char * src

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, if(), ast_frame::mallocd, ast_format_def::module, 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 2004 of file file.c.

2005{
2006#define FORMAT "%-10s %-10s %-20s\n"
2007#define FORMAT2 "%-10s %-10s %-20s\n"
2008 struct ast_format_def *f;
2009 int count_fmt = 0;
2010
2011 switch (cmd) {
2012 case CLI_INIT:
2013 e->command = "core show file formats";
2014 e->usage =
2015 "Usage: core show file formats\n"
2016 " Displays currently registered file formats (if any).\n";
2017 return NULL;
2018 case CLI_GENERATE:
2019 return NULL;
2020 }
2021
2022 if (a->argc != 4)
2023 return CLI_SHOWUSAGE;
2024
2025 ast_cli(a->fd, FORMAT, "Format", "Name", "Extensions");
2026 ast_cli(a->fd, FORMAT, "------", "----", "----------");
2027
2030 ast_cli(a->fd, FORMAT2, ast_format_get_name(f->format), f->name, f->exts);
2031 count_fmt++;
2032 }
2034 ast_cli(a->fd, "%d file formats registered.\n", count_fmt);
2035 return CLI_SUCCESS;
2036#undef FORMAT
2037#undef FORMAT2
2038}
#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 686 of file file.c.

687{
688 return filename[0] == '/';
689}

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

692{
693 return strstr(filename, "://") ? 1 : 0;
694}

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

537{
538 return fn_wrapper(s, NULL, WRAP_OPEN);
539}
static int fn_wrapper(struct ast_filestream *s, const char *comment, enum wrap_fn mode)
Definition: file.c:514

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

803{
804 /*
805 * Use fileexists_core() to find a file in a compatible
806 * language and format, set up a suitable translator,
807 * and open the stream.
808 */
809 struct ast_format_cap *file_fmt_cap;
810 int res;
811 int buflen;
812 char *buf;
813
814 if (!asis) {
815 /* do this first, otherwise we detect the wrong writeformat */
816 ast_stopstream(chan);
817 if (ast_channel_generator(chan))
819 }
820 if (preflang == NULL)
821 preflang = "";
822 buflen = strlen(preflang) + strlen(filename) + 4;
823 buf = ast_alloca(buflen);
824
825 if (!(file_fmt_cap = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT))) {
826 return NULL;
827 }
828 if (!fileexists_core(filename, NULL, preflang, buf, buflen, file_fmt_cap) ||
830
831 if (!quiet) {
832 ast_log(LOG_WARNING, "File %s does not exist in any format\n", filename);
833 }
834 ao2_ref(file_fmt_cap, -1);
835 return NULL;
836 }
837
838 /* Set the channel to a format we can work with and save off the previous format. */
839 ast_channel_lock(chan);
841 /* Set the channel to the best format that exists for the file. */
842 res = ast_set_write_format_from_cap(chan, file_fmt_cap);
843 ast_channel_unlock(chan);
844 /* don't need this anymore now that the channel's write format is set. */
845 ao2_ref(file_fmt_cap, -1);
846
847 if (res == -1) { /* No format available that works with this channel */
848 return NULL;
849 }
850 res = filehelper(buf, chan, NULL, ACTION_OPEN);
851 if (res >= 0)
852 return ast_channel_stream(chan);
853 return NULL;
854}
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:2863
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:5789

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:1538
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 930 of file file.c.

931{
932 struct ast_frame *fr, *new_fr;
933
934 if (!s || !s->fmt) {
935 return NULL;
936 }
937
938 if (!(fr = s->fmt->read(s, whennext))) {
939 return NULL;
940 }
941
942 if (!(new_fr = ast_frisolate(fr))) {
943 ast_frfree(fr);
944 return NULL;
945 }
946
947 if (new_fr != fr) {
948 ast_frfree(fr);
949 fr = new_fr;
950 }
951
952 return fr;
953}
#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 531 of file file.c.

532{
533 return fn_wrapper(s, comment, WRAP_REWRITE);
534}

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

1858{
1859 switch (return_value) {
1863 /* Fall through and set return_value to 0 */
1864 return_value = 0;
1865 break;
1866 default:
1867 /* Do nothing */
1868 break;
1869 }
1870
1871 return return_value;
1872}
@ 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  )

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

385{
386 char *stringp = ast_strdupa(list), *item;
387
388 while ((item = strsep(&stringp, "|"))) {
389 if (!cmp(item, type)) {
390 return 1;
391 }
392 }
393
394 return 0;
395}
static struct aco_type item
Definition: test_config.c:1463

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

1609{
1610 switch (type)
1611 {
1613 {
1614 int eoftest;
1616 eoftest = fgetc(ast_channel_stream(c)->f);
1617 if (feof(ast_channel_stream(c)->f)) {
1619 } else {
1620 ungetc(eoftest, ast_channel_stream(c)->f);
1621 }
1622 }
1623 break;
1626 break;
1627 default:
1628 break;
1629 }
1630
1631 if (cb) {
1632 long ms_len = ast_tellstream(ast_channel_stream(c)) / (ast_format_get_sample_rate(ast_channel_stream(c)->fmt->format) / 1000);
1633 cb(c, ms_len, type);
1634 }
1635
1636 ast_test_suite_event_notify("PLAYBACK","Channel: %s\r\n"
1637 "Control: %s\r\n"
1638 "SkipMs: %d\r\n",
1640 (type == AST_WAITSTREAM_CB_FASTFORWARD) ? "FastForward" : "Rewind",
1641 skip_ms);
1642}
int ast_stream_rewind(struct ast_filestream *fs, off_t ms)
Rewind stream ms.
Definition: file.c:1119
int ast_stream_fastforward(struct ast_filestream *fs, off_t ms)
Fast forward stream ms.
Definition: file.c:1114
@ 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 1647 of file file.c.

1656{
1657 const char *orig_chan_name = NULL;
1658
1659 int err = 0;
1660
1661 if (!breakon)
1662 breakon = "";
1663 if (!forward)
1664 forward = "";
1665 if (!reverse)
1666 reverse = "";
1667
1668 /* Switch the channel to end DTMF frame only. waitstream_core doesn't care about the start of DTMF. */
1670
1672 orig_chan_name = ast_strdupa(ast_channel_name(c));
1673
1674 if (ast_channel_stream(c) && cb) {
1675 long ms_len = ast_tellstream(ast_channel_stream(c)) / (ast_format_get_sample_rate(ast_channel_stream(c)->fmt->format) / 1000);
1676 cb(c, ms_len, AST_WAITSTREAM_CB_START);
1677 }
1678
1679 while (ast_channel_stream(c)) {
1680 int res;
1681 int ms;
1682
1683 if (orig_chan_name && strcasecmp(orig_chan_name, ast_channel_name(c))) {
1685 err = 1;
1686 break;
1687 }
1688
1690
1691 if (ms < 0 && !ast_channel_timingfunc(c)) {
1693 break;
1694 }
1695 if (ms < 0)
1696 ms = 1000;
1697 if (cmdfd < 0) {
1698 res = ast_waitfor(c, ms);
1699 if (res < 0) {
1700 ast_log(LOG_WARNING, "Select failed (%s)\n", strerror(errno));
1702 return res;
1703 }
1704 } else {
1705 int outfd;
1706 struct ast_channel *rchan = ast_waitfor_nandfds(&c, 1, &cmdfd, (cmdfd > -1) ? 1 : 0, NULL, &outfd, &ms);
1707 if (!rchan && (outfd < 0) && (ms)) {
1708 /* Continue */
1709 if (errno == EINTR)
1710 continue;
1711 ast_log(LOG_WARNING, "Wait failed (%s)\n", strerror(errno));
1713 return -1;
1714 } else if (outfd > -1) { /* this requires cmdfd set */
1715 /* The FD we were watching has something waiting */
1717 return 1;
1718 }
1719 /* if rchan is set, it is 'c' */
1720 res = rchan ? 1 : 0; /* map into 'res' values */
1721 }
1722 if (res > 0) {
1723 struct ast_frame *fr = ast_read(c);
1724 if (!fr) {
1726 return -1;
1727 }
1728 switch (fr->frametype) {
1729 case AST_FRAME_DTMF_END:
1730 if (context) {
1731 const char exten[2] = { fr->subclass.integer, '\0' };
1732 if (ast_exists_extension(c, context, exten, 1,
1733 S_COR(ast_channel_caller(c)->id.number.valid, ast_channel_caller(c)->id.number.str, NULL))) {
1734 res = fr->subclass.integer;
1735 ast_frfree(fr);
1737 return res;
1738 }
1739 } else {
1740 res = fr->subclass.integer;
1741 if (strchr(forward, res)) {
1743 } else if (strchr(reverse, res)) {
1745 } else if (strchr(breakon, res)) {
1746 ast_test_suite_event_notify("PLAYBACK","Channel: %s\r\n"
1747 "Control: %s\r\n",
1749 "Break");
1750
1751 ast_frfree(fr);
1753 return res;
1754 }
1755 }
1756 break;
1757 case AST_FRAME_CONTROL:
1758 switch (fr->subclass.integer) {
1762 /* Fall-through and break out */
1763 ast_test_suite_event_notify("PLAYBACK","Channel: %s\r\n"
1764 "Control: %s\r\n",
1766 "Break");
1767 res = fr->subclass.integer;
1768 ast_frfree(fr);
1770 return res;
1772 if (!skip_ms) {
1773 skip_ms = 3000;
1774 }
1776 break;
1778 if (!skip_ms) {
1779 skip_ms = 3000;
1780 }
1782 break;
1783 case AST_CONTROL_HANGUP:
1784 case AST_CONTROL_BUSY:
1786 ast_frfree(fr);
1788 return -1;
1791 case AST_CONTROL_ANSWER:
1795 case AST_CONTROL_HOLD:
1796 case AST_CONTROL_UNHOLD:
1799 case AST_CONTROL_AOC:
1802 case AST_CONTROL_FLASH:
1803 case AST_CONTROL_WINK:
1804 case -1:
1805 /* Unimportant */
1806 break;
1807 default:
1808 ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", fr->subclass.integer);
1809 }
1810 break;
1811 case AST_FRAME_VOICE:
1812 /* Write audio if appropriate */
1813 if (audiofd > -1) {
1814 if (write(audiofd, fr->data.ptr, fr->datalen) < 0) {
1815 ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
1816 }
1817 }
1818 default:
1819 /* Ignore all others */
1820 break;
1821 }
1822 ast_frfree(fr);
1823 }
1825 }
1826
1828
1829 return (err || ast_channel_softhangup_internal_flag(c)) ? -1 : 0;
1830}
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:2958
void ast_channel_clear_flag(struct ast_channel *chan, unsigned int flag)
Clear a flag on a channel.
Definition: channel.c:11048
int ast_waitfor(struct ast_channel *chan, int ms)
Wait for input on a channel.
Definition: channel.c:3132
@ AST_FLAG_END_DTMF_ONLY
Definition: channel.h:1027
struct ast_frame * ast_read(struct ast_channel *chan)
Reads a frame.
Definition: channel.c:4223
void ast_channel_set_flag(struct ast_channel *chan, unsigned int flag)
Set a flag on a channel.
Definition: channel.c:11041
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:1605
@ AST_WAITSTREAM_CB_START
Definition: file.h:57
@ AST_FRAME_DTMF_END
@ AST_FRAME_CONTROL
@ AST_CONTROL_SRCUPDATE
@ AST_CONTROL_WINK
@ AST_CONTROL_PROGRESS
@ AST_CONTROL_BUSY
@ 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_HOLD
@ AST_CONTROL_CONNECTED_LINE
@ AST_CONTROL_STREAM_FORWARD
@ AST_CONTROL_FLASH
@ AST_CONTROL_AOC
@ 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:4196
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::@231 data
Number structure.
Definition: app_followme.c:157

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, voicemailpwcheck::context, 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:2004

Definition at line 2074 of file file.c.

Referenced by ast_file_init(), and file_shutdown().

◆ formats

struct formats formats = { .first = NULL, .last = NULL, .lock = { PTHREAD_RWLOCK_INITIALIZER , NULL, {1, 0} } , }
static

Referenced by load_engine().

◆ read_dirs_lock

ast_mutex_t read_dirs_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} }
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 1290 of file file.c.

Referenced by ast_file_read_dirs().