Asterisk - The Open Source Telephony Project  GIT-master-a24979a
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/sched.h"
#include "asterisk/translate.h"
#include "asterisk/utils.h"
#include "asterisk/lock.h"
#include "asterisk/app.h"
#include "asterisk/pbx.h"
#include "asterisk/linkedlists.h"
#include "asterisk/module.h"
#include "asterisk/astobj2.h"
#include "asterisk/test.h"
#include "asterisk/stasis.h"
#include "asterisk/json.h"
#include "asterisk/stasis_system.h"
#include "asterisk/media_cache.h"
Include dependency graph for file.c:

Go to the source code of this file.

Data Structures

struct  formats
 

Macros

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

Enumerations

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

Functions

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

Variables

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

Detailed Description

Generic File Format Support.

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

Definition in file file.c.

Macro Definition Documentation

◆ exts_compare

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

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

530  {
531  ACTION_EXISTS = 1, /* return matching format if file exists, 0 otherwise */
532  ACTION_DELETE, /* delete file, return 0 on success, -1 on error */
533  ACTION_RENAME, /* rename file. return 0 on success, -1 on error */
534  ACTION_OPEN,
535  ACTION_COPY /* copy file. return 0 on success, -1 on error */
536 };
@ ACTION_OPEN
Definition: file.c:534
@ ACTION_EXISTS
Definition: file.c:531
@ ACTION_COPY
Definition: file.c:535
@ ACTION_DELETE
Definition: file.c:532
@ ACTION_RENAME
Definition: file.c:533

◆ fsread_res

enum fsread_res
Enumerator
FSREAD_FAILURE 
FSREAD_SUCCESS_SCHED 
FSREAD_SUCCESS_NOSCHED 

Definition at line 941 of file file.c.

941  {
945 };
@ FSREAD_FAILURE
Definition: file.c:942
@ FSREAD_SUCCESS_SCHED
Definition: file.c:943
@ FSREAD_SUCCESS_NOSCHED
Definition: file.c:944

◆ wrap_fn

enum wrap_fn
Enumerator
WRAP_OPEN 
WRAP_REWRITE 

Definition at line 501 of file file.c.

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

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

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

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

Referenced by ast_file_read_dirs().

◆ __ast_format_def_register()

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

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

Return values
0on success
-1on failure

Definition at line 124 of file file.c.

125 {
126  struct ast_format_def *tmp;
127 
130  if (!strcasecmp(f->name, tmp->name)) {
132  ast_log(LOG_WARNING, "Tried to register '%s' format, already registered\n", f->name);
133  return -1;
134  }
135  }
136  if (!(tmp = ast_calloc(1, sizeof(*tmp)))) {
138  return -1;
139  }
140  *tmp = *f;
141  tmp->module = mod;
142  if (tmp->buf_size) {
143  /*
144  * Align buf_size properly, rounding up to the machine-specific
145  * alignment for pointers.
146  */
147  struct _test_align { void *a, *b; } p;
148  int align = (char *)&p.b - (char *)&p.a;
149  tmp->buf_size = ((f->buf_size + align - 1) / align) * align;
150  }
151 
152  memset(&tmp->list, 0, sizeof(tmp->list));
153 
156  ast_verb(2, "Registered file format %s, extension(s) %s\n", f->name, f->exts);
158 
159  return 0;
160 }
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:202
static int tmp()
Definition: bt_open.c:389
static int publish_format_update(const struct ast_format_def *f, struct stasis_message_type *type)
Definition: file.c:93
struct stasis_message_type * ast_format_register_type(void)
Get the message type used for signaling a format registration.
#define ast_verb(level,...)
#define LOG_WARNING
#define AST_RWLIST_WRLOCK(head)
Write locks a list.
Definition: linkedlists.h:52
#define AST_RWLIST_UNLOCK(head)
Attempts to unlock a read/write based list.
Definition: linkedlists.h:151
#define AST_RWLIST_TRAVERSE
Definition: linkedlists.h:494
#define AST_RWLIST_INSERT_HEAD
Definition: linkedlists.h:718
Each supported file format is described by the following structure.
Definition: mod_format.h:43
char name[80]
Definition: mod_format.h:44
struct ast_format_def::@267 list
char exts[80]
Definition: mod_format.h:45
Definition: file.c:69
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, publish_format_update(), and tmp().

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

1056 {
1057  s->owner = chan;
1058  return 0;
1059 }
struct ast_channel * owner
Definition: mod_format.h:116

References ast_filestream::owner.

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

◆ ast_closestream()

int ast_closestream ( struct ast_filestream f)

Closes a stream.

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

Definition at line 1109 of file file.c.

1110 {
1111  /* This used to destroy the filestream, but it now just decrements a refcount.
1112  * We close the stream in order to quit queuing frames now, because we might
1113  * change the writeformat, which could result in a subsequent write error, if
1114  * the format is different. */
1115  if (f == NULL) {
1116  return 0;
1117  }
1118  filestream_close(f);
1119  ao2_ref(f, -1);
1120  return 0;
1121 }
#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:392

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

Referenced by __ast_play_and_record(), ast_hangup(), ast_moh_files_next(), ast_monitor_start(), ast_monitor_stop(), ast_readfile(), ast_stopstream(), ast_writefile(), dictate_exec(), filehelper(), filestream_destructor(), gen_closestream(), handle_recordfile(), local_ast_moh_stop(), meetmestate(), mixmonitor_ds_close_fs(), moh_files_release(), msg_create_from_file(), and record_exec().

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

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

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

2025 {
2030  return 0;
2031 }
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:2017
static struct ast_cli_entry cli_file[]
Definition: file.c:2013
struct stasis_message_type * ast_format_unregister_type(void)
Get the message type used for signaling a format unregistration.
#define STASIS_MESSAGE_TYPE_INIT(name)
Boiler-plate messaging macro for initializing message types.
Definition: stasis.h:1493
#define ARRAY_LEN(a)
Definition: utils.h:661

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,
mode_t  mode 
)

same as mkstemp, but return a FILE

Parameters
templateThe 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 187 of file file.c.

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

References ast_format_def::close, and NULL.

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

1273 {
1274  int res;
1275 
1276  errno = 0;
1277 
1278 #if !defined(__GLIBC__)
1280 #endif
1281 
1282  res = __ast_file_read_dirs(dir_name, on_file, obj, max_depth);
1283 
1284 #if !defined(__GLIBC__)
1286 #endif
1287 
1288  return res;
1289 }
static ast_mutex_t read_dirs_lock
Lock to hold when iterating over directories.
Definition: file.c:1269
#define ast_mutex_unlock(a)
Definition: lock.h:188
#define ast_mutex_lock(a)
Definition: lock.h:187

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

Referenced by ast_media_index_update_for_file(), AST_TEST_DEFINE(), 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 1149 of file file.c.

1150 {
1151  return filehelper(filename, filename2, fmt, ACTION_COPY);
1152 }
static int filehelper(const char *filename, const void *arg2, const char *fmt, const enum file_action action)
Definition: file.c:549

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

1140 {
1141  return filehelper(filename, NULL, fmt, ACTION_DELETE);
1142 }

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

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

◆ ast_fileexists()

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

Checks for the existence of a given file.

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

Definition at line 1127 of file file.c.

1128 {
1129  char *buf;
1130  int buflen;
1131 
1132  if (preflang == NULL)
1133  preflang = "";
1134  buflen = strlen(preflang) + strlen(filename) + 4; /* room for everything */
1135  buf = ast_alloca(buflen);
1136  return fileexists_core(filename, fmt, preflang, buf, buflen, NULL) ? 1 : 0;
1137 }
#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:741

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(), ast_moh_files_next(), ast_monitor_start(), ast_monitor_stop(), common_exec(), conf_run(), dial_exec_full(), eivr_comm(), forward_message(), get_folder(), invent_message(), leave_voicemail(), meetme_menu_admin_extended(), minivm_delete_exec(), 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_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 1144 of file file.c.

1145 {
1146  return filehelper(filename, filename2, fmt, ACTION_RENAME);
1147 }

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

Referenced by __ast_play_and_record(), ast_monitor_stop(), 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 162 of file file.c.

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

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

Referenced by unload_module().

◆ ast_format_str_reduce()

char* ast_format_str_reduce ( char *  fmts)

Remove duplicate formats from a format string.

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

Definition at line 1867 of file file.c.

