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

Generic File Format Support. More...

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

Go to the source code of this file.

Data Structures

struct  formats
 

Macros

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

Enumerations

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

Functions

static int __ast_file_read_dirs (const char *path, ast_file_on_file on_file, void *obj, int max_depth)
 
int __ast_format_def_register (const struct ast_format_def *f, struct ast_module *mod)
 Register a new file format capability. Adds a format to Asterisk's format abilities.
 
int ast_applystream (struct ast_channel *chan, struct ast_filestream *s)
 Applies a open stream to a channel.
 
int ast_closestream (struct ast_filestream *f)
 Closes a stream.
 
int ast_file_fdtemp (const char *path, char **filename, const char *template_name)
 Create a temporary file located at path.
 
int ast_file_init (void)
 
FILE * ast_file_mkftemp (char *template_name, mode_t mode)
 same as mkstemp, but return a FILE
 
int ast_file_read_dirs (const char *dir_name, ast_file_on_file on_file, void *obj, int max_depth)
 Recursively iterate through files and directories up to max_depth.
 
int ast_filecopy (const char *filename, const char *filename2, const char *fmt)
 Copies a file.
 
int ast_filedelete (const char *filename, const char *fmt)
 Deletes a file.
 
int ast_fileexists (const char *filename, const char *fmt, const char *preflang)
 Checks for the existence of a given file.
 
int ast_filerename (const char *filename, const char *filename2, const char *fmt)
 Renames a file.
 
int ast_format_def_unregister (const char *name)
 Unregisters a file format.
 
char * ast_format_str_reduce (char *fmts)
 
static int ast_fsread_audio (const void *data)
 
static int ast_fsread_video (const void *data)
 
int ast_get_extension_for_mime_type (const char *mime_type, char *buffer, size_t capacity)
 Get a suitable filename extension for the given MIME type.
 
struct ast_formatast_get_format_for_file_ext (const char *file_ext)
 Get the ast_format associated with the given file extension.
 
struct ast_filestreamast_openstream (struct ast_channel *chan, const char *filename, const char *preflang)
 Opens stream for use in seeking, playing.
 
struct ast_filestreamast_openstream_full (struct ast_channel *chan, const char *filename, const char *preflang, int asis)
 Opens stream for use in seeking, playing.
 
struct ast_filestreamast_openvstream (struct ast_channel *chan, const char *filename, const char *preflang)
 Opens stream for use in seeking, playing.
 
int ast_playstream (struct ast_filestream *s)
 Play a open stream on a channel.
 
int ast_ratestream (struct ast_filestream *fs)
 Return the sample rate of the stream's format.
 
static enum fsread_res ast_readaudio_callback (struct ast_filestream *s)
 
struct ast_filestreamast_readfile (const char *filename, const char *type, const char *comment, int flags, int check, mode_t mode)
 Starts reading from a file.
 
struct ast_frameast_readframe (struct ast_filestream *s)
 Read a frame from a filestream.
 
static enum fsread_res ast_readvideo_callback (struct ast_filestream *s)
 
int ast_seekstream (struct ast_filestream *fs, off_t sample_offset, int whence)
 Seeks into stream.
 
int ast_stopstream (struct ast_channel *tmp)
 Stops a stream.
 
int ast_stream_and_wait (struct ast_channel *chan, const char *file, const char *digits)
 stream file until digit If the file name is non-empty, try to play it.
 
int ast_stream_fastforward (struct ast_filestream *fs, off_t ms)
 Fast forward stream ms.
 
int ast_stream_rewind (struct ast_filestream *fs, off_t ms)
 Rewind stream ms.
 
int ast_streamfile (struct ast_channel *chan, const char *filename, const char *preflang)
 Streams a file.
 
off_t ast_tellstream (struct ast_filestream *fs)
 Tell where we are in a stream.
 
int ast_truncstream (struct ast_filestream *fs)
 Trunc stream at current location.
 
int ast_waitstream (struct ast_channel *c, const char *breakon)
 Waits for a stream to stop or digit to be pressed.
 
int ast_waitstream_exten (struct ast_channel *c, const char *context)
 Waits for a stream to stop or digit matching a valid one digit exten to be pressed.
 
int ast_waitstream_fr (struct ast_channel *c, const char *breakon, const char *forward, const char *reverse, int ms)
 Same as waitstream but allows stream to be forwarded or rewound.
 
int ast_waitstream_fr_w_cb (struct ast_channel *c, const char *breakon, const char *forward, const char *reverse, int ms, ast_waitstream_fr_cb cb)
 Same as waitstream_fr but allows a callback to be alerted when a user fastforwards or rewinds the file.
 
int ast_waitstream_full (struct ast_channel *c, const char *breakon, int audiofd, int cmdfd)
 
struct ast_filestreamast_writefile (const char *filename, const char *type, const char *comment, int flags, int check, mode_t mode)
 Starts writing a file.
 
int ast_writestream (struct ast_filestream *fs, struct ast_frame *f)
 Writes a frame to a stream.
 
static char * build_filename (const char *filename, const char *ext)
 construct a filename. Absolute pathnames are preserved, relative names are prefixed by the sounds/ directory. The wav49 suffix is replaced by 'WAV'. Returns a malloc'ed string to be freed by the caller.
 
static int copy (const char *infile, const char *outfile)
 
static void file_shutdown (void)
 
static int fileexists_core (const char *filename, const char *fmt, const char *preflang, char *buf, int buflen, struct ast_format_cap *result_cap)
 helper routine to locate a file with a given format and language preference.
 
static int fileexists_test (const char *filename, const char *fmt, const char *lang, char *buf, int buflen, struct ast_format_cap *result_cap)
 test if a file exists for a given format.
 
static int filehelper (const char *filename, const void *arg2, const char *fmt, const enum file_action action)
 
static void filestream_close (struct ast_filestream *f)
 
static void filestream_destructor (void *arg)
 
static int fn_wrapper (struct ast_filestream *s, const char *comment, enum wrap_fn mode)
 
static struct ast_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
 

Variables

int ast_language_is_prefix = 1
 The following variable controls the layout of localized sound files. If 0, use the historical layout with prefix just before the filename (i.e. digits/en/1.gsm , digits/it/1.gsm or default to digits/1.gsm), if 1 put the prefix at the beginning of the filename (i.e. en/digits/1.gsm, it/digits/1.gsm or default to digits/1.gsm). The latter permits a language to be entirely in one directory.
 
static struct ast_cli_entry cli_file []
 
static struct formats formats = AST_RWLIST_HEAD_INIT_VALUE
 
static ast_mutex_t read_dirs_lock = AST_MUTEX_INIT_VALUE
 Lock to hold when iterating over directories.
 

Detailed Description

Generic File Format Support.

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

Definition in file file.c.

Macro Definition Documentation

◆ exts_compare

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

Definition at line 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 970 of file file.c.

970 {
974};
@ FSREAD_FAILURE
Definition file.c:971
@ FSREAD_SUCCESS_SCHED
Definition file.c:972
@ FSREAD_SUCCESS_NOSCHED
Definition file.c:973

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

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

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

Referenced by __ast_file_read_dirs(), and ast_file_read_dirs().

◆ __ast_format_def_register()

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

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

Return values
0on success
-1on failure

Definition at line 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.
#define AST_RWLIST_TRAVERSE
#define AST_RWLIST_INSERT_HEAD
Each supported file format is described by the following structure.
Definition mod_format.h:43
char name[80]
Definition mod_format.h:44
struct ast_format_def::@252 list
char exts[80]
Definition mod_format.h:45
Definition file.c:70
static struct test_val b
static struct test_val a

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

