#include "asterisk.h"
#include <sys/types.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <fcntl.h>
#include <dirent.h>
#include <sys/stat.h>
#include "asterisk/frame.h"
#include "asterisk/file.h"
#include "asterisk/cli.h"
#include "asterisk/logger.h"
#include "asterisk/channel.h"
#include "asterisk/sched.h"
#include "asterisk/options.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 dependency graph for file.c:
Go to the source code of this file.
Defines | |
#define | FORMAT "%-10s %-10s %-20s\n" |
#define | FORMAT "%-10s %-10s %-20s\n" |
#define | FORMAT2 "%-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) |
int | ast_applystream (struct ast_channel *chan, struct ast_filestream *s) |
int | ast_closestream (struct ast_filestream *f) |
int | ast_file_init (void) |
int | ast_filecopy (const char *filename, const char *filename2, const char *fmt) |
int | ast_filedelete (const char *filename, const char *fmt) |
int | ast_fileexists (const char *filename, const char *fmt, const char *preflang) |
static int | 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) |
int | ast_format_unregister (const char *name) |
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) |
ast_filestream * | ast_openstream_full (struct ast_channel *chan, const char *filename, const char *preflang, int asis) |
ast_filestream * | ast_openvstream (struct ast_channel *chan, const char *filename, const char *preflang) |
int | ast_playstream (struct ast_filestream *s) |
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) |
ast_frame * | ast_readframe (struct ast_filestream *s) |
static enum fsread_res | ast_readvideo_callback (struct ast_filestream *s) |
static | AST_RWLIST_HEAD_STATIC (formats, ast_format) |
int | ast_seekstream (struct ast_filestream *fs, off_t sample_offset, int whence) |
int | ast_stopstream (struct ast_channel *tmp) |
Stops a stream. | |
int | ast_stream_and_wait (struct ast_channel *chan, const char *file, const char *language, const char *digits) |
int | ast_stream_fastforward (struct ast_filestream *fs, off_t ms) |
int | ast_stream_rewind (struct ast_filestream *fs, off_t ms) |
int | ast_streamfile (struct ast_channel *chan, const char *filename, const char *preflang) |
off_t | ast_tellstream (struct ast_filestream *fs) |
int | ast_truncstream (struct ast_filestream *fs) |
int | ast_waitstream (struct ast_channel *c, const char *breakon) |
int | ast_waitstream_exten (struct ast_channel *c, const char *context) |
int | ast_waitstream_fr (struct ast_channel *c, const char *breakon, const char *forward, const char *rewind, int ms) |
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) |
int | ast_writestream (struct ast_filestream *fs, struct ast_frame *f) |
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 int | 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 '_' suffix, or NULL. In the standard asterisk, language goes just before the last component. In an alternative configuration, the language should be a prefix to the actual filename. | |
static int | fileexists_test (const char *filename, const char *fmt, const char *lang, char *buf, int buflen) |
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 int | is_absolute_path (const char *filename) |
static int | open_wrapper (struct ast_filestream *s) |
static int | rewrite_wrapper (struct ast_filestream *s, const char *comment) |
static int | show_file_formats (int fd, int argc, char *argv[]) |
static int | show_file_formats_deprecated (int fd, int argc, char *argv[]) |
static int | waitstream_core (struct ast_channel *c, const char *breakon, const char *forward, const char *rewind, int skip_ms, int audiofd, int cmdfd, const char *context) |
the core of all waitstream() functions | |
Variables | |
int | ast_language_is_prefix = 1 |
ast_cli_entry | cli_file [] |
ast_cli_entry | cli_show_file_formats_deprecated |
char | show_file_formats_usage [] |
Definition in file file.c.
#define FORMAT "%-10s %-10s %-20s\n" |
#define FORMAT "%-10s %-10s %-20s\n" |
#define FORMAT2 "%-10s %-10s %-20s\n" |
#define FORMAT2 "%-10s %-10s %-20s\n" |
Referenced by __iax2_show_peers(), __sip_show_channels(), _sip_show_peers(), dundi_show_mappings(), dundi_show_peers(), dundi_show_precache(), dundi_show_requests(), dundi_show_trans(), iax2_show_channels(), iax2_show_firmware(), iax2_show_registry(), iax2_show_users(), show_file_formats(), show_file_formats_deprecated(), show_image_formats(), show_image_formats_deprecated(), sip_show_inuse(), sip_show_registry(), zap_show_channels(), and zap_show_status().
enum file_action |
Definition at line 337 of file file.c.
00337 { 00338 ACTION_EXISTS = 1, /* return matching format if file exists, 0 otherwise */ 00339 ACTION_DELETE, /* delete file, return 0 on success, -1 on error */ 00340 ACTION_RENAME, /* rename file. return 0 on success, -1 on error */ 00341 ACTION_OPEN, 00342 ACTION_COPY /* copy file. return 0 on success, -1 on error */ 00343 };
enum fsread_res |
Definition at line 652 of file file.c.
00652 { 00653 FSREAD_FAILURE, 00654 FSREAD_SUCCESS_SCHED, 00655 FSREAD_SUCCESS_NOSCHED, 00656 };
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. returns 0 on success, -1 on failure
Definition at line 68 of file file.c.
References ast_calloc, ast_log(), AST_RWLIST_INSERT_HEAD, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_verbose(), ast_format::buf_size, ast_format::exts, f, LOG_WARNING, ast_format::module, ast_format::name, option_verbose, and VERBOSE_PREFIX_2.
00069 { 00070 struct ast_format *tmp; 00071 00072 AST_RWLIST_WRLOCK(&formats); 00073 AST_RWLIST_TRAVERSE(&formats, tmp, list) { 00074 if (!strcasecmp(f->name, tmp->name)) { 00075 AST_RWLIST_UNLOCK(&formats); 00076 ast_log(LOG_WARNING, "Tried to register '%s' format, already registered\n", f->name); 00077 return -1; 00078 } 00079 } 00080 if (!(tmp = ast_calloc(1, sizeof(*tmp)))) { 00081 AST_RWLIST_UNLOCK(&formats); 00082 return -1; 00083 } 00084 *tmp = *f; 00085 tmp->module = mod; 00086 if (tmp->buf_size) { 00087 /* 00088 * Align buf_size properly, rounding up to the machine-specific 00089 * alignment for pointers. 00090 */ 00091 struct _test_align { void *a, *b; } p; 00092 int align = (char *)&p.b - (char *)&p.a; 00093 tmp->buf_size = ((f->buf_size + align - 1)/align)*align; 00094 } 00095 00096 memset(&tmp->list, 0, sizeof(tmp->list)); 00097 00098 AST_RWLIST_INSERT_HEAD(&formats, tmp, list); 00099 AST_RWLIST_UNLOCK(&formats); 00100 if (option_verbose > 1) 00101 ast_verbose( VERBOSE_PREFIX_2 "Registered file format %s, extension(s) %s\n", f->name, f->exts); 00102 00103 return 0; 00104 }
int ast_applystream | ( | struct ast_channel * | chan, | |
struct ast_filestream * | s | |||
) |
chan | channel to work | |
s | ast_filestream to apply Returns 0 for success, -1 on failure |
Definition at line 749 of file file.c.
References s.
Referenced by ast_streamfile(), handle_getoption(), handle_recordfile(), handle_streamfile(), and speech_streamfile().
00750 { 00751 s->owner = chan; 00752 return 0; 00753 }
int ast_closestream | ( | struct ast_filestream * | f | ) |
f | filestream to close Close a playback or recording stream Returns 0 on success, -1 on failure |
Definition at line 792 of file file.c.
References ast_closestream(), AST_FORMAT_MAX_AUDIO, ast_module_unref(), ast_safe_system(), AST_SCHED_DEL, ast_settimeout(), ast_translator_free_path(), ast_format::close, f, ast_format::format, free, and ast_format::module.
Referenced by __ast_play_and_record(), ast_closestream(), ast_filehelper(), ast_hangup(), ast_moh_files_next(), ast_monitor_start(), ast_monitor_stop(), ast_stopstream(), cli_audio_convert(), cli_audio_convert_deprecated(), dictate_exec(), gen_closestream(), handle_recordfile(), local_ast_moh_stop(), mixmonitor_thread(), moh_files_release(), and rpt().
00793 { 00794 char *cmd = NULL; 00795 size_t size = 0; 00796 /* Stop a running stream if there is one */ 00797 if (f->owner) { 00798 if (f->fmt->format < AST_FORMAT_MAX_AUDIO) { 00799 f->owner->stream = NULL; 00800 AST_SCHED_DEL(f->owner->sched, f->owner->streamid); 00801 #ifdef HAVE_ZAPTEL 00802 ast_settimeout(f->owner, 0, NULL, NULL); 00803 #endif 00804 } else { 00805 f->owner->vstream = NULL; 00806 AST_SCHED_DEL(f->owner->sched, f->owner->vstreamid); 00807 } 00808 } 00809 /* destroy the translator on exit */ 00810 if (f->trans) 00811 ast_translator_free_path(f->trans); 00812 00813 if (f->realfilename && f->filename) { 00814 size = strlen(f->filename) + strlen(f->realfilename) + 15; 00815 cmd = alloca(size); 00816 memset(cmd,0,size); 00817 snprintf(cmd,size,"/bin/mv -f %s %s",f->filename,f->realfilename); 00818 ast_safe_system(cmd); 00819 } 00820 00821 if (f->filename) 00822 free(f->filename); 00823 if (f->realfilename) 00824 free(f->realfilename); 00825 if (f->fmt->close) 00826 f->fmt->close(f); 00827 fclose(f->f); 00828 if (f->vfs) 00829 ast_closestream(f->vfs); 00830 if (f->orig_chan_name) 00831 free((void *) f->orig_chan_name); 00832 ast_module_unref(f->fmt->module); 00833 free(f); 00834 return 0; 00835 }
int ast_file_init | ( | void | ) |
Initializes all the various file stuff. Basically just registers the cli stuff Returns 0 all the time
Definition at line 1314 of file file.c.
References ast_cli_register_multiple(), and cli_file.
Referenced by main().
01315 { 01316 ast_cli_register_multiple(cli_file, sizeof(cli_file) / sizeof(struct ast_cli_entry)); 01317 return 0; 01318 }
int ast_filecopy | ( | const char * | oldname, | |
const char * | newname, | |||
const char * | fmt | |||
) |
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 865 of file file.c.
References ast_filehelper().
Referenced by copy_plain_file(), and vm_forwardoptions().
00866 { 00867 return ast_filehelper(filename, filename2, fmt, ACTION_COPY); 00868 }
int ast_filedelete | ( | const char * | filename, | |
const char * | fmt | |||
) |
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 855 of file file.c.
References ACTION_DELETE, and ast_filehelper().
Referenced by __ast_play_and_record(), ast_monitor_start(), ast_monitor_stop(), cli_audio_convert(), cli_audio_convert_deprecated(), leave_voicemail(), play_mailbox_owner(), play_record_review(), vm_delete(), and vm_forwardoptions().
00856 { 00857 return ast_filehelper(filename, NULL, fmt, ACTION_DELETE); 00858 }
int ast_fileexists | ( | const char * | filename, | |
const char * | fmt, | |||
const char * | preflang | |||
) |
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. Returns -1 if file does not exist, non-zero positive otherwise. |
Definition at line 841 of file file.c.
References ast_filestream::buf, and fileexists_core().
Referenced by app_exec(), ast_moh_files_next(), ast_monitor_start(), ast_monitor_stop(), common_exec(), conf_run(), last_message_index(), leave_voicemail(), play_greeting(), play_mailbox_owner(), play_message_callerid(), record_exec(), retrydial_exec(), rxfax_exec(), say_character_str_full(), say_digit_str_full(), say_phonetic_str_full(), vm_intro(), vm_newuser(), vm_options(), and vm_tempgreeting().
00842 { 00843 char *buf; 00844 int buflen; 00845 00846 if (preflang == NULL) 00847 preflang = ""; 00848 buflen = strlen(preflang) + strlen(filename) + 4; /* room for everything */ 00849 buf = alloca(buflen); 00850 if (buf == NULL) 00851 return 0; 00852 return fileexists_core(filename, fmt, preflang, buf, buflen); 00853 }
static int 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 354 of file file.c.
References ACTION_DELETE, ACTION_EXISTS, ACTION_OPEN, ACTION_RENAME, ast_closestream(), AST_FORMAT_MAX_AUDIO, 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_format::format, free, get_filestream(), LOG_WARNING, open_wrapper(), s, ast_channel::stream, strsep(), ast_channel::vstream, and ast_channel::writeformat.
Referenced by ast_filecopy(), ast_filedelete(), ast_filerename(), ast_openstream_full(), ast_openvstream(), fileexists_core(), and fileexists_test().
00355 { 00356 struct ast_format *f; 00357 int res = (action == ACTION_EXISTS) ? 0 : -1; 00358 00359 AST_RWLIST_RDLOCK(&formats); 00360 /* Check for a specific format */ 00361 AST_RWLIST_TRAVERSE(&formats, f, list) { 00362 char *stringp, *ext = NULL; 00363 00364 if (fmt && !exts_compare(f->exts, fmt)) 00365 continue; 00366 00367 /* Look for a file matching the supported extensions. 00368 * The file must exist, and for OPEN, must match 00369 * one of the formats supported by the channel. 00370 */ 00371 stringp = ast_strdupa(f->exts); /* this is in the stack so does not need to be freed */ 00372 while ( (ext = strsep(&stringp, "|")) ) { 00373 struct stat st; 00374 char *fn = build_filename(filename, ext); 00375 00376 if (fn == NULL) 00377 continue; 00378 00379 if ( stat(fn, &st) ) { /* file not existent */ 00380 free(fn); 00381 continue; 00382 } 00383 /* for 'OPEN' we need to be sure that the format matches 00384 * what the channel can process 00385 */ 00386 if (action == ACTION_OPEN) { 00387 struct ast_channel *chan = (struct ast_channel *)arg2; 00388 FILE *bfile; 00389 struct ast_filestream *s; 00390 00391 if ( !(chan->writeformat & f->format) && 00392 !(f->format >= AST_FORMAT_MAX_AUDIO && fmt)) { 00393 free(fn); 00394 continue; /* not a supported format */ 00395 } 00396 if ( (bfile = fopen(fn, "r")) == NULL) { 00397 free(fn); 00398 continue; /* cannot open file */ 00399 } 00400 s = get_filestream(f, bfile); 00401 if (!s) { 00402 fclose(bfile); 00403 free(fn); /* cannot allocate descriptor */ 00404 continue; 00405 } 00406 if (open_wrapper(s)) { 00407 fclose(bfile); 00408 free(fn); 00409 free(s); 00410 continue; /* cannot run open on file */ 00411 } 00412 /* ok this is good for OPEN */ 00413 res = 1; /* found */ 00414 s->lasttimeout = -1; 00415 s->fmt = f; 00416 s->trans = NULL; 00417 s->filename = NULL; 00418 if (s->fmt->format < AST_FORMAT_MAX_AUDIO) { 00419 if (chan->stream) 00420 ast_closestream(chan->stream); 00421 chan->stream = s; 00422 } else { 00423 if (chan->vstream) 00424 ast_closestream(chan->vstream); 00425 chan->vstream = s; 00426 } 00427 free(fn); 00428 break; 00429 } 00430 switch (action) { 00431 case ACTION_OPEN: 00432 break; /* will never get here */ 00433 00434 case ACTION_EXISTS: /* return the matching format */ 00435 res |= f->format; 00436 break; 00437 00438 case ACTION_DELETE: 00439 if ( (res = unlink(fn)) ) 00440 ast_log(LOG_WARNING, "unlink(%s) failed: %s\n", fn, strerror(errno)); 00441 break; 00442 00443 case ACTION_RENAME: 00444 case ACTION_COPY: { 00445 char *nfn = build_filename((const char *)arg2, ext); 00446 if (!nfn) 00447 ast_log(LOG_WARNING, "Out of memory\n"); 00448 else { 00449 res = action == ACTION_COPY ? copy(fn, nfn) : rename(fn, nfn); 00450 if (res) 00451 ast_log(LOG_WARNING, "%s(%s,%s) failed: %s\n", 00452 action == ACTION_COPY ? "copy" : "rename", 00453 fn, nfn, strerror(errno)); 00454 free(nfn); 00455 } 00456 } 00457 break; 00458 00459 default: 00460 ast_log(LOG_WARNING, "Unknown helper %d\n", action); 00461 } 00462 free(fn); 00463 } 00464 } 00465 AST_RWLIST_UNLOCK(&formats); 00466 return res; 00467 }
int ast_filerename | ( | const char * | oldname, | |
const char * | newname, | |||
const char * | fmt | |||
) |
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 Returns -1 on failure |
Definition at line 860 of file file.c.
References ACTION_RENAME, and ast_filehelper().
Referenced by __ast_play_and_record(), ast_monitor_stop(), leave_voicemail(), play_record_review(), and rename_file().
00861 { 00862 return ast_filehelper(filename, filename2, fmt, ACTION_RENAME); 00863 }
int ast_format_unregister | ( | const char * | name | ) |
name | the name of the format you wish to unregister Unregisters a format based on the name of the format. Returns 0 on success, -1 on failure to unregister |
Definition at line 106 of file file.c.
References ast_log(), AST_RWLIST_REMOVE_CURRENT, AST_RWLIST_TRAVERSE_SAFE_BEGIN, AST_RWLIST_TRAVERSE_SAFE_END, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_verbose(), free, LOG_WARNING, ast_format::name, option_verbose, and VERBOSE_PREFIX_2.
Referenced by unload_module().
00107 { 00108 struct ast_format *tmp; 00109 int res = -1; 00110 00111 AST_RWLIST_WRLOCK(&formats); 00112 AST_RWLIST_TRAVERSE_SAFE_BEGIN(&formats, tmp, list) { 00113 if (!strcasecmp(name, tmp->name)) { 00114 AST_RWLIST_REMOVE_CURRENT(&formats, list); 00115 free(tmp); 00116 res = 0; 00117 } 00118 } 00119 AST_RWLIST_TRAVERSE_SAFE_END 00120 AST_RWLIST_UNLOCK(&formats); 00121 00122 if (!res) { 00123 if (option_verbose > 1) 00124 ast_verbose( VERBOSE_PREFIX_2 "Unregistered format %s\n", name); 00125 } else 00126 ast_log(LOG_WARNING, "Tried to unregister format %s, already unregistered\n", name); 00127 00128 return res; 00129 }
static int ast_fsread_audio | ( | const void * | data | ) | [static] |
Definition at line 697 of file file.c.
References ast_readaudio_callback(), and FSREAD_SUCCESS_SCHED.
Referenced by ast_readaudio_callback().
00698 { 00699 struct ast_filestream *fs = (struct ast_filestream *)data; 00700 enum fsread_res res; 00701 00702 res = ast_readaudio_callback(fs); 00703 00704 if (res == FSREAD_SUCCESS_SCHED) 00705 return 1; 00706 00707 return 0; 00708 }
static int ast_fsread_video | ( | const void * | data | ) | [static] |
Definition at line 736 of file file.c.
References ast_readvideo_callback(), and FSREAD_SUCCESS_SCHED.
Referenced by ast_readvideo_callback().
00737 { 00738 struct ast_filestream *fs = (struct ast_filestream *)data; 00739 enum fsread_res res; 00740 00741 res = ast_readvideo_callback(fs); 00742 00743 if (res == FSREAD_SUCCESS_SCHED) 00744 return 1; 00745 00746 return 0; 00747 }
struct ast_filestream* ast_openstream | ( | struct ast_channel * | chan, | |
const char * | filename, | |||
const char * | preflang | |||
) |
chan | channel to work with | |
filename | to use | |
preflang | prefered language to use Returns a ast_filestream pointer if it opens the file, NULL on error |
Definition at line 567 of file file.c.
References ast_openstream_full().
Referenced by ast_streamfile(), dictate_exec(), handle_getoption(), handle_streamfile(), and speech_streamfile().
00568 { 00569 return ast_openstream_full(chan, filename, preflang, 0); 00570 }
struct ast_filestream* ast_openstream_full | ( | struct ast_channel * | chan, | |
const char * | filename, | |||
const char * | preflang, | |||
int | asis | |||
) |
chan | channel to work with | |
filename | to use | |
preflang | prefered language to use | |
asis | if set, don't clear generators Returns a ast_filestream pointer if it opens the file, NULL on error |
Definition at line 572 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_moh_files_next(), ast_openstream(), and gen_nextfile().
00573 { 00574 /* 00575 * Use fileexists_core() to find a file in a compatible 00576 * language and format, set up a suitable translator, 00577 * and open the stream. 00578 */ 00579 int fmts, res, buflen; 00580 char *buf; 00581 00582 if (!asis) { 00583 /* do this first, otherwise we detect the wrong writeformat */ 00584 ast_stopstream(chan); 00585 if (chan->generator) 00586 ast_deactivate_generator(chan); 00587 } 00588 if (preflang == NULL) 00589 preflang = ""; 00590 buflen = strlen(preflang) + strlen(filename) + 4; 00591 buf = alloca(buflen); 00592 if (buf == NULL) 00593 return NULL; 00594 fmts = fileexists_core(filename, NULL, preflang, buf, buflen); 00595 if (fmts > 0) 00596 fmts &= AST_FORMAT_AUDIO_MASK; 00597 if (fmts < 1) { 00598 ast_log(LOG_WARNING, "File %s does not exist in any format\n", filename); 00599 return NULL; 00600 } 00601 chan->oldwriteformat = chan->writeformat; 00602 /* Set the channel to a format we can work with */ 00603 res = ast_set_write_format(chan, fmts); 00604 res = ast_filehelper(buf, chan, NULL, ACTION_OPEN); 00605 if (res >= 0) 00606 return chan->stream; 00607 return NULL; 00608 }
struct ast_filestream* ast_openvstream | ( | struct ast_channel * | chan, | |
const char * | filename, | |||
const char * | preflang | |||
) |
chan | channel to work with | |
filename | to use | |
preflang | prefered language to use Returns a ast_filestream pointer if it opens the file, NULL on error |
Definition at line 610 of file file.c.
References ACTION_OPEN, ast_filehelper(), AST_FORMAT_MAX_AUDIO, AST_FORMAT_MAX_VIDEO, ast_getformatname(), ast_log(), ast_filestream::buf, fileexists_core(), fmt, format, LOG_WARNING, ast_channel::nativeformats, and ast_channel::vstream.
Referenced by ast_streamfile(), handle_getoption(), and handle_streamfile().
00611 { 00612 /* As above, but for video. But here we don't have translators 00613 * so we must enforce a format. 00614 */ 00615 unsigned int format; 00616 char *buf; 00617 int buflen; 00618 00619 if (preflang == NULL) 00620 preflang = ""; 00621 buflen = strlen(preflang) + strlen(filename) + 4; 00622 buf = alloca(buflen); 00623 if (buf == NULL) 00624 return NULL; 00625 00626 for (format = AST_FORMAT_MAX_AUDIO << 1; format <= AST_FORMAT_MAX_VIDEO; format = format << 1) { 00627 int fd; 00628 const char *fmt; 00629 00630 if (!(chan->nativeformats & format)) 00631 continue; 00632 fmt = ast_getformatname(format); 00633 if ( fileexists_core(filename, fmt, preflang, buf, buflen) < 1) /* no valid format */ 00634 continue; 00635 fd = ast_filehelper(buf, chan, fmt, ACTION_OPEN); 00636 if (fd >= 0) 00637 return chan->vstream; 00638 ast_log(LOG_WARNING, "File %s has video but couldn't be opened\n", filename); 00639 } 00640 return NULL; 00641 }
int ast_playstream | ( | struct ast_filestream * | s | ) |
s | filestream to play Returns 0 for success, -1 on failure |
Definition at line 755 of file file.c.
References AST_FORMAT_MAX_AUDIO, ast_readaudio_callback(), ast_readvideo_callback(), FSREAD_FAILURE, and s.
Referenced by ast_streamfile(), handle_getoption(), handle_streamfile(), and speech_streamfile().
00756 { 00757 enum fsread_res res; 00758 00759 if (s->fmt->format < AST_FORMAT_MAX_AUDIO) 00760 res = ast_readaudio_callback(s); 00761 else 00762 res = ast_readvideo_callback(s); 00763 00764 return (res == FSREAD_FAILURE) ? -1 : 0; 00765 }
static enum fsread_res ast_readaudio_callback | ( | struct ast_filestream * | s | ) | [static] |
Definition at line 660 of file file.c.
References ast_fsread_audio(), ast_log(), ast_sched_add(), ast_settimeout(), ast_write(), FSREAD_FAILURE, FSREAD_SUCCESS_NOSCHED, FSREAD_SUCCESS_SCHED, LOG_WARNING, and s.
Referenced by ast_fsread_audio(), and ast_playstream().
00661 { 00662 int whennext = 0; 00663 00664 while (!whennext) { 00665 struct ast_frame *fr; 00666 00667 if (s->orig_chan_name && strcasecmp(s->owner->name, s->orig_chan_name)) 00668 goto return_failure; 00669 00670 fr = s->fmt->read(s, &whennext); 00671 if (!fr /* stream complete */ || ast_write(s->owner, fr) /* error writing */) { 00672 if (fr) 00673 ast_log(LOG_WARNING, "Failed to write frame\n"); 00674 goto return_failure; 00675 } 00676 } 00677 if (whennext != s->lasttimeout) { 00678 #ifdef HAVE_ZAPTEL 00679 if (s->owner->timingfd > -1) 00680 ast_settimeout(s->owner, whennext, ast_fsread_audio, s); 00681 else 00682 #endif 00683 s->owner->streamid = ast_sched_add(s->owner->sched, whennext/8, ast_fsread_audio, s); 00684 s->lasttimeout = whennext; 00685 return FSREAD_SUCCESS_NOSCHED; 00686 } 00687 return FSREAD_SUCCESS_SCHED; 00688 00689 return_failure: 00690 s->owner->streamid = -1; 00691 #ifdef HAVE_ZAPTEL 00692 ast_settimeout(s->owner, 0, NULL, NULL); 00693 #endif 00694 return FSREAD_FAILURE; 00695 }
struct ast_filestream* ast_readfile | ( | const char * | filename, | |
const char * | type, | |||
const char * | comment, | |||
int | flags, | |||
int | check, | |||
mode_t | mode | |||
) |
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. Returns a struct ast_filestream on success, NULL on failure |
Definition at line 901 of file file.c.
References ast_free, ast_log(), AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, build_filename(), errno, ast_format::exts, exts_compare(), f, ast_filestream::filename, ast_filestream::flags, ast_filestream::fmt, free, get_filestream(), LOG_WARNING, ast_filestream::mode, open_wrapper(), strdup, ast_filestream::trans, and ast_filestream::vfs.
Referenced by __ast_play_and_record(), cli_audio_convert(), and cli_audio_convert_deprecated().
00902 { 00903 FILE *bfile; 00904 struct ast_format *f; 00905 struct ast_filestream *fs = NULL; 00906 char *fn; 00907 00908 AST_RWLIST_RDLOCK(&formats); 00909 00910 AST_RWLIST_TRAVERSE(&formats, f, list) { 00911 fs = NULL; 00912 if (!exts_compare(f->exts, type)) 00913 continue; 00914 00915 fn = build_filename(filename, type); 00916 errno = 0; 00917 bfile = fopen(fn, "r"); 00918 if (!bfile || (fs = get_filestream(f, bfile)) == NULL || 00919 open_wrapper(fs) ) { 00920 ast_log(LOG_WARNING, "Unable to open %s\n", fn); 00921 if (fs) 00922 ast_free(fs); 00923 if (bfile) 00924 fclose(bfile); 00925 free(fn); 00926 continue; 00927 } 00928 /* found it */ 00929 fs->trans = NULL; 00930 fs->fmt = f; 00931 fs->flags = flags; 00932 fs->mode = mode; 00933 fs->filename = strdup(filename); 00934 fs->vfs = NULL; 00935 break; 00936 } 00937 00938 AST_RWLIST_UNLOCK(&formats); 00939 if (!fs) 00940 ast_log(LOG_WARNING, "No such format '%s'\n", type); 00941 00942 return fs; 00943 }
struct ast_frame* ast_readframe | ( | struct ast_filestream * | s | ) |
s | ast_filestream to act on Returns a frame or NULL if read failed |
Definition at line 643 of file file.c.
Referenced by __ast_play_and_record(), cli_audio_convert(), cli_audio_convert_deprecated(), dictate_exec(), gen_readframe(), and moh_files_readframe().
00644 { 00645 struct ast_frame *f = NULL; 00646 int whennext = 0; 00647 if (s && s->fmt) 00648 f = s->fmt->read(s, &whennext); 00649 return f; 00650 }
static enum fsread_res ast_readvideo_callback | ( | struct ast_filestream * | s | ) | [static] |
Definition at line 712 of file file.c.
References ast_fsread_video(), ast_log(), ast_sched_add(), ast_write(), FSREAD_FAILURE, FSREAD_SUCCESS_NOSCHED, FSREAD_SUCCESS_SCHED, LOG_WARNING, and s.
Referenced by ast_fsread_video(), and ast_playstream().
00713 { 00714 int whennext = 0; 00715 00716 while (!whennext) { 00717 struct ast_frame *fr = s->fmt->read(s, &whennext); 00718 if (!fr || ast_write(s->owner, fr)) { /* no stream or error, as above */ 00719 if (fr) 00720 ast_log(LOG_WARNING, "Failed to write frame\n"); 00721 s->owner->vstreamid = -1; 00722 return FSREAD_FAILURE; 00723 } 00724 } 00725 00726 if (whennext != s->lasttimeout) { 00727 s->owner->vstreamid = ast_sched_add(s->owner->sched, whennext / 8, 00728 ast_fsread_video, s); 00729 s->lasttimeout = whennext; 00730 return FSREAD_SUCCESS_NOSCHED; 00731 } 00732 00733 return FSREAD_SUCCESS_SCHED; 00734 }
static AST_RWLIST_HEAD_STATIC | ( | formats | , | |
ast_format | ||||
) | [static] |
int ast_seekstream | ( | struct ast_filestream * | fs, | |
off_t | sample_offset, | |||
int | whence | |||
) |
fs | ast_filestream to perform seek on | |
sample_offset | numbers of samples to seek | |
whence | SEEK_SET, SEEK_CUR, SEEK_END Returns 0 for success, or -1 for error |
Definition at line 767 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_write(), dictate_exec(), handle_getoption(), handle_recordfile(), and handle_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 131 of file file.c.
References ast_channel_lock, ast_channel_unlock, ast_closestream(), 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_app_getdata(), 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_number_full_cz(), 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_ge(), ast_say_number_full_gr(), ast_say_number_full_he(), ast_say_number_full_it(), 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_tw(), background_detect_exec(), builtin_blindtransfer(), conf_exec(), conf_run(), directory_exec(), handle_getoption(), handle_streamfile(), ices_exec(), ivr_dispatch(), leave_voicemail(), mp3_exec(), NBScat_exec(), nv_background_detect_exec(), parkandannounce_exec(), pbx_builtin_background(), pl_odtworz_plik(), play_file(), play_mailbox_owner(), playback_exec(), queue_exec(), read_exec(), recordthread(), rpt_tele_thread(), s_streamwait3(), say_character_str_full(), say_digit_str_full(), say_phonetic_str_full(), saycharstr(), sayfile(), saynum(), send_morse(), send_tone_telemetry(), send_waveform_to_channel(), speech_background(), vm_authenticate(), vm_execmain(), wait_for_winner(), waitstream_core(), and zapateller_exec().
00132 { 00133 ast_channel_lock(tmp); 00134 00135 /* Stop a running stream if there is one */ 00136 if (tmp->stream) { 00137 ast_closestream(tmp->stream); 00138 tmp->stream = NULL; 00139 if (tmp->oldwriteformat && ast_set_write_format(tmp, tmp->oldwriteformat)) 00140 ast_log(LOG_WARNING, "Unable to restore format back to %d\n", tmp->oldwriteformat); 00141 } 00142 /* Stop the video stream too */ 00143 if (tmp->vstream != NULL) { 00144 ast_closestream(tmp->vstream); 00145 tmp->vstream = NULL; 00146 } 00147 00148 ast_channel_unlock(tmp); 00149 00150 return 0; 00151 }
int ast_stream_and_wait | ( | struct ast_channel * | chan, | |
const char * | file, | |||
const char * | language, | |||
const char * | digits | |||
) |
Definition at line 1237 of file file.c.
References ast_streamfile(), ast_strlen_zero(), and ast_waitstream().
Referenced by __ast_play_and_record(), app_exec(), ast_record_review(), bridge_playfile(), builtin_atxfer(), builtin_automonitor(), builtin_blindtransfer(), directory_exec(), invent_message(), ivr_dispatch(), leave_voicemail(), park_exec(), play_mailbox_owner(), play_message_callerid(), play_record_review(), and wait_file2().
01239 { 01240 int res = 0; 01241 if (!ast_strlen_zero(file)) { 01242 res = ast_streamfile(chan, file, language); 01243 if (!res) 01244 res = ast_waitstream(chan, digits); 01245 } 01246 return res; 01247 }
int ast_stream_fastforward | ( | struct ast_filestream * | fs, | |
off_t | ms | |||
) |
fs | filestream to act on | |
ms | milliseconds to move Returns 0 for success, or -1 for error |
Definition at line 782 of file file.c.
References ast_seekstream(), and DEFAULT_SAMPLES_PER_MS.
Referenced by waitstream_core().
00783 { 00784 return ast_seekstream(fs, ms * DEFAULT_SAMPLES_PER_MS, SEEK_CUR); 00785 }
int ast_stream_rewind | ( | struct ast_filestream * | fs, | |
off_t | ms | |||
) |
fs | filestream to act on | |
ms | milliseconds to move Returns 0 for success, or -1 for error |
Definition at line 787 of file file.c.
References ast_seekstream(), and DEFAULT_SAMPLES_PER_MS.
Referenced by __ast_play_and_record(), handle_recordfile(), and waitstream_core().
00788 { 00789 return ast_seekstream(fs, -ms * DEFAULT_SAMPLES_PER_MS, SEEK_CUR); 00790 }
int ast_streamfile | ( | struct ast_channel * | c, | |
const char * | filename, | |||
const char * | preflang | |||
) |
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. Returns 0 on success, or -1 on failure. |
Definition at line 870 of file file.c.
References ast_applystream(), AST_FLAG_MASQ_NOSTREAM, ast_getformatname(), ast_getformatname_multiple(), ast_log(), ast_openstream(), ast_openvstream(), ast_playstream(), ast_strdup, ast_test_flag, ast_verbose(), errno, fmt, ast_filestream::fmt, ast_format::format, LOG_DEBUG, LOG_WARNING, ast_channel::nativeformats, option_verbose, ast_filestream::orig_chan_name, VERBOSE_PREFIX_3, and ast_filestream::vfs.
Referenced by __login_exec(), action_bridge(), agent_call(), 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_ge(), ast_say_date_gr(), ast_say_date_nl(), 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_ge(), ast_say_datetime_gr(), ast_say_datetime_nl(), ast_say_datetime_pt(), ast_say_datetime_tw(), ast_say_enumeration_full_da(), ast_say_enumeration_full_de(), ast_say_enumeration_full_en(), ast_say_number_full_cz(), 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_ge(), ast_say_number_full_gr(), ast_say_number_full_he(), ast_say_number_full_it(), 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_tw(), ast_say_time_de(), ast_say_time_en(), ast_say_time_fr(), ast_say_time_ge(), ast_say_time_gr(), ast_say_time_nl(), ast_say_time_tw(), ast_stream_and_wait(), background_detect_exec(), bridge_exec(), check_availability(), check_beep(), common_exec(), conf_exec(), conf_run(), do_directory(), forward_message(), gr_say_number_female(), handle_recordfile(), leave_voicemail(), nv_background_detect_exec(), page_exec(), park_exec(), parkandannounce_exec(), pbx_builtin_background(), pl_odtworz_plik(), play_and_wait(), play_file(), play_greeting(), playback_exec(), privacy_exec(), retrydial_exec(), rpt_tele_thread(), s_streamwait3(), say_character_str_full(), say_digit_str_full(), say_phonetic_str_full(), sayfile(), ss_thread(), vm_authenticate(), wait_file(), and wait_for_winner().
00871 { 00872 struct ast_filestream *fs; 00873 struct ast_filestream *vfs=NULL; 00874 char fmt[256]; 00875 00876 fs = ast_openstream(chan, filename, preflang); 00877 if (fs) 00878 vfs = ast_openvstream(chan, filename, preflang); 00879 if (vfs) 00880 ast_log(LOG_DEBUG, "Ooh, found a video stream, too, format %s\n", ast_getformatname(vfs->fmt->format)); 00881 if (fs){ 00882 int res; 00883 if (ast_test_flag(chan, AST_FLAG_MASQ_NOSTREAM)) 00884 fs->orig_chan_name = ast_strdup(chan->name); 00885 if (ast_applystream(chan, fs)) 00886 return -1; 00887 if (vfs && ast_applystream(chan, vfs)) 00888 return -1; 00889 res = ast_playstream(fs); 00890 if (!res && vfs) 00891 res = ast_playstream(vfs); 00892 if (option_verbose > 2) 00893 ast_verbose(VERBOSE_PREFIX_3 "<%s> Playing '%s' (language '%s')\n", chan->name, filename, preflang ? preflang : "default"); 00894 00895 return res; 00896 } 00897 ast_log(LOG_WARNING, "Unable to open %s (format %s): %s\n", filename, ast_getformatname_multiple(fmt, sizeof(fmt), chan->nativeformats), strerror(errno)); 00898 return -1; 00899 }
off_t ast_tellstream | ( | struct ast_filestream * | fs | ) |
fs | fs to act on Returns a long as a sample offset into stream |
Definition at line 777 of file file.c.
References ast_filestream::fmt, and ast_format::tell.
Referenced by __ast_play_and_record(), ast_control_streamfile(), handle_getoption(), handle_recordfile(), and handle_streamfile().
int ast_truncstream | ( | struct ast_filestream * | fs | ) |
fs | filestream to act on Returns 0 for success, or -1 for error |
Definition at line 772 of file file.c.
References ast_filestream::fmt, and ast_format::trunc.
Referenced by __ast_play_and_record(), and handle_recordfile().
int ast_waitstream | ( | struct ast_channel * | c, | |
const char * | breakon | |||
) |
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, Returns 0 if the stream finishes, the character if it was interrupted, and -1 on error |
Definition at line 1210 of file file.c.
References waitstream_core().
Referenced by __login_exec(), action_bridge(), agent_call(), app_exec(), ast_app_getdata(), ast_play_and_wait(), ast_say_date_da(), ast_say_date_de(), ast_say_date_en(), ast_say_date_fr(), ast_say_date_ge(), ast_say_date_gr(), ast_say_date_nl(), 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_ge(), ast_say_datetime_gr(), ast_say_datetime_nl(), ast_say_datetime_pt(), ast_say_datetime_tw(), ast_say_enumeration_full_da(), ast_say_enumeration_full_de(), ast_say_enumeration_full_en(), ast_say_number_full_cz(), 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_ge(), ast_say_number_full_gr(), ast_say_number_full_he(), ast_say_number_full_it(), 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_tw(), ast_say_time_de(), ast_say_time_en(), ast_say_time_ge(), ast_say_time_gr(), ast_say_time_nl(), ast_say_time_tw(), ast_stream_and_wait(), bridge_exec(), check_availability(), check_beep(), common_exec(), conf_exec(), conf_run(), directory_exec(), gr_say_number_female(), handle_recordfile(), leave_voicemail(), page_exec(), park_exec(), parkandannounce_exec(), pbx_builtin_background(), pl_odtworz_plik(), play_and_wait(), play_file(), play_greeting(), 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(), send_morse(), send_tone_telemetry(), ss_thread(), vm_authenticate(), and wait_file().
01211 { 01212 return waitstream_core(c, breakon, NULL, NULL, 0, -1, -1, NULL); 01213 }
int ast_waitstream_exten | ( | struct ast_channel * | c, | |
const char * | context | |||
) |
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, Returns 0 if the stream finishes, the character if it was interrupted, and -1 on error |
Definition at line 1221 of file file.c.
References ast_channel::context, and waitstream_core().
Referenced by pbx_builtin_background().
01222 { 01223 /* Waitstream, with return in the case of a valid 1 digit extension */ 01224 /* in the current or specified context being pressed */ 01225 01226 if (!context) 01227 context = c->context; 01228 return waitstream_core(c, NULL, NULL, NULL, 0, 01229 -1, -1, context); 01230 }
int ast_waitstream_fr | ( | struct ast_channel * | c, | |
const char * | breakon, | |||
const char * | forward, | |||
const char * | rewind, | |||
int | ms | |||
) |
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, Returns 0 if the stream finishes, the character if it was interrupted, and -1 on error |
Definition at line 1204 of file file.c.
References waitstream_core().
Referenced by ast_control_streamfile().
01205 { 01206 return waitstream_core(c, breakon, forward, rewind, ms, 01207 -1 /* no audiofd */, -1 /* no cmdfd */, NULL /* no context */); 01208 }
int ast_waitstream_full | ( | struct ast_channel * | c, | |
const char * | breakon, | |||
int | audiofd, | |||
int | cmdfd | |||
) |
Definition at line 1215 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_number_full_cz(), 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_ge(), ast_say_number_full_gr(), ast_say_number_full_he(), ast_say_number_full_it(), 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_tw(), handle_getoption(), handle_streamfile(), pl_odtworz_plik(), s_streamwait3(), say_character_str_full(), say_digit_str_full(), and say_phonetic_str_full().
01216 { 01217 return waitstream_core(c, breakon, NULL, NULL, 0, 01218 audiofd, cmdfd, NULL /* no context */); 01219 }
struct ast_filestream* ast_writefile | ( | const char * | filename, | |
const char * | type, | |||
const char * | comment, | |||
int | flags, | |||
int | check, | |||
mode_t | mode | |||
) |
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. Returns a struct ast_filestream on success, NULL on failure |
Definition at line 945 of file file.c.
References ast_free, ast_log(), ast_opt_cache_record_files, AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_strdupa, ast_filestream::buf, build_filename(), errno, ast_format::exts, exts_compare(), f, ast_filestream::filename, ast_filestream::flags, ast_filestream::fmt, free, get_filestream(), LOG_WARNING, ast_filestream::mode, ast_filestream::realfilename, record_cache_dir, rewrite_wrapper(), ast_format::seek, strdup, ast_filestream::trans, and ast_filestream::vfs.
Referenced by __ast_play_and_record(), ast_monitor_start(), ast_writestream(), cli_audio_convert(), cli_audio_convert_deprecated(), dictate_exec(), handle_recordfile(), mixmonitor_thread(), recordthread(), and rpt().
00946 { 00947 int fd, myflags = 0; 00948 /* compiler claims this variable can be used before initialization... */ 00949 FILE *bfile = NULL; 00950 struct ast_format *f; 00951 struct ast_filestream *fs = NULL; 00952 char *buf = NULL; 00953 size_t size = 0; 00954 int format_found = 0; 00955 00956 AST_RWLIST_RDLOCK(&formats); 00957 00958 /* set the O_TRUNC flag if and only if there is no O_APPEND specified */ 00959 /* We really can't use O_APPEND as it will break WAV header updates */ 00960 if (flags & O_APPEND) { 00961 flags &= ~O_APPEND; 00962 } else { 00963 myflags = O_TRUNC; 00964 } 00965 00966 myflags |= O_WRONLY | O_CREAT; 00967 00968 /* XXX need to fix this - we should just do the fopen, 00969 * not open followed by fdopen() 00970 */ 00971 AST_RWLIST_TRAVERSE(&formats, f, list) { 00972 char *fn, *orig_fn = NULL; 00973 if (fs) 00974 break; 00975 00976 if (!exts_compare(f->exts, type)) 00977 continue; 00978 else 00979 format_found = 1; 00980 00981 fn = build_filename(filename, type); 00982 fd = open(fn, flags | myflags, mode); 00983 if (fd > -1) { 00984 /* fdopen() the resulting file stream */ 00985 bfile = fdopen(fd, ((flags | myflags) & O_RDWR) ? "w+" : "w"); 00986 if (!bfile) { 00987 ast_log(LOG_WARNING, "Whoa, fdopen failed: %s!\n", strerror(errno)); 00988 close(fd); 00989 fd = -1; 00990 } 00991 } 00992 00993 if (ast_opt_cache_record_files && (fd > -1)) { 00994 char *c; 00995 00996 fclose(bfile); /* this also closes fd */ 00997 /* 00998 We touch orig_fn just as a place-holder so other things (like vmail) see the file is there. 00999 What we are really doing is writing to record_cache_dir until we are done then we will mv the file into place. 01000 */ 01001 orig_fn = ast_strdupa(fn); 01002 for (c = fn; *c; c++) 01003 if (*c == '/') 01004 *c = '_'; 01005 01006 size = strlen(fn) + strlen(record_cache_dir) + 2; 01007 buf = alloca(size); 01008 strcpy(buf, record_cache_dir); 01009 strcat(buf, "/"); 01010 strcat(buf, fn); 01011 free(fn); 01012 fn = buf; 01013 fd = open(fn, flags | myflags, mode); 01014 if (fd > -1) { 01015 /* fdopen() the resulting file stream */ 01016 bfile = fdopen(fd, ((flags | myflags) & O_RDWR) ? "w+" : "w"); 01017 if (!bfile) { 01018 ast_log(LOG_WARNING, "Whoa, fdopen failed: %s!\n", strerror(errno)); 01019 close(fd); 01020 fd = -1; 01021 } 01022 } 01023 } 01024 if (fd > -1) { 01025 errno = 0; 01026 fs = get_filestream(f, bfile); 01027 if (!fs || rewrite_wrapper(fs, comment)) { 01028 ast_log(LOG_WARNING, "Unable to rewrite %s\n", fn); 01029 close(fd); 01030 if (orig_fn) { 01031 unlink(fn); 01032 unlink(orig_fn); 01033 } 01034 if (fs) 01035 ast_free(fs); 01036 fs = NULL; 01037 continue; 01038 } 01039 fs->trans = NULL; 01040 fs->fmt = f; 01041 fs->flags = flags; 01042 fs->mode = mode; 01043 if (orig_fn) { 01044 fs->realfilename = strdup(orig_fn); 01045 fs->filename = strdup(fn); 01046 } else { 01047 fs->realfilename = NULL; 01048 fs->filename = strdup(filename); 01049 } 01050 fs->vfs = NULL; 01051 /* If truncated, we'll be at the beginning; if not truncated, then append */ 01052 f->seek(fs, 0, SEEK_END); 01053 } else if (errno != EEXIST) { 01054 ast_log(LOG_WARNING, "Unable to open file %s: %s\n", fn, strerror(errno)); 01055 if (orig_fn) 01056 unlink(orig_fn); 01057 } 01058 /* if buf != NULL then fn is already free and pointing to it */ 01059 if (!buf) 01060 free(fn); 01061 } 01062 01063 AST_RWLIST_UNLOCK(&formats); 01064 01065 if (!format_found) 01066 ast_log(LOG_WARNING, "No such format '%s'\n", type); 01067 01068 return fs; 01069 }
int ast_writestream | ( | struct ast_filestream * | fs, | |
struct ast_frame * | f | |||
) |
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 Returns 0 on success, -1 on failure. |
Definition at line 153 of file file.c.
References AST_FORMAT_MAX_AUDIO, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_frfree, ast_getformatname(), 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_DEBUG, 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(), cli_audio_convert(), cli_audio_convert_deprecated(), dictate_exec(), handle_recordfile(), mixmonitor_thread(), recordthread(), and rpt().
00154 { 00155 int res = -1; 00156 int alt = 0; 00157 if (f->frametype == AST_FRAME_VIDEO) { 00158 if (fs->fmt->format < AST_FORMAT_MAX_AUDIO) { 00159 /* This is the audio portion. Call the video one... */ 00160 if (!fs->vfs && fs->filename) { 00161 const char *type = ast_getformatname(f->subclass & ~0x1); 00162 fs->vfs = ast_writefile(fs->filename, type, NULL, fs->flags, 0, fs->mode); 00163 ast_log(LOG_DEBUG, "Opened video output file\n"); 00164 } 00165 if (fs->vfs) 00166 return ast_writestream(fs->vfs, f); 00167 /* else ignore */ 00168 return 0; 00169 } else { 00170 /* Might / might not have mark set */ 00171 alt = 1; 00172 } 00173 } else if (f->frametype != AST_FRAME_VOICE) { 00174 ast_log(LOG_WARNING, "Tried to write non-voice frame\n"); 00175 return -1; 00176 } 00177 if (((fs->fmt->format | alt) & f->subclass) == f->subclass) { 00178 res = fs->fmt->write(fs, f); 00179 if (res < 0) 00180 ast_log(LOG_WARNING, "Natural write failed\n"); 00181 else if (res > 0) 00182 ast_log(LOG_WARNING, "Huh??\n"); 00183 } else { 00184 /* XXX If they try to send us a type of frame that isn't the normal frame, and isn't 00185 the one we've setup a translator for, we do the "wrong thing" XXX */ 00186 if (fs->trans && f->subclass != fs->lastwriteformat) { 00187 ast_translator_free_path(fs->trans); 00188 fs->trans = NULL; 00189 } 00190 if (!fs->trans) 00191 fs->trans = ast_translator_build_path(fs->fmt->format, f->subclass); 00192 if (!fs->trans) 00193 ast_log(LOG_WARNING, "Unable to translate to format %s, source format %s\n", 00194 fs->fmt->name, ast_getformatname(f->subclass)); 00195 else { 00196 struct ast_frame *trf; 00197 fs->lastwriteformat = f->subclass; 00198 /* Get the translated frame but don't consume the original in case they're using it on another stream */ 00199 trf = ast_translate(fs->trans, f, 0); 00200 if (trf) { 00201 res = fs->fmt->write(fs, trf); 00202 ast_frfree(trf); 00203 if (res) 00204 ast_log(LOG_WARNING, "Translated frame write failed\n"); 00205 } else 00206 res = 0; 00207 } 00208 } 00209 return res; 00210 }
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 255 of file file.c.
References asprintf, and ast_config_AST_DATA_DIR.
Referenced by ast_filehelper(), ast_readfile(), and ast_writefile().
00256 { 00257 char *fn = NULL; 00258 00259 if (!strcmp(ext, "wav49")) 00260 ext = "WAV"; 00261 00262 if (filename[0] == '/') 00263 asprintf(&fn, "%s.%s", filename, ext); 00264 else 00265 asprintf(&fn, "%s/sounds/%s.%s", 00266 ast_config_AST_DATA_DIR, filename, ext); 00267 return fn; 00268 }
static int copy | ( | const char * | infile, | |
const char * | outfile | |||
) | [static] |
Definition at line 212 of file file.c.
References ast_log(), errno, len, and LOG_WARNING.
Referenced by action_getvar(), ast_filehelper(), copy_plain_file(), iax2_register(), and transcoder_show().
00213 { 00214 int ifd, ofd, len; 00215 char buf[4096]; /* XXX make it lerger. */ 00216 00217 if ((ifd = open(infile, O_RDONLY)) < 0) { 00218 ast_log(LOG_WARNING, "Unable to open %s in read-only mode\n", infile); 00219 return -1; 00220 } 00221 if ((ofd = open(outfile, O_WRONLY | O_TRUNC | O_CREAT, 0600)) < 0) { 00222 ast_log(LOG_WARNING, "Unable to open %s in write-only mode\n", outfile); 00223 close(ifd); 00224 return -1; 00225 } 00226 while ( (len = read(ifd, buf, sizeof(buf)) ) ) { 00227 int res; 00228 if (len < 0) { 00229 ast_log(LOG_WARNING, "Read failed on %s: %s\n", infile, strerror(errno)); 00230 break; 00231 } 00232 /* XXX handle partial writes */ 00233 res = write(ofd, buf, len); 00234 if (res != len) { 00235 ast_log(LOG_WARNING, "Write failed on %s (%d of %d): %s\n", outfile, res, len, strerror(errno)); 00236 len = -1; /* error marker */ 00237 break; 00238 } 00239 } 00240 close(ifd); 00241 close(ofd); 00242 if (len < 0) { 00243 unlink(outfile); 00244 return -1; /* error */ 00245 } 00246 return 0; /* success */ 00247 }
static int exts_compare | ( | const char * | exts, | |
const char * | type | |||
) | [static] |
Definition at line 272 of file file.c.
Referenced by ast_filehelper(), ast_readfile(), and ast_writefile().
00273 { 00274 char tmp[256]; 00275 char *stringp = tmp, *ext; 00276 00277 ast_copy_string(tmp, exts, sizeof(tmp)); 00278 while ((ext = strsep(&stringp, "|"))) { 00279 if (!strcmp(ext, type)) 00280 return 1; 00281 } 00282 00283 return 0; 00284 }
static int 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 '_' suffix, or NULL. In the standard asterisk, language goes just before the last component. In an alternative configuration, the language should be a prefix to the actual filename.
The last parameter(s) point to a buffer of sufficient size, which on success is filled with the matching filename.
Definition at line 511 of file file.c.
References ACTION_EXISTS, ast_filehelper(), ast_strdupa, ast_strlen_zero(), DEFAULT_LANGUAGE, fileexists_test(), is_absolute_path(), and strsep().
Referenced by ast_fileexists(), ast_openstream_full(), and ast_openvstream().
00513 { 00514 int res = -1; 00515 char *lang = NULL; 00516 00517 if (buf == NULL) { 00518 return -1; 00519 } 00520 00521 if (is_absolute_path(filename)) { 00522 ast_copy_string(buf, filename, buflen); 00523 return ast_filehelper(buf, NULL, fmt, ACTION_EXISTS); 00524 } 00525 00526 /* We try languages in the following order: 00527 * preflang (may include dialect) 00528 * lang (preflang without dialect - if any) 00529 * <none> 00530 * default (unless the same as preflang or lang without dialect) 00531 */ 00532 00533 /* Try preferred language */ 00534 if (!ast_strlen_zero(preflang)) { 00535 /* try the preflang exactly as it was requested */ 00536 if ((res = fileexists_test(filename, fmt, preflang, buf, buflen)) > 0) { 00537 return res; 00538 } else { 00539 /* try without a dialect */ 00540 char *postfix = NULL; 00541 postfix = lang = ast_strdupa(preflang); 00542 00543 strsep(&postfix, "_"); 00544 if (postfix) { 00545 if ((res = fileexists_test(filename, fmt, lang, buf, buflen)) > 0) { 00546 return res; 00547 } 00548 } 00549 } 00550 } 00551 00552 /* Try without any language */ 00553 if ((res = fileexists_test(filename, fmt, NULL, buf, buflen)) > 0) { 00554 return res; 00555 } 00556 00557 /* Finally try the default language unless it was already tried before */ 00558 if ((ast_strlen_zero(preflang) || strcmp(preflang, DEFAULT_LANGUAGE)) && (ast_strlen_zero(lang) || strcmp(lang, DEFAULT_LANGUAGE))) { 00559 if ((res = fileexists_test(filename, fmt, DEFAULT_LANGUAGE, buf, buflen)) > 0) { 00560 return res; 00561 } 00562 } 00563 00564 return 0; 00565 }
static int fileexists_test | ( | const char * | filename, | |
const char * | fmt, | |||
const char * | lang, | |||
char * | buf, | |||
int | buflen | |||
) | [static] |
Definition at line 474 of file file.c.
References ACTION_EXISTS, ast_filehelper(), and offset.
Referenced by fileexists_core().
00476 { 00477 if (buf == NULL) { 00478 return -1; 00479 } 00480 00481 if (ast_language_is_prefix) { /* new layout */ 00482 if (lang) { 00483 snprintf(buf, buflen, "%s/%s", lang, filename); 00484 } else { 00485 snprintf(buf, buflen, "%s", filename); 00486 } 00487 } else { /* old layout */ 00488 strcpy(buf, filename); /* first copy the full string */ 00489 if (lang) { 00490 /* insert the language and suffix if needed */ 00491 const char *c = strrchr(filename, '/'); 00492 int offset = c ? c - filename + 1 : 0; /* points right after the last '/' */ 00493 snprintf(buf + offset, buflen - offset, "%s/%s", lang, filename + offset); 00494 } 00495 } 00496 00497 return ast_filehelper(buf, NULL, fmt, ACTION_EXISTS); 00498 }
static int fn_wrapper | ( | struct ast_filestream * | s, | |
const char * | comment, | |||
enum wrap_fn | mode | |||
) | [static] |
Definition at line 310 of file file.c.
References ast_log(), ast_module_ref(), f, LOG_WARNING, ast_format::module, ast_format::name, ast_format::open, ast_format::rewrite, s, and WRAP_OPEN.
Referenced by open_wrapper(), and rewrite_wrapper().
00311 { 00312 struct ast_format *f = s->fmt; 00313 int ret = -1; 00314 00315 if (mode == WRAP_OPEN && f->open && f->open(s)) 00316 ast_log(LOG_WARNING, "Unable to open format %s\n", f->name); 00317 else if (mode == WRAP_REWRITE && f->rewrite && f->rewrite(s, comment)) 00318 ast_log(LOG_WARNING, "Unable to rewrite format %s\n", f->name); 00319 else { 00320 /* preliminary checks succeed. update usecount */ 00321 ast_module_ref(f->module); 00322 ret = 0; 00323 } 00324 return ret; 00325 }
static struct ast_filestream* get_filestream | ( | struct ast_format * | fmt, | |
FILE * | bfile | |||
) | [static] |
Definition at line 286 of file file.c.
References ast_calloc, fmt, and s.
Referenced by ast_filehelper(), ast_readfile(), and ast_writefile().
00287 { 00288 struct ast_filestream *s; 00289 00290 int l = sizeof(*s) + fmt->buf_size + fmt->desc_size; /* total allocation size */ 00291 if ( (s = ast_calloc(1, l)) == NULL) 00292 return NULL; 00293 s->fmt = fmt; 00294 s->f = bfile; 00295 00296 if (fmt->desc_size) 00297 s->_private = ((char *)(s+1)) + fmt->buf_size; 00298 if (fmt->buf_size) 00299 s->buf = (char *)(s+1); 00300 s->fr.src = fmt->name; 00301 return s; 00302 }
static int is_absolute_path | ( | const char * | filename | ) | [static] |
Definition at line 469 of file file.c.
Referenced by fileexists_core().
00470 { 00471 return filename[0] == '/'; 00472 }
static int open_wrapper | ( | struct ast_filestream * | s | ) | [static] |
Definition at line 332 of file file.c.
References fn_wrapper(), s, and WRAP_OPEN.
Referenced by ast_filehelper(), and ast_readfile().
00333 { 00334 return fn_wrapper(s, NULL, WRAP_OPEN); 00335 }
static int rewrite_wrapper | ( | struct ast_filestream * | s, | |
const char * | comment | |||
) | [static] |
Definition at line 327 of file file.c.
References fn_wrapper(), and s.
Referenced by ast_writefile().
00328 { 00329 return fn_wrapper(s, comment, WRAP_REWRITE); 00330 }
static int show_file_formats | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1249 of file file.c.
References ast_cli(), ast_getformatname(), AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_format::exts, f, ast_format::format, FORMAT, FORMAT2, ast_format::name, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
01250 { 01251 #define FORMAT "%-10s %-10s %-20s\n" 01252 #define FORMAT2 "%-10s %-10s %-20s\n" 01253 struct ast_format *f; 01254 int count_fmt = 0; 01255 01256 if (argc != 4) 01257 return RESULT_SHOWUSAGE; 01258 ast_cli(fd, FORMAT, "Format", "Name", "Extensions"); 01259 01260 AST_RWLIST_RDLOCK(&formats); 01261 AST_RWLIST_TRAVERSE(&formats, f, list) { 01262 ast_cli(fd, FORMAT2, ast_getformatname(f->format), f->name, f->exts); 01263 count_fmt++; 01264 } 01265 AST_RWLIST_UNLOCK(&formats); 01266 ast_cli(fd, "%d file formats registered.\n", count_fmt); 01267 return RESULT_SUCCESS; 01268 #undef FORMAT 01269 #undef FORMAT2 01270 }
static int show_file_formats_deprecated | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1272 of file file.c.
References ast_cli(), ast_getformatname(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_format::exts, f, ast_format::format, FORMAT, FORMAT2, LOG_WARNING, ast_format::name, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
01273 { 01274 #define FORMAT "%-10s %-10s %-20s\n" 01275 #define FORMAT2 "%-10s %-10s %-20s\n" 01276 struct ast_format *f; 01277 int count_fmt = 0; 01278 01279 if (argc != 3) 01280 return RESULT_SHOWUSAGE; 01281 ast_cli(fd, FORMAT, "Format", "Name", "Extensions"); 01282 01283 if (AST_LIST_LOCK(&formats)) { 01284 ast_log(LOG_WARNING, "Unable to lock format list\n"); 01285 return -1; 01286 } 01287 01288 AST_LIST_TRAVERSE(&formats, f, list) { 01289 ast_cli(fd, FORMAT2, ast_getformatname(f->format), f->name, f->exts); 01290 count_fmt++; 01291 } 01292 AST_LIST_UNLOCK(&formats); 01293 ast_cli(fd, "%d file formats registered.\n", count_fmt); 01294 return RESULT_SUCCESS; 01295 #undef FORMAT 01296 #undef FORMAT2 01297 }
static int waitstream_core | ( | struct ast_channel * | c, | |
const char * | breakon, | |||
const char * | forward, | |||
const char * | rewind, | |||
int | skip_ms, | |||
int | audiofd, | |||
int | cmdfd, | |||
const char * | context | |||
) | [static] |
the core of all waitstream() functions
Definition at line 1074 of file file.c.
References ast_channel::_softhangup, ast_clear_flag, AST_CONTROL_ANSWER, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_HANGUP, AST_CONTROL_HOLD, AST_CONTROL_RINGING, AST_CONTROL_SRCUPDATE, AST_CONTROL_UNHOLD, 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::cid, ast_callerid::cid_num, ast_frame::data, ast_frame::datalen, errno, exten, ast_frame::frametype, LOG_WARNING, ast_filestream::orig_chan_name, ast_channel::sched, ast_channel::stream, and ast_frame::subclass.
Referenced by ast_waitstream(), ast_waitstream_exten(), ast_waitstream_fr(), and ast_waitstream_full().
01077 { 01078 const char *orig_chan_name = NULL; 01079 int err = 0; 01080 01081 if (!breakon) 01082 breakon = ""; 01083 if (!forward) 01084 forward = ""; 01085 if (!rewind) 01086 rewind = ""; 01087 01088 /* Switch the channel to end DTMF frame only. waitstream_core doesn't care about the start of DTMF. */ 01089 ast_set_flag(c, AST_FLAG_END_DTMF_ONLY); 01090 01091 if (ast_test_flag(c, AST_FLAG_MASQ_NOSTREAM)) 01092 orig_chan_name = ast_strdupa(c->name); 01093 01094 while (c->stream) { 01095 int res; 01096 int ms; 01097 01098 if (orig_chan_name && strcasecmp(orig_chan_name, c->name)) { 01099 ast_stopstream(c); 01100 err = 1; 01101 break; 01102 } 01103 01104 ms = ast_sched_wait(c->sched); 01105 01106 if (ms < 0 && !c->timingfunc) { 01107 ast_stopstream(c); 01108 break; 01109 } 01110 if (ms < 0) 01111 ms = 1000; 01112 if (cmdfd < 0) { 01113 res = ast_waitfor(c, ms); 01114 if (res < 0) { 01115 ast_log(LOG_WARNING, "Select failed (%s)\n", strerror(errno)); 01116 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 01117 return res; 01118 } 01119 } else { 01120 int outfd; 01121 struct ast_channel *rchan = ast_waitfor_nandfds(&c, 1, &cmdfd, (cmdfd > -1) ? 1 : 0, NULL, &outfd, &ms); 01122 if (!rchan && (outfd < 0) && (ms)) { 01123 /* Continue */ 01124 if (errno == EINTR) 01125 continue; 01126 ast_log(LOG_WARNING, "Wait failed (%s)\n", strerror(errno)); 01127 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 01128 return -1; 01129 } else if (outfd > -1) { /* this requires cmdfd set */ 01130 /* The FD we were watching has something waiting */ 01131 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 01132 return 1; 01133 } 01134 /* if rchan is set, it is 'c' */ 01135 res = rchan ? 1 : 0; /* map into 'res' values */ 01136 } 01137 if (res > 0) { 01138 struct ast_frame *fr = ast_read(c); 01139 if (!fr) { 01140 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 01141 return -1; 01142 } 01143 switch(fr->frametype) { 01144 case AST_FRAME_DTMF_END: 01145 if (context) { 01146 const char exten[2] = { fr->subclass, '\0' }; 01147 if (ast_exists_extension(c, context, exten, 1, c->cid.cid_num)) { 01148 res = fr->subclass; 01149 ast_frfree(fr); 01150 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 01151 return res; 01152 } 01153 } else { 01154 res = fr->subclass; 01155 if (strchr(forward,res)) { 01156 ast_stream_fastforward(c->stream, skip_ms); 01157 } else if (strchr(rewind,res)) { 01158 ast_stream_rewind(c->stream, skip_ms); 01159 } else if (strchr(breakon, res)) { 01160 ast_frfree(fr); 01161 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 01162 return res; 01163 } 01164 } 01165 break; 01166 case AST_FRAME_CONTROL: 01167 switch(fr->subclass) { 01168 case AST_CONTROL_HANGUP: 01169 case AST_CONTROL_BUSY: 01170 case AST_CONTROL_CONGESTION: 01171 ast_frfree(fr); 01172 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 01173 return -1; 01174 case AST_CONTROL_RINGING: 01175 case AST_CONTROL_ANSWER: 01176 case AST_CONTROL_VIDUPDATE: 01177 case AST_CONTROL_SRCUPDATE: 01178 case AST_CONTROL_HOLD: 01179 case AST_CONTROL_UNHOLD: 01180 /* Unimportant */ 01181 break; 01182 default: 01183 ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", fr->subclass); 01184 } 01185 break; 01186 case AST_FRAME_VOICE: 01187 /* Write audio if appropriate */ 01188 if (audiofd > -1) 01189 write(audiofd, fr->data, fr->datalen); 01190 default: 01191 /* Ignore all others */ 01192 break; 01193 } 01194 ast_frfree(fr); 01195 } 01196 ast_sched_runq(c->sched); 01197 } 01198 01199 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 01200 01201 return (err || c->_softhangup) ? -1 : 0; 01202 }
int ast_language_is_prefix = 1 |
struct ast_cli_entry cli_file[] |
Initial value:
{ { { "core", "show", "file", "formats" }, show_file_formats, "Displays file formats", show_file_formats_usage, NULL, &cli_show_file_formats_deprecated }, }
Definition at line 1308 of file file.c.
Referenced by ast_file_init().
Initial value:
{ { "show", "file", "formats" }, show_file_formats_deprecated, NULL, NULL }
char show_file_formats_usage[] |