1868 {
1869  struct ast_format_def *f;
1870  struct ast_format_def *fmts_ptr[AST_MAX_FORMATS];
1871  char *fmts_str[AST_MAX_FORMATS];
1872  char *stringp, *type;
1873  char *orig = fmts;
1874  int i, j, x, first, found = 0;
1875  int len = strlen(fmts) + 1;
1876  int res;
1877 
1878  if (AST_RWLIST_RDLOCK(&formats)) {
1879  ast_log(LOG_WARNING, "Unable to lock format list\n");
1880  return NULL;
1881  }
1882 
1883  stringp = ast_strdupa(fmts);
1884 
1885  for (x = 0; (type = strsep(&stringp, "|")) && x < AST_MAX_FORMATS; x++) {
1887  if (exts_compare(f->exts, type)) {
1888  found = 1;
1889  break;
1890  }
1891  }
1892 
1893  fmts_str[x] = type;
1894  if (found) {
1895  fmts_ptr[x] = f;
1896  } else {
1897  fmts_ptr[x] = NULL;
1898  }
1899  }
1901 
1902  first = 1;
1903  for (i = 0; i < x; i++) {
1904  /* ignore invalid entries */
1905  if (!fmts_ptr[i]) {
1906  ast_log(LOG_WARNING, "ignoring unknown format '%s'\n", fmts_str[i]);
1907  continue;
1908  }
1909 
1910  /* special handling for the first entry */
1911  if (first) {
1912  res = snprintf(fmts, len, "%s", fmts_str[i]);
1913  fmts += res;
1914  len -= res;
1915  first = 0;
1916  continue;
1917  }
1918 
1919  found = 0;
1920  for (j = 0; j < i; j++) {
1921  /* this is a duplicate */
1922  if (fmts_ptr[j] == fmts_ptr[i]) {
1923  found = 1;
1924  break;
1925  }
1926  }
1927 
1928  if (!found) {
1929  res = snprintf(fmts, len, "|%s", fmts_str[i]);
1930  fmts += res;
1931  len -= res;
1932  }
1933  }
1934 
1935  if (first) {
1936  ast_log(LOG_WARNING, "no known formats found in format list (%s)\n", orig);
1937  return NULL;
1938  }
1939 
1940  return orig;
1941 }
struct sla_ringing_trunk * first
Definition: app_meetme.c:1094
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:298
static const char type[]
Definition: chan_ooh323.c:109
#define exts_compare(list, type)
Definition: file.c:386
#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)
char * strsep(char **str, const char *delims)
#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 997 of file file.c.

998 {
999  struct ast_filestream *fs = (struct ast_filestream *)data;
1000  enum fsread_res res;
1001 
1002  res = ast_readaudio_callback(fs);
1003 
1004  if (res == FSREAD_SUCCESS_SCHED)
1005  return 1;
1006 
1007  return 0;
1008 }
fsread_res
Definition: file.c:941
static enum fsread_res ast_readaudio_callback(struct ast_filestream *s)
Definition: file.c:949
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.

◆ ast_fsread_video()

static int ast_fsread_video ( const void *  data)
static

Definition at line 1042 of file file.c.

1043 {
1044  struct ast_filestream *fs = (struct ast_filestream *)data;
1045  enum fsread_res res;
1046 
1047  res = ast_readvideo_callback(fs);
1048 
1049  if (res == FSREAD_SUCCESS_SCHED)
1050  return 1;
1051 
1052  return 0;
1053 }
static enum fsread_res ast_readvideo_callback(struct ast_filestream *s)
Definition: file.c:1012

References ast_readvideo_callback(), and FSREAD_SUCCESS_SCHED.

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

1993 {
1994  struct ast_format_def *f;
1996 
1997  ast_assert(buffer && capacity);
1998 
2000  if (type_in_list(f->mime_types, mime_type, strcasecmp)) {
2001  size_t item_len = strcspn(f->exts, "|");
2002  size_t bytes_written = snprintf(buffer, capacity, ".%.*s", (int) item_len, f->exts);
2003  if (bytes_written < capacity) {
2004  /* Only return success if we didn't truncate */
2005  return 1;
2006  }
2007  }
2008  }
2009 
2010  return 0;
2011 }
ast_mutex_t lock
Definition: app_meetme.c:1093
static int type_in_list(const char *list, const char *type, int(*cmp)(const char *s1, const char *s2))
Definition: file.c:373
#define SCOPED_RDLOCK(varname, lock)
scoped lock specialization for read locks
Definition: lock.h:592
char mime_types[80]
Definition: mod_format.h:47
ast_rwlock_t lock
Definition: file.c:69
#define ast_assert(a)
Definition: utils.h:734

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

1980 {
1981  struct ast_format_def *f;
1984  if (exts_compare(f->exts, file_ext)) {
1985  return f->format;
1986  }
1987  }
1988 
1989  return NULL;
1990 }
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 790 of file file.c.

791 {
792  return ast_openstream_full(chan, filename, preflang, 0);
793 }
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.
Definition: file.c:795

References ast_openstream_full(), and ast_filestream::filename.

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

◆ ast_openstream_full()

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

Opens stream for use in seeking, playing.

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

Definition at line 795 of file file.c.

796 {
797  /*
798  * Use fileexists_core() to find a file in a compatible
799  * language and format, set up a suitable translator,
800  * and open the stream.
801  */
802  struct ast_format_cap *file_fmt_cap;
803  int res;
804  int buflen;
805  char *buf;
806 
807  if (!asis) {
808  /* do this first, otherwise we detect the wrong writeformat */
809  ast_stopstream(chan);
810  if (ast_channel_generator(chan))
812  }
813  if (preflang == NULL)
814  preflang = "";
815  buflen = strlen(preflang) + strlen(filename) + 4;
816  buf = ast_alloca(buflen);
817 
818  if (!(file_fmt_cap = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT))) {
819  return NULL;
820  }
821  if (!fileexists_core(filename, NULL, preflang, buf, buflen, file_fmt_cap) ||
823 
824  ast_log(LOG_WARNING, "File %s does not exist in any format\n", filename);
825  ao2_ref(file_fmt_cap, -1);
826  return NULL;
827  }
828 
829  /* Set the channel to a format we can work with and save off the previous format. */
830  ast_channel_lock(chan);
832  /* Set the channel to the best format that exists for the file. */
833  res = ast_set_write_format_from_cap(chan, file_fmt_cap);
834  ast_channel_unlock(chan);
835  /* don't need this anymore now that the channel's write format is set. */
836  ao2_ref(file_fmt_cap, -1);
837 
838  if (res == -1) { /* No format available that works with this channel */
839  return NULL;
840  }
841  res = filehelper(buf, chan, NULL, ACTION_OPEN);
842  if (res >= 0)
843  return ast_channel_stream(chan);
844  return NULL;
845 }
struct ast_filestream * ast_channel_stream(const struct ast_channel *chan)
struct ast_format * ast_channel_writeformat(struct ast_channel *chan)
void ast_channel_set_oldwriteformat(struct ast_channel *chan, struct ast_format *format)
#define ast_channel_lock(chan)
Definition: channel.h:2922
struct ast_generator * ast_channel_generator(const struct ast_channel *chan)
void ast_deactivate_generator(struct ast_channel *chan)
Definition: channel.c:2894
#define ast_channel_unlock(chan)
Definition: channel.h:2923
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:5898
@ AST_MEDIA_TYPE_AUDIO
Definition: codec.h:32
int ast_stopstream(struct ast_channel *tmp)
Stops a stream.
Definition: file.c:222
@ AST_FORMAT_CAP_FLAG_DEFAULT
Definition: format_cap.h:38
int ast_format_cap_has_type(const struct ast_format_cap *cap, enum ast_media_type type)
Find out if the capabilities structure has any formats of a specific type.
Definition: format_cap.c:613
#define ast_format_cap_alloc(flags)
Allocate a new ast_format_cap structure.
Definition: format_cap.h:49
Format capabilities structure, holds formats + preference order + etc.
Definition: format_cap.c:54

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, and NULL.

Referenced by ast_moh_files_next(), ast_openstream(), and gen_nextfile().

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

