Fri May 26 01:48:34 2006

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 346 of file file.c.

Referenced by ast_filecopy(), and ast_filehelper().

#define ACTION_DELETE   2
 

Definition at line 343 of file file.c.

Referenced by ast_filedelete(), and ast_filehelper().

#define ACTION_EXISTS   1
 

Definition at line 342 of file file.c.

Referenced by ast_fileexists(), and ast_filehelper().

#define ACTION_OPEN   4
 

Definition at line 345 of file file.c.

Referenced by ast_filehelper(), ast_openstream_full(), and ast_openvstream().

#define ACTION_RENAME   3
 

Definition at line 344 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(), 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 641 of file file.c.

References s.

Referenced by ast_streamfile(), handle_getoption(), handle_recordfile(), and handle_streamfile().

00642 {
00643    s->owner = chan;
00644    return 0;
00645 }

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 686 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_stopstream(), gen_closestream(), handle_recordfile(), local_ast_moh_stop(), record_exec(), and recordthread().

00687 {
00688    char *cmd = NULL;
00689    size_t size = 0;
00690    /* Stop a running stream if there is one */
00691    if (f->owner) {
00692       if (f->fmt->format < AST_FORMAT_MAX_AUDIO) {
00693          f->owner->stream = NULL;
00694          if (f->owner->streamid > -1)
00695             ast_sched_del(f->owner->sched, f->owner->streamid);
00696          f->owner->streamid = -1;
00697 #ifdef ZAPTEL_OPTIMIZATIONS
00698          ast_settimeout(f->owner, 0, NULL, NULL);
00699 #endif         
00700       } else {
00701          f->owner->vstream = NULL;
00702          if (f->owner->vstreamid > -1)
00703             ast_sched_del(f->owner->sched, f->owner->vstreamid);
00704          f->owner->vstreamid = -1;
00705       }
00706    }
00707    /* destroy the translator on exit */
00708    if (f->trans) {
00709       ast_translator_free_path(f->trans);
00710       f->trans = NULL;
00711    }
00712 
00713    if (f->realfilename && f->filename) {
00714          size = strlen(f->filename) + strlen(f->realfilename) + 15;
00715          cmd = alloca(size);
00716          memset(cmd,0,size);
00717          snprintf(cmd,size,"/bin/mv -f %s %s",f->filename,f->realfilename);
00718          ast_safe_system(cmd);
00719    }
00720 
00721    if (f->filename) {
00722       free(f->filename);
00723       f->filename = NULL;
00724    }
00725    if (f->realfilename) {
00726       free(f->realfilename);
00727       f->realfilename = NULL;
00728    }
00729    f->fmt->close(f);
00730    return 0;
00731 }

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 1283 of file file.c.

References ast_cli_register(), and show_file.

01284 {
01285    ast_cli_register(&show_file);
01286    return 0;
01287 }

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 792 of file file.c.

References ACTION_COPY, and ast_filehelper().

Referenced by copy_file().

00793 {
00794    return ast_filehelper(filename, filename2, fmt, ACTION_COPY);
00795 }

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 782 of file file.c.

References ACTION_DELETE, and ast_filehelper().

Referenced by ast_monitor_start(), ast_monitor_stop(), and vm_delete().

00783 {
00784    return ast_filehelper(filename, NULL, fmt, ACTION_DELETE);
00785 }

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 734 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(), conf_run(), dial_exec_full(), invent_message(), last_message_index(), leave_voicemail(), play_mailbox_owner(), play_message_callerid(), record_exec(), and vm_tempgreeting().

00735 {
00736    char filename2[256];
00737    char tmp[256];
00738    char *postfix;
00739    char *prefix;
00740    char *c;
00741    char lang2[MAX_LANGUAGE];
00742    int res = -1;
00743    if (!ast_strlen_zero(preflang)) {
00744       /* Insert the language between the last two parts of the path */
00745       ast_copy_string(tmp, filename, sizeof(tmp));
00746       c = strrchr(tmp, '/');
00747       if (c) {
00748          *c = '\0';
00749          postfix = c+1;
00750          prefix = tmp;
00751          snprintf(filename2, sizeof(filename2), "%s/%s/%s", prefix, preflang, postfix);
00752       } else {
00753          postfix = tmp;
00754          prefix="";
00755          snprintf(filename2, sizeof(filename2), "%s/%s", preflang, postfix);
00756       }
00757       res = ast_filehelper(filename2, NULL, fmt, ACTION_EXISTS);
00758       if (res < 1) {
00759          char *stringp=NULL;
00760          ast_copy_string(lang2, preflang, sizeof(lang2));
00761          stringp=lang2;
00762          strsep(&stringp, "_");
00763          /* If language is a specific locality of a language (like es_MX), strip the locality and try again */
00764          if (strcmp(lang2, preflang)) {
00765             if (ast_strlen_zero(prefix)) {
00766                snprintf(filename2, sizeof(filename2), "%s/%s", lang2, postfix);
00767             } else {
00768                snprintf(filename2, sizeof(filename2), "%s/%s/%s", prefix, lang2, postfix);
00769             }
00770             res = ast_filehelper(filename2, NULL, fmt, ACTION_EXISTS);
00771          }
00772       }
00773    }
00774 
00775    /* Fallback to no language (usually winds up being American English) */
00776    if (res < 1) {
00777       res = ast_filehelper(filename, NULL, fmt, ACTION_EXISTS);
00778    }
00779    return res;
00780 }

static int ast_filehelper const char *  filename,
const char *  filename2,
const char *  fmt,
int  action
[static]
 

Definition at line 348 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().

