#include "asterisk.h"
#include <dirent.h>
#include <sys/stat.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_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 388 of file file.c.
00388 { 00389 ACTION_EXISTS = 1, /* return matching format if file exists, 0 otherwise */ 00390 ACTION_DELETE, /* delete file, return 0 on success, -1 on error */ 00391 ACTION_RENAME, /* rename file. return 0 on success, -1 on error */ 00392 ACTION_OPEN, 00393 ACTION_COPY /* copy file. return 0 on success, -1 on error */ 00394 };
enum fsread_res |
Definition at line 724 of file file.c.
00724 { 00725 FSREAD_FAILURE, 00726 FSREAD_SUCCESS_SCHED, 00727 FSREAD_SUCCESS_NOSCHED, 00728 };
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 62 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.
00063 { 00064 struct ast_format *tmp; 00065 00066 AST_RWLIST_WRLOCK(&formats); 00067 AST_RWLIST_TRAVERSE(&formats, tmp, list) { 00068 if (!strcasecmp(f->name, tmp->name)) { 00069 AST_RWLIST_UNLOCK(&formats); 00070 ast_log(LOG_WARNING, "Tried to register '%s' format, already registered\n", f->name); 00071 return -1; 00072 } 00073 } 00074 if (!(tmp = ast_calloc(1, sizeof(*tmp)))) { 00075 AST_RWLIST_UNLOCK(&formats); 00076 return -1; 00077 } 00078 *tmp = *f; 00079 tmp->module = mod; 00080 if (tmp->buf_size) { 00081 /* 00082 * Align buf_size properly, rounding up to the machine-specific 00083 * alignment for pointers. 00084 */ 00085 struct _test_align { void *a, *b; } p; 00086 int align = (char *)&p.b - (char *)&p.a; 00087 tmp->buf_size = ((f->buf_size + align - 1) / align) * align; 00088 } 00089 00090 memset(&tmp->list, 0, sizeof(tmp->list)); 00091 00092 AST_RWLIST_INSERT_HEAD(&formats, tmp, list); 00093 AST_RWLIST_UNLOCK(&formats); 00094 ast_verb(2, "Registered file format %s, extension(s) %s\n", f->name, f->exts); 00095 00096 return 0; 00097 }
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 841 of file file.c.
References ast_filestream::owner.
Referenced by ast_streamfile(), handle_getoption(), handle_recordfile(), handle_streamfile(), and speech_streamfile().
00842 { 00843 s->owner = chan; 00844 return 0; 00845 }
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 884 of file file.c.
References ao2_ref, AST_FORMAT_AUDIO_MASK, AST_SCHED_DEL, ast_settimeout(), f, and ast_format::format.
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(), moh_files_release(), and rpt().
00885 { 00886 /* This used to destroy the filestream, but it now just decrements a refcount. 00887 * We need to force the stream to quit queuing frames now, because we might 00888 * change the writeformat, which could result in a subsequent write error, if 00889 * the format is different. */ 00890 00891 /* Stop a running stream if there is one */ 00892 if (f->owner) { 00893 if (f->fmt->format < AST_FORMAT_AUDIO_MASK) { 00894 f->owner->stream = NULL; 00895 AST_SCHED_DEL(f->owner->sched, f->owner->streamid); 00896 ast_settimeout(f->owner, 0, NULL, NULL); 00897 } else { 00898 f->owner->vstream = NULL; 00899 AST_SCHED_DEL(f->owner->sched, f->owner->vstreamid); 00900 } 00901 } 00902 00903 ao2_ref(f, -1); 00904 return 0; 00905 }
int ast_file_init | ( | void | ) |
Provided by file.c
Definition at line 1474 of file file.c.
References ARRAY_LEN, ast_cli_register_multiple(), and cli_file.
01475 { 01476 ast_cli_register_multiple(cli_file, ARRAY_LEN(cli_file)); 01477 return 0; 01478 }
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 935 of file file.c.
References ast_filehelper().
Referenced by copy_plain_file(), and vm_forwardoptions().
00936 { 00937 return ast_filehelper(filename, filename2, fmt, ACTION_COPY); 00938 }
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 925 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().
00926 { 00927 return ast_filehelper(filename, NULL, fmt, ACTION_DELETE); 00928 }
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 911 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(), function_playback(), invent_message(), leave_voicemail(), minivm_delete_exec(), play_file(), play_message(), play_message_callerid(), readexten_exec(), record_exec(), retrydial_exec(), rpt_tele_thread(), say_character_str_full(), say_digit_str_full(), say_phonetic_str_full(), sayname(), saynode(), setup_privacy_args(), vm_intro(), vm_newuser(), vm_options(), and vm_tempgreeting().
00912 { 00913 char *buf; 00914 int buflen; 00915 00916 if (preflang == NULL) 00917 preflang = ""; 00918 buflen = strlen(preflang) + strlen(filename) + 4; /* room for everything */ 00919 buf = alloca(buflen); 00920 if (buf == NULL) 00921 return 0; 00922 return fileexists_core(filename, fmt, preflang, buf, buflen); 00923 }
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 405 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().
00406 { 00407 struct ast_format *f; 00408 format_t res = (action == ACTION_EXISTS) ? 0 : -1; 00409 00410 AST_RWLIST_RDLOCK(&formats); 00411 /* Check for a specific format */ 00412 AST_RWLIST_TRAVERSE(&formats, f, list) { 00413 char *stringp, *ext = NULL; 00414 00415 if (fmt && !exts_compare(f->exts, fmt)) 00416 continue; 00417 00418 /* Look for a file matching the supported extensions. 00419 * The file must exist, and for OPEN, must match 00420 * one of the formats supported by the channel. 00421 */ 00422 stringp = ast_strdupa(f->exts); /* this is in the stack so does not need to be freed */ 00423 while ( (ext = strsep(&stringp, "|")) ) { 00424 struct stat st; 00425 char *fn = build_filename(filename, ext); 00426 00427 if (fn == NULL) 00428 continue; 00429 00430 if ( stat(fn, &st) ) { /* file not existent */ 00431 ast_free(fn); 00432 continue; 00433 } 00434 /* for 'OPEN' we need to be sure that the format matches 00435 * what the channel can process 00436 */ 00437 if (action == ACTION_OPEN) { 00438 struct ast_channel *chan = (struct ast_channel *)arg2; 00439 FILE *bfile; 00440 struct ast_filestream *s; 00441 00442 if ( !(chan->writeformat & f->format) && 00443 !((f->format & AST_FORMAT_AUDIO_MASK && fmt) || 00444 (f->format & AST_FORMAT_VIDEO_MASK && fmt))) { 00445 ast_free(fn); 00446 continue; /* not a supported format */ 00447 } 00448 if ( (bfile = fopen(fn, "r")) == NULL) { 00449 ast_free(fn); 00450 continue; /* cannot open file */ 00451 } 00452 s = get_filestream(f, bfile); 00453 if (!s) { 00454 fclose(bfile); 00455 ast_free(fn); /* cannot allocate descriptor */ 00456 continue; 00457 } 00458 if (open_wrapper(s)) { 00459 ast_free(fn); 00460 ast_closestream(s); 00461 continue; /* cannot run open on file */ 00462 } 00463 if (st.st_size == 0) { 00464 ast_log(LOG_WARNING, "File %s detected to have zero size.\n", fn); 00465 } 00466 /* ok this is good for OPEN */ 00467 res = 1; /* found */ 00468 s->lasttimeout = -1; 00469 s->fmt = f; 00470 s->trans = NULL; 00471 s->filename = NULL; 00472 if (s->fmt->format & AST_FORMAT_AUDIO_MASK) { 00473 if (chan->stream) 00474 ast_closestream(chan->stream); 00475 chan->stream = s; 00476 } else { 00477 if (chan->vstream) 00478 ast_closestream(chan->vstream); 00479 chan->vstream = s; 00480 } 00481 ast_free(fn); 00482 break; 00483 } 00484 switch (action) { 00485 case ACTION_OPEN: 00486 break; /* will never get here */ 00487 00488 case ACTION_EXISTS: /* return the matching format */ 00489 res |= f->format; 00490 break; 00491 00492 case ACTION_DELETE: 00493 if ( (res = unlink(fn)) ) 00494 ast_log(LOG_WARNING, "unlink(%s) failed: %s\n", fn, strerror(errno)); 00495 break; 00496 00497 case ACTION_RENAME: 00498 case ACTION_COPY: { 00499 char *nfn = build_filename((const char *)arg2, ext); 00500 if (!nfn) 00501 ast_log(LOG_WARNING, "Out of memory\n"); 00502 else { 00503 res = action == ACTION_COPY ? copy(fn, nfn) : rename(fn, nfn); 00504 if (res) 00505 ast_log(LOG_WARNING, "%s(%s,%s) failed: %s\n", 00506 action == ACTION_COPY ? "copy" : "rename", 00507 fn, nfn, strerror(errno)); 00508 ast_free(nfn); 00509 } 00510 } 00511 break; 00512 00513 default: 00514 ast_log(LOG_WARNING, "Unknown helper %d\n", action); 00515 } 00516 ast_free(fn); 00517 } 00518 } 00519 AST_RWLIST_UNLOCK(&formats); 00520 return res; 00521 }
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 930 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().
00931 { 00932 return ast_filehelper(filename, filename2, fmt, ACTION_RENAME); 00933 }
char* ast_format_str_reduce | ( | char * | fmts | ) |
fmts | a format string, this string will be modified |
NULL | error |
Definition at line 1358 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 load_config().
01359 { 01360 struct ast_format *f; 01361 struct ast_format *fmts_ptr[AST_MAX_FORMATS]; 01362 char *fmts_str[AST_MAX_FORMATS]; 01363 char *stringp, *type; 01364 char *orig = fmts; 01365 int i, j, x, first, found = 0; 01366 int len = strlen(fmts) + 1; 01367 int res; 01368 01369 if (AST_RWLIST_RDLOCK(&formats)) { 01370 ast_log(LOG_WARNING, "Unable to lock format list\n"); 01371 return NULL; 01372 } 01373 01374 stringp = ast_strdupa(fmts); 01375 01376 for (x = 0; (type = strsep(&stringp, "|")) && x < AST_MAX_FORMATS; x++) { 01377 AST_RWLIST_TRAVERSE(&formats, f, list) { 01378 if (exts_compare(f->exts, type)) { 01379 found = 1; 01380 break; 01381 } 01382 } 01383 01384 fmts_str[x] = type; 01385 if (found) { 01386 fmts_ptr[x] = f; 01387 } else { 01388 fmts_ptr[x] = NULL; 01389 } 01390 } 01391 AST_RWLIST_UNLOCK(&formats); 01392 01393 first = 1; 01394 for (i = 0; i < x; i++) { 01395 /* ignore invalid entries */ 01396 if (!fmts_ptr[i]) { 01397 ast_log(LOG_WARNING, "ignoring unknown format '%s'\n", fmts_str[i]); 01398 continue; 01399 } 01400 01401 /* special handling for the first entry */ 01402 if (first) { 01403 res = snprintf(fmts, len, "%s", fmts_str[i]); 01404 fmts += res; 01405 len -= res; 01406 first = 0; 01407 continue; 01408 } 01409 01410 found = 0; 01411 for (j = 0; j < i; j++) { 01412 /* this is a duplicate */ 01413 if (fmts_ptr[j] == fmts_ptr[i]) { 01414 found = 1; 01415 break; 01416 } 01417 } 01418 01419 if (!found) { 01420 res = snprintf(fmts, len, "|%s", fmts_str[i]); 01421 fmts += res; 01422 len -= res; 01423 } 01424 } 01425 01426 if (first) { 01427 ast_log(LOG_WARNING, "no known formats found in format list (%s)\n", orig); 01428 return NULL; 01429 } 01430 01431 return orig; 01432 }
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 99 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().
00100 { 00101 struct ast_format *tmp; 00102 int res = -1; 00103 00104 AST_RWLIST_WRLOCK(&formats); 00105 AST_RWLIST_TRAVERSE_SAFE_BEGIN(&formats, tmp, list) { 00106 if (!strcasecmp(name, tmp->name)) { 00107 AST_RWLIST_REMOVE_CURRENT(list); 00108 ast_free(tmp); 00109 res = 0; 00110 } 00111 } 00112 AST_RWLIST_TRAVERSE_SAFE_END; 00113 AST_RWLIST_UNLOCK(&formats); 00114 00115 if (!res) 00116 ast_verb(2, "Unregistered format %s\n", name); 00117 else 00118 ast_log(LOG_WARNING, "Tried to unregister format %s, already unregistered\n", name); 00119 00120 return res; 00121 }
static int ast_fsread_audio | ( | const void * | data | ) | [static] |
Definition at line 781 of file file.c.
References ast_readaudio_callback(), and FSREAD_SUCCESS_SCHED.
Referenced by ast_readaudio_callback().
00782 { 00783 struct ast_filestream *fs = (struct ast_filestream *)data; 00784 enum fsread_res res; 00785 00786 res = ast_readaudio_callback(fs); 00787 00788 if (res == FSREAD_SUCCESS_SCHED) 00789 return 1; 00790 00791 return 0; 00792 }
static int ast_fsread_video | ( | const void * | data | ) | [static] |
Definition at line 828 of file file.c.
References ast_readvideo_callback(), and FSREAD_SUCCESS_SCHED.
Referenced by ast_readvideo_callback().
00829 { 00830 struct ast_filestream *fs = (struct ast_filestream *)data; 00831 enum fsread_res res; 00832 00833 res = ast_readvideo_callback(fs); 00834 00835 if (res == FSREAD_SUCCESS_SCHED) 00836 return 1; 00837 00838 return 0; 00839 }
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 612 of file file.c.
References ast_openstream_full().
Referenced by ast_streamfile(), dictate_exec(), handle_getoption(), handle_streamfile(), and speech_streamfile().
00613 { 00614 return ast_openstream_full(chan, filename, preflang, 0); 00615 }
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 617 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().
00618 { 00619 /* 00620 * Use fileexists_core() to find a file in a compatible 00621 * language and format, set up a suitable translator, 00622 * and open the stream. 00623 */ 00624 format_t fmts, res; 00625 int buflen; 00626 char *buf; 00627 00628 if (!asis) { 00629 /* do this first, otherwise we detect the wrong writeformat */ 00630 ast_stopstream(chan); 00631 if (chan->generator) 00632 ast_deactivate_generator(chan); 00633 } 00634 if (preflang == NULL) 00635 preflang = ""; 00636 buflen = strlen(preflang) + strlen(filename) + 4; 00637 buf = alloca(buflen); 00638 if (buf == NULL) 00639 return NULL; 00640 fmts = fileexists_core(filename, NULL, preflang, buf, buflen); 00641 if (fmts > 0) 00642 fmts &= AST_FORMAT_AUDIO_MASK; 00643 if (fmts < 1) { 00644 ast_log(LOG_WARNING, "File %s does not exist in any format\n", filename); 00645 return NULL; 00646 } 00647 chan->oldwriteformat = chan->writeformat; 00648 /* Set the channel to a format we can work with */ 00649 res = ast_set_write_format(chan, fmts); 00650 if (res == -1) { /* No format available that works with this channel */ 00651 return NULL; 00652 } 00653 res = ast_filehelper(buf, chan, NULL, ACTION_OPEN); 00654 if (res >= 0) 00655 return chan->stream; 00656 return NULL; 00657 }
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 659 of file file.c.
References ACTION_OPEN, ast_filehelper(), AST_FORMAT_AUDIO_MASK, 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().
00660 { 00661 /* As above, but for video. But here we don't have translators 00662 * so we must enforce a format. 00663 */ 00664 format_t format; 00665 char *buf; 00666 int buflen; 00667 00668 if (preflang == NULL) 00669 preflang = ""; 00670 buflen = strlen(preflang) + strlen(filename) + 4; 00671 buf = alloca(buflen); 00672 if (buf == NULL) 00673 return NULL; 00674 00675 for (format = AST_FORMAT_AUDIO_MASK + 1; format <= AST_FORMAT_VIDEO_MASK; format = format << 1) { 00676 int fd; 00677 const char *fmt; 00678 00679 if (!(chan->nativeformats & format)) 00680 continue; 00681 fmt = ast_getformatname(format); 00682 if ( fileexists_core(filename, fmt, preflang, buf, buflen) < 1) /* no valid format */ 00683 continue; 00684 fd = ast_filehelper(buf, chan, fmt, ACTION_OPEN); 00685 if (fd >= 0) 00686 return chan->vstream; 00687 ast_log(LOG_WARNING, "File %s has video but couldn't be opened\n", filename); 00688 } 00689 return NULL; 00690 }
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 847 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().
00848 { 00849 enum fsread_res res; 00850 00851 if (s->fmt->format & AST_FORMAT_AUDIO_MASK) 00852 res = ast_readaudio_callback(s); 00853 else 00854 res = ast_readvideo_callback(s); 00855 00856 return (res == FSREAD_FAILURE) ? -1 : 0; 00857 }
static enum fsread_res ast_readaudio_callback | ( | struct ast_filestream * | s | ) | [static] |
Definition at line 732 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().
00733 { 00734 int whennext = 0; 00735 00736 while (!whennext) { 00737 struct ast_frame *fr; 00738 00739 if (s->orig_chan_name && strcasecmp(s->owner->name, s->orig_chan_name)) { 00740 goto return_failure; 00741 } 00742 00743 fr = read_frame(s, &whennext); 00744 00745 if (!fr /* stream complete */ || ast_write(s->owner, fr) /* error writing */) { 00746 if (fr) { 00747 ast_log(LOG_WARNING, "Failed to write frame\n"); 00748 ast_frfree(fr); 00749 } 00750 goto return_failure; 00751 } 00752 00753 if (fr) { 00754 ast_frfree(fr); 00755 } 00756 } 00757 00758 if (whennext != s->lasttimeout) { 00759 if (s->owner->timingfd > -1) { 00760 float samp_rate = (float) ast_format_rate(s->fmt->format); 00761 unsigned int rate; 00762 00763 rate = (unsigned int) roundf(samp_rate / ((float) whennext)); 00764 00765 ast_settimeout(s->owner, rate, ast_fsread_audio, s); 00766 } else { 00767 s->owner->streamid = ast_sched_add(s->owner->sched, 00768 whennext / (ast_format_rate(s->fmt->format) / 1000), ast_fsread_audio, s); 00769 } 00770 s->lasttimeout = whennext; 00771 return FSREAD_SUCCESS_NOSCHED; 00772 } 00773 return FSREAD_SUCCESS_SCHED; 00774 00775 return_failure: 00776 s->owner->streamid = -1; 00777 ast_settimeout(s->owner, 0, NULL, NULL); 00778 return FSREAD_FAILURE; 00779 }
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 984 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().
00985 { 00986 FILE *bfile; 00987 struct ast_format *f; 00988 struct ast_filestream *fs = NULL; 00989 char *fn; 00990 int format_found = 0; 00991 00992 AST_RWLIST_RDLOCK(&formats); 00993 00994 AST_RWLIST_TRAVERSE(&formats, f, list) { 00995 fs = NULL; 00996 if (!exts_compare(f->exts, type)) 00997 continue; 00998 else 00999 format_found = 1; 01000 01001 fn = build_filename(filename, type); 01002 errno = 0; 01003 bfile = fopen(fn, "r"); 01004 01005 if (!bfile || (fs = get_filestream(f, bfile)) == NULL || open_wrapper(fs) ) { 01006 ast_log(LOG_WARNING, "Unable to open %s\n", fn); 01007 if (fs) { 01008 ast_closestream(fs); 01009 } 01010 fs = NULL; 01011 bfile = NULL; 01012 ast_free(fn); 01013 break; 01014 } 01015 /* found it */ 01016 fs->trans = NULL; 01017 fs->fmt = f; 01018 fs->flags = flags; 01019 fs->mode = mode; 01020 fs->filename = ast_strdup(filename); 01021 fs->vfs = NULL; 01022 break; 01023 } 01024 01025 AST_RWLIST_UNLOCK(&formats); 01026 if (!format_found) 01027 ast_log(LOG_WARNING, "No such format '%s'\n", type); 01028 01029 return fs; 01030 }
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 717 of file file.c.
References read_frame().
Referenced by dictate_exec(), gen_readframe(), handle_cli_file_convert(), and moh_files_readframe().
00718 { 00719 int whennext = 0; 00720 00721 return read_frame(s, &whennext); 00722 }
static enum fsread_res ast_readvideo_callback | ( | struct ast_filestream * | s | ) | [static] |
Definition at line 796 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().
00797 { 00798 int whennext = 0; 00799 00800 while (!whennext) { 00801 struct ast_frame *fr = read_frame(s, &whennext); 00802 00803 if (!fr /* stream complete */ || ast_write(s->owner, fr) /* error writing */) { 00804 if (fr) { 00805 ast_log(LOG_WARNING, "Failed to write frame\n"); 00806 ast_frfree(fr); 00807 } 00808 s->owner->vstreamid = -1; 00809 return FSREAD_FAILURE; 00810 } 00811 00812 if (fr) { 00813 ast_frfree(fr); 00814 } 00815 } 00816 00817 if (whennext != s->lasttimeout) { 00818 s->owner->vstreamid = ast_sched_add(s->owner->sched, 00819 whennext / (ast_format_rate(s->fmt->format) / 1000), 00820 ast_fsread_video, s); 00821 s->lasttimeout = whennext; 00822 return FSREAD_SUCCESS_NOSCHED; 00823 } 00824 00825 return FSREAD_SUCCESS_SCHED; 00826 }
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 859 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 123 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 ast_adsi_transmit_message_full(), ast_control_streamfile(), ast_openstream_full(), ast_play_and_wait(), ast_readstring_full(), ast_say_enumeration_full_da(), ast_say_enumeration_full_de(), ast_say_enumeration_full_en(), ast_say_enumeration_full_he(), ast_say_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(), builtin_blindtransfer(), 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(), rpt_tele_thread(), s_streamwait3(), say_character_str_full(), say_digit_str_full(), say_phonetic_str_full(), saycharstr(), sayfile(), saynum(), select_item_seq(), send_morse(), send_tone_telemetry(), send_waveform_to_channel(), speech_background(), vm_authenticate(), vm_execmain(), wait_for_winner(), waitstream_core(), and zapateller_exec().
00124 { 00125 ast_channel_lock(tmp); 00126 00127 /* Stop a running stream if there is one */ 00128 if (tmp->stream) { 00129 ast_closestream(tmp->stream); 00130 tmp->stream = NULL; 00131 if (tmp->oldwriteformat && ast_set_write_format(tmp, tmp->oldwriteformat)) 00132 ast_log(LOG_WARNING, "Unable to restore format back to %s\n", ast_getformatname(tmp->oldwriteformat)); 00133 } 00134 /* Stop the video stream too */ 00135 if (tmp->vstream != NULL) { 00136 ast_closestream(tmp->vstream); 00137 tmp->vstream = NULL; 00138 } 00139 00140 ast_channel_unlock(tmp); 00141 00142 return 0; 00143 }
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 1346 of file file.c.
References ast_streamfile(), ast_strlen_zero(), 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_exec_full(), play_mailbox_owner(), play_message_callerid(), play_message_in_bridged_call(), play_prompt_to_channel(), play_record_review(), play_sound_file(), sayname(), select_item_seq(), vmsayname_exec(), and wait_file2().
01347 { 01348 int res = 0; 01349 if (!ast_strlen_zero(file)) { 01350 res = ast_streamfile(chan, file, chan->language); 01351 if (!res) { 01352 res = ast_waitstream(chan, digits); 01353 } 01354 } 01355 return res; 01356 }
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 874 of file file.c.
References ast_seekstream(), and DEFAULT_SAMPLES_PER_MS.
Referenced by waitstream_core().
00875 { 00876 return ast_seekstream(fs, ms * DEFAULT_SAMPLES_PER_MS, SEEK_CUR); 00877 }
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 879 of file file.c.
References ast_seekstream(), and DEFAULT_SAMPLES_PER_MS.
Referenced by handle_recordfile(), and waitstream_core().
00880 { 00881 return ast_seekstream(fs, -ms * DEFAULT_SAMPLES_PER_MS, SEEK_CUR); 00882 }
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 940 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(), page_exec(), park_exec_full(), parkandannounce_exec(), pbx_builtin_background(), pl_odtworz_plik(), play_and_wait(), play_file(), play_record_review(), playback_exec(), privacy_exec(), readexten_exec(), retrydial_exec(), rpt_tele_thread(), s_streamwait3(), say_character_str_full(), say_digit_str_full(), say_phonetic_str_full(), sayfile(), select_item_menu(), setup_privacy_args(), vm_authenticate(), wait_file(), and wait_for_winner().
00941 { 00942 struct ast_filestream *fs; 00943 struct ast_filestream *vfs=NULL; 00944 char fmt[256]; 00945 int seekattempt; 00946 int res; 00947 00948 fs = ast_openstream(chan, filename, preflang); 00949 if (!fs) { 00950 ast_log(LOG_WARNING, "Unable to open %s (format %s): %s\n", filename, ast_getformatname_multiple(fmt, sizeof(fmt), chan->nativeformats), strerror(errno)); 00951 return -1; 00952 } 00953 00954 /* check to see if there is any data present (not a zero length file), 00955 * done this way because there is no where for ast_openstream_full to 00956 * return the file had no data. */ 00957 seekattempt = fseek(fs->f, -1, SEEK_END); 00958 if (seekattempt && errno == EINVAL) { 00959 /* Zero-length file, as opposed to a pipe */ 00960 return 0; 00961 } else { 00962 ast_seekstream(fs, 0, SEEK_SET); 00963 } 00964 00965 vfs = ast_openvstream(chan, filename, preflang); 00966 if (vfs) { 00967 ast_debug(1, "Ooh, found a video stream, too, format %s\n", ast_getformatname(vfs->fmt->format)); 00968 } 00969 00970 if (ast_test_flag(chan, AST_FLAG_MASQ_NOSTREAM)) 00971 fs->orig_chan_name = ast_strdup(chan->name); 00972 if (ast_applystream(chan, fs)) 00973 return -1; 00974 if (vfs && ast_applystream(chan, vfs)) 00975 return -1; 00976 res = ast_playstream(fs); 00977 if (!res && vfs) 00978 res = ast_playstream(vfs); 00979 ast_verb(3, "<%s> Playing '%s.%s' (language '%s')\n", chan->name, filename, ast_getformatname(chan->writeformat), preflang ? preflang : "default"); 00980 00981 return res; 00982 }
off_t ast_tellstream | ( | struct ast_filestream * | fs | ) |
Tell where we are in a stream.
fs | fs to act on |
Definition at line 869 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 864 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 1319 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(), page_exec(), park_exec_full(), parkandannounce_exec(), pbx_builtin_background(), pl_odtworz_plik(), play_and_wait(), play_file(), play_record_review(), playback_exec(), privacy_exec(), retrydial_exec(), rpt_tele_thread(), s_streamwait3(), say_character_str_full(), say_digit_str_full(), say_phonetic_str_full(), saycharstr(), sayfile(), saynum(), select_item_menu(), send_morse(), send_tone_telemetry(), setup_privacy_args(), vm_authenticate(), and wait_file().
01320 { 01321 return waitstream_core(c, breakon, NULL, NULL, 0, -1, -1, NULL); 01322 }
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 1330 of file file.c.
References ast_channel::context, and waitstream_core().
Referenced by pbx_builtin_background().
01331 { 01332 /* Waitstream, with return in the case of a valid 1 digit extension */ 01333 /* in the current or specified context being pressed */ 01334 01335 if (!context) 01336 context = c->context; 01337 return waitstream_core(c, NULL, NULL, NULL, 0, 01338 -1, -1, context); 01339 }
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 1313 of file file.c.
References waitstream_core().
Referenced by ast_control_streamfile().
01314 { 01315 return waitstream_core(c, breakon, forward, reverse, ms, 01316 -1 /* no audiofd */, -1 /* no cmdfd */, NULL /* no context */); 01317 }
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 1324 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().
01325 { 01326 return waitstream_core(c, breakon, NULL, NULL, 0, 01327 audiofd, cmdfd, NULL /* no context */); 01328 }
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 1032 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(), recordthread(), and rpt().
01033 { 01034 int fd, myflags = 0; 01035 /* compiler claims this variable can be used before initialization... */ 01036 FILE *bfile = NULL; 01037 struct ast_format *f; 01038 struct ast_filestream *fs = NULL; 01039 char *buf = NULL; 01040 size_t size = 0; 01041 int format_found = 0; 01042 01043 AST_RWLIST_RDLOCK(&formats); 01044 01045 /* set the O_TRUNC flag if and only if there is no O_APPEND specified */ 01046 /* We really can't use O_APPEND as it will break WAV header updates */ 01047 if (flags & O_APPEND) { 01048 flags &= ~O_APPEND; 01049 } else { 01050 myflags = O_TRUNC; 01051 } 01052 01053 myflags |= O_WRONLY | O_CREAT; 01054 01055 /* XXX need to fix this - we should just do the fopen, 01056 * not open followed by fdopen() 01057 */ 01058 AST_RWLIST_TRAVERSE(&formats, f, list) { 01059 char *fn, *orig_fn = NULL; 01060 if (fs) 01061 break; 01062 01063 if (!exts_compare(f->exts, type)) 01064 continue; 01065 else 01066 format_found = 1; 01067 01068 fn = build_filename(filename, type); 01069 fd = open(fn, flags | myflags, mode); 01070 if (fd > -1) { 01071 /* fdopen() the resulting file stream */ 01072 bfile = fdopen(fd, ((flags | myflags) & O_RDWR) ? "w+" : "w"); 01073 if (!bfile) { 01074 ast_log(LOG_WARNING, "Whoa, fdopen failed: %s!\n", strerror(errno)); 01075 close(fd); 01076 fd = -1; 01077 } 01078 } 01079 01080 if (ast_opt_cache_record_files && (fd > -1)) { 01081 char *c; 01082 01083 fclose(bfile); /* this also closes fd */ 01084 /* 01085 We touch orig_fn just as a place-holder so other things (like vmail) see the file is there. 01086 What we are really doing is writing to record_cache_dir until we are done then we will mv the file into place. 01087 */ 01088 orig_fn = ast_strdupa(fn); 01089 for (c = fn; *c; c++) 01090 if (*c == '/') 01091 *c = '_'; 01092 01093 size = strlen(fn) + strlen(record_cache_dir) + 2; 01094 buf = alloca(size); 01095 strcpy(buf, record_cache_dir); 01096 strcat(buf, "/"); 01097 strcat(buf, fn); 01098 ast_free(fn); 01099 fn = buf; 01100 fd = open(fn, flags | myflags, mode); 01101 if (fd > -1) { 01102 /* fdopen() the resulting file stream */ 01103 bfile = fdopen(fd, ((flags | myflags) & O_RDWR) ? "w+" : "w"); 01104 if (!bfile) { 01105 ast_log(LOG_WARNING, "Whoa, fdopen failed: %s!\n", strerror(errno)); 01106 close(fd); 01107 fd = -1; 01108 } 01109 } 01110 } 01111 if (fd > -1) { 01112 errno = 0; 01113 fs = get_filestream(f, bfile); 01114 if (!fs || rewrite_wrapper(fs, comment)) { 01115 ast_log(LOG_WARNING, "Unable to rewrite %s\n", fn); 01116 close(fd); 01117 if (orig_fn) { 01118 unlink(fn); 01119 unlink(orig_fn); 01120 } 01121 if (fs) { 01122 ast_closestream(fs); 01123 fs = NULL; 01124 } 01125 continue; 01126 } 01127 fs->trans = NULL; 01128 fs->fmt = f; 01129 fs->flags = flags; 01130 fs->mode = mode; 01131 if (orig_fn) { 01132 fs->realfilename = ast_strdup(orig_fn); 01133 fs->filename = ast_strdup(fn); 01134 } else { 01135 fs->realfilename = NULL; 01136 fs->filename = ast_strdup(filename); 01137 } 01138 fs->vfs = NULL; 01139 /* If truncated, we'll be at the beginning; if not truncated, then append */ 01140 01141 if ((fs->write_buffer = ast_malloc(32768))){ 01142 setvbuf(fs->f, fs->write_buffer, _IOFBF, 32768); 01143 } 01144 01145 f->seek(fs, 0, SEEK_END); 01146 } else if (errno != EEXIST) { 01147 ast_log(LOG_WARNING, "Unable to open file %s: %s\n", fn, strerror(errno)); 01148 if (orig_fn) 01149 unlink(orig_fn); 01150 } 01151 /* if buf != NULL then fn is already free and pointing to it */ 01152 if (!buf) 01153 ast_free(fn); 01154 } 01155 01156 AST_RWLIST_UNLOCK(&formats); 01157 01158 if (!format_found) 01159 ast_log(LOG_WARNING, "No such format '%s'\n", type); 01160 01161 return fs; 01162 }
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 145 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(), recordthread(), and rpt().
00146 { 00147 int res = -1; 00148 int alt = 0; 00149 if (f->frametype == AST_FRAME_VIDEO) { 00150 if (fs->fmt->format & AST_FORMAT_AUDIO_MASK) { 00151 /* This is the audio portion. Call the video one... */ 00152 if (!fs->vfs && fs->filename) { 00153 const char *type = ast_getformatname(f->subclass.codec & ~0x1); 00154 fs->vfs = ast_writefile(fs->filename, type, NULL, fs->flags, 0, fs->mode); 00155 ast_debug(1, "Opened video output file\n"); 00156 } 00157 if (fs->vfs) 00158 return ast_writestream(fs->vfs, f); 00159 /* else ignore */ 00160 return 0; 00161 } else { 00162 /* Might / might not have mark set */ 00163 alt = 1; 00164 } 00165 } else if (f->frametype != AST_FRAME_VOICE) { 00166 ast_log(LOG_WARNING, "Tried to write non-voice frame\n"); 00167 return -1; 00168 } 00169 if (((fs->fmt->format | alt) & f->subclass.codec) == f->subclass.codec) { 00170 res = fs->fmt->write(fs, f); 00171 if (res < 0) 00172 ast_log(LOG_WARNING, "Natural write failed\n"); 00173 else if (res > 0) 00174 ast_log(LOG_WARNING, "Huh??\n"); 00175 } else { 00176 /* XXX If they try to send us a type of frame that isn't the normal frame, and isn't 00177 the one we've setup a translator for, we do the "wrong thing" XXX */ 00178 if (fs->trans && f->subclass.codec != fs->lastwriteformat) { 00179 ast_translator_free_path(fs->trans); 00180 fs->trans = NULL; 00181 } 00182 if (!fs->trans) 00183 fs->trans = ast_translator_build_path(fs->fmt->format, f->subclass.codec); 00184 if (!fs->trans) 00185 ast_log(LOG_WARNING, "Unable to translate to format %s, source format %s\n", 00186 fs->fmt->name, ast_getformatname(f->subclass.codec)); 00187 else { 00188 struct ast_frame *trf; 00189 fs->lastwriteformat = f->subclass.codec; 00190 /* Get the translated frame but don't consume the original in case they're using it on another stream */ 00191 if ((trf = ast_translate(fs->trans, f, 0))) { 00192 struct ast_frame *cur; 00193 00194 /* the translator may have returned multiple frames, so process them */ 00195 for (cur = trf; cur; cur = AST_LIST_NEXT(cur, frame_list)) { 00196 if ((res = fs->fmt->write(fs, trf))) { 00197 ast_log(LOG_WARNING, "Translated frame write failed\n"); 00198 break; 00199 } 00200 } 00201 ast_frfree(trf); 00202 } else { 00203 res = 0; 00204 } 00205 } 00206 } 00207 return res; 00208 }
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 253 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().
00254 { 00255 char *fn = NULL; 00256 00257 if (!strcmp(ext, "wav49")) 00258 ext = "WAV"; 00259 00260 if (filename[0] == '/') { 00261 if (asprintf(&fn, "%s.%s", filename, ext) < 0) { 00262 ast_log(LOG_WARNING, "asprintf() failed: %s\n", strerror(errno)); 00263 fn = NULL; 00264 } 00265 } else { 00266 if (asprintf(&fn, "%s/sounds/%s.%s", 00267 ast_config_AST_DATA_DIR, filename, ext) < 0) { 00268 ast_log(LOG_WARNING, "asprintf() failed: %s\n", strerror(errno)); 00269 fn = NULL; 00270 } 00271 } 00272 return fn; 00273 }
static int copy | ( | const char * | infile, | |
const char * | outfile | |||
) | [static] |
Definition at line 210 of file file.c.
References AST_FILE_MODE, ast_log(), errno, len(), and LOG_WARNING.
00211 { 00212 int ifd, ofd, len; 00213 char buf[4096]; /* XXX make it lerger. */ 00214 00215 if ((ifd = open(infile, O_RDONLY)) < 0) { 00216 ast_log(LOG_WARNING, "Unable to open %s in read-only mode\n", infile); 00217 return -1; 00218 } 00219 if ((ofd = open(outfile, O_WRONLY | O_TRUNC | O_CREAT, AST_FILE_MODE)) < 0) { 00220 ast_log(LOG_WARNING, "Unable to open %s in write-only mode\n", outfile); 00221 close(ifd); 00222 return -1; 00223 } 00224 while ( (len = read(ifd, buf, sizeof(buf)) ) ) { 00225 int res; 00226 if (len < 0) { 00227 ast_log(LOG_WARNING, "Read failed on %s: %s\n", infile, strerror(errno)); 00228 break; 00229 } 00230 /* XXX handle partial writes */ 00231 res = write(ofd, buf, len); 00232 if (res != len) { 00233 ast_log(LOG_WARNING, "Write failed on %s (%d of %d): %s\n", outfile, res, len, strerror(errno)); 00234 len = -1; /* error marker */ 00235 break; 00236 } 00237 } 00238 close(ifd); 00239 close(ofd); 00240 if (len < 0) { 00241 unlink(outfile); 00242 return -1; /* error */ 00243 } 00244 return 0; /* success */ 00245 }
static int exts_compare | ( | const char * | exts, | |
const char * | type | |||
) | [static] |
Definition at line 277 of file file.c.
References ast_copy_string(), ext, and strsep().
Referenced by ast_filehelper(), ast_format_str_reduce(), ast_readfile(), and ast_writefile().
00278 { 00279 char tmp[256]; 00280 char *stringp = tmp, *ext; 00281 00282 ast_copy_string(tmp, exts, sizeof(tmp)); 00283 while ((ext = strsep(&stringp, "|"))) { 00284 if (!strcmp(ext, type)) 00285 return 1; 00286 } 00287 00288 return 0; 00289 }
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 562 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().
00564 { 00565 format_t res = -1; 00566 char *lang; 00567 00568 if (buf == NULL) { 00569 return -1; 00570 } 00571 00572 /* We try languages in the following order: 00573 * preflang (may include dialect and style codes) 00574 * lang (preflang without dialect - if any) 00575 * <none> 00576 * default (unless the same as preflang or lang without dialect) 00577 */ 00578 00579 lang = ast_strdupa(preflang); 00580 00581 /* Try preferred language, including removing any style or dialect codes */ 00582 while (!ast_strlen_zero(lang)) { 00583 char *end; 00584 00585 if ((res = fileexists_test(filename, fmt, lang, buf, buflen)) > 0) { 00586 return res; 00587 } 00588 00589 if ((end = strrchr(lang, '_')) != NULL) { 00590 *end = '\0'; 00591 continue; 00592 } 00593 00594 break; 00595 } 00596 00597 /* Try without any language */ 00598 if ((res = fileexists_test(filename, fmt, NULL, buf, buflen)) > 0) { 00599 return res; 00600 } 00601 00602 /* Finally try the default language unless it was already tried before */ 00603 if ((ast_strlen_zero(preflang) || strcmp(preflang, DEFAULT_LANGUAGE)) && (ast_strlen_zero(lang) || strcmp(lang, DEFAULT_LANGUAGE))) { 00604 if ((res = fileexists_test(filename, fmt, DEFAULT_LANGUAGE, buf, buflen)) > 0) { 00605 return res; 00606 } 00607 } 00608 00609 return 0; 00610 }
static format_t fileexists_test | ( | const char * | filename, | |
const char * | fmt, | |||
const char * | lang, | |||
char * | buf, | |||
int | buflen | |||
) | [static] |
Definition at line 528 of file file.c.
References ACTION_EXISTS, ast_filehelper(), and is_absolute_path().
Referenced by fileexists_core().
00530 { 00531 if (buf == NULL) { 00532 return -1; 00533 } 00534 00535 if (ast_language_is_prefix && !is_absolute_path(filename)) { /* new layout */ 00536 if (lang) { 00537 snprintf(buf, buflen, "%s/%s", lang, filename); 00538 } else { 00539 snprintf(buf, buflen, "%s", filename); 00540 } 00541 } else { /* old layout */ 00542 strcpy(buf, filename); /* first copy the full string */ 00543 if (lang) { 00544 /* insert the language and suffix if needed */ 00545 const char *c = strrchr(filename, '/'); 00546 int offset = c ? c - filename + 1 : 0; /* points right after the last '/' */ 00547 snprintf(buf + offset, buflen - offset, "%s/%s", lang, filename + offset); 00548 } 00549 } 00550 00551 return ast_filehelper(buf, NULL, fmt, ACTION_EXISTS); 00552 }
static void filestream_destructor | ( | void * | arg | ) | [static] |
Definition at line 291 of file file.c.
References ast_closestream(), AST_FORMAT_AUDIO_MASK, ast_free, ast_module_unref(), ast_safe_fork(), AST_SCHED_DEL, ast_settimeout(), ast_translator_free_path(), ast_format::close, f, ast_format::format, free, ast_format::module, and SENTINEL.
Referenced by get_filestream().
00292 { 00293 struct ast_filestream *f = arg; 00294 00295 /* Stop a running stream if there is one */ 00296 if (f->owner) { 00297 if (f->fmt->format < AST_FORMAT_AUDIO_MASK) { 00298 f->owner->stream = NULL; 00299 AST_SCHED_DEL(f->owner->sched, f->owner->streamid); 00300 ast_settimeout(f->owner, 0, NULL, NULL); 00301 } else { 00302 f->owner->vstream = NULL; 00303 AST_SCHED_DEL(f->owner->sched, f->owner->vstreamid); 00304 } 00305 } 00306 /* destroy the translator on exit */ 00307 if (f->trans) 00308 ast_translator_free_path(f->trans); 00309 00310 if (f->realfilename && f->filename) { 00311 if (ast_safe_fork(0) == 0) { 00312 execl("/bin/mv", "mv", "-f", f->filename, f->realfilename, SENTINEL); 00313 } 00314 } 00315 00316 if (f->filename) 00317 free(f->filename); 00318 if (f->realfilename) 00319 free(f->realfilename); 00320 if (f->fmt->close) { 00321 void (*closefn)(struct ast_filestream *) = f->fmt->close; 00322 closefn(f); 00323 } 00324 if (f->f) 00325 fclose(f->f); 00326 if (f->vfs) 00327 ast_closestream(f->vfs); 00328 if (f->write_buffer) { 00329 ast_free(f->write_buffer); 00330 } 00331 if (f->orig_chan_name) 00332 free((void *) f->orig_chan_name); 00333 ast_module_unref(f->fmt->module); 00334 }
static int fn_wrapper | ( | struct ast_filestream * | s, | |
const char * | comment, | |||
enum wrap_fn | mode | |||
) | [static] |
Definition at line 360 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().
00361 { 00362 struct ast_format *f = s->fmt; 00363 int ret = -1; 00364 int (*openfn)(struct ast_filestream *s); 00365 00366 if (mode == WRAP_OPEN && (openfn = f->open) && openfn(s)) 00367 ast_log(LOG_WARNING, "Unable to open format %s\n", f->name); 00368 else if (mode == WRAP_REWRITE && f->rewrite && f->rewrite(s, comment)) 00369 ast_log(LOG_WARNING, "Unable to rewrite format %s\n", f->name); 00370 else { 00371 /* preliminary checks succeed. update usecount */ 00372 ast_module_ref(f->module); 00373 ret = 0; 00374 } 00375 return ret; 00376 }
static struct ast_filestream* get_filestream | ( | struct ast_format * | fmt, | |
FILE * | bfile | |||
) | [static] |
Definition at line 336 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().
00337 { 00338 struct ast_filestream *s; 00339 00340 int l = sizeof(*s) + fmt->buf_size + fmt->desc_size; /* total allocation size */ 00341 if ( (s = ao2_alloc(l, filestream_destructor)) == NULL) 00342 return NULL; 00343 s->fmt = fmt; 00344 s->f = bfile; 00345 00346 if (fmt->desc_size) 00347 s->_private = ((char *)(s + 1)) + fmt->buf_size; 00348 if (fmt->buf_size) 00349 s->buf = (char *)(s + 1); 00350 s->fr.src = fmt->name; 00351 return s; 00352 }
static char* handle_cli_core_show_file_formats | ( | struct ast_cli_entry * | e, | |
int | cmd, | |||
struct ast_cli_args * | a | |||
) | [static] |
Definition at line 1434 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.
01435 { 01436 #define FORMAT "%-10s %-10s %-20s\n" 01437 #define FORMAT2 "%-10s %-10s %-20s\n" 01438 struct ast_format *f; 01439 int count_fmt = 0; 01440 01441 switch (cmd) { 01442 case CLI_INIT: 01443 e->command = "core show file formats"; 01444 e->usage = 01445 "Usage: core show file formats\n" 01446 " Displays currently registered file formats (if any).\n"; 01447 return NULL; 01448 case CLI_GENERATE: 01449 return NULL; 01450 } 01451 01452 if (a->argc != 4) 01453 return CLI_SHOWUSAGE; 01454 01455 ast_cli(a->fd, FORMAT, "Format", "Name", "Extensions"); 01456 ast_cli(a->fd, FORMAT, "------", "----", "----------"); 01457 01458 AST_RWLIST_RDLOCK(&formats); 01459 AST_RWLIST_TRAVERSE(&formats, f, list) { 01460 ast_cli(a->fd, FORMAT2, ast_getformatname(f->format), f->name, f->exts); 01461 count_fmt++; 01462 } 01463 AST_RWLIST_UNLOCK(&formats); 01464 ast_cli(a->fd, "%d file formats registered.\n", count_fmt); 01465 return CLI_SUCCESS; 01466 #undef FORMAT 01467 #undef FORMAT2 01468 }
static int is_absolute_path | ( | const char * | filename | ) | [static] |
static int open_wrapper | ( | struct ast_filestream * | s | ) | [static] |
Definition at line 383 of file file.c.
References fn_wrapper(), and WRAP_OPEN.
Referenced by ast_filehelper(), and ast_readfile().
00384 { 00385 return fn_wrapper(s, NULL, WRAP_OPEN); 00386 }
static struct ast_frame* read_frame | ( | struct ast_filestream * | s, | |
int * | whennext | |||
) | [static] |
Definition at line 692 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().
00693 { 00694 struct ast_frame *fr, *new_fr; 00695 00696 if (!s || !s->fmt) { 00697 return NULL; 00698 } 00699 00700 if (!(fr = s->fmt->read(s, whennext))) { 00701 return NULL; 00702 } 00703 00704 if (!(new_fr = ast_frisolate(fr))) { 00705 ast_frfree(fr); 00706 return NULL; 00707 } 00708 00709 if (new_fr != fr) { 00710 ast_frfree(fr); 00711 fr = new_fr; 00712 } 00713 00714 return fr; 00715 }
static int rewrite_wrapper | ( | struct ast_filestream * | s, | |
const char * | comment | |||
) | [static] |
Definition at line 378 of file file.c.
References fn_wrapper().
Referenced by ast_writefile().
00379 { 00380 return fn_wrapper(s, comment, WRAP_REWRITE); 00381 }
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 1167 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_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().
01170 { 01171 const char *orig_chan_name = NULL; 01172 int err = 0; 01173 01174 if (!breakon) 01175 breakon = ""; 01176 if (!forward) 01177 forward = ""; 01178 if (!reverse) 01179 reverse = ""; 01180 01181 /* Switch the channel to end DTMF frame only. waitstream_core doesn't care about the start of DTMF. */ 01182 ast_set_flag(c, AST_FLAG_END_DTMF_ONLY); 01183 01184 if (ast_test_flag(c, AST_FLAG_MASQ_NOSTREAM)) 01185 orig_chan_name = ast_strdupa(c->name); 01186 01187 while (c->stream) { 01188 int res; 01189 int ms; 01190 01191 if (orig_chan_name && strcasecmp(orig_chan_name, c->name)) { 01192 ast_stopstream(c); 01193 err = 1; 01194 break; 01195 } 01196 01197 ms = ast_sched_wait(c->sched); 01198 01199 if (ms < 0 && !c->timingfunc) { 01200 ast_stopstream(c); 01201 break; 01202 } 01203 if (ms < 0) 01204 ms = 1000; 01205 if (cmdfd < 0) { 01206 res = ast_waitfor(c, ms); 01207 if (res < 0) { 01208 ast_log(LOG_WARNING, "Select failed (%s)\n", strerror(errno)); 01209 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 01210 return res; 01211 } 01212 } else { 01213 int outfd; 01214 struct ast_channel *rchan = ast_waitfor_nandfds(&c, 1, &cmdfd, (cmdfd > -1) ? 1 : 0, NULL, &outfd, &ms); 01215 if (!rchan && (outfd < 0) && (ms)) { 01216 /* Continue */ 01217 if (errno == EINTR) 01218 continue; 01219 ast_log(LOG_WARNING, "Wait failed (%s)\n", strerror(errno)); 01220 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 01221 return -1; 01222 } else if (outfd > -1) { /* this requires cmdfd set */ 01223 /* The FD we were watching has something waiting */ 01224 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 01225 return 1; 01226 } 01227 /* if rchan is set, it is 'c' */ 01228 res = rchan ? 1 : 0; /* map into 'res' values */ 01229 } 01230 if (res > 0) { 01231 struct ast_frame *fr = ast_read(c); 01232 if (!fr) { 01233 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 01234 return -1; 01235 } 01236 switch (fr->frametype) { 01237 case AST_FRAME_DTMF_END: 01238 if (context) { 01239 const char exten[2] = { fr->subclass.integer, '\0' }; 01240 if (ast_exists_extension(c, context, exten, 1, 01241 S_COR(c->caller.id.number.valid, c->caller.id.number.str, NULL))) { 01242 res = fr->subclass.integer; 01243 ast_frfree(fr); 01244 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 01245 return res; 01246 } 01247 } else { 01248 res = fr->subclass.integer; 01249 if (strchr(forward, res)) { 01250 int eoftest; 01251 ast_stream_fastforward(c->stream, skip_ms); 01252 eoftest = fgetc(c->stream->f); 01253 if (feof(c->stream->f)) { 01254 ast_stream_rewind(c->stream, skip_ms); 01255 } else { 01256 ungetc(eoftest, c->stream->f); 01257 } 01258 } else if (strchr(reverse, res)) { 01259 ast_stream_rewind(c->stream, skip_ms); 01260 } else if (strchr(breakon, res)) { 01261 ast_frfree(fr); 01262 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 01263 return res; 01264 } 01265 } 01266 break; 01267 case AST_FRAME_CONTROL: 01268 switch (fr->subclass.integer) { 01269 case AST_CONTROL_HANGUP: 01270 case AST_CONTROL_BUSY: 01271 case AST_CONTROL_CONGESTION: 01272 ast_frfree(fr); 01273 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 01274 return -1; 01275 case AST_CONTROL_RINGING: 01276 case AST_CONTROL_ANSWER: 01277 case AST_CONTROL_VIDUPDATE: 01278 case AST_CONTROL_SRCUPDATE: 01279 case AST_CONTROL_SRCCHANGE: 01280 case AST_CONTROL_HOLD: 01281 case AST_CONTROL_UNHOLD: 01282 case AST_CONTROL_CONNECTED_LINE: 01283 case AST_CONTROL_REDIRECTING: 01284 case AST_CONTROL_AOC: 01285 case -1: 01286 /* Unimportant */ 01287 break; 01288 default: 01289 ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", fr->subclass.integer); 01290 } 01291 break; 01292 case AST_FRAME_VOICE: 01293 /* Write audio if appropriate */ 01294 if (audiofd > -1) { 01295 if (write(audiofd, fr->data.ptr, fr->datalen) < 0) { 01296 ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno)); 01297 } 01298 } 01299 default: 01300 /* Ignore all others */ 01301 break; 01302 } 01303 ast_frfree(fr); 01304 } 01305 ast_sched_runq(c->sched); 01306 } 01307 01308 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 01309 01310 return (err || c->_softhangup) ? -1 : 0; 01311 }
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 1470 of file file.c.
Referenced by ast_file_init().