848 {
849  /* As above, but for video. But here we don't have translators
850  * so we must enforce a format.
851  */
852  struct ast_format_cap *nativeformats, *tmp_cap;
853  char *buf;
854  int buflen;
855  int i, fd;
856 
857  if (preflang == NULL) {
858  preflang = "";
859  }
860  buflen = strlen(preflang) + strlen(filename) + 4;
861  buf = ast_alloca(buflen);
862 
863  ast_channel_lock(chan);
864  nativeformats = ao2_bump(ast_channel_nativeformats(chan));
865  ast_channel_unlock(chan);
866 
867  /* is the channel capable of video without translation ?*/
868  if (!ast_format_cap_has_type(nativeformats, AST_MEDIA_TYPE_VIDEO)) {
869  ao2_cleanup(nativeformats);
870  return NULL;
871  }
873  ao2_cleanup(nativeformats);
874  return NULL;
875  }
876  /* Video is supported, so see what video formats exist for this file */
877  if (!fileexists_core(filename, NULL, preflang, buf, buflen, tmp_cap)) {
878  ao2_ref(tmp_cap, -1);
879  ao2_cleanup(nativeformats);
880  return NULL;
881  }
882 
883  /* iterate over file formats and pick the first one compatible with the channel's native formats */
884  for (i = 0; i < ast_format_cap_count(tmp_cap); ++i) {
885  struct ast_format *format = ast_format_cap_get_format(tmp_cap, i);
886 
888  !ast_format_cap_iscompatible(nativeformats, tmp_cap)) {
889  ao2_ref(format, -1);
890  continue;
891  }
892 
894  if (fd >= 0) {
895  ao2_ref(format, -1);
896  ao2_ref(tmp_cap, -1);
897  ao2_cleanup(nativeformats);
898  return ast_channel_vstream(chan);
899  }
900  ast_log(LOG_WARNING, "File %s has video but couldn't be opened\n", filename);
901  ao2_ref(format, -1);
902  }
903  ao2_ref(tmp_cap, -1);
904  ao2_cleanup(nativeformats);
905 
906  return NULL;
907 }
#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
static snd_pcm_format_t format
Definition: chan_alsa.c:106
struct ast_format_cap * ast_channel_nativeformats(const struct ast_channel *chan)
struct ast_filestream * ast_channel_vstream(const struct ast_channel *chan)
@ AST_MEDIA_TYPE_VIDEO
Definition: codec.h:33
const char * ast_format_get_name(const struct ast_format *format)
Get the name associated with a format.
Definition: format.c:334
enum ast_media_type ast_format_get_type(const struct ast_format *format)
Get the media type of a format.
Definition: format.c:354
struct ast_format * ast_format_cap_get_format(const struct ast_format_cap *cap, int position)
Get the format at a specific index.
Definition: format_cap.c:400
int ast_format_cap_iscompatible(const struct ast_format_cap *cap1, const struct ast_format_cap *cap2)
Determine if any joint capabilities exist between two capabilities structures.
Definition: format_cap.c:653
size_t ast_format_cap_count(const struct ast_format_cap *cap)
Get the number of formats present within the capabilities structure.
Definition: format_cap.c:395
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(), format, 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 1061 of file file.c.

1062 {
1063  enum fsread_res res;
1064 
1066  res = ast_readaudio_callback(s);
1067  else
1068  res = ast_readvideo_callback(s);
1069 
1070  return (res == FSREAD_FAILURE) ? -1 : 0;
1071 }
struct ast_format_def * fmt
Definition: mod_format.h:103

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

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

◆ ast_ratestream()

int ast_ratestream ( struct ast_filestream fs)

Return the sample rate of the stream's format.

Parameters
fsfs to act on
Returns
sample rate in Hz

Definition at line 1088 of file file.c.

1089 {
1090  return ast_format_get_sample_rate(fs->fmt->format);
1091 }
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 947 of file file.c.

950 {
951  int whennext = 0;
952 
953  while (!whennext) {
954  struct ast_frame *fr;
955 
956  if (s->orig_chan_name && strcasecmp(ast_channel_name(s->owner), s->orig_chan_name)) {
957  goto return_failure;
958  }
959 
960  fr = read_frame(s, &whennext);
961 
962  if (!fr /* stream complete */ || ast_write(s->owner, fr) /* error writing */) {
963  if (fr) {
964  ast_debug(2, "Failed to write frame\n");
965  ast_frfree(fr);
966  }
967  goto return_failure;
968  }
969 
970  if (fr) {
971  ast_frfree(fr);
972  }
973  }
974 
975  if (whennext != s->lasttimeout) {
976  if (ast_channel_timingfd(s->owner) > -1) {
977  float samp_rate = (float) ast_format_get_sample_rate(s->fmt->format);
978  unsigned int rate;
979 
980  rate = (unsigned int) roundf(samp_rate / ((float) whennext));
981 
982  ast_settimeout_full(s->owner, rate, ast_fsread_audio, s, 1);
983  } else {
985  }
986  s->lasttimeout = whennext;
987  return FSREAD_SUCCESS_NOSCHED;
988  }
989  return FSREAD_SUCCESS_SCHED;
990 
991 return_failure:
993  ast_settimeout(s->owner, 0, NULL, NULL);
994  return FSREAD_FAILURE;
995 }
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:3186
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:5179
const char * ast_channel_name(const struct ast_channel *chan)
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:3181
struct ast_sched_context * ast_channel_sched(const struct ast_channel *chan)
static struct ast_frame * read_frame(struct ast_filestream *s, int *whennext)
Definition: file.c:909
static int ast_fsread_audio(const void *data)
Definition: file.c:997
float roundf(float x)
#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.

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

1351 {
1352  FILE *bfile;
1353  struct ast_format_def *f;
1354  struct ast_filestream *fs = NULL;
1355  char *fn;
1356  int format_found = 0;
1357 
1359 
1360  AST_RWLIST_TRAVERSE(&formats, f, list) {
1361  fs = NULL;
1362  if (!exts_compare(f->exts, type))
1363  continue;
1364  else
1365  format_found = 1;
1366 
1367  fn = build_filename(filename, type);
1368  if (!fn) {
1369  continue;
1370  }
1371  errno = 0;
1372  bfile = fopen(fn, "r");
1373 
1374  if (!bfile || (fs = get_filestream(f, bfile)) == NULL || open_wrapper(fs) ) {
1375  ast_log(LOG_WARNING, "Unable to open %s\n", fn);
1376  if (fs) {
1377  ast_closestream(fs);
1378  }
1379  fs = NULL;
1380  bfile = NULL;
1381  ast_free(fn);
1382  break;
1383  }
1384  /* found it */
1385  fs->trans = NULL;
1386  fs->fmt = f;
1387  fs->flags = flags;
1388  fs->mode = mode;
1389  fs->filename = ast_strdup(filename);
1390  fs->vfs = NULL;
1391  ast_free(fn);
1392  break;
1393  }
1394 
1396  if (!format_found)
1397  ast_log(LOG_WARNING, "No such format '%s'\n", type);
1398 
1399  return fs;
1400 }
#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:349
static struct ast_filestream * get_filestream(struct ast_format_def *fmt, FILE *bfile)
Definition: file.c:463
int ast_closestream(struct ast_filestream *f)
Closes a stream.
Definition: file.c:1109
static int open_wrapper(struct ast_filestream *s)
Definition: file.c:525
struct ast_filestream * vfs
Definition: mod_format.h:110
struct ast_trans_pvt * trans
Definition: mod_format.h:112
char * filename
Definition: mod_format.h:107

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

Referenced by __ast_play_and_record(), 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 934 of file file.c.

935 {
936  int whennext = 0;
937 
938  return read_frame(s, &whennext);
939 }

References read_frame().

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

◆ ast_readvideo_callback()

static enum fsread_res ast_readvideo_callback ( struct ast_filestream s)
static

Definition at line 1010 of file file.c.

1013 {
1014  int whennext = 0;
1015 
1016  while (!whennext) {
1017  struct ast_frame *fr = read_frame(s, &whennext);
1018 
1019  if (!fr /* stream complete */ || ast_write(s->owner, fr) /* error writing */) {
1020  if (fr) {
1021  ast_debug(2, "Failed to write frame\n");
1022  ast_frfree(fr);
1023  }
1025  return FSREAD_FAILURE;
1026  }
1027 
1028  if (fr) {
1029  ast_frfree(fr);
1030  }
1031  }
1032 
1033  if (whennext != s->lasttimeout) {
1035  s->lasttimeout = whennext;
1036  return FSREAD_SUCCESS_NOSCHED;
1037  }
1038 
1039  return FSREAD_SUCCESS_SCHED;
1040 }
void ast_channel_vstreamid_set(struct ast_channel *chan, int value)
static int ast_fsread_video(const void *data)
Definition: file.c:1042

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