00349 {
00350    struct stat st;
00351    struct ast_format *f;
00352    struct ast_filestream *s;
00353    int res=0, ret = 0;
00354    char *ext=NULL, *exts, *fn, *nfn;
00355    FILE *bfile;
00356    struct ast_channel *chan = (struct ast_channel *)filename2;
00357    
00358    /* Start with negative response */
00359    if (action == ACTION_EXISTS)
00360       res = 0;
00361    else
00362       res = -1;
00363    if (action == ACTION_OPEN)
00364       ret = -1;
00365    /* Check for a specific format */
00366    if (ast_mutex_lock(&formatlock)) {
00367       ast_log(LOG_WARNING, "Unable to lock format list\n");
00368       if (action == ACTION_EXISTS)
00369          return 0;
00370       else
00371          return -1;
00372    }
00373    f = formats;
00374    while(f) {
00375       if (!fmt || exts_compare(f->exts, fmt)) {
00376          char *stringp=NULL;
00377          exts = ast_strdupa(f->exts);
00378          /* Try each kind of extension */
00379          stringp=exts;
00380          ext = strsep(&stringp, "|");
00381          do {
00382             fn = build_filename(filename, ext);
00383             if (fn) {
00384                res = stat(fn, &st);
00385                if (!res) {
00386                   switch(action) {
00387                   case ACTION_EXISTS:
00388                      ret |= f->format;
00389                      break;
00390                   case ACTION_DELETE:
00391                      res = unlink(fn);
00392                      if (res)
00393                         ast_log(LOG_WARNING, "unlink(%s) failed: %s\n", fn, strerror(errno));
00394                      break;
00395                   case ACTION_RENAME:
00396                      nfn = build_filename(filename2, ext);
00397                      if (nfn) {
00398                         res = rename(fn, nfn);
00399                         if (res)
00400                            ast_log(LOG_WARNING, "rename(%s,%s) failed: %s\n", fn, nfn, strerror(errno));
00401                         free(nfn);
00402                      } else
00403                         ast_log(LOG_WARNING, "Out of memory\n");
00404                      break;
00405                   case ACTION_COPY:
00406                      nfn = build_filename(filename2, ext);
00407                      if (nfn) {
00408                         res = copy(fn, nfn);
00409                         if (res)
00410                            ast_log(LOG_WARNING, "copy(%s,%s) failed: %s\n", fn, nfn, strerror(errno));
00411                         free(nfn);
00412                      } else
00413                         ast_log(LOG_WARNING, "Out of memory\n");
00414                      break;
00415                   case ACTION_OPEN:
00416                      if ((ret < 0) && ((chan->writeformat & f->format) ||
00417                               ((f->format >= AST_FORMAT_MAX_AUDIO) && fmt))) {
00418                         bfile = fopen(fn, "r");
00419                         if (bfile) {
00420                            ret = 1;
00421                            s = f->open(bfile);
00422                            if (s) {
00423                               s->lasttimeout = -1;
00424                               s->fmt = f;
00425                               s->trans = NULL;
00426                               s->filename = NULL;
00427                               if (s->fmt->format < AST_FORMAT_MAX_AUDIO)
00428                                  chan->stream = s;
00429                               else
00430                                  chan->vstream = s;
00431                            } else {
00432                               fclose(bfile);
00433                               ast_log(LOG_WARNING, "Unable to open file on %s\n", fn);
00434                               ret = -1;
00435                            }
00436                         } else{
00437                            ast_log(LOG_WARNING, "Couldn't open file %s\n", fn);
00438                            ret = -1;
00439                         }
00440                      }
00441                      break;
00442                   default:
00443                      ast_log(LOG_WARNING, "Unknown helper %d\n", action);
00444                   }
00445                   /* Conveniently this logic is the same for all */
00446                   if (res)
00447                      break;
00448                }
00449                free(fn);
00450             }
00451             ext = strsep(&stringp, "|");
00452          } while(ext);
00453          
00454       }
00455       f = f->next;
00456    }
00457    ast_mutex_unlock(&formatlock);
00458    if ((action == ACTION_EXISTS) || (action == ACTION_OPEN))
00459       res = ret ? ret : -1;
00460    return res;
00461 }

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 787 of file file.c.

References ACTION_RENAME, and ast_filehelper().

Referenced by ast_monitor_stop(), and rename_file().

00788 {
00789    return ast_filehelper(filename, filename2, fmt, ACTION_RENAME);
00790 }

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 462 of file file.c.

References ast_openstream_full().

Referenced by ast_streamfile(), handle_getoption(), and handle_streamfile().

00463 {
00464    return ast_openstream_full(chan, filename, preflang, 0);
00465 }

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

