Generic File Format Support. More...
#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) |
struct ast_filestream * | ast_openstream (struct ast_channel *chan, const char *filename, const char *preflang) |
Opens stream for use in seeking, playing. | |
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. | |
struct 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) |
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. | |
struct 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) |
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. | |
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 void | file_shutdown (void) |
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 [] |
Generic File Format Support.
Definition in file file.c.
#define FORMAT "%-10s %-10s %-20s\n" |
#define FORMAT2 "%-10s %-10s %-20s\n" |
enum file_action |
Definition at line 412 of file file.c.
00412 { 00413 ACTION_EXISTS = 1, /* return matching format if file exists, 0 otherwise */ 00414 ACTION_DELETE, /* delete file, return 0 on success, -1 on error */ 00415 ACTION_RENAME, /* rename file. return 0 on success, -1 on error */ 00416 ACTION_OPEN, 00417 ACTION_COPY /* copy file. return 0 on success, -1 on error */ 00418 };
enum fsread_res |
Definition at line 744 of file file.c.
00744 { 00745 FSREAD_FAILURE, 00746 FSREAD_SUCCESS_SCHED, 00747 FSREAD_SUCCESS_NOSCHED, 00748 };
enum wrap_fn |
Definition at line 382 of file file.c.
00382 { WRAP_OPEN, WRAP_REWRITE };
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, 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 861 of file file.c.
References ast_filestream::owner.
Referenced by ast_streamfile(), handle_getoption(), handle_recordfile(), handle_streamfile(), and speech_streamfile().
00862 { 00863 s->owner = chan; 00864 return 0; 00865 }
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 904 of file file.c.
References ao2_ref, and filestream_close().
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(), dictate_exec(), filestream_destructor(), gen_closestream(), handle_cli_file_convert(), handle_recordfile(), local_ast_moh_stop(), mixmonitor_ds_close_fs(), moh_files_release(), record_exec(), and recordthread().
00905 { 00906 /* This used to destroy the filestream, but it now just decrements a refcount. 00907 * We close the stream in order to quit queuing frames now, because we might 00908 * change the writeformat, which could result in a subsequent write error, if 00909 * the format is different. */ 00910 filestream_close(f); 00911 ao2_ref(f, -1); 00912 return 0; 00913 }
int ast_file_init | ( | void | ) |
Provided by file.c
Definition at line 1503 of file file.c.
References ARRAY_LEN, ast_cli_register_multiple(), ast_register_atexit(), and file_shutdown().
Referenced by main().
01504 { 01505 ast_cli_register_multiple(cli_file, ARRAY_LEN(cli_file)); 01506 ast_register_atexit(file_shutdown); 01507 return 0; 01508 }
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 941 of file file.c.
References ACTION_COPY, and ast_filehelper().
Referenced by copy_plain_file(), and vm_forwardoptions().
00942 { 00943 return ast_filehelper(filename, filename2, fmt, ACTION_COPY); 00944 }
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 931 of file file.c.
References ACTION_DELETE, and ast_filehelper().
Referenced by __ast_play_and_record(), announce_thread(), ast_monitor_start(), ast_monitor_stop(), conf_free(), conf_run(), dial_exec_full(), handle_cli_file_convert(), leave_voicemail(), play_record_review(), record_exec(), setup_privacy_args(), and vm_delete().
00932 { 00933 return ast_filehelper(filename, NULL, fmt, ACTION_DELETE); 00934 }
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 919 of file file.c.
References ast_alloca, ast_filestream::buf, and fileexists_core().
Referenced by announce_thread(), app_exec(), ast_moh_files_next(), ast_monitor_start(), ast_monitor_stop(), common_exec(), dial_exec_full(), eivr_comm(), forward_message(), get_folder(), invent_message(), leave_voicemail(), meetme_menu_admin_extended(), 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().
00920 { 00921 char *buf; 00922 int buflen; 00923 00924 if (preflang == NULL) 00925 preflang = ""; 00926 buflen = strlen(preflang) + strlen(filename) + 4; /* room for everything */ 00927 buf = ast_alloca(buflen); 00928 return fileexists_core(filename, fmt, preflang, buf, buflen); 00929 }
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 429 of file file.c.
References ACTION_COPY, 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, 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().
00430 { 00431 struct ast_format *f; 00432 format_t res = (action == ACTION_EXISTS) ? 0 : -1; 00433 00434 AST_RWLIST_RDLOCK(&formats); 00435 /* Check for a specific format */ 00436 AST_RWLIST_TRAVERSE(&formats, f, list) { 00437 char *stringp, *ext = NULL; 00438 00439 if (fmt && !exts_compare(f->exts, fmt)) 00440 continue; 00441 00442 /* Look for a file matching the supported extensions. 00443 * The file must exist, and for OPEN, must match 00444 * one of the formats supported by the channel. 00445 */ 00446 stringp = ast_strdupa(f->exts); /* this is in the stack so does not need to be freed */ 00447 while ( (ext = strsep(&stringp, "|")) ) { 00448 struct stat st; 00449 char *fn = build_filename(filename, ext); 00450 00451 if (fn == NULL) 00452 continue; 00453 00454 if ( stat(fn, &st) ) { /* file not existent */ 00455 ast_free(fn); 00456 continue; 00457 } 00458 /* for 'OPEN' we need to be sure that the format matches 00459 * what the channel can process 00460 */ 00461 if (action == ACTION_OPEN) { 00462 struct ast_channel *chan = (struct ast_channel *)arg2; 00463 FILE *bfile; 00464 struct ast_filestream *s; 00465 00466 if ( !(chan->writeformat & f->format) && 00467 !((f->format & AST_FORMAT_AUDIO_MASK && fmt) || 00468 (f->format & AST_FORMAT_VIDEO_MASK && fmt))) { 00469 ast_free(fn); 00470 continue; /* not a supported format */ 00471 } 00472 if ( (bfile = fopen(fn, "r")) == NULL) { 00473 ast_free(fn); 00474 continue; /* cannot open file */ 00475 } 00476 s = get_filestream(f, bfile); 00477 if (!s) { 00478 fclose(bfile); 00479 ast_free(fn); /* cannot allocate descriptor */ 00480 continue; 00481 } 00482 if (open_wrapper(s)) { 00483 ast_free(fn); 00484 ast_closestream(s); 00485 continue; /* cannot run open on file */ 00486 } 00487 if (st.st_size == 0) { 00488 ast_log(LOG_WARNING, "File %s detected to have zero size.\n", fn); 00489 } 00490 /* ok this is good for OPEN */ 00491 res = 1; /* found */ 00492 s->lasttimeout = -1; 00493 s->fmt = f; 00494 s->trans = NULL; 00495 s->filename = NULL; 00496 if (s->fmt->format & AST_FORMAT_AUDIO_MASK) { 00497 if (chan->stream) 00498 ast_closestream(chan->stream); 00499 chan->stream = s; 00500 } else { 00501 if (chan->vstream) 00502 ast_closestream(chan->vstream); 00503 chan->vstream = s; 00504 } 00505 ast_free(fn); 00506 break; 00507 } 00508 switch (action) { 00509 case ACTION_OPEN: 00510 break; /* will never get here */ 00511 00512 case ACTION_EXISTS: /* return the matching format */ 00513 res |= f->format; 00514 break; 00515 00516 case ACTION_DELETE: 00517 if ( (res = unlink(fn)) ) 00518 ast_log(LOG_WARNING, "unlink(%s) failed: %s\n", fn, strerror(errno)); 00519 break; 00520 00521 case ACTION_RENAME: 00522 case ACTION_COPY: { 00523 char *nfn = build_filename((const char *)arg2, ext); 00524 if (!nfn) 00525 ast_log(LOG_WARNING, "Out of memory\n"); 00526 else { 00527 res = action == ACTION_COPY ? copy(fn, nfn) : rename(fn, nfn); 00528 if (res) 00529 ast_log(LOG_WARNING, "%s(%s,%s) failed: %s\n", 00530 action == ACTION_COPY ? "copy" : "rename", 00531 fn, nfn, strerror(errno)); 00532 ast_free(nfn); 00533 } 00534 } 00535 break; 00536 00537 default: 00538 ast_log(LOG_WARNING, "Unknown helper %u\n", action); 00539 } 00540 ast_free(fn); 00541 } 00542 } 00543 AST_RWLIST_UNLOCK(&formats); 00544 return res; 00545 }
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 936 of file file.c.
References ACTION_RENAME, and ast_filehelper().
Referenced by __ast_play_and_record(), ast_monitor_stop(), forward_message(), leave_voicemail(), play_record_review(), rename_file(), and vm_forwardoptions().
00937 { 00938 return ast_filehelper(filename, filename2, fmt, ACTION_RENAME); 00939 }
char* ast_format_str_reduce | ( | char * | fmts | ) |
Remove duplicate formats from a format string.
fmts | a format string, this string will be modified |
NULL | error |
Definition at line 1382 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, and type.
Referenced by actual_load_config().
01383 { 01384 struct ast_format *f; 01385 struct ast_format *fmts_ptr[AST_MAX_FORMATS]; 01386 char *fmts_str[AST_MAX_FORMATS]; 01387 char *stringp, *type; 01388 char *orig = fmts; 01389 int i, j, x, first, found = 0; 01390 int len = strlen(fmts) + 1; 01391 int res; 01392 01393 if (AST_RWLIST_RDLOCK(&formats)) { 01394 ast_log(LOG_WARNING, "Unable to lock format list\n"); 01395 return NULL; 01396 } 01397 01398 stringp = ast_strdupa(fmts); 01399 01400 for (x = 0; (type = strsep(&stringp, "|")) && x < AST_MAX_FORMATS; x++) { 01401 AST_RWLIST_TRAVERSE(&formats, f, list) { 01402 if (exts_compare(f->exts, type)) { 01403 found = 1; 01404 break; 01405 } 01406 } 01407 01408 fmts_str[x] = type; 01409 if (found) { 01410 fmts_ptr[x] = f; 01411 } else { 01412 fmts_ptr[x] = NULL; 01413 } 01414 } 01415 AST_RWLIST_UNLOCK(&formats); 01416 01417 first = 1; 01418 for (i = 0; i < x; i++) { 01419 /* ignore invalid entries */ 01420 if (!fmts_ptr[i]) { 01421 ast_log(LOG_WARNING, "ignoring unknown format '%s'\n", fmts_str[i]); 01422 continue; 01423 } 01424 01425 /* special handling for the first entry */ 01426 if (first) { 01427 res = snprintf(fmts, len, "%s", fmts_str[i]); 01428 fmts += res; 01429 len -= res; 01430 first = 0; 01431 continue; 01432 } 01433 01434 found = 0; 01435 for (j = 0; j < i; j++) { 01436 /* this is a duplicate */ 01437 if (fmts_ptr[j] == fmts_ptr[i]) { 01438 found = 1; 01439 break; 01440 } 01441 } 01442 01443 if (!found) { 01444 res = snprintf(fmts, len, "|%s", fmts_str[i]); 01445 fmts += res; 01446 len -= res; 01447 } 01448 } 01449 01450 if (first) { 01451 ast_log(LOG_WARNING, "no known formats found in format list (%s)\n", orig); 01452 return NULL; 01453 } 01454 01455 return orig; 01456 }
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 801 of file file.c.
References ast_readaudio_callback(), and FSREAD_SUCCESS_SCHED.
Referenced by ast_readaudio_callback().
00802 { 00803 struct ast_filestream *fs = (struct ast_filestream *)data; 00804 enum fsread_res res; 00805 00806 res = ast_readaudio_callback(fs); 00807 00808 if (res == FSREAD_SUCCESS_SCHED) 00809 return 1; 00810 00811 return 0; 00812 }
static int ast_fsread_video | ( | const void * | data | ) | [static] |
Definition at line 848 of file file.c.
References ast_readvideo_callback(), and FSREAD_SUCCESS_SCHED.
Referenced by ast_readvideo_callback().
00849 { 00850 struct ast_filestream *fs = (struct ast_filestream *)data; 00851 enum fsread_res res; 00852 00853 res = ast_readvideo_callback(fs); 00854 00855 if (res == FSREAD_SUCCESS_SCHED) 00856 return 1; 00857 00858 return 0; 00859 }
struct ast_filestream* ast_openstream | ( | struct ast_channel * | chan, | |
const char * | filename, | |||
const char * | preflang | |||
) | [read] |
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 636 of file file.c.
References ast_openstream_full().
Referenced by ast_streamfile(), dictate_exec(), handle_getoption(), handle_streamfile(), and speech_streamfile().
00637 { 00638 return ast_openstream_full(chan, filename, preflang, 0); 00639 }
struct ast_filestream* ast_openstream_full | ( | struct ast_channel * | chan, | |
const char * | filename, | |||
const char * | preflang, | |||
int | asis | |||
) | [read] |
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 641 of file file.c.
References ACTION_OPEN, ast_alloca, ast_deactivate_generator(), ast_filehelper(), AST_FORMAT_AUDIO_MASK, ast_log(), ast_set_write_format(), ast_stopstream(), ast_filestream::buf, fileexists_core(), ast_channel::generator, LOG_WARNING, ast_channel::oldwriteformat, ast_channel::stream, and ast_channel::writeformat.
Referenced by ast_moh_files_next(), ast_openstream(), and gen_nextfile().
00642 { 00643 /* 00644 * Use fileexists_core() to find a file in a compatible 00645 * language and format, set up a suitable translator, 00646 * and open the stream. 00647 */ 00648 format_t fmts, res; 00649 int buflen; 00650 char *buf; 00651 00652 if (!asis) { 00653 /* do this first, otherwise we detect the wrong writeformat */ 00654 ast_stopstream(chan); 00655 if (chan->generator) 00656 ast_deactivate_generator(chan); 00657 } 00658 if (preflang == NULL) 00659 preflang = ""; 00660 buflen = strlen(preflang) + strlen(filename) + 4; 00661 buf = ast_alloca(buflen); 00662 fmts = fileexists_core(filename, NULL, preflang, buf, buflen); 00663 if (fmts > 0) 00664 fmts &= AST_FORMAT_AUDIO_MASK; 00665 if (fmts < 1) { 00666 ast_log(LOG_WARNING, "File %s does not exist in any format\n", filename); 00667 return NULL; 00668 } 00669 chan->oldwriteformat = chan->writeformat; 00670 /* Set the channel to a format we can work with */ 00671 res = ast_set_write_format(chan, fmts); 00672 if (res == -1) { /* No format available that works with this channel */ 00673 return NULL; 00674 } 00675 res = ast_filehelper(buf, chan, NULL, ACTION_OPEN); 00676 if (res >= 0) 00677 return chan->stream; 00678 return NULL; 00679 }
struct ast_filestream* ast_openvstream | ( | struct ast_channel * | chan, | |
const char * | filename, | |||
const char * | preflang | |||
) | [read] |
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 681 of file file.c.
References ACTION_OPEN, ast_alloca, 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().
00682 { 00683 /* As above, but for video. But here we don't have translators 00684 * so we must enforce a format. 00685 */ 00686 format_t format; 00687 char *buf; 00688 int buflen; 00689 00690 if (preflang == NULL) 00691 preflang = ""; 00692 buflen = strlen(preflang) + strlen(filename) + 4; 00693 buf = ast_alloca(buflen); 00694 00695 for (format = AST_FORMAT_FIRST_VIDEO_BIT; format <= AST_FORMAT_VIDEO_MASK; format = format << 1) { 00696 int fd; 00697 const char *fmt; 00698 00699 if (!(chan->nativeformats & format)) 00700 continue; 00701 fmt = ast_getformatname(format); 00702 if ( fileexists_core(filename, fmt, preflang, buf, buflen) < 1) /* no valid format */ 00703 continue; 00704 fd = ast_filehelper(buf, chan, fmt, ACTION_OPEN); 00705 if (fd >= 0) 00706 return chan->vstream; 00707 ast_log(LOG_WARNING, "File %s has video but couldn't be opened\n", filename); 00708 } 00709 return NULL; 00710 }
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 867 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().
00868 { 00869 enum fsread_res res; 00870 00871 if (s->fmt->format & AST_FORMAT_AUDIO_MASK) 00872 res = ast_readaudio_callback(s); 00873 else 00874 res = ast_readvideo_callback(s); 00875 00876 return (res == FSREAD_FAILURE) ? -1 : 0; 00877 }
static enum fsread_res ast_readaudio_callback | ( | struct ast_filestream * | s | ) | [static] |
Definition at line 752 of file file.c.
References ast_format_rate(), ast_frfree, ast_fsread_audio(), ast_log(), ast_sched_add(), ast_settimeout(), ast_settimeout_full(), ast_write(), ast_filestream::fmt, ast_format::format, FSREAD_FAILURE, FSREAD_SUCCESS_NOSCHED, FSREAD_SUCCESS_SCHED, ast_filestream::lasttimeout, LOG_WARNING, 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().
00753 { 00754 int whennext = 0; 00755 00756 while (!whennext) { 00757 struct ast_frame *fr; 00758 00759 if (s->orig_chan_name && strcasecmp(s->owner->name, s->orig_chan_name)) { 00760 goto return_failure; 00761 } 00762 00763 fr = read_frame(s, &whennext); 00764 00765 if (!fr /* stream complete */ || ast_write(s->owner, fr) /* error writing */) { 00766 if (fr) { 00767 ast_log(LOG_WARNING, "Failed to write frame\n"); 00768 ast_frfree(fr); 00769 } 00770 goto return_failure; 00771 } 00772 00773 if (fr) { 00774 ast_frfree(fr); 00775 } 00776 } 00777 00778 if (whennext != s->lasttimeout) { 00779 if (s->owner->timingfd > -1) { 00780 float samp_rate = (float) ast_format_rate(s->fmt->format); 00781 unsigned int rate; 00782 00783 rate = (unsigned int) roundf(samp_rate / ((float) whennext)); 00784 00785 ast_settimeout_full(s->owner, rate, ast_fsread_audio, s, 1); 00786 } else { 00787 s->owner->streamid = ast_sched_add(s->owner->sched, 00788 whennext / (ast_format_rate(s->fmt->format) / 1000), ast_fsread_audio, s); 00789 } 00790 s->lasttimeout = whennext; 00791 return FSREAD_SUCCESS_NOSCHED; 00792 } 00793 return FSREAD_SUCCESS_SCHED; 00794 00795 return_failure: 00796 s->owner->streamid = -1; 00797 ast_settimeout(s->owner, 0, NULL, NULL); 00798 return FSREAD_FAILURE; 00799 }
struct ast_filestream* ast_readfile | ( | const char * | filename, | |
const char * | type, | |||
const char * | comment, | |||
int | flags, | |||
int | check, | |||
mode_t | mode | |||
) | [read] |
Starts reading from a file.
filename | the name of the file to read from | |
type | format of file you wish to read from | |
comment | comment to go with | |
flags | file flags | |
check | (unimplemented, hence negligible) | |
mode | Open mode Open an incoming file stream. flags are flags for the open() command, and if check is non-zero, then it will not read a file if there are any files that start with that name and have an extension Please note, this is a blocking function. Program execution will not return until ast_waitstream completes it's execution. |
a | struct ast_filestream on success. | |
NULL | on failure. |
Definition at line 997 of file file.c.
References ast_closestream(), ast_free, ast_log(), AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_strdup, build_filename(), errno, ast_format::exts, exts_compare(), f, ast_filestream::filename, ast_filestream::flags, ast_filestream::fmt, get_filestream(), LOG_WARNING, ast_filestream::mode, open_wrapper(), ast_filestream::trans, and ast_filestream::vfs.
Referenced by __ast_play_and_record(), and handle_cli_file_convert().
00998 { 00999 FILE *bfile; 01000 struct ast_format *f; 01001 struct ast_filestream *fs = NULL; 01002 char *fn; 01003 int format_found = 0; 01004 01005 AST_RWLIST_RDLOCK(&formats); 01006 01007 AST_RWLIST_TRAVERSE(&formats, f, list) { 01008 fs = NULL; 01009 if (!exts_compare(f->exts, type)) 01010 continue; 01011 else 01012 format_found = 1; 01013 01014 fn = build_filename(filename, type); 01015 if (!fn) { 01016 continue; 01017 } 01018 errno = 0; 01019 bfile = fopen(fn, "r"); 01020 01021 if (!bfile || (fs = get_filestream(f, bfile)) == NULL || open_wrapper(fs) ) { 01022 ast_log(LOG_WARNING, "Unable to open %s\n", fn); 01023 if (fs) { 01024 ast_closestream(fs); 01025 } 01026 fs = NULL; 01027 bfile = NULL; 01028 ast_free(fn); 01029 break; 01030 } 01031 /* found it */ 01032 fs->trans = NULL; 01033 fs->fmt = f; 01034 fs->flags = flags; 01035 fs->mode = mode; 01036 fs->filename = ast_strdup(filename); 01037 fs->vfs = NULL; 01038 ast_free(fn); 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] |
Read a frame from a filestream.
s | ast_filestream to act on |
NULL | if read failed. |
Definition at line 737 of file file.c.
References read_frame().
Referenced by __ast_play_and_record(), dictate_exec(), gen_readframe(), handle_cli_file_convert(), and moh_files_readframe().
00738 { 00739 int whennext = 0; 00740 00741 return read_frame(s, &whennext); 00742 }
static enum fsread_res ast_readvideo_callback | ( | struct ast_filestream * | s | ) | [static] |
Definition at line 816 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().
00817 { 00818 int whennext = 0; 00819 00820 while (!whennext) { 00821 struct ast_frame *fr = read_frame(s, &whennext); 00822 00823 if (!fr /* stream complete */ || ast_write(s->owner, fr) /* error writing */) { 00824 if (fr) { 00825 ast_log(LOG_WARNING, "Failed to write frame\n"); 00826 ast_frfree(fr); 00827 } 00828 s->owner->vstreamid = -1; 00829 return FSREAD_FAILURE; 00830 } 00831 00832 if (fr) { 00833 ast_frfree(fr); 00834 } 00835 } 00836 00837 if (whennext != s->lasttimeout) { 00838 s->owner->vstreamid = ast_sched_add(s->owner->sched, 00839 whennext / (ast_format_rate(s->fmt->format) / 1000), 00840 ast_fsread_video, s); 00841 s->lasttimeout = whennext; 00842 return FSREAD_SUCCESS_NOSCHED; 00843 } 00844 00845 return FSREAD_SUCCESS_SCHED; 00846 }
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 879 of file file.c.
References ast_filestream::fmt, and ast_format::seek.
Referenced by __ast_read(), ast_control_streamfile(), ast_moh_files_next(), 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 |
Stop playback of a stream
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(), leave_voicemail(), meetme_menu_admin(), meetme_menu_admin_extended(), menu_callback(), minivm_greet_exec(), mp3_exec(), NBScat_exec(), parkandannounce_exec(), pbx_builtin_background(), pl_odtworz_plik(), play_file(), play_mailbox_owner(), playback_exec(), queue_exec(), read_exec(), readexten_exec(), record_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 1370 of file file.c.
References ast_streamfile(), ast_strlen_zero(), and ast_waitstream().
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(), leave_voicemail(), 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().
01371 { 01372 int res = 0; 01373 if (!ast_strlen_zero(file)) { 01374 res = ast_streamfile(chan, file, chan->language); 01375 if (!res) { 01376 res = ast_waitstream(chan, digits); 01377 } 01378 } 01379 return res; 01380 }
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 894 of file file.c.
References ast_seekstream(), and DEFAULT_SAMPLES_PER_MS.
Referenced by waitstream_core().
00895 { 00896 return ast_seekstream(fs, ms * DEFAULT_SAMPLES_PER_MS, SEEK_CUR); 00897 }
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 899 of file file.c.
References ast_seekstream(), and DEFAULT_SAMPLES_PER_MS.
Referenced by __ast_play_and_record(), handle_recordfile(), record_exec(), and waitstream_core().
00900 { 00901 return ast_seekstream(fs, -ms * DEFAULT_SAMPLES_PER_MS, SEEK_CUR); 00902 }
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 946 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_test_suite_event_notify, ast_verb, errno, ast_filestream::f, ast_filestream::fmt, ast_format::format, LOG_WARNING, 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(), auth_exec(), 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(), meetme_menu_admin(), meetme_menu_admin_extended(), meetme_menu_normal(), menu_callback(), minivm_greet_exec(), page_exec(), parkandannounce_exec(), pbx_builtin_background(), pl_odtworz_plik(), play_and_wait(), play_file(), play_record_review(), playback_exec(), privacy_exec(), readexten_exec(), record_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().
00947 { 00948 struct ast_filestream *fs; 00949 struct ast_filestream *vfs=NULL; 00950 char fmt[256]; 00951 off_t pos; 00952 int seekattempt; 00953 int res; 00954 00955 fs = ast_openstream(chan, filename, preflang); 00956 if (!fs) { 00957 ast_log(LOG_WARNING, "Unable to open %s (format %s): %s\n", filename, ast_getformatname_multiple(fmt, sizeof(fmt), chan->nativeformats), strerror(errno)); 00958 return -1; 00959 } 00960 00961 /* check to see if there is any data present (not a zero length file), 00962 * done this way because there is no where for ast_openstream_full to 00963 * return the file had no data. */ 00964 pos = ftello(fs->f); 00965 seekattempt = fseeko(fs->f, -1, SEEK_END); 00966 if (seekattempt) { 00967 if (errno == EINVAL) { 00968 /* Zero-length file, as opposed to a pipe */ 00969 return 0; 00970 } else { 00971 ast_seekstream(fs, 0, SEEK_SET); 00972 } 00973 } else { 00974 fseeko(fs->f, pos, SEEK_SET); 00975 } 00976 00977 vfs = ast_openvstream(chan, filename, preflang); 00978 if (vfs) { 00979 ast_debug(1, "Ooh, found a video stream, too, format %s\n", ast_getformatname(vfs->fmt->format)); 00980 } 00981 00982 if (ast_test_flag(chan, AST_FLAG_MASQ_NOSTREAM)) 00983 fs->orig_chan_name = ast_strdup(chan->name); 00984 if (ast_applystream(chan, fs)) 00985 return -1; 00986 if (vfs && ast_applystream(chan, vfs)) 00987 return -1; 00988 ast_test_suite_event_notify("PLAYBACK", "Message: %s\r\nChannel: %s", filename, chan->name); 00989 res = ast_playstream(fs); 00990 if (!res && vfs) 00991 res = ast_playstream(vfs); 00992 ast_verb(3, "<%s> Playing '%s.%s' (language '%s')\n", chan->name, filename, ast_getformatname(chan->writeformat), preflang ? preflang : "default"); 00993 00994 return res; 00995 }
off_t ast_tellstream | ( | struct ast_filestream * | fs | ) |
Tell where we are in a stream.
fs | fs to act on |
Definition at line 889 of file file.c.
References ast_filestream::fmt, and ast_format::tell.
Referenced by __ast_play_and_record(), ast_control_streamfile(), ast_moh_files_next(), 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 884 of file file.c.
References ast_filestream::fmt, and ast_format::trunc.
Referenced by __ast_play_and_record(), handle_recordfile(), and record_exec().
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 1343 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(), auth_exec(), 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(), meetme_menu_admin(), meetme_menu_admin_extended(), meetme_menu_normal(), menu_callback(), minivm_greet_exec(), page_exec(), parkandannounce_exec(), pbx_builtin_background(), pl_odtworz_plik(), play_and_wait(), play_file(), play_record_review(), playback_exec(), privacy_exec(), record_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().
01344 { 01345 return waitstream_core(c, breakon, NULL, NULL, 0, -1, -1, NULL); 01346 }
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 1354 of file file.c.
References ast_channel::context, and waitstream_core().
Referenced by pbx_builtin_background().
01355 { 01356 /* Waitstream, with return in the case of a valid 1 digit extension */ 01357 /* in the current or specified context being pressed */ 01358 01359 if (!context) 01360 context = c->context; 01361 return waitstream_core(c, NULL, NULL, NULL, 0, 01362 -1, -1, context); 01363 }
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 1337 of file file.c.
References waitstream_core().
Referenced by ast_control_streamfile().
01338 { 01339 return waitstream_core(c, breakon, forward, reverse, ms, 01340 -1 /* no audiofd */, -1 /* no cmdfd */, NULL /* no context */); 01341 }
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 1348 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().
01349 { 01350 return waitstream_core(c, breakon, NULL, NULL, 0, 01351 audiofd, cmdfd, NULL /* no context */); 01352 }
struct ast_filestream* ast_writefile | ( | const char * | filename, | |
const char * | type, | |||
const char * | comment, | |||
int | flags, | |||
int | check, | |||
mode_t | mode | |||
) | [read] |
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_alloca, 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(), record_exec(), 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 if (!fn) { 01087 continue; 01088 } 01089 fd = open(fn, flags | myflags, mode); 01090 if (fd > -1) { 01091 /* fdopen() the resulting file stream */ 01092 bfile = fdopen(fd, ((flags | myflags) & O_RDWR) ? "w+" : "w"); 01093 if (!bfile) { 01094 ast_log(LOG_WARNING, "Whoa, fdopen failed: %s!\n", strerror(errno)); 01095 close(fd); 01096 fd = -1; 01097 } 01098 } 01099 01100 if (ast_opt_cache_record_files && (fd > -1)) { 01101 char *c; 01102 01103 fclose(bfile); /* this also closes fd */ 01104 /* 01105 We touch orig_fn just as a place-holder so other things (like vmail) see the file is there. 01106 What we are really doing is writing to record_cache_dir until we are done then we will mv the file into place. 01107 */ 01108 orig_fn = ast_strdupa(fn); 01109 for (c = fn; *c; c++) 01110 if (*c == '/') 01111 *c = '_'; 01112 01113 size = strlen(fn) + strlen(record_cache_dir) + 2; 01114 buf = ast_alloca(size); 01115 strcpy(buf, record_cache_dir); 01116 strcat(buf, "/"); 01117 strcat(buf, fn); 01118 ast_free(fn); 01119 fn = buf; 01120 fd = open(fn, flags | myflags, mode); 01121 if (fd > -1) { 01122 /* fdopen() the resulting file stream */ 01123 bfile = fdopen(fd, ((flags | myflags) & O_RDWR) ? "w+" : "w"); 01124 if (!bfile) { 01125 ast_log(LOG_WARNING, "Whoa, fdopen failed: %s!\n", strerror(errno)); 01126 close(fd); 01127 fd = -1; 01128 } 01129 } 01130 } 01131 if (fd > -1) { 01132 errno = 0; 01133 fs = get_filestream(f, bfile); 01134 if (fs) { 01135 if ((fs->write_buffer = ast_malloc(32768))) { 01136 setvbuf(fs->f, fs->write_buffer, _IOFBF, 32768); 01137 } 01138 } 01139 if (!fs || rewrite_wrapper(fs, comment)) { 01140 ast_log(LOG_WARNING, "Unable to rewrite %s\n", fn); 01141 close(fd); 01142 if (orig_fn) { 01143 unlink(fn); 01144 unlink(orig_fn); 01145 } 01146 if (fs) { 01147 ast_closestream(fs); 01148 fs = NULL; 01149 } 01150 if (!buf) { 01151 ast_free(fn); 01152 } 01153 continue; 01154 } 01155 fs->trans = NULL; 01156 fs->fmt = f; 01157 fs->flags = flags; 01158 fs->mode = mode; 01159 if (orig_fn) { 01160 fs->realfilename = ast_strdup(orig_fn); 01161 fs->filename = ast_strdup(fn); 01162 } else { 01163 fs->realfilename = NULL; 01164 fs->filename = ast_strdup(filename); 01165 } 01166 fs->vfs = NULL; 01167 /* If truncated, we'll be at the beginning; if not truncated, then append */ 01168 f->seek(fs, 0, SEEK_END); 01169 } else if (errno != EEXIST) { 01170 ast_log(LOG_WARNING, "Unable to open file %s: %s\n", fn, strerror(errno)); 01171 if (orig_fn) 01172 unlink(orig_fn); 01173 } 01174 /* if buf != NULL then fn is already free and pointing to it */ 01175 if (!buf) 01176 ast_free(fn); 01177 } 01178 01179 AST_RWLIST_UNLOCK(&formats); 01180 01181 if (!format_found) 01182 ast_log(LOG_WARNING, "No such format '%s'\n", type); 01183 01184 return fs; 01185 }
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(), ast_frame_subclass::codec, ast_filestream::filename, ast_filestream::flags, ast_filestream::fmt, ast_format::format, ast_frame::frametype, ast_filestream::lastwriteformat, LOG_WARNING, ast_filestream::mode, ast_format::name, ast_frame::subclass, 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(), record_exec(), 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 ast_asprintf, and ast_config_AST_DATA_DIR.
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 (ast_asprintf(&fn, "%s.%s", filename, ext) < 0) { 00267 fn = NULL; 00268 } 00269 } else { 00270 if (ast_asprintf(&fn, "%s/sounds/%s.%s", 00271 ast_config_AST_DATA_DIR, filename, ext) < 0) { 00272 fn = NULL; 00273 } 00274 } 00275 return fn; 00276 }
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.
Referenced by ast_filehelper().
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 280 of file file.c.
References ast_copy_string(), and ext.
Referenced by ast_filehelper(), ast_format_str_reduce(), ast_readfile(), and ast_writefile().
00281 { 00282 char tmp[256]; 00283 char *stringp = tmp, *ext; 00284 00285 ast_copy_string(tmp, exts, sizeof(tmp)); 00286 while ((ext = strsep(&stringp, "|"))) { 00287 if (!strcmp(ext, type)) 00288 return 1; 00289 } 00290 00291 return 0; 00292 }
static void file_shutdown | ( | void | ) | [static] |
Definition at line 1498 of file file.c.
References ARRAY_LEN, and ast_cli_unregister_multiple().
Referenced by ast_file_init().
01499 { 01500 ast_cli_unregister_multiple(cli_file, ARRAY_LEN(cli_file)); 01501 }
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 586 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().
00588 { 00589 format_t res = -1; 00590 char *lang; 00591 00592 if (buf == NULL) { 00593 return -1; 00594 } 00595 00596 /* We try languages in the following order: 00597 * preflang (may include dialect and style codes) 00598 * lang (preflang without dialect - if any) 00599 * <none> 00600 * default (unless the same as preflang or lang without dialect) 00601 */ 00602 00603 lang = ast_strdupa(preflang); 00604 00605 /* Try preferred language, including removing any style or dialect codes */ 00606 while (!ast_strlen_zero(lang)) { 00607 char *end; 00608 00609 if ((res = fileexists_test(filename, fmt, lang, buf, buflen)) > 0) { 00610 return res; 00611 } 00612 00613 if ((end = strrchr(lang, '_')) != NULL) { 00614 *end = '\0'; 00615 continue; 00616 } 00617 00618 break; 00619 } 00620 00621 /* Try without any language */ 00622 if ((res = fileexists_test(filename, fmt, NULL, buf, buflen)) > 0) { 00623 return res; 00624 } 00625 00626 /* Finally try the default language unless it was already tried before */ 00627 if ((ast_strlen_zero(preflang) || strcmp(preflang, DEFAULT_LANGUAGE)) && (ast_strlen_zero(lang) || strcmp(lang, DEFAULT_LANGUAGE))) { 00628 if ((res = fileexists_test(filename, fmt, DEFAULT_LANGUAGE, buf, buflen)) > 0) { 00629 return res; 00630 } 00631 } 00632 00633 return 0; 00634 }
static format_t fileexists_test | ( | const char * | filename, | |
const char * | fmt, | |||
const char * | lang, | |||
char * | buf, | |||
int | buflen | |||
) | [static] |
Definition at line 552 of file file.c.
References ACTION_EXISTS, ast_filehelper(), and is_absolute_path().
Referenced by fileexists_core().
00554 { 00555 if (buf == NULL) { 00556 return -1; 00557 } 00558 00559 if (ast_language_is_prefix && !is_absolute_path(filename)) { /* new layout */ 00560 if (lang) { 00561 snprintf(buf, buflen, "%s/%s", lang, filename); 00562 } else { 00563 snprintf(buf, buflen, "%s", filename); 00564 } 00565 } else { /* old layout */ 00566 strcpy(buf, filename); /* first copy the full string */ 00567 if (lang) { 00568 /* insert the language and suffix if needed */ 00569 const char *c = strrchr(filename, '/'); 00570 int offset = c ? c - filename + 1 : 0; /* points right after the last '/' */ 00571 snprintf(buf + offset, buflen - offset, "%s/%s", lang, filename + offset); 00572 } 00573 } 00574 00575 return ast_filehelper(buf, NULL, fmt, ACTION_EXISTS); 00576 }
static void filestream_close | ( | struct ast_filestream * | f | ) | [static] |
Definition at line 295 of file file.c.
References AST_FORMAT_AUDIO_MASK, AST_FORMAT_VIDEO_MASK, ast_log(), AST_LOG_WARNING, AST_SCHED_DEL, ast_settimeout(), ast_filestream::fmt, ast_format::format, ast_format::name, ast_filestream::owner, ast_channel::sched, ast_channel::stream, ast_channel::streamid, ast_channel::vstream, and ast_channel::vstreamid.
Referenced by ast_closestream(), and filestream_destructor().
00296 { 00297 /* Stop a running stream if there is one */ 00298 if (f->owner) { 00299 if (f->fmt->format & AST_FORMAT_AUDIO_MASK) { 00300 f->owner->stream = NULL; 00301 AST_SCHED_DEL(f->owner->sched, f->owner->streamid); 00302 ast_settimeout(f->owner, 0, NULL, NULL); 00303 } else if (f->fmt->format & AST_FORMAT_VIDEO_MASK) { 00304 f->owner->vstream = NULL; 00305 AST_SCHED_DEL(f->owner->sched, f->owner->vstreamid); 00306 } else { 00307 ast_log(AST_LOG_WARNING, "Unable to schedule deletion of filestream with unsupported type %s\n", f->fmt->name); 00308 } 00309 } 00310 }
static void filestream_destructor | ( | void * | arg | ) | [static] |
Definition at line 312 of file file.c.
References ast_closestream(), ast_free, ast_module_unref(), ast_safe_fork(), ast_translator_free_path(), ast_format::close, ast_filestream::f, f, ast_filestream::filename, filestream_close(), ast_filestream::fmt, free, ast_format::module, ast_filestream::orig_chan_name, ast_filestream::realfilename, SENTINEL, status, ast_filestream::trans, ast_filestream::vfs, and ast_filestream::write_buffer.
Referenced by get_filestream().
00313 { 00314 struct ast_filestream *f = arg; 00315 int status; 00316 int pid = -1; 00317 00318 /* Stop a running stream if there is one */ 00319 filestream_close(f); 00320 00321 /* destroy the translator on exit */ 00322 if (f->trans) 00323 ast_translator_free_path(f->trans); 00324 00325 if (f->fmt->close) { 00326 void (*closefn)(struct ast_filestream *) = f->fmt->close; 00327 closefn(f); 00328 } 00329 00330 if (f->f) { 00331 fclose(f->f); 00332 } 00333 00334 if (f->realfilename && f->filename) { 00335 pid = ast_safe_fork(0); 00336 if (!pid) { 00337 execl("/bin/mv", "mv", "-f", f->filename, f->realfilename, SENTINEL); 00338 _exit(1); 00339 } 00340 else if (pid > 0) { 00341 /* Block the parent until the move is complete.*/ 00342 waitpid(pid, &status, 0); 00343 } 00344 } 00345 00346 if (f->filename) 00347 free(f->filename); 00348 if (f->realfilename) 00349 free(f->realfilename); 00350 if (f->vfs) 00351 ast_closestream(f->vfs); 00352 if (f->write_buffer) { 00353 ast_free(f->write_buffer); 00354 } 00355 if (f->orig_chan_name) 00356 free((void *) f->orig_chan_name); 00357 ast_module_unref(f->fmt->module); 00358 }
static int fn_wrapper | ( | struct ast_filestream * | s, | |
const char * | comment, | |||
enum wrap_fn | mode | |||
) | [static] |
Definition at line 384 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, WRAP_OPEN, and WRAP_REWRITE.
Referenced by open_wrapper(), and rewrite_wrapper().
00385 { 00386 struct ast_format *f = s->fmt; 00387 int ret = -1; 00388 int (*openfn)(struct ast_filestream *s); 00389 00390 if (mode == WRAP_OPEN && (openfn = f->open) && openfn(s)) 00391 ast_log(LOG_WARNING, "Unable to open format %s\n", f->name); 00392 else if (mode == WRAP_REWRITE && f->rewrite && f->rewrite(s, comment)) 00393 ast_log(LOG_WARNING, "Unable to rewrite format %s\n", f->name); 00394 else { 00395 /* preliminary checks succeed. update usecount */ 00396 ast_module_ref(f->module); 00397 ret = 0; 00398 } 00399 return ret; 00400 }
static struct ast_filestream* get_filestream | ( | struct ast_format * | fmt, | |
FILE * | bfile | |||
) | [static, read] |
Definition at line 360 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().
00361 { 00362 struct ast_filestream *s; 00363 00364 int l = sizeof(*s) + fmt->buf_size + fmt->desc_size; /* total allocation size */ 00365 if ( (s = ao2_alloc(l, filestream_destructor)) == NULL) 00366 return NULL; 00367 s->fmt = fmt; 00368 s->f = bfile; 00369 00370 if (fmt->desc_size) 00371 s->_private = ((char *)(s + 1)) + fmt->buf_size; 00372 if (fmt->buf_size) 00373 s->buf = (char *)(s + 1); 00374 s->fr.src = fmt->name; 00375 return s; 00376 }
static char* handle_cli_core_show_file_formats | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 1458 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.
01459 { 01460 #define FORMAT "%-10s %-10s %-20s\n" 01461 #define FORMAT2 "%-10s %-10s %-20s\n" 01462 struct ast_format *f; 01463 int count_fmt = 0; 01464 01465 switch (cmd) { 01466 case CLI_INIT: 01467 e->command = "core show file formats"; 01468 e->usage = 01469 "Usage: core show file formats\n" 01470 " Displays currently registered file formats (if any).\n"; 01471 return NULL; 01472 case CLI_GENERATE: 01473 return NULL; 01474 } 01475 01476 if (a->argc != 4) 01477 return CLI_SHOWUSAGE; 01478 01479 ast_cli(a->fd, FORMAT, "Format", "Name", "Extensions"); 01480 ast_cli(a->fd, FORMAT, "------", "----", "----------"); 01481 01482 AST_RWLIST_RDLOCK(&formats); 01483 AST_RWLIST_TRAVERSE(&formats, f, list) { 01484 ast_cli(a->fd, FORMAT2, ast_getformatname(f->format), f->name, f->exts); 01485 count_fmt++; 01486 } 01487 AST_RWLIST_UNLOCK(&formats); 01488 ast_cli(a->fd, "%d file formats registered.\n", count_fmt); 01489 return CLI_SUCCESS; 01490 #undef FORMAT 01491 #undef FORMAT2 01492 }
static int is_absolute_path | ( | const char * | filename | ) | [static] |
Definition at line 547 of file file.c.
Referenced by fileexists_test().
static int open_wrapper | ( | struct ast_filestream * | s | ) | [static] |
Definition at line 407 of file file.c.
References fn_wrapper(), and WRAP_OPEN.
Referenced by ast_filehelper(), and ast_readfile().
00408 { 00409 return fn_wrapper(s, NULL, WRAP_OPEN); 00410 }
static struct ast_frame* read_frame | ( | struct ast_filestream * | s, | |
int * | whennext | |||
) | [static, read] |
Definition at line 712 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().
00713 { 00714 struct ast_frame *fr, *new_fr; 00715 00716 if (!s || !s->fmt) { 00717 return NULL; 00718 } 00719 00720 if (!(fr = s->fmt->read(s, whennext))) { 00721 return NULL; 00722 } 00723 00724 if (!(new_fr = ast_frisolate(fr))) { 00725 ast_frfree(fr); 00726 return NULL; 00727 } 00728 00729 if (new_fr != fr) { 00730 ast_frfree(fr); 00731 fr = new_fr; 00732 } 00733 00734 return fr; 00735 }
static int rewrite_wrapper | ( | struct ast_filestream * | s, | |
const char * | comment | |||
) | [static] |
Definition at line 402 of file file.c.
References fn_wrapper(), and WRAP_REWRITE.
Referenced by ast_writefile().
00403 { 00404 return fn_wrapper(s, comment, WRAP_REWRITE); 00405 }
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 1190 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_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().
01193 { 01194 const char *orig_chan_name = NULL; 01195 int err = 0; 01196 01197 if (!breakon) 01198 breakon = ""; 01199 if (!forward) 01200 forward = ""; 01201 if (!reverse) 01202 reverse = ""; 01203 01204 /* Switch the channel to end DTMF frame only. waitstream_core doesn't care about the start of DTMF. */ 01205 ast_set_flag(c, AST_FLAG_END_DTMF_ONLY); 01206 01207 if (ast_test_flag(c, AST_FLAG_MASQ_NOSTREAM)) 01208 orig_chan_name = ast_strdupa(c->name); 01209 01210 while (c->stream) { 01211 int res; 01212 int ms; 01213 01214 if (orig_chan_name && strcasecmp(orig_chan_name, c->name)) { 01215 ast_stopstream(c); 01216 err = 1; 01217 break; 01218 } 01219 01220 ms = ast_sched_wait(c->sched); 01221 01222 if (ms < 0 && !c->timingfunc) { 01223 ast_stopstream(c); 01224 break; 01225 } 01226 if (ms < 0) 01227 ms = 1000; 01228 if (cmdfd < 0) { 01229 res = ast_waitfor(c, ms); 01230 if (res < 0) { 01231 ast_log(LOG_WARNING, "Select failed (%s)\n", strerror(errno)); 01232 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 01233 return res; 01234 } 01235 } else { 01236 int outfd; 01237 struct ast_channel *rchan = ast_waitfor_nandfds(&c, 1, &cmdfd, (cmdfd > -1) ? 1 : 0, NULL, &outfd, &ms); 01238 if (!rchan && (outfd < 0) && (ms)) { 01239 /* Continue */ 01240 if (errno == EINTR) 01241 continue; 01242 ast_log(LOG_WARNING, "Wait failed (%s)\n", strerror(errno)); 01243 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 01244 return -1; 01245 } else if (outfd > -1) { /* this requires cmdfd set */ 01246 /* The FD we were watching has something waiting */ 01247 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 01248 return 1; 01249 } 01250 /* if rchan is set, it is 'c' */ 01251 res = rchan ? 1 : 0; /* map into 'res' values */ 01252 } 01253 if (res > 0) { 01254 struct ast_frame *fr = ast_read(c); 01255 if (!fr) { 01256 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 01257 return -1; 01258 } 01259 switch (fr->frametype) { 01260 case AST_FRAME_DTMF_END: 01261 if (context) { 01262 const char exten[2] = { fr->subclass.integer, '\0' }; 01263 if (ast_exists_extension(c, context, exten, 1, 01264 S_COR(c->caller.id.number.valid, c->caller.id.number.str, NULL))) { 01265 res = fr->subclass.integer; 01266 ast_frfree(fr); 01267 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 01268 return res; 01269 } 01270 } else { 01271 res = fr->subclass.integer; 01272 if (strchr(forward, res)) { 01273 int eoftest; 01274 ast_stream_fastforward(c->stream, skip_ms); 01275 eoftest = fgetc(c->stream->f); 01276 if (feof(c->stream->f)) { 01277 ast_stream_rewind(c->stream, skip_ms); 01278 } else { 01279 ungetc(eoftest, c->stream->f); 01280 } 01281 } else if (strchr(reverse, res)) { 01282 ast_stream_rewind(c->stream, skip_ms); 01283 } else if (strchr(breakon, res)) { 01284 ast_frfree(fr); 01285 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 01286 return res; 01287 } 01288 } 01289 break; 01290 case AST_FRAME_CONTROL: 01291 switch (fr->subclass.integer) { 01292 case AST_CONTROL_HANGUP: 01293 case AST_CONTROL_BUSY: 01294 case AST_CONTROL_CONGESTION: 01295 ast_frfree(fr); 01296 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 01297 return -1; 01298 case AST_CONTROL_RINGING: 01299 case AST_CONTROL_ANSWER: 01300 case AST_CONTROL_VIDUPDATE: 01301 case AST_CONTROL_SRCUPDATE: 01302 case AST_CONTROL_SRCCHANGE: 01303 case AST_CONTROL_HOLD: 01304 case AST_CONTROL_UNHOLD: 01305 case AST_CONTROL_CONNECTED_LINE: 01306 case AST_CONTROL_REDIRECTING: 01307 case AST_CONTROL_AOC: 01308 case AST_CONTROL_UPDATE_RTP_PEER: 01309 case -1: 01310 /* Unimportant */ 01311 break; 01312 default: 01313 ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", fr->subclass.integer); 01314 } 01315 break; 01316 case AST_FRAME_VOICE: 01317 /* Write audio if appropriate */ 01318 if (audiofd > -1) { 01319 if (write(audiofd, fr->data.ptr, fr->datalen) < 0) { 01320 ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno)); 01321 } 01322 } 01323 default: 01324 /* Ignore all others */ 01325 break; 01326 } 01327 ast_frfree(fr); 01328 } 01329 ast_sched_runq(c->sched); 01330 } 01331 01332 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 01333 01334 return (err || c->_softhangup) ? -1 : 0; 01335 }
int ast_language_is_prefix = 1 |
Definition at line 63 of file file.c.
Referenced by ast_readconfig(), handle_show_settings(), and main().
struct ast_cli_entry cli_file[] [static] |
{ AST_CLI_DEFINE(handle_cli_core_show_file_formats, "Displays file formats") }