1085{
1086 s->owner = chan;
1087 return 0;
1088}
struct ast_channel * owner
Definition mod_format.h:116

References ast_filestream::owner.

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

◆ ast_closestream()

int ast_closestream ( struct ast_filestream f)

Closes a stream.

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

Definition at line 1138 of file file.c.

1139{
1140 /* This used to destroy the filestream, but it now just decrements a refcount.
1141 * We close the stream in order to quit queuing frames now, because we might
1142 * change the writeformat, which could result in a subsequent write error, if
1143 * the format is different. */
1144 if (f == NULL) {
1145 return 0;
1146 }
1148 ao2_ref(f, -1);
1149 return 0;
1150}
#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:2513

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

◆ ast_file_init()

int ast_file_init ( void  )

Provided by file.c

Definition at line 2093 of file file.c.

2094{
2099 return 0;
2100}
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:2086
static struct ast_cli_entry cli_file[]
Definition file.c:2082
struct stasis_message_type * ast_format_unregister_type(void)
Get the message type used for signaling a format unregistration.
#define STASIS_MESSAGE_TYPE_INIT(name)
Boiler-plate messaging macro for initializing message types.
Definition stasis.h:1524
#define ARRAY_LEN(a)
Definition utils.h:706

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

Referenced by asterisk_daemon().

◆ ast_file_mkftemp()

FILE * ast_file_mkftemp ( char *  template_name,
mode_t  mode 
)

same as mkstemp, but return a FILE

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

Definition at line 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(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), AST_TEST_DEFINE(), sendmail(), and sendpage().

◆ ast_file_read_dirs()

int ast_file_read_dirs ( const char *  dir_name,
ast_file_on_file  on_file,
void *  obj,
int  max_depth 
)

Recursively iterate through files and directories up to max_depth.

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

Definition at line 1301 of file file.c.

1302{
1303 int res;
1304
1305 errno = 0;
1306
1307#if !defined(__GLIBC__)
1309#endif
1310
1311 res = __ast_file_read_dirs(dir_name, on_file, obj, max_depth);
1312
1313#if !defined(__GLIBC__)
1315#endif
1316
1317 return res;
1318}
static ast_mutex_t read_dirs_lock
Lock to hold when iterating over directories.
Definition file.c:1298
#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 1178 of file file.c.

1179{
1180 return filehelper(filename, filename2, fmt, ACTION_COPY);
1181}
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 1168 of file file.c.

1169{
1170 return filehelper(filename, NULL, fmt, ACTION_DELETE);
1171}

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(), leave_voicemail(), mixmonitor_thread(), msg_create_from_file(), play_record_review(), record_exec(), recording_cancel(), setup_privacy_args(), vm_delete(), and vm_delete().

◆ ast_fileexists()

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

Checks for the existence of a given file.

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

Definition at line 1156 of file file.c.

1157{
1158 char *buf;
1159 int buflen;
1160
1161 if (preflang == NULL)
1162 preflang = "";
1163 buflen = strlen(preflang) + strlen(filename) + 4; /* room for everything */
1164 buf = ast_alloca(buflen);
1165 return fileexists_core(filename, fmt, preflang, buf, buflen, NULL) ? 1 : 0;
1166}
#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:760

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(), invent_message(), leave_voicemail(), leave_voicemail(), meetme_menu_admin_extended(), minivm_delete_exec(), moh_files_next(), msg_create_from_file(), page_exec(), play_file(), play_message(), play_message_by_id_helper(), play_message_callerid(), readexten_exec(), record_exec(), retrydial_exec(), sayname(), setup_privacy_args(), sound_file_exists(), stasis_app_control_record(), vm_intro(), vm_msg_play(), vm_newuser_setup(), vm_options(), and vm_tempgreeting().

◆ ast_filerename()

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

Renames a file.

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

Definition at line 1173 of file file.c.

1174{
1175 return filehelper(filename, filename2, fmt, ACTION_RENAME);
1176}

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
#define AST_RWLIST_TRAVERSE_SAFE_BEGIN
#define AST_RWLIST_TRAVERSE_SAFE_END

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

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

◆ ast_format_str_reduce()

char * ast_format_str_reduce ( char *  fmts)

Remove duplicate formats from a format string.

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

Definition at line 1936 of file file.c.

1937{
1938 struct ast_format_def *f;
1939 struct ast_format_def *fmts_ptr[AST_MAX_FORMATS];
1940 char *fmts_str[AST_MAX_FORMATS];
1941 char *stringp, *type;
1942 char *orig = fmts;
1943 int i, j, x, first, found = 0;
1944 int len = strlen(fmts) + 1;
1945 int res;
1946
1947 if (AST_RWLIST_RDLOCK(&formats)) {
1948 ast_log(LOG_WARNING, "Unable to lock format list\n");
1949 return NULL;
1950 }
1951
1952 stringp = ast_strdupa(fmts);
1953
1954 for (x = 0; (type = strsep(&stringp, "|")) && x < AST_MAX_FORMATS; x++) {
1956 if (exts_compare(f->exts, type)) {
1957 found = 1;
1958 break;
1959 }
1960 }
1961
1962 fmts_str[x] = type;
1963 if (found) {
1964 fmts_ptr[x] = f;
1965 } else {
1966 fmts_ptr[x] = NULL;
1967 }
1968 }
1970
1971 first = 1;
1972 for (i = 0; i < x; i++) {
1973 /* ignore invalid entries */
1974 if (!fmts_ptr[i]) {
1975 ast_log(LOG_WARNING, "ignoring unknown format '%s'\n", fmts_str[i]);
1976 continue;
1977 }
1978
1979 /* special handling for the first entry */
1980 if (first) {
1981 res = snprintf(fmts, len, "%s", fmts_str[i]);
1982 fmts += res;
1983 len -= res;
1984 first = 0;
1985 continue;
1986 }
1987
1988 found = 0;
1989 for (j = 0; j < i; j++) {
1990 /* this is a duplicate */
1991 if (fmts_ptr[j] == fmts_ptr[i]) {
1992 found = 1;
1993 break;
1994 }
1995 }
1996
1997 if (!found) {
1998 res = snprintf(fmts, len, "|%s", fmts_str[i]);
1999 fmts += res;
2000 len -= res;
2001 }
2002 }
2003
2004 if (first) {
2005 ast_log(LOG_WARNING, "no known formats found in format list (%s)\n", orig);
2006 return NULL;
2007 }
2008
2009 return orig;
2010}
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[]
#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 1026 of file file.c.

1027{
1028 struct ast_filestream *fs = (struct ast_filestream *)data;
1029 enum fsread_res res;
1030
1031 res = ast_readaudio_callback(fs);
1032
1033 if (res == FSREAD_SUCCESS_SCHED)
1034 return 1;
1035
1036 return 0;
1037}
fsread_res
Definition file.c:970
static enum fsread_res ast_readaudio_callback(struct ast_filestream *s)
Definition file.c:978
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 1071 of file file.c.

1072{
1073 struct ast_filestream *fs = (struct ast_filestream *)data;
1074 enum fsread_res res;
1075
1076 res = ast_readvideo_callback(fs);
1077
1078 if (res == FSREAD_SUCCESS_SCHED)
1079 return 1;
1080
1081 return 0;
1082}
static enum fsread_res ast_readvideo_callback(struct ast_filestream *s)
Definition file.c:1041

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