00468 {
00469    /* This is a fairly complex routine.  Essentially we should do 
00470       the following:
00471       
00472       1) Find which file handlers produce our type of format.
00473       2) Look for a filename which it can handle.
00474       3) If we find one, then great.  
00475       4) If not, see what files are there
00476       5) See what we can actually support
00477       6) Choose the one with the least costly translator path and
00478           set it up.
00479          
00480    */
00481    int fmts = -1;
00482    char filename2[256]="";
00483    char filename3[256];
00484    char *endpart;
00485    int res;
00486 
00487    if (!asis) {
00488       /* do this first, otherwise we detect the wrong writeformat */
00489       ast_stopstream(chan);
00490       if (chan->generator)
00491          ast_deactivate_generator(chan);
00492    }
00493    if (!ast_strlen_zero(preflang)) {
00494       ast_copy_string(filename3, filename, sizeof(filename3));
00495       endpart = strrchr(filename3, '/');
00496       if (endpart) {
00497          *endpart = '\0';
00498          endpart++;
00499          snprintf(filename2, sizeof(filename2), "%s/%s/%s", filename3, preflang, endpart);
00500       } else
00501          snprintf(filename2, sizeof(filename2), "%s/%s", preflang, filename);
00502       fmts = ast_fileexists(filename2, NULL, NULL);
00503    }
00504    if (fmts < 1) {
00505       ast_copy_string(filename2, filename, sizeof(filename2));
00506       fmts = ast_fileexists(filename2, NULL, NULL);
00507    }
00508    if (fmts < 1) {
00509       ast_log(LOG_WARNING, "File %s does not exist in any format\n", filename);
00510       return NULL;
00511    }
00512    chan->oldwriteformat = chan->writeformat;
00513    /* Set the channel to a format we can work with */
00514    res = ast_set_write_format(chan, fmts);
00515    
00516    res = ast_filehelper(filename2, (char *)chan, NULL, ACTION_OPEN);
00517    if (res >= 0)
00518       return chan->stream;
00519    return NULL;
00520 }

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

00523 {
00524    /* This is a fairly complex routine.  Essentially we should do 
00525       the following:
00526       
00527       1) Find which file handlers produce our type of format.
00528       2) Look for a filename which it can handle.
00529       3) If we find one, then great.  
00530       4) If not, see what files are there
00531       5) See what we can actually support
00532       6) Choose the one with the least costly translator path and
00533           set it up.
00534          
00535    */
00536    int fd = -1;
00537    int fmts = -1;
00538    char filename2[256];
00539    char lang2[MAX_LANGUAGE];
00540    /* XXX H.263 only XXX */
00541    char *fmt = "h263";
00542    if (!ast_strlen_zero(preflang)) {
00543       snprintf(filename2, sizeof(filename2), "%s/%s", preflang, filename);
00544       fmts = ast_fileexists(filename2, fmt, NULL);
00545       if (fmts < 1) {
00546          ast_copy_string(lang2, preflang, sizeof(lang2));
00547          snprintf(filename2, sizeof(filename2), "%s/%s", lang2, filename);
00548          fmts = ast_fileexists(filename2, fmt, NULL);
00549       }
00550    }
00551    if (fmts < 1) {
00552       ast_copy_string(filename2, filename, sizeof(filename2));
00553       fmts = ast_fileexists(filename2, fmt, NULL);
00554    }
00555    if (fmts < 1) {
00556       return NULL;
00557    }
00558    fd = ast_filehelper(filename2, (char *)chan, fmt, ACTION_OPEN);
00559    if (fd >= 0)
00560       return chan->vstream;
00561    ast_log(LOG_WARNING, "File %s has video but couldn't be opened\n", filename);
00562    return NULL;
00563 }

int ast_playstream struct ast_filestream s  ) 
 

Parameters:
s filestream to play Returns 0 for success, -1 on failure

Definition at line 647 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().

00648 {
00649    if (s->fmt->format < AST_FORMAT_MAX_AUDIO)
00650       ast_readaudio_callback(s);
00651    else
00652       ast_readvideo_callback(s);
00653    return 0;
00654 }

static int ast_readaudio_callback void *  data  )  [static]
 

Definition at line 574 of file file.c.

References ast_log(), ast_sched_add(), ast_settimeout(), ast_write(), LOG_WARNING, and s.

Referenced by ast_playstream().

00575 {
00576    struct ast_filestream *s = data;
00577    struct ast_frame *fr;
00578    int whennext = 0;
00579 
00580    while(!whennext) {
00581       fr = s->fmt->read(s, &whennext);
00582       if (fr) {
00583          if (ast_write(s->owner, fr)) {
00584             ast_log(LOG_WARNING, "Failed to write frame\n");
00585             s->owner->streamid = -1;
00586 #ifdef ZAPTEL_OPTIMIZATIONS
00587             ast_settimeout(s->owner, 0, NULL, NULL);
00588 #endif         
00589             return 0;
00590          }
00591       } else {
00592          /* Stream has finished */
00593          s->owner->streamid = -1;
00594 #ifdef ZAPTEL_OPTIMIZATIONS
00595          ast_settimeout(s->owner, 0, NULL, NULL);
00596 #endif         
00597          return 0;
00598       }
00599    }
00600    if (whennext != s->lasttimeout) {
00601 #ifdef ZAPTEL_OPTIMIZATIONS
00602       if (s->owner->timingfd > -1)
00603          ast_settimeout(s->owner, whennext, ast_readaudio_callback, s);
00604       else
00605 #endif      
00606          s->owner->streamid = ast_sched_add(s->owner->sched, whennext/8, ast_readaudio_callback, s);
00607       s->lasttimeout = whennext;
00608       return 0;
00609    }
00610    return 1;
00611 }

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 825 of file file.c.

References ast_log(), ast_mutex_lock(), 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.

