#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 649 of file file.c.
References s.
Referenced by ast_streamfile(), handle_getoption(), handle_recordfile(), and handle_streamfile().
00650 { 00651 s->owner = chan; 00652 return 0; 00653 }
| 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 694 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_filehelper(), 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(), local_ast_moh_stop(), mixmonitor_thread(), moh_files_release(), and recordthread().
00695 { 00696 char *cmd = NULL; 00697 size_t size = 0; 00698 /* Stop a running stream if there is one */ 00699 if (f->owner) { 00700 if (f->fmt->format < AST_FORMAT_MAX_AUDIO) { 00701 f->owner->stream = NULL; 00702 if (f->owner->streamid > -1) 00703 ast_sched_del(f->owner->sched, f->owner->streamid); 00704 f->owner->streamid = -1; 00705 #ifdef ZAPTEL_OPTIMIZATIONS 00706 ast_settimeout(f->owner, 0, NULL, NULL); 00707 #endif 00708 } else { 00709 f->owner->vstream = NULL; 00710 if (f->owner->vstreamid > -1) 00711 ast_sched_del(f->owner->sched, f->owner->vstreamid); 00712 f->owner->vstreamid = -1; 00713 } 00714 } 00715 /* destroy the translator on exit */ 00716 if (f->trans) { 00717 ast_translator_free_path(f->trans); 00718 f->trans = NULL; 00719 } 00720 00721 if (f->realfilename && f->filename) { 00722 size = strlen(f->filename) + strlen(f->realfilename) + 15; 00723 cmd = alloca(size); 00724 memset(cmd,0,size); 00725 snprintf(cmd,size,"/bin/mv -f %s %s",f->filename,f->realfilename); 00726 ast_safe_system(cmd); 00727 } 00728 00729 if (f->filename) { 00730 free(f->filename); 00731 f->filename = NULL; 00732 } 00733 if (f->realfilename) { 00734 free(f->realfilename); 00735 f->realfilename = NULL; 00736 } 00737 f->fmt->close(f); 00738 return 0; 00739 }
| 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 1302 of file file.c.
References ast_cli_register(), and show_file.
Referenced by main().
01303 { 01304 ast_cli_register(&show_file); 01305 return 0; 01306 }
| 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 800 of file file.c.
References ACTION_COPY, and ast_filehelper().
Referenced by copy_file().
00801 { 00802 return ast_filehelper(filename, filename2, fmt, ACTION_COPY); 00803 }
| 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 790 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(), play_record_review(), and vm_delete().
00791 { 00792 return ast_filehelper(filename, NULL, fmt, ACTION_DELETE); 00793 }
| 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 742 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(), vm_newuser(), and vm_tempgreeting().
00743 { 00744 char filename2[256]; 00745 char tmp[256]; 00746 char *postfix; 00747 char *prefix; 00748 char *c; 00749 char lang2[MAX_LANGUAGE]; 00750 int res = -1; 00751 if (!ast_strlen_zero(preflang)) { 00752 /* Insert the language between the last two parts of the path */ 00753 ast_copy_string(tmp, filename, sizeof(tmp)); 00754 c = strrchr(tmp, '/'); 00755 if (c) { 00756 *c = '\0'; 00757 postfix = c+1; 00758 prefix = tmp; 00759 snprintf(filename2, sizeof(filename2), "%s/%s/%s", prefix, preflang, postfix); 00760 } else { 00761 postfix = tmp; 00762 prefix=""; 00763 snprintf(filename2, sizeof(filename2), "%s/%s", preflang, postfix); 00764 } 00765 res = ast_filehelper(filename2, NULL, fmt, ACTION_EXISTS); 00766 if (res < 1) { 00767 char *stringp=NULL; 00768 ast_copy_string(lang2, preflang, sizeof(lang2)); 00769 stringp=lang2; 00770 strsep(&stringp, "_"); 00771 /* If language is a specific locality of a language (like es_MX), strip the locality and try again */ 00772 if (strcmp(lang2, preflang)) { 00773 if (ast_strlen_zero(prefix)) { 00774 snprintf(filename2, sizeof(filename2), "%s/%s", lang2, postfix); 00775 } else { 00776 snprintf(filename2, sizeof(filename2), "%s/%s/%s", prefix, lang2, postfix); 00777 } 00778 res = ast_filehelper(filename2, NULL, fmt, ACTION_EXISTS); 00779 } 00780 } 00781 } 00782 00783 /* Fallback to no language (usually winds up being American English) */ 00784 if (res < 1) { 00785 res = ast_filehelper(filename, NULL, fmt, ACTION_EXISTS); 00786 } 00787 return res; 00788 }
| 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_closestream(), 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 if (chan->stream) 00432 ast_closestream(chan->stream); 00433 chan->stream = s; 00434 } else { 00435 if (chan->vstream) 00436 ast_closestream(chan->vstream); 00437 chan->vstream = s; 00438 } 00439 } else { 00440 fclose(bfile); 00441 ast_log(LOG_WARNING, "Unable to open file on %s\n", fn); 00442 ret = -1; 00443 } 00444 } else{ 00445 ast_log(LOG_WARNING, "Couldn't open file %s\n", fn); 00446 ret = -1; 00447 } 00448 } 00449 break; 00450 default: 00451 ast_log(LOG_WARNING, "Unknown helper %d\n", action); 00452 } 00453 /* Conveniently this logic is the same for all */ 00454 if (res) 00455 break; 00456 } 00457 free(fn); 00458 } 00459 ext = strsep(&stringp, "|"); 00460 } while(ext); 00461 00462 } 00463 f = f->next; 00464 } 00465 ast_mutex_unlock(&formatlock); 00466 if ((action == ACTION_EXISTS) || (action == ACTION_OPEN)) 00467 res = ret ? ret : -1; 00468 return res; 00469 }
| 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 795 of file file.c.
References ACTION_RENAME, and ast_filehelper().
Referenced by ast_monitor_stop(), ast_play_and_prepend(), leave_voicemail(), play_record_review(), and rename_file().
00796 { 00797 return ast_filehelper(filename, filename2, fmt, ACTION_RENAME); 00798 }
| 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 470 of file file.c.
References ast_openstream_full().
Referenced by ast_streamfile(), dictate_exec(), handle_getoption(), and handle_streamfile().
00471 { 00472 return ast_openstream_full(chan, filename, preflang, 0); 00473 }
| 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 475 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_moh_files_next(), ast_openstream(), and gen_nextfile().
00476 { 00477 /* This is a fairly complex routine. Essentially we should do 00478 the following: 00479 00480 1) Find which file handlers produce our type of format. 00481 2) Look for a filename which it can handle. 00482 3) If we find one, then great. 00483 4) If not, see what files are there 00484 5) See what we can actually support 00485 6) Choose the one with the least costly translator path and 00486 set it up. 00487 00488 */ 00489 int fmts = -1; 00490 char filename2[256]=""; 00491 char filename3[256]; 00492 char *endpart; 00493 int res; 00494 00495 if (!asis) { 00496 /* do this first, otherwise we detect the wrong writeformat */ 00497 ast_stopstream(chan); 00498 if (chan->generator) 00499 ast_deactivate_generator(chan); 00500 } 00501 if (!ast_strlen_zero(preflang)) { 00502 ast_copy_string(filename3, filename, sizeof(filename3)); 00503 endpart = strrchr(filename3, '/'); 00504 if (endpart) { 00505 *endpart = '\0'; 00506 endpart++; 00507 snprintf(filename2, sizeof(filename2), "%s/%s/%s", filename3, preflang, endpart); 00508 } else 00509 snprintf(filename2, sizeof(filename2), "%s/%s", preflang, filename); 00510 fmts = ast_fileexists(filename2, NULL, NULL); 00511 } 00512 if (fmts < 1) { 00513 ast_copy_string(filename2, filename, sizeof(filename2)); 00514 fmts = ast_fileexists(filename2, NULL, NULL); 00515 } 00516 if (fmts < 1) { 00517 ast_log(LOG_WARNING, "File %s does not exist in any format\n", filename); 00518 return NULL; 00519 } 00520 chan->oldwriteformat = chan->writeformat; 00521 /* Set the channel to a format we can work with */ 00522 res = ast_set_write_format(chan, fmts); 00523 00524 res = ast_filehelper(filename2, (char *)chan, NULL, ACTION_OPEN); 00525 if (res >= 0) 00526 return chan->stream; 00527 return NULL; 00528 }
| 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 530 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().
00531 { 00532 /* This is a fairly complex routine. Essentially we should do 00533 the following: 00534 00535 1) Find which file handlers produce our type of format. 00536 2) Look for a filename which it can handle. 00537 3) If we find one, then great. 00538 4) If not, see what files are there 00539 5) See what we can actually support 00540 6) Choose the one with the least costly translator path and 00541 set it up. 00542 00543 */ 00544 int fd = -1; 00545 int fmts = -1; 00546 char filename2[256]; 00547 char lang2[MAX_LANGUAGE]; 00548 /* XXX H.263 only XXX */ 00549 char *fmt = "h263"; 00550 if (!ast_strlen_zero(preflang)) { 00551 snprintf(filename2, sizeof(filename2), "%s/%s", preflang, filename); 00552 fmts = ast_fileexists(filename2, fmt, NULL); 00553 if (fmts < 1) { 00554 ast_copy_string(lang2, preflang, sizeof(lang2)); 00555 snprintf(filename2, sizeof(filename2), "%s/%s", lang2, filename); 00556 fmts = ast_fileexists(filename2, fmt, NULL); 00557 } 00558 } 00559 if (fmts < 1) { 00560 ast_copy_string(filename2, filename, sizeof(filename2)); 00561 fmts = ast_fileexists(filename2, fmt, NULL); 00562 } 00563 if (fmts < 1) { 00564 return NULL; 00565 } 00566 fd = ast_filehelper(filename2, (char *)chan, fmt, ACTION_OPEN); 00567 if (fd >= 0) 00568 return chan->vstream; 00569 ast_log(LOG_WARNING, "File %s has video but couldn't be opened\n", filename); 00570 return NULL; 00571 }
| int ast_playstream | ( | struct ast_filestream * | s | ) |
| s | filestream to play Returns 0 for success, -1 on failure |
Definition at line 655 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().
00656 { 00657 if (s->fmt->format < AST_FORMAT_MAX_AUDIO) 00658 ast_readaudio_callback(s); 00659 else 00660 ast_readvideo_callback(s); 00661 return 0; 00662 }
| static int ast_readaudio_callback | ( | void * | data | ) | [static] |
Definition at line 582 of file file.c.
References ast_log(), ast_sched_add(), ast_settimeout(), ast_write(), LOG_WARNING, and s.
Referenced by ast_playstream().
00583 { 00584 struct ast_filestream *s = data; 00585 struct ast_frame *fr; 00586 int whennext = 0; 00587 00588 while(!whennext) { 00589 fr = s->fmt->read(s, &whennext); 00590 if (fr) { 00591 if (ast_write(s->owner, fr)) { 00592 ast_log(LOG_WARNING, "Failed to write frame\n"); 00593 s->owner->streamid = -1; 00594 #ifdef ZAPTEL_OPTIMIZATIONS 00595 ast_settimeout(s->owner, 0, NULL, NULL); 00596 #endif 00597 return 0; 00598 } 00599 } else { 00600 /* Stream has finished */ 00601 s->owner->streamid = -1; 00602 #ifdef ZAPTEL_OPTIMIZATIONS 00603 ast_settimeout(s->owner, 0, NULL, NULL); 00604 #endif 00605 return 0; 00606 } 00607 } 00608 if (whennext != s->lasttimeout) { 00609 #ifdef ZAPTEL_OPTIMIZATIONS 00610 if (s->owner->timingfd > -1) 00611 ast_settimeout(s->owner, whennext, ast_readaudio_callback, s); 00612 else 00613 #endif 00614 s->owner->streamid = ast_sched_add(s->owner->sched, whennext/8, ast_readaudio_callback, s); 00615 s->lasttimeout = whennext; 00616 return 0; 00617 } 00618 return 1; 00619 }
| 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 832 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().
00833 { 00834 FILE *bfile; 00835 struct ast_format *f; 00836 struct ast_filestream *fs = NULL; 00837 char *fn; 00838 00839 if (ast_mutex_lock(&formatlock)) { 00840 ast_log(LOG_WARNING, "Unable to lock format list\n"); 00841 return NULL; 00842 } 00843 00844 for (f = formats; f && !fs; f = f->next) { 00845 if (!exts_compare(f->exts, type)) 00846 continue; 00847 00848 fn = build_filename(filename, type); 00849 bfile = fopen(fn, "r"); 00850 if (bfile) { 00851 errno = 0; 00852 00853