2062{
2063 struct ast_format_def *f;
2065
2066 ast_assert(buffer && capacity);
2067
2069 if (type_in_list(f->mime_types, mime_type, strcasecmp)) {
2070 size_t item_len = strcspn(f->exts, "|");
2071 size_t bytes_written = snprintf(buffer, capacity, ".%.*s", (int) item_len, f->exts);
2072 if (bytes_written < capacity) {
2073 /* Only return success if we didn't truncate */
2074 return 1;
2075 }
2076 }
2077 }
2078
2079 return 0;
2080}
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:779

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

Referenced by derive_extension_from_mime_type().

◆ ast_get_format_for_file_ext()

struct ast_format * ast_get_format_for_file_ext ( const char *  file_ext)

Get the ast_format associated with the given file extension.

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

Definition at line 2048 of file file.c.

2049{
2050 struct ast_format_def *f;
2053 if (exts_compare(f->exts, file_ext)) {
2054 return f->format;
2055 }
2056 }
2057
2058 return NULL;
2059}
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 864 of file file.c.

865{
866 return openstream_internal(chan, filename, preflang, 0, 0);
867}
static struct ast_filestream * openstream_internal(struct ast_channel *chan, const char *filename, const char *preflang, int asis, int quiet)
Definition file.c:809

References ast_filestream::filename, and openstream_internal().

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

◆ ast_openstream_full()

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

Opens stream for use in seeking, playing.

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

Definition at line 869 of file file.c.

871{
872 return openstream_internal(chan, filename, preflang, asis, 0);
873}

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

877{
878 /* As above, but for video. But here we don't have translators
879 * so we must enforce a format.
880 */
881 struct ast_format_cap *nativeformats, *tmp_cap;
882 char *buf;
883 int buflen;
884 int i, fd;
885
886 if (preflang == NULL) {
887 preflang = "";
888 }
889 buflen = strlen(preflang) + strlen(filename) + 4;
890 buf = ast_alloca(buflen);
891
892 ast_channel_lock(chan);
893 nativeformats = ao2_bump(ast_channel_nativeformats(chan));
894 ast_channel_unlock(chan);
895
896 /* is the channel capable of video without translation ?*/
897 if (!ast_format_cap_has_type(nativeformats, AST_MEDIA_TYPE_VIDEO)) {
898 ao2_cleanup(nativeformats);
899 return NULL;
900 }
902 ao2_cleanup(nativeformats);
903 return NULL;
904 }
905 /* Video is supported, so see what video formats exist for this file */
906 if (!fileexists_core(filename, NULL, preflang, buf, buflen, tmp_cap)) {
907 ao2_ref(tmp_cap, -1);
908 ao2_cleanup(nativeformats);
909 return NULL;
910 }
911
912 /* iterate over file formats and pick the first one compatible with the channel's native formats */
913 for (i = 0; i < ast_format_cap_count(tmp_cap); ++i) {
914 struct ast_format *format = ast_format_cap_get_format(tmp_cap, i);
915
916 if ((ast_format_get_type(format) != AST_MEDIA_TYPE_VIDEO) ||
917 !ast_format_cap_iscompatible(nativeformats, tmp_cap)) {
918 ao2_ref(format, -1);
919 continue;
920 }
921
922 fd = filehelper(buf, chan, ast_format_get_name(format), ACTION_OPEN);
923 if (fd >= 0) {
924 ao2_ref(format, -1);
925 ao2_ref(tmp_cap, -1);
926 ao2_cleanup(nativeformats);
927 return ast_channel_vstream(chan);
928 }
929 ast_log(LOG_WARNING, "File %s has video but couldn't be opened\n", filename);
930 ao2_ref(format, -1);
931 }
932 ao2_ref(tmp_cap, -1);
933 ao2_cleanup(nativeformats);
934
935 return NULL;
936}
#define ao2_cleanup(obj)
Definition astobj2.h:1934
#define ao2_bump(obj)
Bump refcount on an AO2 object by one, returning the object.
Definition astobj2.h:480
#define ast_channel_lock(chan)
Definition channel.h:2983
struct ast_format_cap * ast_channel_nativeformats(const struct ast_channel *chan)
struct ast_filestream * ast_channel_vstream(const struct ast_channel *chan)
#define ast_channel_unlock(chan)
Definition channel.h:2984
@ AST_MEDIA_TYPE_VIDEO
Definition codec.h:33
enum ast_media_type ast_format_get_type(const struct ast_format *format)
Get the media type of a format.
Definition format.c:354
const char * ast_format_get_name(const struct ast_format *format)
Get the name associated with a format.
Definition format.c:334
struct ast_format * ast_format_cap_get_format(const struct ast_format_cap *cap, int position)
Get the format at a specific index.
Definition format_cap.c:408
@ AST_FORMAT_CAP_FLAG_DEFAULT
Definition format_cap.h:38
int ast_format_cap_has_type(const struct ast_format_cap *cap, enum ast_media_type type)
Find out if the capabilities structure has any formats of a specific type.
Definition format_cap.c:621
int ast_format_cap_iscompatible(const struct ast_format_cap *cap1, const struct ast_format_cap *cap2)
Determine if any joint capabilities exist between two capabilities structures.
Definition format_cap.c:661
#define ast_format_cap_alloc(flags)
Allocate a new ast_format_cap structure.
Definition format_cap.h:49
size_t ast_format_cap_count(const struct ast_format_cap *cap)
Get the number of formats present within the capabilities structure.
Definition format_cap.c:403
Format capabilities structure, holds formats + preference order + etc.
Definition format_cap.c:54
Definition of a media format.
Definition format.c:43

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

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

◆ ast_playstream()

int ast_playstream ( struct ast_filestream s)

Play a open stream on a channel.

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

Definition at line 1090 of file file.c.

1091{
1092 enum fsread_res res;
1093
1095 res = ast_readaudio_callback(s);
1096 else
1097 res = ast_readvideo_callback(s);
1098
1099 return (res == FSREAD_FAILURE) ? -1 : 0;
1100}
@ AST_MEDIA_TYPE_AUDIO
Definition codec.h:32
struct ast_format_def * fmt
Definition mod_format.h:103

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

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

◆ ast_ratestream()

int ast_ratestream ( struct ast_filestream fs)

Return the sample rate of the stream's format.

Parameters
fsfs to act on
Returns
sample rate in Hz

Definition at line 1117 of file file.c.

1118{
1120}
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 978 of file file.c.

