#include "asterisk.h"
#include <sys/types.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <fcntl.h>
#include <dirent.h>
#include <sys/stat.h>
#include "asterisk/frame.h"
#include "asterisk/file.h"
#include "asterisk/cli.h"
#include "asterisk/logger.h"
#include "asterisk/channel.h"
#include "asterisk/sched.h"
#include "asterisk/options.h"
#include "asterisk/translate.h"
#include "asterisk/utils.h"
#include "asterisk/lock.h"
#include "asterisk/app.h"
#include "asterisk/pbx.h"
#include "asterisk/linkedlists.h"
#include "asterisk/module.h"
Go to the source code of this file.
Defines | |
#define | FORMAT "%-10s %-10s %-20s\n" |
#define | FORMAT "%-10s %-10s %-20s\n" |
#define | FORMAT2 "%-10s %-10s %-20s\n" |
#define | FORMAT2 "%-10s %-10s %-20s\n" |
Enumerations | |
enum | file_action { ACTION_EXISTS = 1, ACTION_DELETE, ACTION_RENAME, ACTION_OPEN, ACTION_COPY } |
enum | wrap_fn { WRAP_OPEN, WRAP_REWRITE } |
Functions | |
int | __ast_format_register (const struct ast_format *f, struct ast_module *mod) |
int | ast_applystream (struct ast_channel *chan, struct ast_filestream *s) |
int | ast_closestream (struct ast_filestream *f) |
int | ast_file_init (void) |
int | ast_filecopy (const char *filename, const char *filename2, const char *fmt) |
int | ast_filedelete (const char *filename, const char *fmt) |
int | ast_fileexists (const char *filename, const char *fmt, const char *preflang) |
static int | ast_filehelper (const char *filename, const void *arg2, const char *fmt, const enum file_action action) |
perform various actions on a file. Second argument arg2 depends on the command: unused for EXISTS and DELETE destination file name (const char *) for COPY and RENAME struct ast_channel * for OPEN if fmt is NULL, OPEN will return the first matching entry, whereas other functions will run on all matching entries. | |
int | ast_filerename (const char *filename, const char *filename2, const char *fmt) |
int | ast_format_unregister (const char *name) |
static | AST_LIST_HEAD_STATIC (formats, ast_format) |
struct ast_filestream * | ast_openstream (struct ast_channel *chan, const char *filename, const char *preflang) |
struct ast_filestream * | ast_openstream_full (struct ast_channel *chan, const char *filename, const char *preflang, int asis) |
struct ast_filestream * | ast_openvstream (struct ast_channel *chan, const char *filename, const char *preflang) |
int | ast_playstream (struct ast_filestream *s) |
static int | ast_readaudio_callback (void *data) |
struct ast_filestream * | ast_readfile (const char *filename, const char *type, const char *comment, int flags, int check, mode_t mode) |
struct ast_frame * | ast_readframe (struct ast_filestream *s) |
static int | ast_readvideo_callback (void *data) |
int | ast_seekstream (struct ast_filestream *fs, off_t sample_offset, int whence) |
int | ast_stopstream (struct ast_channel *tmp) |
int | ast_stream_and_wait (struct ast_channel *chan, const char *file, const char *language, const char *digits) |
int | ast_stream_fastforward (struct ast_filestream *fs, off_t ms) |
int | ast_stream_rewind (struct ast_filestream *fs, off_t ms) |
int | ast_streamfile (struct ast_channel *chan, const char *filename, const char *preflang) |
off_t | ast_tellstream (struct ast_filestream *fs) |
int | ast_truncstream (struct ast_filestream *fs) |
int | ast_waitstream (struct ast_channel *c, const char *breakon) |
int | ast_waitstream_exten (struct ast_channel *c, const char *context) |
int | ast_waitstream_fr (struct ast_channel *c, const char *breakon, const char *forward, const char *rewind, int ms) |
int | ast_waitstream_full (struct ast_channel *c, const char *breakon, int audiofd, int cmdfd) |
struct ast_filestream * | ast_writefile (const char *filename, const char *type, const char *comment, int flags, int check, mode_t mode) |
int | ast_writestream (struct ast_filestream *fs, struct ast_frame *f) |
static char * | build_filename (const char *filename, const char *ext) |
construct a filename. Absolute pathnames are preserved, relative names are prefixed by the sounds/ directory. The wav49 suffix is replaced by 'WAV'. Returns a malloc'ed string to be freed by the caller. | |
static int | copy (const char *infile, const char *outfile) |
static int | exts_compare (const char *exts, const char *type) |
static int | fileexists_core (const char *filename, const char *fmt, const char *preflang, char *buf, int buflen) |
helper routine to locate a file with a given format and language preference. Try preflang, preflang with stripped '_' suffix, or NULL. In the standard asterisk, language goes just before the last component. In an alternative configuration, the language should be a prefix to the actual filename. | |
static int | fn_wrapper (struct ast_filestream *s, const char *comment, enum wrap_fn mode) |
static struct ast_filestream * | get_filestream (struct ast_format *fmt, FILE *bfile) |
static int | open_wrapper (struct ast_filestream *s) |
static int | rewrite_wrapper (struct ast_filestream *s, const char *comment) |
static int | show_file_formats (int fd, int argc, char *argv[]) |
static int | show_file_formats_deprecated (int fd, int argc, char *argv[]) |
static int | waitstream_core (struct ast_channel *c, const char *breakon, const char *forward, const char *rewind, int skip_ms, int audiofd, int cmdfd, const char *context) |
the core of all waitstream() functions | |
Variables | |
int | ast_language_is_prefix |
struct ast_cli_entry | cli_file [] |
struct ast_cli_entry | cli_show_file_formats_deprecated |
char | show_file_formats_usage [] |
Definition in file file.c.
#define FORMAT "%-10s %-10s %-20s\n" |
#define FORMAT "%-10s %-10s %-20s\n" |
#define FORMAT2 "%-10s %-10s %-20s\n" |
#define FORMAT2 "%-10s %-10s %-20s\n" |
Referenced by __iax2_show_peers(), __sip_show_channels(), _sip_show_peers(), dundi_show_mappings(), dundi_show_peers(), dundi_show_precache(), dundi_show_requests(), dundi_show_trans(), iax2_show_channels(), iax2_show_firmware(), iax2_show_registry(), iax2_show_users(), show_file_formats(), show_file_formats_deprecated(), show_image_formats(), show_image_formats_deprecated(), sip_show_inuse(), sip_show_registry(), zap_show_channels(), and zap_show_status().
enum file_action |
Definition at line 337 of file file.c.
00337 { 00338 ACTION_EXISTS = 1, /* return matching format if file exists, 0 otherwise */ 00339 ACTION_DELETE, /* delete file, return 0 on success, -1 on error */ 00340 ACTION_RENAME, /* rename file. return 0 on success, -1 on error */ 00341 ACTION_OPEN, 00342 ACTION_COPY /* copy file. return 0 on success, -1 on error */ 00343 };
enum wrap_fn |
int __ast_format_register | ( | const struct ast_format * | f, | |
struct ast_module * | mod | |||
) |
Register a new file format capability Adds a format to Asterisk's format abilities. returns 0 on success, -1 on failure
Definition at line 68 of file file.c.
00069 { 00070 struct ast_format *tmp; 00071 00072 if (AST_LIST_LOCK(&formats)) { 00073 ast_log(LOG_WARNING, "Unable to lock format list\n"); 00074 return -1; 00075 } 00076 AST_LIST_TRAVERSE(&formats, tmp, list) { 00077 if (!strcasecmp(f->name, tmp->name)) { 00078 AST_LIST_UNLOCK(&formats); 00079 ast_log(LOG_WARNING, "Tried to register '%s' format, already registered\n", f->name); 00080 return -1; 00081 } 00082 } 00083 if (!(tmp = ast_calloc(1, sizeof(*tmp)))) { 00084 AST_LIST_UNLOCK(&formats); 00085 return -1; 00086 } 00087 *tmp = *f; 00088 tmp->module = mod; 00089 if (tmp->buf_size) { 00090 /* 00091 * Align buf_size properly, rounding up to the machine-specific 00092 * alignment for pointers. 00093 */ 00094 struct _test_align { void *a, *b; } p; 00095 int align = (char *)&p.b - (char *)&p.a; 00096 tmp->buf_size = ((f->buf_size + align - 1)/align)*align; 00097 } 00098 00099 memset(&tmp->list, 0, sizeof(tmp->list)); 00100 00101 AST_LIST_INSERT_HEAD(&formats, tmp, list); 00102 AST_LIST_UNLOCK(&formats); 00103 if (option_verbose > 1) 00104 ast_verbose( VERBOSE_PREFIX_2 "Registered file format %s, extension(s) %s\n", f->name, f->exts); 00105 00106 return 0; 00107 }
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 Returns 0 for success, -1 on failure |
Definition at line 669 of file file.c.
Referenced by ast_streamfile(), handle_getoption(), handle_recordfile(), handle_streamfile(), and speech_streamfile().
00670 { 00671 s->owner = chan; 00672 return 0; 00673 }
int ast_closestream | ( | struct ast_filestream * | f | ) |
Closes a stream
f | filestream to close Close a playback or recording stream Returns 0 on success, -1 on failure |
Definition at line 709 of file file.c.
Referenced by __ast_play_and_record(), ast_closestream(), ast_filehelper(), ast_hangup(), ast_moh_files_next(), ast_monitor_start(), ast_monitor_stop(), ast_stopstream(), channel_spy(), cli_audio_convert(), cli_audio_convert_deprecated(), dictate_exec(), gen_closestream(), handle_recordfile(), local_ast_moh_stop(), mixmonitor_thread(), moh_files_release(), record_exec(), recordthread(), and rpt().
00710 { 00711 char *cmd = NULL; 00712 size_t size = 0; 00713 /* Stop a running stream if there is one */ 00714 if (f->owner) { 00715 if (f->fmt->format < AST_FORMAT_MAX_AUDIO) { 00716 f->owner->stream = NULL; 00717 if (f->owner->streamid > -1) 00718 ast_sched_del(f->owner->sched, f->owner->streamid); 00719 f->owner->streamid = -1; 00720 #ifdef HAVE_ZAPTEL 00721 ast_settimeout(f->owner, 0, NULL, NULL); 00722 #endif 00723 } else { 00724 f->owner->vstream = NULL; 00725 if (f->owner->vstreamid > -1) 00726 ast_sched_del(f->owner->sched, f->owner->vstreamid); 00727 f->owner->vstreamid = -1; 00728 } 00729 } 00730 /* destroy the translator on exit */ 00731 if (f->trans) 00732 ast_translator_free_path(f->trans); 00733 00734 if (f->realfilename && f->filename) { 00735 size = strlen(f->filename) + strlen(f->realfilename) + 15; 00736 cmd = alloca(size); 00737 memset(cmd,0,size); 00738 snprintf(cmd,size,"/bin/mv -f %s %s",f->filename,f->realfilename); 00739 ast_safe_system(cmd); 00740 } 00741 00742 if (f->filename) 00743 free(f->filename); 00744 if (f->realfilename) 00745 free(f->realfilename); 00746 if (f->fmt->close) 00747 f->fmt->close(f); 00748 fclose(f->f); 00749 if (f->vfs) 00750 ast_closestream(f->vfs); 00751 ast_module_unref(f->fmt->module); 00752 free(f); 00753 return 0; 00754 }
int ast_file_init | ( | void | ) |
Initialize file stuff
Initializes all the various file stuff. Basically just registers the cli stuff Returns 0 all the time
Definition at line 1210 of file file.c.
Referenced by main().
01211 { 01212 ast_cli_register_multiple(cli_file, sizeof(cli_file) / sizeof(struct ast_cli_entry)); 01213 return 0; 01214 }
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 784 of file file.c.
Referenced by copy_file().
00785 { 00786 return ast_filehelper(filename, filename2, fmt, ACTION_COPY); 00787 }
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 774 of file file.c.
Referenced by __ast_play_and_record(), ast_monitor_start(), ast_monitor_stop(), cli_audio_convert(), cli_audio_convert_deprecated(), conf_run(), leave_voicemail(), play_mailbox_owner(), play_record_review(), and vm_delete().
00775 { 00776 return ast_filehelper(filename, NULL, fmt, ACTION_DELETE); 00777 }
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. Returns -1 if file does not exist, non-zero positive otherwise. |
Definition at line 760 of file file.c.
Referenced by app_exec(), ast_moh_files_next(), ast_monitor_start(), ast_monitor_stop(), common_exec(), conf_run(), invent_message(), last_message_index(), leave_voicemail(), play_mailbox_owner(), play_message_callerid(), record_exec(), retrydial_exec(), say_character_str_full(), say_digit_str_full(), say_phonetic_str_full(), vm_intro(), vm_newuser(), and vm_tempgreeting().
00761 { 00762 char *buf; 00763 int buflen; 00764 00765 if (preflang == NULL) 00766 preflang = ""; 00767 buflen = strlen(preflang) + strlen(filename) + 2; /* room for everything */ 00768 buf = alloca(buflen); 00769 if (buf == NULL) 00770 return 0; 00771 return fileexists_core(filename, fmt, preflang, buf, buflen); 00772 }
static int ast_filehelper | ( | const char * | filename, | |
const void * | arg2, | |||
const char * | fmt, | |||
const enum file_action | action | |||
) | [static] |
perform various actions on a file. Second argument arg2 depends on the command: unused for EXISTS and DELETE destination file name (const char *) for COPY and RENAME struct ast_channel * for OPEN if fmt is NULL, OPEN will return the first matching entry, whereas other functions will run on all matching entries.
Definition at line 354 of file file.c.
References ACTION_COPY, ACTION_DELETE, ACTION_EXISTS, ACTION_OPEN, ACTION_RENAME, ast_closestream(), AST_FORMAT_MAX_AUDIO, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_strdupa, build_filename(), copy(), ext, ast_format::exts, exts_compare(), f, ast_filestream::filename, ast_filestream::fmt, ast_format::format, free, get_filestream(), ast_filestream::lasttimeout, LOG_WARNING, open_wrapper(), s, 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_core().
00355 { 00356 struct ast_format *f; 00357 int res = (action == ACTION_EXISTS) ? 0 : -1; 00358 00359 if (AST_LIST_LOCK(&formats)) { 00360 ast_log(LOG_WARNING, "Unable to lock format list\n"); 00361 return res; 00362 } 00363 /* Check for a specific format */ 00364 AST_LIST_TRAVERSE(&formats, f, list) { 00365 char *stringp, *ext = NULL; 00366 00367 if (fmt && !exts_compare(f->exts, fmt)) 00368 continue; 00369 00370 /* Look for a file matching the supported extensions. 00371 * The file must exist, and for OPEN, must match 00372 * one of the formats supported by the channel. 00373 */ 00374 stringp = ast_strdupa(f->exts); /* this is in the stack so does not need to be freed */ 00375 while ( (ext = strsep(&stringp, "|")) ) { 00376 struct stat st; 00377 char *fn = build_filename(filename, ext); 00378 00379 if (fn == NULL) 00380 continue; 00381 00382 if ( stat(fn, &st) ) { /* file not existent */ 00383 free(fn); 00384 continue; 00385 } 00386 /* for 'OPEN' we need to be sure that the format matches 00387 * what the channel can process 00388 */ 00389 if (action == ACTION_OPEN) { 00390 struct ast_channel *chan = (struct ast_channel *)arg2; 00391 FILE *bfile; 00392 struct ast_filestream *s; 00393 00394 if ( !(chan->writeformat & f->format) && 00395 !(f->format >= AST_FORMAT_MAX_AUDIO && fmt)) { 00396 free(fn); 00397 continue; /* not a supported format */ 00398 } 00399 if ( (bfile = fopen(fn, "r")) == NULL) { 00400 free(fn); 00401 continue; /* cannot open file */ 00402 } 00403 s = get_filestream(f, bfile); 00404 if (!s) { 00405 fclose(bfile); 00406 free(fn); /* cannot allocate descriptor */ 00407 continue; 00408 } 00409 if (open_wrapper(s)) { 00410 fclose(bfile); 00411 free(fn); 00412 free(s); 00413 continue; /* cannot run open on file */ 00414 } 00415 /* ok this is good for OPEN */ 00416 res = 1; /* found */ 00417 s->lasttimeout = -1; 00418 s->fmt = f; 00419 s->trans = NULL; 00420 s->filename = NULL; 00421 if (s->fmt->format < AST_FORMAT_MAX_AUDIO) { 00422 if (chan->stream) 00423 ast_closestream(chan->stream); 00424 chan->stream = s; 00425 } else { 00426 if (chan->vstream) 00427 ast_closestream(chan->vstream); 00428 chan->vstream = s; 00429 } 00430 free(fn); 00431 break; 00432 } 00433 switch (action) { 00434 case ACTION_OPEN: 00435 break; /* will never get here */ 00436 00437 case ACTION_EXISTS: /* return the matching format */ 00438 res |= f->format; 00439 break; 00440 00441 case ACTION_DELETE: 00442 if ( (res = unlink(fn)) ) 00443 ast_log(LOG_WARNING, "unlink(%s) failed: %s\n", fn, strerror(errno)); 00444 break; 00445 00446 case ACTION_RENAME: 00447 case ACTION_COPY: { 00448 char *nfn = build_filename((const char *)arg2, ext); 00449 if (!nfn) 00450 ast_log(LOG_WARNING, "Out of memory\n"); 00451 else { 00452 res = action == ACTION_COPY ? copy(fn, nfn) : rename(fn, nfn); 00453 if (res) 00454 ast_log(LOG_WARNING, "%s(%s,%s) failed: %s\n", 00455 action == ACTION_COPY ? "copy" : "rename", 00456 fn, nfn, strerror(errno)); 00457 free(nfn); 00458 } 00459 } 00460 break; 00461 00462 default: 00463 ast_log(LOG_WARNING, "Unknown helper %d\n", action); 00464 } 00465 free(fn); 00466 } 00467 } 00468 AST_LIST_UNLOCK(&formats); 00469 return res; 00470 }
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 Returns -1 on failure |
Definition at line 779 of file file.c.
Referenced by __ast_play_and_record(), ast_monitor_stop(), leave_voicemail(), play_record_review(), and rename_file().
00780 { 00781 return ast_filehelper(filename, filename2, fmt, ACTION_RENAME); 00782 }
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. Returns 0 on success, -1 on failure to unregister |
Definition at line 109 of file file.c.
Referenced by unload_module().
00110 { 00111 struct ast_format *tmp; 00112 int res = -1; 00113 00114 if (AST_LIST_LOCK(&formats)) { 00115 ast_log(LOG_WARNING, "Unable to lock format list\n"); 00116 return -1; 00117 } 00118 AST_LIST_TRAVERSE_SAFE_BEGIN(&formats, tmp, list) { 00119 if (!strcasecmp(name, tmp->name)) { 00120 AST_LIST_REMOVE_CURRENT(&formats, list); 00121 free(tmp); 00122 res = 0; 00123 } 00124 } 00125 AST_LIST_TRAVERSE_SAFE_END 00126 AST_LIST_UNLOCK(&formats); 00127 00128 if (!res) { 00129 if (option_verbose > 1) 00130 ast_verbose( VERBOSE_PREFIX_2 "Unregistered format %s\n", name); 00131 } else 00132 ast_log(LOG_WARNING, "Tried to unregister format %s, already unregistered\n", name); 00133 00134 return res; 00135 }
static AST_LIST_HEAD_STATIC | ( | formats | , | |
ast_format | ||||
) | [static] |
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 Returns a ast_filestream pointer if it opens the file, NULL on error |
Definition at line 532 of file file.c.
Referenced by ast_streamfile(), dictate_exec(), handle_getoption(), handle_streamfile(), and speech_streamfile().
00533 { 00534 return ast_openstream_full(chan, filename, preflang, 0); 00535 }
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 Returns a ast_filestream pointer if it opens the file, NULL on error |
Definition at line 537 of file file.c.
Referenced by ast_moh_files_next(), ast_openstream(), channel_spy(), and gen_nextfile().
00538 { 00539 /* 00540 * Use fileexists_core() to find a file in a compatible 00541 * language and format, set up a suitable translator, 00542 * and open the stream. 00543 */ 00544 int fmts, res, buflen; 00545 char *buf; 00546 00547 if (!asis) { 00548 /* do this first, otherwise we detect the wrong writeformat */ 00549 ast_stopstream(chan); 00550 if (chan->generator) 00551 ast_deactivate_generator(chan); 00552 } 00553 if (preflang == NULL) 00554 preflang = ""; 00555 buflen = strlen(preflang) + strlen(filename) + 2; 00556 buf = alloca(buflen); 00557 if (buf == NULL) 00558 return NULL; 00559 fmts = fileexists_core(filename, NULL, preflang, buf, buflen); 00560 if (fmts > 0) 00561 fmts &= AST_FORMAT_AUDIO_MASK; 00562 if (fmts < 1) { 00563 ast_log(LOG_WARNING, "File %s does not exist in any format\n", filename); 00564 return NULL; 00565 } 00566 chan->oldwriteformat = chan->writeformat; 00567 /* Set the channel to a format we can work with */ 00568 res = ast_set_write_format(chan, fmts); 00569 res = ast_filehelper(buf, chan, NULL, ACTION_OPEN); 00570 if (res >= 0) 00571 return chan->stream; 00572 return NULL; 00573 }
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 Returns a ast_filestream pointer if it opens the file, NULL on error |
Definition at line 575 of file file.c.
Referenced by ast_streamfile(), handle_getoption(), and handle_streamfile().
00576 { 00577 /* As above, but for video. But here we don't have translators 00578 * so we must enforce a format. 00579 */ 00580 unsigned int format; 00581 char *buf; 00582 int buflen; 00583 00584 if (preflang == NULL) 00585 preflang = ""; 00586 buflen = strlen(preflang) + strlen(filename) + 2; 00587 buf = alloca(buflen); 00588 if (buf == NULL) 00589 return NULL; 00590 00591 for (format = AST_FORMAT_MAX_AUDIO << 1; format <= AST_FORMAT_MAX_VIDEO; format = format << 1) { 00592 int fd; 00593 const char *fmt; 00594 00595 if (!(chan->nativeformats & format)) 00596 continue; 00597 fmt = ast_getformatname(format); 00598 if ( fileexists_core(filename, fmt, preflang, buf, buflen) < 1) /* no valid format */ 00599 continue; 00600 fd = ast_filehelper(buf, chan, fmt, ACTION_OPEN); 00601 if (fd >= 0) 00602 return chan->vstream; 00603 ast_log(LOG_WARNING, "File %s has video but couldn't be opened\n", filename); 00604 } 00605 return NULL; 00606 }
int ast_playstream | ( | struct ast_filestream * | s | ) |
play a open stream on a channel.
s | filestream to play Returns 0 for success, -1 on failure |
Definition at line 675 of file file.c.
Referenced by ast_streamfile(), handle_getoption(), handle_streamfile(), and speech_streamfile().
00676 { 00677 if (s->fmt->format < AST_FORMAT_MAX_AUDIO) 00678 ast_readaudio_callback(s); 00679 else 00680 ast_readvideo_callback(s); 00681 return 0; 00682 }
static int ast_readaudio_callback | ( | void * | data | ) | [static] |
Definition at line 617 of file file.c.
References ast_log(), ast_sched_add(), ast_settimeout(), ast_write(), ast_filestream::fmt, ast_filestream::lasttimeout, LOG_WARNING, ast_filestream::owner, ast_format::read, s, ast_channel::sched, ast_channel::streamid, and ast_channel::timingfd.
Referenced by ast_playstream().
00618 { 00619 struct ast_filestream *s = data; 00620 int whennext = 0; 00621 00622 while(!whennext) { 00623 struct ast_frame *fr = s->fmt->read(s, &whennext); 00624 if (!fr /* stream complete */ || ast_write(s->owner, fr) /* error writing */) { 00625 if (fr) 00626 ast_log(LOG_WARNING, "Failed to write frame\n"); 00627 s->owner->streamid = -1; 00628 #ifdef HAVE_ZAPTEL 00629 ast_settimeout(s->owner, 0, NULL, NULL); 00630 #endif 00631 return 0; 00632 } 00633 } 00634 if (whennext != s->lasttimeout) { 00635 #ifdef HAVE_ZAPTEL 00636 if (s->owner->timingfd > -1) 00637 ast_settimeout(s->owner, whennext, ast_readaudio_callback, s); 00638 else 00639 #endif 00640 s->owner->streamid = ast_sched_add(s->owner->sched, whennext/8, ast_readaudio_callback, s); 00641 s->lasttimeout = whennext; 00642 return 0; 00643 } 00644 return 1; 00645 }
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. Returns a struct ast_filestream on success, NULL on failure |
Definition at line 817 of file file.c.
Referenced by __ast_play_and_record(), cli_audio_convert(), and cli_audio_convert_deprecated().
00818 { 00819 FILE *bfile; 00820 struct ast_format *f; 00821 struct ast_filestream *fs = NULL; 00822 char *fn; 00823 00824 if (AST_LIST_LOCK(&formats)) { 00825 ast_log(LOG_WARNING, "Unable to lock format list\n"); 00826 return NULL; 00827 } 00828 00829 AST_LIST_TRAVERSE(&formats, f, list) { 00830 fs = NULL; 00831 if (!exts_compare(f->exts, type)) 00832 continue; 00833 00834 fn = build_filename(filename, type); 00835 errno = 0; 00836 bfile = fopen(fn, "r"); 00837 if (!bfile || (fs = get_filestream(f, bfile)) == NULL || 00838 open_wrapper(fs) ) { 00839 ast_log(LOG_WARNING, "Unable to open %s\n", fn); 00840 if (fs) 00841 ast_free(fs); 00842 if (bfile) 00843 fclose(bfile); 00844 free(fn); 00845 continue; 00846 } 00847 /* found it */ 00848 fs->trans = NULL; 00849 fs->fmt = f; 00850 fs->flags = flags; 00851 fs->mode = mode; 00852 fs->filename = strdup(filename); 00853 fs->vfs = NULL; 00854 break; 00855 } 00856 00857 AST_LIST_UNLOCK(&formats); 00858 if (!fs) 00859 ast_log(LOG_WARNING, "No such format '%s'\n", type); 00860 00861 return fs; 00862 }
struct ast_frame* ast_readframe | ( | struct ast_filestream * | s | ) | [read] |
Read a frame from a filestream
s | ast_filestream to act on Returns a frame or NULL if read failed |
Definition at line 608 of file file.c.
Referenced by __ast_play_and_record(), channel_spy(), cli_audio_convert(), cli_audio_convert_deprecated(), dictate_exec(), gen_readframe(), and moh_files_readframe().
00609 { 00610 struct ast_frame *f = NULL; 00611 int whennext = 0; 00612 if (s && s->fmt) 00613 f = s->fmt->read(s, &whennext); 00614 return f; 00615 }
static int ast_readvideo_callback | ( | void * | data | ) | [static] |
Definition at line 647 of file file.c.
References ast_log(), ast_sched_add(), ast_write(), ast_filestream::fmt, ast_filestream::lasttimeout, LOG_WARNING, ast_filestream::owner, ast_format::read, s, ast_channel::sched, and ast_channel::vstreamid.
Referenced by ast_playstream().
00648 { 00649 struct ast_filestream *s = data; 00650 int whennext = 0; 00651 00652 while (!whennext) { 00653 struct ast_frame *fr = s->fmt->read(s, &whennext); 00654 if (!fr || ast_write(s->owner, fr)) { /* no stream or error, as above */ 00655 if (fr) 00656 ast_log(LOG_WARNING, "Failed to write frame\n"); 00657 s->owner->vstreamid = -1; 00658 return 0; 00659 } 00660 } 00661 if (whennext != s->lasttimeout) { 00662 s->owner->vstreamid = ast_sched_add(s->owner->sched, whennext/8, ast_readvideo_callback, s); 00663 s->lasttimeout = whennext; 00664 return 0; 00665 } 00666 return 1; 00667 }
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 Returns 0 for success, or -1 for error |
Definition at line 684 of file file.c.
Referenced by __ast_read(), ast_control_streamfile(), ast_moh_files_next(), ast_stream_fastforward(), ast_stream_rewind(), ast_write(), dictate_exec(), handle_getoption(), handle_recordfile(), and handle_streamfile().
int ast_stopstream | ( | struct ast_channel * | c | ) |
Stops a stream
c | The channel you wish to stop playback on Stop playback of a stream Returns 0 regardless |
Definition at line 137 of file file.c.
Referenced by app_exec(), 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_number_full_cz(), 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_ge(), ast_say_number_full_gr(), ast_say_number_full_he(), ast_say_number_full_it(), 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_tw(), background_detect_exec(), builtin_blindtransfer(), conf_exec(), conf_run(), directory_exec(), handle_getoption(), handle_streamfile(), ices_exec(), ivr_dispatch(), leave_voicemail(), mp3_exec(), NBScat_exec(), parkandannounce_exec(), pbx_builtin_background(), pl_odtworz_plik(), play_file(), play_mailbox_owner(), playback_exec(), queue_exec(), read_exec(), record_exec(), recordthread(), rpt_tele_thread(), s_streamwait3(), say_character_str_full(), say_digit_str_full(), say_phonetic_str_full(), saycharstr(), sayfile(), saynum(), send_morse(), send_tone_telemetry(), send_waveform_to_channel(), speech_background(), vm_authenticate(), vm_execmain(), wait_for_winner(), waitstream_core(), and zapateller_exec().
00138 { 00139 /* Stop a running stream if there is one */ 00140 if (tmp->stream) { 00141 ast_closestream(tmp->stream); 00142 tmp->stream = NULL; 00143 if (tmp->oldwriteformat && ast_set_write_format(tmp, tmp->oldwriteformat)) 00144 ast_log(LOG_WARNING, "Unable to restore format back to %d\n", tmp->oldwriteformat); 00145 } 00146 /* Stop the video stream too */ 00147 if (tmp->vstream != NULL) { 00148 ast_closestream(tmp->vstream); 00149 tmp->vstream = NULL; 00150 } 00151 return 0; 00152 }
int ast_stream_and_wait | ( | struct ast_channel * | chan, | |
const char * | file, | |||
const char * | language, | |||
const char * | digits | |||
) |
Definition at line 1129 of file file.c.
Referenced by __ast_play_and_record(), app_exec(), ast_record_review(), bridge_playfile(), builtin_atxfer(), builtin_automonitor(), builtin_blindtransfer(), directory_exec(), invent_message(), ivr_dispatch(), leave_voicemail(), park_exec(), play_mailbox_owner(), play_message_callerid(), play_record_review(), and wait_file2().
01131 { 01132 int res = 0; 01133 if (!ast_strlen_zero(file)) { 01134 res = ast_streamfile(chan, file, language); 01135 if (!res) 01136 res = ast_waitstream(chan, digits); 01137 } 01138 return res; 01139 }
int ast_stream_fastforward | ( | struct ast_filestream * | fs, | |
off_t | ms | |||
) |
Fast forward stream ms
fs | filestream to act on | |
ms | milliseconds to move Returns 0 for success, or -1 for error |
Definition at line 699 of file file.c.
Referenced by waitstream_core().
00700 { 00701 return ast_seekstream(fs, ms * DEFAULT_SAMPLES_PER_MS, SEEK_CUR); 00702 }
int ast_stream_rewind | ( | struct ast_filestream * | fs, | |
off_t | ms | |||
) |
Rewind stream ms
fs | filestream to act on | |
ms | milliseconds to move Returns 0 for success, or -1 for error |
Definition at line 704 of file file.c.
Referenced by __ast_play_and_record(), handle_recordfile(), record_exec(), and waitstream_core().
00705 { 00706 return ast_seekstream(fs, -ms * DEFAULT_SAMPLES_PER_MS, SEEK_CUR); 00707 }
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. Returns 0 on success, or -1 on failure. |
Definition at line 789 of file file.c.
Referenced by __login_exec(), agent_call(), 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_ge(), ast_say_date_gr(), ast_say_date_nl(), ast_say_date_with_format_gr(), ast_say_datetime_en(), ast_say_datetime_fr(), ast_say_datetime_from_now_en(), ast_say_datetime_from_now_fr(), ast_say_datetime_from_now_ge(), ast_say_datetime_gr(), ast_say_datetime_nl(), ast_say_datetime_pt(), ast_say_datetime_tw(), ast_say_enumeration_full_da(), ast_say_enumeration_full_de(), ast_say_enumeration_full_en(), ast_say_number_full_cz(), 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_ge(), ast_say_number_full_gr(), ast_say_number_full_he(), ast_say_number_full_it(), 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_tw(), ast_say_time_de(), ast_say_time_en(), ast_say_time_fr(), ast_say_time_ge(), ast_say_time_gr(), ast_say_time_nl(), ast_say_time_tw(), ast_stream_and_wait(), auth_exec(), background_detect_exec(), check_availability(), check_beep(), common_exec(), conf_exec(), conf_run(), do_directory(), forward_message(), gr_say_number_female(), handle_recordfile(), leave_voicemail(), page_exec(), park_exec(), parkandannounce_exec(), pbx_builtin_background(), pl_odtworz_plik(), play_and_wait(), play_file(), playback_exec(), privacy_exec(), record_exec(), retrydial_exec(), rpt_tele_thread(), s_streamwait3(), say_character_str_full(), say_digit_str_full(), say_phonetic_str_full(), sayfile(), ss_thread(), vm_authenticate(), wait_file(), and wait_for_winner().
00790 { 00791 struct ast_filestream *fs; 00792 struct ast_filestream *vfs=NULL; 00793 char fmt[256]; 00794 00795 fs = ast_openstream(chan, filename, preflang); 00796 if (fs) 00797 vfs = ast_openvstream(chan, filename, preflang); 00798 if (vfs) 00799 ast_log(LOG_DEBUG, "Ooh, found a video stream, too, format %s\n", ast_getformatname(vfs->fmt->format)); 00800 if (fs){ 00801 if (ast_applystream(chan, fs)) 00802 return -1; 00803 if (vfs && ast_applystream(chan, vfs)) 00804 return -1; 00805 ast_playstream(fs); 00806 if (vfs) 00807 ast_playstream(vfs); 00808 if (option_verbose > 2) 00809 ast_verbose(VERBOSE_PREFIX_3 "<%s> Playing '%s' (language '%s')\n", chan->name, filename, preflang ? preflang : "default"); 00810 00811 return 0; 00812 } 00813 ast_log(LOG_WARNING, "Unable to open %s (format %s): %s\n", filename, ast_getformatname_multiple(fmt, sizeof(fmt), chan->nativeformats), strerror(errno)); 00814 return -1; 00815 }
off_t ast_tellstream | ( | struct ast_filestream * | fs | ) |
Tell where we are in a stream
fs | fs to act on Returns a long as a sample offset into stream |
Definition at line 694 of file file.c.
Referenced by ast_control_streamfile(), handle_getoption(), handle_recordfile(), and handle_streamfile().
int ast_truncstream | ( | struct ast_filestream * | fs | ) |
Trunc stream at current location
fs | filestream to act on Returns 0 for success, or -1 for error |
Definition at line 689 of file file.c.
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, Returns 0 if the stream finishes, the character if it was interrupted, and -1 on error |
Definition at line 1102 of file file.c.
Referenced by __login_exec(), agent_call(), 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_ge(), ast_say_date_gr(), ast_say_date_nl(), ast_say_date_with_format_gr(), ast_say_datetime_en(), ast_say_datetime_fr(), ast_say_datetime_from_now_en(), ast_say_datetime_from_now_fr(), ast_say_datetime_from_now_ge(), ast_say_datetime_gr(), ast_say_datetime_nl(), ast_say_datetime_pt(), ast_say_datetime_tw(), ast_say_enumeration_full_da(), ast_say_enumeration_full_de(), ast_say_enumeration_full_en(), ast_say_number_full_cz(), 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_ge(), ast_say_number_full_gr(), ast_say_number_full_he(), ast_say_number_full_it(), 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_tw(), ast_say_time_de(), ast_say_time_en(), ast_say_time_ge(), ast_say_time_gr(), ast_say_time_nl(), ast_say_time_tw(), ast_stream_and_wait(), auth_exec(), check_availability(), check_beep(), common_exec(), conf_exec(), conf_run(), directory_exec(), gr_say_number_female(), handle_recordfile(), leave_voicemail(), page_exec(), park_exec(), parkandannounce_exec(), pbx_builtin_background(), pl_odtworz_plik(), play_and_wait(), play_file(), playback_exec(), privacy_exec(), record_exec(), retrydial_exec(), rpt_tele_thread(), s_streamwait3(), say_character_str_full(), say_digit_str_full(), say_phonetic_str_full(), saycharstr(), sayfile(), saynum(), send_morse(), send_tone_telemetry(), ss_thread(), vm_authenticate(), and wait_file().
01103 { 01104 return waitstream_core(c, breakon, NULL, NULL, 0, -1, -1, NULL); 01105 }
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, Returns 0 if the stream finishes, the character if it was interrupted, and -1 on error |
Definition at line 1113 of file file.c.
Referenced by pbx_builtin_background().
01114 { 01115 /* Waitstream, with return in the case of a valid 1 digit extension */ 01116 /* in the current or specified context being pressed */ 01117 01118 if (!context) 01119 context = c->context; 01120 return waitstream_core(c, NULL, NULL, NULL, 0, 01121 -1, -1, context); 01122 }
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, Returns 0 if the stream finishes, the character if it was interrupted, and -1 on error |
Definition at line 1096 of file file.c.
Referenced by ast_control_streamfile().
01097 { 01098 return waitstream_core(c, breakon, forward, rewind, ms, 01099 -1 /* no audiofd */, -1 /* no cmdfd */, NULL /* no context */); 01100 }
int ast_waitstream_full | ( | struct ast_channel * | c, | |
const char * | breakon, | |||
int | audiofd, | |||
int | cmdfd | |||
) |
Definition at line 1107 of file file.c.
Referenced by ast_readstring_full(), ast_say_enumeration_full_da(), ast_say_enumeration_full_de(), ast_say_enumeration_full_en(), ast_say_number_full_cz(), 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_ge(), ast_say_number_full_gr(), ast_say_number_full_he(), ast_say_number_full_it(), 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_tw(), handle_getoption(), handle_streamfile(), pl_odtworz_plik(), s_streamwait3(), say_character_str_full(), say_digit_str_full(), and say_phonetic_str_full().
01108 { 01109 return waitstream_core(c, breakon, NULL, NULL, 0, 01110 audiofd, cmdfd, NULL /* no context */); 01111 }
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. Returns a struct ast_filestream on success, NULL on failure |
Definition at line 864 of file file.c.
Referenced by __ast_play_and_record(), ast_monitor_start(), ast_writestream(), cli_audio_convert(), cli_audio_convert_deprecated(), dictate_exec(), handle_recordfile(), mixmonitor_thread(), record_exec(), recordthread(), and rpt().
00865 { 00866 int fd, myflags = 0; 00867 /* compiler claims this variable can be used before initialization... */ 00868 FILE *bfile = NULL; 00869 struct ast_format *f; 00870 struct ast_filestream *fs = NULL; 00871 char *buf = NULL; 00872 size_t size = 0; 00873 int format_found = 0; 00874 00875 if (AST_LIST_LOCK(&formats)) { 00876 ast_log(LOG_WARNING, "Unable to lock format list\n"); 00877 return NULL; 00878 } 00879 00880 /* set the O_TRUNC flag if and only if there is no O_APPEND specified */ 00881 /* We really can't use O_APPEND as it will break WAV header updates */ 00882 if (flags & O_APPEND) { 00883 flags &= ~O_APPEND; 00884 } else { 00885 myflags = O_TRUNC; 00886 } 00887 00888 myflags |= O_WRONLY | O_CREAT; 00889 00890 /* XXX need to fix this - we should just do the fopen, 00891 * not open followed by fdopen() 00892 */ 00893 AST_LIST_TRAVERSE(&formats, f, list) { 00894 char *fn, *orig_fn = NULL; 00895 if (fs) 00896 break; 00897 00898 if (!exts_compare(f->exts, type)) 00899 continue; 00900 else 00901 format_found = 1; 00902 00903 fn = build_filename(filename, type); 00904 fd = open(fn, flags | myflags, mode); 00905 if (fd > -1) { 00906 /* fdopen() the resulting file stream */ 00907 bfile = fdopen(fd, ((flags | myflags) & O_RDWR) ? "w+" : "w"); 00908 if (!bfile) { 00909 ast_log(LOG_WARNING, "Whoa, fdopen failed: %s!\n", strerror(errno)); 00910 close(fd); 00911 fd = -1; 00912 } 00913 } 00914 00915 if (ast_opt_cache_record_files && (fd > -1)) { 00916 char *c; 00917 00918 fclose(bfile); /* this also closes fd */ 00919 /* 00920 We touch orig_fn just as a place-holder so other things (like vmail) see the file is there. 00921 What we are really doing is writing to record_cache_dir until we are done then we will mv the file into place. 00922 */ 00923 orig_fn = ast_strdupa(fn); 00924 for (c = fn; *c; c++) 00925 if (*c == '/') 00926 *c = '_'; 00927 00928 size = strlen(fn) + strlen(record_cache_dir) + 2; 00929 buf = alloca(size); 00930 strcpy(buf, record_cache_dir); 00931 strcat(buf, "/"); 00932 strcat(buf, fn); 00933 free(fn); 00934 fn = buf; 00935 fd = open(fn, flags | myflags, mode); 00936 if (fd > -1) { 00937 /* fdopen() the resulting file stream */ 00938 bfile = fdopen(fd, ((flags | myflags) & O_RDWR) ? "w+" : "w"); 00939 if (!bfile) { 00940 ast_log(LOG_WARNING, "Whoa, fdopen failed: %s!\n", strerror(errno)); 00941 close(fd); 00942 fd = -1; 00943 } 00944 } 00945 } 00946 if (fd > -1) { 00947 errno = 0; 00948 fs = get_filestream(f, bfile); 00949 if (!fs || rewrite_wrapper(fs, comment)) { 00950 ast_log(LOG_WARNING, "Unable to rewrite %s\n", fn); 00951 close(fd); 00952 if (orig_fn) { 00953 unlink(fn); 00954 unlink(orig_fn); 00955 } 00956 if (fs) 00957 ast_free(fs); 00958 fs = NULL; 00959 continue; 00960 } 00961 fs->trans = NULL; 00962 fs->fmt = f; 00963 fs->flags = flags; 00964 fs->mode = mode; 00965 if (orig_fn) { 00966 fs->realfilename = strdup(orig_fn); 00967 fs->filename = strdup(fn); 00968 } else { 00969 fs->realfilename = NULL; 00970 fs->filename = strdup(filename); 00971 } 00972 fs->vfs = NULL; 00973 /* If truncated, we'll be at the beginning; if not truncated, then append */ 00974 f->seek(fs, 0, SEEK_END); 00975 } else if (errno != EEXIST) { 00976 ast_log(LOG_WARNING, "Unable to open file %s: %s\n", fn, strerror(errno)); 00977 if (orig_fn) 00978 unlink(orig_fn); 00979 } 00980 /* if buf != NULL then fn is already free and pointing to it */ 00981 if (!buf) 00982 free(fn); 00983 } 00984 00985 AST_LIST_UNLOCK(&formats); 00986 00987 if (!format_found) 00988 ast_log(LOG_WARNING, "No such format '%s'\n", type); 00989 00990 return fs; 00991 }
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 Returns 0 on success, -1 on failure. |
Definition at line 154 of file file.c.
Referenced by __ast_play_and_record(), __ast_read(), ast_write(), ast_writestream(), cli_audio_convert(), cli_audio_convert_deprecated(), dictate_exec(), handle_recordfile(), mixmonitor_thread(), record_exec(), recordthread(), and rpt().
00155 { 00156 int res = -1; 00157 int alt = 0; 00158 if (f->frametype == AST_FRAME_VIDEO) { 00159 if (fs->fmt->format < AST_FORMAT_MAX_AUDIO) { 00160 /* This is the audio portion. Call the video one... */ 00161 if (!fs->vfs && fs->filename) { 00162 const char *type = ast_getformatname(f->subclass & ~0x1); 00163 fs->vfs = ast_writefile(fs->filename, type, NULL, fs->flags, 0, fs->mode); 00164 ast_log(LOG_DEBUG, "Opened video output file\n"); 00165 } 00166 if (fs->vfs) 00167 return ast_writestream(fs->vfs, f); 00168 /* else ignore */ 00169 return 0; 00170 } else { 00171 /* Might / might not have mark set */ 00172 alt = 1; 00173 } 00174 } else if (f->frametype != AST_FRAME_VOICE) { 00175 ast_log(LOG_WARNING, "Tried to write non-voice frame\n"); 00176 return -1; 00177 } 00178 if (((fs->fmt->format | alt) & f->subclass) == f->subclass) { 00179 res = fs->fmt->write(fs, f); 00180 if (res < 0) 00181 ast_log(LOG_WARNING, "Natural write failed\n"); 00182 else if (res > 0) 00183 ast_log(LOG_WARNING, "Huh??\n"); 00184 } else { 00185 /* XXX If they try to send us a type of frame that isn't the normal frame, and isn't 00186 the one we've setup a translator for, we do the "wrong thing" XXX */ 00187 if (fs->trans && f->subclass != fs->lastwriteformat) { 00188 ast_translator_free_path(fs->trans); 00189 fs->trans = NULL; 00190 } 00191 if (!fs->trans) 00192 fs->trans = ast_translator_build_path(fs->fmt->format, f->subclass); 00193 if (!fs->trans) 00194 ast_log(LOG_WARNING, "Unable to translate to format %s, source format %s\n", 00195 fs->fmt->name, ast_getformatname(f->subclass)); 00196 else { 00197 struct ast_frame *trf; 00198 fs->lastwriteformat = f->subclass; 00199 /* Get the translated frame but don't consume the original in case they're using it on another stream */ 00200 trf = ast_translate(fs->trans, f, 0); 00201 if (trf) { 00202 res = fs->fmt->write(fs, trf); 00203 if (res) 00204 ast_log(LOG_WARNING, "Translated frame write failed\n"); 00205 } else 00206 res = 0; 00207 } 00208 } 00209 return res; 00210 }
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 255 of file file.c.
References asprintf, and ast_config_AST_DATA_DIR.
Referenced by ast_filehelper(), ast_readfile(), and ast_writefile().
00256 { 00257 char *fn = NULL; 00258 00259 if (!strcmp(ext, "wav49")) 00260 ext = "WAV"; 00261 00262 if (filename[0] == '/') 00263 asprintf(&fn, "%s.%s", filename, ext); 00264 else 00265 asprintf(&fn, "%s/sounds/%s.%s", 00266 ast_config_AST_DATA_DIR, filename, ext); 00267 return fn; 00268 }
static int copy | ( | const char * | infile, | |
const char * | outfile | |||
) | [static] |
Definition at line 212 of file file.c.
References ast_log(), len, and LOG_WARNING.
Referenced by action_getvar(), ast_filehelper(), copy_file(), and iax2_register().
00213 { 00214 int ifd, ofd, len; 00215 char buf[4096]; /* XXX make it lerger. */ 00216 00217 if ((ifd = open(infile, O_RDONLY)) < 0) { 00218 ast_log(LOG_WARNING, "Unable to open %s in read-only mode\n", infile); 00219 return -1; 00220 } 00221 if ((ofd = open(outfile, O_WRONLY | O_TRUNC | O_CREAT, 0600)) < 0) { 00222 ast_log(LOG_WARNING, "Unable to open %s in write-only mode\n", outfile); 00223 close(ifd); 00224 return -1; 00225 } 00226 while ( (len = read(ifd, buf, sizeof(buf)) ) ) { 00227 int res; 00228 if (len < 0) { 00229 ast_log(LOG_WARNING, "Read failed on %s: %s\n", infile, strerror(errno)); 00230 break; 00231 } 00232 /* XXX handle partial writes */ 00233 res = write(ofd, buf, len); 00234 if (res != len) { 00235 ast_log(LOG_WARNING, "Write failed on %s (%d of %d): %s\n", outfile, res, len, strerror(errno)); 00236 len = -1; /* error marker */ 00237 break; 00238 } 00239 } 00240 close(ifd); 00241 close(ofd); 00242 if (len < 0) { 00243 unlink(outfile); 00244 return -1; /* error */ 00245 } 00246 return 0; /* success */ 00247 }
static int exts_compare | ( | const char * | exts, | |
const char * | type | |||
) | [static] |
Definition at line 272 of file file.c.
Referenced by ast_filehelper(), ast_readfile(), and ast_writefile().
00273 { 00274 char tmp[256]; 00275 char *stringp = tmp, *ext; 00276 00277 ast_copy_string(tmp, exts, sizeof(tmp)); 00278 while ((ext = strsep(&stringp, "|"))) { 00279 if (!strcmp(ext, type)) 00280 return 1; 00281 } 00282 00283 return 0; 00284 }
static int fileexists_core | ( | const char * | filename, | |
const char * | fmt, | |||
const char * | preflang, | |||
char * | buf, | |||
int | buflen | |||
) | [static] |
helper routine to locate a file with a given format and language preference. Try preflang, preflang with stripped '_' suffix, or NULL. In the standard asterisk, language goes just before the last component. In an alternative configuration, the language should be a prefix to the actual filename.
The last parameter(s) point to a buffer of sufficient size, which on success is filled with the matching filename.
Definition at line 483 of file file.c.
References ACTION_EXISTS, ast_filehelper(), ast_log(), LOG_WARNING, and offset.
Referenced by ast_fileexists(), ast_openstream_full(), and ast_openvstream().
00485 { 00486 int res = -1; 00487 int langlen; /* length of language string */ 00488 const char *c = strrchr(filename, '/'); 00489 int offset = c ? c - filename + 1 : 0; /* points right after the last '/' */ 00490 00491 if (preflang == NULL) 00492 preflang = ""; 00493 langlen = strlen(preflang); 00494 00495 if (buflen < langlen + strlen(filename) + 2) { 00496 ast_log(LOG_WARNING, "buffer too small\n"); 00497 buf[0] = '\0'; /* set to empty */ 00498 buf = alloca(langlen + strlen(filename) + 2); /* room for everything */ 00499 } 00500 if (buf == NULL) 00501 return 0; 00502 buf[0] = '\0'; 00503 for (;;) { 00504 if (ast_language_is_prefix) { /* new layout */ 00505 if (langlen) { 00506 strcpy(buf, preflang); 00507 buf[langlen] = '/'; 00508 strcpy(buf + langlen + 1, filename); 00509 } else 00510 strcpy(buf, filename); /* first copy the full string */ 00511 } else { /* old layout */ 00512 strcpy(buf, filename); /* first copy the full string */ 00513 if (langlen) { 00514 /* insert the language and suffix if needed */ 00515 strcpy(buf + offset, preflang); 00516 sprintf(buf + offset + langlen, "/%s", filename + offset); 00517 } 00518 } 00519 res = ast_filehelper(buf, NULL, fmt, ACTION_EXISTS); 00520 if (res > 0) /* found format */ 00521 break; 00522 if (langlen == 0) /* no more formats */ 00523 break; 00524 if (preflang[langlen] == '_') /* we are on the local suffix */ 00525 langlen = 0; /* try again with no language */ 00526 else 00527 langlen = (c = strchr(preflang, '_')) ? c - preflang : 0; 00528 } 00529 return res; 00530 }
static int fn_wrapper | ( | struct ast_filestream * | s, | |
const char * | comment, | |||
enum wrap_fn | mode | |||
) | [static] |
Definition at line 310 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().
00311 { 00312 struct ast_format *f = s->fmt; 00313 int ret = -1; 00314 00315 if (mode == WRAP_OPEN && f->open && f->open(s)) 00316 ast_log(LOG_WARNING, "Unable to open format %s\n", f->name); 00317 else if (mode == WRAP_REWRITE && f->rewrite && f->rewrite(s, comment)) 00318 ast_log(LOG_WARNING, "Unable to rewrite format %s\n", f->name); 00319 else { 00320 /* preliminary checks succeed. update usecount */ 00321 ast_module_ref(f->module); 00322 ret = 0; 00323 } 00324 return ret; 00325 }
static struct ast_filestream* get_filestream | ( | struct ast_format * | fmt, | |
FILE * | bfile | |||
) | [static, read] |
Definition at line 286 of file file.c.
References ast_calloc, ast_filestream::buf, ast_format::buf_size, ast_format::desc_size, ast_filestream::f, ast_filestream::fmt, ast_filestream::fr, ast_format::name, ast_filestream::private, s, and ast_frame::src.
Referenced by ast_filehelper(), ast_readfile(), and ast_writefile().
00287 { 00288 struct ast_filestream *s; 00289 00290 int l = sizeof(*s) + fmt->buf_size + fmt->desc_size; /* total allocation size */ 00291 if ( (s = ast_calloc(1, l)) == NULL) 00292 return NULL; 00293 s->fmt = fmt; 00294 s->f = bfile; 00295 00296 if (fmt->desc_size) 00297 s->private = ((char *)(s+1)) + fmt->buf_size; 00298 if (fmt->buf_size) 00299 s->buf = (char *)(s+1); 00300 s->fr.src = fmt->name; 00301 return s; 00302 }
static int open_wrapper | ( | struct ast_filestream * | s | ) | [static] |
Definition at line 332 of file file.c.
References fn_wrapper(), and WRAP_OPEN.
Referenced by ast_filehelper(), and ast_readfile().
00333 { 00334 return fn_wrapper(s, NULL, WRAP_OPEN); 00335 }
static int rewrite_wrapper | ( | struct ast_filestream * | s, | |
const char * | comment | |||
) | [static] |
Definition at line 327 of file file.c.
References fn_wrapper(), and WRAP_REWRITE.
Referenced by ast_writefile().
00328 { 00329 return fn_wrapper(s, comment, WRAP_REWRITE); 00330 }
static int show_file_formats | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1141 of file file.c.
References ast_cli(), ast_getformatname(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_format::exts, f, ast_format::format, FORMAT, FORMAT2, LOG_WARNING, ast_format::name, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
01142 { 01143 #define FORMAT "%-10s %-10s %-20s\n" 01144 #define FORMAT2 "%-10s %-10s %-20s\n" 01145 struct ast_format *f; 01146 int count_fmt = 0; 01147 01148 if (argc != 4) 01149 return RESULT_SHOWUSAGE; 01150 ast_cli(fd, FORMAT, "Format", "Name", "Extensions"); 01151 01152 if (AST_LIST_LOCK(&formats)) { 01153 ast_log(LOG_WARNING, "Unable to lock format list\n"); 01154 return -1; 01155 } 01156 01157 AST_LIST_TRAVERSE(&formats, f, list) { 01158 ast_cli(fd, FORMAT2, ast_getformatname(f->format), f->name, f->exts); 01159 count_fmt++; 01160 } 01161 AST_LIST_UNLOCK(&formats); 01162 ast_cli(fd, "%d file formats registered.\n", count_fmt); 01163 return RESULT_SUCCESS; 01164 #undef FORMAT 01165 #undef FORMAT2 01166 }
static int show_file_formats_deprecated | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1168 of file file.c.
References ast_cli(), ast_getformatname(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_format::exts, f, ast_format::format, FORMAT, FORMAT2, LOG_WARNING, ast_format::name, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
01169 { 01170 #define FORMAT "%-10s %-10s %-20s\n" 01171 #define FORMAT2 "%-10s %-10s %-20s\n" 01172 struct ast_format *f; 01173 int count_fmt = 0; 01174 01175 if (argc != 3) 01176 return RESULT_SHOWUSAGE; 01177 ast_cli(fd, FORMAT, "Format", "Name", "Extensions"); 01178 01179 if (AST_LIST_LOCK(&formats)) { 01180 ast_log(LOG_WARNING, "Unable to lock format list\n"); 01181 return -1; 01182 } 01183 01184 AST_LIST_TRAVERSE(&formats, f, list) { 01185 ast_cli(fd, FORMAT2, ast_getformatname(f->format), f->name, f->exts); 01186 count_fmt++; 01187 } 01188 AST_LIST_UNLOCK(&formats); 01189 ast_cli(fd, "%d file formats registered.\n", count_fmt); 01190 return RESULT_SUCCESS; 01191 #undef FORMAT 01192 #undef FORMAT2 01193 }
static int waitstream_core | ( | struct ast_channel * | c, | |
const char * | breakon, | |||
const char * | forward, | |||
const char * | rewind, | |||
int | skip_ms, | |||
int | audiofd, | |||
int | cmdfd, | |||
const char * | context | |||
) | [static] |
the core of all waitstream() functions
Definition at line 996 of file file.c.
References ast_channel::_softhangup, AST_CONTROL_ANSWER, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_HANGUP, AST_CONTROL_HOLD, AST_CONTROL_RINGING, AST_CONTROL_UNHOLD, AST_CONTROL_VIDUPDATE, ast_exists_extension(), AST_FRAME_CONTROL, AST_FRAME_DTMF_END, AST_FRAME_VOICE, ast_frfree(), ast_log(), ast_read(), ast_sched_runq(), ast_sched_wait(), ast_stopstream(), ast_stream_fastforward(), ast_stream_rewind(), ast_waitfor(), ast_waitfor_nandfds(), ast_channel::cid, ast_callerid::cid_num, ast_frame::data, ast_frame::datalen, exten, ast_frame::frametype, LOG_WARNING, ast_channel::sched, ast_channel::stream, and ast_frame::subclass.
Referenced by ast_waitstream(), ast_waitstream_exten(), ast_waitstream_fr(), and ast_waitstream_full().
00999 { 01000 if (!breakon) 01001 breakon = ""; 01002 if (!forward) 01003 forward = ""; 01004 if (!rewind) 01005 rewind = ""; 01006 01007 while (c->stream) { 01008 int res; 01009 int ms = ast_sched_wait(c->sched); 01010 if (ms < 0 && !c->timingfunc) { 01011 ast_stopstream(c); 01012 break; 01013 } 01014 if (ms < 0) 01015 ms = 1000; 01016 if (cmdfd < 0) { 01017 res = ast_waitfor(c, ms); 01018 if (res < 0) { 01019 ast_log(LOG_WARNING, "Select failed (%s)\n", strerror(errno)); 01020 return res; 01021 } 01022 } else { 01023 int outfd; 01024 struct ast_channel *rchan = ast_waitfor_nandfds(&c, 1, &cmdfd, (cmdfd > -1) ? 1 : 0, NULL, &outfd, &ms); 01025 if (!rchan && (outfd < 0) && (ms)) { 01026 /* Continue */ 01027 if (errno == EINTR) 01028 continue; 01029 ast_log(LOG_WARNING, "Wait failed (%s)\n", strerror(errno)); 01030 return -1; 01031 } else if (outfd > -1) { /* this requires cmdfd set */ 01032 /* The FD we were watching has something waiting */ 01033 return 1; 01034 } 01035 /* if rchan is set, it is 'c' */ 01036 res = rchan ? 1 : 0; /* map into 'res' values */ 01037 } 01038 if (res > 0) { 01039 struct ast_frame *fr = ast_read(c); 01040 if (!fr) 01041 return -1; 01042 switch(fr->frametype) { 01043 case AST_FRAME_DTMF_END: 01044 if (context) { 01045 const char exten[2] = { fr->subclass, '\0' }; 01046 if (ast_exists_extension(c, context, exten, 1, c->cid.cid_num)) { 01047 res = fr->subclass; 01048 ast_frfree(fr); 01049 return res; 01050 } 01051 } else { 01052 res = fr->subclass; 01053 if (strchr(forward,res)) { 01054 ast_stream_fastforward(c->stream, skip_ms); 01055 } else if (strchr(rewind,res)) { 01056 ast_stream_rewind(c->stream, skip_ms); 01057 } else if (strchr(breakon, res)) { 01058 ast_frfree(fr); 01059 return res; 01060 } 01061 } 01062 break; 01063 case AST_FRAME_CONTROL: 01064 switch(fr->subclass) { 01065 case AST_CONTROL_HANGUP: 01066 case AST_CONTROL_BUSY: 01067 case AST_CONTROL_CONGESTION: 01068 ast_frfree(fr); 01069 return -1; 01070 case AST_CONTROL_RINGING: 01071 case AST_CONTROL_ANSWER: 01072 case AST_CONTROL_VIDUPDATE: 01073 case AST_CONTROL_HOLD: 01074 case AST_CONTROL_UNHOLD: 01075 /* Unimportant */ 01076 break; 01077 default: 01078 ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", fr->subclass); 01079 } 01080 break; 01081 case AST_FRAME_VOICE: 01082 /* Write audio if appropriate */ 01083 if (audiofd > -1) 01084 write(audiofd, fr->data, fr->datalen); 01085 default: 01086 /* Ignore all others */ 01087 break; 01088 } 01089 ast_frfree(fr); 01090 } 01091 ast_sched_runq(c->sched); 01092 } 01093 return (c->_softhangup ? -1 : 0); 01094 }
struct ast_cli_entry cli_file[] |
Initial value:
{ { { "core", "show", "file", "formats" }, show_file_formats, "Displays file formats", show_file_formats_usage, NULL, &cli_show_file_formats_deprecated }, }
Initial value:
{ { "show", "file", "formats" }, show_file_formats_deprecated, NULL, NULL }
char show_file_formats_usage[] |