00826 {
00827    FILE *bfile;
00828    struct ast_format *f;
00829    struct ast_filestream *fs = NULL;
00830    char *fn;
00831 
00832    if (ast_mutex_lock(&formatlock)) {
00833       ast_log(LOG_WARNING, "Unable to lock format list\n");
00834       return NULL;
00835    }
00836 
00837    for (f = formats; f && !fs; f = f->next) {
00838       if (!exts_compare(f->exts, type))
00839          continue;
00840 
00841       fn = build_filename(filename, type);
00842       bfile = fopen(fn, "r");
00843       if (bfile) {
00844          errno = 0;
00845 
00846          if (!(fs = f->open(bfile))) {
00847             ast_log(LOG_WARNING, "Unable to open %s\n", fn);
00848             fclose(bfile);
00849             free(fn);
00850             continue;
00851          }
00852 
00853          fs->trans = NULL;
00854          fs->fmt = f;
00855          fs->flags = flags;
00856          fs->mode = mode;
00857          fs->filename = strdup(filename);
00858          fs->vfs = NULL;
00859       } else if (errno != EEXIST)
00860          ast_log(LOG_WARNING, "Unable to open file %s: %s\n", fn, strerror(errno));
00861       free(fn);
00862    }
00863 
00864    ast_mutex_unlock(&formatlock);
00865    if (!fs) 
00866       ast_log(LOG_WARNING, "No such format '%s'\n", type);
00867 
00868    return fs;
00869 }

struct ast_frame* ast_readframe struct ast_filestream s  ) 
 

Parameters:
s ast_filestream to act on Returns a frame or NULL if read failed

Definition at line 565 of file file.c.

References s.

Referenced by gen_readframe(), and moh_files_readframe().

00566 {
00567    struct ast_frame *f = NULL;
00568    int whennext = 0; 
00569    if (s && s->fmt)
00570       f = s->fmt->read(s, &whennext);
00571    return f;
00572 }

static int ast_readvideo_callback void *  data  )  [static]
 

Definition at line 613 of file file.c.

References ast_log(), ast_sched_add(), ast_write(), LOG_WARNING, and s.

Referenced by ast_playstream().

00614 {
00615    struct ast_filestream *s = data;
00616    struct ast_frame *fr;
00617    int whennext = 0;
00618 
00619    while(!whennext) {
00620       fr = s->fmt->read(s, &whennext);
00621       if (fr) {
00622          if (ast_write(s->owner, fr)) {
00623             ast_log(LOG_WARNING, "Failed to write frame\n");
00624             s->owner->vstreamid = -1;
00625             return 0;
00626          }
00627       } else {
00628          /* Stream has finished */
00629          s->owner->vstreamid = -1;
00630          return 0;
00631       }
00632    }
00633    if (whennext != s->lasttimeout) {
00634       s->owner->vstreamid = ast_sched_add(s->owner->sched, whennext/8, ast_readvideo_callback, s);
00635       s->lasttimeout = whennext;
00636       return 0;
00637    }
00638    return 1;
00639 }

int ast_seekstream struct ast_filestream fs,
long  sample_offset,
int  whence
 

Parameters:
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 656 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(), handle_getoption(), handle_recordfile(), handle_streamfile(), and mixmonitor_thread().

00657 {
00658    return fs->fmt->seek(fs, sample_offset, whence);
00659 }

int ast_stopstream struct ast_channel c  ) 
 

Parameters:
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(), 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(), read_exec(), record_exec(), recordthread(), saycharstr(), sayfile(), saynum(), 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    if (tmp->stream) {
00190       ast_closestream(tmp->stream);
00191       if (tmp->oldwriteformat && ast_set_write_format(tmp, tmp->oldwriteformat))
00192          ast_log(LOG_WARNING, "Unable to restore format back to %d\n", tmp->oldwriteformat);
00193    }
00194    return 0;
00195 }

int ast_stream_fastforward struct ast_filestream fs,
long  ms
 

Parameters:
fs filestream to act on
ms milliseconds to move Returns 0 for success, or -1 for error

Definition at line 671 of file file.c.

References ast_seekstream(), and ast_frame::samples.

Referenced by ast_waitstream_fr().

00672 {
00673    /* I think this is right, 8000 samples per second, 1000 ms a second so 8
00674     * samples per ms  */
00675    long samples = ms * 8;
00676    return ast_seekstream(fs, samples, SEEK_CUR);
00677 }

int ast_stream_rewind struct ast_filestream fs,
long  ms
 

Parameters:
fs filestream to act on
ms milliseconds to move Returns 0 for success, or -1 for error

Definition at line 679 of file file.c.

References ast_seekstream(), and ast_frame::samples.

Referenced by ast_waitstream_fr(), handle_recordfile(), and record_exec().

00680 {
00681    long samples = ms * 8;
00682    samples = samples * -1;
00683    return ast_seekstream(fs, samples, SEEK_CUR);
00684 }

int ast_streamfile struct ast_channel c,
const char *  filename,
const char *  preflang
 

Parameters:
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 797 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(), 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(), background_detect_exec(), background_file(), bridge_playfile(), builtin_atxfer(), builtin_automonitor(), builtin_blindtransfer(), chanspy_exec(), check_availability(), check_beep(), conf_run(), directory_exec(), do_directory(), forward_message(), gr_say_number_female(), handle_recordfile(), invent_message(), ivr_dispatch(), leave_voicemail(), page_exec(), park_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(), record_exec(), retrydial_exec(), sayfile(), ss_thread(), vm_authenticate(), wait_file(), and wait_file2().

00798 {
00799    struct ast_filestream *fs;
00800    struct ast_filestream *vfs;
00801 
00802    fs = ast_openstream(chan, filename, preflang);
00803    vfs = ast_openvstream(chan, filename, preflang);
00804    if (vfs)
00805       ast_log(LOG_DEBUG, "Ooh, found a video stream, too\n");
00806    if (fs){
00807       if (ast_applystream(chan, fs))
00808          return -1;
00809       if (vfs && ast_applystream(chan, vfs))
00810          return -1;
00811       if (ast_playstream(fs))
00812          return -1;
00813       if (vfs && ast_playstream(vfs))
00814          return -1;
00815 #if 1
00816       if (option_verbose > 2)
00817          ast_verbose(VERBOSE_PREFIX_3 "Playing '%s' (language '%s')\n", filename, preflang ? preflang : "default");
00818 #endif
00819       return 0;
00820    }
00821    ast_log(LOG_WARNING, "Unable to open %s (format %s): %s\n", filename, ast_getformatname(chan->nativeformats), strerror(errno));
00822    return -1;
00823 }