979{
980 int whennext = 0;
981
982 while (!whennext) {
983 struct ast_frame *fr;
984
985 if (s->orig_chan_name && strcasecmp(ast_channel_name(s->owner), s->orig_chan_name)) {
986 goto return_failure;
987 }
988
989 fr = read_frame(s, &whennext);
990
991 if (!fr /* stream complete */ || ast_write(s->owner, fr) /* error writing */) {
992 if (fr) {
993 ast_debug(2, "Failed to write frame\n");
994 ast_frfree(fr);
995 }
996 goto return_failure;
997 }
998
999 if (fr) {
1000 ast_frfree(fr);
1001 }
1002 }
1003
1004 if (whennext != s->lasttimeout) {
1005 if (ast_channel_timingfd(s->owner) > -1) {
1006 float samp_rate = (float) ast_format_get_sample_rate(s->fmt->format);
1007 unsigned int rate;
1008
1009 rate = (unsigned int) roundf(samp_rate / ((float) whennext));
1010
1012 } else {
1014 }
1015 s->lasttimeout = whennext;
1017 }
1018 return FSREAD_SUCCESS_SCHED;
1019
1020return_failure:
1022 ast_settimeout(s->owner, 0, NULL, NULL);
1023 return FSREAD_FAILURE;
1024}
float roundf(float x)
const char * ast_channel_name(const struct ast_channel *chan)
int ast_settimeout_full(struct ast_channel *c, unsigned int rate, int(*func)(const void *data), void *data, unsigned int is_ao2_obj)
Definition channel.c:3189
void ast_channel_streamid_set(struct ast_channel *chan, int value)
int ast_write(struct ast_channel *chan, struct ast_frame *frame)
Write a frame to a channel This function writes the given frame to the indicated channel.
Definition channel.c:5167
int ast_channel_timingfd(const struct ast_channel *chan)
int ast_settimeout(struct ast_channel *c, unsigned int rate, int(*func)(const void *data), void *data)
Enable or disable timer ticks for a channel.
Definition channel.c:3184
struct ast_sched_context * ast_channel_sched(const struct ast_channel *chan)
static int ast_fsread_audio(const void *data)
Definition file.c:1026
static struct ast_frame * read_frame(struct ast_filestream *s, int *whennext)
Definition file.c:938
#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 1413 of file file.c.

1414{
1415 FILE *bfile;
1416 struct ast_format_def *f;
1417 struct ast_filestream *fs = NULL;
1418 char *fn;
1419 int format_found = 0;
1420
1422
1423 AST_RWLIST_TRAVERSE(&formats, f, list) {
1424 fs = NULL;
1425 if (!exts_compare(f->exts, type))
1426 continue;
1427 else
1428 format_found = 1;
1429
1431 if (!fn) {
1432 continue;
1433 }
1434 errno = 0;
1435 bfile = fopen(fn, "r");
1436
1437 if (!bfile || (fs = get_filestream(f, bfile)) == NULL || open_wrapper(fs) ) {
1438 ast_log(LOG_WARNING, "Unable to open %s\n", fn);
1439 if (fs) {
1440 ast_closestream(fs);
1441 }
1442 fs = NULL;
1443 bfile = NULL;
1444 ast_free(fn);
1445 break;
1446 }
1447 /* found it */
1448 fs->trans = NULL;
1449 fs->fmt = f;
1450 fs->flags = flags;
1451 fs->mode = mode;
1453 fs->vfs = NULL;
1454 ast_free(fn);
1455 break;
1456 }
1457
1459 if (!format_found)
1460 ast_log(LOG_WARNING, "No such format '%s'\n", type);
1461
1462 return fs;
1463}
#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:1138
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

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

964{
965 int whennext = 0;
966
967 return read_frame(s, &whennext);
968}

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

1042{
1043 int whennext = 0;
1044
1045 while (!whennext) {
1046 struct ast_frame *fr = read_frame(s, &whennext);
1047
1048 if (!fr /* stream complete */ || ast_write(s->owner, fr) /* error writing */) {
1049 if (fr) {
1050 ast_debug(2, "Failed to write frame\n");
1051 ast_frfree(fr);
1052 }
1054 return FSREAD_FAILURE;
1055 }
1056
1057 if (fr) {
1058 ast_frfree(fr);
1059 }
1060 }
1061
1062 if (whennext != s->lasttimeout) {
1064 s->lasttimeout = whennext;
1066 }
1067
1068 return FSREAD_SUCCESS_SCHED;
1069}
void ast_channel_vstreamid_set(struct ast_channel *chan, int value)
static int ast_fsread_video(const void *data)
Definition file.c:1071

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

1103{
1104 return fs->fmt->seek(fs, sample_offset, whence);
1105}
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:1762
@ AST_CEL_STREAM_END
A stream ended.
Definition cel.h:84
void ast_channel_stream_set(struct ast_channel *chan, struct ast_filestream *value)
struct ast_format * ast_channel_oldwriteformat(struct ast_channel *chan)
int ast_set_write_format(struct ast_channel *chan, struct ast_format *format)
Sets write format on channel chan.
Definition channel.c:5826
struct ast_filestream * ast_channel_stream(const struct ast_channel *chan)
void ast_channel_vstream_set(struct ast_channel *chan, struct ast_filestream *value)
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
Definition json.c:73
struct ast_json * ast_json_pack(char const *format,...)
Helper for creating complex JSON values.
Definition json.c:612
Abstract JSON element (object, array, string, int, ...).

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

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

◆ ast_stream_and_wait()

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

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

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

Definition at line 1920 of file file.c.

1921{
1922 int res = 0;
1923 if (!ast_strlen_zero(file)) {
1924 res = ast_streamfile(chan, file, ast_channel_language(chan));
1925 if (!res) {
1926 res = ast_waitstream(chan, digits);
1927 }
1928 }
1929 if (res == -1) {
1930 ast_stopstream(chan);
1931 }
1932
1933 return res;
1934}
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:1320
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:1882
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition strings.h:65

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

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

◆ ast_stream_fastforward()

int ast_stream_fastforward ( struct ast_filestream fs,
off_t  ms 
)

Fast forward stream ms.

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

Definition at line 1122 of file file.c.

1123{
1124 return ast_seekstream(fs, ms * DEFAULT_SAMPLES_PER_MS, SEEK_CUR);
1125}
#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:1102

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

1128{
1129 off_t offset = ast_tellstream(fs);
1130 if (ms * DEFAULT_SAMPLES_PER_MS > offset) {
1131 /* Don't even bother asking the file format to seek to a negative offset... */
1132 ast_debug(1, "Restarting, rather than seeking to negative offset %ld\n", (long) (offset - (ms * DEFAULT_SAMPLES_PER_MS)));
1133 return ast_seekstream(fs, 0, SEEK_SET);
1134 }
1135 return ast_seekstream(fs, -ms * DEFAULT_SAMPLES_PER_MS, SEEK_CUR);
1136}
off_t ast_tellstream(struct ast_filestream *fs)
Tell where we are in a stream.
Definition file.c:1112

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