1074 {
1075  return fs->fmt->seek(fs, sample_offset, whence);
1076 }
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_read(), ast_moh_files_next(), ast_stream_fastforward(), ast_stream_rewind(), ast_streamfile(), ast_write_stream(), control_streamfile(), dictate_exec(), handle_getoption(), handle_recordfile(), handle_streamfile(), 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 222 of file file.c.

223 {
225 
226  /* Stop a running stream if there is one */
227  if (ast_channel_stream(tmp)) {
231  ast_log(LOG_WARNING, "Unable to restore format back to %s\n", ast_format_get_name(ast_channel_oldwriteformat(tmp)));
232  }
233  /* Stop the video stream too */
234  if (ast_channel_vstream(tmp) != NULL) {
237  }
238 
240 
241  return 0;
242 }
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:5880
void ast_channel_vstream_set(struct ast_channel *chan, struct ast_filestream *value)

References 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_log, ast_set_write_format(), LOG_WARNING, NULL, and tmp().

Referenced by action_playback_and_continue(), adsi_transmit_message_full(), agent_alert(), announce_to_dial(), ast_openstream_full(), ast_play_and_wait(), ast_readstring_full(), ast_say_enumeration_full_da(), ast_say_enumeration_full_de(), ast_say_enumeration_full_en(), ast_say_enumeration_full_he(), ast_say_enumeration_full_is(), ast_say_enumeration_full_vi(), ast_say_number_full_cs(), ast_say_number_full_da(), ast_say_number_full_de(), ast_say_number_full_en_GB(), ast_say_number_full_es(), ast_say_number_full_fr(), ast_say_number_full_gr(), ast_say_number_full_he(), ast_say_number_full_hu(), ast_say_number_full_is(), ast_say_number_full_it(), ast_say_number_full_ja(), ast_say_number_full_ka(), ast_say_number_full_nl(), ast_say_number_full_no(), ast_say_number_full_pt(), ast_say_number_full_ru(), ast_say_number_full_se(), ast_say_number_full_th(), ast_say_number_full_ur(), ast_say_number_full_vi(), ast_say_number_full_zh(), background_detect_exec(), conf_exec(), conf_run(), control_streamfile(), dial_exec_full(), directory_exec(), grab_transfer(), handle_getoption(), handle_streamfile(), ivr_dispatch(), leave_voicemail(), meetme_menu_admin(), meetme_menu_admin_extended(), meetmestate(), minivm_greet_exec(), mp3_exec(), pbx_builtin_background(), pl_odtworz_plik(), play_file(), play_files_helper(), play_mailbox_owner(), playback_exec(), queue_exec(), read_exec(), readexten_exec(), record_exec(), 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.
Return values
0if success.
-1if error.
digitif interrupted by a digit.

Definition at line 1855 of file file.c.

1856 {
1857  int res = 0;
1858  if (!ast_strlen_zero(file)) {
1859  res = ast_streamfile(chan, file, ast_channel_language(chan));
1860  if (!res) {
1861  res = ast_waitstream(chan, digits);
1862  }
1863  }
1864  return res;
1865 }
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:1291
int ast_waitstream(struct ast_channel *c, const char *breakon)
Waits for a stream to stop or digit to be pressed.
Definition: file.c:1817
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65

References ast_channel_language(), ast_streamfile(), ast_strlen_zero(), ast_waitstream(), and make_ari_stubs::file.

Referenced by __ast_play_and_record(), action_playback(), action_toggle_mute_participants(), agent_alert(), agent_login_exec(), announce_user_count(), app_exec(), ast_bridge_channel_playfile(), ast_pickup_call(), ast_record_review(), bridge_features_duration_callback(), confbridge_exec(), directory_exec(), forward_message(), grab_transfer(), invent_message(), ivr_dispatch(), join_conference_bridge(), leave_voicemail(), limits_interval_playback(), mixmonitor_thread(), park_app_exec(), parked_call_app_exec(), play_file(), play_files_helper(), play_mailbox_owner(), play_message_callerid(), play_prompt_to_user(), play_record_review(), playback_common(), sayname(), select_item_seq(), setup_mixmonitor_ds(), stream_failsound(), vm_forwardoptions(), 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 1093 of file file.c.

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

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

1099 {
1100  off_t offset = ast_tellstream(fs);
1101  if (ms * DEFAULT_SAMPLES_PER_MS > offset) {
1102  /* Don't even bother asking the file format to seek to a negative offset... */
1103  ast_debug(1, "Restarting, rather than seeking to negative offset %ld\n", (long) (offset - (ms * DEFAULT_SAMPLES_PER_MS)));
1104  return ast_seekstream(fs, 0, SEEK_SET);
1105  }
1106  return ast_seekstream(fs, -ms * DEFAULT_SAMPLES_PER_MS, SEEK_CUR);
1107 }
off_t ast_tellstream(struct ast_filestream *fs)
Tell where we are in a stream.
Definition: file.c:1083

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

1292 {
1293  struct ast_filestream *fs;
1294  struct ast_filestream *vfs=NULL;
1295  off_t pos;
1296  int seekattempt;
1297  int res;
1298 
1299  fs = ast_openstream(chan, filename, preflang);
1300  if (!fs) {
1301  struct ast_str *codec_buf = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN);
1302  ast_channel_lock(chan);
1303  ast_log(LOG_WARNING, "Unable to open %s (format %s): %s\n",
1304  filename, ast_format_cap_get_names(ast_channel_nativeformats(chan), &codec_buf), strerror(errno));
1305  ast_channel_unlock(chan);
1306  return -1;
1307  }
1308 
1309  /* check to see if there is any data present (not a zero length file),
1310  * done this way because there is no where for ast_openstream_full to
1311  * return the file had no data. */
1312  pos = ftello(fs->f);
1313  seekattempt = fseeko(fs->f, -1, SEEK_END);
1314  if (seekattempt) {
1315  if (errno == EINVAL) {
1316  /* Zero-length file, as opposed to a pipe */
1317  return 0;
1318  } else {
1319  ast_seekstream(fs, 0, SEEK_SET);
1320  }
1321  } else {
1322  fseeko(fs->f, pos, SEEK_SET);
1323  }
1324 
1325  vfs = ast_openvstream(chan, filename, preflang);
1326  if (vfs) {
1327  ast_debug(1, "Ooh, found a video stream, too, format %s\n", ast_format_get_name(vfs->fmt->format));
1328  }
1329 
1332  if (ast_applystream(chan, fs))
1333  return -1;
1334  if (vfs && ast_applystream(chan, vfs))
1335  return -1;
1336  ast_test_suite_event_notify("PLAYBACK", "Message: %s\r\nChannel: %s", filename, ast_channel_name(chan));
1337  res = ast_playstream(fs);
1338  if (!res && vfs)
1339  res = ast_playstream(vfs);
1340 
1341  if (VERBOSITY_ATLEAST(3)) {
1342  ast_channel_lock(chan);
1343  ast_verb(3, "<%s> Playing '%s.%s' (language '%s')\n", ast_channel_name(chan), filename, ast_format_get_name(ast_channel_writeformat(chan)), preflang ? preflang : "default");
1344  ast_channel_unlock(chan);
1345  }
1346 
1347  return res;
1348 }
@ AST_FLAG_MASQ_NOSTREAM
Definition: channel.h:1014
struct ast_flags * ast_channel_flags(struct ast_channel *chan)
int ast_applystream(struct ast_channel *chan, struct ast_filestream *s)
Applies a open stream to a channel.
Definition: file.c:1055
int ast_playstream(struct ast_filestream *s)
Play a open stream on a channel.
Definition: file.c:1061
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:790
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:847
#define AST_FORMAT_CAP_NAMES_LEN
Definition: format_cap.h:324
const char * ast_format_cap_get_names(const struct ast_format_cap *cap, struct ast_str **buf)
Get the names of codecs of a set of formats.
Definition: format_cap.c:734
#define VERBOSITY_ATLEAST(level)
#define ast_str_alloca(init_len)
Definition: strings.h:826
Support for dynamic strings.
Definition: strings.h:604
#define ast_test_suite_event_notify(s, f,...)
Definition: test.h:189
#define ast_test_flag(p, flag)
Definition: utils.h:63