long ast_tellstream struct ast_filestream fs  ) 
 

Parameters:
fs fs to act on Returns a long as a sample offset into stream

Definition at line 666 of file file.c.

References ast_filestream::fmt, and ast_format::tell.

Referenced by ast_control_streamfile(), handle_getoption(), handle_recordfile(), and handle_streamfile().

00667 {
00668    return fs->fmt->tell(fs);
00669 }

int ast_truncstream struct ast_filestream fs  ) 
 

Parameters:
fs filestream to act on Returns 0 for success, or -1 for error

Definition at line 661 of file file.c.

References ast_filestream::fmt, and ast_format::trunc.

Referenced by handle_recordfile(), and record_exec().

00662 {
00663    return fs->fmt->trunc(fs);
00664 }

int ast_waitstream struct ast_channel c,
const char *  breakon
 

Parameters:
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 986 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(), 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(), background_file(), bridge_playfile(), builtin_atxfer(), builtin_automonitor(), builtin_blindtransfer(), chanspy_exec(), check_availability(), check_beep(), conf_run(), directory_exec(), gr_say_number_female(), handle_recordfile(), invent_message(), ivr_dispatch(), leave_voicemail(), page_exec(), park_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(), record_exec(), retrydial_exec(), saycharstr(), sayfile(), saynum(), ss_thread(), vm_authenticate(), wait_file(), and wait_file2().

00987 {
00988    /* XXX Maybe I should just front-end ast_waitstream_full ? XXX */
00989    int res;
00990    struct ast_frame *fr;
00991    if (!breakon) breakon = "";
00992    while(c->stream) {
00993       res = ast_sched_wait(c->sched);
00994       if ((res < 0) && !c->timingfunc) {
00995          ast_stopstream(c);
00996          break;
00997       }
00998       if (res < 0)
00999          res = 1000;
01000       res = ast_waitfor(c, res);
01001       if (res < 0) {
01002          ast_log(LOG_WARNING, "Select failed (%s)\n", strerror(errno));
01003          return res;
01004       } else if (res > 0) {
01005          fr = ast_read(c);
01006          if (!fr) {
01007 #if 0
01008             ast_log(LOG_DEBUG, "Got hung up\n");
01009 #endif
01010             return -1;
01011          }
01012          
01013          switch(fr->frametype) {
01014          case AST_FRAME_DTMF:
01015             res = fr->subclass;
01016             if (strchr(breakon, res)) {
01017                ast_frfree(fr);
01018                return res;
01019             }
01020             break;
01021          case AST_FRAME_CONTROL:
01022             switch(fr->subclass) {
01023             case AST_CONTROL_HANGUP:
01024                ast_frfree(fr);
01025                return -1;
01026             case AST_CONTROL_RINGING:
01027             case AST_CONTROL_ANSWER:
01028             case AST_CONTROL_VIDUPDATE:
01029                /* Unimportant */
01030                break;
01031             default:
01032                ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", fr->subclass);
01033             }
01034          }
01035          /* Ignore */
01036          ast_frfree(fr);
01037       }
01038       ast_sched_runq(c->sched);
01039    }
01040    return (c->_softhangup ? -1 : 0);
01041 }

int ast_waitstream_exten struct ast_channel c,
const char *  context
 

Parameters:
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 1183 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().

01184 {
01185    /* Waitstream, with return in the case of a valid 1 digit extension */
01186    /* in the current or specified context being pressed */
01187    /* XXX Maybe I should just front-end ast_waitstream_full ? XXX */
01188    int res;
01189    struct ast_frame *fr;
01190    char exten[AST_MAX_EXTENSION];
01191 
01192    if (!context) context = c->context;
01193    while(c->stream) {
01194       res = ast_sched_wait(c->sched);
01195       if ((res < 0) && !c->timingfunc) {
01196          ast_stopstream(c);
01197          break;
01198       }
01199       if (res < 0)
01200          res = 1000;
01201       res = ast_waitfor(c, res);
01202       if (res < 0) {
01203          ast_log(LOG_WARNING, "Select failed (%s)\n", strerror(errno));
01204          return res;
01205       } else if (res > 0) {
01206          fr = ast_read(c);
01207          if (!fr) {
01208 #if 0
01209             ast_log(LOG_DEBUG, "Got hung up\n");
01210 #endif
01211             return -1;
01212          }
01213          
01214          switch(fr->frametype) {
01215          case AST_FRAME_DTMF:
01216             res = fr->subclass;
01217             snprintf(exten, sizeof(exten), "%c", res);
01218             if (ast_exists_extension(c, context, exten, 1, c->cid.cid_num)) {
01219                ast_frfree(fr);
01220                return res;
01221             }
01222             break;
01223          case AST_FRAME_CONTROL:
01224             switch(fr->subclass) {
01225             case AST_CONTROL_HANGUP:
01226                ast_frfree(fr);
01227                return -1;
01228             case AST_CONTROL_RINGING:
01229             case AST_CONTROL_ANSWER:
01230                /* Unimportant */
01231                break;
01232             default:
01233                ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", fr->subclass);
01234             }
01235          }
01236          /* Ignore */
01237          ast_frfree(fr);
01238       }
01239       ast_sched_runq(c->sched);
01240    }
01241    return (c->_softhangup ? -1 : 0);
01242 }