1322{
1323 struct ast_json * cel_event = NULL;
1324 struct ast_filestream *fs = NULL;
1325 struct ast_filestream *vfs = NULL;
1326 off_t pos;
1327 int seekattempt;
1328 int res;
1329 char custom_filename[256];
1330 char *tmp_filename;
1331
1332 /* If file with the same name exists in /var/lib/asterisk/sounds/custom directory, use that file.
1333 * Otherwise, use the original file*/
1334
1336 memset(custom_filename, 0, sizeof(custom_filename));
1337 snprintf(custom_filename, sizeof(custom_filename), "custom/%s", filename);
1338 fs = openstream_internal(chan, custom_filename, preflang, 0, 1); /* open stream, do not warn for missing files */
1339 if (fs) {
1340 tmp_filename = custom_filename;
1341 ast_debug(3, "Found file %s in custom directory\n", filename);
1342 }
1343 }
1344
1345 if (!fs) {
1346 fs = ast_openstream(chan, filename, preflang);
1347 if (!fs) {
1348 struct ast_str *codec_buf = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN);
1349 ast_channel_lock(chan);
1350 ast_log(LOG_WARNING, "Unable to open %s (format %s)\n",
1351 filename, ast_format_cap_get_names(ast_channel_nativeformats(chan), &codec_buf));
1352 ast_channel_unlock(chan);
1353 return -1;
1354 }
1355 tmp_filename = (char *)filename;
1356 }
1357
1358 /* check to see if there is any data present (not a zero length file),
1359 * done this way because there is no where for ast_openstream_full to
1360 * return the file had no data. */
1361 pos = ftello(fs->f);
1362 seekattempt = fseeko(fs->f, -1, SEEK_END);
1363 if (seekattempt) {
1364 if (errno == EINVAL) {
1365 /* Zero-length file, as opposed to a pipe */
1366 return 0;
1367 } else {
1368 ast_seekstream(fs, 0, SEEK_SET);
1369 }
1370 } else {
1371 fseeko(fs->f, pos, SEEK_SET);
1372 }
1373
1374 vfs = ast_openvstream(chan, tmp_filename, preflang);
1375 if (vfs) {
1376 ast_debug(1, "Ooh, found a video stream, too, format %s\n", ast_format_get_name(vfs->fmt->format));
1377 }
1378
1381 if (ast_applystream(chan, fs))
1382 return -1;
1383 if (vfs && ast_applystream(chan, vfs))
1384 return -1;
1385 ast_test_suite_event_notify("PLAYBACK", "Message: %s\r\nChannel: %s", tmp_filename, ast_channel_name(chan));
1386 res = ast_playstream(fs);
1387 if (!res && vfs)
1388 res = ast_playstream(vfs);
1389
1390 cel_event = ast_json_pack("{ s: s, s: {s: s, s: s, s: s}}",
1391 "event", "FILE_STREAM_BEGIN",
1392 "extra",
1393 "sound", tmp_filename,
1395 "language", preflang ? preflang : "default"
1396 );
1397 if (cel_event) {
1399 } else {
1400 ast_log(LOG_WARNING, "Unable to build extradata for sound file STREAM_BEGIN event on channel %s", ast_channel_name(chan));
1401 }
1402 ast_json_unref(cel_event);
1403
1404 if (VERBOSITY_ATLEAST(3)) {
1405 ast_channel_lock(chan);
1406 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");
1407 ast_channel_unlock(chan);
1408 }
1409
1410 return res;
1411}
@ AST_CEL_STREAM_BEGIN
A stream started.
Definition cel.h:82
@ AST_FLAG_MASQ_NOSTREAM
Definition channel.h:1034
struct ast_flags * ast_channel_flags(struct ast_channel *chan)
struct ast_format * ast_channel_writeformat(struct ast_channel *chan)
struct ast_filestream * ast_openstream(struct ast_channel *chan, const char *filename, const char *preflang)
Opens stream for use in seeking, playing.
Definition file.c:864
int ast_applystream(struct ast_channel *chan, struct ast_filestream *s)
Applies a open stream to a channel.
Definition file.c:1084
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:875
static int is_absolute_path(const char *filename)
Definition file.c:694
int ast_playstream(struct ast_filestream *s)
Play a open stream on a channel.
Definition file.c:1090
#define AST_FORMAT_CAP_NAMES_LEN
Definition format_cap.h:324
const char * ast_format_cap_get_names(const struct ast_format_cap *cap, struct ast_str **buf)
Get the names of codecs of a set of formats.
Definition format_cap.c:742
#define VERBOSITY_ATLEAST(level)
#define ast_opt_sounds_search_custom
Definition options.h:148
#define ast_str_alloca(init_len)
Definition strings.h:848
Support for dynamic strings.
Definition strings.h:623
#define ast_test_suite_event_notify(s, f,...)
Definition test.h:189
#define ast_test_flag(p, flag)
Definition utils.h:64

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

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

◆ ast_tellstream()

off_t ast_tellstream ( struct ast_filestream fs)

Tell where we are in a stream.

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

Definition at line 1112 of file file.c.

1113{
1114 return fs->fmt->tell(fs);
1115}
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 1107 of file file.c.

1108{
1109 return fs->fmt->trunc(fs);
1110}
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 1882 of file file.c.

1883{
1884 int res;
1885
1886 res = waitstream_core(c, breakon, NULL, NULL, 0, -1, -1, NULL, NULL /* no callback */);
1887
1888 return sanitize_waitstream_return(res);
1889}
static int sanitize_waitstream_return(int return_value)
Definition file.c:1865
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:1655
static struct test_val c

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

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

◆ ast_waitstream_exten()

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

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

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

Definition at line 1901 of file file.c.

1902{
1903 int res;
1904
1905 /* Waitstream, with return in the case of a valid 1 digit extension */
1906 /* in the current or specified context being pressed */
1907 if (!context)
1909 res = waitstream_core(c, NULL, NULL, NULL, 0,
1910 -1, -1, context, NULL /* no callback */);
1911
1912 return sanitize_waitstream_return(res);
1913}
const char * ast_channel_context(const struct ast_channel *chan)

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

Referenced by pbx_builtin_background().

◆ ast_waitstream_fr()

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

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

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

Definition at line 1851 of file file.c.

1852{
1853 return waitstream_core(c, breakon, forward, reverse, ms,
1854 -1 /* no audiofd */, -1 /* no cmdfd */, NULL /* no context */, NULL /* no callback */);
1855}

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

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

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