References ast_applystream(), ast_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_log, ast_openstream(), ast_openvstream(), 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, LOG_WARNING, NULL, 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_play_and_wait(), ast_say_date_da(), ast_say_date_de(), ast_say_date_en(), ast_say_date_fr(), ast_say_date_gr(), ast_say_date_he(), ast_say_date_hu(), ast_say_date_is(), ast_say_date_ja(), ast_say_date_ka(), ast_say_date_nl(), ast_say_date_th(), ast_say_date_with_format_gr(), ast_say_datetime_en(), ast_say_datetime_fr(), ast_say_datetime_from_now_en(), ast_say_datetime_from_now_fr(), ast_say_datetime_from_now_he(), ast_say_datetime_from_now_ka(), ast_say_datetime_gr(), ast_say_datetime_he(), ast_say_datetime_ja(), ast_say_datetime_nl(), ast_say_datetime_pt(), ast_say_datetime_th(), ast_say_datetime_zh(), ast_say_enumeration_full_da(), ast_say_enumeration_full_de(), ast_say_enumeration_full_en(), ast_say_enumeration_full_he(), ast_say_enumeration_full_is(), ast_say_enumeration_full_vi(), ast_say_number_full_cs(), ast_say_number_full_da(), ast_say_number_full_de(), ast_say_number_full_en_GB(), ast_say_number_full_es(), ast_say_number_full_fr(), ast_say_number_full_gr(), ast_say_number_full_he(), ast_say_number_full_hu(), ast_say_number_full_is(), ast_say_number_full_it(), ast_say_number_full_ja(), ast_say_number_full_ka(), ast_say_number_full_nl(), ast_say_number_full_no(), ast_say_number_full_pt(), ast_say_number_full_ru(), ast_say_number_full_se(), ast_say_number_full_th(), ast_say_number_full_ur(), ast_say_number_full_vi(), ast_say_number_full_zh(), ast_say_time_de(), ast_say_time_en(), ast_say_time_fr(), ast_say_time_gr(), ast_say_time_hu(), ast_say_time_ja(), ast_say_time_ka(), ast_say_time_nl(), ast_say_time_zh(), ast_stream_and_wait(), auth_exec(), background_detect_exec(), common_exec(), conf_exec(), conf_get_pin(), conf_run(), control_streamfile(), dial_exec_full(), do_directory(), find_conf_realtime(), forward_message(), gr_say_number_female(), handle_recordfile(), invent_message(), leave_voicemail(), meetme_menu_admin(), meetme_menu_admin_extended(), meetme_menu_normal(), minivm_greet_exec(), page_exec(), pbx_builtin_background(), pl_odtworz_plik(), play_and_wait(), play_file(), play_record_review(), playback_exec(), privacy_exec(), readexten_exec(), record_exec(), retrydial_exec(), s_streamwait3(), say_filenames(), select_item_menu(), setup_privacy_args(), vm_authenticate(), wait_file(), 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 1083 of file file.c.

1084 {
1085  return fs->fmt->tell(fs);
1086 }
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_moh_files_next(), ast_stream_rewind(), control_streamfile(), handle_getoption(), handle_recordfile(), handle_streamfile(), 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 1078 of file file.c.

1079 {
1080  return fs->fmt->trunc(fs);
1081 }
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 1817 of file file.c.

1818 {
1819  int res;
1820 
1821  res = waitstream_core(c, breakon, NULL, NULL, 0, -1, -1, NULL, NULL /* no callback */);
1822 
1823  return sanitize_waitstream_return(res);
1824 }
static int sanitize_waitstream_return(int return_value)
Definition: file.c:1800
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:1592
static struct test_val c

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

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

◆ ast_waitstream_exten()

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

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

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

Definition at line 1836 of file file.c.

1837 {
1838  int res;
1839 
1840  /* Waitstream, with return in the case of a valid 1 digit extension */
1841  /* in the current or specified context being pressed */
1842  if (!context)
1844  res = waitstream_core(c, NULL, NULL, NULL, 0,
1845  -1, -1, context, NULL /* no callback */);
1846 
1847  return sanitize_waitstream_return(res);
1848 }
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:120
const char * ast_channel_context(const struct ast_channel *chan)

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

Referenced by pbx_builtin_background().

◆ ast_waitstream_fr()

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

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

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

Definition at line 1786 of file file.c.

1787 {
1788  return waitstream_core(c, breakon, forward, reverse, ms,
1789  -1 /* no audiofd */, -1 /* no cmdfd */, NULL /* no context */, NULL /* no callback */);
1790 }

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

1781 {
1782  return waitstream_core(c, breakon, forward, reverse, ms,
1783  -1 /* no audiofd */, -1 /* no cmdfd */, NULL /* no context */, cb);
1784 }

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

1403 {
1404  int fd, myflags = 0;
1405  /* compiler claims this variable can be used before initialization... */
1406  FILE *bfile = NULL;
1407  struct ast_format_def *f;
1408  struct ast_filestream *fs = NULL;
1409  char *buf = NULL;
1410  size_t size = 0;
1411  int format_found = 0;
1412 
1414 
1415  /* set the O_TRUNC flag if and only if there is no O_APPEND specified */
1416  /* We really can't use O_APPEND as it will break WAV header updates */
1417  if (flags & O_APPEND) {
1418  flags &= ~O_APPEND;
1419  } else {
1420  myflags = O_TRUNC;
1421  }
1422 
1423  myflags |= O_WRONLY | O_CREAT;
1424 
1425  /* XXX need to fix this - we should just do the fopen,
1426  * not open followed by fdopen()
1427  */
1428  AST_RWLIST_TRAVERSE(&formats, f, list) {
1429  char *fn, *orig_fn = NULL;
1430  if (fs)
1431  break;
1432 
1433  if (!exts_compare(f->exts, type))
1434  continue;
1435  else
1436  format_found = 1;
1437 
1438  fn = build_filename(filename, type);
1439  if (!fn) {
1440  continue;
1441  }
1442  fd = open(fn, flags | myflags, mode);
1443  if (fd > -1) {
1444  /* fdopen() the resulting file stream */
1445  bfile = fdopen(fd, ((flags | myflags) & O_RDWR) ? "w+" : "w");
1446  if (!bfile) {
1447  ast_log(LOG_WARNING, "Whoa, fdopen failed: %s!\n", strerror(errno));
1448  close(fd);
1449  fd = -1;
1450  }
1451  }
1452 
1453  if (ast_opt_cache_record_files && (fd > -1)) {
1454  char *c;
1455 
1456  fclose(bfile); /* this also closes fd */
1457  /*
1458  We touch orig_fn just as a place-holder so other things (like vmail) see the file is there.
1459  What we are really doing is writing to record_cache_dir until we are done then we will mv the file into place.
1460  */
1461  orig_fn = ast_strdup(fn);
1462  for (c = fn; *c; c++)
1463  if (*c == '/')
1464  *c = '_';
1465 
1466  size = strlen(fn) + strlen(record_cache_dir) + 2;
1467  buf = ast_malloc(size);
1468  strcpy(buf, record_cache_dir);
1469  strcat(buf, "/");
1470  strcat(buf, fn);
1471  ast_free(fn);
1472  fn = buf;
1473  fd = open(fn, flags | myflags, mode);
1474  if (fd > -1) {
1475  /* fdopen() the resulting file stream */
1476  bfile = fdopen(fd, ((flags | myflags) & O_RDWR) ? "w+" : "w");
1477  if (!bfile) {
1478  ast_log(LOG_WARNING, "Whoa, fdopen failed: %s!\n", strerror(errno));
1479  close(fd);
1480  fd = -1;
1481  }
1482  }
1483  }
1484  if (fd > -1) {
1485  errno = 0;
1486  fs = get_filestream(f, bfile);
1487  if (fs) {
1488  if ((fs->write_buffer = ast_malloc(32768))) {
1489  setvbuf(fs->f, fs->write_buffer, _IOFBF, 32768);
1490  }
1491  }
1492  if (!fs || rewrite_wrapper(fs, comment)) {
1493  ast_log(LOG_WARNING, "Unable to rewrite %s\n", fn);
1494  close(fd);
1495  if (orig_fn) {
1496  unlink(fn);
1497  unlink(orig_fn);
1498  ast_free(orig_fn);
1499  }
1500  if (fs) {
1501  ast_closestream(fs);
1502  fs = NULL;
1503  }
1504  /*
1505  * 'fn' was has either been allocated from build_filename, or that was freed
1506  * and now 'fn' points to memory allocated for 'buf'. Either way the memory
1507  * now needs to be released.
1508  */
1509  ast_free(fn);
1510  continue;
1511  }
1512  fs->trans = NULL;
1513  fs->fmt = f;
1514  fs->flags = flags;
1515  fs->mode = mode;
1516  if (orig_fn) {
1517  fs->realfilename = orig_fn;
1518  fs->filename = fn;
1519  /*
1520  * The above now manages the memory allocated for 'orig_fn' and 'fn', so
1521  * set them to NULL, so they don't get released at the end of the loop.
1522  */
1523  orig_fn = NULL;
1524  fn = NULL;
1525  } else {
1526  fs->realfilename = NULL;
1527  fs->filename = ast_strdup(filename);
1528  }
1529  fs->vfs = NULL;
1530  /* If truncated, we'll be at the beginning; if not truncated, then append */
1531  f->seek(fs, 0, SEEK_END);
1532  } else if (errno != EEXIST) {
1533  ast_log(LOG_WARNING, "Unable to open file %s: %s\n", fn, strerror(errno));
1534  if (orig_fn)
1535  unlink(orig_fn);
1536  }
1537  /* Free 'fn', or if 'fn' points to 'buf' then free 'buf' */
1538  ast_free(fn);
1539  ast_free(orig_fn);
1540  }
1541 
1543 
1544  if (!format_found)
1545  ast_log(LOG_WARNING, "No such format '%s'\n", type);
1546 
1547  return fs;
1548 }
#define comment
Definition: ael_lex.c:976
static int rewrite_wrapper(struct ast_filestream *s, const char *comment)
Definition: file.c:520
char record_cache_dir[AST_CACHE_DIR_LEN]
Definition: options.c:96
#define ast_opt_cache_record_files
Definition: options.h:120
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_monitor_start(), ast_writestream(), dictate_exec(), handle_recordfile(), meetmestate(), mixmonitor_save_prep(), and record_exec().

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