int ast_waitstream_fr struct ast_channel c,
const char *  breakon,
const char *  forward,
const char *  rewind,
int  ms
 

Parameters:
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 1043 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().

01044 {
01045    int res;
01046    struct ast_frame *fr;
01047 
01048    if (!breakon)
01049          breakon = "";
01050    if (!forward)
01051          forward = "";
01052    if (!rewind)
01053          rewind = "";
01054    
01055    while(c->stream) {
01056       res = ast_sched_wait(c->sched);
01057       if ((res < 0) && !c->timingfunc) {
01058          ast_stopstream(c);
01059          break;
01060       }
01061       if (res < 0)
01062          res = 1000;
01063       res = ast_waitfor(c, res);
01064       if (res < 0) {
01065          ast_log(LOG_WARNING, "Select failed (%s)\n", strerror(errno));
01066          return res;
01067       } else
01068       if (res > 0) {
01069          fr = ast_read(c);
01070          if (!fr) {
01071 #if 0
01072             ast_log(LOG_DEBUG, "Got hung up\n");
01073 #endif
01074             return -1;
01075          }
01076          
01077          switch(fr->frametype) {
01078          case AST_FRAME_DTMF:
01079             res = fr->subclass;
01080             if (strchr(forward,res)) {
01081                ast_stream_fastforward(c->stream, ms);
01082             } else if (strchr(rewind,res)) {
01083                ast_stream_rewind(c->stream, ms);
01084             } else if (strchr(breakon, res)) {
01085                ast_frfree(fr);
01086                return res;
01087             }              
01088             break;
01089          case AST_FRAME_CONTROL:
01090             switch(fr->subclass) {
01091             case AST_CONTROL_HANGUP:
01092                ast_frfree(fr);
01093                return -1;
01094             case AST_CONTROL_RINGING:
01095             case AST_CONTROL_ANSWER:
01096                /* Unimportant */
01097                break;
01098             default:
01099                ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", fr->subclass);
01100             }
01101          }
01102          /* Ignore */
01103          ast_frfree(fr);
01104       } else
01105          ast_sched_runq(c->sched);
01106    
01107       
01108    }
01109    return (c->_softhangup ? -1 : 0);
01110 }

int ast_waitstream_full struct ast_channel c,
const char *  breakon,
int  audiofd,
int  cmdfd
 

Definition at line 1112 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().

01113 {
01114    int res;
01115    int ms;
01116    int outfd;
01117    struct ast_frame *fr;
01118    struct ast_channel *rchan;
01119 
01120    if (!breakon)
01121       breakon = "";
01122    
01123    while(c->stream) {
01124       ms = ast_sched_wait(c->sched);
01125       if ((ms < 0) && !c->timingfunc) {
01126          ast_stopstream(c);
01127          break;
01128       }
01129       if (ms < 0)
01130          ms = 1000;
01131       rchan = ast_waitfor_nandfds(&c, 1, &cmdfd, (cmdfd > -1) ? 1 : 0, NULL, &outfd, &ms);
01132       if (!rchan && (outfd < 0) && (ms)) {
01133          /* Continue */
01134          if (errno == EINTR)
01135             continue;
01136          ast_log(LOG_WARNING, "Wait failed (%s)\n", strerror(errno));
01137          return -1;
01138       } else if (outfd > -1) {
01139          /* The FD we were watching has something waiting */
01140          return 1;
01141       } else if (rchan) {
01142          fr = ast_read(c);
01143          if (!fr) {
01144 #if 0
01145             ast_log(LOG_DEBUG, "Got hung up\n");
01146 #endif
01147             return -1;
01148          }
01149          
01150          switch(fr->frametype) {
01151          case AST_FRAME_DTMF:
01152             res = fr->subclass;
01153             if (strchr(breakon, res)) {
01154                ast_frfree(fr);
01155                return res;
01156             }
01157             break;
01158          case AST_FRAME_CONTROL:
01159             switch(fr->subclass) {
01160             case AST_CONTROL_HANGUP:
01161                ast_frfree(fr);
01162                return -1;
01163             case AST_CONTROL_RINGING:
01164             case AST_CONTROL_ANSWER:
01165                /* Unimportant */
01166                break;
01167             default:
01168                ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", fr->subclass);
01169             }
01170          case AST_FRAME_VOICE:
01171             /* Write audio if appropriate */
01172             if (audiofd > -1)
01173                write(audiofd, fr->data, fr->datalen);
01174          }
01175          /* Ignore */
01176          ast_frfree(fr);
01177       }
01178       ast_sched_runq(c->sched);
01179    }
01180    return (c->_softhangup ? -1 : 0);
01181 }

struct ast_filestream* ast_writefile const char *  filename,
const char *  type,
const char *  comment,
int  flags,
int  check,
mode_t  mode
 

Parameters:
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 871 of file file.c.

References ast_log(), ast_mutex_lock(), 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(), ast_writestream(), handle_recordfile(), mixmonitor_thread(), record_exec(), and recordthread().