1466{
1467 int fd, myflags = 0;
1468 /* compiler claims this variable can be used before initialization... */
1469 FILE *bfile = NULL;
1470 struct ast_format_def *f;
1471 struct ast_filestream *fs = NULL;
1472 char *buf = NULL;
1473 size_t size = 0;
1474 int format_found = 0;
1475
1477
1478 /* set the O_TRUNC flag if and only if there is no O_APPEND specified */
1479 /* We really can't use O_APPEND as it will break WAV header updates */
1480 if (flags & O_APPEND) {
1481 flags &= ~O_APPEND;
1482 } else {
1483 myflags = O_TRUNC;
1484 }
1485
1486 myflags |= O_WRONLY | O_CREAT;
1487
1488 /* XXX need to fix this - we should just do the fopen,
1489 * not open followed by fdopen()
1490 */
1491 AST_RWLIST_TRAVERSE(&formats, f, list) {
1492 char *fn, *orig_fn = NULL;
1493 if (fs)
1494 break;
1495
1496 if (!exts_compare(f->exts, type))
1497 continue;
1498 else
1499 format_found = 1;
1500
1502 if (!fn) {
1503 continue;
1504 }
1505 fd = open(fn, flags | myflags, mode);
1506 if (fd > -1) {
1507 /* fdopen() the resulting file stream */
1508 bfile = fdopen(fd, ((flags | myflags) & O_RDWR) ? "w+" : "w");
1509 if (!bfile) {
1510 ast_log(LOG_WARNING, "Whoa, fdopen failed: %s!\n", strerror(errno));
1511 close(fd);
1512 fd = -1;
1513 }
1514 }
1515
1516 if (ast_opt_cache_record_files && (fd > -1)) {
1517 char *c;
1518
1519 fclose(bfile); /* this also closes fd */
1520 /*
1521 We touch orig_fn just as a place-holder so other things (like vmail) see the file is there.
1522 What we are really doing is writing to record_cache_dir until we are done then we will mv the file into place.
1523 */
1524 orig_fn = ast_strdup(fn);
1525 for (c = fn; *c; c++)
1526 if (*c == '/')
1527 *c = '_';
1528
1529 size = strlen(fn) + strlen(record_cache_dir) + 2;
1530 buf = ast_malloc(size);
1531 strcpy(buf, record_cache_dir);
1532 strcat(buf, "/");
1533 strcat(buf, fn);
1534 ast_free(fn);
1535 fn = buf;
1536 fd = open(fn, flags | myflags, mode);
1537 if (fd > -1) {
1538 /* fdopen() the resulting file stream */
1539 bfile = fdopen(fd, ((flags | myflags) & O_RDWR) ? "w+" : "w");
1540 if (!bfile) {
1541 ast_log(LOG_WARNING, "Whoa, fdopen failed: %s!\n", strerror(errno));
1542 close(fd);
1543 fd = -1;
1544 }
1545 }
1546 }
1547 if (fd > -1) {
1548 errno = 0;
1549 fs = get_filestream(f, bfile);
1550 if (fs) {
1551 if ((fs->write_buffer = ast_malloc(32768))) {
1552 setvbuf(fs->f, fs->write_buffer, _IOFBF, 32768);
1553 }
1554 }
1555 if (!fs || rewrite_wrapper(fs, comment)) {
1556 ast_log(LOG_WARNING, "Unable to rewrite %s\n", fn);
1557 close(fd);
1558 if (orig_fn) {
1559 unlink(fn);
1560 unlink(orig_fn);
1561 ast_free(orig_fn);
1562 }
1563 if (fs) {
1564 ast_closestream(fs);
1565 fs = NULL;
1566 }
1567 /*
1568 * 'fn' was has either been allocated from build_filename, or that was freed
1569 * and now 'fn' points to memory allocated for 'buf'. Either way the memory
1570 * now needs to be released.
1571 */
1572 ast_free(fn);
1573 continue;
1574 }
1575 fs->trans = NULL;
1576 fs->fmt = f;
1577 fs->flags = flags;
1578 fs->mode = mode;
1579 if (orig_fn) {
1580 fs->realfilename = orig_fn;
1581 fs->filename = fn;
1582 /*
1583 * The above now manages the memory allocated for 'orig_fn' and 'fn', so
1584 * set them to NULL, so they don't get released at the end of the loop.
1585 */
1586 orig_fn = NULL;
1587 fn = NULL;
1588 } else {
1589 fs->realfilename = NULL;
1591 }
1592 fs->vfs = NULL;
1593 /* If truncated, we'll be at the beginning; if not truncated, then append */
1594 f->seek(fs, 0, SEEK_END);
1595 } else if (errno != EEXIST) {
1596 ast_log(LOG_WARNING, "Unable to open file %s: %s\n", fn, strerror(errno));
1597 if (orig_fn)
1598 unlink(orig_fn);
1599 }
1600 /* Free 'fn', or if 'fn' points to 'buf' then free 'buf' */
1601 ast_free(fn);
1602 ast_free(orig_fn);
1603 }
1604
1606
1607 if (!format_found)
1608 ast_log(LOG_WARNING, "No such format '%s'\n", type);
1609
1610 return fs;
1611}
#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, cur))) {
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:1465
enum ast_format_cmp_res ast_format_cmp(const struct ast_format *format1, const struct ast_format *format2)
Compare two formats.
Definition format.c:201
@ AST_FORMAT_CMP_EQUAL
Definition format.h:36
@ AST_FORMAT_CMP_NOT_EQUAL
Definition format.h:38
#define AST_LIST_NEXT(elm, field)
Returns the next entry in the list after the given entry.
struct ast_format * lastwriteformat
Definition mod_format.h:114
int(* write)(struct ast_filestream *, struct ast_frame *)
Definition mod_format.h:66
struct ast_format * format
struct ast_frame_subclass subclass
enum ast_frame_type frametype
struct ast_frame * ast_translate(struct ast_trans_pvt *tr, struct ast_frame *f, int consume)
translates one or more frames Apply an input frame into the translator and receive zero or one output...
Definition translate.c:623
void ast_translator_free_path(struct ast_trans_pvt *tr)
Frees a translator path Frees the given translator path structure.
Definition translate.c:533
struct ast_trans_pvt * ast_translator_build_path(struct ast_format *dest, struct ast_format *source)
Builds a translator path Build a path (possibly NULL) from source to dest.
Definition translate.c:543

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

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

◆ build_filename()

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

construct a filename. Absolute pathnames are preserved, relative names are prefixed by the sounds/ directory. 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:151
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 2086 of file file.c.

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

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

Referenced by ast_file_init().

◆ fileexists_core()

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

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

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

Definition at line 760 of file file.c.

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

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

712{
713 if (buf == NULL) {
714 return 0;
715 }
716
717 if (is_remote_path(filename) && !ast_media_cache_retrieve(filename, NULL, buf, buflen)) {
718 return filehelper(buf, result_cap, NULL, ACTION_EXISTS);
719 }
720
721 if (ast_language_is_prefix && !is_absolute_path(filename)) { /* new layout */
722 if (lang) {
723 snprintf(buf, buflen, "%s/%s", lang, filename);
724 } else {
725 snprintf(buf, buflen, "%s", filename);
726 }
727 } else { /* old layout */
728 strcpy(buf, filename); /* first copy the full string */
729 if (lang) {
730 /* insert the language and suffix if needed */
731 const char *c = strrchr(filename, '/');
732 int offset = c ? c - filename + 1 : 0; /* points right after the last '/' */
733 snprintf(buf + offset, buflen - offset, "%s/%s", lang, filename + offset);
734 }
735 }
736
737 return filehelper(buf, result_cap, fmt, ACTION_EXISTS);
738}
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:699
int ast_media_cache_retrieve(const char *uri, const char *preferred_file_name, char *file_path, size_t len)
Retrieve an item from the cache.

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

Referenced by fileexists_core().

◆ filehelper()

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

Definition at line 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_debug(3, "File %s format is not compatible with the channel\n", fn);
604 ast_free(fn);
605 continue; /* not a supported format */
606 }
607 if ( (bfile = fopen(fn, "r")) == NULL) {
608 ast_log(LOG_WARNING, "Failed to open file %s due to: %s\n", fn, strerror(errno));
609 ast_free(fn);
610 continue; /* cannot open file */
611 }
612 s = get_filestream(f, bfile);
613 if (!s) {
614 ast_log(LOG_WARNING, "Failed to open file %s due to: file stream creation failure\n", fn);
615 fclose(bfile);
616 ast_free(fn); /* cannot allocate descriptor */
617 continue;
618 }
619 if (open_wrapper(s)) {
620 ast_free(fn);
622 continue; /* cannot run open on file */
623 }
624 if (st.st_size == 0) {
625 ast_log(LOG_WARNING, "File %s detected to have zero size.\n", fn);
626 }
627 /* ok this is good for OPEN */
628 res = 1; /* found */
629 s->lasttimeout = -1;
630 s->fmt = f;
631 s->trans = NULL;
632 s->filename = NULL;
634 if (ast_channel_stream(chan))
636 ast_channel_stream_set(chan, s);
637 } else {
638 if (ast_channel_vstream(chan))
641 }
642 ast_free(fn);
643 break;
644 }
645 switch (action) {
646 case ACTION_OPEN:
647 break; /* will never get here */
648
649 case ACTION_EXISTS: /* return the matching format */
650 /* if arg2 is present, it is a format capabilities structure.
651 * Add this format to the set of formats this file can be played in */
652 if (arg2) {
653 ast_format_cap_append((struct ast_format_cap *) arg2, f->format, 0);
654 }
655 res = 1; /* file does exist and format it exists in is returned in arg2 */
656 break;
657
658 case ACTION_DELETE:
659 if ( (res = unlink(fn)) )
660 ast_log(LOG_WARNING, "unlink(%s) failed: %s\n", fn, strerror(errno));
661 break;
662
663 case ACTION_RENAME:
664 case ACTION_COPY: {
665 char *nfn = build_filename((const char *)arg2, ext);
666 if (!nfn)
667 ast_log(LOG_WARNING, "Out of memory\n");
668 else {
669 res = action == ACTION_COPY ? copy(fn, nfn) : rename(fn, nfn);
670 if (res)
671 ast_log(LOG_WARNING, "%s(%s,%s) failed: %s\n",
672 action == ACTION_COPY ? "copy" : "rename",
673 fn, nfn, strerror(errno));
674 ast_free(nfn);
675 }
676 }
677 break;
678
679 default:
680 ast_log(LOG_WARNING, "Unknown helper %u\n", action);
681 }
682 ast_free(fn);
683 }
684
685 /* If we have successfully opened a file, we are done. */
686 if (action == ACTION_OPEN && res == 1) {
687 break;
688 }
689 }
691 return res;
692}
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_debug, ast_format_cap_append, ast_format_cmp(), AST_FORMAT_CMP_NOT_EQUAL, ast_format_get_type(), ast_free, ast_log, AST_MEDIA_TYPE_AUDIO, AST_MEDIA_TYPE_VIDEO, AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, build_filename(), 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:3208
#define ast_module_unref(mod)
Release a reference to the module.
Definition module.h:483

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