245 {
246  int res = -1;
247  if (f->frametype == AST_FRAME_VIDEO) {
249  /* This is the audio portion. Call the video one... */
250  if (!fs->vfs && fs->filename) {
251  const char *type = ast_format_get_name(f->subclass.format);
252  fs->vfs = ast_writefile(fs->filename, type, NULL, fs->flags, 0, fs->mode);
253  ast_debug(1, "Opened video output file\n");
254  }
255  if (fs->vfs)
256  return ast_writestream(fs->vfs, f);
257  /* else ignore */
258  return 0;
259  }
260  } else if (f->frametype != AST_FRAME_VOICE) {
261  ast_log(LOG_WARNING, "Tried to write non-voice frame\n");
262  return -1;
263  }
265  res = fs->fmt->write(fs, f);
266  if (res < 0)
267  ast_log(LOG_WARNING, "Natural write failed\n");
268  else if (res > 0)
269  ast_log(LOG_WARNING, "Huh??\n");
270  } else {
271  /* XXX If they try to send us a type of frame that isn't the normal frame, and isn't
272  the one we've setup a translator for, we do the "wrong thing" XXX */
275  fs->trans = NULL;
276  }
277  if (!fs->trans) {
279  }
280  if (!fs->trans) {
281  ast_log(LOG_WARNING, "Unable to translate to format %s, source format %s\n",
283  } else {
284  struct ast_frame *trf;
286  /* Get the translated frame but don't consume the original in case they're using it on another stream */
287  if ((trf = ast_translate(fs->trans, f, 0))) {
288  struct ast_frame *cur;
289 
290  /* the translator may have returned multiple frames, so process them */
291  for (cur = trf; cur; cur = AST_LIST_NEXT(cur, frame_list)) {
292  if ((res = fs->fmt->write(fs, trf))) {
293  ast_log(LOG_WARNING, "Translated frame write failed\n");
294  break;
295  }
296  }
297  ast_frfree(trf);
298  } else {
299  res = 0;
300  }
301  }
302  }
303  return res;
304 }
#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:244
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:1402
enum ast_format_cmp_res ast_format_cmp(const struct ast_format *format1, const struct ast_format *format2)
Compare two formats.
Definition: format.c:201
@ AST_FORMAT_CMP_EQUAL
Definition: format.h:36
@ AST_FORMAT_CMP_NOT_EQUAL
Definition: format.h:38
@ AST_FRAME_VIDEO
@ AST_FRAME_VOICE
#define AST_LIST_NEXT(elm, field)
Returns the next entry in the list after the given entry.
Definition: linkedlists.h:439
struct ast_format * lastwriteformat
Definition: mod_format.h:114
int(* write)(struct ast_filestream *, struct ast_frame *)
Definition: mod_format.h:66
struct ast_format * format
struct ast_frame_subclass subclass
enum ast_frame_type frametype
struct ast_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:485
void ast_translator_free_path(struct ast_trans_pvt *tr)
Frees a translator path Frees the given translator path structure.
Definition: translate.c:475
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:565

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_read(), ast_write_stream(), ast_writestream(), dictate_exec(), handle_recordfile(), meetmestate(), mixmonitor_thread(), and record_exec().

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

350 {
351  char *fn = NULL;
352 
353  /* The wav49 -> WAV translation is duplicated in apps/app_mixmonitor.c, so
354  if you change it here you need to change it there as well */
355  if (!strcmp(ext, "wav49"))
356  ext = "WAV";
357 
358  if (filename[0] == '/') {
359  if (ast_asprintf(&fn, "%s.%s", filename, ext) < 0) {
360  fn = NULL;
361  }
362  } else {
363  if (ast_asprintf(&fn, "%s/sounds/%s.%s",
364  ast_config_AST_DATA_DIR, filename, ext) < 0) {
365  fn = NULL;
366  }
367  }
368  return fn;
369 }
const char * ext
Definition: http.c:150
const char * ast_config_AST_DATA_DIR
Definition: options.c:158

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

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

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

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

Referenced by ast_file_init().

◆ fileexists_core()

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

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

Note
Try preflang, preflang with stripped '_' suffices, or NULL.
The last parameter(s) point to a buffer of sufficient size, which on success is filled with the matching filename.
Parameters
filenameName of the file.
fmtFormat to look for the file in. OPTIONAL
preflangThe perfered 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 741 of file file.c.

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

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_openstream_full(), and ast_openvstream().

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

693 {
694  if (buf == NULL) {
695  return 0;
696  }
697 
698  if (is_remote_path(filename) && !ast_media_cache_retrieve(filename, NULL, buf, buflen)) {
699  return filehelper(buf, result_cap, NULL, ACTION_EXISTS);
700  }
701 
702  if (ast_language_is_prefix && !is_absolute_path(filename)) { /* new layout */
703  if (lang) {
704  snprintf(buf, buflen, "%s/%s", lang, filename);
705  } else {
706  snprintf(buf, buflen, "%s", filename);
707  }
708  } else { /* old layout */
709  strcpy(buf, filename); /* first copy the full string */
710  if (lang) {
711  /* insert the language and suffix if needed */
712  const char *c = strrchr(filename, '/');
713  int offset = c ? c - filename + 1 : 0; /* points right after the last '/' */
714  snprintf(buf + offset, buflen - offset, "%s/%s", lang, filename + offset);
715  }
716  }
717 
718  return filehelper(buf, result_cap, fmt, ACTION_EXISTS);
719 }
int ast_language_is_prefix
The following variable controls the layout of localized sound files. If 0, use the historical layout ...
Definition: file.c:67
static int is_remote_path(const char *filename)
Definition: file.c:680
static int is_absolute_path(const char *filename)
Definition: file.c:675
int ast_media_cache_retrieve(const char *uri, const char *preferred_file_name, char *file_path, size_t len)
Retrieve an item from the cache.
Definition: media_cache.c:157

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

Referenced by fileexists_core().

◆ filehelper()

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

Definition at line 549 of file file.c.

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

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

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

◆ filestream_close()

static void filestream_close ( struct ast_filestream f)
static

Definition at line 392 of file file.c.

