#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) |
void | ast_filestream_frame_freed (struct ast_frame *fr) |
destroy a filestream using an ast_frame as input | |
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 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 722 of file file.c.
00722 { 00723 FSREAD_FAILURE, 00724 FSREAD_SUCCESS_SCHED, 00725 FSREAD_SUCCESS_NOSCHED, 00726 };
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 848 of file file.c.
References s.
Referenced by ast_streamfile(), handle_getoption(), handle_recordfile(), handle_streamfile(), and speech_streamfile().
00849 { 00850 s->owner = chan; 00851 return 0; 00852 }
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 891 of file file.c.
References ao2_ref(), AST_FRFLAG_FROM_FILESTREAM, ast_test_flag, and f.
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().
00892 { 00893 00894 if (ast_test_flag(&f->fr, AST_FRFLAG_FROM_FILESTREAM)) { 00895 /* If this flag is still set, it essentially means that the reference 00896 * count of f is non-zero. We can't destroy this filestream until 00897 * whatever is using the filestream's frame has finished. 00898 * 00899 * Since this was called, however, we need to remove the reference from 00900 * when this filestream was first allocated. That way, when the embedded 00901 * frame is freed, the refcount will reach 0 and we can finish destroying 00902 * this filestream properly. 00903 */ 00904 ao2_ref(f, -1); 00905 return 0; 00906 } 00907 00908 ao2_ref(f, -1); 00909 return 0; 00910 }
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 1424 of file file.c.
References ast_cli_register_multiple(), and cli_file.
Referenced by main().
01425 { 01426 ast_cli_register_multiple(cli_file, sizeof(cli_file) / sizeof(struct ast_cli_entry)); 01427 return 0; 01428 }
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 940 of file file.c.
References ast_filehelper().
Referenced by copy_plain_file(), and vm_forwardoptions().
00941 { 00942 return ast_filehelper(filename, filename2, fmt, ACTION_COPY); 00943 }
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 930 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().
00931 { 00932 return ast_filehelper(filename, NULL, fmt, ACTION_DELETE); 00933 }
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 916 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().
00917 { 00918 char *buf; 00919 int buflen; 00920 00921 if (preflang == NULL) 00922 preflang = ""; 00923 buflen = strlen(preflang) + strlen(filename) + 4; /* room for everything */ 00924 buf = alloca(buflen); 00925 if (buf == NULL) 00926 return 0; 00927 return fileexists_core(filename, fmt, preflang, buf, buflen); 00928 }
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 935 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().
00936 { 00937 return ast_filehelper(filename, filename2, fmt, ACTION_RENAME); 00938 }
void ast_filestream_frame_freed | ( | struct ast_frame * | fr | ) |
destroy a filestream using an ast_frame as input
This is a hack that is used also by the ast_trans_pvt and ast_dsp structures. When a structure contains an ast_frame pointer as one of its fields. It may be that the frame is still used after the outer structure is freed. This leads to invalid memory accesses. This function allows for us to hold off on destroying the ast_filestream until we are done using the ast_frame pointer that is part of it
fr | The ast_frame that is part of an ast_filestream we wish to free. |
Definition at line 1327 of file file.c.
References ao2_ref(), ast_clear_flag, AST_FRFLAG_FROM_FILESTREAM, and ast_filestream::fr.
Referenced by __frame_free().
01328 { 01329 struct ast_filestream *fs; 01330 01331 ast_clear_flag(fr, AST_FRFLAG_FROM_FILESTREAM); 01332 01333 fs = (struct ast_filestream *) (((char *) fr) - offsetof(struct ast_filestream, fr)); 01334 01335 ao2_ref(fs, -1); 01336 }
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 786 of file file.c.
References ast_readaudio_callback(), and FSREAD_SUCCESS_SCHED.
Referenced by ast_readaudio_callback().
00787 { 00788 struct ast_filestream *fs = (struct ast_filestream *)data; 00789 enum fsread_res res; 00790 00791 res = ast_readaudio_callback(fs); 00792 00793 if (res == FSREAD_SUCCESS_SCHED) 00794 return 1; 00795 00796 return 0; 00797 }
static int ast_fsread_video | ( | const void * | data | ) | [static] |
Definition at line 835 of file file.c.
References ast_readvideo_callback(), and FSREAD_SUCCESS_SCHED.
Referenced by ast_readvideo_callback().
00836 { 00837 struct ast_filestream *fs = (struct ast_filestream *)data; 00838 enum fsread_res res; 00839 00840 res = ast_readvideo_callback(fs); 00841 00842 if (res == FSREAD_SUCCESS_SCHED) 00843 return 1; 00844 00845 return 0; 00846 }
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 854 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().
00855 { 00856 enum fsread_res res; 00857 00858 if (s->fmt->format < AST_FORMAT_MAX_AUDIO) 00859 res = ast_readaudio_callback(s); 00860 else 00861 res = ast_readvideo_callback(s); 00862 00863 return (res == FSREAD_FAILURE) ? -1 : 0; 00864 }
static enum fsread_res ast_readaudio_callback | ( | struct ast_filestream * | s | ) | [static] |
Definition at line 730 of file file.c.
References ao2_ref(), ast_format_rate(), AST_FRFLAG_FROM_FILESTREAM, ast_frfree, ast_fsread_audio(), ast_log(), ast_sched_add(), ast_set_flag, ast_settimeout(), ast_write(), FSREAD_FAILURE, FSREAD_SUCCESS_NOSCHED, FSREAD_SUCCESS_SCHED, LOG_WARNING, and s.
Referenced by ast_fsread_audio(), and ast_playstream().
00731 { 00732 int whennext = 0; 00733 00734 while (!whennext) { 00735 struct ast_frame *fr; 00736 00737 if (s->orig_chan_name && strcasecmp(s->owner->name, s->orig_chan_name)) 00738 goto return_failure; 00739 00740 fr = s->fmt->read(s, &whennext); 00741 if (fr) { 00742 ast_set_flag(fr, AST_FRFLAG_FROM_FILESTREAM); 00743 ao2_ref(s, +1); 00744 } 00745 if (!fr /* stream complete */ || ast_write(s->owner, fr) /* error writing */) { 00746 if (fr) { 00747 ast_log(LOG_WARNING, "Failed to write frame\n"); 00748 ast_frfree(fr); 00749 } 00750 goto return_failure; 00751 } 00752 if (fr) { 00753 ast_frfree(fr); 00754 } 00755 } 00756 if (whennext != s->lasttimeout) { 00757 #ifdef HAVE_DAHDI 00758 if (s->owner->timingfd > -1) { 00759 int zap_timer_samples = whennext; 00760 int rate; 00761 /* whennext is in samples, but DAHDI timers operate in 8 kHz samples. */ 00762 if ((rate = ast_format_rate(s->fmt->format)) != 8000) { 00763 float factor; 00764 factor = ((float) rate) / ((float) 8000.0); 00765 zap_timer_samples = (int) ( ((float) zap_timer_samples) / factor ); 00766 } 00767 ast_settimeout(s->owner, zap_timer_samples, ast_fsread_audio, s); 00768 } else 00769 #endif 00770 s->owner->streamid = ast_sched_add(s->owner->sched, 00771 whennext / (ast_format_rate(s->fmt->format) / 1000), 00772 ast_fsread_audio, s); 00773 s->lasttimeout = whennext; 00774 return FSREAD_SUCCESS_NOSCHED; 00775 } 00776 return FSREAD_SUCCESS_SCHED; 00777 00778 return_failure: 00779 s->owner->streamid = -1; 00780 #ifdef HAVE_DAHDI 00781 ast_settimeout(s->owner, 0, NULL, NULL); 00782 #endif 00783 return FSREAD_FAILURE; 00784 }
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 976 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().
00977 { 00978 FILE *bfile; 00979 struct ast_format *f; 00980 struct ast_filestream *fs = NULL; 00981 char *fn; 00982 00983 if (AST_LIST_LOCK(&formats)) { 00984 ast_log(LOG_WARNING, "Unable to lock format list\n"); 00985 return NULL; 00986 } 00987 00988 AST_LIST_TRAVERSE(&formats, f, list) { 00989 fs = NULL; 00990 if (!exts_compare(f->exts, type)) 00991 continue; 00992 00993 fn = build_filename(filename, type); 00994 errno = 0; 00995 bfile = fopen(fn, "r"); 00996 if (!bfile || (fs = get_filestream(f, bfile)) == NULL || 00997 open_wrapper(fs) ) { 00998 ast_log(LOG_WARNING, "Unable to open %s\n", fn); 00999 if (fs) { 01000 ast_closestream(fs); 01001 } 01002 fs = NULL; 01003 bfile = NULL; 01004 free(fn); 01005 continue; 01006 } 01007 /* found it */ 01008 fs->trans = NULL; 01009 fs->fmt = f; 01010 fs->flags = flags; 01011 fs->mode = mode; 01012 fs->filename = strdup(filename); 01013 fs->vfs = NULL; 01014 break; 01015 } 01016 01017 AST_LIST_UNLOCK(&formats); 01018 if (!fs) 01019 ast_log(LOG_WARNING, "No such format '%s'\n", type); 01020 01021 return fs; 01022 }
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 709 of file file.c.
References ao2_ref(), AST_FRFLAG_FROM_FILESTREAM, ast_set_flag, f, and s.
Referenced by __ast_play_and_record(), cli_audio_convert(), cli_audio_convert_deprecated(), dictate_exec(), gen_readframe(), and moh_files_readframe().
00710 { 00711 struct ast_frame *f = NULL; 00712 int whennext = 0; 00713 if (s && s->fmt) 00714 f = s->fmt->read(s, &whennext); 00715 if (f) { 00716 ast_set_flag(f, AST_FRFLAG_FROM_FILESTREAM); 00717 ao2_ref(s, +1); 00718 } 00719 return f; 00720 }
static enum fsread_res ast_readvideo_callback | ( | struct ast_filestream * | s | ) | [static] |
Definition at line 801 of file file.c.
References ao2_ref(), ast_format_rate(), AST_FRFLAG_FROM_FILESTREAM, ast_frfree, ast_fsread_video(), ast_log(), ast_sched_add(), ast_set_flag, ast_write(), FSREAD_FAILURE, FSREAD_SUCCESS_NOSCHED, FSREAD_SUCCESS_SCHED, LOG_WARNING, and s.
Referenced by ast_fsread_video(), and ast_playstream().
00802 { 00803 int whennext = 0; 00804 00805 while (!whennext) { 00806 struct ast_frame *fr = s->fmt->read(s, &whennext); 00807 if (fr) { 00808 ast_set_flag(fr, AST_FRFLAG_FROM_FILESTREAM); 00809 ao2_ref(s, +1); 00810 } 00811 if (!fr /* stream complete */ || ast_write(s->owner, fr) /* error writing */) { 00812 if (fr) { 00813 ast_log(LOG_WARNING, "Failed to write frame\n"); 00814 ast_frfree(fr); 00815 } 00816 s->owner->vstreamid = -1; 00817 return FSREAD_FAILURE; 00818 } 00819 if (fr) { 00820 ast_frfree(fr); 00821 } 00822 } 00823 00824 if (whennext != s->lasttimeout) { 00825 s->owner->vstreamid = ast_sched_add(s->owner->sched, 00826 whennext / (ast_format_rate(s->fmt->format) / 1000), 00827 ast_fsread_video, s); 00828 s->lasttimeout = whennext; 00829 return FSREAD_SUCCESS_NOSCHED; 00830 } 00831 00832 return FSREAD_SUCCESS_SCHED; 00833 }
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 866 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 1343 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().
01345 { 01346 int res = 0; 01347 if (!ast_strlen_zero(file)) { 01348 res = ast_streamfile(chan, file, language); 01349 if (!res) 01350 res = ast_waitstream(chan, digits); 01351 } 01352 return res; 01353 }
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 881 of file file.c.
References ast_seekstream(), and DEFAULT_SAMPLES_PER_MS.
Referenced by waitstream_core().
00882 { 00883 return ast_seekstream(fs, ms * DEFAULT_SAMPLES_PER_MS, SEEK_CUR); 00884 }
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 886 of file file.c.
References ast_seekstream(), and DEFAULT_SAMPLES_PER_MS.
Referenced by __ast_play_and_record(), handle_recordfile(), and waitstream_core().
00887 { 00888 return ast_seekstream(fs, -ms * DEFAULT_SAMPLES_PER_MS, SEEK_CUR); 00889 }
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 945 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().
00946 { 00947 struct ast_filestream *fs; 00948 struct ast_filestream *vfs=NULL; 00949 char fmt[256]; 00950 00951 fs = ast_openstream(chan, filename, preflang); 00952 if (fs) 00953 vfs = ast_openvstream(chan, filename, preflang); 00954 if (vfs) 00955 ast_log(LOG_DEBUG, "Ooh, found a video stream, too, format %s\n", ast_getformatname(vfs->fmt->format)); 00956 if (fs){ 00957 int res; 00958 if (ast_test_flag(chan, AST_FLAG_MASQ_NOSTREAM)) 00959 fs->orig_chan_name = ast_strdup(chan->name); 00960 if (ast_applystream(chan, fs)) 00961 return -1; 00962 if (vfs && ast_applystream(chan, vfs)) 00963 return -1; 00964 res = ast_playstream(fs); 00965 if (!res && vfs) 00966 res = ast_playstream(vfs); 00967 if (option_verbose > 2) 00968 ast_verbose(VERBOSE_PREFIX_3 "<%s> Playing '%s' (language '%s')\n", chan->name, filename, preflang ? preflang : "default"); 00969 00970 return res; 00971 } 00972 ast_log(LOG_WARNING, "Unable to open %s (format %s): %s\n", filename, ast_getformatname_multiple(fmt, sizeof(fmt), chan->nativeformats), strerror(errno)); 00973 return -1; 00974 }
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 876 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 871 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 1305 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().
01306 { 01307 return waitstream_core(c, breakon, NULL, NULL, 0, -1, -1, NULL); 01308 }
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 1316 of file file.c.
References ast_channel::context, and waitstream_core().
Referenced by pbx_builtin_background().
01317 { 01318 /* Waitstream, with return in the case of a valid 1 digit extension */ 01319 /* in the current or specified context being pressed */ 01320 01321 if (!context) 01322 context = c->context; 01323 return waitstream_core(c, NULL, NULL, NULL, 0, 01324 -1, -1, context); 01325 }
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 1299 of file file.c.
References waitstream_core().
Referenced by ast_control_streamfile().
01300 { 01301 return waitstream_core(c, breakon, forward, rewind, ms, 01302 -1 /* no audiofd */, -1 /* no cmdfd */, NULL /* no context */); 01303 }
int ast_waitstream_full | ( | struct ast_channel * | c, | |
const char * | breakon, | |||
int | audiofd, | |||
int | cmdfd | |||
) |
Definition at line 1310 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().
01311 { 01312 return waitstream_core(c, breakon, NULL, NULL, 0, 01313 audiofd, cmdfd, NULL /* no context */); 01314 }
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 1024 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().
01025 { 01026 int fd, myflags = 0; 01027 /* compiler claims this variable can be used before initialization... */ 01028 FILE *bfile = NULL; 01029 struct ast_format *f; 01030 struct ast_filestream *fs = NULL; 01031 char *buf = NULL; 01032 size_t size = 0; 01033 int format_found = 0; 01034 01035 if (AST_LIST_LOCK(&formats)) { 01036 ast_log(LOG_WARNING, "Unable to lock format list\n"); 01037 return NULL; 01038 } 01039 01040 /* set the O_TRUNC flag if and only if there is no O_APPEND specified */ 01041 /* We really can't use O_APPEND as it will break WAV header updates */ 01042 if (flags & O_APPEND) { 01043 flags &= ~O_APPEND; 01044 } else { 01045 myflags = O_TRUNC; 01046 } 01047 01048 myflags |= O_WRONLY | O_CREAT; 01049 01050 /* XXX need to fix this - we should just do the fopen, 01051 * not open followed by fdopen() 01052 */ 01053 AST_LIST_TRAVERSE(&formats, f, list) { 01054 char *fn, *orig_fn = NULL; 01055 if (fs) 01056 break; 01057 01058 if (!exts_compare(f->exts, type)) 01059 continue; 01060 else 01061 format_found = 1; 01062 01063 fn = build_filename(filename, type); 01064 fd = open(fn, flags | myflags, mode); 01065 if (fd > -1) { 01066 /* fdopen() the resulting file stream */ 01067 bfile = fdopen(fd, ((flags | myflags) & O_RDWR) ? "w+" : "w"); 01068 if (!bfile) { 01069 ast_log(LOG_WARNING, "Whoa, fdopen failed: %s!\n", strerror(errno)); 01070 close(fd); 01071 fd = -1; 01072 } 01073 } 01074 01075 if (ast_opt_cache_record_files && (fd > -1)) { 01076 char *c; 01077 01078 fclose(bfile); /* this also closes fd */ 01079 /* 01080 We touch orig_fn just as a place-holder so other things (like vmail) see the file is there. 01081 What we are really doing is writing to record_cache_dir until we are done then we will mv the file into place. 01082 */ 01083 orig_fn = ast_strdupa(fn); 01084 for (c = fn; *c; c++) 01085 if (*c == '/') 01086 *c = '_'; 01087 01088 size = strlen(fn) + strlen(record_cache_dir) + 2; 01089 buf = alloca(size); 01090 strcpy(buf, record_cache_dir); 01091 strcat(buf, "/"); 01092 strcat(buf, fn); 01093 free(fn); 01094 fn = buf; 01095 fd = open(fn, flags | myflags, mode); 01096 if (fd > -1) { 01097 /* fdopen() the resulting file stream */ 01098 bfile = fdopen(fd, ((flags | myflags) & O_RDWR) ? "w+" : "w"); 01099 if (!bfile) { 01100 ast_log(LOG_WARNING, "Whoa, fdopen failed: %s!\n", strerror(errno)); 01101 close(fd); 01102 fd = -1; 01103 } 01104 } 01105 } 01106 if (fd > -1) { 01107 errno = 0; 01108 fs = get_filestream(f, bfile); 01109 if (!fs || rewrite_wrapper(fs, comment)) { 01110 ast_log(LOG_WARNING, "Unable to rewrite %s\n", fn); 01111 close(fd); 01112 if (orig_fn) { 01113 unlink(fn); 01114 unlink(orig_fn); 01115 } 01116 if (fs) { 01117 ast_closestream(fs); 01118 fs = NULL; 01119 } 01120 continue; 01121 } 01122 fs->trans = NULL; 01123 fs->fmt = f; 01124 fs->flags = flags; 01125 fs->mode = mode; 01126 if (orig_fn) { 01127 fs->realfilename = strdup(orig_fn); 01128 fs->filename = strdup(fn); 01129 } else { 01130 fs->realfilename = NULL; 01131 fs->filename = strdup(filename); 01132 } 01133 fs->vfs = NULL; 01134 /* If truncated, we'll be at the beginning; if not truncated, then append */ 01135 f->seek(fs, 0, SEEK_END); 01136 } else if (errno != EEXIST) { 01137 ast_log(LOG_WARNING, "Unable to open file %s: %s\n", fn, strerror(errno)); 01138 if (orig_fn) 01139 unlink(orig_fn); 01140 } 01141 /* if buf != NULL then fn is already free and pointing to it */ 01142 if (!buf) 01143 free(fn); 01144 } 01145 01146 AST_LIST_UNLOCK(&formats); 01147 01148 if (!format_found) 01149 ast_log(LOG_WARNING, "No such format '%s'\n", type); 01150 01151 return fs; 01152 }
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 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 1355 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.
01356 { 01357 #define FORMAT "%-10s %-10s %-20s\n" 01358 #define FORMAT2 "%-10s %-10s %-20s\n" 01359 struct ast_format *f; 01360 int count_fmt = 0; 01361 01362 if (argc != 4) 01363 return RESULT_SHOWUSAGE; 01364 ast_cli(fd, FORMAT, "Format", "Name", "Extensions"); 01365 01366 if (AST_LIST_LOCK(&formats)) { 01367 ast_log(LOG_WARNING, "Unable to lock format list\n"); 01368 return -1; 01369 } 01370 01371 AST_LIST_TRAVERSE(&formats, f, list) { 01372 ast_cli(fd, FORMAT2, ast_getformatname(f->format), f->name, f->exts); 01373 count_fmt++; 01374 } 01375 AST_LIST_UNLOCK(&formats); 01376 ast_cli(fd, "%d file formats registered.\n", count_fmt); 01377 return RESULT_SUCCESS; 01378 #undef FORMAT 01379 #undef FORMAT2 01380 }
static int show_file_formats_deprecated | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1382 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.
01383 { 01384 #define FORMAT "%-10s %-10s %-20s\n" 01385 #define FORMAT2 "%-10s %-10s %-20s\n" 01386 struct ast_format *f; 01387 int count_fmt = 0; 01388 01389 if (argc != 3) 01390 return RESULT_SHOWUSAGE; 01391 ast_cli(fd, FORMAT, "Format", "Name", "Extensions"); 01392 01393 if (AST_LIST_LOCK(&formats)) { 01394 ast_log(LOG_WARNING, "Unable to lock format list\n"); 01395 return -1; 01396 } 01397 01398 AST_LIST_TRAVERSE(&formats, f, list) { 01399 ast_cli(fd, FORMAT2, ast_getformatname(f->format), f->name, f->exts); 01400 count_fmt++; 01401 } 01402 AST_LIST_UNLOCK(&formats); 01403 ast_cli(fd, "%d file formats registered.\n", count_fmt); 01404 return RESULT_SUCCESS; 01405 #undef FORMAT 01406 #undef FORMAT2 01407 }
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 1157 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().
01160 { 01161 const char *orig_chan_name = NULL; 01162 int err = 0; 01163 01164 if (!breakon) 01165 breakon = ""; 01166 if (!forward) 01167 forward = ""; 01168 if (!rewind) 01169 rewind = ""; 01170 01171 /* Switch the channel to end DTMF frame only. waitstream_core doesn't care about the start of DTMF. */ 01172 ast_set_flag(c, AST_FLAG_END_DTMF_ONLY); 01173 01174 if (ast_test_flag(c, AST_FLAG_MASQ_NOSTREAM)) 01175 orig_chan_name = ast_strdupa(c->name); 01176 01177 while (c->stream) { 01178 int res; 01179 int ms; 01180 01181 if (orig_chan_name && strcasecmp(orig_chan_name, c->name)) { 01182 ast_stopstream(c); 01183 err = 1; 01184 break; 01185 } 01186 01187 ms = ast_sched_wait(c->sched); 01188 01189 if (ms < 0 && !c->timingfunc) { 01190 ast_stopstream(c); 01191 break; 01192 } 01193 if (ms < 0) 01194 ms = 1000; 01195 if (cmdfd < 0) { 01196 res = ast_waitfor(c, ms); 01197 if (res < 0) { 01198 ast_log(LOG_WARNING, "Select failed (%s)\n", strerror(errno)); 01199 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 01200 return res; 01201 } 01202 } else { 01203 int outfd; 01204 struct ast_channel *rchan = ast_waitfor_nandfds(&c, 1, &cmdfd, (cmdfd > -1) ? 1 : 0, NULL, &outfd, &ms); 01205 if (!rchan && (outfd < 0) && (ms)) { 01206 /* Continue */ 01207 if (errno == EINTR) 01208 continue; 01209 ast_log(LOG_WARNING, "Wait failed (%s)\n", strerror(errno)); 01210 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 01211 return -1; 01212 } else if (outfd > -1) { /* this requires cmdfd set */ 01213 /* The FD we were watching has something waiting */ 01214 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 01215 return 1; 01216 } 01217 /* if rchan is set, it is 'c' */ 01218 res = rchan ? 1 : 0; /* map into 'res' values */ 01219 } 01220 if (res > 0) { 01221 struct ast_frame *fr = ast_read(c); 01222 if (!fr) { 01223 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 01224 return -1; 01225 } 01226 switch(fr->frametype) { 01227 case AST_FRAME_DTMF_END: 01228 if (context) { 01229 const char exten[2] = { fr->subclass, '\0' }; 01230 if (ast_exists_extension(c, context, exten, 1, c->cid.cid_num)) { 01231 res = fr->subclass; 01232 ast_frfree(fr); 01233 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 01234 return res; 01235 } 01236 } else { 01237 res = fr->subclass; 01238 if (strchr(forward,res)) { 01239 int eoftest; 01240 ast_stream_fastforward(c->stream, skip_ms); 01241 eoftest = fgetc(c->stream->f); 01242 if (feof(c->stream->f)) { 01243 ast_stream_rewind(c->stream, skip_ms); 01244 } else { 01245 ungetc(eoftest, c->stream->f); 01246 } 01247 } else if (strchr(rewind,res)) { 01248 ast_stream_rewind(c->stream, skip_ms); 01249 } else if (strchr(breakon, res)) { 01250 ast_frfree(fr); 01251 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 01252 return res; 01253 } 01254 } 01255 break; 01256 case AST_FRAME_CONTROL: 01257 switch(fr->subclass) { 01258 case AST_CONTROL_HANGUP: 01259 case AST_CONTROL_BUSY: 01260 case AST_CONTROL_CONGESTION: 01261 ast_frfree(fr); 01262 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 01263 return -1; 01264 case AST_CONTROL_RINGING: 01265 case AST_CONTROL_ANSWER: 01266 case AST_CONTROL_VIDUPDATE: 01267 case AST_CONTROL_SRCUPDATE: 01268 case AST_CONTROL_HOLD: 01269 case AST_CONTROL_UNHOLD: 01270 case AST_CONTROL_PROGRESS: 01271 case AST_CONTROL_PROCEEDING: 01272 /* Unimportant */ 01273 break; 01274 default: 01275 ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", fr->subclass); 01276 } 01277 break; 01278 case AST_FRAME_VOICE: 01279 /* Write audio if appropriate */ 01280 if (audiofd > -1) { 01281 if (write(audiofd, fr->data, fr->datalen) < 0) { 01282 ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno)); 01283 } 01284 } 01285 default: 01286 /* Ignore all others */ 01287 break; 01288 } 01289 ast_frfree(fr); 01290 } 01291 ast_sched_runq(c->sched); 01292 } 01293 01294 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 01295 01296 return (err || c->_softhangup) ? -1 : 0; 01297 }
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 1418 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[] |