#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.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 dependency graph for file.c:
Go to the source code of this file.
Data Structures | |
struct | ast_filestream |
struct | ast_format |
Defines | |
#define | ACTION_COPY 5 |
#define | ACTION_DELETE 2 |
#define | ACTION_EXISTS 1 |
#define | ACTION_OPEN 4 |
#define | ACTION_RENAME 3 |
#define | FORMAT "%-10s %-10s %-20s\n" |
#define | FORMAT2 "%-10s %-10s %-20s\n" |
Functions | |
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 char *filename2, const char *fmt, int action) |
int | ast_filerename (const char *filename, const char *filename2, const char *fmt) |
int | ast_format_register (const char *name, const char *exts, int format, struct ast_filestream *(*open)(FILE *f), struct ast_filestream *(*rewrite)(FILE *f, const char *comment), int(*write)(struct ast_filestream *, struct ast_frame *), int(*seek)(struct ast_filestream *, long sample_offset, int whence), int(*trunc)(struct ast_filestream *), long(*tell)(struct ast_filestream *), struct ast_frame *(*read)(struct ast_filestream *, int *whennext), void(*close)(struct ast_filestream *), char *(*getcomment)(struct ast_filestream *)) |
int | ast_format_unregister (const char *name) |
AST_MUTEX_DEFINE_STATIC (formatlock) | |
ast_filestream * | ast_openstream (struct ast_channel *chan, const char *filename, const char *preflang) |
ast_filestream * | ast_openstream_full (struct ast_channel *chan, const char *filename, const char *preflang, int asis) |
ast_filestream * | ast_openvstream (struct ast_channel *chan, const char *filename, const char *preflang) |
int | ast_playstream (struct ast_filestream *s) |
static int | ast_readaudio_callback (void *data) |
ast_filestream * | ast_readfile (const char *filename, const char *type, const char *comment, int flags, int check, mode_t mode) |
ast_frame * | ast_readframe (struct ast_filestream *s) |
static int | ast_readvideo_callback (void *data) |
int | ast_seekstream (struct ast_filestream *fs, long sample_offset, int whence) |
int | ast_stopstream (struct ast_channel *tmp) |
int | ast_stream_fastforward (struct ast_filestream *fs, long ms) |
int | ast_stream_rewind (struct ast_filestream *fs, long ms) |
int | ast_streamfile (struct ast_channel *chan, const char *filename, const char *preflang) |
long | ast_tellstream (struct ast_filestream *fs) |
int | ast_truncstream (struct ast_filestream *fs) |
int | ast_waitstream (struct ast_channel *c, const char *breakon) |
int | ast_waitstream_exten (struct ast_channel *c, const char *context) |
int | ast_waitstream_fr (struct ast_channel *c, const char *breakon, const char *forward, const char *rewind, int ms) |
int | ast_waitstream_full (struct ast_channel *c, const char *breakon, int audiofd, int cmdfd) |
ast_filestream * | ast_writefile (const char *filename, const char *type, const char *comment, int flags, int check, mode_t mode) |
int | ast_writestream (struct ast_filestream *fs, struct ast_frame *f) |
static char * | build_filename (const char *filename, const char *ext) |
static int | copy (const char *infile, const char *outfile) |
static int | exts_compare (const char *exts, const char *type) |
static int | show_file_formats (int fd, int argc, char *argv[]) |
Variables | |
static struct ast_format * | formats = NULL |
ast_cli_entry | show_file |
Definition in file file.c.
#define ACTION_COPY 5 |
#define ACTION_DELETE 2 |
#define ACTION_EXISTS 1 |
#define ACTION_OPEN 4 |
Definition at line 348 of file file.c.
Referenced by ast_filehelper(), ast_openstream_full(), and ast_openvstream().
#define ACTION_RENAME 3 |
#define FORMAT "%-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_image_formats(), sip_show_inuse(), sip_show_registry(), zap_show_channels(), and zap_show_status().
int ast_applystream | ( | struct ast_channel * | chan, | |
struct ast_filestream * | s | |||
) |
chan | channel to work | |
s | ast_filestream to apply Returns 0 for success, -1 on failure |
Definition at line 644 of file file.c.
References s.
Referenced by ast_streamfile(), handle_getoption(), handle_recordfile(), and handle_streamfile().
00645 { 00646 s->owner = chan; 00647 return 0; 00648 }
int ast_closestream | ( | struct ast_filestream * | f | ) |
f | filestream to close Close a playback or recording stream Returns 0 on success, -1 on failure |
Definition at line 689 of file file.c.
References AST_FORMAT_MAX_AUDIO, ast_safe_system(), ast_sched_del(), ast_settimeout(), ast_translator_free_path(), ast_format::close, ast_filestream::filename, ast_filestream::fmt, ast_format::format, free, ast_filestream::owner, ast_filestream::realfilename, ast_channel::sched, ast_channel::stream, ast_channel::streamid, ast_filestream::trans, ast_channel::vstream, and ast_channel::vstreamid.
Referenced by ast_hangup(), ast_moh_files_next(), ast_monitor_start(), ast_monitor_stop(), ast_play_and_prepend(), ast_play_and_record_full(), ast_stopstream(), dictate_exec(), gen_closestream(), handle_recordfile(), launch_monitor_thread(), local_ast_moh_stop(), mixmonitor_thread(), moh_files_release(), and recordthread().
00690 { 00691 char *cmd = NULL; 00692 size_t size = 0; 00693 /* Stop a running stream if there is one */ 00694 if (f->owner) { 00695 if (f->fmt->format < AST_FORMAT_MAX_AUDIO) { 00696 f->owner->stream = NULL; 00697 if (f->owner->streamid > -1) 00698 ast_sched_del(f->owner->sched, f->owner->streamid); 00699 f->owner->streamid = -1; 00700 #ifdef ZAPTEL_OPTIMIZATIONS 00701 ast_settimeout(f->owner, 0, NULL, NULL); 00702 #endif 00703 } else { 00704 f->owner->vstream = NULL; 00705 if (f->owner->vstreamid > -1) 00706 ast_sched_del(f->owner->sched, f->owner->vstreamid); 00707 f->owner->vstreamid = -1; 00708 } 00709 } 00710 /* destroy the translator on exit */ 00711 if (f->trans) { 00712 ast_translator_free_path(f->trans); 00713 f->trans = NULL; 00714 } 00715 00716 if (f->realfilename && f->filename) { 00717 size = strlen(f->filename) + strlen(f->realfilename) + 15; 00718 cmd = alloca(size); 00719 memset(cmd,0,size); 00720 snprintf(cmd,size,"/bin/mv -f %s %s",f->filename,f->realfilename); 00721 ast_safe_system(cmd); 00722 } 00723 00724 if (f->filename) { 00725 free(f->filename); 00726 f->filename = NULL; 00727 } 00728 if (f->realfilename) { 00729 free(f->realfilename); 00730 f->realfilename = NULL; 00731 } 00732 f->fmt->close(f); 00733 return 0; 00734 }
int ast_file_init | ( | void | ) |
Initializes all the various file stuff. Basically just registers the cli stuff Returns 0 all the time
Definition at line 1290 of file file.c.
References ast_cli_register(), and show_file.
Referenced by main().
01291 { 01292 ast_cli_register(&show_file); 01293 return 0; 01294 }
int ast_filecopy | ( | const char * | oldname, | |
const char * | newname, | |||
const char * | fmt | |||
) |
oldname | name of the file you wish to copy (minus extension) | |
newname | name you wish the file to be copied to (minus extension) | |
fmt | the format of the file Copy a given file in a given format, or if fmt is NULL, then do so for all |
Definition at line 795 of file file.c.
References ACTION_COPY, and ast_filehelper().
Referenced by copy_file().
00796 { 00797 return ast_filehelper(filename, filename2, fmt, ACTION_COPY); 00798 }
int ast_filedelete | ( | const char * | filename, | |
const char * | fmt | |||
) |
filename | name of the file you wish to delete (minus the extension) | |
fmt | of the file Delete a given file in a given format, or if fmt is NULL, then do so for all |
Definition at line 785 of file file.c.
References ACTION_DELETE, and ast_filehelper().
Referenced by ast_monitor_start(), ast_monitor_stop(), ast_play_and_prepend(), dial_exec_full(), leave_voicemail(), play_mailbox_owner(), and vm_delete().
00786 { 00787 return ast_filehelper(filename, NULL, fmt, ACTION_DELETE); 00788 }
int ast_fileexists | ( | const char * | filename, | |
const char * | fmt, | |||
const char * | preflang | |||
) |
filename | name of the file you wish to check, minus the extension | |
fmt | the format you wish to check (the extension) | |
preflang | (the preferred language you wisht to find the file in) See if a given file exists in a given format. If fmt is NULL, any format is accepted. Returns -1 if file does not exist, non-zero positive otherwise. |
Definition at line 737 of file file.c.
References ACTION_EXISTS, ast_filehelper(), ast_strlen_zero(), MAX_LANGUAGE, and strsep().
Referenced by app_exec(), ast_moh_files_next(), ast_monitor_start(), ast_monitor_stop(), ast_openstream_full(), ast_openvstream(), chanspy_exec(), conf_run(), dial_exec_full(), invent_message(), last_message_index(), leave_voicemail(), play_mailbox_owner(), play_message_callerid(), record_exec(), and vm_tempgreeting().
00738 { 00739 char filename2[256]; 00740 char tmp[256]; 00741 char *postfix; 00742 char *prefix; 00743 char *c; 00744 char lang2[MAX_LANGUAGE]; 00745 int res = -1; 00746 if (!ast_strlen_zero(preflang)) { 00747 /* Insert the language between the last two parts of the path */ 00748 ast_copy_string(tmp, filename, sizeof(tmp)); 00749 c = strrchr(tmp, '/'); 00750 if (c) { 00751 *c = '\0'; 00752 postfix = c+1; 00753 prefix = tmp; 00754 snprintf(filename2, sizeof(filename2), "%s/%s/%s", prefix, preflang, postfix); 00755 } else { 00756 postfix = tmp; 00757 prefix=""; 00758 snprintf(filename2, sizeof(filename2), "%s/%s", preflang, postfix); 00759 } 00760 res = ast_filehelper(filename2, NULL, fmt, ACTION_EXISTS); 00761 if (res < 1) { 00762 char *stringp=NULL; 00763 ast_copy_string(lang2, preflang, sizeof(lang2)); 00764 stringp=lang2; 00765 strsep(&stringp, "_"); 00766 /* If language is a specific locality of a language (like es_MX), strip the locality and try again */ 00767 if (strcmp(lang2, preflang)) { 00768 if (ast_strlen_zero(prefix)) { 00769 snprintf(filename2, sizeof(filename2), "%s/%s", lang2, postfix); 00770 } else { 00771 snprintf(filename2, sizeof(filename2), "%s/%s/%s", prefix, lang2, postfix); 00772 } 00773 res = ast_filehelper(filename2, NULL, fmt, ACTION_EXISTS); 00774 } 00775 } 00776 } 00777 00778 /* Fallback to no language (usually winds up being American English) */ 00779 if (res < 1) { 00780 res = ast_filehelper(filename, NULL, fmt, ACTION_EXISTS); 00781 } 00782 return res; 00783 }
static int ast_filehelper | ( | const char * | filename, | |
const char * | filename2, | |||
const char * | fmt, | |||
int | action | |||
) | [static] |
Definition at line 351 of file file.c.
References ACTION_COPY, ACTION_DELETE, ACTION_EXISTS, ACTION_OPEN, ACTION_RENAME, AST_FORMAT_MAX_AUDIO, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_strdupa, build_filename(), copy(), ast_format::exts, exts_compare(), ast_format::format, formats, free, LOG_WARNING, ast_format::next, ast_format::open, s, ast_channel::stream, strsep(), ast_channel::vstream, and ast_channel::writeformat.
Referenced by ast_filecopy(), ast_filedelete(), ast_fileexists(), ast_filerename(), ast_openstream_full(), and ast_openvstream().
00352 { 00353 struct stat st; 00354 struct ast_format *f; 00355 struct ast_filestream *s; 00356 int res=0, ret = 0; 00357 char *ext=NULL, *exts, *fn, *nfn; 00358 FILE *bfile; 00359 struct ast_channel *chan = (struct ast_channel *)filename2; 00360 00361 /* Start with negative response */ 00362 if (action == ACTION_EXISTS) 00363 res = 0; 00364 else 00365 res = -1; 00366 if (action == ACTION_OPEN) 00367 ret = -1; 00368 /* Check for a specific format */ 00369 if (ast_mutex_lock(&formatlock)) { 00370 ast_log(LOG_WARNING, "Unable to lock format list\n"); 00371 if (action == ACTION_EXISTS) 00372 return 0; 00373 else 00374 return -1; 00375 } 00376 f = formats; 00377 while(f) { 00378 if (!fmt || exts_compare(f->exts, fmt)) { 00379 char *stringp=NULL; 00380 exts = ast_strdupa(f->exts); 00381 /* Try each kind of extension */ 00382 stringp=exts; 00383 ext = strsep(&stringp, "|"); 00384 do { 00385 fn = build_filename(filename, ext); 00386 if (fn) { 00387 res = stat(fn, &st); 00388 if (!res) { 00389 switch(action) { 00390 case ACTION_EXISTS: 00391 ret |= f->format; 00392 break; 00393 case ACTION_DELETE: 00394 res = unlink(fn); 00395 if (res) 00396 ast_log(LOG_WARNING, "unlink(%s) failed: %s\n", fn, strerror(errno)); 00397 break; 00398 case ACTION_RENAME: 00399 nfn = build_filename(filename2, ext); 00400 if (nfn) { 00401 res = rename(fn, nfn); 00402 if (res) 00403 ast_log(LOG_WARNING, "rename(%s,%s) failed: %s\n", fn, nfn, strerror(errno)); 00404 free(nfn); 00405 } else 00406 ast_log(LOG_WARNING, "Out of memory\n"); 00407 break; 00408 case ACTION_COPY: 00409 nfn = build_filename(filename2, ext); 00410 if (nfn) { 00411 res = copy(fn, nfn); 00412 if (res) 00413 ast_log(LOG_WARNING, "copy(%s,%s) failed: %s\n", fn, nfn, strerror(errno)); 00414 free(nfn); 00415 } else 00416 ast_log(LOG_WARNING, "Out of memory\n"); 00417 break; 00418 case ACTION_OPEN: 00419 if ((ret < 0) && ((chan->writeformat & f->format) || 00420 ((f->format >= AST_FORMAT_MAX_AUDIO) && fmt))) { 00421 bfile = fopen(fn, "r"); 00422 if (bfile) { 00423 ret = 1; 00424 s = f->open(bfile); 00425 if (s) { 00426 s->lasttimeout = -1; 00427 s->fmt = f; 00428 s->trans = NULL; 00429 s->filename = NULL; 00430 if (s->fmt->format < AST_FORMAT_MAX_AUDIO) 00431 chan->stream = s; 00432 else 00433 chan->vstream = s; 00434 } else { 00435 fclose(bfile); 00436 ast_log(LOG_WARNING, "Unable to open file on %s\n", fn); 00437 ret = -1; 00438 } 00439 } else{ 00440 ast_log(LOG_WARNING, "Couldn't open file %s\n", fn); 00441 ret = -1; 00442 } 00443 } 00444 break; 00445 default: 00446 ast_log(LOG_WARNING, "Unknown helper %d\n", action); 00447 } 00448 /* Conveniently this logic is the same for all */ 00449 if (res) 00450 break; 00451 } 00452 free(fn); 00453 } 00454 ext = strsep(&stringp, "|"); 00455 } while(ext); 00456 00457 } 00458 f = f->next; 00459 } 00460 ast_mutex_unlock(&formatlock); 00461 if ((action == ACTION_EXISTS) || (action == ACTION_OPEN)) 00462 res = ret ? ret : -1; 00463 return res; 00464 }
int ast_filerename | ( | const char * | oldname, | |
const char * | newname, | |||
const char * | fmt | |||
) |
oldname | the name of the file you wish to act upon (minus the extension) | |
newname | the name you wish to rename the file to (minus the extension) | |
fmt | the format of the file Rename a given file in a given format, or if fmt is NULL, then do so for all Returns -1 on failure |
Definition at line 790 of file file.c.
References ACTION_RENAME, and ast_filehelper().
Referenced by ast_monitor_stop(), ast_play_and_prepend(), leave_voicemail(), and rename_file().
00791 { 00792 return ast_filehelper(filename, filename2, fmt, ACTION_RENAME); 00793 }
int ast_format_register | ( | const char * | name, | |
const char * | exts, | |||
int | format, | |||
struct ast_filestream *(*)(FILE *f) | open, | |||
struct ast_filestream *(*)(FILE *f, const char *comment) | rewrite, | |||
int(*)(struct ast_filestream *, struct ast_frame *) | write, | |||
int(*)(struct ast_filestream *, long sample_offset, int whence) | seek, | |||
int(*)(struct ast_filestream *) | trunc, | |||
long(*)(struct ast_filestream *) | tell, | |||
struct ast_frame *(*)(struct ast_filestream *, int *whennext) | read, | |||
void(*)(struct ast_filestream *) | close, | |||
char *(*)(struct ast_filestream *) | getcomment | |||
) |
Definition at line 105 of file file.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), ast_format::close, ast_format::exts, ast_format::format, formats, ast_format::getcomment, LOG_WARNING, malloc, ast_format::name, ast_format::next, ast_format::open, option_verbose, ast_format::read, ast_format::rewrite, ast_format::seek, ast_format::tell, ast_format::trunc, VERBOSE_PREFIX_2, and ast_format::write.
Referenced by load_module().
00115 { 00116 struct ast_format *tmp; 00117 if (ast_mutex_lock(&formatlock)) { 00118 ast_log(LOG_WARNING, "Unable to lock format list\n"); 00119 return -1; 00120 } 00121 tmp = formats; 00122 while(tmp) { 00123 if (!strcasecmp(name, tmp->name)) { 00124 ast_mutex_unlock(&formatlock); 00125 ast_log(LOG_WARNING, "Tried to register '%s' format, already registered\n", name); 00126 return -1; 00127 } 00128 tmp = tmp->next; 00129 } 00130 tmp = malloc(sizeof(struct ast_format)); 00131 if (!tmp) { 00132 ast_log(LOG_WARNING, "Out of memory\n"); 00133 ast_mutex_unlock(&formatlock); 00134 return -1; 00135 } 00136 ast_copy_string(tmp->name, name, sizeof(tmp->name)); 00137 ast_copy_string(tmp->exts, exts, sizeof(tmp->exts)); 00138 tmp->open = open; 00139 tmp->rewrite = rewrite; 00140 tmp->read = read; 00141 tmp->write = write; 00142 tmp->seek = seek; 00143 tmp->trunc = trunc; 00144 tmp->tell = tell; 00145 tmp->close = close; 00146 tmp->format = format; 00147 tmp->getcomment = getcomment; 00148 tmp->next = formats; 00149 formats = tmp; 00150 ast_mutex_unlock(&formatlock); 00151 if (option_verbose > 1) 00152 ast_verbose( VERBOSE_PREFIX_2 "Registered file format %s, extension(s) %s\n", name, exts); 00153 return 0; 00154 }
int ast_format_unregister | ( | const char * | name | ) |
name | the name of the format you wish to unregister Unregisters a format based on the name of the format. Returns 0 on success, -1 on failure to unregister |
Definition at line 156 of file file.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), formats, free, LOG_WARNING, ast_format::name, ast_format::next, option_verbose, and VERBOSE_PREFIX_2.
Referenced by unload_module().
00157 { 00158 struct ast_format *tmp, *tmpl = NULL; 00159 if (ast_mutex_lock(&formatlock)) { 00160 ast_log(LOG_WARNING, "Unable to lock format list\n"); 00161 return -1; 00162 } 00163 tmp = formats; 00164 while(tmp) { 00165 if (!strcasecmp(name, tmp->name)) { 00166 if (tmpl) 00167 tmpl->next = tmp->next; 00168 else 00169 formats = tmp->next; 00170 free(tmp); 00171 ast_mutex_unlock(&formatlock); 00172 if (option_verbose > 1) 00173 ast_verbose( VERBOSE_PREFIX_2 "Unregistered format %s\n", name); 00174 return 0; 00175 } 00176 tmpl = tmp; 00177 tmp = tmp->next; 00178 } 00179 ast_mutex_unlock(&formatlock); 00180 ast_log(LOG_WARNING, "Tried to unregister format %s, already unregistered\n", name); 00181 return -1; 00182 }
AST_MUTEX_DEFINE_STATIC | ( | formatlock | ) |
struct ast_filestream* ast_openstream | ( | struct ast_channel * | chan, | |
const char * | filename, | |||
const char * | preflang | |||
) |
chan | channel to work with | |
filename | to use | |
preflang | prefered language to use Returns a ast_filestream pointer if it opens the file, NULL on error |
Definition at line 465 of file file.c.
References ast_openstream_full().
Referenced by ast_streamfile(), dictate_exec(), handle_getoption(), and handle_streamfile().
00466 { 00467 return ast_openstream_full(chan, filename, preflang, 0); 00468 }
struct ast_filestream* ast_openstream_full | ( | struct ast_channel * | chan, | |
const char * | filename, | |||
const char * | preflang, | |||
int | asis | |||
) |
chan | channel to work with | |
filename | to use | |
preflang | prefered language to use | |
asis | if set, don't clear generators Returns a ast_filestream pointer if it opens the file, NULL on error |
Definition at line 470 of file file.c.
References ACTION_OPEN, ast_deactivate_generator(), ast_fileexists(), ast_filehelper(), ast_log(), ast_set_write_format(), ast_stopstream(), ast_strlen_zero(), LOG_WARNING, ast_channel::oldwriteformat, and ast_channel::writeformat.
Referenced by ast_openstream(), and gen_nextfile().
00471 { 00472 /* This is a fairly complex routine. Essentially we should do 00473 the following: 00474 00475 1) Find which file handlers produce our type of format. 00476 2) Look for a filename which it can handle. 00477 3) If we find one, then great. 00478 4) If not, see what files are there 00479 5) See what we can actually support 00480 6) Choose the one with the least costly translator path and 00481 set it up. 00482 00483 */ 00484 int fmts = -1; 00485 char filename2[256]=""; 00486 char filename3[256]; 00487 char *endpart; 00488 int res; 00489 00490 if (!asis) { 00491 /* do this first, otherwise we detect the wrong writeformat */ 00492 ast_stopstream(chan); 00493 if (chan->generator) 00494 ast_deactivate_generator(chan); 00495 } 00496 if (!ast_strlen_zero(preflang)) { 00497 ast_copy_string(filename3, filename, sizeof(filename3)); 00498 endpart = strrchr(filename3, '/'); 00499 if (endpart) { 00500 *endpart = '\0'; 00501 endpart++; 00502 snprintf(filename2, sizeof(filename2), "%s/%s/%s", filename3, preflang, endpart); 00503 } else 00504 snprintf(filename2, sizeof(filename2), "%s/%s", preflang, filename); 00505 fmts = ast_fileexists(filename2, NULL, NULL); 00506 } 00507 if (fmts < 1) { 00508 ast_copy_string(filename2, filename, sizeof(filename2)); 00509 fmts = ast_fileexists(filename2, NULL, NULL); 00510 } 00511 if (fmts < 1) { 00512 ast_log(LOG_WARNING, "File %s does not exist in any format\n", filename); 00513 return NULL; 00514 } 00515 chan->oldwriteformat = chan->writeformat; 00516 /* Set the channel to a format we can work with */ 00517 res = ast_set_write_format(chan, fmts); 00518 00519 res = ast_filehelper(filename2, (char *)chan, NULL, ACTION_OPEN); 00520 if (res >= 0) 00521 return chan->stream; 00522 return NULL; 00523 }
struct ast_filestream* ast_openvstream | ( | struct ast_channel * | chan, | |
const char * | filename, | |||
const char * | preflang | |||
) |
chan | channel to work with | |
filename | to use | |
preflang | prefered language to use Returns a ast_filestream pointer if it opens the file, NULL on error |
Definition at line 525 of file file.c.
References ACTION_OPEN, ast_fileexists(), ast_filehelper(), ast_log(), ast_strlen_zero(), fmt, LOG_WARNING, and MAX_LANGUAGE.
Referenced by ast_streamfile().
00526 { 00527 /* This is a fairly complex routine. Essentially we should do 00528 the following: 00529 00530 1) Find which file handlers produce our type of format. 00531 2) Look for a filename which it can handle. 00532 3) If we find one, then great. 00533 4) If not, see what files are there 00534 5) See what we can actually support 00535 6) Choose the one with the least costly translator path and 00536 set it up. 00537 00538 */ 00539 int fd = -1; 00540 int fmts = -1; 00541 char filename2[256]; 00542 char lang2[MAX_LANGUAGE]; 00543 /* XXX H.263 only XXX */ 00544 char *fmt = "h263"; 00545 if (!ast_strlen_zero(preflang)) { 00546 snprintf(filename2, sizeof(filename2), "%s/%s", preflang, filename); 00547 fmts = ast_fileexists(filename2, fmt, NULL); 00548 if (fmts < 1) { 00549 ast_copy_string(lang2, preflang, sizeof(lang2)); 00550 snprintf(filename2, sizeof(filename2), "%s/%s", lang2, filename); 00551 fmts = ast_fileexists(filename2, fmt, NULL); 00552 } 00553 } 00554 if (fmts < 1) { 00555 ast_copy_string(filename2, filename, sizeof(filename2)); 00556 fmts = ast_fileexists(filename2, fmt, NULL); 00557 } 00558 if (fmts < 1) { 00559 return NULL; 00560 } 00561 fd = ast_filehelper(filename2, (char *)chan, fmt, ACTION_OPEN); 00562 if (fd >= 0) 00563 return chan->vstream; 00564 ast_log(LOG_WARNING, "File %s has video but couldn't be opened\n", filename); 00565 return NULL; 00566 }
int ast_playstream | ( | struct ast_filestream * | s | ) |
s | filestream to play Returns 0 for success, -1 on failure |
Definition at line 650 of file file.c.
References AST_FORMAT_MAX_AUDIO, ast_readaudio_callback(), ast_readvideo_callback(), and s.
Referenced by ast_streamfile(), handle_getoption(), and handle_streamfile().
00651 { 00652 if (s->fmt->format < AST_FORMAT_MAX_AUDIO) 00653 ast_readaudio_callback(s); 00654 else 00655 ast_readvideo_callback(s); 00656 return 0; 00657 }
static int ast_readaudio_callback | ( | void * | data | ) | [static] |
Definition at line 577 of file file.c.
References ast_log(), ast_sched_add(), ast_settimeout(), ast_write(), LOG_WARNING, and s.
Referenced by ast_playstream().
00578 { 00579 struct ast_filestream *s = data; 00580 struct ast_frame *fr; 00581 int whennext = 0; 00582 00583 while(!whennext) { 00584 fr = s->fmt->read(s, &whennext); 00585 if (fr) { 00586 if (ast_write(s->owner, fr)) { 00587 ast_log(LOG_WARNING, "Failed to write frame\n"); 00588 s->owner->streamid = -1; 00589 #ifdef ZAPTEL_OPTIMIZATIONS 00590 ast_settimeout(s->owner, 0, NULL, NULL); 00591 #endif 00592 return 0; 00593 } 00594 } else { 00595 /* Stream has finished */ 00596 s->owner->streamid = -1; 00597 #ifdef ZAPTEL_OPTIMIZATIONS 00598 ast_settimeout(s->owner, 0, NULL, NULL); 00599 #endif 00600 return 0; 00601 } 00602 } 00603 if (whennext != s->lasttimeout) { 00604 #ifdef ZAPTEL_OPTIMIZATIONS 00605 if (s->owner->timingfd > -1) 00606 ast_settimeout(s->owner, whennext, ast_readaudio_callback, s); 00607 else 00608 #endif 00609 s->owner->streamid = ast_sched_add(s->owner->sched, whennext/8, ast_readaudio_callback, s); 00610 s->lasttimeout = whennext; 00611 return 0; 00612 } 00613 return 1; 00614 }
struct ast_filestream* ast_readfile | ( | const char * | filename, | |
const char * | type, | |||
const char * | comment, | |||
int | flags, | |||
int | check, | |||
mode_t | mode | |||
) |
filename | the name of the file to read from | |
type | format of file you wish to read from | |
comment | comment to go with | |
flags | file flags | |
check | (unimplemented, hence negligible) | |
mode | Open mode Open an incoming file stream. flags are flags for the open() command, and if check is non-zero, then it will not read a file if there are any files that start with that name and have an extension Please note, this is a blocking function. Program execution will not return until ast_waitstream completes it's execution. Returns a struct ast_filestream on success, NULL on failure |
Definition at line 828 of file file.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), build_filename(), exts_compare(), ast_filestream::f, ast_filestream::filename, ast_filestream::flags, ast_filestream::fmt, formats, free, LOG_WARNING, ast_filestream::mode, strdup, ast_filestream::trans, and ast_filestream::vfs.
Referenced by ast_play_and_prepend().
00829 { 00830 FILE *bfile; 00831 struct ast_format *f; 00832 struct ast_filestream *fs = NULL; 00833 char *fn; 00834 00835 if (ast_mutex_lock(&formatlock)) { 00836 ast_log(LOG_WARNING, "Unable to lock format list\n"); 00837 return NULL; 00838 } 00839 00840 for (f = formats; f && !fs; f = f->next) { 00841 if (!exts_compare(f->exts, type)) 00842 continue; 00843 00844 fn = build_filename(filename, type); 00845 bfile = fopen(fn, "r"); 00846 if (bfile) { 00847 errno = 0; 00848 00849 if (!(fs = f->open(bfile))) { 00850 ast_log(LOG_WARNING, "Unable to open %s\n", fn); 00851 fclose(bfile); 00852 free(fn); 00853 continue; 00854 } 00855 00856 fs->trans = NULL; 00857 fs->fmt = f; 00858 fs->flags = flags; 00859 fs->mode = mode; 00860 fs->filename = strdup(filename); 00861 fs->vfs = NULL; 00862 } else if (errno != EEXIST) 00863 ast_log(LOG_WARNING, "Unable to open file %s: %s\n", fn, strerror(errno)); 00864 free(fn); 00865 } 00866 00867 ast_mutex_unlock(&formatlock); 00868 if (!fs) 00869 ast_log(LOG_WARNING, "No such format '%s'\n", type); 00870 00871 return fs; 00872 }
struct ast_frame* ast_readframe | ( | struct ast_filestream * | s | ) |
s | ast_filestream to act on Returns a frame or NULL if read failed |
Definition at line 568 of file file.c.
References s.
Referenced by ast_play_and_prepend(), dictate_exec(), gen_readframe(), and moh_files_readframe().
00569 { 00570 struct ast_frame *f = NULL; 00571 int whennext = 0; 00572 if (s && s->fmt) 00573 f = s->fmt->read(s, &whennext); 00574 return f; 00575 }
static int ast_readvideo_callback | ( | void * | data | ) | [static] |
Definition at line 616 of file file.c.
References ast_log(), ast_sched_add(), ast_write(), LOG_WARNING, and s.
Referenced by ast_playstream().
00617 { 00618 struct ast_filestream *s = data; 00619 struct ast_frame *fr; 00620 int whennext = 0; 00621 00622 while(!whennext) { 00623 fr = s->fmt->read(s, &whennext); 00624 if (fr) { 00625 if (ast_write(s->owner, fr)) { 00626 ast_log(LOG_WARNING, "Failed to write frame\n"); 00627 s->owner->vstreamid = -1; 00628 return 0; 00629 } 00630 } else { 00631 /* Stream has finished */ 00632 s->owner->vstreamid = -1; 00633 return 0; 00634 } 00635 } 00636 if (whennext != s->lasttimeout) { 00637 s->owner->vstreamid = ast_sched_add(s->owner->sched, whennext/8, ast_readvideo_callback, s); 00638 s->lasttimeout = whennext; 00639 return 0; 00640 } 00641 return 1; 00642 }
int ast_seekstream | ( | struct ast_filestream * | fs, | |
long | sample_offset, | |||
int | whence | |||
) |
fs | ast_filestream to perform seek on | |
sample_offset | numbers of samples to seek | |
whence | SEEK_SET, SEEK_CUR, SEEK_END Returns 0 for success, or -1 for error |
Definition at line 659 of file file.c.
References ast_filestream::fmt, and ast_format::seek.
Referenced by ast_control_streamfile(), ast_read(), ast_stream_fastforward(), ast_stream_rewind(), ast_write(), dictate_exec(), handle_getoption(), handle_recordfile(), and handle_streamfile().
int ast_stopstream | ( | struct ast_channel * | c | ) |
c | The channel you wish to stop playback on Stop playback of a stream Returns 0 regardless |
Definition at line 184 of file file.c.
References ast_closestream(), ast_log(), ast_set_write_format(), LOG_WARNING, ast_channel::oldwriteformat, ast_channel::stream, and ast_channel::vstream.
Referenced by adsi_transmit_message_full(), ast_control_streamfile(), ast_openstream_full(), ast_play_and_wait(), ast_readstring(), ast_readstring_full(), ast_say_character_str_full(), ast_say_digit_str_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_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_phonetic_str_full(), ast_waitstream(), ast_waitstream_exten(), ast_waitstream_fr(), ast_waitstream_full(), background_detect_exec(), background_file(), builtin_blindtransfer(), conf_exec(), conf_run(), directory_exec(), handle_getoption(), handle_streamfile(), ices_exec(), ivr_dispatch(), leave_voicemail(), mp3_exec(), NBScat_exec(), parkandannounce_exec(), pbx_builtin_background(), pl_odtworz_plik(), play_file(), play_mailbox_owner(), playback_exec(), queue_exec(), read_exec(), recordthread(), rpt_tele_thread(), saycharstr(), sayfile(), saynum(), send_morse(), send_tone_telemetry(), send_waveform_to_channel(), vm_authenticate(), vm_execmain(), and zapateller_exec().
00185 { 00186 /* Stop a running stream if there is one */ 00187 if (tmp->vstream) { 00188 ast_closestream(tmp->vstream); 00189 tmp->vstream = NULL; 00190 } 00191 if (tmp->stream) { 00192 ast_closestream(tmp->stream); 00193 tmp->stream = NULL; 00194 if (tmp->oldwriteformat && ast_set_write_format(tmp, tmp->oldwriteformat)) 00195 ast_log(LOG_WARNING, "Unable to restore format back to %d\n", tmp->oldwriteformat); 00196 } 00197 return 0; 00198 }
int ast_stream_fastforward | ( | struct ast_filestream * | fs, | |
long | ms | |||
) |
fs | filestream to act on | |
ms | milliseconds to move Returns 0 for success, or -1 for error |
Definition at line 674 of file file.c.
References ast_seekstream(), and ast_frame::samples.
Referenced by ast_waitstream_fr().
00675 { 00676 /* I think this is right, 8000 samples per second, 1000 ms a second so 8 00677 * samples per ms */ 00678 long samples = ms * 8; 00679 return ast_seekstream(fs, samples, SEEK_CUR); 00680 }
int ast_stream_rewind | ( | struct ast_filestream * | fs, | |
long | ms | |||
) |
fs | filestream to act on | |
ms | milliseconds to move Returns 0 for success, or -1 for error |
Definition at line 682 of file file.c.
References ast_seekstream(), and ast_frame::samples.
Referenced by ast_play_and_prepend(), ast_play_and_record_full(), ast_waitstream_fr(), and handle_recordfile().
00683 { 00684 long samples = ms * 8; 00685 samples = samples * -1; 00686 return ast_seekstream(fs, samples, SEEK_CUR); 00687 }
int ast_streamfile | ( | struct ast_channel * | c, | |
const char * | filename, | |||
const char * | preflang | |||
) |
c | channel to stream the file to | |
filename | the name of the file you wish to stream, minus the extension | |
preflang | the preferred language you wish to have the file streamed to you in Prepares a channel for the streaming of a file. To start the stream, afterward do a ast_waitstream() on the channel Also, it will stop any existing streams on the channel. Returns 0 on success, or -1 on failure. |
Definition at line 800 of file file.c.
References ast_applystream(), ast_getformatname(), ast_log(), ast_openstream(), ast_openvstream(), ast_playstream(), ast_verbose(), LOG_DEBUG, LOG_WARNING, ast_channel::nativeformats, option_verbose, VERBOSE_PREFIX_3, and ast_filestream::vfs.
Referenced by __login_exec(), agent_call(), ast_app_getdata(), ast_app_getdata_full(), ast_app_getvoice(), ast_control_streamfile(), ast_play_and_prepend(), ast_play_and_record_full(), ast_play_and_wait(), ast_record_review(), ast_say_character_str_full(), ast_say_date_da(), ast_say_date_de(), ast_say_date_en(), ast_say_date_fr(), 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_gr(), ast_say_datetime_nl(), ast_say_datetime_pt(), ast_say_datetime_tw(), ast_say_digit_str_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_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_phonetic_str_full(), ast_say_time_de(), ast_say_time_en(), ast_say_time_fr(), ast_say_time_gr(), ast_say_time_nl(), ast_say_time_tw(), auth_exec(), background_detect_exec(), background_file(), bridge_playfile(), builtin_atxfer(), builtin_automonitor(), builtin_blindtransfer(), chanspy_exec(), check_availability(), check_beep(), conf_exec(), conf_run(), dial_exec_full(), directory_exec(), do_directory(), forward_message(), gr_say_number_female(), handle_recordfile(), invent_message(), ivr_dispatch(), leave_voicemail(), page_exec(), park_exec(), parkandannounce_exec(), pbx_builtin_background(), pl_odtworz_plik(), play_and_wait(), play_file(), play_mailbox_owner(), play_message_callerid(), play_record_review(), playback_exec(), privacy_exec(), retrydial_exec(), rpt_tele_thread(), sayfile(), ss_thread(), vm_authenticate(), wait_file(), and wait_file2().
00801 { 00802 struct ast_filestream *fs; 00803 struct ast_filestream *vfs; 00804 00805 fs = ast_openstream(chan, filename, preflang); 00806 vfs = ast_openvstream(chan, filename, preflang); 00807 if (vfs) 00808 ast_log(LOG_DEBUG, "Ooh, found a video stream, too\n"); 00809 if (fs){ 00810 if (ast_applystream(chan, fs)) 00811 return -1; 00812 if (vfs && ast_applystream(chan, vfs)) 00813 return -1; 00814 if (ast_playstream(fs)) 00815 return -1; 00816 if (vfs && ast_playstream(vfs)) 00817 return -1; 00818 #if 1 00819 if (option_verbose > 2) 00820 ast_verbose(VERBOSE_PREFIX_3 "Playing '%s' (language '%s')\n", filename, preflang ? preflang : "default"); 00821 #endif 00822 return 0; 00823 } 00824 ast_log(LOG_WARNING, "Unable to open %s (format %s): %s\n", filename, ast_getformatname(chan->nativeformats), strerror(errno)); 00825 return -1; 00826 }
long ast_tellstream | ( | struct ast_filestream * | fs | ) |
fs | fs to act on Returns a long as a sample offset into stream |
Definition at line 669 of file file.c.
References ast_filestream::fmt, and ast_format::tell.
Referenced by ast_control_streamfile(), handle_getoption(), handle_recordfile(), and handle_streamfile().
int ast_truncstream | ( | struct ast_filestream * | fs | ) |
fs | filestream to act on Returns 0 for success, or -1 for error |
Definition at line 664 of file file.c.
References ast_filestream::fmt, and ast_format::trunc.
Referenced by ast_play_and_prepend(), ast_play_and_record_full(), and handle_recordfile().
int ast_waitstream | ( | struct ast_channel * | c, | |
const char * | breakon | |||
) |
c | channel to waitstram 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 993 of file file.c.
References ast_channel::_softhangup, AST_CONTROL_ANSWER, AST_CONTROL_HANGUP, AST_CONTROL_RINGING, AST_CONTROL_VIDUPDATE, AST_FRAME_CONTROL, AST_FRAME_DTMF, ast_frfree(), ast_log(), ast_read(), ast_sched_runq(), ast_sched_wait(), ast_stopstream(), ast_waitfor(), ast_frame::frametype, LOG_DEBUG, LOG_WARNING, ast_channel::sched, ast_channel::stream, ast_frame::subclass, and ast_channel::timingfunc.
Referenced by __login_exec(), agent_call(), ast_app_getvoice(), ast_play_and_prepend(), ast_play_and_record_full(), ast_play_and_wait(), ast_readstring(), ast_record_review(), ast_say_date_da(), ast_say_date_de(), ast_say_date_en(), ast_say_date_fr(), 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_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_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_gr(), ast_say_time_nl(), ast_say_time_tw(), auth_exec(), background_file(), bridge_playfile(), builtin_atxfer(), builtin_automonitor(), builtin_blindtransfer(), chanspy_exec(), check_availability(), check_beep(), conf_exec(), conf_run(), dial_exec_full(), directory_exec(), gr_say_number_female(), handle_recordfile(), invent_message(), ivr_dispatch(), leave_voicemail(), page_exec(), park_exec(), parkandannounce_exec(), pbx_builtin_background(), pl_odtworz_plik(), play_and_wait(), play_file(), play_mailbox_owner(), play_message_callerid(), play_record_review(), playback_exec(), privacy_exec(), retrydial_exec(), rpt_tele_thread(), saycharstr(), sayfile(), saynum(), send_morse(), send_tone_telemetry(), ss_thread(), vm_authenticate(), wait_file(), and wait_file2().
00994 { 00995 /* XXX Maybe I should just front-end ast_waitstream_full ? XXX */ 00996 int res; 00997 struct ast_frame *fr; 00998 if (!breakon) breakon = ""; 00999 while(c->stream) { 01000 res = ast_sched_wait(c->sched); 01001 if ((res < 0) && !c->timingfunc) { 01002 ast_stopstream(c); 01003 break; 01004 } 01005 if (res < 0) 01006 res = 1000; 01007 res = ast_waitfor(c, res); 01008 if (res < 0) { 01009 ast_log(LOG_WARNING, "Select failed (%s)\n", strerror(errno)); 01010 return res; 01011 } else if (res > 0) { 01012 fr = ast_read(c); 01013 if (!fr) { 01014 #if 0 01015 ast_log(LOG_DEBUG, "Got hung up\n"); 01016 #endif 01017 return -1; 01018 } 01019 01020 switch(fr->frametype) { 01021 case AST_FRAME_DTMF: 01022 res = fr->subclass; 01023 if (strchr(breakon, res)) { 01024 ast_frfree(fr); 01025 return res; 01026 } 01027 break; 01028 case AST_FRAME_CONTROL: 01029 switch(fr->subclass) { 01030 case AST_CONTROL_HANGUP: 01031 ast_frfree(fr); 01032 return -1; 01033 case AST_CONTROL_RINGING: 01034 case AST_CONTROL_ANSWER: 01035 case AST_CONTROL_VIDUPDATE: 01036 /* Unimportant */ 01037 break; 01038 default: 01039 ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", fr->subclass); 01040 } 01041 } 01042 /* Ignore */ 01043 ast_frfree(fr); 01044 } 01045 ast_sched_runq(c->sched); 01046 } 01047 return (c->_softhangup ? -1 : 0); 01048 }
int ast_waitstream_exten | ( | struct ast_channel * | c, | |
const char * | context | |||
) |
c | channel to waitstram 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 1190 of file file.c.
References ast_channel::_softhangup, AST_CONTROL_ANSWER, AST_CONTROL_HANGUP, AST_CONTROL_RINGING, ast_exists_extension(), AST_FRAME_CONTROL, AST_FRAME_DTMF, ast_frfree(), ast_log(), AST_MAX_EXTENSION, ast_read(), ast_sched_runq(), ast_sched_wait(), ast_stopstream(), ast_waitfor(), ast_channel::cid, ast_callerid::cid_num, ast_channel::context, exten, ast_frame::frametype, LOG_DEBUG, LOG_WARNING, ast_channel::sched, ast_channel::stream, ast_frame::subclass, and ast_channel::timingfunc.
Referenced by pbx_builtin_background().
01191 { 01192 /* Waitstream, with return in the case of a valid 1 digit extension */ 01193 /* in the current or specified context being pressed */ 01194 /* XXX Maybe I should just front-end ast_waitstream_full ? XXX */ 01195 int res; 01196 struct ast_frame *fr; 01197 char exten[AST_MAX_EXTENSION]; 01198 01199 if (!context) context = c->context; 01200 while(c->stream) { 01201 res = ast_sched_wait(c->sched); 01202 if ((res < 0) && !c->timingfunc) { 01203 ast_stopstream(c); 01204 break; 01205 } 01206 if (res < 0) 01207 res = 1000; 01208 res = ast_waitfor(c, res); 01209 if (res < 0) { 01210 ast_log(LOG_WARNING, "Select failed (%s)\n", strerror(errno)); 01211 return res; 01212 } else if (res > 0) { 01213 fr = ast_read(c); 01214 if (!fr) { 01215 #if 0 01216 ast_log(LOG_DEBUG, "Got hung up\n"); 01217 #endif 01218 return -1; 01219 } 01220 01221 switch(fr->frametype) { 01222 case AST_FRAME_DTMF: 01223 res = fr->subclass; 01224 snprintf(exten, sizeof(exten), "%c", res); 01225 if (ast_exists_extension(c, context, exten, 1, c->cid.cid_num)) { 01226 ast_frfree(fr); 01227 return res; 01228 } 01229 break; 01230 case AST_FRAME_CONTROL: 01231 switch(fr->subclass) { 01232 case AST_CONTROL_HANGUP: 01233 ast_frfree(fr); 01234 return -1; 01235 case AST_CONTROL_RINGING: 01236 case AST_CONTROL_ANSWER: 01237 /* Unimportant */ 01238 break; 01239 default: 01240 ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", fr->subclass); 01241 } 01242 } 01243 /* Ignore */ 01244 ast_frfree(fr); 01245 } 01246 ast_sched_runq(c->sched); 01247 } 01248 return (c->_softhangup ? -1 : 0); 01249 }
int ast_waitstream_fr | ( | struct ast_channel * | c, | |
const char * | breakon, | |||
const char * | forward, | |||
const char * | rewind, | |||
int | ms | |||
) |
c | channel to waitstram 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 1050 of file file.c.
References ast_channel::_softhangup, AST_CONTROL_ANSWER, AST_CONTROL_HANGUP, AST_CONTROL_RINGING, AST_FRAME_CONTROL, AST_FRAME_DTMF, ast_frfree(), ast_log(), ast_read(), ast_sched_runq(), ast_sched_wait(), ast_stopstream(), ast_stream_fastforward(), ast_stream_rewind(), ast_waitfor(), ast_frame::frametype, LOG_DEBUG, LOG_WARNING, ast_channel::sched, ast_channel::stream, ast_frame::subclass, and ast_channel::timingfunc.
Referenced by ast_control_streamfile().
01051 { 01052 int res; 01053 struct ast_frame *fr; 01054 01055 if (!breakon) 01056 breakon = ""; 01057 if (!forward) 01058 forward = ""; 01059 if (!rewind) 01060 rewind = ""; 01061 01062 while(c->stream) { 01063 res = ast_sched_wait(c->sched); 01064 if ((res < 0) && !c->timingfunc) { 01065 ast_stopstream(c); 01066 break; 01067 } 01068 if (res < 0) 01069 res = 1000; 01070 res = ast_waitfor(c, res); 01071 if (res < 0) { 01072 ast_log(LOG_WARNING, "Select failed (%s)\n", strerror(errno)); 01073 return res; 01074 } else 01075 if (res > 0) { 01076 fr = ast_read(c); 01077 if (!fr) { 01078 #if 0 01079 ast_log(LOG_DEBUG, "Got hung up\n"); 01080 #endif 01081 return -1; 01082 } 01083 01084 switch(fr->frametype) { 01085 case AST_FRAME_DTMF: 01086 res = fr->subclass; 01087 if (strchr(forward,res)) { 01088 ast_stream_fastforward(c->stream, ms); 01089 } else if (strchr(rewind,res)) { 01090 ast_stream_rewind(c->stream, ms); 01091 } else if (strchr(breakon, res)) { 01092 ast_frfree(fr); 01093 return res; 01094 } 01095 break; 01096 case AST_FRAME_CONTROL: 01097 switch(fr->subclass) { 01098 case AST_CONTROL_HANGUP: 01099 ast_frfree(fr); 01100 return -1; 01101 case AST_CONTROL_RINGING: 01102 case AST_CONTROL_ANSWER: 01103 /* Unimportant */ 01104 break; 01105 default: 01106 ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", fr->subclass); 01107 } 01108 } 01109 /* Ignore */ 01110 ast_frfree(fr); 01111 } else 01112 ast_sched_runq(c->sched); 01113 01114 01115 } 01116 return (c->_softhangup ? -1 : 0); 01117 }
int ast_waitstream_full | ( | struct ast_channel * | c, | |
const char * | breakon, | |||
int | audiofd, | |||
int | cmdfd | |||
) |
Definition at line 1119 of file file.c.
References ast_channel::_softhangup, AST_CONTROL_ANSWER, AST_CONTROL_HANGUP, AST_CONTROL_RINGING, AST_FRAME_CONTROL, AST_FRAME_DTMF, AST_FRAME_VOICE, ast_frfree(), ast_log(), ast_read(), ast_sched_runq(), ast_sched_wait(), ast_stopstream(), ast_waitfor_nandfds(), ast_frame::data, ast_frame::datalen, ast_frame::frametype, LOG_DEBUG, LOG_WARNING, ast_channel::sched, ast_channel::stream, ast_frame::subclass, and ast_channel::timingfunc.
Referenced by ast_readstring_full(), ast_say_character_str_full(), ast_say_digit_str_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_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_phonetic_str_full(), handle_getoption(), handle_streamfile(), and pl_odtworz_plik().
01120 { 01121 int res; 01122 int ms; 01123 int outfd; 01124 struct ast_frame *fr; 01125 struct ast_channel *rchan; 01126 01127 if (!breakon) 01128 breakon = ""; 01129 01130 while(c->stream) { 01131 ms = ast_sched_wait(c->sched); 01132 if ((ms < 0) && !c->timingfunc) { 01133 ast_stopstream(c); 01134 break; 01135 } 01136 if (ms < 0) 01137 ms = 1000; 01138 rchan = ast_waitfor_nandfds(&c, 1, &cmdfd, (cmdfd > -1) ? 1 : 0, NULL, &outfd, &ms); 01139 if (!rchan && (outfd < 0) && (ms)) { 01140 /* Continue */ 01141 if (errno == EINTR) 01142 continue; 01143 ast_log(LOG_WARNING, "Wait failed (%s)\n", strerror(errno)); 01144 return -1; 01145 } else if (outfd > -1) { 01146 /* The FD we were watching has something waiting */ 01147 return 1; 01148 } else if (rchan) { 01149 fr = ast_read(c); 01150 if (!fr) { 01151 #if 0 01152 ast_log(LOG_DEBUG, "Got hung up\n"); 01153 #endif 01154 return -1; 01155 } 01156 01157 switch(fr->frametype) { 01158 case AST_FRAME_DTMF: 01159 res = fr->subclass; 01160 if (strchr(breakon, res)) { 01161 ast_frfree(fr); 01162 return res; 01163 } 01164 break; 01165 case AST_FRAME_CONTROL: 01166 switch(fr->subclass) { 01167 case AST_CONTROL_HANGUP: 01168 ast_frfree(fr); 01169 return -1; 01170 case AST_CONTROL_RINGING: 01171 case AST_CONTROL_ANSWER: 01172 /* Unimportant */ 01173 break; 01174 default: 01175 ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", fr->subclass); 01176 } 01177 case AST_FRAME_VOICE: 01178 /* Write audio if appropriate */ 01179 if (audiofd > -1) 01180 write(audiofd, fr->data, fr->datalen); 01181 } 01182 /* Ignore */ 01183 ast_frfree(fr); 01184 } 01185 ast_sched_runq(c->sched); 01186 } 01187 return (c->_softhangup ? -1 : 0); 01188 }
struct ast_filestream* ast_writefile | ( | const char * | filename, | |
const char * | type, | |||
const char * | comment, | |||
int | flags, | |||
int | check, | |||
mode_t | mode | |||
) |
filename | the name of the file to write to | |
type | format of file you wish to write out to | |
comment | comment to go with | |
flags | output file flags | |
check | (unimplemented, hence negligible) | |
mode | Open mode Create an outgoing file stream. oflags are flags for the open() command, and if check is non-zero, then it will not write a file if there are any files that start with that name and have an extension Please note, this is a blocking function. Program execution will not return until ast_waitstream completes it's execution. Returns a struct ast_filestream on success, NULL on failure |
Definition at line 874 of file file.c.
References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_strdupa, ast_filestream::buf, build_filename(), exts_compare(), ast_filestream::f, ast_filestream::filename, ast_filestream::flags, ast_filestream::fmt, formats, free, LOG_WARNING, ast_filestream::mode, option_cache_record_files, ast_filestream::realfilename, record_cache_dir, strdup, ast_filestream::trans, and ast_filestream::vfs.
Referenced by ast_app_getvoice(), ast_monitor_start(), ast_play_and_prepend(), ast_play_and_record_full(), ast_writestream(), dictate_exec(), handle_recordfile(), launch_monitor_thread(), and recordthread().
00875 { 00876 int fd, myflags = 0; 00877 /* compiler claims this variable can be used before initialization... */ 00878 FILE *bfile = NULL; 00879 struct ast_format *f; 00880 struct ast_filestream *fs = NULL; 00881 char *fn, *orig_fn = NULL; 00882 char *buf = NULL; 00883 size_t size = 0; 00884 int format_found = 0; 00885 00886 if (ast_mutex_lock(&formatlock)) { 00887 ast_log(LOG_WARNING, "Unable to lock format list\n"); 00888 return NULL; 00889 } 00890 00891 /* set the O_TRUNC flag if and only if there is no O_APPEND specified */ 00892 if (flags & O_APPEND) { 00893 /* We really can't use O_APPEND as it will break WAV header updates */ 00894 flags &= ~O_APPEND; 00895 } else { 00896 myflags = O_TRUNC; 00897 } 00898 00899 myflags |= O_WRONLY | O_CREAT; 00900 00901 for (f = formats; f && !fs; f = f->next) { 00902 if (!exts_compare(f->exts, type)) 00903 continue; 00904 else 00905 format_found = 1; 00906 00907 fn = build_filename(filename, type); 00908 fd = open(fn, flags | myflags, mode); 00909 if (fd > -1) { 00910 /* fdopen() the resulting file stream */ 00911 bfile = fdopen(fd, ((flags | myflags) & O_RDWR) ? "w+" : "w"); 00912 if (!bfile) { 00913 ast_log(LOG_WARNING, "Whoa, fdopen failed: %s!\n", strerror(errno)); 00914 close(fd); 00915 fd = -1; 00916 } 00917 } 00918 00919 if (option_cache_record_files && (fd > -1)) { 00920 char *c; 00921 00922 fclose(bfile); 00923 /* 00924 We touch orig_fn just as a place-holder so other things (like vmail) see the file is there. 00925 What we are really doing is writing to record_cache_dir until we are done then we will mv the file into place. 00926 */ 00927 orig_fn = ast_strdupa(fn); 00928 for (c = fn; *c; c++) 00929 if (*c == '/') 00930 *c = '_'; 00931 00932 size = strlen(fn) + strlen(record_cache_dir) + 2; 00933 buf = alloca(size); 00934 strcpy(buf, record_cache_dir); 00935 strcat(buf, "/"); 00936 strcat(buf, fn); 00937 free(fn); 00938 fn = buf; 00939 fd = open(fn, flags | myflags, mode); 00940 if (fd > -1) { 00941 /* fdopen() the resulting file stream */ 00942 bfile = fdopen(fd, ((flags | myflags) & O_RDWR) ? "w+" : "w"); 00943 if (!bfile) { 00944 ast_log(LOG_WARNING, "Whoa, fdopen failed: %s!\n", strerror(errno)); 00945 close(fd); 00946 fd = -1; 00947 } 00948 } 00949 } 00950 if (fd > -1) { 00951 errno = 0; 00952 if ((fs = f->rewrite(bfile, comment))) { 00953 fs->trans = NULL; 00954 fs->fmt = f; 00955 fs->flags = flags; 00956 fs->mode = mode; 00957 if (orig_fn) { 00958 fs->realfilename = strdup(orig_fn); 00959 fs->filename = strdup(fn); 00960 } else { 00961 fs->realfilename = NULL; 00962 fs->filename = strdup(filename); 00963 } 00964 fs->vfs = NULL; 00965 /* If truncated, we'll be at the beginning; if not truncated, then append */ 00966 f->seek(fs, 0, SEEK_END); 00967 } else { 00968 ast_log(LOG_WARNING, "Unable to rewrite %s\n", fn); 00969 close(fd); 00970 if (orig_fn) { 00971 unlink(fn); 00972 unlink(orig_fn); 00973 } 00974 } 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_mutex_unlock(&formatlock); 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 | |||
) |
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 200 of file file.c.
References AST_FORMAT_MAX_AUDIO, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_getformatname(), ast_log(), ast_translate(), ast_translator_build_path(), ast_translator_free_path(), ast_writefile(), ast_writestream(), ast_filestream::filename, ast_filestream::flags, ast_filestream::fmt, ast_format::format, ast_frame::frametype, ast_filestream::lastwriteformat, LOG_DEBUG, LOG_WARNING, ast_filestream::mode, ast_format::name, ast_frame::subclass, ast_filestream::trans, type, ast_filestream::vfs, and ast_format::write.
Referenced by ast_app_getvoice(), ast_play_and_prepend(), ast_play_and_record_full(), ast_read(), ast_write(), ast_writestream(), dictate_exec(), handle_recordfile(), mixmonitor_thread(), and recordthread().
00201 { 00202 struct ast_frame *trf; 00203 int res = -1; 00204 int alt=0; 00205 if (f->frametype == AST_FRAME_VIDEO) { 00206 if (fs->fmt->format < AST_FORMAT_MAX_AUDIO) { 00207 /* This is the audio portion. Call the video one... */ 00208 if (!fs->vfs && fs->filename) { 00209 /* XXX Support other video formats XXX */ 00210 const char *type = "h263"; 00211 fs->vfs = ast_writefile(fs->filename, type, NULL, fs->flags, 0, fs->mode); 00212 ast_log(LOG_DEBUG, "Opened video output file\n"); 00213 } 00214 if (fs->vfs) 00215 return ast_writestream(fs->vfs, f); 00216 /* Ignore */ 00217 return 0; 00218 } else { 00219 /* Might / might not have mark set */ 00220 alt = 1; 00221 } 00222 } else if (f->frametype != AST_FRAME_VOICE) { 00223 ast_log(LOG_WARNING, "Tried to write non-voice frame\n"); 00224 return -1; 00225 } 00226 if (((fs->fmt->format | alt) & f->subclass) == f->subclass) { 00227 res = fs->fmt->write(fs, f); 00228 if (res < 0) 00229 ast_log(LOG_WARNING, "Natural write failed\n"); 00230 if (res > 0) 00231 ast_log(LOG_WARNING, "Huh??\n"); 00232 return res; 00233 } else { 00234 /* XXX If they try to send us a type of frame that isn't the normal frame, and isn't 00235 the one we've setup a translator for, we do the "wrong thing" XXX */ 00236 if (fs->trans && (f->subclass != fs->lastwriteformat)) { 00237 ast_translator_free_path(fs->trans); 00238 fs->trans = NULL; 00239 } 00240 if (!fs->trans) 00241 fs->trans = ast_translator_build_path(fs->fmt->format, f->subclass); 00242 if (!fs->trans) 00243 ast_log(LOG_WARNING, "Unable to translate to format %s, source format %s\n", fs->fmt->name, ast_getformatname(f->subclass)); 00244 else { 00245 fs->lastwriteformat = f->subclass; 00246 res = 0; 00247 /* Get the translated frame but don't consume the original in case they're using it on another stream */ 00248 trf = ast_translate(fs->trans, f, 0); 00249 if (trf) { 00250 res = fs->fmt->write(fs, trf); 00251 if (res) 00252 ast_log(LOG_WARNING, "Translated frame write failed\n"); 00253 } else 00254 res = 0; 00255 } 00256 return res; 00257 } 00258 }
static char* build_filename | ( | const char * | filename, | |
const char * | ext | |||
) | [static] |
Definition at line 300 of file file.c.
References ast_config_AST_DATA_DIR, AST_CONFIG_MAX_PATH, malloc, and type.
Referenced by ast_filehelper(), ast_readfile(), and ast_writefile().
00301 { 00302 char *fn, type[16]; 00303 int fnsize = 0; 00304 00305 if (!strcmp(ext, "wav49")) { 00306 ast_copy_string(type, "WAV", sizeof(type)); 00307 } else { 00308 ast_copy_string(type, ext, sizeof(type)); 00309 } 00310 00311 if (filename[0] == '/') { 00312 fnsize = strlen(filename) + strlen(type) + 2; 00313 fn = malloc(fnsize); 00314 if (fn) 00315 snprintf(fn, fnsize, "%s.%s", filename, type); 00316 } else { 00317 char tmp[AST_CONFIG_MAX_PATH] = ""; 00318 00319 snprintf(tmp, sizeof(tmp), "%s/%s", ast_config_AST_DATA_DIR, "sounds"); 00320 fnsize = strlen(tmp) + strlen(filename) + strlen(type) + 3; 00321 fn = malloc(fnsize); 00322 if (fn) 00323 snprintf(fn, fnsize, "%s/%s.%s", tmp, filename, type); 00324 } 00325 00326 return fn; 00327 }
static int copy | ( | const char * | infile, | |
const char * | outfile | |||
) | [static] |
Definition at line 260 of file file.c.
References ast_log(), and LOG_WARNING.
Referenced by ast_filehelper(), ast_get_group(), copy_file(), get_group(), iax2_register(), and sip_register().
00261 { 00262 int ifd; 00263 int ofd; 00264 int res; 00265 int len; 00266 char buf[4096]; 00267 00268 if ((ifd = open(infile, O_RDONLY)) < 0) { 00269 ast_log(LOG_WARNING, "Unable to open %s in read-only mode\n", infile); 00270 return -1; 00271 } 00272 if ((ofd = open(outfile, O_WRONLY | O_TRUNC | O_CREAT, 0600)) < 0) { 00273 ast_log(LOG_WARNING, "Unable to open %s in write-only mode\n", outfile); 00274 close(ifd); 00275 return -1; 00276 } 00277 do { 00278 len = read(ifd, buf, sizeof(buf)); 00279 if (len < 0) { 00280 ast_log(LOG_WARNING, "Read failed on %s: %s\n", infile, strerror(errno)); 00281 close(ifd); 00282 close(ofd); 00283 unlink(outfile); 00284 } 00285 if (len) { 00286 res = write(ofd, buf, len); 00287 if (res != len) { 00288 ast_log(LOG_WARNING, "Write failed on %s (%d of %d): %s\n", outfile, res, len, strerror(errno)); 00289 close(ifd); 00290 close(ofd); 00291 unlink(outfile); 00292 } 00293 } 00294 } while(len); 00295 close(ifd); 00296 close(ofd); 00297 return 0; 00298 }
static int exts_compare | ( | const char * | exts, | |
const char * | type | |||
) | [static] |
Definition at line 329 of file file.c.
References strsep().
Referenced by ast_filehelper(), ast_readfile(), and ast_writefile().
00330 { 00331 char *stringp = NULL, *ext; 00332 char tmp[256]; 00333 00334 ast_copy_string(tmp, exts, sizeof(tmp)); 00335 stringp = tmp; 00336 while ((ext = strsep(&stringp, "|"))) { 00337 if (!strcmp(ext, type)) { 00338 return 1; 00339 } 00340 } 00341 00342 return 0; 00343 }
static int show_file_formats | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 1251 of file file.c.
References ast_cli(), ast_getformatname(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_format::exts, ast_format::format, FORMAT, FORMAT2, formats, LOG_WARNING, ast_format::name, ast_format::next, RESULT_SHOWUSAGE, and RESULT_SUCCESS.
01252 { 01253 #define FORMAT "%-10s %-10s %-20s\n" 01254 #define FORMAT2 "%-10s %-10s %-20s\n" 01255 struct ast_format *f; 01256 int count_fmt = 0; 01257 01258 if (argc != 3) 01259 return RESULT_SHOWUSAGE; 01260 ast_cli(fd, FORMAT, "Format", "Name", "Extensions"); 01261 01262 if (ast_mutex_lock(&formatlock)) { 01263 ast_log(LOG_WARNING, "Unable to lock format list\n"); 01264 return -1; 01265 } 01266 01267 f = formats; 01268 while(f) { 01269 ast_cli(fd, FORMAT2, ast_getformatname(f->format), f->name, f->exts); 01270 f = f->next; 01271 count_fmt++; 01272 }; 01273 ast_mutex_unlock(&formatlock); 01274 ast_cli(fd, "%d file formats registered.\n", count_fmt); 01275 return RESULT_SUCCESS; 01276 #undef FORMAT 01277 #undef FORMAT2 01278 01279 }
struct ast_format* formats = NULL [static] |
Definition at line 103 of file file.c.
Referenced by ast_filehelper(), ast_format_register(), ast_format_unregister(), ast_readfile(), ast_writefile(), and show_file_formats().
struct ast_cli_entry show_file |