Referenced by get_filestream().

◆ fn_wrapper()

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

Definition at line 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
479 if (!ast_module_running_ref(fmt->module)) {
480 return NULL;
481 }
482
484 if (!s) {
485 ast_module_unref(fmt->module);
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}
#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

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

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

◆ handle_cli_core_show_file_formats()

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

Definition at line 2012 of file file.c.

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

695{
696 return filename[0] == '/';
697}

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

700{
701 return strstr(filename, "://") ? 1 : 0;
702}

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

811{
812 /*
813 * Use fileexists_core() to find a file in a compatible
814 * language and format, set up a suitable translator,
815 * and open the stream.
816 */
817 struct ast_format_cap *file_fmt_cap;
818 int res;
819 int buflen;
820 char *buf;
821
822 if (!asis) {
823 /* do this first, otherwise we detect the wrong writeformat */
824 ast_stopstream(chan);
825 if (ast_channel_generator(chan))
827 }
828 if (preflang == NULL)
829 preflang = "";
830 buflen = strlen(preflang) + strlen(filename) + 4;
831 buf = ast_alloca(buflen);
832
833 if (!(file_fmt_cap = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT))) {
834 return NULL;
835 }
836 if (!fileexists_core(filename, NULL, preflang, buf, buflen, file_fmt_cap) ||
838
839 if (!quiet) {
840 ast_log(LOG_WARNING, "File %s does not exist in any format\n", filename);
841 }
842 ao2_ref(file_fmt_cap, -1);
843 return NULL;
844 }
845
846 /* Set the channel to a format we can work with and save off the previous format. */
847 ast_channel_lock(chan);
849 /* Set the channel to the best format that exists for the file. */
850 res = ast_set_write_format_from_cap(chan, file_fmt_cap);
851 ast_channel_unlock(chan);
852 /* don't need this anymore now that the channel's write format is set. */
853 ao2_ref(file_fmt_cap, -1);
854
855 if (res == -1) { /* No format available that works with this channel */
856 return NULL;
857 }
858 res = filehelper(buf, chan, NULL, ACTION_OPEN);
859 if (res >= 0)
860 return ast_channel_stream(chan);
861 return NULL;
862}
static int quiet
Definition ael_main.c:123
void ast_channel_set_oldwriteformat(struct ast_channel *chan, struct ast_format *format)
void ast_deactivate_generator(struct ast_channel *chan)
Definition channel.c:2892
struct ast_generator * ast_channel_generator(const struct ast_channel *chan)
int ast_set_write_format_from_cap(struct ast_channel *chan, struct ast_format_cap *formats)
Sets write format on channel chan Set write format for channel to whichever component of "format" is ...
Definition channel.c:5844

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

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

◆ publish_format_update()

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

Definition at line 94 of file file.c.

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

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

Referenced by __ast_format_def_register(), and ast_format_def_unregister().

◆ read_frame()

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

Definition at line 938 of file file.c.

939{
940 struct ast_frame *fr, *new_fr;
941
942 if (!s || !s->fmt) {
943 return NULL;
944 }
945
946 if (!(fr = s->fmt->read(s, whennext))) {
947 return NULL;
948 }
949
950 if (!(new_fr = ast_frisolate(fr))) {
951 ast_frfree(fr);
952 return NULL;
953 }
954
955 if (new_fr != fr) {
956 ast_frfree(fr);
957 fr = new_fr;
958 }
959
960 return fr;
961}
#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 1865 of file file.c.

1866{
1867 switch (return_value) {
1871 /* Fall through and set return_value to 0 */
1872 return_value = 0;
1873 break;
1874 default:
1875 /* Do nothing */
1876 break;
1877 }
1878
1879 return return_value;
1880}
@ 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

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

1617{
1618 switch (type)
1619 {
1621 {
1622 int eoftest;
1624 eoftest = fgetc(ast_channel_stream(c)->f);
1625 if (feof(ast_channel_stream(c)->f)) {
1627 } else {
1628 ungetc(eoftest, ast_channel_stream(c)->f);
1629 }
1630 }
1631 break;
1634 break;
1635 default:
1636 break;
1637 }
1638
1639 if (cb) {
1640 long ms_len = ast_tellstream(ast_channel_stream(c)) / (ast_format_get_sample_rate(ast_channel_stream(c)->fmt->format) / 1000);
1641 cb(c, ms_len, type);
1642 }
1643
1644 ast_test_suite_event_notify("PLAYBACK","Channel: %s\r\n"
1645 "Control: %s\r\n"
1646 "SkipMs: %d\r\n",
1648 (type == AST_WAITSTREAM_CB_FASTFORWARD) ? "FastForward" : "Rewind",
1649 skip_ms);
1650}
int ast_stream_rewind(struct ast_filestream *fs, off_t ms)
Rewind stream ms.
Definition file.c:1127
int ast_stream_fastforward(struct ast_filestream *fs, off_t ms)
Fast forward stream ms.
Definition file.c:1122
@ 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 1655 of file file.c.