393 {
394  enum ast_media_type format_type = ast_format_get_type(f->fmt->format);
395 
396  if (!f->owner) {
397  return;
398  }
399 
400  /* Stop a running stream if there is one */
401  switch (format_type)
402  {
406  ast_settimeout(f->owner, 0, NULL, NULL);
407  break;
411  break;
412  default:
413  ast_log(AST_LOG_WARNING, "Unable to schedule deletion of filestream with unsupported type %s\n", f->fmt->name);
414  break;
415  }
416 }
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 418 of file file.c.

419 {
420  struct ast_filestream *f = arg;
421  int status;
422  int pid = -1;
423 
424  /* Stop a running stream if there is one */
426 
427  /* destroy the translator on exit */
428  if (f->trans)
429  ast_translator_free_path(f->trans);
430 
431  if (f->fmt->close) {
432  void (*closefn)(struct ast_filestream *) = f->fmt->close;
433  closefn(f);
434  }
435 
436  if (f->f) {
437  fclose(f->f);
438  }
439 
440  if (f->realfilename && f->filename) {
441  pid = ast_safe_fork(0);
442  if (!pid) {
443  execl("/bin/mv", "mv", "-f", f->filename, f->realfilename, SENTINEL);
444  _exit(1);
445  }
446  else if (pid > 0) {
447  /* Block the parent until the move is complete.*/
448  waitpid(pid, &status, 0);
449  }
450  }
451 
452  ast_free(f->filename);
453  ast_free(f->realfilename);
454  if (f->vfs)
455  ast_closestream(f->vfs);
456  ast_free(f->write_buffer);
457  ast_free((void *)f->orig_chan_name);
458  ao2_cleanup(f->lastwriteformat);
459  ao2_cleanup(f->fr.subclass.format);
460  ast_module_unref(f->fmt->module);
461 }
jack_status_t status
Definition: app_jack.c:146
#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:3267
#define ast_module_unref(mod)
Release a reference to the module.
Definition: module.h:469

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

504 {
505  struct ast_format_def *f = s->fmt;
506  int ret = -1;
507  int (*openfn)(struct ast_filestream *s);
508 
509  if (mode == WRAP_OPEN && (openfn = f->open) && openfn(s))
510  ast_log(LOG_WARNING, "Unable to open format %s\n", f->name);
511  else if (mode == WRAP_REWRITE && f->rewrite && f->rewrite(s, comment))
512  ast_log(LOG_WARNING, "Unable to rewrite format %s\n", f->name);
513  else {
514  /* preliminary checks succeed. */
515  ret = 0;
516  }
517  return ret;
518 }

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

464 {
465  struct ast_filestream *s;
466  int l = sizeof(*s) + fmt->buf_size + fmt->desc_size; /* total allocation size */
467 
469  return NULL;
470  }
471 
473  if (!s) {
475  return NULL;
476  }
477  s->fmt = fmt;
478  s->f = bfile;
479 
480  if (fmt->desc_size)
481  s->_private = ((char *)(s + 1)) + fmt->buf_size;
482  if (fmt->buf_size)
483  s->buf = (char *)(s + 1);
484  s->fr.src = fmt->name;
485 
490  }
491  s->fr.mallocd = 0;
493 
494  return s;
495 }
if(!yyg->yy_init)
Definition: ast_expr2f.c:868
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:409
static void filestream_destructor(void *arg)
Definition: file.c:418
#define ast_module_running_ref(mod)
Hold a reference to the module if it is running.
Definition: module.h:455
struct ast_frame fr
frame produced by read, typically
Definition: mod_format.h:122
void * _private
Definition: mod_format.h:124
struct ast_module * module
Definition: mod_format.h:93
const char * src

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

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

◆ handle_cli_core_show_file_formats()

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

Definition at line 1943 of file file.c.

1944 {
1945 #define FORMAT "%-10s %-10s %-20s\n"
1946 #define FORMAT2 "%-10s %-10s %-20s\n"
1947  struct ast_format_def *f;
1948  int count_fmt = 0;
1949 
1950  switch (cmd) {
1951  case CLI_INIT:
1952  e->command = "core show file formats";
1953  e->usage =
1954  "Usage: core show file formats\n"
1955  " Displays currently registered file formats (if any).\n";
1956  return NULL;
1957  case CLI_GENERATE:
1958  return NULL;
1959  }
1960 
1961  if (a->argc != 4)
1962  return CLI_SHOWUSAGE;
1963 
1964  ast_cli(a->fd, FORMAT, "Format", "Name", "Extensions");
1965  ast_cli(a->fd, FORMAT, "------", "----", "----------");
1966 
1969  ast_cli(a->fd, FORMAT2, ast_format_get_name(f->format), f->name, f->exts);
1970  count_fmt++;
1971  }
1973  ast_cli(a->fd, "%d file formats registered.\n", count_fmt);
1974  return CLI_SUCCESS;
1975 #undef FORMAT
1976 #undef FORMAT2
1977 }
#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 675 of file file.c.

676 {
677  return filename[0] == '/';
678 }

References ast_filestream::filename.

Referenced by fileexists_test().

◆ is_remote_path()

static int is_remote_path ( const char *  filename)
static

Definition at line 680 of file file.c.

681 {
682  return strstr(filename, "://") ? 1 : 0;
683 }

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

75 {
77  char *stringp, *ext;
78 
79  stringp = ast_strdupa(list); /* this is in the stack so does not need to be freed */
80  if (!array || !stringp) {
81  return NULL;
82  }
83 
84  while ((ext = strsep(&stringp, sep))) {
86  return NULL;
87  }
88  }
89 
90  return ast_json_ref(array);
91 }
static int array(struct ast_channel *chan, const char *cmd, char *var, const char *value)
struct ast_json * ast_json_ref(struct ast_json *value)
Increase refcount on value.
Definition: json.c:67
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
Definition: json.c:73
int ast_json_array_append(struct ast_json *array, struct ast_json *value)
Append to an array.
Definition: json.c:368
struct ast_json * ast_json_array_create(void)
Create a empty JSON array.
Definition: json.c:352
struct ast_json * ast_json_string_create(const char *value)
Construct a JSON string from value.
Definition: json.c:268
Abstract JSON element (object, array, string, int, ...).

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

526 {
527  return fn_wrapper(s, NULL, WRAP_OPEN);
528 }
static int fn_wrapper(struct ast_filestream *s, const char *comment, enum wrap_fn mode)
Definition: file.c:503

References fn_wrapper(), NULL, and WRAP_OPEN.

Referenced by ast_readfile(), and filehelper().

◆ publish_format_update()

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

Definition at line 93 of file file.c.

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

910 {
911  struct ast_frame *fr, *new_fr;
912 
913  if (!s || !s->fmt) {
914  return NULL;
915  }
916 
917  if (!(fr = s->fmt->read(s, whennext))) {
918  return NULL;
919  }
920 
921  if (!(new_fr = ast_frisolate(fr))) {
922  ast_frfree(fr);
923  return NULL;
924  }
925 
926  if (new_fr != fr) {
927  ast_frfree(fr);
928  fr = new_fr;
929  }
930 
931  return fr;
932 }
#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_readframe(), and audiohook_read_frame_helper().

◆ rewrite_wrapper()

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

Definition at line 520 of file file.c.

521 {
522  return fn_wrapper(s, comment, WRAP_REWRITE);
523 }

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

1801 {
1802  switch (return_value) {
1806  /* Fall through and set return_value to 0 */
1807  return_value = 0;
1808  break;
1809  default:
1810  /* Do nothing */
1811  break;
1812  }
1813 
1814  return return_value;
1815 }
@ 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 373 of file file.c.

374 {
375  char *stringp = ast_strdupa(list), *item;
376 
377  while ((item = strsep(&stringp, "|"))) {
378  if (!cmp(item, type)) {
379  return 1;
380  }
381  }
382 
383  return 0;
384 }
static struct aco_type item
Definition: test_config.c:1463

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

Referenced by ast_get_extension_for_mime_type().

◆ waitstream_control()

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

Definition at line 1550 of file file.c.

