#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"
Go to the source code of this file.
Data Structures | |
struct | formats |
Defines | |
#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 | |
int | __ast_format_register (const struct ast_format *f, struct ast_module *mod) |
Register a new file format capability. Adds a format to Asterisk's format abilities. | |
int | ast_applystream (struct ast_channel *chan, struct ast_filestream *s) |
Applys a open stream to a channel. | |
int | ast_closestream (struct ast_filestream *f) |
Closes a stream. | |
int | ast_file_init (void) |
int | ast_filecopy (const char *filename, const char *filename2, const char *fmt) |
Copies a file. | |
int | ast_filedelete (const char *filename, const char *fmt) |
Deletes a file. | |
int | ast_fileexists (const char *filename, const char *fmt, const char *preflang) |
Checks for the existence of a given file. | |
static format_t | ast_filehelper (const char *filename, const void *arg2, const char *fmt, const enum file_action action) |
perform various actions on a file. Second argument arg2 depends on the command: unused for EXISTS and DELETE destination file name (const char *) for COPY and RENAME struct ast_channel * for OPEN if fmt is NULL, OPEN will return the first matching entry, whereas other functions will run on all matching entries. | |
int | ast_filerename (const char *filename, const char *filename2, const char *fmt) |
Renames a file. | |
char * | ast_format_str_reduce (char *fmts) |
int | ast_format_unregister (const char *name) |
Unregisters a file format. | |
static int | ast_fsread_audio (const void *data) |
static int | ast_fsread_video (const void *data) |
ast_filestream * | ast_openstream (struct ast_channel *chan, const char *filename, const char *preflang) |
Opens stream for use in seeking, playing. | |
ast_filestream * | ast_openstream_full (struct ast_channel *chan, const char *filename, const char *preflang, int asis) |
Opens stream for use in seeking, playing. | |
ast_filestream * | ast_openvstream (struct ast_channel *chan, const char *filename, const char *preflang) |
Opens stream for use in seeking, playing. | |
int | ast_playstream (struct ast_filestream *s) |
Play a open stream on a channel. | |
static enum fsread_res | ast_readaudio_callback (struct ast_filestream *s) |
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. | |
ast_frame * | ast_readframe (struct ast_filestream *s) |
Read a frame from a filestream. | |
static enum fsread_res | ast_readvideo_callback (struct ast_filestream *s) |
int | ast_seekstream (struct ast_filestream *fs, off_t sample_offset, int whence) |
Seeks into stream. | |
int | ast_stopstream (struct ast_channel *tmp) |
Stops a stream. | |
int | ast_stream_and_wait (struct ast_channel *chan, const char *file, const char *digits) |
stream file until digit If the file name is non-empty, try to play it. | |
int | ast_stream_fastforward (struct ast_filestream *fs, off_t ms) |
Fast forward stream ms. | |
int | ast_stream_rewind (struct ast_filestream *fs, off_t ms) |
Rewind stream ms. | |
int | ast_streamfile (struct ast_channel *chan, const char *filename, const char *preflang) |
Streams a file. | |
off_t | ast_tellstream (struct ast_filestream *fs) |
Tell where we are in a stream. | |
int | ast_truncstream (struct ast_filestream *fs) |
Trunc stream at current location. | |
int | ast_waitstream (struct ast_channel *c, const char *breakon) |
Waits for a stream to stop or digit to be pressed. | |
int | ast_waitstream_exten (struct ast_channel *c, const char *context) |
Waits for a stream to stop or digit matching a valid one digit exten to be pressed. | |
int | ast_waitstream_fr (struct ast_channel *c, const char *breakon, const char *forward, const char *reverse, int ms) |
Same as waitstream but allows stream to be forwarded or rewound. | |
int | ast_waitstream_full (struct ast_channel *c, const char *breakon, int audiofd, int cmdfd) |
ast_filestream * | ast_writefile (const char *filename, const char *type, const char *comment, int flags, int check, mode_t mode) |
Starts writing a file. | |
int | ast_writestream (struct ast_filestream *fs, struct ast_frame *f) |
Writes a frame to a stream. | |
static char * | build_filename (const char *filename, const char *ext) |
construct a filename. Absolute pathnames are preserved, relative names are prefixed by the sounds/ directory. The wav49 suffix is replaced by 'WAV'. Returns a malloc'ed string to be freed by the caller. | |
static int | copy (const char *infile, const char *outfile) |
static int | exts_compare (const char *exts, const char *type) |
static format_t | fileexists_core (const char *filename, const char *fmt, const char *preflang, char *buf, int buflen) |
helper routine to locate a file with a given format and language preference. Try preflang, preflang with stripped '_' suffices, or NULL. | |
static format_t | fileexists_test (const char *filename, const char *fmt, const char *lang, char *buf, int buflen) |
static void | filestream_close (struct ast_filestream *f) |
static void | filestream_destructor (void *arg) |
static int | fn_wrapper (struct ast_filestream *s, const char *comment, enum wrap_fn mode) |
static struct ast_filestream * | get_filestream (struct ast_format *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 | open_wrapper (struct ast_filestream *s) |
static struct ast_frame * | read_frame (struct ast_filestream *s, int *whennext) |
static int | rewrite_wrapper (struct ast_filestream *s, const char *comment) |
static int | 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) |
the core of all waitstream() functions | |
Variables | |
int | ast_language_is_prefix = 1 |
static struct ast_cli_entry | cli_file [] |
Definition in file file.c.
#define FORMAT "%-10s %-10s %-20s\n" |
#define FORMAT2 "%-10s %-10s %-20s\n" |
enum file_action |
Definition at line 407 of file file.c.
00407 { 00408 ACTION_EXISTS = 1, /* return matching format if file exists, 0 otherwise */ 00409 ACTION_DELETE, /* delete file, return 0 on success, -1 on error */ 00410 ACTION_RENAME, /* rename file. return 0 on success, -1 on error */ 00411 ACTION_OPEN, 00412 ACTION_COPY /* copy file. return 0 on success, -1 on error */ 00413 };
enum fsread_res |
Definition at line 743 of file file.c.
00743 { 00744 FSREAD_FAILURE, 00745 FSREAD_SUCCESS_SCHED, 00746 FSREAD_SUCCESS_NOSCHED, 00747 };
enum wrap_fn |
int __ast_format_register | ( | const struct ast_format * | f, | |
struct ast_module * | mod | |||
) |
Register a new file format capability. Adds a format to Asterisk's format abilities.
0 | on success | |
-1 | on failure |
Definition at line 63 of file file.c.
References ast_calloc, ast_log(), AST_RWLIST_INSERT_HEAD, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_verb, ast_format::buf_size, ast_format::exts, f, ast_format::list, LOG_WARNING, ast_format::module, and ast_format::name.
00064 { 00065 struct ast_format *tmp; 00066 00067 AST_RWLIST_WRLOCK(&formats); 00068 AST_RWLIST_TRAVERSE(&formats, tmp, list) { 00069 if (!strcasecmp(f->name, tmp->name)) { 00070 AST_RWLIST_UNLOCK(&formats); 00071 ast_log(LOG_WARNING, "Tried to register '%s' format, already registered\n", f->name); 00072 return -1; 00073 } 00074 } 00075 if (!(tmp = ast_calloc(1, sizeof(*tmp)))) { 00076 AST_RWLIST_UNLOCK(&formats); 00077 return -1; 00078 } 00079 *tmp = *f; 00080 tmp->module = mod; 00081 if (tmp->buf_size) { 00082 /* 00083 * Align buf_size properly, rounding up to the machine-specific 00084 * alignment for pointers. 00085 */ 00086 struct _test_align { void *a, *b; } p; 00087 int align = (char *)&p.b - (char *)&p.a; 00088 tmp->buf_size = ((f->buf_size + align - 1) / align) * align; 00089 } 00090 00091 memset(&tmp->list, 0, sizeof(tmp->list)); 00092 00093 AST_RWLIST_INSERT_HEAD(&formats, tmp, list); 00094 AST_RWLIST_UNLOCK(&formats); 00095 ast_verb(2, "Registered file format %s, extension(s) %s\n", f->name, f->exts); 00096 00097 return 0; 00098 }
int ast_applystream | ( | struct ast_channel * | chan, | |
struct ast_filestream * | s | |||
) |
Applys a open stream to a channel.
chan | channel to work | |
s | ast_filestream to apply |
0 | on success. | |
-1 | on failure. |
Definition at line 860 of file file.c.
References ast_filestream::owner.
Referenced by ast_streamfile(), handle_getoption(), handle_recordfile(), handle_streamfile(), and speech_streamfile().
00861 { 00862 s->owner = chan; 00863 return 0; 00864 }
int ast_closestream | ( | struct ast_filestream * | f | ) |
Closes a stream.
f | filestream to close Close a playback or recording stream |
0 | on success. | |
-1 | on failure. |
Definition at line 903 of file file.c.
References ao2_ref, f, and filestream_close().
Referenced by ast_filehelper(), ast_hangup(), ast_moh_files_next(), ast_monitor_start(), ast_monitor_stop(), ast_readfile(), ast_stopstream(), ast_writefile(), dictate_exec(), filestream_destructor(), gen_closestream(), handle_cli_file_convert(), handle_recordfile(), local_ast_moh_stop(), mixmonitor_ds_close_fs(), moh_files_release(), and rpt().
00904 { 00905 /* This used to destroy the filestream, but it now just decrements a refcount. 00906 * We close the stream in order to quit queuing frames now, because we might 00907 * change the writeformat, which could result in a subsequent write error, if 00908 * the format is different. */ 00909 filestream_close(f); 00910 ao2_ref(f, -1); 00911 return 0; 00912 }
int ast_file_init | ( | void | ) |
Provided by file.c
Definition at line 1489 of file file.c.
References ARRAY_LEN, ast_cli_register_multiple(), and cli_file.
01490 { 01491 ast_cli_register_multiple(cli_file, ARRAY_LEN(cli_file)); 01492 return 0; 01493 }
int ast_filecopy | ( | const char * | oldname, | |
const char * | newname, | |||
const char * | fmt | |||
) |
Copies a file.
oldname | name of the file you wish to copy (minus extension) | |
newname | name you wish the file to be copied to (minus extension) | |
fmt | the 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 942 of file file.c.
References ast_filehelper().
Referenced by copy_plain_file(), and vm_forwardoptions().
00943 { 00944 return ast_filehelper(filename, filename2, fmt, ACTION_COPY); 00945 }
int ast_filedelete | ( | const char * | filename, | |
const char * | fmt | |||
) |
Deletes a file.
filename | name of the file you wish to delete (minus the extension) | |
fmt | of the file Delete a given file in a given format, or if fmt is NULL, then do so for all |
Definition at line 932 of file file.c.
References ACTION_DELETE, and ast_filehelper().
Referenced by announce_thread(), ast_monitor_start(), ast_monitor_stop(), conf_free(), dial_exec_full(), handle_cli_file_convert(), leave_voicemail(), play_record_review(), setup_privacy_args(), and vm_delete().
00933 { 00934 return ast_filehelper(filename, NULL, fmt, ACTION_DELETE); 00935 }
int ast_fileexists | ( | const char * | filename, | |
const char * | fmt, | |||
const char * | preflang | |||
) |
Checks for the existence of a given file.
filename | name of the file you wish to check, minus the extension | |
fmt | the 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. |
Definition at line 918 of file file.c.
References ast_filestream::buf, and fileexists_core().
Referenced by announce_thread(), app_exec(), ast_moh_files_next(), ast_monitor_start(), ast_monitor_stop(), common_exec(), conf_run(), dial_exec_full(), eivr_comm(), forward_message(), function_playback(), get_folder(), invent_message(), leave_voicemail(), minivm_delete_exec(), play_file(), play_message(), play_message_callerid(), readexten_exec(), record_exec(), retrydial_exec(), rpt_tele_thread(), say_character_str_full(), say_digit_str_full(), say_phonetic_str_full(), sayname(), saynode(), setup_privacy_args(), vm_intro(), vm_newuser(), vm_options(), and vm_tempgreeting().
00919 { 00920 char *buf; 00921 int buflen; 00922 00923 if (preflang == NULL) 00924 preflang = ""; 00925 buflen = strlen(preflang) + strlen(filename) + 4; /* room for everything */ 00926 buf = alloca(buflen); 00927 if (buf == NULL) 00928 return 0; 00929 return fileexists_core(filename, fmt, preflang, buf, buflen); 00930 }
static format_t ast_filehelper | ( | const char * | filename, | |
const void * | arg2, | |||
const char * | fmt, | |||
const enum file_action | action | |||
) | [static] |
perform various actions on a file. Second argument arg2 depends on the command: unused for EXISTS and DELETE destination file name (const char *) for COPY and RENAME struct ast_channel * for OPEN if fmt is NULL, OPEN will return the first matching entry, whereas other functions will run on all matching entries.
Definition at line 424 of file file.c.
References ACTION_DELETE, ACTION_EXISTS, ACTION_OPEN, ACTION_RENAME, ast_closestream(), AST_FORMAT_AUDIO_MASK, AST_FORMAT_VIDEO_MASK, ast_free, ast_log(), AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_strdupa, build_filename(), copy(), errno, ext, ast_format::exts, exts_compare(), f, ast_filestream::filename, ast_filestream::fmt, ast_format::format, get_filestream(), ast_filestream::lasttimeout, ast_format::list, LOG_WARNING, open_wrapper(), ast_channel::stream, strsep(), ast_filestream::trans, ast_channel::vstream, and ast_channel::writeformat.
Referenced by ast_filecopy(), ast_filedelete(), ast_filerename(), ast_openstream_full(), ast_openvstream(), and fileexists_test().
00425 { 00426 struct ast_format *f; 00427 format_t res = (action == ACTION_EXISTS) ? 0 : -1; 00428 00429 AST_RWLIST_RDLOCK(&formats); 00430 /* Check for a specific format */ 00431 AST_RWLIST_TRAVERSE(&formats, f, list) { 00432 char *stringp, *ext = NULL; 00433 00434 if (fmt && !exts_compare(f->exts, fmt)) 00435 continue; 00436 00437 /* Look for a file matching the supported extensions. 00438 * The file must exist, and for OPEN, must match 00439 * one of the formats supported by the channel. 00440 */ 00441 stringp = ast_strdupa(f->exts); /* this is in the stack so does not need to be freed */ 00442 while ( (ext = strsep(&stringp, "|")) ) { 00443 struct stat st; 00444 char *fn = build_filename(filename, ext); 00445 00446 if (fn == NULL) 00447 continue; 00448 00449 if ( stat(fn, &st) ) { /* file not existent */ 00450 ast_free(fn); 00451 continue; 00452 } 00453 /* for 'OPEN' we need to be sure that the format matches 00454 * what the channel can process 00455 */ 00456 if (action == ACTION_OPEN) { 00457 struct ast_channel *chan = (struct ast_channel *)arg2; 00458 FILE *bfile; 00459 struct ast_filestream *s; 00460 00461 if ( !(chan->writeformat & f->format) && 00462 !((f->format & AST_FORMAT_AUDIO_MASK && fmt) || 00463 (f->format & AST_FORMAT_VIDEO_MASK && fmt))) { 00464 ast_free(fn); 00465 continue; /* not a supported format */ 00466 } 00467 if ( (bfile = fopen(fn, "r")) == NULL) { 00468 ast_free(fn); 00469 continue; /* cannot open file */ 00470 } 00471 s = get_filestream(f, bfile); 00472 if (!s) { 00473 fclose(bfile); 00474 ast_free(fn); /* cannot allocate descriptor */ 00475 continue; 00476 } 00477 if (open_wrapper(s)) { 00478 ast_free(fn); 00479 ast_closestream(s); 00480 continue; /* cannot run open on file */ 00481 } 00482 if (st.st_size == 0) { 00483 ast_log(LOG_WARNING, "File %s detected to have zero size.\n", fn); 00484 } 00485 /* ok this is good for OPEN */ 00486 res = 1; /* found */ 00487 s->lasttimeout = -1; 00488 s->fmt = f; 00489 s->trans = NULL; 00490 s->filename = NULL; 00491 if (s->fmt->format & AST_FORMAT_AUDIO_MASK) { 00492 if (chan->stream) 00493 ast_closestream(chan->stream); 00494 chan->stream = s; 00495 } else { 00496 if (chan->vstream) 00497 ast_closestream(chan->vstream); 00498 chan->vstream = s; 00499 } 00500 ast_free(fn); 00501 break; 00502 } 00503 switch (action) { 00504 case ACTION_OPEN: 00505 break; /* will never get here */ 00506 00507 case ACTION_EXISTS: /* return the matching format */ 00508 res |= f->format; 00509 break; 00510 00511 case ACTION_DELETE: 00512 if ( (res = unlink(fn)) ) 00513 ast_log(LOG_WARNING, "unlink(%s) failed: %s\n", fn, strerror(errno)); 00514 break; 00515 00516 case ACTION_RENAME: 00517 case ACTION_COPY: { 00518 char *nfn = build_filename((const char *)arg2, ext); 00519 if (!nfn) 00520 ast_log(LOG_WARNING, "Out of memory\n"); 00521 else { 00522 res = action == ACTION_COPY ? copy(fn, nfn) : rename(fn, nfn); 00523 if (res) 00524 ast_log(LOG_WARNING, "%s(%s,%s) failed: %s\n", 00525 action == ACTION_COPY ? "copy" : "rename", 00526 fn, nfn, strerror(errno)); 00527 ast_free(nfn); 00528 } 00529 } 00530 break; 00531 00532 default: 00533 ast_log(LOG_WARNING, "Unknown helper %d\n", action); 00534 } 00535 ast_free(fn); 00536 } 00537 } 00538 AST_RWLIST_UNLOCK(&formats); 00539 return res; 00540 }
int ast_filerename | ( | const char * | oldname, | |
const char * | newname, | |||
const char * | fmt | |||
) |
Renames a file.
oldname | the name of the file you wish to act upon (minus the extension) | |
newname | the name you wish to rename the file to (minus the extension) | |
fmt | the format of the file Rename a given file in a given format, or if fmt is NULL, then do so for all |
Definition at line 937 of file file.c.
References ACTION_RENAME, and ast_filehelper().
Referenced by ast_monitor_stop(), forward_message(), play_record_review(), rename_file(), and vm_forwardoptions().
00938 { 00939 return ast_filehelper(filename, filename2, fmt, ACTION_RENAME); 00940 }
char* ast_format_str_reduce | ( | char * | fmts | ) |
fmts | a format string, this string will be modified |
NULL | error |
Definition at line 1373 of file file.c.
References ast_log(), AST_MAX_FORMATS, AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_strdupa, ast_format::exts, exts_compare(), f, first, len(), ast_format::list, LOG_WARNING, strsep(), and type.
Referenced by actual_load_config().
01374 { 01375 struct ast_format *f; 01376 struct ast_format *fmts_ptr[AST_MAX_FORMATS]; 01377 char *fmts_str[AST_MAX_FORMATS]; 01378 char *stringp, *type; 01379 char *orig = fmts; 01380 int i, j, x, first, found = 0; 01381 int len = strlen(fmts) + 1; 01382 int res; 01383 01384 if (AST_RWLIST_RDLOCK(&formats)) { 01385 ast_log(LOG_WARNING, "Unable to lock format list\n"); 01386 return NULL; 01387 } 01388 01389 stringp = ast_strdupa(fmts); 01390 01391 for (x = 0; (type = strsep(&stringp, "|")) && x < AST_MAX_FORMATS; x++) { 01392 AST_RWLIST_TRAVERSE(&formats, f, list) { 01393 if (exts_compare(f->exts, type)) { 01394 found = 1; 01395 break; 01396 } 01397 } 01398 01399 fmts_str[x] = type; 01400 if (found) { 01401 fmts_ptr[x] = f; 01402 } else { 01403 fmts_ptr[x] = NULL; 01404 } 01405 } 01406 AST_RWLIST_UNLOCK(&formats); 01407 01408 first = 1; 01409 for (i = 0; i < x; i++) { 01410 /* ignore invalid entries */ 01411 if (!fmts_ptr[i]) { 01412 ast_log(LOG_WARNING, "ignoring unknown format '%s'\n", fmts_str[i]); 01413 continue; 01414 } 01415 01416 /* special handling for the first entry */ 01417 if (first) { 01418 res = snprintf(fmts, len, "%s", fmts_str[i]); 01419 fmts += res; 01420 len -= res; 01421 first = 0; 01422 continue; 01423 } 01424 01425 found = 0; 01426 for (j = 0; j < i; j++) { 01427 /* this is a duplicate */ 01428 if (fmts_ptr[j] == fmts_ptr[i]) { 01429 found = 1; 01430 break; 01431 } 01432 } 01433 01434 if (!found) { 01435 res = snprintf(fmts, len, "|%s", fmts_str[i]); 01436 fmts += res; 01437 len -= res; 01438 } 01439 } 01440 01441 if (first) { 01442 ast_log(LOG_WARNING, "no known formats found in format list (%s)\n", orig); 01443 return NULL; 01444 } 01445 01446 return orig; 01447 }
int ast_format_unregister | ( | const char * | name | ) |
Unregisters a file format.
name | the name of the format you wish to unregister Unregisters a format based on the name of the format. |
0 | on success | |
-1 | on failure to unregister |
Definition at line 100 of file file.c.
References 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::list, LOG_WARNING, and ast_format::name.
Referenced by unload_module().
00101 { 00102 struct ast_format *tmp; 00103 int res = -1; 00104 00105 AST_RWLIST_WRLOCK(&formats); 00106 AST_RWLIST_TRAVERSE_SAFE_BEGIN(&formats, tmp, list) { 00107 if (!strcasecmp(name, tmp->name)) { 00108 AST_RWLIST_REMOVE_CURRENT(list); 00109 ast_free(tmp); 00110 res = 0; 00111 } 00112 } 00113 AST_RWLIST_TRAVERSE_SAFE_END; 00114 AST_RWLIST_UNLOCK(&formats); 00115 00116 if (!res) 00117 ast_verb(2, "Unregistered format %s\n", name); 00118 else 00119 ast_log(LOG_WARNING, "Tried to unregister format %s, already unregistered\n", name); 00120 00121 return res; 00122 }
static int ast_fsread_audio | ( | const void * | data | ) | [static] |
Definition at line 800 of file file.c.
References ast_readaudio_callback(), and FSREAD_SUCCESS_SCHED.
Referenced by ast_readaudio_callback().
00801 { 00802 struct ast_filestream *fs = (struct ast_filestream *)data; 00803 enum fsread_res res; 00804 00805 res = ast_readaudio_callback(fs); 00806 00807 if (res == FSREAD_SUCCESS_SCHED) 00808 return 1; 00809 00810 return 0; 00811 }
static int ast_fsread_video | ( | const void * | data | ) | [static] |
Definition at line 847 of file file.c.
References ast_readvideo_callback(), and FSREAD_SUCCESS_SCHED.
Referenced by ast_readvideo_callback().
00848 { 00849 struct ast_filestream *fs = (struct ast_filestream *)data; 00850 enum fsread_res res; 00851 00852 res = ast_readvideo_callback(fs); 00853 00854 if (res == FSREAD_SUCCESS_SCHED) 00855 return 1; 00856 00857 return 0; 00858 }
struct ast_filestream* ast_openstream | ( | struct ast_channel * | chan, | |
const char * | filename, | |||
const char * | preflang | |||
) |
Opens stream for use in seeking, playing.
chan | channel to work with | |
filename | to use | |
preflang | prefered language to use |
a | ast_filestream pointer if it opens the file. | |
NULL | on error. |
Definition at line 631 of file file.c.
References ast_openstream_full().
Referenced by ast_streamfile(), dictate_exec(), handle_getoption(), handle_streamfile(), and speech_streamfile().
00632 { 00633 return ast_openstream_full(chan, filename, preflang, 0); 00634 }
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.
chan | channel to work with | |
filename | to use | |
preflang | prefered language to use | |
asis | if set, don't clear generators |
a | ast_filestream pointer if it opens the file. | |
NULL | on error. |
Definition at line 636 of file file.c.
References ACTION_OPEN, ast_deactivate_generator(), ast_filehelper(), AST_FORMAT_AUDIO_MASK, ast_log(), ast_set_write_format(), ast_stopstream(), ast_filestream::buf, fileexists_core(), LOG_WARNING, ast_channel::oldwriteformat, ast_channel::stream, and ast_channel::writeformat.
Referenced by ast_openstream(), and gen_nextfile().
00637 { 00638 /* 00639 * Use fileexists_core() to find a file in a compatible 00640 * language and format, set up a suitable translator, 00641 * and open the stream. 00642 */ 00643 format_t fmts, res; 00644 int buflen; 00645 char *buf; 00646 00647 if (!asis) { 00648 /* do this first, otherwise we detect the wrong writeformat */ 00649 ast_stopstream(chan); 00650 if (chan->generator) 00651 ast_deactivate_generator(chan); 00652 } 00653 if (preflang == NULL) 00654 preflang = ""; 00655 buflen = strlen(preflang) + strlen(filename) + 4; 00656 buf = alloca(buflen); 00657 if (buf == NULL) 00658 return NULL; 00659 fmts = fileexists_core(filename, NULL, preflang, buf, buflen); 00660 if (fmts > 0) 00661 fmts &= AST_FORMAT_AUDIO_MASK; 00662 if (fmts < 1) { 00663 ast_log(LOG_WARNING, "File %s does not exist in any format\n", filename); 00664 return NULL; 00665 } 00666 chan->oldwriteformat = chan->writeformat; 00667 /* Set the channel to a format we can work with */ 00668 res = ast_set_write_format(chan, fmts); 00669 if (res == -1) { /* No format available that works with this channel */ 00670 return NULL; 00671 } 00672 res = ast_filehelper(buf, chan, NULL, ACTION_OPEN); 00673 if (res >= 0) 00674 return chan->stream; 00675 return NULL; 00676 }
struct ast_filestream* ast_openvstream | ( | struct ast_channel * | chan, | |
const char * | filename, | |||
const char * | preflang | |||
) |
Opens stream for use in seeking, playing.
chan | channel to work with | |
filename | to use | |
preflang | prefered language to use |
a | ast_filestream pointer if it opens the file. | |
NULL | on error. |
Definition at line 678 of file file.c.
References ACTION_OPEN, ast_filehelper(), AST_FORMAT_FIRST_VIDEO_BIT, AST_FORMAT_VIDEO_MASK, ast_getformatname(), ast_log(), ast_filestream::buf, fileexists_core(), ast_filestream::fmt, format, LOG_WARNING, ast_channel::nativeformats, and ast_channel::vstream.
Referenced by ast_streamfile(), handle_getoption(), and handle_streamfile().
00679 { 00680 /* As above, but for video. But here we don't have translators 00681 * so we must enforce a format. 00682 */ 00683 format_t format; 00684 char *buf; 00685 int buflen; 00686 00687 if (preflang == NULL) 00688 preflang = ""; 00689 buflen = strlen(preflang) + strlen(filename) + 4; 00690 buf = alloca(buflen); 00691 if (buf == NULL) 00692 return NULL; 00693 00694 for (format = AST_FORMAT_FIRST_VIDEO_BIT; format <= AST_FORMAT_VIDEO_MASK; format = format << 1) { 00695 int fd; 00696 const char *fmt; 00697 00698 if (!(chan->nativeformats & format)) 00699 continue; 00700 fmt = ast_getformatname(format); 00701 if ( fileexists_core(filename, fmt, preflang, buf, buflen) < 1) /* no valid format */ 00702 continue; 00703 fd = ast_filehelper(buf, chan, fmt, ACTION_OPEN); 00704 if (fd >= 0) 00705 return chan->vstream; 00706 ast_log(LOG_WARNING, "File %s has video but couldn't be opened\n", filename); 00707 } 00708 return NULL; 00709 }
int ast_playstream | ( | struct ast_filestream * | s | ) |
Play a open stream on a channel.
s | filestream to play |
0 | on success. | |
-1 | on failure. |
Definition at line 866 of file file.c.
References AST_FORMAT_AUDIO_MASK, ast_readaudio_callback(), ast_readvideo_callback(), ast_filestream::fmt, ast_format::format, and FSREAD_FAILURE.
Referenced by ast_streamfile(), handle_getoption(), handle_streamfile(), and speech_streamfile().
00867 { 00868 enum fsread_res res; 00869 00870 if (s->fmt->format & AST_FORMAT_AUDIO_MASK) 00871 res = ast_readaudio_callback(s); 00872 else 00873 res = ast_readvideo_callback(s); 00874 00875 return (res == FSREAD_FAILURE) ? -1 : 0; 00876 }
static enum fsread_res ast_readaudio_callback | ( | struct ast_filestream * | s | ) | [static] |
Definition at line 751 of file file.c.
References ast_format_rate(), ast_frfree, ast_fsread_audio(), ast_log(), ast_sched_add(), ast_settimeout(), ast_write(), ast_filestream::fmt, ast_format::format, FSREAD_FAILURE, FSREAD_SUCCESS_NOSCHED, FSREAD_SUCCESS_SCHED, ast_filestream::lasttimeout, LOG_WARNING, ast_channel::name, ast_filestream::orig_chan_name, ast_filestream::owner, read_frame(), ast_channel::sched, ast_channel::streamid, and ast_channel::timingfd.
Referenced by ast_fsread_audio(), and ast_playstream().
00752 { 00753 int whennext = 0; 00754 00755 while (!whennext) { 00756 struct ast_frame *fr; 00757 00758 if (s->orig_chan_name && strcasecmp(s->owner->name, s->orig_chan_name)) { 00759 goto return_failure; 00760 } 00761 00762 fr = read_frame(s, &whennext); 00763 00764 if (!fr /* stream complete */ || ast_write(s->owner, fr) /* error writing */) { 00765 if (fr) { 00766 ast_log(LOG_WARNING, "Failed to write frame\n"); 00767 ast_frfree(fr); 00768 } 00769 goto return_failure; 00770 } 00771 00772 if (fr) { 00773 ast_frfree(fr); 00774 } 00775 } 00776 00777 if (whennext != s->lasttimeout) { 00778 if (s->owner->timingfd > -1) { 00779 float samp_rate = (float) ast_format_rate(s->fmt->format); 00780 unsigned int rate; 00781 00782 rate = (unsigned int) roundf(samp_rate / ((float) whennext)); 00783 00784 ast_settimeout(s->owner, rate, ast_fsread_audio, s); 00785 } else { 00786 s->owner->streamid = ast_sched_add(s->owner->sched, 00787 whennext / (ast_format_rate(s->fmt->format) / 1000), ast_fsread_audio, s); 00788 } 00789 s->lasttimeout = whennext; 00790 return FSREAD_SUCCESS_NOSCHED; 00791 } 00792 return FSREAD_SUCCESS_SCHED; 00793 00794 return_failure: 00795 s->owner->streamid = -1; 00796 ast_settimeout(s->owner, 0, NULL, NULL); 00797 return FSREAD_FAILURE; 00798 }
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.
filename | the name of the file to read from | |
type | format of file you wish to read from | |
comment | comment to go with | |
flags | file flags | |
check | (unimplemented, hence negligible) | |
mode | Open 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. |
a | struct ast_filestream on success. | |
NULL | on failure. |
Definition at line 997 of file file.c.
References ast_closestream(), ast_free, ast_log(), AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_strdup, build_filename(), errno, ast_format::exts, exts_compare(), f, ast_filestream::filename, ast_filestream::flags, ast_filestream::fmt, get_filestream(), LOG_WARNING, ast_filestream::mode, open_wrapper(), ast_filestream::trans, and ast_filestream::vfs.
Referenced by handle_cli_file_convert().
00998 { 00999 FILE *bfile; 01000 struct ast_format *f; 01001 struct ast_filestream *fs = NULL; 01002 char *fn; 01003 int format_found = 0; 01004 01005 AST_RWLIST_RDLOCK(&formats); 01006 01007 AST_RWLIST_TRAVERSE(&formats, f, list) { 01008 fs = NULL; 01009 if (!exts_compare(f->exts, type)) 01010 continue; 01011 else 01012 format_found = 1; 01013 01014 fn = build_filename(filename, type); 01015 errno = 0; 01016 bfile = fopen(fn, "r"); 01017 01018 if (!bfile || (fs = get_filestream(f, bfile)) == NULL || open_wrapper(fs) ) { 01019 ast_log(LOG_WARNING, "Unable to open %s\n", fn); 01020 if (fs) { 01021 ast_closestream(fs); 01022 } 01023 fs = NULL; 01024 bfile = NULL; 01025 ast_free(fn); 01026 break; 01027 } 01028 /* found it */ 01029 fs->trans = NULL; 01030 fs->fmt = f; 01031 fs->flags = flags; 01032 fs->mode = mode; 01033 fs->filename = ast_strdup(filename); 01034 fs->vfs = NULL; 01035 break; 01036 } 01037 01038 AST_RWLIST_UNLOCK(&formats); 01039 if (!format_found) 01040 ast_log(LOG_WARNING, "No such format '%s'\n", type); 01041 01042 return fs; 01043 }
struct ast_frame* ast_readframe | ( | struct ast_filestream * | s | ) |
Read a frame from a filestream.
s | ast_filestream to act on |
NULL | if read failed. |
Definition at line 736 of file file.c.
References read_frame().
Referenced by dictate_exec(), gen_readframe(), handle_cli_file_convert(), and moh_files_readframe().
00737 { 00738 int whennext = 0; 00739 00740 return read_frame(s, &whennext); 00741 }
static enum fsread_res ast_readvideo_callback | ( | struct ast_filestream * | s | ) | [static] |
Definition at line 815 of file file.c.
References ast_format_rate(), ast_frfree, ast_fsread_video(), ast_log(), ast_sched_add(), ast_write(), ast_filestream::fmt, ast_format::format, FSREAD_FAILURE, FSREAD_SUCCESS_NOSCHED, FSREAD_SUCCESS_SCHED, ast_filestream::lasttimeout, LOG_WARNING, ast_filestream::owner, read_frame(), ast_channel::sched, and ast_channel::vstreamid.
Referenced by ast_fsread_video(), and ast_playstream().
00816 { 00817 int whennext = 0; 00818 00819 while (!whennext) { 00820 struct ast_frame *fr = read_frame(s, &whennext); 00821 00822 if (!fr /* stream complete */ || ast_write(s->owner, fr) /* error writing */) { 00823 if (fr) { 00824 ast_log(LOG_WARNING, "Failed to write frame\n"); 00825 ast_frfree(fr); 00826 } 00827 s->owner->vstreamid = -1; 00828 return FSREAD_FAILURE; 00829 } 00830 00831 if (fr) { 00832 ast_frfree(fr); 00833 } 00834 } 00835 00836 if (whennext != s->lasttimeout) { 00837 s->owner->vstreamid = ast_sched_add(s->owner->sched, 00838 whennext / (ast_format_rate(s->fmt->format) / 1000), 00839 ast_fsread_video, s); 00840 s->lasttimeout = whennext; 00841 return FSREAD_SUCCESS_NOSCHED; 00842 } 00843 00844 return FSREAD_SUCCESS_SCHED; 00845 }
int ast_seekstream | ( | struct ast_filestream * | fs, | |
off_t | sample_offset, | |||
int | whence | |||
) |
Seeks into stream.
fs | ast_filestream to perform seek on | |
sample_offset | numbers of samples to seek | |
whence | SEEK_SET, SEEK_CUR, SEEK_END |
0 | on success. | |
-1 | on failure. |
Definition at line 878 of file file.c.
References ast_filestream::fmt, and ast_format::seek.
Referenced by __ast_read(), ast_control_streamfile(), ast_stream_fastforward(), ast_stream_rewind(), ast_streamfile(), ast_write(), dictate_exec(), handle_getoption(), handle_recordfile(), handle_streamfile(), and speech_streamfile().
int ast_stopstream | ( | struct ast_channel * | c | ) |
Stops a stream.
c | The channel you wish to stop playback on |
0 | always |
Definition at line 124 of file file.c.
References ast_channel_lock, ast_channel_unlock, ast_closestream(), ast_getformatname(), ast_log(), ast_set_write_format(), LOG_WARNING, ast_channel::oldwriteformat, ast_channel::stream, and ast_channel::vstream.
Referenced by ast_adsi_transmit_message_full(), ast_control_streamfile(), 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_vi(), ast_say_number_full_cs(), ast_say_number_full_da(), ast_say_number_full_de(), ast_say_number_full_en(), 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_it(), 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(), dial_exec_full(), directory_exec(), grab_transfer(), handle_getoption(), handle_speechrecognize(), handle_streamfile(), ices_exec(), ivr_dispatch(), menu_callback(), minivm_greet_exec(), mp3_exec(), NBScat_exec(), parkandannounce_exec(), pbx_builtin_background(), pl_odtworz_plik(), play_file(), play_mailbox_owner(), playback_exec(), read_exec(), readexten_exec(), recordthread(), rpt_tele_thread(), s_streamwait3(), say_character_str_full(), say_digit_str_full(), say_phonetic_str_full(), saycharstr(), sayfile(), saynum(), select_item_seq(), send_morse(), send_tone_telemetry(), send_waveform_to_channel(), speech_background(), vm_authenticate(), vm_execmain(), wait_for_winner(), waitstream_core(), and zapateller_exec().
00125 { 00126 ast_channel_lock(tmp); 00127 00128 /* Stop a running stream if there is one */ 00129 if (tmp->stream) { 00130 ast_closestream(tmp->stream); 00131 tmp->stream = NULL; 00132 if (tmp->oldwriteformat && ast_set_write_format(tmp, tmp->oldwriteformat)) 00133 ast_log(LOG_WARNING, "Unable to restore format back to %s\n", ast_getformatname(tmp->oldwriteformat)); 00134 } 00135 /* Stop the video stream too */ 00136 if (tmp->vstream != NULL) { 00137 ast_closestream(tmp->vstream); 00138 tmp->vstream = NULL; 00139 } 00140 00141 ast_channel_unlock(tmp); 00142 00143 return 0; 00144 }
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.
-1 | if error. | |
digit | if interrupted by a digit. |
Definition at line 1360 of file file.c.
References ast_streamfile(), ast_strlen_zero(), ast_test_suite_event_notify, ast_waitstream(), and ast_channel::language.
Referenced by __ast_play_and_record(), announce_user_count(), app_exec(), ast_pickup_call(), ast_record_review(), bridge_playfile(), builtin_atxfer(), builtin_automixmonitor(), builtin_blindtransfer(), confbridge_exec(), directory_exec(), feature_attended_transfer(), feature_blind_transfer(), forward_message(), grab_transfer(), invent_message(), ivr_dispatch(), join_conference_bridge(), masq_park_call(), menu_callback(), park_call_exec(), parked_call_exec(), play_mailbox_owner(), play_message_callerid(), play_message_on_chan(), play_prompt_to_channel(), play_record_review(), play_sound_file(), sayname(), select_item_seq(), vm_forwardoptions(), vmsayname_exec(), wait_file2(), and xfer_park_call_helper().
01361 { 01362 int res = 0; 01363 if (!ast_strlen_zero(file)) { 01364 ast_test_suite_event_notify("PLAYBACK", "Message: %s", file); 01365 res = ast_streamfile(chan, file, chan->language); 01366 if (!res) { 01367 res = ast_waitstream(chan, digits); 01368 } 01369 } 01370 return res; 01371 }
int ast_stream_fastforward | ( | struct ast_filestream * | fs, | |
off_t | ms | |||
) |
Fast forward stream ms.
fs | filestream to act on | |
ms | milliseconds to move |
0 | on success. | |
-1 | on failure. |
Definition at line 893 of file file.c.
References ast_seekstream(), and DEFAULT_SAMPLES_PER_MS.
Referenced by waitstream_core().
00894 { 00895 return ast_seekstream(fs, ms * DEFAULT_SAMPLES_PER_MS, SEEK_CUR); 00896 }
int ast_stream_rewind | ( | struct ast_filestream * | fs, | |
off_t | ms | |||
) |
Rewind stream ms.
fs | filestream to act on | |
ms | milliseconds to move |
0 | on success. | |
-1 | on failure. |
Definition at line 898 of file file.c.
References ast_seekstream(), and DEFAULT_SAMPLES_PER_MS.
Referenced by handle_recordfile(), and waitstream_core().
00899 { 00900 return ast_seekstream(fs, -ms * DEFAULT_SAMPLES_PER_MS, SEEK_CUR); 00901 }
int ast_streamfile | ( | struct ast_channel * | c, | |
const char * | filename, | |||
const char * | preflang | |||
) |
Streams a file.
c | channel to stream the file to | |
filename | the name of the file you wish to stream, minus the extension | |
preflang | the 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. |
0 | on success. | |
-1 | on failure. |
Definition at line 947 of file file.c.
References ast_applystream(), ast_debug, AST_FLAG_MASQ_NOSTREAM, ast_getformatname(), ast_getformatname_multiple(), ast_log(), ast_openstream(), ast_openvstream(), ast_playstream(), ast_seekstream(), ast_strdup, ast_test_flag, ast_verb, errno, ast_filestream::f, ast_filestream::fmt, ast_format::format, LOG_WARNING, ast_channel::name, ast_channel::nativeformats, ast_filestream::orig_chan_name, ast_filestream::vfs, and ast_channel::writeformat.
Referenced by __analog_ss_thread(), action_bridge(), agent_call(), analog_ss_thread(), announce_thread(), app_exec(), ast_app_getdata(), ast_app_getdata_full(), ast_control_streamfile(), 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_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_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_vi(), ast_say_number_full_cs(), ast_say_number_full_da(), ast_say_number_full_de(), ast_say_number_full_en(), 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_it(), 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_ka(), ast_say_time_nl(), ast_say_time_zh(), ast_stream_and_wait(), background_detect_exec(), bridge_exec(), check_availability(), check_beep(), common_exec(), conf_exec(), conf_run(), dial_exec_full(), do_directory(), find_conf_realtime(), forward_message(), gr_say_number_female(), handle_recordfile(), invent_message(), leave_voicemail(), local_attended_transfer(), login_exec(), menu_callback(), minivm_greet_exec(), page_exec(), parkandannounce_exec(), pbx_builtin_background(), pl_odtworz_plik(), play_and_wait(), play_file(), play_record_review(), playback_exec(), privacy_exec(), readexten_exec(), retrydial_exec(), rpt_tele_thread(), s_streamwait3(), say_character_str_full(), say_digit_str_full(), say_phonetic_str_full(), sayfile(), select_item_menu(), setup_privacy_args(), vm_authenticate(), wait_file(), and wait_for_winner().
00948 { 00949 struct ast_filestream *fs; 00950 struct ast_filestream *vfs=NULL; 00951 char fmt[256]; 00952 off_t pos; 00953 int seekattempt; 00954 int res; 00955 00956 fs = ast_openstream(chan, filename, preflang); 00957 if (!fs) { 00958 ast_log(LOG_WARNING, "Unable to open %s (format %s): %s\n", filename, ast_getformatname_multiple(fmt, sizeof(fmt), chan->nativeformats), strerror(errno)); 00959 return -1; 00960 } 00961 00962 /* check to see if there is any data present (not a zero length file), 00963 * done this way because there is no where for ast_openstream_full to 00964 * return the file had no data. */ 00965 pos = ftello(fs->f); 00966 seekattempt = fseeko(fs->f, -1, SEEK_END); 00967 if (seekattempt) { 00968 if (errno == EINVAL) { 00969 /* Zero-length file, as opposed to a pipe */ 00970 return 0; 00971 } else { 00972 ast_seekstream(fs, 0, SEEK_SET); 00973 } 00974 } else { 00975 fseeko(fs->f, pos, SEEK_SET); 00976 } 00977 00978 vfs = ast_openvstream(chan, filename, preflang); 00979 if (vfs) { 00980 ast_debug(1, "Ooh, found a video stream, too, format %s\n", ast_getformatname(vfs->fmt->format)); 00981 } 00982 00983 if (ast_test_flag(chan, AST_FLAG_MASQ_NOSTREAM)) 00984 fs->orig_chan_name = ast_strdup(chan->name); 00985 if (ast_applystream(chan, fs)) 00986 return -1; 00987 if (vfs && ast_applystream(chan, vfs)) 00988 return -1; 00989 res = ast_playstream(fs); 00990 if (!res && vfs) 00991 res = ast_playstream(vfs); 00992 ast_verb(3, "<%s> Playing '%s.%s' (language '%s')\n", chan->name, filename, ast_getformatname(chan->writeformat), preflang ? preflang : "default"); 00993 00994 return res; 00995 }
off_t ast_tellstream | ( | struct ast_filestream * | fs | ) |
Tell where we are in a stream.
fs | fs to act on |
Definition at line 888 of file file.c.
References ast_filestream::fmt, and ast_format::tell.
Referenced by ast_control_streamfile(), handle_getoption(), handle_recordfile(), handle_speechrecognize(), and handle_streamfile().
int ast_truncstream | ( | struct ast_filestream * | fs | ) |
Trunc stream at current location.
fs | filestream to act on |
0 | on success. | |
-1 | on failure. |
Definition at line 883 of file file.c.
References ast_filestream::fmt, and ast_format::trunc.
Referenced by handle_recordfile().
int ast_waitstream | ( | struct ast_channel * | c, | |
const char * | breakon | |||
) |
Waits for a stream to stop or digit to be pressed.
c | channel to waitstream on | |
breakon | string 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, |
0 | if the stream finishes | |
the | character if it was interrupted, | |
-1 | on error |
Definition at line 1333 of file file.c.
References waitstream_core().
Referenced by __analog_ss_thread(), action_bridge(), agent_call(), analog_ss_thread(), announce_thread(), 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_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_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_vi(), ast_say_number_full_cs(), ast_say_number_full_da(), ast_say_number_full_de(), ast_say_number_full_en(), 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_it(), 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_ka(), ast_say_time_nl(), ast_say_time_zh(), ast_stream_and_wait(), bridge_exec(), check_availability(), check_beep(), common_exec(), conf_exec(), conf_run(), directory_exec(), find_conf_realtime(), gr_say_number_female(), handle_recordfile(), invent_message(), leave_voicemail(), local_attended_transfer(), login_exec(), menu_callback(), minivm_greet_exec(), page_exec(), parkandannounce_exec(), pbx_builtin_background(), pl_odtworz_plik(), play_and_wait(), play_file(), play_record_review(), playback_exec(), privacy_exec(), retrydial_exec(), rpt_tele_thread(), s_streamwait3(), say_character_str_full(), say_digit_str_full(), say_phonetic_str_full(), saycharstr(), sayfile(), saynum(), select_item_menu(), send_morse(), send_tone_telemetry(), setup_privacy_args(), vm_authenticate(), and wait_file().
01334 { 01335 return waitstream_core(c, breakon, NULL, NULL, 0, -1, -1, NULL); 01336 }
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.
c | channel to waitstream on | |
context | string 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, |
0 | if the stream finishes. | |
the | character if it was interrupted. | |
-1 | on error. |
Definition at line 1344 of file file.c.
References ast_channel::context, and waitstream_core().
Referenced by pbx_builtin_background().
01345 { 01346 /* Waitstream, with return in the case of a valid 1 digit extension */ 01347 /* in the current or specified context being pressed */ 01348 01349 if (!context) 01350 context = c->context; 01351 return waitstream_core(c, NULL, NULL, NULL, 0, 01352 -1, -1, context); 01353 }
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.
c | channel to waitstream on | |
breakon | string of DTMF digits to break upon | |
forward | DTMF digit to fast forward upon | |
rewind | DTMF digit to rewind upon | |
ms | How 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, |
0 | if the stream finishes. | |
the | character if it was interrupted. | |
-1 | on error. |
Definition at line 1327 of file file.c.
References waitstream_core().
Referenced by ast_control_streamfile().
01328 { 01329 return waitstream_core(c, breakon, forward, reverse, ms, 01330 -1 /* no audiofd */, -1 /* no cmdfd */, NULL /* no context */); 01331 }
int ast_waitstream_full | ( | struct ast_channel * | c, | |
const char * | breakon, | |||
int | audiofd, | |||
int | monfd | |||
) |
Same as waitstream, but with audio output to fd and monitored fd checking.
Definition at line 1338 of file file.c.
References waitstream_core().
Referenced by 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_vi(), ast_say_number_full_cs(), ast_say_number_full_da(), ast_say_number_full_de(), ast_say_number_full_en(), 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_it(), 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(), handle_getoption(), handle_streamfile(), pl_odtworz_plik(), s_streamwait3(), say_character_str_full(), say_digit_str_full(), and say_phonetic_str_full().
01339 { 01340 return waitstream_core(c, breakon, NULL, NULL, 0, 01341 audiofd, cmdfd, NULL /* no context */); 01342 }
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.
filename | the name of the file to write to | |
type | format of file you wish to write out to | |
comment | comment to go with | |
flags | output file flags | |
check | (unimplemented, hence negligible) | |
mode | Open 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. |
a | struct ast_filestream on success. | |
NULL | on failure. |
Definition at line 1045 of file file.c.
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, ast_strdupa, ast_filestream::buf, build_filename(), errno, ast_format::exts, exts_compare(), ast_filestream::f, f, ast_filestream::filename, ast_filestream::flags, ast_filestream::fmt, get_filestream(), LOG_WARNING, ast_filestream::mode, ast_filestream::realfilename, record_cache_dir, rewrite_wrapper(), ast_format::seek, ast_filestream::trans, ast_filestream::vfs, and ast_filestream::write_buffer.
Referenced by __ast_play_and_record(), ast_monitor_start(), ast_writestream(), dictate_exec(), handle_cli_file_convert(), handle_recordfile(), mixmonitor_thread(), recordthread(), and rpt().
01046 { 01047 int fd, myflags = 0; 01048 /* compiler claims this variable can be used before initialization... */ 01049 FILE *bfile = NULL; 01050 struct ast_format *f; 01051 struct ast_filestream *fs = NULL; 01052 char *buf = NULL; 01053 size_t size = 0; 01054 int format_found = 0; 01055 01056 AST_RWLIST_RDLOCK(&formats); 01057 01058 /* set the O_TRUNC flag if and only if there is no O_APPEND specified */ 01059 /* We really can't use O_APPEND as it will break WAV header updates */ 01060 if (flags & O_APPEND) { 01061 flags &= ~O_APPEND; 01062 } else { 01063 myflags = O_TRUNC; 01064 } 01065 01066 myflags |= O_WRONLY | O_CREAT; 01067 01068 /* XXX need to fix this - we should just do the fopen, 01069 * not open followed by fdopen() 01070 */ 01071 AST_RWLIST_TRAVERSE(&formats, f, list) { 01072 char *fn, *orig_fn = NULL; 01073 if (fs) 01074 break; 01075 01076 if (!exts_compare(f->exts, type)) 01077 continue; 01078 else 01079 format_found = 1; 01080 01081 fn = build_filename(filename, type); 01082 fd = open(fn, flags | myflags, mode); 01083 if (fd > -1) { 01084 /* fdopen() the resulting file stream */ 01085 bfile = fdopen(fd, ((flags | myflags) & O_RDWR) ? "w+" : "w"); 01086 if (!bfile) { 01087 ast_log(LOG_WARNING, "Whoa, fdopen failed: %s!\n", strerror(errno)); 01088 close(fd); 01089 fd = -1; 01090 } 01091 } 01092 01093 if (ast_opt_cache_record_files && (fd > -1)) { 01094 char *c; 01095 01096 fclose(bfile); /* this also closes fd */ 01097 /* 01098 We touch orig_fn just as a place-holder so other things (like vmail) see the file is there. 01099 What we are really doing is writing to record_cache_dir until we are done then we will mv the file into place. 01100 */ 01101 orig_fn = ast_strdupa(fn); 01102 for (c = fn; *c; c++) 01103 if (*c == '/') 01104 *c = '_'; 01105 01106 size = strlen(fn) + strlen(record_cache_dir) + 2; 01107 buf = alloca(size); 01108 strcpy(buf, record_cache_dir); 01109 strcat(buf, "/"); 01110 strcat(buf, fn); 01111 ast_free(fn); 01112 fn = buf; 01113 fd = open(fn, flags | myflags, mode); 01114 if (fd > -1) { 01115 /* fdopen() the resulting file stream */ 01116 bfile = fdopen(fd, ((flags | myflags) & O_RDWR) ? "w+" : "w"); 01117 if (!bfile) { 01118 ast_log(LOG_WARNING, "Whoa, fdopen failed: %s!\n", strerror(errno)); 01119 close(fd); 01120 fd = -1; 01121 } 01122 } 01123 } 01124 if (fd > -1) { 01125 errno = 0; 01126 fs = get_filestream(f, bfile); 01127 if (fs) { 01128 if ((fs->write_buffer = ast_malloc(32768))) { 01129 setvbuf(fs->f, fs->write_buffer, _IOFBF, 32768); 01130 } 01131 } 01132 if (!fs || rewrite_wrapper(fs, comment)) { 01133 ast_log(LOG_WARNING, "Unable to rewrite %s\n", fn); 01134 close(fd); 01135 if (orig_fn) { 01136 unlink(fn); 01137 unlink(orig_fn); 01138 } 01139 if (fs) { 01140 ast_closestream(fs); 01141 fs = NULL; 01142 } 01143 continue; 01144 } 01145 fs->trans = NULL; 01146 fs->fmt = f; 01147 fs->flags = flags; 01148 fs->mode = mode; 01149 if (orig_fn) { 01150 fs->realfilename = ast_strdup(orig_fn); 01151 fs->filename = ast_strdup(fn); 01152 } else { 01153 fs->realfilename = NULL; 01154 fs->filename = ast_strdup(filename); 01155 } 01156 fs->vfs = NULL; 01157 /* If truncated, we'll be at the beginning; if not truncated, then append */ 01158 f->seek(fs, 0, SEEK_END); 01159 } else if (errno != EEXIST) { 01160 ast_log(LOG_WARNING, "Unable to open file %s: %s\n", fn, strerror(errno)); 01161 if (orig_fn) 01162 unlink(orig_fn); 01163 } 01164 /* if buf != NULL then fn is already free and pointing to it */ 01165 if (!buf) 01166 ast_free(fn); 01167 } 01168 01169 AST_RWLIST_UNLOCK(&formats); 01170 01171 if (!format_found) 01172 ast_log(LOG_WARNING, "No such format '%s'\n", type); 01173 01174 return fs; 01175 }
int ast_writestream | ( | struct ast_filestream * | fs, | |
struct ast_frame * | f | |||
) |
Writes a frame to a stream.
fs | filestream to write to | |
f | frame to write to the filestream Send a frame to a filestream -- note: does NOT free the frame, call ast_frfree manually |
0 | on success. | |
-1 | on failure. |
Definition at line 146 of file file.c.
References ast_debug, AST_FORMAT_AUDIO_MASK, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_frfree, ast_getformatname(), AST_LIST_NEXT, ast_log(), ast_translate(), ast_translator_build_path(), ast_translator_free_path(), ast_writefile(), ast_writestream(), f, ast_filestream::filename, ast_filestream::flags, ast_filestream::fmt, ast_format::format, ast_filestream::lastwriteformat, LOG_WARNING, ast_filestream::mode, ast_format::name, ast_filestream::trans, type, ast_filestream::vfs, and ast_format::write.
Referenced by __ast_play_and_record(), __ast_read(), ast_write(), ast_writestream(), dictate_exec(), handle_cli_file_convert(), handle_recordfile(), mixmonitor_thread(), recordthread(), and rpt().
00147 { 00148 int res = -1; 00149 int alt = 0; 00150 if (f->frametype == AST_FRAME_VIDEO) { 00151 if (fs->fmt->format & AST_FORMAT_AUDIO_MASK) { 00152 /* This is the audio portion. Call the video one... */ 00153 if (!fs->vfs && fs->filename) { 00154 const char *type = ast_getformatname(f->subclass.codec & ~0x1); 00155 fs->vfs = ast_writefile(fs->filename, type, NULL, fs->flags, 0, fs->mode); 00156 ast_debug(1, "Opened video output file\n"); 00157 } 00158 if (fs->vfs) 00159 return ast_writestream(fs->vfs, f); 00160 /* else ignore */ 00161 return 0; 00162 } else { 00163 /* Might / might not have mark set */ 00164 alt = 1; 00165 } 00166 } else if (f->frametype != AST_FRAME_VOICE) { 00167 ast_log(LOG_WARNING, "Tried to write non-voice frame\n"); 00168 return -1; 00169 } 00170 if (((fs->fmt->format | alt) & f->subclass.codec) == f->subclass.codec) { 00171 res = fs->fmt->write(fs, f); 00172 if (res < 0) 00173 ast_log(LOG_WARNING, "Natural write failed\n"); 00174 else if (res > 0) 00175 ast_log(LOG_WARNING, "Huh??\n"); 00176 } else { 00177 /* XXX If they try to send us a type of frame that isn't the normal frame, and isn't 00178 the one we've setup a translator for, we do the "wrong thing" XXX */ 00179 if (fs->trans && f->subclass.codec != fs->lastwriteformat) { 00180 ast_translator_free_path(fs->trans); 00181 fs->trans = NULL; 00182 } 00183 if (!fs->trans) 00184 fs->trans = ast_translator_build_path(fs->fmt->format, f->subclass.codec); 00185 if (!fs->trans) 00186 ast_log(LOG_WARNING, "Unable to translate to format %s, source format %s\n", 00187 fs->fmt->name, ast_getformatname(f->subclass.codec)); 00188 else { 00189 struct ast_frame *trf; 00190 fs->lastwriteformat = f->subclass.codec; 00191 /* Get the translated frame but don't consume the original in case they're using it on another stream */ 00192 if ((trf = ast_translate(fs->trans, f, 0))) { 00193 struct ast_frame *cur; 00194 00195 /* the translator may have returned multiple frames, so process them */ 00196 for (cur = trf; cur; cur = AST_LIST_NEXT(cur, frame_list)) { 00197 if ((res = fs->fmt->write(fs, trf))) { 00198 ast_log(LOG_WARNING, "Translated frame write failed\n"); 00199 break; 00200 } 00201 } 00202 ast_frfree(trf); 00203 } else { 00204 res = 0; 00205 } 00206 } 00207 } 00208 return res; 00209 }
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 254 of file file.c.
References asprintf, ast_config_AST_DATA_DIR, ast_log(), errno, and LOG_WARNING.
Referenced by ast_filehelper(), ast_readfile(), and ast_writefile().
00255 { 00256 char *fn = NULL; 00257 00258 if (!strcmp(ext, "wav49")) 00259 ext = "WAV"; 00260 00261 if (filename[0] == '/') { 00262 if (asprintf(&fn, "%s.%s", filename, ext) < 0) { 00263 ast_log(LOG_WARNING, "asprintf() failed: %s\n", strerror(errno)); 00264 fn = NULL; 00265 } 00266 } else { 00267 if (asprintf(&fn, "%s/sounds/%s.%s", 00268 ast_config_AST_DATA_DIR, filename, ext) < 0) { 00269 ast_log(LOG_WARNING, "asprintf() failed: %s\n", strerror(errno)); 00270 fn = NULL; 00271 } 00272 } 00273 return fn; 00274 }
static int copy | ( | const char * | infile, | |
const char * | outfile | |||
) | [static] |
Definition at line 211 of file file.c.
References AST_FILE_MODE, ast_log(), errno, len(), and LOG_WARNING.
00212 { 00213 int ifd, ofd, len; 00214 char buf[4096]; /* XXX make it lerger. */ 00215 00216 if ((ifd = open(infile, O_RDONLY)) < 0) { 00217 ast_log(LOG_WARNING, "Unable to open %s in read-only mode\n", infile); 00218 return -1; 00219 } 00220 if ((ofd = open(outfile, O_WRONLY | O_TRUNC | O_CREAT, AST_FILE_MODE)) < 0) { 00221 ast_log(LOG_WARNING, "Unable to open %s in write-only mode\n", outfile); 00222 close(ifd); 00223 return -1; 00224 } 00225 while ( (len = read(ifd, buf, sizeof(buf)) ) ) { 00226 int res; 00227 if (len < 0) { 00228 ast_log(LOG_WARNING, "Read failed on %s: %s\n", infile, strerror(errno)); 00229 break; 00230 } 00231 /* XXX handle partial writes */ 00232 res = write(ofd, buf, len); 00233 if (res != len) { 00234 ast_log(LOG_WARNING, "Write failed on %s (%d of %d): %s\n", outfile, res, len, strerror(errno)); 00235 len = -1; /* error marker */ 00236 break; 00237 } 00238 } 00239 close(ifd); 00240 close(ofd); 00241 if (len < 0) { 00242 unlink(outfile); 00243 return -1; /* error */ 00244 } 00245 return 0; /* success */ 00246 }
static int exts_compare | ( | const char * | exts, | |
const char * | type | |||
) | [static] |
Definition at line 278 of file file.c.
References ast_copy_string(), ext, and strsep().
Referenced by ast_filehelper(), ast_format_str_reduce(), ast_readfile(), and ast_writefile().
00279 { 00280 char tmp[256]; 00281 char *stringp = tmp, *ext; 00282 00283 ast_copy_string(tmp, exts, sizeof(tmp)); 00284 while ((ext = strsep(&stringp, "|"))) { 00285 if (!strcmp(ext, type)) 00286 return 1; 00287 } 00288 00289 return 0; 00290 }
static format_t fileexists_core | ( | const char * | filename, | |
const char * | fmt, | |||
const char * | preflang, | |||
char * | buf, | |||
int | buflen | |||
) | [static] |
helper routine to locate a file with a given format and language preference. 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.
Definition at line 581 of file file.c.
References ast_strdupa, ast_strlen_zero(), DEFAULT_LANGUAGE, and fileexists_test().
Referenced by ast_fileexists(), ast_openstream_full(), and ast_openvstream().
00583 { 00584 format_t res = -1; 00585 char *lang; 00586 00587 if (buf == NULL) { 00588 return -1; 00589 } 00590 00591 /* We try languages in the following order: 00592 * preflang (may include dialect and style codes) 00593 * lang (preflang without dialect - if any) 00594 * <none> 00595 * default (unless the same as preflang or lang without dialect) 00596 */ 00597 00598 lang = ast_strdupa(preflang); 00599 00600 /* Try preferred language, including removing any style or dialect codes */ 00601 while (!ast_strlen_zero(lang)) { 00602 char *end; 00603 00604 if ((res = fileexists_test(filename, fmt, lang, buf, buflen)) > 0) { 00605 return res; 00606 } 00607 00608 if ((end = strrchr(lang, '_')) != NULL) { 00609 *end = '\0'; 00610 continue; 00611 } 00612 00613 break; 00614 } 00615 00616 /* Try without any language */ 00617 if ((res = fileexists_test(filename, fmt, NULL, buf, buflen)) > 0) { 00618 return res; 00619 } 00620 00621 /* Finally try the default language unless it was already tried before */ 00622 if ((ast_strlen_zero(preflang) || strcmp(preflang, DEFAULT_LANGUAGE)) && (ast_strlen_zero(lang) || strcmp(lang, DEFAULT_LANGUAGE))) { 00623 if ((res = fileexists_test(filename, fmt, DEFAULT_LANGUAGE, buf, buflen)) > 0) { 00624 return res; 00625 } 00626 } 00627 00628 return 0; 00629 }
static format_t fileexists_test | ( | const char * | filename, | |
const char * | fmt, | |||
const char * | lang, | |||
char * | buf, | |||
int | buflen | |||
) | [static] |
Definition at line 547 of file file.c.
References ACTION_EXISTS, ast_filehelper(), and is_absolute_path().
Referenced by fileexists_core().
00549 { 00550 if (buf == NULL) { 00551 return -1; 00552 } 00553 00554 if (ast_language_is_prefix && !is_absolute_path(filename)) { /* new layout */ 00555 if (lang) { 00556 snprintf(buf, buflen, "%s/%s", lang, filename); 00557 } else { 00558 snprintf(buf, buflen, "%s", filename); 00559 } 00560 } else { /* old layout */ 00561 strcpy(buf, filename); /* first copy the full string */ 00562 if (lang) { 00563 /* insert the language and suffix if needed */ 00564 const char *c = strrchr(filename, '/'); 00565 int offset = c ? c - filename + 1 : 0; /* points right after the last '/' */ 00566 snprintf(buf + offset, buflen - offset, "%s/%s", lang, filename + offset); 00567 } 00568 } 00569 00570 return ast_filehelper(buf, NULL, fmt, ACTION_EXISTS); 00571 }
static void filestream_close | ( | struct ast_filestream * | f | ) | [static] |
Definition at line 293 of file file.c.
References AST_FORMAT_AUDIO_MASK, AST_FORMAT_VIDEO_MASK, ast_log(), AST_LOG_WARNING, AST_SCHED_DEL, ast_settimeout(), f, ast_format::format, and ast_format::name.
Referenced by ast_closestream(), and filestream_destructor().
00294 { 00295 /* Stop a running stream if there is one */ 00296 if (f->owner) { 00297 if (f->fmt->format & AST_FORMAT_AUDIO_MASK) { 00298 f->owner->stream = NULL; 00299 AST_SCHED_DEL(f->owner->sched, f->owner->streamid); 00300 ast_settimeout(f->owner, 0, NULL, NULL); 00301 } else if (f->fmt->format & AST_FORMAT_VIDEO_MASK) { 00302 f->owner->vstream = NULL; 00303 AST_SCHED_DEL(f->owner->sched, f->owner->vstreamid); 00304 } else { 00305 ast_log(AST_LOG_WARNING, "Unable to schedule deletion of filestream with unsupported type %s\n", f->fmt->name); 00306 } 00307 } 00308 }
static void filestream_destructor | ( | void * | arg | ) | [static] |
Definition at line 310 of file file.c.
References ast_closestream(), ast_free, ast_module_unref(), ast_safe_fork(), ast_translator_free_path(), ast_format::close, f, filestream_close(), free, ast_format::module, SENTINEL, and status.
Referenced by get_filestream().
00311 { 00312 struct ast_filestream *f = arg; 00313 int status; 00314 int pid = -1; 00315 00316 /* Stop a running stream if there is one */ 00317 filestream_close(f); 00318 00319 /* destroy the translator on exit */ 00320 if (f->trans) 00321 ast_translator_free_path(f->trans); 00322 00323 if (f->realfilename && f->filename) { 00324 pid = ast_safe_fork(0); 00325 if (!pid) { 00326 execl("/bin/mv", "mv", "-f", f->filename, f->realfilename, SENTINEL); 00327 _exit(1); 00328 } 00329 else if (pid > 0) { 00330 /* Block the parent until the move is complete.*/ 00331 waitpid(pid, &status, 0); 00332 } 00333 } 00334 00335 if (f->filename) 00336 free(f->filename); 00337 if (f->realfilename) 00338 free(f->realfilename); 00339 if (f->fmt->close) { 00340 void (*closefn)(struct ast_filestream *) = f->fmt->close; 00341 closefn(f); 00342 } 00343 if (f->f) 00344 fclose(f->f); 00345 if (f->vfs) 00346 ast_closestream(f->vfs); 00347 if (f->write_buffer) { 00348 ast_free(f->write_buffer); 00349 } 00350 if (f->orig_chan_name) 00351 free((void *) f->orig_chan_name); 00352 ast_module_unref(f->fmt->module); 00353 }
static int fn_wrapper | ( | struct ast_filestream * | s, | |
const char * | comment, | |||
enum wrap_fn | mode | |||
) | [static] |
Definition at line 379 of file file.c.
References ast_log(), ast_module_ref(), f, ast_filestream::fmt, LOG_WARNING, ast_format::module, ast_format::name, ast_format::open, ast_format::rewrite, and WRAP_OPEN.
Referenced by open_wrapper(), and rewrite_wrapper().
00380 { 00381 struct ast_format *f = s->fmt; 00382 int ret = -1; 00383 int (*openfn)(struct ast_filestream *s); 00384 00385 if (mode == WRAP_OPEN && (openfn = f->open) && openfn(s)) 00386 ast_log(LOG_WARNING, "Unable to open format %s\n", f->name); 00387 else if (mode == WRAP_REWRITE && f->rewrite && f->rewrite(s, comment)) 00388 ast_log(LOG_WARNING, "Unable to rewrite format %s\n", f->name); 00389 else { 00390 /* preliminary checks succeed. update usecount */ 00391 ast_module_ref(f->module); 00392 ret = 0; 00393 } 00394 return ret; 00395 }
static struct ast_filestream* get_filestream | ( | struct ast_format * | fmt, | |
FILE * | bfile | |||
) | [static] |
Definition at line 355 of file file.c.
References ast_filestream::_private, ao2_alloc, ast_filestream::buf, ast_format::buf_size, ast_format::desc_size, ast_filestream::f, filestream_destructor(), ast_filestream::fmt, ast_filestream::fr, ast_format::name, and ast_frame::src.
Referenced by ast_filehelper(), ast_readfile(), and ast_writefile().
00356 { 00357 struct ast_filestream *s; 00358 00359 int l = sizeof(*s) + fmt->buf_size + fmt->desc_size; /* total allocation size */ 00360 if ( (s = ao2_alloc(l, filestream_destructor)) == NULL) 00361 return NULL; 00362 s->fmt = fmt; 00363 s->f = bfile; 00364 00365 if (fmt->desc_size) 00366 s->_private = ((char *)(s + 1)) + fmt->buf_size; 00367 if (fmt->buf_size) 00368 s->buf = (char *)(s + 1); 00369 s->fr.src = fmt->name; 00370 return s; 00371 }
static char* handle_cli_core_show_file_formats | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 1449 of file file.c.
References ast_cli_args::argc, ast_cli(), ast_getformatname(), AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_format::exts, f, ast_cli_args::fd, ast_format::format, FORMAT, FORMAT2, ast_format::list, ast_format::name, and ast_cli_entry::usage.
01450 { 01451 #define FORMAT "%-10s %-10s %-20s\n" 01452 #define FORMAT2 "%-10s %-10s %-20s\n" 01453 struct ast_format *f; 01454 int count_fmt = 0; 01455 01456 switch (cmd) { 01457 case CLI_INIT: 01458 e->command = "core show file formats"; 01459 e->usage = 01460 "Usage: core show file formats\n" 01461 " Displays currently registered file formats (if any).\n"; 01462 return NULL; 01463 case CLI_GENERATE: 01464 return NULL; 01465 } 01466 01467 if (a->argc != 4) 01468 return CLI_SHOWUSAGE; 01469 01470 ast_cli(a->fd, FORMAT, "Format", "Name", "Extensions"); 01471 ast_cli(a->fd, FORMAT, "------", "----", "----------"); 01472 01473 AST_RWLIST_RDLOCK(&formats); 01474 AST_RWLIST_TRAVERSE(&formats, f, list) { 01475 ast_cli(a->fd, FORMAT2, ast_getformatname(f->format), f->name, f->exts); 01476 count_fmt++; 01477 } 01478 AST_RWLIST_UNLOCK(&formats); 01479 ast_cli(a->fd, "%d file formats registered.\n", count_fmt); 01480 return CLI_SUCCESS; 01481 #undef FORMAT 01482 #undef FORMAT2 01483 }
static int is_absolute_path | ( | const char * | filename | ) | [static] |
static int open_wrapper | ( | struct ast_filestream * | s | ) | [static] |
Definition at line 402 of file file.c.
References fn_wrapper(), and WRAP_OPEN.
Referenced by ast_filehelper(), and ast_readfile().
00403 { 00404 return fn_wrapper(s, NULL, WRAP_OPEN); 00405 }
static struct ast_frame* read_frame | ( | struct ast_filestream * | s, | |
int * | whennext | |||
) | [static] |
Definition at line 711 of file file.c.
References ast_frfree, ast_frisolate(), ast_filestream::fmt, and ast_format::read.
Referenced by ast_audiohook_read_frame(), ast_readaudio_callback(), ast_readframe(), and ast_readvideo_callback().
00712 { 00713 struct ast_frame *fr, *new_fr; 00714 00715 if (!s || !s->fmt) { 00716 return NULL; 00717 } 00718 00719 if (!(fr = s->fmt->read(s, whennext))) { 00720 return NULL; 00721 } 00722 00723 if (!(new_fr = ast_frisolate(fr))) { 00724 ast_frfree(fr); 00725 return NULL; 00726 } 00727 00728 if (new_fr != fr) { 00729 ast_frfree(fr); 00730 fr = new_fr; 00731 } 00732 00733 return fr; 00734 }
static int rewrite_wrapper | ( | struct ast_filestream * | s, | |
const char * | comment | |||
) | [static] |
Definition at line 397 of file file.c.
References fn_wrapper().
Referenced by ast_writefile().
00398 { 00399 return fn_wrapper(s, comment, WRAP_REWRITE); 00400 }
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 | |||
) | [static] |
the core of all waitstream() functions
Definition at line 1180 of file file.c.
References ast_channel::_softhangup, ast_clear_flag, AST_CONTROL_ANSWER, AST_CONTROL_AOC, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_CONNECTED_LINE, AST_CONTROL_HANGUP, AST_CONTROL_HOLD, AST_CONTROL_REDIRECTING, AST_CONTROL_RINGING, AST_CONTROL_SRCCHANGE, AST_CONTROL_SRCUPDATE, AST_CONTROL_UNHOLD, AST_CONTROL_UPDATE_RTP_PEER, AST_CONTROL_VIDUPDATE, ast_exists_extension(), AST_FLAG_END_DTMF_ONLY, AST_FLAG_MASQ_NOSTREAM, AST_FRAME_CONTROL, AST_FRAME_DTMF_END, AST_FRAME_VOICE, ast_frfree, ast_log(), ast_read(), ast_sched_runq(), ast_sched_wait(), ast_set_flag, ast_stopstream(), ast_strdupa, ast_stream_fastforward(), ast_stream_rewind(), ast_test_flag, ast_waitfor(), ast_waitfor_nandfds(), ast_channel::caller, ast_frame::data, ast_frame::datalen, errno, exten, ast_filestream::f, ast_frame::frametype, ast_party_caller::id, ast_frame_subclass::integer, LOG_WARNING, ast_channel::name, ast_party_id::number, ast_filestream::orig_chan_name, ast_frame::ptr, S_COR, ast_channel::sched, ast_party_number::str, ast_channel::stream, ast_frame::subclass, and ast_party_number::valid.
Referenced by ast_waitstream(), ast_waitstream_exten(), ast_waitstream_fr(), and ast_waitstream_full().
01183 { 01184 const char *orig_chan_name = NULL; 01185 int err = 0; 01186 01187 if (!breakon) 01188 breakon = ""; 01189 if (!forward) 01190 forward = ""; 01191 if (!reverse) 01192 reverse = ""; 01193 01194 /* Switch the channel to end DTMF frame only. waitstream_core doesn't care about the start of DTMF. */ 01195 ast_set_flag(c, AST_FLAG_END_DTMF_ONLY); 01196 01197 if (ast_test_flag(c, AST_FLAG_MASQ_NOSTREAM)) 01198 orig_chan_name = ast_strdupa(c->name); 01199 01200 while (c->stream) { 01201 int res; 01202 int ms; 01203 01204 if (orig_chan_name && strcasecmp(orig_chan_name, c->name)) { 01205 ast_stopstream(c); 01206 err = 1; 01207 break; 01208 } 01209 01210 ms = ast_sched_wait(c->sched); 01211 01212 if (ms < 0 && !c->timingfunc) { 01213 ast_stopstream(c); 01214 break; 01215 } 01216 if (ms < 0) 01217 ms = 1000; 01218 if (cmdfd < 0) { 01219 res = ast_waitfor(c, ms); 01220 if (res < 0) { 01221 ast_log(LOG_WARNING, "Select failed (%s)\n", strerror(errno)); 01222 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 01223 return res; 01224 } 01225 } else { 01226 int outfd; 01227 struct ast_channel *rchan = ast_waitfor_nandfds(&c, 1, &cmdfd, (cmdfd > -1) ? 1 : 0, NULL, &outfd, &ms); 01228 if (!rchan && (outfd < 0) && (ms)) { 01229 /* Continue */ 01230 if (errno == EINTR) 01231 continue; 01232 ast_log(LOG_WARNING, "Wait failed (%s)\n", strerror(errno)); 01233 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 01234 return -1; 01235 } else if (outfd > -1) { /* this requires cmdfd set */ 01236 /* The FD we were watching has something waiting */ 01237 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 01238 return 1; 01239 } 01240 /* if rchan is set, it is 'c' */ 01241 res = rchan ? 1 : 0; /* map into 'res' values */ 01242 } 01243 if (res > 0) { 01244 struct ast_frame *fr = ast_read(c); 01245 if (!fr) { 01246 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 01247 return -1; 01248 } 01249 switch (fr->frametype) { 01250 case AST_FRAME_DTMF_END: 01251 if (context) { 01252 const char exten[2] = { fr->subclass.integer, '\0' }; 01253 if (ast_exists_extension(c, context, exten, 1, 01254 S_COR(c->caller.id.number.valid, c->caller.id.number.str, NULL))) { 01255 res = fr->subclass.integer; 01256 ast_frfree(fr); 01257 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 01258 return res; 01259 } 01260 } else { 01261 res = fr->subclass.integer; 01262 if (strchr(forward, res)) { 01263 int eoftest; 01264 ast_stream_fastforward(c->stream, skip_ms); 01265 eoftest = fgetc(c->stream->f); 01266 if (feof(c->stream->f)) { 01267 ast_stream_rewind(c->stream, skip_ms); 01268 } else { 01269 ungetc(eoftest, c->stream->f); 01270 } 01271 } else if (strchr(reverse, res)) { 01272 ast_stream_rewind(c->stream, skip_ms); 01273 } else if (strchr(breakon, res)) { 01274 ast_frfree(fr); 01275 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 01276 return res; 01277 } 01278 } 01279 break; 01280 case AST_FRAME_CONTROL: 01281 switch (fr->subclass.integer) { 01282 case AST_CONTROL_HANGUP: 01283 case AST_CONTROL_BUSY: 01284 case AST_CONTROL_CONGESTION: 01285 ast_frfree(fr); 01286 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 01287 return -1; 01288 case AST_CONTROL_RINGING: 01289 case AST_CONTROL_ANSWER: 01290 case AST_CONTROL_VIDUPDATE: 01291 case AST_CONTROL_SRCUPDATE: 01292 case AST_CONTROL_SRCCHANGE: 01293 case AST_CONTROL_HOLD: 01294 case AST_CONTROL_UNHOLD: 01295 case AST_CONTROL_CONNECTED_LINE: 01296 case AST_CONTROL_REDIRECTING: 01297 case AST_CONTROL_AOC: 01298 case AST_CONTROL_UPDATE_RTP_PEER: 01299 case -1: 01300 /* Unimportant */ 01301 break; 01302 default: 01303 ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", fr->subclass.integer); 01304 } 01305 break; 01306 case AST_FRAME_VOICE: 01307 /* Write audio if appropriate */ 01308 if (audiofd > -1) { 01309 if (write(audiofd, fr->data.ptr, fr->datalen) < 0) { 01310 ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno)); 01311 } 01312 } 01313 default: 01314 /* Ignore all others */ 01315 break; 01316 } 01317 ast_frfree(fr); 01318 } 01319 ast_sched_runq(c->sched); 01320 } 01321 01322 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 01323 01324 return (err || c->_softhangup) ? -1 : 0; 01325 }
int ast_language_is_prefix = 1 |
struct ast_cli_entry cli_file[] [static] |
Initial value:
{ { .handler = handle_cli_core_show_file_formats , .summary = "Displays file formats" ,__VA_ARGS__ } }
Definition at line 1485 of file file.c.
Referenced by ast_file_init().