#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 "asterisk/astobj2.h"
Go to the source code of this file.
Data Structures | |
struct | formats |
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) |
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 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 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 | 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 |
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(), dahdi_show_channels(), dahdi_show_status(), 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(), and sip_show_registry().
enum file_action |
Definition at line 406 of file file.c.
00406 { 00407 ACTION_EXISTS = 1, /* return matching format if file exists, 0 otherwise */ 00408 ACTION_DELETE, /* delete file, return 0 on success, -1 on error */ 00409 ACTION_RENAME, /* rename file. return 0 on success, -1 on error */ 00410 ACTION_OPEN, 00411 ACTION_COPY /* copy file. return 0 on success, -1 on error */ 00412 };
enum fsread_res |
Definition at line 741 of file file.c.
00741 { 00742 FSREAD_FAILURE, 00743 FSREAD_SUCCESS_SCHED, 00744 FSREAD_SUCCESS_NOSCHED, 00745 };
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 69 of file file.c.
References ast_calloc, AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_verbose(), ast_format::buf_size, ast_format::exts, f, ast_format::list, LOG_WARNING, ast_format::module, ast_format::name, option_verbose, and VERBOSE_PREFIX_2.
00070 { 00071 struct ast_format *tmp; 00072 00073 if (AST_LIST_LOCK(&formats)) { 00074 ast_log(LOG_WARNING, "Unable to lock format list\n"); 00075 return -1; 00076 } 00077 AST_LIST_TRAVERSE(&formats, tmp, list) { 00078 if (!strcasecmp(f->name, tmp->name)) { 00079 AST_LIST_UNLOCK(&formats); 00080 ast_log(LOG_WARNING, "Tried to register '%s' format, already registered\n", f->name); 00081 return -1; 00082 } 00083 } 00084 if (!(tmp = ast_calloc(1, sizeof(*tmp)))) { 00085 AST_LIST_UNLOCK(&formats); 00086 return -1; 00087 } 00088 *tmp = *f; 00089 tmp->module = mod; 00090 if (tmp->buf_size) { 00091 /* 00092 * Align buf_size properly, rounding up to the machine-specific 00093 * alignment for pointers. 00094 */ 00095 struct _test_align { void *a, *b; } p; 00096 int align = (char *)&p.b - (char *)&p.a; 00097 tmp->buf_size = ((f->buf_size + align - 1)/align)*align; 00098 } 00099 00100 memset(&tmp->list, 0, sizeof(tmp->list)); 00101 00102 AST_LIST_INSERT_HEAD(&formats, tmp, list); 00103 AST_LIST_UNLOCK(&formats); 00104 if (option_verbose > 1) 00105 ast_verbose( VERBOSE_PREFIX_2 "Registered file format %s, extension(s) %s\n", f->name, f->exts); 00106 00107 return 0; 00108 }
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 865 of file file.c.
References s.
Referenced by ast_streamfile(), handle_getoption(), handle_recordfile(), handle_streamfile(), and speech_streamfile().
00866 { 00867 s->owner = chan; 00868 return 0; 00869 }
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 908 of file file.c.
References ao2_ref(), AST_FORMAT_AUDIO_MASK, AST_SCHED_DEL, ast_settimeout(), f, and ast_format::format.
Referenced by __ast_play_and_record(), ast_filehelper(), ast_hangup(), ast_moh_files_next(), ast_monitor_start(), ast_monitor_stop(), ast_readfile(), ast_stopstream(), ast_writefile(), cli_audio_convert(), cli_audio_convert_deprecated(), dictate_exec(), filestream_destructor(), gen_closestream(), handle_recordfile(), local_ast_moh_stop(), mixmonitor_ds_close_fs(), moh_files_release(), and rpt().
00909 { 00910 /* This used to destroy the filestream, but it now just decrements a refcount. 00911 * We need to force the stream to quit queuing frames now, because we might 00912 * change the writeformat, which could result in a subsequent write error, if 00913 * the format is different. */ 00914 00915 /* Stop a running stream if there is one */ 00916 if (f->owner) { 00917 if (f->fmt->format < AST_FORMAT_AUDIO_MASK) { 00918 f->owner->stream = NULL; 00919 AST_SCHED_DEL(f->owner->sched, f->owner->streamid); 00920 ast_settimeout(f->owner, 0, NULL, NULL); 00921 } else { 00922 f->owner->vstream = NULL; 00923 AST_SCHED_DEL(f->owner->sched, f->owner->vstreamid); 00924 } 00925 } 00926 00927 ao2_ref(f, -1); 00928 return 0; 00929 }
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 1432 of file file.c.
References ast_cli_register_multiple(), and cli_file.
Referenced by main().
01433 { 01434 ast_cli_register_multiple(cli_file, sizeof(cli_file) / sizeof(struct ast_cli_entry)); 01435 return 0; 01436 }
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 959 of file file.c.
References ast_filehelper().
Referenced by copy_plain_file(), and vm_forwardoptions().
00960 { 00961 return ast_filehelper(filename, filename2, fmt, ACTION_COPY); 00962 }
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 949 of file file.c.
References ACTION_DELETE, and ast_filehelper().
Referenced by __ast_play_and_record(), announce_thread(), ast_monitor_start(), ast_monitor_stop(), cli_audio_convert(), cli_audio_convert_deprecated(), conf_free(), leave_voicemail(), play_mailbox_owner(), play_record_review(), vm_delete(), and vm_forwardoptions().
00950 { 00951 return ast_filehelper(filename, NULL, fmt, ACTION_DELETE); 00952 }
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 935 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(), last_message_index(), leave_voicemail(), play_greeting(), play_mailbox_owner(), play_message_callerid(), record_exec(), retrydial_exec(), say_character_str_full(), say_digit_str_full(), say_phonetic_str_full(), vm_intro(), vm_newuser(), vm_options(), and vm_tempgreeting().
00936 { 00937 char *buf; 00938 int buflen; 00939 00940 if (preflang == NULL) 00941 preflang = ""; 00942 buflen = strlen(preflang) + strlen(filename) + 4; /* room for everything */ 00943 buf = alloca(buflen); 00944 if (buf == NULL) 00945 return 0; 00946 return fileexists_core(filename, fmt, preflang, buf, buflen); 00947 }
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 423 of file file.c.
References ACTION_DELETE, ACTION_EXISTS, ACTION_OPEN, ACTION_RENAME, ast_closestream(), AST_FORMAT_MAX_AUDIO, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_strdupa, build_filename(), copy(), errno, ext, ast_format::exts, exts_compare(), f, ast_format::format, free, get_filestream(), ast_format::list, LOG_WARNING, open_wrapper(), s, ast_channel::stream, ast_channel::vstream, and ast_channel::writeformat.
Referenced by ast_filecopy(), ast_filedelete(), ast_filerename(), ast_openstream_full(), ast_openvstream(), and fileexists_test().
00424 { 00425 struct ast_format *f; 00426 int res = (action == ACTION_EXISTS) ? 0 : -1; 00427 00428 if (AST_LIST_LOCK(&formats)) { 00429 ast_log(LOG_WARNING, "Unable to lock format list\n"); 00430 return res; 00431 } 00432 /* Check for a specific format */ 00433 AST_LIST_TRAVERSE(&formats, f, list) { 00434 char *stringp, *ext = NULL; 00435 00436 if (fmt && !exts_compare(f->exts, fmt)) 00437 continue; 00438 00439 /* Look for a file matching the supported extensions. 00440 * The file must exist, and for OPEN, must match 00441 * one of the formats supported by the channel. 00442 */ 00443 stringp = ast_strdupa(f->exts); /* this is in the stack so does not need to be freed */ 00444 while ( (ext = strsep(&stringp, "|")) ) { 00445 struct stat st; 00446 char *fn = build_filename(filename, ext); 00447 00448 if (fn == NULL) 00449 continue; 00450 00451 if ( stat(fn, &st) ) { /* file not existent */ 00452 free(fn); 00453 continue; 00454 } 00455 /* for 'OPEN' we need to be sure that the format matches 00456 * what the channel can process 00457 */ 00458 if (action == ACTION_OPEN) { 00459 struct ast_channel *chan = (struct ast_channel *)arg2; 00460 FILE *bfile; 00461 struct ast_filestream *s; 00462 00463 if ( !(chan->writeformat & f->format) && 00464 !(f->format >= AST_FORMAT_MAX_AUDIO && fmt)) { 00465 free(fn); 00466 continue; /* not a supported format */ 00467 } 00468 if ( (bfile = fopen(fn, "r")) == NULL) { 00469 free(fn); 00470 continue; /* cannot open file */ 00471 } 00472 s = get_filestream(f, bfile); 00473 if (!s) { 00474 fclose(bfile); 00475 free(fn); /* cannot allocate descriptor */ 00476 continue; 00477 } 00478 if (open_wrapper(s)) { 00479 free(fn); 00480 ast_closestream(s); 00481 continue; /* cannot run open on file */ 00482 } 00483 /* ok this is good for OPEN */ 00484 res = 1; /* found */ 00485 s->lasttimeout = -1; 00486 s->fmt = f; 00487 s->trans = NULL; 00488 s->filename = NULL; 00489 if (s->fmt->format < AST_FORMAT_MAX_AUDIO) { 00490 if (chan->stream) 00491 ast_closestream(chan->stream); 00492 chan->stream = s; 00493 } else { 00494 if (chan->vstream) 00495 ast_closestream(chan->vstream); 00496 chan->vstream = s; 00497 } 00498 free(fn); 00499 break; 00500 } 00501 switch (action) { 00502 case ACTION_OPEN: 00503 break; /* will never get here */ 00504 00505 case ACTION_EXISTS: /* return the matching format */ 00506 res |= f->format; 00507 break; 00508 00509 case ACTION_DELETE: 00510 if ( (res = unlink(fn)) ) 00511 ast_log(LOG_WARNING, "unlink(%s) failed: %s\n", fn, strerror(errno)); 00512 break; 00513 00514 case ACTION_RENAME: 00515 case ACTION_COPY: { 00516 char *nfn = build_filename((const char *)arg2, ext); 00517 if (!nfn) 00518 ast_log(LOG_WARNING, "Out of memory\n"); 00519 else { 00520 res = action == ACTION_COPY ? copy(fn, nfn) : rename(fn, nfn); 00521 if (res) 00522 ast_log(LOG_WARNING, "%s(%s,%s) failed: %s\n", 00523 action == ACTION_COPY ? "copy" : "rename", 00524 fn, nfn, strerror(errno)); 00525 free(nfn); 00526 } 00527 } 00528 break; 00529 00530 default: 00531 ast_log(LOG_WARNING, "Unknown helper %d\n", action); 00532 } 00533 free(fn); 00534 } 00535 } 00536 AST_LIST_UNLOCK(&formats); 00537 return res; 00538 }
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 954 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().
00955 { 00956 return ast_filehelper(filename, filename2, fmt, ACTION_RENAME); 00957 }
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 110 of file file.c.
References AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_log(), ast_verbose(), free, ast_format::list, LOG_WARNING, ast_format::name, option_verbose, and VERBOSE_PREFIX_2.
Referenced by unload_module().
00111 { 00112 struct ast_format *tmp; 00113 int res = -1; 00114 00115 if (AST_LIST_LOCK(&formats)) { 00116 ast_log(LOG_WARNING, "Unable to lock format list\n"); 00117 return -1; 00118 } 00119 AST_LIST_TRAVERSE_SAFE_BEGIN(&formats, tmp, list) { 00120 if (!strcasecmp(name, tmp->name)) { 00121 AST_LIST_REMOVE_CURRENT(&formats, list); 00122 free(tmp); 00123 res = 0; 00124 } 00125 } 00126 AST_LIST_TRAVERSE_SAFE_END 00127 AST_LIST_UNLOCK(&formats); 00128 00129 if (!res) { 00130 if (option_verbose > 1) 00131 ast_verbose( VERBOSE_PREFIX_2 "Unregistered format %s\n", name); 00132 } else 00133 ast_log(LOG_WARNING, "Tried to unregister format %s, already unregistered\n", name); 00134 00135 return res; 00136 }
static int ast_fsread_audio | ( | const void * | data | ) | [static] |
Definition at line 805 of file file.c.
References ast_readaudio_callback(), and FSREAD_SUCCESS_SCHED.
Referenced by ast_readaudio_callback().
00806 { 00807 struct ast_filestream *fs = (struct ast_filestream *)data; 00808 enum fsread_res res; 00809 00810 res = ast_readaudio_callback(fs); 00811 00812 if (res == FSREAD_SUCCESS_SCHED) 00813 return 1; 00814 00815 return 0; 00816 }
static int ast_fsread_video | ( | const void * | data | ) | [static] |
Definition at line 852 of file file.c.
References ast_readvideo_callback(), and FSREAD_SUCCESS_SCHED.
Referenced by ast_readvideo_callback().
00853 { 00854 struct ast_filestream *fs = (struct ast_filestream *)data; 00855 enum fsread_res res; 00856 00857 res = ast_readvideo_callback(fs); 00858 00859 if (res == FSREAD_SUCCESS_SCHED) 00860 return 1; 00861 00862 return 0; 00863 }
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 633 of file file.c.
References ast_openstream_full().
Referenced by ast_streamfile(), dictate_exec(), handle_getoption(), handle_streamfile(), and speech_streamfile().
00634 { 00635 return ast_openstream_full(chan, filename, preflang, 0); 00636 }
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 638 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().
00639 { 00640 /* 00641 * Use fileexists_core() to find a file in a compatible 00642 * language and format, set up a suitable translator, 00643 * and open the stream. 00644 */ 00645 int fmts, res, buflen; 00646 char *buf; 00647 00648 if (!asis) { 00649 /* do this first, otherwise we detect the wrong writeformat */ 00650 ast_stopstream(chan); 00651 if (chan->generator) 00652 ast_deactivate_generator(chan); 00653 } 00654 if (preflang == NULL) 00655 preflang = ""; 00656 buflen = strlen(preflang) + strlen(filename) + 4; 00657 buf = alloca(buflen); 00658 if (buf == NULL) 00659 return NULL; 00660 fmts = fileexists_core(filename, NULL, preflang, buf, buflen); 00661 if (fmts > 0) 00662 fmts &= AST_FORMAT_AUDIO_MASK; 00663 if (fmts < 1) { 00664 ast_log(LOG_WARNING, "File %s does not exist in any format\n", filename); 00665 return NULL; 00666 } 00667 chan->oldwriteformat = chan->writeformat; 00668 /* Set the channel to a format we can work with */ 00669 res = ast_set_write_format(chan, fmts); 00670 res = ast_filehelper(buf, chan, NULL, ACTION_OPEN); 00671 if (res >= 0) 00672 return chan->stream; 00673 return NULL; 00674 }
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 676 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(), ast_filestream::fmt, format, LOG_WARNING, ast_channel::nativeformats, and ast_channel::vstream.
Referenced by ast_streamfile(), handle_getoption(), and handle_streamfile().
00677 { 00678 /* As above, but for video. But here we don't have translators 00679 * so we must enforce a format. 00680 */ 00681 unsigned int format; 00682 char *buf; 00683 int buflen; 00684 00685 if (preflang == NULL) 00686 preflang = ""; 00687 buflen = strlen(preflang) + strlen(filename) + 4; 00688 buf = alloca(buflen); 00689 if (buf == NULL) 00690 return NULL; 00691 00692 for (format = AST_FORMAT_MAX_AUDIO << 1; format <= AST_FORMAT_MAX_VIDEO; format = format << 1) { 00693 int fd; 00694 const char *fmt; 00695 00696 if (!(chan->nativeformats & format)) 00697 continue; 00698 fmt = ast_getformatname(format); 00699 if ( fileexists_core(filename, fmt, preflang, buf, buflen) < 1) /* no valid format */ 00700 continue; 00701 fd = ast_filehelper(buf, chan, fmt, ACTION_OPEN); 00702 if (fd >= 0) 00703 return chan->vstream; 00704 ast_log(LOG_WARNING, "File %s has video but couldn't be opened\n", filename); 00705 } 00706 return NULL; 00707 }
int ast_playstream | ( | struct ast_filestream * | s | ) |
s | filestream to play Returns 0 for success, -1 on failure |
Definition at line 871 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().
00872 { 00873 enum fsread_res res; 00874 00875 if (s->fmt->format < AST_FORMAT_MAX_AUDIO) 00876 res = ast_readaudio_callback(s); 00877 else 00878 res = ast_readvideo_callback(s); 00879 00880 return (res == FSREAD_FAILURE) ? -1 : 0; 00881 }
static enum fsread_res ast_readaudio_callback | ( | struct ast_filestream * | s | ) | [static] |
Definition at line 749 of file file.c.
References ast_format_rate(), ast_frfree, ast_fsread_audio(), ast_log(), ast_sched_add(), ast_settimeout(), ast_write(), FSREAD_FAILURE, FSREAD_SUCCESS_NOSCHED, FSREAD_SUCCESS_SCHED, LOG_WARNING, read_frame(), and s.
Referenced by ast_fsread_audio(), and ast_playstream().
00750 { 00751 int whennext = 0; 00752 00753 while (!whennext) { 00754 struct ast_frame *fr; 00755 00756 if (s->orig_chan_name && strcasecmp(s->owner->name, s->orig_chan_name)) { 00757 goto return_failure; 00758 } 00759 00760 fr = read_frame(s, &whennext); 00761 00762 if (!fr /* stream complete */ || ast_write(s->owner, fr) /* error writing */) { 00763 if (fr) { 00764 ast_log(LOG_WARNING, "Failed to write frame\n"); 00765 ast_frfree(fr); 00766 } 00767 goto return_failure; 00768 } 00769 00770 if (fr) { 00771 ast_frfree(fr); 00772 } 00773 } 00774 00775 if (whennext != s->lasttimeout) { 00776 #ifdef HAVE_DAHDI 00777 if (s->owner->timingfd > -1) { 00778 int zap_timer_samples = whennext; 00779 int rate; 00780 /* whennext is in samples, but DAHDI timers operate in 8 kHz samples. */ 00781 if ((rate = ast_format_rate(s->fmt->format)) != 8000) { 00782 float factor; 00783 factor = ((float) rate) / ((float) 8000.0); 00784 zap_timer_samples = (int) ( ((float) zap_timer_samples) / factor ); 00785 } 00786 ast_settimeout(s->owner, zap_timer_samples, ast_fsread_audio, s); 00787 } else 00788 #endif 00789 s->owner->streamid = ast_sched_add(s->owner->sched, 00790 whennext / (ast_format_rate(s->fmt->format) / 1000), 00791 ast_fsread_audio, s); 00792 s->lasttimeout = whennext; 00793 return FSREAD_SUCCESS_NOSCHED; 00794 } 00795 return FSREAD_SUCCESS_SCHED; 00796 00797 return_failure: 00798 s->owner->streamid = -1; 00799 #ifdef HAVE_DAHDI 00800 ast_settimeout(s->owner, 0, NULL, NULL); 00801 #endif 00802 return FSREAD_FAILURE; 00803 }
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 995 of file file.c.
References ast_closestream(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), 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().
00996 { 00997 FILE *bfile; 00998 struct ast_format *f; 00999 struct ast_filestream *fs = NULL; 01000 char *fn; 01001 01002 if (AST_LIST_LOCK(&formats)) { 01003 ast_log(LOG_WARNING, "Unable to lock format list\n"); 01004 return NULL; 01005 } 01006 01007 AST_LIST_TRAVERSE(&formats, f, list) { 01008 fs = NULL; 01009 if (!exts_compare(f->exts, type)) 01010 continue; 01011 01012 fn = build_filename(filename, type); 01013 errno = 0; 01014 bfile = fopen(fn, "r"); 01015 if (!bfile || (fs = get_filestream(f, bfile)) == NULL || 01016 open_wrapper(fs) ) { 01017 ast_log(LOG_WARNING, "Unable to open %s\n", fn); 01018 if (fs) { 01019 ast_closestream(fs); 01020 } 01021 fs = NULL; 01022 bfile = NULL; 01023 free(fn); 01024 continue; 01025 } 01026 /* found it */ 01027 fs->trans = NULL; 01028 fs->fmt = f; 01029 fs->flags = flags; 01030 fs->mode = mode; 01031 fs->filename = strdup(filename); 01032 fs->vfs = NULL; 01033 break; 01034 } 01035 01036 AST_LIST_UNLOCK(&formats); 01037 if (!fs) 01038 ast_log(LOG_WARNING, "No such format '%s'\n", type); 01039 01040 return fs; 01041 }
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 734 of file file.c.
References read_frame(), and s.
Referenced by __ast_play_and_record(), cli_audio_convert(), cli_audio_convert_deprecated(), dictate_exec(), gen_readframe(), and moh_files_readframe().
00735 { 00736 int whennext = 0; 00737 00738 return read_frame(s, &whennext); 00739 }
static enum fsread_res ast_readvideo_callback | ( | struct ast_filestream * | s | ) | [static] |
Definition at line 820 of file file.c.
References ast_format_rate(), ast_frfree, ast_fsread_video(), ast_log(), ast_sched_add(), ast_write(), FSREAD_FAILURE, FSREAD_SUCCESS_NOSCHED, FSREAD_SUCCESS_SCHED, LOG_WARNING, read_frame(), and s.
Referenced by ast_fsread_video(), and ast_playstream().
00821 { 00822 int whennext = 0; 00823 00824 while (!whennext) { 00825 struct ast_frame *fr = read_frame(s, &whennext); 00826 00827 if (!fr /* stream complete */ || ast_write(s->owner, fr) /* error writing */) { 00828 if (fr) { 00829 ast_log(LOG_WARNING, "Failed to write frame\n"); 00830 ast_frfree(fr); 00831 } 00832 s->owner->vstreamid = -1; 00833 return FSREAD_FAILURE; 00834 } 00835 00836 if (fr) { 00837 ast_frfree(fr); 00838 } 00839 } 00840 00841 if (whennext != s->lasttimeout) { 00842 s->owner->vstreamid = ast_sched_add(s->owner->sched, 00843 whennext / (ast_format_rate(s->fmt->format) / 1000), 00844 ast_fsread_video, s); 00845 s->lasttimeout = whennext; 00846 return FSREAD_SUCCESS_NOSCHED; 00847 } 00848 00849 return FSREAD_SUCCESS_SCHED; 00850 }
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 883 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 138 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_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_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_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_zh(), 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(), 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().
00139 { 00140 ast_channel_lock(tmp); 00141 00142 /* Stop a running stream if there is one */ 00143 if (tmp->stream) { 00144 ast_closestream(tmp->stream); 00145 tmp->stream = NULL; 00146 if (tmp->oldwriteformat && ast_set_write_format(tmp, tmp->oldwriteformat)) 00147 ast_log(LOG_WARNING, "Unable to restore format back to %d\n", tmp->oldwriteformat); 00148 } 00149 /* Stop the video stream too */ 00150 if (tmp->vstream != NULL) { 00151 ast_closestream(tmp->vstream); 00152 tmp->vstream = NULL; 00153 } 00154 00155 ast_channel_unlock(tmp); 00156 00157 return 0; 00158 }
int ast_stream_and_wait | ( | struct ast_channel * | chan, | |
const char * | file, | |||
const char * | language, | |||
const char * | digits | |||
) |
Definition at line 1351 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_automonitor(), builtin_blindtransfer(), directory_exec(), do_atxfer(), invent_message(), ivr_dispatch(), leave_voicemail(), masq_park_call(), park_exec(), play_mailbox_owner(), play_message_callerid(), play_record_review(), and wait_file2().
01353 { 01354 int res = 0; 01355 if (!ast_strlen_zero(file)) { 01356 res = ast_streamfile(chan, file, language); 01357 if (!res) 01358 res = ast_waitstream(chan, digits); 01359 } 01360 return res; 01361 }
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 898 of file file.c.
References ast_seekstream(), and DEFAULT_SAMPLES_PER_MS.
Referenced by waitstream_core().
00899 { 00900 return ast_seekstream(fs, ms * DEFAULT_SAMPLES_PER_MS, SEEK_CUR); 00901 }
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 903 of file file.c.
References ast_seekstream(), and DEFAULT_SAMPLES_PER_MS.
Referenced by __ast_play_and_record(), handle_recordfile(), and waitstream_core().
00904 { 00905 return ast_seekstream(fs, -ms * DEFAULT_SAMPLES_PER_MS, SEEK_CUR); 00906 }
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 964 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, ast_filestream::fmt, ast_format::format, LOG_DEBUG, LOG_WARNING, ast_channel::name, ast_channel::nativeformats, option_verbose, ast_filestream::orig_chan_name, VERBOSE_PREFIX_3, and ast_filestream::vfs.
Referenced by __login_exec(), agent_call(), 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_ka(), 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_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_zh(), ast_say_enumeration_full_da(), ast_say_enumeration_full_de(), ast_say_enumeration_full_en(), ast_say_enumeration_full_he(), 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_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_zh(), ast_say_time_de(), ast_say_time_en(), ast_say_time_fr(), ast_say_time_gr(), ast_say_time_ka(), ast_say_time_nl(), ast_say_time_zh(), ast_stream_and_wait(), background_detect_exec(), check_availability(), check_beep(), common_exec(), conf_exec(), conf_run(), do_directory(), forward_message(), 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(), sayfile(), ss_thread(), vm_authenticate(), wait_file(), and wait_for_winner().
00965 { 00966 struct ast_filestream *fs; 00967 struct ast_filestream *vfs=NULL; 00968 char fmt[256]; 00969 00970 fs = ast_openstream(chan, filename, preflang); 00971 if (fs) 00972 vfs = ast_openvstream(chan, filename, preflang); 00973 if (vfs) 00974 ast_log(LOG_DEBUG, "Ooh, found a video stream, too, format %s\n", ast_getformatname(vfs->fmt->format)); 00975 if (fs){ 00976 int res; 00977 if (ast_test_flag(chan, AST_FLAG_MASQ_NOSTREAM)) 00978 fs->orig_chan_name = ast_strdup(chan->name); 00979 if (ast_applystream(chan, fs)) 00980 return -1; 00981 if (vfs && ast_applystream(chan, vfs)) 00982 return -1; 00983 res = ast_playstream(fs); 00984 if (!res && vfs) 00985 res = ast_playstream(vfs); 00986 if (option_verbose > 2) 00987 ast_verbose(VERBOSE_PREFIX_3 "<%s> Playing '%s' (language '%s')\n", chan->name, filename, preflang ? preflang : "default"); 00988 00989 return res; 00990 } 00991 ast_log(LOG_WARNING, "Unable to open %s (format %s): %s\n", filename, ast_getformatname_multiple(fmt, sizeof(fmt), chan->nativeformats), strerror(errno)); 00992 return -1; 00993 }
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 893 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 888 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 1324 of file file.c.
References waitstream_core().
Referenced by __login_exec(), agent_call(), announce_thread(), app_exec(), ast_play_and_wait(), ast_say_date_da(), ast_say_date_de(), ast_say_date_en(), ast_say_date_es(), ast_say_date_fr(), ast_say_date_gr(), ast_say_date_he(), ast_say_date_ka(), 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_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_zh(), ast_say_enumeration_full_da(), ast_say_enumeration_full_de(), ast_say_enumeration_full_en(), ast_say_enumeration_full_he(), 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_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_zh(), ast_say_time_de(), ast_say_time_en(), ast_say_time_gr(), ast_say_time_he(), ast_say_time_ka(), ast_say_time_nl(), ast_say_time_zh(), ast_stream_and_wait(), 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().
01325 { 01326 return waitstream_core(c, breakon, NULL, NULL, 0, -1, -1, NULL); 01327 }
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 1335 of file file.c.
References ast_channel::context, and waitstream_core().
Referenced by pbx_builtin_background().
01336 { 01337 /* Waitstream, with return in the case of a valid 1 digit extension */ 01338 /* in the current or specified context being pressed */ 01339 01340 if (!context) 01341 context = c->context; 01342 return waitstream_core(c, NULL, NULL, NULL, 0, 01343 -1, -1, context); 01344 }
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 1318 of file file.c.
References waitstream_core().
Referenced by ast_control_streamfile().
01319 { 01320 return waitstream_core(c, breakon, forward, rewind, ms, 01321 -1 /* no audiofd */, -1 /* no cmdfd */, NULL /* no context */); 01322 }
int ast_waitstream_full | ( | struct ast_channel * | c, | |
const char * | breakon, | |||
int | audiofd, | |||
int | cmdfd | |||
) |
Definition at line 1329 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_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_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_zh(), handle_getoption(), handle_streamfile(), pl_odtworz_plik(), s_streamwait3(), say_character_str_full(), say_digit_str_full(), and say_phonetic_str_full().
01330 { 01331 return waitstream_core(c, breakon, NULL, NULL, 0, 01332 audiofd, cmdfd, NULL /* no context */); 01333 }
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 1043 of file file.c.
References ast_closestream(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_opt_cache_record_files, 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().
01044 { 01045 int fd, myflags = 0; 01046 /* compiler claims this variable can be used before initialization... */ 01047 FILE *bfile = NULL; 01048 struct ast_format *f; 01049 struct ast_filestream *fs = NULL; 01050 char *buf = NULL; 01051 size_t size = 0; 01052 int format_found = 0; 01053 01054 if (AST_LIST_LOCK(&formats)) { 01055 ast_log(LOG_WARNING, "Unable to lock format list\n"); 01056 return NULL; 01057 } 01058 01059 /* set the O_TRUNC flag if and only if there is no O_APPEND specified */ 01060 /* We really can't use O_APPEND as it will break WAV header updates */ 01061 if (flags & O_APPEND) { 01062 flags &= ~O_APPEND; 01063 } else { 01064 myflags = O_TRUNC; 01065 } 01066 01067 myflags |= O_WRONLY | O_CREAT; 01068 01069 /* XXX need to fix this - we should just do the fopen, 01070 * not open followed by fdopen() 01071 */ 01072 AST_LIST_TRAVERSE(&formats, f, list) { 01073 char *fn, *orig_fn = NULL; 01074 if (fs) 01075 break; 01076 01077 if (!exts_compare(f->exts, type)) 01078 continue; 01079 else 01080 format_found = 1; 01081 01082 fn = build_filename(filename, type); 01083 fd = open(fn, flags | myflags, mode); 01084 if (fd > -1) { 01085 /* fdopen() the resulting file stream */ 01086 bfile = fdopen(fd, ((flags | myflags) & O_RDWR) ? "w+" : "w"); 01087 if (!bfile) { 01088 ast_log(LOG_WARNING, "Whoa, fdopen failed: %s!\n", strerror(errno)); 01089 close(fd); 01090 fd = -1; 01091 } 01092 } 01093 01094 if (ast_opt_cache_record_files && (fd > -1)) { 01095 char *c; 01096 01097 fclose(bfile); /* this also closes fd */ 01098 /* 01099 We touch orig_fn just as a place-holder so other things (like vmail) see the file is there. 01100 What we are really doing is writing to record_cache_dir until we are done then we will mv the file into place. 01101 */ 01102 orig_fn = ast_strdupa(fn); 01103 for (c = fn; *c; c++) 01104 if (*c == '/') 01105 *c = '_'; 01106 01107 size = strlen(fn) + strlen(record_cache_dir) + 2; 01108 buf = alloca(size); 01109 strcpy(buf, record_cache_dir); 01110 strcat(buf, "/"); 01111 strcat(buf, fn); 01112 free(fn); 01113 fn = buf; 01114 fd = open(fn, flags | myflags, mode); 01115 if (fd > -1) { 01116 /* fdopen() the resulting file stream */ 01117 bfile = fdopen(fd, ((flags | myflags) & O_RDWR) ? "w+" : "w"); 01118 if (!bfile) { 01119 ast_log(LOG_WARNING, "Whoa, fdopen failed: %s!\n", strerror(errno)); 01120 close(fd); 01121 fd = -1; 01122 } 01123 } 01124 } 01125 if (fd > -1) { 01126 errno = 0; 01127 fs = get_filestream(f, bfile); 01128 if (!fs || rewrite_wrapper(fs, comment)) { 01129 ast_log(LOG_WARNING, "Unable to rewrite %s\n", fn); 01130 close(fd); 01131 if (orig_fn) { 01132 unlink(fn); 01133 unlink(orig_fn); 01134 } 01135 if (fs) { 01136 ast_closestream(fs); 01137 fs = NULL; 01138 } 01139 continue; 01140 } 01141 fs->trans = NULL; 01142 fs->fmt = f; 01143 fs->flags = flags; 01144 fs->mode = mode; 01145 if (orig_fn) { 01146 fs->realfilename = strdup(orig_fn); 01147 fs->filename = strdup(fn); 01148 } else { 01149 fs->realfilename = NULL; 01150 fs->filename = strdup(filename); 01151 } 01152 fs->vfs = NULL; 01153 /* If truncated, we'll be at the beginning; if not truncated, then append */ 01154 f->seek(fs, 0, SEEK_END); 01155 } else if (errno != EEXIST) { 01156 ast_log(LOG_WARNING, "Unable to open file %s: %s\n", fn, strerror(errno)); 01157 if (orig_fn) 01158 unlink(orig_fn); 01159 } 01160 /* if buf != NULL then fn is already free and pointing to it */ 01161 if (!buf) 01162 free(fn); 01163 } 01164 01165 AST_LIST_UNLOCK(&formats); 01166 01167 if (!format_found) 01168 ast_log(LOG_WARNING, "No such format '%s'\n", type); 01169 01170 return fs; 01171 }
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 160 of file file.c.
References AST_FORMAT_MAX_AUDIO, 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_frame::frame_list, 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().
00161 { 00162 int res = -1; 00163 int alt = 0; 00164 if (f->frametype == AST_FRAME_VIDEO) { 00165 if (fs->fmt->format < AST_FORMAT_MAX_AUDIO) { 00166 /* This is the audio portion. Call the video one... */ 00167 if (!fs->vfs && fs->filename) { 00168 const char *type = ast_getformatname(f->subclass & ~0x1); 00169 fs->vfs = ast_writefile(fs->filename, type, NULL, fs->flags, 0, fs->mode); 00170 ast_log(LOG_DEBUG, "Opened video output file\n"); 00171 } 00172 if (fs->vfs) 00173 return ast_writestream(fs->vfs, f); 00174 /* else ignore */ 00175 return 0; 00176 } else { 00177 /* Might / might not have mark set */ 00178 alt = 1; 00179 } 00180 } else if (f->frametype != AST_FRAME_VOICE) { 00181 ast_log(LOG_WARNING, "Tried to write non-voice frame\n"); 00182 return -1; 00183 } 00184 if (((fs->fmt->format | alt) & f->subclass) == f->subclass) { 00185 res = fs->fmt->write(fs, f); 00186 if (res < 0) 00187 ast_log(LOG_WARNING, "Natural write failed\n"); 00188 else if (res > 0) 00189 ast_log(LOG_WARNING, "Huh??\n"); 00190 } else { 00191 /* XXX If they try to send us a type of frame that isn't the normal frame, and isn't 00192 the one we've setup a translator for, we do the "wrong thing" XXX */ 00193 if (fs->trans && f->subclass != fs->lastwriteformat) { 00194 ast_translator_free_path(fs->trans); 00195 fs->trans = NULL; 00196 } 00197 if (!fs->trans) 00198 fs->trans = ast_translator_build_path(fs->fmt->format, f->subclass); 00199 if (!fs->trans) 00200 ast_log(LOG_WARNING, "Unable to translate to format %s, source format %s\n", 00201 fs->fmt->name, ast_getformatname(f->subclass)); 00202 else { 00203 struct ast_frame *trf; 00204 fs->lastwriteformat = f->subclass; 00205 /* Get the translated frame but don't consume the original in case they're using it on another stream */ 00206 if ((trf = ast_translate(fs->trans, f, 0))) { 00207 struct ast_frame *cur; 00208 00209 /* the translator may have returned multiple frames, so process them */ 00210 for (cur = trf; cur; cur = AST_LIST_NEXT(cur, frame_list)) { 00211 if ((res = fs->fmt->write(fs, trf))) { 00212 ast_log(LOG_WARNING, "Translated frame write failed\n"); 00213 break; 00214 } 00215 } 00216 ast_frfree(trf); 00217 } else { 00218 res = 0; 00219 } 00220 } 00221 } 00222 return res; 00223 }
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 268 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().
00269 { 00270 char *fn = NULL; 00271 00272 if (!strcmp(ext, "wav49")) 00273 ext = "WAV"; 00274 00275 if (filename[0] == '/') { 00276 if (asprintf(&fn, "%s.%s", filename, ext) < 0) { 00277 ast_log(LOG_WARNING, "asprintf() failed: %s\n", strerror(errno)); 00278 fn = NULL; 00279 } 00280 } else { 00281 if (asprintf(&fn, "%s/sounds/%s.%s", 00282 ast_config_AST_DATA_DIR, filename, ext) < 0) { 00283 ast_log(LOG_WARNING, "asprintf() failed: %s\n", strerror(errno)); 00284 fn = NULL; 00285 } 00286 } 00287 return fn; 00288 }
static int copy | ( | const char * | infile, | |
const char * | outfile | |||
) | [static] |
Definition at line 225 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().
00226 { 00227 int ifd, ofd, len; 00228 char buf[4096]; /* XXX make it lerger. */ 00229 00230 if ((ifd = open(infile, O_RDONLY)) < 0) { 00231 ast_log(LOG_WARNING, "Unable to open %s in read-only mode\n", infile); 00232 return -1; 00233 } 00234 if ((ofd = open(outfile, O_WRONLY | O_TRUNC | O_CREAT, 0600)) < 0) { 00235 ast_log(LOG_WARNING, "Unable to open %s in write-only mode\n", outfile); 00236 close(ifd); 00237 return -1; 00238 } 00239 while ( (len = read(ifd, buf, sizeof(buf)) ) ) { 00240 int res; 00241 if (len < 0) { 00242 ast_log(LOG_WARNING, "Read failed on %s: %s\n", infile, strerror(errno)); 00243 break; 00244 } 00245 /* XXX handle partial writes */ 00246 res = write(ofd, buf, len); 00247 if (res != len) { 00248 ast_log(LOG_WARNING, "Write failed on %s (%d of %d): %s\n", outfile, res, len, strerror(errno)); 00249 len = -1; /* error marker */ 00250 break; 00251 } 00252 } 00253 close(ifd); 00254 close(ofd); 00255 if (len < 0) { 00256 unlink(outfile); 00257 return -1; /* error */ 00258 } 00259 return 0; /* success */ 00260 }
static int exts_compare | ( | const char * | exts, | |
const char * | type | |||
) | [static] |
Definition at line 292 of file file.c.
References ast_copy_string(), and ext.
Referenced by ast_filehelper(), ast_readfile(), and ast_writefile().
00293 { 00294 char tmp[256]; 00295 char *stringp = tmp, *ext; 00296 00297 ast_copy_string(tmp, exts, sizeof(tmp)); 00298 while ((ext = strsep(&stringp, "|"))) { 00299 if (!strcmp(ext, type)) 00300 return 1; 00301 } 00302 00303 return 0; 00304 }
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 582 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().
00584 { 00585 int res = -1; 00586 char *lang = NULL; 00587 00588 if (buf == NULL) { 00589 return -1; 00590 } 00591 00592 /* We try languages in the following order: 00593 * preflang (may include dialect) 00594 * lang (preflang without dialect - if any) 00595 * <none> 00596 * default (unless the same as preflang or lang without dialect) 00597 */ 00598 00599 /* Try preferred language */ 00600 if (!ast_strlen_zero(preflang)) { 00601 /* try the preflang exactly as it was requested */ 00602 if ((res = fileexists_test(filename, fmt, preflang, buf, buflen)) > 0) { 00603 return res; 00604 } else { 00605 /* try without a dialect */ 00606 char *postfix = NULL; 00607 postfix = lang = ast_strdupa(preflang); 00608 00609 strsep(&postfix, "_"); 00610 if (postfix) { 00611 if ((res = fileexists_test(filename, fmt, lang, buf, buflen)) > 0) { 00612 return res; 00613 } 00614 } 00615 } 00616 } 00617 00618 /* Try without any language */ 00619 if ((res = fileexists_test(filename, fmt, NULL, buf, buflen)) > 0) { 00620 return res; 00621 } 00622 00623 /* Finally try the default language unless it was already tried before */ 00624 if ((ast_strlen_zero(preflang) || strcmp(preflang, DEFAULT_LANGUAGE)) && (ast_strlen_zero(lang) || strcmp(lang, DEFAULT_LANGUAGE))) { 00625 if ((res = fileexists_test(filename, fmt, DEFAULT_LANGUAGE, buf, buflen)) > 0) { 00626 return res; 00627 } 00628 } 00629 00630 return 0; 00631 }
static int fileexists_test | ( | const char * | filename, | |
const char * | fmt, | |||
const char * | lang, | |||
char * | buf, | |||
int | buflen | |||
) | [static] |
Definition at line 545 of file file.c.
References ACTION_EXISTS, ast_filehelper(), is_absolute_path(), and offset.
Referenced by fileexists_core().
00547 { 00548 if (buf == NULL) { 00549 return -1; 00550 } 00551 00552 if (ast_language_is_prefix && !is_absolute_path(filename)) { /* new layout */ 00553 if (lang) { 00554 snprintf(buf, buflen, "%s/%s", lang, filename); 00555 } else { 00556 snprintf(buf, buflen, "%s", filename); 00557 } 00558 } else { /* old layout */ 00559 strcpy(buf, filename); /* first copy the full string */ 00560 if (lang) { 00561 /* insert the language and suffix if needed */ 00562 const char *c = strrchr(filename, '/'); 00563 int offset = c ? c - filename + 1 : 0; /* points right after the last '/' */ 00564 snprintf(buf + offset, buflen - offset, "%s/%s", lang, filename + offset); 00565 } 00566 } 00567 00568 return ast_filehelper(buf, NULL, fmt, ACTION_EXISTS); 00569 }
static void filestream_destructor | ( | void * | arg | ) | [static] |
Definition at line 306 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 get_filestream().
00307 { 00308 char *cmd = NULL; 00309 size_t size = 0; 00310 struct ast_filestream *f = arg; 00311 00312 /* Stop a running stream if there is one */ 00313 if (f->owner) { 00314 if (f->fmt->format < AST_FORMAT_MAX_AUDIO) { 00315 f->owner->stream = NULL; 00316 AST_SCHED_DEL(f->owner->sched, f->owner->streamid); 00317 #ifdef HAVE_DAHDI 00318 ast_settimeout(f->owner, 0, NULL, NULL); 00319 #endif 00320 } else { 00321 f->owner->vstream = NULL; 00322 AST_SCHED_DEL(f->owner->sched, f->owner->vstreamid); 00323 } 00324 } 00325 /* destroy the translator on exit */ 00326 if (f->trans) 00327 ast_translator_free_path(f->trans); 00328 00329 if (f->realfilename && f->filename) { 00330 size = strlen(f->filename) + strlen(f->realfilename) + 15; 00331 cmd = alloca(size); 00332 memset(cmd,0,size); 00333 snprintf(cmd,size,"/bin/mv -f %s %s",f->filename,f->realfilename); 00334 ast_safe_system(cmd); 00335 } 00336 00337 if (f->filename) 00338 free(f->filename); 00339 if (f->realfilename) 00340 free(f->realfilename); 00341 if (f->fmt->close) { 00342 void (*closefn)(struct ast_filestream *) = f->fmt->close; 00343 closefn(f); 00344 } 00345 if (f->f) 00346 fclose(f->f); 00347 if (f->vfs) 00348 ast_closestream(f->vfs); 00349 if (f->orig_chan_name) 00350 free((void *) f->orig_chan_name); 00351 ast_module_unref(f->fmt->module); 00352 }
static int fn_wrapper | ( | struct ast_filestream * | s, | |
const char * | comment, | |||
enum wrap_fn | mode | |||
) | [static] |
Definition at line 378 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().
00379 { 00380 struct ast_format *f = s->fmt; 00381 int ret = -1; 00382 int (*openfn)(struct ast_filestream *s); 00383 00384 if (mode == WRAP_OPEN && (openfn = f->open) && openfn(s)) 00385 ast_log(LOG_WARNING, "Unable to open format %s\n", f->name); 00386 else if (mode == WRAP_REWRITE && f->rewrite && f->rewrite(s, comment)) 00387 ast_log(LOG_WARNING, "Unable to rewrite format %s\n", f->name); 00388 else { 00389 /* preliminary checks succeed. update usecount */ 00390 ast_module_ref(f->module); 00391 ret = 0; 00392 } 00393 return ret; 00394 }
static struct ast_filestream* get_filestream | ( | struct ast_format * | fmt, | |
FILE * | bfile | |||
) | [static] |
Definition at line 354 of file file.c.
References ao2_alloc(), ast_format::buf_size, ast_format::desc_size, filestream_destructor(), ast_filestream::fmt, ast_format::name, and s.
Referenced by ast_filehelper(), ast_readfile(), and ast_writefile().
00355 { 00356 struct ast_filestream *s; 00357 00358 int l = sizeof(*s) + fmt->buf_size + fmt->desc_size; /* total allocation size */ 00359 if ( (s = ao2_alloc(l, filestream_destructor)) == NULL) 00360 return NULL; 00361 s->fmt = fmt; 00362 s->f = bfile; 00363 00364 if (fmt->desc_size) 00365 s->_private = ((char *)(s+1)) + fmt->buf_size; 00366 if (fmt->buf_size) 00367 s->buf = (char *)(s+1); 00368 s->fr.src = fmt->name; 00369 return s; 00370 }
static int is_absolute_path | ( | const char * | filename | ) | [static] |
Definition at line 540 of file file.c.
Referenced by fileexists_test().
00541 { 00542 return filename[0] == '/'; 00543 }
static int open_wrapper | ( | struct ast_filestream * | s | ) | [static] |
Definition at line 401 of file file.c.
References fn_wrapper(), s, and WRAP_OPEN.
Referenced by ast_filehelper(), and ast_readfile().
00402 { 00403 return fn_wrapper(s, NULL, WRAP_OPEN); 00404 }
static struct ast_frame* read_frame | ( | struct ast_filestream * | s, | |
int * | whennext | |||
) | [static] |
Definition at line 709 of file file.c.
References ast_frfree, ast_frisolate(), and s.
Referenced by ast_audiohook_read_frame(), ast_readaudio_callback(), ast_readframe(), and ast_readvideo_callback().
00710 { 00711 struct ast_frame *fr, *new_fr; 00712 00713 if (!s || !s->fmt) { 00714 return NULL; 00715 } 00716 00717 if (!(fr = s->fmt->read(s, whennext))) { 00718 return NULL; 00719 } 00720 00721 if (!(new_fr = ast_frisolate(fr))) { 00722 ast_frfree(fr); 00723 return NULL; 00724 } 00725 00726 if (new_fr != fr) { 00727 ast_frfree(fr); 00728 fr = new_fr; 00729 } 00730 00731 return fr; 00732 }
static int rewrite_wrapper | ( | struct ast_filestream * | s, | |
const char * | comment | |||
) | [static] |
Definition at line 396 of file file.c.
References fn_wrapper(), and s.
Referenced by ast_writefile().
00397 { 00398 return fn_wrapper(s, comment, WRAP_REWRITE); 00399 }
static int show_file_formats | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1363 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, ast_format::list, LOG_WARNING, ast_format::name, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
01364 { 01365 #define FORMAT "%-10s %-10s %-20s\n" 01366 #define FORMAT2 "%-10s %-10s %-20s\n" 01367 struct ast_format *f; 01368 int count_fmt = 0; 01369 01370 if (argc != 4) 01371 return RESULT_SHOWUSAGE; 01372 ast_cli(fd, FORMAT, "Format", "Name", "Extensions"); 01373 01374 if (AST_LIST_LOCK(&formats)) { 01375 ast_log(LOG_WARNING, "Unable to lock format list\n"); 01376 return -1; 01377 } 01378 01379 AST_LIST_TRAVERSE(&formats, f, list) { 01380 ast_cli(fd, FORMAT2, ast_getformatname(f->format), f->name, f->exts); 01381 count_fmt++; 01382 } 01383 AST_LIST_UNLOCK(&formats); 01384 ast_cli(fd, "%d file formats registered.\n", count_fmt); 01385 return RESULT_SUCCESS; 01386 #undef FORMAT 01387 #undef FORMAT2 01388 }
static int show_file_formats_deprecated | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1390 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, ast_format::list, LOG_WARNING, ast_format::name, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
01391 { 01392 #define FORMAT "%-10s %-10s %-20s\n" 01393 #define FORMAT2 "%-10s %-10s %-20s\n" 01394 struct ast_format *f; 01395 int count_fmt = 0; 01396 01397 if (argc != 3) 01398 return RESULT_SHOWUSAGE; 01399 ast_cli(fd, FORMAT, "Format", "Name", "Extensions"); 01400 01401 if (AST_LIST_LOCK(&formats)) { 01402 ast_log(LOG_WARNING, "Unable to lock format list\n"); 01403 return -1; 01404 } 01405 01406 AST_LIST_TRAVERSE(&formats, f, list) { 01407 ast_cli(fd, FORMAT2, ast_getformatname(f->format), f->name, f->exts); 01408 count_fmt++; 01409 } 01410 AST_LIST_UNLOCK(&formats); 01411 ast_cli(fd, "%d file formats registered.\n", count_fmt); 01412 return RESULT_SUCCESS; 01413 #undef FORMAT 01414 #undef FORMAT2 01415 }
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 1176 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_PROCEEDING, AST_CONTROL_PROGRESS, 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_filestream::f, ast_frame::frametype, LOG_WARNING, ast_channel::name, 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().
01179 { 01180 const char *orig_chan_name = NULL; 01181 int err = 0; 01182 01183 if (!breakon) 01184 breakon = ""; 01185 if (!forward) 01186 forward = ""; 01187 if (!rewind) 01188 rewind = ""; 01189 01190 /* Switch the channel to end DTMF frame only. waitstream_core doesn't care about the start of DTMF. */ 01191 ast_set_flag(c, AST_FLAG_END_DTMF_ONLY); 01192 01193 if (ast_test_flag(c, AST_FLAG_MASQ_NOSTREAM)) 01194 orig_chan_name = ast_strdupa(c->name); 01195 01196 while (c->stream) { 01197 int res; 01198 int ms; 01199 01200 if (orig_chan_name && strcasecmp(orig_chan_name, c->name)) { 01201 ast_stopstream(c); 01202 err = 1; 01203 break; 01204 } 01205 01206 ms = ast_sched_wait(c->sched); 01207 01208 if (ms < 0 && !c->timingfunc) { 01209 ast_stopstream(c); 01210 break; 01211 } 01212 if (ms < 0) 01213 ms = 1000; 01214 if (cmdfd < 0) { 01215 res = ast_waitfor(c, ms); 01216 if (res < 0) { 01217 ast_log(LOG_WARNING, "Select failed (%s)\n", strerror(errno)); 01218 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 01219 return res; 01220 } 01221 } else { 01222 int outfd; 01223 struct ast_channel *rchan = ast_waitfor_nandfds(&c, 1, &cmdfd, (cmdfd > -1) ? 1 : 0, NULL, &outfd, &ms); 01224 if (!rchan && (outfd < 0) && (ms)) { 01225 /* Continue */ 01226 if (errno == EINTR) 01227 continue; 01228 ast_log(LOG_WARNING, "Wait failed (%s)\n", strerror(errno)); 01229 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 01230 return -1; 01231 } else if (outfd > -1) { /* this requires cmdfd set */ 01232 /* The FD we were watching has something waiting */ 01233 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 01234 return 1; 01235 } 01236 /* if rchan is set, it is 'c' */ 01237 res = rchan ? 1 : 0; /* map into 'res' values */ 01238 } 01239 if (res > 0) { 01240 struct ast_frame *fr = ast_read(c); 01241 if (!fr) { 01242 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 01243 return -1; 01244 } 01245 switch(fr->frametype) { 01246 case AST_FRAME_DTMF_END: 01247 if (context) { 01248 const char exten[2] = { fr->subclass, '\0' }; 01249 if (ast_exists_extension(c, context, exten, 1, c->cid.cid_num)) { 01250 res = fr->subclass; 01251 ast_frfree(fr); 01252 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 01253 return res; 01254 } 01255 } else { 01256 res = fr->subclass; 01257 if (strchr(forward,res)) { 01258 int eoftest; 01259 ast_stream_fastforward(c->stream, skip_ms); 01260 eoftest = fgetc(c->stream->f); 01261 if (feof(c->stream->f)) { 01262 ast_stream_rewind(c->stream, skip_ms); 01263 } else { 01264 ungetc(eoftest, c->stream->f); 01265 } 01266 } else if (strchr(rewind,res)) { 01267 ast_stream_rewind(c->stream, skip_ms); 01268 } else if (strchr(breakon, res)) { 01269 ast_frfree(fr); 01270 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 01271 return res; 01272 } 01273 } 01274 break; 01275 case AST_FRAME_CONTROL: 01276 switch(fr->subclass) { 01277 case AST_CONTROL_HANGUP: 01278 case AST_CONTROL_BUSY: 01279 case AST_CONTROL_CONGESTION: 01280 ast_frfree(fr); 01281 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 01282 return -1; 01283 case AST_CONTROL_RINGING: 01284 case AST_CONTROL_ANSWER: 01285 case AST_CONTROL_VIDUPDATE: 01286 case AST_CONTROL_SRCUPDATE: 01287 case AST_CONTROL_HOLD: 01288 case AST_CONTROL_UNHOLD: 01289 case AST_CONTROL_PROGRESS: 01290 case AST_CONTROL_PROCEEDING: 01291 /* Unimportant */ 01292 break; 01293 default: 01294 ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", fr->subclass); 01295 } 01296 break; 01297 case AST_FRAME_VOICE: 01298 /* Write audio if appropriate */ 01299 if (audiofd > -1) { 01300 if (write(audiofd, fr->data, fr->datalen) < 0) { 01301 ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno)); 01302 } 01303 } 01304 default: 01305 /* Ignore all others */ 01306 break; 01307 } 01308 ast_frfree(fr); 01309 } 01310 ast_sched_runq(c->sched); 01311 } 01312 01313 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 01314 01315 return (err || c->_softhangup) ? -1 : 0; 01316 }
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 1426 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[] |