1664{
1665 const char *orig_chan_name = NULL;
1666
1667 int err = 0;
1668
1669 if (!breakon)
1670 breakon = "";
1671 if (!forward)
1672 forward = "";
1673 if (!reverse)
1674 reverse = "";
1675
1676 /* Switch the channel to end DTMF frame only. waitstream_core doesn't care about the start of DTMF. */
1678
1680 orig_chan_name = ast_strdupa(ast_channel_name(c));
1681
1682 if (ast_channel_stream(c) && cb) {
1683 long ms_len = ast_tellstream(ast_channel_stream(c)) / (ast_format_get_sample_rate(ast_channel_stream(c)->fmt->format) / 1000);
1684 cb(c, ms_len, AST_WAITSTREAM_CB_START);
1685 }
1686
1687 while (ast_channel_stream(c)) {
1688 int res;
1689 int ms;
1690
1691 if (orig_chan_name && strcasecmp(orig_chan_name, ast_channel_name(c))) {
1693 err = 1;
1694 break;
1695 }
1696
1698
1699 if (ms < 0 && !ast_channel_timingfunc(c)) {
1701 break;
1702 }
1703 if (ms < 0)
1704 ms = 1000;
1705 if (cmdfd < 0) {
1706 res = ast_waitfor(c, ms);
1707 if (res < 0) {
1708 ast_log(LOG_WARNING, "Select failed (%s)\n", strerror(errno));
1710 return res;
1711 }
1712 } else {
1713 int outfd;
1714 struct ast_channel *rchan = ast_waitfor_nandfds(&c, 1, &cmdfd, (cmdfd > -1) ? 1 : 0, NULL, &outfd, &ms);
1715 if (!rchan && (outfd < 0) && (ms)) {
1716 /* Continue */
1717 if (errno == EINTR)
1718 continue;
1719 ast_log(LOG_WARNING, "Wait failed (%s)\n", strerror(errno));
1721 return -1;
1722 } else if (outfd > -1) { /* this requires cmdfd set */
1723 /* The FD we were watching has something waiting */
1725 return 1;
1726 }
1727 /* if rchan is set, it is 'c' */
1728 res = rchan ? 1 : 0; /* map into 'res' values */
1729 }
1730 if (res > 0) {
1731 struct ast_frame *fr = ast_read(c);
1732 if (!fr) {
1734 return -1;
1735 }
1736 switch (fr->frametype) {
1737 case AST_FRAME_DTMF_END:
1738 if (context) {
1739 const char exten[2] = { fr->subclass.integer, '\0' };
1740 if (ast_exists_extension(c, context, exten, 1,
1741 S_COR(ast_channel_caller(c)->id.number.valid, ast_channel_caller(c)->id.number.str, NULL))) {
1742 res = fr->subclass.integer;
1743 ast_frfree(fr);
1745 return res;
1746 }
1747 } else {
1748 res = fr->subclass.integer;
1749 if (strchr(forward, res)) {
1751 } else if (strchr(reverse, res)) {
1753 } else if (strchr(breakon, res)) {
1754 ast_test_suite_event_notify("PLAYBACK","Channel: %s\r\n"
1755 "Control: %s\r\n",
1757 "Break");
1758
1759 ast_frfree(fr);
1761 return res;
1762 }
1763 }
1764 break;
1765 case AST_FRAME_CONTROL:
1766 switch (fr->subclass.integer) {
1770 /* Fall-through and break out */
1771 ast_test_suite_event_notify("PLAYBACK","Channel: %s\r\n"
1772 "Control: %s\r\n",
1774 "Break");
1775 res = fr->subclass.integer;
1776 ast_frfree(fr);
1778 return res;
1780 if (!skip_ms) {
1781 skip_ms = 3000;
1782 }
1784 break;
1786 if (!skip_ms) {
1787 skip_ms = 3000;
1788 }
1790 break;
1791 case AST_CONTROL_HANGUP:
1792 case AST_CONTROL_BUSY:
1794 ast_frfree(fr);
1796 return -1;
1799 case AST_CONTROL_ANSWER:
1803 case AST_CONTROL_HOLD:
1804 case AST_CONTROL_UNHOLD:
1807 case AST_CONTROL_AOC:
1810 case AST_CONTROL_FLASH:
1811 case AST_CONTROL_WINK:
1812 case -1:
1813 /* Unimportant */
1814 break;
1815 default:
1816 ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", fr->subclass.integer);
1817 }
1818 break;
1819 case AST_FRAME_VOICE:
1820 /* Write audio if appropriate */
1821 if (audiofd > -1) {
1822 if (write(audiofd, fr->data.ptr, fr->datalen) < 0) {
1823 ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
1824 }
1825 }
1826 default:
1827 /* Ignore all others */
1828 break;
1829 }
1830 ast_frfree(fr);
1831 }
1833 }
1834
1836
1837 return (err || ast_channel_softhangup_internal_flag(c)) ? -1 : 0;
1838}
struct ast_channel * ast_waitfor_nandfds(struct ast_channel **c, int n, int *fds, int nfds, int *exception, int *outfd, int *ms)
Waits for activity on a group of channels.
Definition channel.c:2992
void ast_channel_clear_flag(struct ast_channel *chan, unsigned int flag)
Clear a flag on a channel.
Definition channel.c:11214
@ AST_FLAG_END_DTMF_ONLY
Definition channel.h:1027
int ast_waitfor(struct ast_channel *chan, int ms)
Wait for input on a channel.
Definition channel.c:3166
struct ast_frame * ast_read(struct ast_channel *chan)
Reads a frame.
Definition channel.c:4278
void ast_channel_set_flag(struct ast_channel *chan, unsigned int flag)
Set a flag on a channel.
Definition channel.c:11207
ast_timing_func_t ast_channel_timingfunc(const struct ast_channel *chan)
int ast_channel_softhangup_internal_flag(struct ast_channel *chan)
struct ast_party_caller * ast_channel_caller(struct ast_channel *chan)
static void waitstream_control(struct ast_channel *c, enum ast_waitstream_fr_cb_values type, ast_waitstream_fr_cb cb, int skip_ms)
Definition file.c:1613
@ AST_WAITSTREAM_CB_START
Definition file.h:57
@ AST_FRAME_DTMF_END
@ AST_FRAME_CONTROL
@ AST_CONTROL_SRCUPDATE
@ AST_CONTROL_PROGRESS
@ AST_CONTROL_UNHOLD
@ AST_CONTROL_VIDUPDATE
@ AST_CONTROL_STREAM_REVERSE
@ AST_CONTROL_REDIRECTING
@ AST_CONTROL_CONGESTION
@ AST_CONTROL_ANSWER
@ AST_CONTROL_RINGING
@ AST_CONTROL_HANGUP
@ AST_CONTROL_CONNECTED_LINE
@ AST_CONTROL_STREAM_FORWARD
@ AST_CONTROL_FLASH
@ AST_CONTROL_SRCCHANGE
@ AST_CONTROL_PVT_CAUSE_CODE
@ AST_CONTROL_UPDATE_RTP_PEER
int ast_exists_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Determine whether an extension exists.
Definition pbx.c:2735
int ast_sched_runq(struct ast_sched_context *con)
Runs the queue.
Definition sched.c:786
int ast_sched_wait(struct ast_sched_context *con) attribute_warn_unused_result
Determines number of seconds until the next outstanding event to take place.
Definition sched.c:433
#define S_COR(a, b, c)
returns the equivalent of logic or for strings, with an additional boolean check: second one if not e...
Definition strings.h:87
union ast_frame::@237 data
Number structure.

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

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

Variable Documentation

◆ ast_language_is_prefix

int ast_language_is_prefix = 1

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

This is settable in asterisk.conf.

Definition at line 68 of file file.c.

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

◆ cli_file

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

Definition at line 2082 of file file.c.

2082 {
2083 AST_CLI_DEFINE(handle_cli_core_show_file_formats, "Displays file formats")
2084};
#define AST_CLI_DEFINE(fn, txt,...)
Definition cli.h:197

Referenced by ast_file_init(), and file_shutdown().

◆ formats

◆ read_dirs_lock

ast_mutex_t read_dirs_lock = AST_MUTEX_INIT_VALUE
static

Lock to hold when iterating over directories.

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

Definition at line 1298 of file file.c.

Referenced by ast_file_read_dirs().