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