1554 {
1555  switch (type)
1556  {
1558  {
1559  int eoftest;
1561  eoftest = fgetc(ast_channel_stream(c)->f);
1562  if (feof(ast_channel_stream(c)->f)) {
1564  } else {
1565  ungetc(eoftest, ast_channel_stream(c)->f);
1566  }
1567  }
1568  break;
1571  break;
1572  default:
1573  break;
1574  }
1575 
1576  if (cb) {
1577  long ms_len = ast_tellstream(ast_channel_stream(c)) / (ast_format_get_sample_rate(ast_channel_stream(c)->fmt->format) / 1000);
1578  cb(c, ms_len, type);
1579  }
1580 
1581  ast_test_suite_event_notify("PLAYBACK","Channel: %s\r\n"
1582  "Control: %s\r\n"
1583  "SkipMs: %d\r\n",
1585  (type == AST_WAITSTREAM_CB_FASTFORWARD) ? "FastForward" : "Rewind",
1586  skip_ms);
1587 }
int ast_stream_rewind(struct ast_filestream *fs, off_t ms)
Rewind stream ms.
Definition: file.c:1098
int ast_stream_fastforward(struct ast_filestream *fs, off_t ms)
Fast forward stream ms.
Definition: file.c:1093
@ 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 1592 of file file.c.

1601 {
1602  const char *orig_chan_name = NULL;
1603 
1604  int err = 0;
1605 
1606  if (!breakon)
1607  breakon = "";
1608  if (!forward)
1609  forward = "";
1610  if (!reverse)
1611  reverse = "";
1612 
1613  /* Switch the channel to end DTMF frame only. waitstream_core doesn't care about the start of DTMF. */
1615 
1617  orig_chan_name = ast_strdupa(ast_channel_name(c));
1618 
1619  if (ast_channel_stream(c) && cb) {
1620  long ms_len = ast_tellstream(ast_channel_stream(c)) / (ast_format_get_sample_rate(ast_channel_stream(c)->fmt->format) / 1000);
1621  cb(c, ms_len, AST_WAITSTREAM_CB_START);
1622  }
1623 
1624  while (ast_channel_stream(c)) {
1625  int res;
1626  int ms;
1627 
1628  if (orig_chan_name && strcasecmp(orig_chan_name, ast_channel_name(c))) {
1629  ast_stopstream(c);
1630  err = 1;
1631  break;
1632  }
1633 
1635 
1636  if (ms < 0 && !ast_channel_timingfunc(c)) {
1637  ast_stopstream(c);
1638  break;
1639  }
1640  if (ms < 0)
1641  ms = 1000;
1642  if (cmdfd < 0) {
1643  res = ast_waitfor(c, ms);
1644  if (res < 0) {
1645  ast_log(LOG_WARNING, "Select failed (%s)\n", strerror(errno));
1647  return res;
1648  }
1649  } else {
1650  int outfd;
1651  struct ast_channel *rchan = ast_waitfor_nandfds(&c, 1, &cmdfd, (cmdfd > -1) ? 1 : 0, NULL, &outfd, &ms);
1652  if (!rchan && (outfd < 0) && (ms)) {
1653  /* Continue */
1654  if (errno == EINTR)
1655  continue;
1656  ast_log(LOG_WARNING, "Wait failed (%s)\n", strerror(errno));
1658  return -1;
1659  } else if (outfd > -1) { /* this requires cmdfd set */
1660  /* The FD we were watching has something waiting */
1662  return 1;
1663  }
1664  /* if rchan is set, it is 'c' */
1665  res = rchan ? 1 : 0; /* map into 'res' values */
1666  }
1667  if (res > 0) {
1668  struct ast_frame *fr = ast_read(c);
1669  if (!fr) {
1671  return -1;
1672  }
1673  switch (fr->frametype) {
1674  case AST_FRAME_DTMF_END:
1675  if (context) {
1676  const char exten[2] = { fr->subclass.integer, '\0' };
1678  S_COR(ast_channel_caller(c)->id.number.valid, ast_channel_caller(c)->id.number.str, NULL))) {
1679  res = fr->subclass.integer;
1680  ast_frfree(fr);
1682  return res;
1683  }
1684  } else {
1685  res = fr->subclass.integer;
1686  if (strchr(forward, res)) {
1688  } else if (strchr(reverse, res)) {
1690  } else if (strchr(breakon, res)) {
1691  ast_test_suite_event_notify("PLAYBACK","Channel: %s\r\n"
1692  "Control: %s\r\n",
1694  "Break");
1695 
1696  ast_frfree(fr);
1698  return res;
1699  }
1700  }
1701  break;
1702  case AST_FRAME_CONTROL:
1703  switch (fr->subclass.integer) {
1707  /* Fall-through and break out */
1708  ast_test_suite_event_notify("PLAYBACK","Channel: %s\r\n"
1709  "Control: %s\r\n",
1711  "Break");
1712  res = fr->subclass.integer;
1713  ast_frfree(fr);
1715  return res;
1717  if (!skip_ms) {
1718  skip_ms = 3000;
1719  }
1721  break;
1723  if (!skip_ms) {
1724  skip_ms = 3000;
1725  }
1727  break;
1728  case AST_CONTROL_HANGUP:
1729  case AST_CONTROL_BUSY:
1731  ast_frfree(fr);
1733  return -1;
1734  case AST_CONTROL_RINGING:
1735  case AST_CONTROL_ANSWER:
1736  case AST_CONTROL_VIDUPDATE:
1737  case AST_CONTROL_SRCUPDATE:
1738  case AST_CONTROL_SRCCHANGE:
1739  case AST_CONTROL_HOLD:
1740  case AST_CONTROL_UNHOLD:
1743  case AST_CONTROL_AOC:
1746  case AST_CONTROL_FLASH:
1747  case -1:
1748  /* Unimportant */
1749  break;
1750  default:
1751  ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", fr->subclass.integer);
1752  }
1753  break;
1754  case AST_FRAME_VOICE:
1755  /* Write audio if appropriate */
1756  if (audiofd > -1) {
1757  if (write(audiofd, fr->data.ptr, fr->datalen) < 0) {
1758  ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
1759  }
1760  }
1761  default:
1762  /* Ignore all others */
1763  break;
1764  }
1765  ast_frfree(fr);
1766  }
1768  }
1769 
1771 
1772  return (err || ast_channel_softhangup_internal_flag(c)) ? -1 : 0;
1773 }
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:122
void ast_channel_clear_flag(struct ast_channel *chan, unsigned int flag)
Clear a flag on a channel.
Definition: channel.c:11220
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:2989
int ast_waitfor(struct ast_channel *chan, int ms)
Wait for input on a channel.
Definition: channel.c:3163
struct ast_frame * ast_read(struct ast_channel *chan)
Reads a frame.
Definition: channel.c:4292
@ AST_FLAG_END_DTMF_ONLY
Definition: channel.h:1007
void ast_channel_set_flag(struct ast_channel *chan, unsigned int flag)
Set a flag on a channel.
Definition: channel.c:11213
ast_timing_func_t ast_channel_timingfunc(const struct ast_channel *chan)
struct ast_party_caller * ast_channel_caller(struct ast_channel *chan)
int ast_channel_softhangup_internal_flag(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:1550
@ AST_WAITSTREAM_CB_START
Definition: file.h:57
@ AST_FRAME_DTMF_END
@ AST_FRAME_CONTROL
@ AST_CONTROL_SRCUPDATE
@ AST_CONTROL_BUSY
@ AST_CONTROL_UNHOLD
@ AST_CONTROL_VIDUPDATE
@ AST_CONTROL_STREAM_REVERSE
@ AST_CONTROL_REDIRECTING
@ AST_CONTROL_CONGESTION
@ AST_CONTROL_ANSWER
@ AST_CONTROL_RINGING
@ AST_CONTROL_HANGUP
@ AST_CONTROL_HOLD
@ AST_CONTROL_CONNECTED_LINE
@ AST_CONTROL_STREAM_FORWARD
@ AST_CONTROL_FLASH
@ AST_CONTROL_AOC
@ AST_CONTROL_SRCCHANGE
@ AST_CONTROL_PVT_CAUSE_CODE
@ AST_CONTROL_UPDATE_RTP_PEER
int ast_exists_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Determine whether an extension exists.
Definition: pbx.c:4182
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::@254 data
Number structure.
Definition: app_followme.c:154

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_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_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, context, ast_frame::data, ast_frame::datalen, errno, exten, 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 67 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:1943

Definition at line 1992 of file file.c.

Referenced by ast_file_init(), and file_shutdown().

◆ formats

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

Referenced by load_engine().

◆ read_dirs_lock

ast_mutex_t read_dirs_lock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, {1, 0} }
static

Lock to hold when iterating over directories.

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

Definition at line 1269 of file file.c.

Referenced by ast_file_read_dirs().