00872 {
00873    int fd, myflags = 0;
00874    /* compiler claims this variable can be used before initialization... */
00875    FILE *bfile = NULL;
00876    struct ast_format *f;
00877    struct ast_filestream *fs = NULL;
00878    char *fn, *orig_fn = NULL;
00879    char *buf = NULL;
00880    size_t size = 0;
00881 
00882    if (ast_mutex_lock(&formatlock)) {
00883       ast_log(LOG_WARNING, "Unable to lock format list\n");
00884       return NULL;
00885    }
00886 
00887    /* set the O_TRUNC flag if and only if there is no O_APPEND specified */
00888    if (flags & O_APPEND) { 
00889       /* We really can't use O_APPEND as it will break WAV header updates */
00890       flags &= ~O_APPEND;
00891    } else {
00892       myflags = O_TRUNC;
00893    }
00894    
00895    myflags |= O_WRONLY | O_CREAT;
00896 
00897    for (f = formats; f && !fs; f = f->next) {
00898       if (!exts_compare(f->exts, type))
00899          continue;
00900 
00901       fn = build_filename(filename, type);
00902       fd = open(fn, flags | myflags, mode);
00903       if (fd > -1) {
00904          /* fdopen() the resulting file stream */
00905          bfile = fdopen(fd, ((flags | myflags) & O_RDWR) ? "w+" : "w");
00906          if (!bfile) {
00907             ast_log(LOG_WARNING, "Whoa, fdopen failed: %s!\n", strerror(errno));
00908             close(fd);
00909             fd = -1;
00910          }
00911       }
00912       
00913       if (option_cache_record_files && (fd > -1)) {
00914          char *c;
00915 
00916          fclose(bfile);
00917          /*
00918            We touch orig_fn just as a place-holder so other things (like vmail) see the file is there.
00919            What we are really doing is writing to record_cache_dir until we are done then we will mv the file into place.
00920          */
00921          orig_fn = ast_strdupa(fn);
00922          for (c = fn; *c; c++)
00923             if (*c == '/')
00924                *c = '_';
00925 
00926          size = strlen(fn) + strlen(record_cache_dir) + 2;
00927          buf = alloca(size);
00928          strcpy(buf, record_cache_dir);
00929          strcat(buf, "/");
00930          strcat(buf, fn);
00931          free(fn);
00932          fn = buf;
00933          fd = open(fn, flags | myflags, mode);
00934          if (fd > -1) {
00935             /* fdopen() the resulting file stream */
00936             bfile = fdopen(fd, ((flags | myflags) & O_RDWR) ? "w+" : "w");
00937             if (!bfile) {
00938                ast_log(LOG_WARNING, "Whoa, fdopen failed: %s!\n", strerror(errno));
00939                close(fd);
00940                fd = -1;
00941             }
00942          }
00943       }
00944       if (fd > -1) {
00945          errno = 0;
00946          if ((fs = f->rewrite(bfile, comment))) {
00947             fs->trans = NULL;
00948             fs->fmt = f;
00949             fs->flags = flags;
00950             fs->mode = mode;
00951             if (orig_fn) {
00952                fs->realfilename = strdup(orig_fn);
00953                fs->filename = strdup(fn);
00954             } else {
00955                fs->realfilename = NULL;
00956                fs->filename = strdup(filename);
00957             }
00958             fs->vfs = NULL;
00959             /* If truncated, we'll be at the beginning; if not truncated, then append */
00960             f->seek(fs, 0, SEEK_END);
00961          } else {
00962             ast_log(LOG_WARNING, "Unable to rewrite %s\n", fn);
00963             close(fd);
00964             if (orig_fn) {
00965                unlink(fn);
00966                unlink(orig_fn);
00967             }
00968          }
00969       } else if (errno != EEXIST) {
00970          ast_log(LOG_WARNING, "Unable to open file %s: %s\n", fn, strerror(errno));
00971          if (orig_fn)
00972             unlink(orig_fn);
00973       }
00974       /* if buf != NULL then fn is already free and pointing to it */
00975       if (!buf)
00976          free(fn);
00977    }
00978 
00979    ast_mutex_unlock(&formatlock);
00980    if (!fs)
00981       ast_log(LOG_WARNING, "No such format '%s'\n", type);
00982 
00983    return fs;
00984 }

int ast_writestream struct ast_filestream fs,
struct ast_frame f
 

Parameters:
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 197 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_read(), ast_write(), ast_writestream(), handle_recordfile(), mixmonitor_thread(), record_exec(), and recordthread().

00198 {
00199    struct ast_frame *trf;
00200    int res = -1;
00201    int alt=0;
00202    if (f->frametype == AST_FRAME_VIDEO) {
00203       if (fs->fmt->format < AST_FORMAT_MAX_AUDIO) {
00204          /* This is the audio portion.  Call the video one... */
00205          if (!fs->vfs && fs->filename) {
00206             /* XXX Support other video formats XXX */
00207             const char *type = "h263";
00208             fs->vfs = ast_writefile(fs->filename, type, NULL, fs->flags, 0, fs->mode);
00209             ast_log(LOG_DEBUG, "Opened video output file\n");
00210          }
00211          if (fs->vfs)
00212             return ast_writestream(fs->vfs, f);
00213          /* Ignore */
00214          return 0;            
00215       } else {
00216          /* Might / might not have mark set */
00217          alt = 1;
00218       }
00219    } else if (f->frametype != AST_FRAME_VOICE) {
00220       ast_log(LOG_WARNING, "Tried to write non-voice frame\n");
00221       return -1;
00222    }
00223    if (((fs->fmt->format | alt) & f->subclass) == f->subclass) {
00224       res =  fs->fmt->write(fs, f);
00225       if (res < 0) 
00226          ast_log(LOG_WARNING, "Natural write failed\n");
00227       if (res > 0)
00228          ast_log(LOG_WARNING, "Huh??\n");
00229       return res;
00230    } else {
00231       /* XXX If they try to send us a type of frame that isn't the normal frame, and isn't
00232              the one we've setup a translator for, we do the "wrong thing" XXX */
00233       if (fs->trans && (f->subclass != fs->lastwriteformat)) {
00234          ast_translator_free_path(fs->trans);
00235          fs->trans = NULL;
00236       }
00237       if (!fs->trans) 
00238          fs->trans = ast_translator_build_path(fs->fmt->format, f->subclass);
00239       if (!fs->trans)
00240          ast_log(LOG_WARNING, "Unable to translate to format %s, source format %s\n", fs->fmt->name, ast_getformatname(f->subclass));
00241       else {
00242          fs->lastwriteformat = f->subclass;
00243          res = 0;
00244          /* Get the translated frame but don't consume the original in case they're using it on another stream */
00245          trf = ast_translate(fs->trans, f, 0);
00246          if (trf) {
00247             res = fs->fmt->write(fs, trf);
00248             if (res) 
00249                ast_log(LOG_WARNING, "Translated frame write failed\n");
00250          } else
00251             res = 0;
00252       }
00253       return res;
00254    }
00255 }

