Sat Nov 1 06:31:04 2008

Asterisk developer's documentation


file.c File Reference

Generic File Format Support. More...

#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_filestreamast_openstream (struct ast_channel *chan, const char *filename, const char *preflang)
ast_filestreamast_openstream_full (struct ast_channel *chan, const char *filename, const char *preflang, int asis)
ast_filestreamast_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_filestreamast_readfile (const char *filename, const char *type, const char *comment, int flags, int check, mode_t mode)
ast_frameast_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_filestreamast_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_formatformats = NULL
ast_cli_entry show_file


Detailed Description

Generic File Format Support.

Definition in file file.c.


Define Documentation

#define ACTION_COPY   5

Definition at line 349 of file file.c.

Referenced by ast_filecopy(), and ast_filehelper().

#define ACTION_DELETE   2

Definition at line 346 of file file.c.

Referenced by ast_filedelete(), and ast_filehelper().

#define ACTION_EXISTS   1

Definition at line 345 of file file.c.

Referenced by ast_fileexists(), and ast_filehelper().

#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

Definition at line 347 of file file.c.

Referenced by ast_filehelper(), and ast_filerename().

#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().


Function Documentation

int ast_applystream ( struct ast_channel chan,
struct ast_filestream s 
)

Parameters:
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  ) 

Parameters:
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 
)

Parameters:
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 
)

Parameters:
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 
)

Parameters:
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 
)

Parameters:
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  ) 

Parameters:
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 
)

Parameters:
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 
)

Parameters:
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 
)

Parameters:
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  ) 

Parameters:
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 
)

Parameters:
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