static char* build_filename const char *  filename,
const char *  ext
[static]
 

Definition at line 297 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().

00298 {
00299    char *fn, type[16];
00300    int fnsize = 0;
00301 
00302    if (!strcmp(ext, "wav49")) {
00303       ast_copy_string(type, "WAV", sizeof(type));
00304    } else {
00305       ast_copy_string(type, ext, sizeof(type));
00306    }
00307 
00308    if (filename[0] == '/') {
00309       fnsize = strlen(filename) + strlen(type) + 2;
00310       fn = malloc(fnsize);
00311       if (fn)
00312          snprintf(fn, fnsize, "%s.%s", filename, type);
00313    } else {
00314       char tmp[AST_CONFIG_MAX_PATH] = "";
00315 
00316       snprintf(tmp, sizeof(tmp), "%s/%s", ast_config_AST_DATA_DIR, "sounds");
00317       fnsize = strlen(tmp) + strlen(filename) + strlen(type) + 3;
00318       fn = malloc(fnsize);
00319       if (fn)
00320          snprintf(fn, fnsize, "%s/%s.%s", tmp, filename, type);
00321    }
00322 
00323    return fn;
00324 }

static int copy const char *  infile,
const char *  outfile
[static]
 

Definition at line 257 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().

00258 {
00259    int ifd;
00260    int ofd;
00261    int res;
00262    int len;
00263    char buf[4096];
00264 
00265    if ((ifd = open(infile, O_RDONLY)) < 0) {
00266       ast_log(LOG_WARNING, "Unable to open %s in read-only mode\n", infile);
00267       return -1;
00268    }
00269    if ((ofd = open(outfile, O_WRONLY | O_TRUNC | O_CREAT, 0600)) < 0) {
00270       ast_log(LOG_WARNING, "Unable to open %s in write-only mode\n", outfile);
00271       close(ifd);
00272       return -1;
00273    }
00274    do {
00275       len = read(ifd, buf, sizeof(buf));
00276       if (len < 0) {
00277          ast_log(LOG_WARNING, "Read failed on %s: %s\n", infile, strerror(errno));
00278          close(ifd);
00279          close(ofd);
00280          unlink(outfile);
00281       }
00282       if (len) {
00283          res = write(ofd, buf, len);
00284          if (res != len) {
00285             ast_log(LOG_WARNING, "Write failed on %s (%d of %d): %s\n", outfile, res, len, strerror(errno));
00286             close(ifd);
00287             close(ofd);
00288             unlink(outfile);
00289          }
00290       }
00291    } while(len);
00292    close(ifd);
00293    close(ofd);
00294    return 0;
00295 }

static int exts_compare const char *  exts,
const char *  type
[static]
 

Definition at line 326 of file file.c.

References strsep().

Referenced by ast_filehelper(), ast_readfile(), and ast_writefile().

00327 {
00328    char *stringp = NULL, *ext;
00329    char tmp[256];
00330 
00331    ast_copy_string(tmp, exts, sizeof(tmp));
00332    stringp = tmp;
00333    while ((ext = strsep(&stringp, "|"))) {
00334       if (!strcmp(ext, type)) {
00335          return 1;
00336       }
00337    }
00338 
00339    return 0;
00340 }

static int show_file_formats int  fd,
int  argc,
char *  argv[]
[static]
 

Definition at line 1244 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.

01245 {
01246 #define FORMAT "%-10s %-10s %-20s\n"
01247 #define FORMAT2 "%-10s %-10s %-20s\n"
01248    struct ast_format *f;
01249    int count_fmt = 0;
01250 
01251    if (argc != 3)
01252       return RESULT_SHOWUSAGE;
01253    ast_cli(fd, FORMAT, "Format", "Name", "Extensions");
01254            
01255    if (ast_mutex_lock(&formatlock)) {
01256       ast_log(LOG_WARNING, "Unable to lock format list\n");
01257       return -1;
01258    }
01259 
01260    f = formats;
01261    while(f) {
01262       ast_cli(fd, FORMAT2, ast_getformatname(f->format), f->name, f->exts);
01263       f = f->next;
01264       count_fmt++;
01265    };
01266    ast_mutex_unlock(&formatlock);
01267    ast_cli(fd, "%d file formats registered.\n", count_fmt);
01268    return RESULT_SUCCESS;
01269 #undef FORMAT
01270 #undef FORMAT2
01271    
01272 }


Variable Documentation

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
 

Definition at line 1274 of file file.c.

Referenced by ast_file_init().


Generated on Fri May 26 01:48:35 2006 for Asterisk - the Open Source PBX by  doxygen 1.4.6