Codename Pineapple

Home page | Mailing list | Docs

Last updated: Sat Feb 3 05:01:31 2007

Asterisk developer's documentation :: Codename Pineapple


file.c File Reference


Detailed Description

Generic File Format Support.

Author:
Mark Spencer <markster@digium.com>

Definition in file file.c.

#include "asterisk.h"
#include <sys/types.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <fcntl.h>
#include <dirent.h>
#include <sys/stat.h>
#include "asterisk/frame.h"
#include "asterisk/file.h"
#include "asterisk/cli.h"
#include "asterisk/logger.h"
#include "asterisk/channel.h"
#include "asterisk/sched.h"
#include "asterisk/options.h"
#include "asterisk/translate.h"
#include "asterisk/utils.h"
#include "asterisk/lock.h"
#include "asterisk/app.h"
#include "asterisk/pbx.h"
#include "asterisk/linkedlists.h"
#include "asterisk/module.h"

Include dependency graph for file.c:

Go to the source code of this file.

Defines

#define FORMAT   "%-10s %-10s %-20s\n"
#define FORMAT2   "%-10s %-10s %-20s\n"

Enumerations

enum  file_action {
  ACTION_EXISTS = 1, ACTION_DELETE, ACTION_RENAME, ACTION_OPEN,
  ACTION_COPY
}
enum  wrap_fn { WRAP_OPEN, WRAP_REWRITE }

Functions

int __ast_format_register (const struct ast_format *f, struct ast_module *mod)
int ast_applystream (struct ast_channel *chan, struct ast_filestream *s)
int ast_closestream (struct ast_filestream *f)
int ast_file_init (void)
int ast_filecopy (const char *filename, const char *filename2, const char *fmt)
int ast_filedelete (const char *filename, const char *fmt)
int ast_fileexists (const char *filename, const char *fmt, const char *preflang)
static int ast_filehelper (const char *filename, const void *arg2, const char *fmt, const enum file_action action)
 perform various actions on a file. Second argument arg2 depends on the command: unused for EXISTS and DELETE destination file name (const char *) for COPY and RENAME struct ast_channel * for OPEN if fmt is NULL, OPEN will return the first matching entry, whereas other functions will run on all matching entries.
int ast_filerename (const char *filename, const char *filename2, const char *fmt)
int ast_format_unregister (const char *name)
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)
static AST_RWLIST_HEAD_STATIC (formats, ast_format)
int ast_seekstream (struct ast_filestream *fs, off_t sample_offset, int whence)
int ast_stopstream (struct ast_channel *tmp)
int ast_stream_and_wait (struct ast_channel *chan, const char *file, const char *digits)
int ast_stream_fastforward (struct ast_filestream *fs, off_t ms)
int ast_stream_rewind (struct ast_filestream *fs, off_t ms)
int ast_streamfile (struct ast_channel *chan, const char *filename, const char *preflang)
off_t ast_tellstream (struct ast_filestream *fs)
int ast_truncstream (struct ast_filestream *fs)
int ast_waitstream (struct ast_channel *c, const char *breakon)
int ast_waitstream_exten (struct ast_channel *c, const char *context)
int ast_waitstream_fr (struct ast_channel *c, const char *breakon, const char *forward, const char *rewind, int ms)
int ast_waitstream_full (struct ast_channel *c, const char *breakon, int audiofd, int cmdfd)
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)
 construct a filename. Absolute pathnames are preserved, relative names are prefixed by the sounds/ directory. The wav49 suffix is replaced by 'WAV'. Returns a malloc'ed string to be freed by the caller.
static int copy (const char *infile, const char *outfile)
static int exts_compare (const char *exts, const char *type)
static int fileexists_core (const char *filename, const char *fmt, const char *preflang, char *buf, int buflen)
 helper routine to locate a file with a given format and language preference. Try preflang, preflang with stripped '_' suffix, or NULL. In the standard asterisk, language goes just before the last component. In an alternative configuration, the language should be a prefix to the actual filename.
static int fn_wrapper (struct ast_filestream *s, const char *comment, enum wrap_fn mode)
static struct ast_filestreamget_filestream (struct ast_format *fmt, FILE *bfile)
static int open_wrapper (struct ast_filestream *s)
static int rewrite_wrapper (struct ast_filestream *s, const char *comment)
static int show_file_formats (int fd, int argc, char *argv[])
static int waitstream_core (struct ast_channel *c, const char *breakon, const char *forward, const char *rewind, int skip_ms, int audiofd, int cmdfd, const char *context)
 the core of all waitstream() functions

Variables

int ast_language_is_prefix = 1
ast_cli_entry cli_file []
static const char show_file_formats_usage []


Define Documentation

#define FORMAT   "%-10s %-10s %-20s\n"
 

#define FORMAT2   "%-10s %-10s %-20s\n"
 

Referenced by __iax2_show_peers(), __sip_show_channels(), _sip_show_devices(), _sip_show_peers(), dundi_show_mappings(), dundi_show_peers(), dundi_show_precache(), dundi_show_requests(), dundi_show_trans(), iax2_show_channels(), iax2_show_registry(), iax2_show_users(), show_file_formats(), show_image_formats(), sip_show_inuse(), sip_show_registry(), and zap_show_status().


Enumeration Type Documentation

enum file_action
 

Enumerator:
ACTION_EXISTS 
ACTION_DELETE 
ACTION_RENAME 
ACTION_OPEN 
ACTION_COPY 

Definition at line 327 of file file.c.

00327                  {
00328    ACTION_EXISTS = 1, /* return matching format if file exists, 0 otherwise */
00329    ACTION_DELETE, /* delete file, return 0 on success, -1 on error */
00330    ACTION_RENAME, /* rename file. return 0 on success, -1 on error */
00331    ACTION_OPEN,
00332    ACTION_COPY /* copy file. return 0 on success, -1 on error */
00333 };

enum wrap_fn
 

Enumerator:
WRAP_OPEN 
WRAP_REWRITE 

Definition at line 298 of file file.c.

00298 { WRAP_OPEN, WRAP_REWRITE };


Function Documentation

int __ast_format_register const struct ast_format f,
struct ast_module mod
 

Register a new file format capability Adds a format to Asterisk's format abilities. returns 0 on success, -1 on failure

Definition at line 68 of file file.c.

References ast_calloc, ast_log(), AST_RWLIST_INSERT_HEAD, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_verbose(), ast_format::buf_size, ast_format::exts, LOG_WARNING, ast_format::module, ast_format::name, option_verbose, and VERBOSE_PREFIX_2.

00069 {
00070    struct ast_format *tmp;
00071 
00072    AST_RWLIST_WRLOCK(&formats);
00073    AST_RWLIST_TRAVERSE(&formats, tmp, list) {
00074       if (!strcasecmp(f->name, tmp->name)) {
00075          AST_RWLIST_UNLOCK(&formats);
00076          ast_log(LOG_WARNING, "Tried to register '%s' format, already registered\n", f->name);
00077          return -1;
00078       }
00079    }
00080    if (!(tmp = ast_calloc(1, sizeof(*tmp)))) {
00081       AST_RWLIST_UNLOCK(&formats);
00082       return -1;
00083    }
00084    *tmp = *f;
00085    tmp->module = mod;
00086    if (tmp->buf_size) {
00087       /*
00088        * Align buf_size properly, rounding up to the machine-specific
00089        * alignment for pointers.
00090        */
00091       struct _test_align { void *a, *b; } p;
00092       int align = (char *)&p.b - (char *)&p.a;
00093       tmp->buf_size = ((f->buf_size + align - 1)/align)*align;
00094    }
00095    
00096    memset(&tmp->list, 0, sizeof(tmp->list));
00097 
00098    AST_RWLIST_INSERT_HEAD(&formats, tmp, list);
00099    AST_RWLIST_UNLOCK(&formats);
00100    if (option_verbose > 1)
00101       ast_verbose( VERBOSE_PREFIX_2 "Registered file format %s, extension(s) %s\n", f->name, f->exts);
00102 
00103    return 0;
00104 }

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

References s.

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

00652 {
00653    s->owner = chan;
00654    return 0;
00655 }

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

References ast_closestream(), AST_FORMAT_MAX_AUDIO, ast_module_unref(), ast_safe_system(), ast_sched_del(), ast_settimeout(), ast_translator_free_path(), ast_format::close, ast_filestream::f, ast_filestream::filename, ast_filestream::fmt, ast_format::format, free, ast_format::module, ast_filestream::owner, ast_filestream::realfilename, ast_channel::sched, ast_channel::stream, ast_channel::streamid, ast_filestream::trans, ast_filestream::vfs, ast_channel::vstream, and ast_channel::vstreamid.

Referenced by ast_closestream(), ast_hangup(), ast_moh_files_next(), ast_monitor_start(), ast_monitor_stop(), ast_stopstream(), cli_audio_convert(), handle_recordfile(), local_ast_moh_stop(), and moh_files_release().

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

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

References ast_cli_register_multiple(), and cli_file.

01150 {
01151    ast_cli_register_multiple(cli_file, sizeof(cli_file) / sizeof(struct ast_cli_entry));
01152    return 0;
01153 }

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

References ACTION_COPY, and ast_filehelper().

00767 {
00768    return ast_filehelper(filename, filename2, fmt, ACTION_COPY);
00769 }

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

References ACTION_DELETE, and ast_filehelper().

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

00757 {
00758    return ast_filehelper(filename, NULL, fmt, ACTION_DELETE);
00759 }

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

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

00743 {
00744    char *buf;
00745    int buflen;
00746 
00747    if (preflang == NULL)
00748       preflang = "";
00749    buflen = strlen(preflang) + strlen(filename) + 2;  /* room for everything */
00750    buf = alloca(buflen);
00751    if (buf == NULL)
00752       return 0;
00753    return fileexists_core(filename, fmt, preflang, buf, buflen);
00754 }

static int ast_filehelper const char *  filename,
const void *  arg2,
const char *  fmt,
const enum file_action  action
[static]
 

perform various actions on a file. Second argument arg2 depends on the command: unused for EXISTS and DELETE destination file name (const char *) for COPY and RENAME struct ast_channel * for OPEN if fmt is NULL, OPEN will return the first matching entry, whereas other functions will run on all matching entries.

Definition at line 344 of file file.c.

References ACTION_DELETE, ACTION_EXISTS, ACTION_OPEN, ACTION_RENAME, AST_FORMAT_MAX_AUDIO, ast_log(), AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_strdupa, build_filename(), copy(), ext, ast_format::exts, exts_compare(), ast_filestream::f, free, get_filestream(), LOG_WARNING, open_wrapper(), s, ast_channel::stream, strsep(), ast_channel::vstream, and ast_channel::writeformat.

Referenced by ast_filecopy(), ast_filedelete(), ast_filerename(), ast_openstream_full(), and ast_openvstream().

00345 {
00346    struct ast_format *f;
00347    int res = (action == ACTION_EXISTS) ? 0 : -1;
00348 
00349    AST_RWLIST_RDLOCK(&formats);
00350    /* Check for a specific format */
00351    AST_RWLIST_TRAVERSE(&formats, f, list) {
00352       char *stringp, *ext = NULL;
00353 
00354       if (fmt && !exts_compare(f->exts, fmt))
00355          continue;
00356 
00357       /* Look for a file matching the supported extensions.
00358        * The file must exist, and for OPEN, must match
00359        * one of the formats supported by the channel.
00360        */
00361       stringp = ast_strdupa(f->exts);  /* this is in the stack so does not need to be freed */
00362       while ( (ext = strsep(&stringp, "|")) ) {
00363          struct stat st;
00364          char *fn = build_filename(filename, ext);
00365 
00366          if (fn == NULL)
00367             continue;
00368 
00369          if ( stat(fn, &st) ) { /* file not existent */
00370             free(fn);
00371             continue;
00372          }
00373          /* for 'OPEN' we need to be sure that the format matches
00374           * what the channel can process
00375           */
00376          if (action == ACTION_OPEN) {
00377             struct ast_channel *chan = (struct ast_channel *)arg2;
00378             FILE *bfile;
00379             struct ast_filestream *s;
00380 
00381             if ( !(chan->writeformat & f->format) &&
00382                  !(f->format >= AST_FORMAT_MAX_AUDIO && fmt)) {
00383                free(fn);
00384                continue;   /* not a supported format */
00385             }
00386             if ( (bfile = fopen(fn, "r")) == NULL) {
00387                free(fn);
00388                continue;   /* cannot open file */
00389             }
00390             s = get_filestream(f, bfile);
00391             if (!s) {
00392                fclose(bfile);
00393                free(fn);   /* cannot allocate descriptor */
00394                continue;
00395             }
00396             if (open_wrapper(s)) {
00397                fclose(bfile);
00398                free(fn);
00399                free(s);
00400                continue;   /* cannot run open on file */
00401             }
00402             /* ok this is good for OPEN */
00403             res = 1; /* found */
00404             s->lasttimeout = -1;
00405             s->fmt = f;
00406             s->trans = NULL;
00407             s->filename = NULL;
00408             if (s->fmt->format < AST_FORMAT_MAX_AUDIO)
00409                chan->stream = s;
00410             else
00411                chan->vstream = s;
00412             free(fn);
00413             break;
00414          }
00415          switch (action) {
00416          case ACTION_OPEN:
00417             break;   /* will never get here */
00418 
00419          case ACTION_EXISTS:  /* return the matching format */
00420             res |= f->format;
00421             break;
00422 
00423          case ACTION_DELETE:
00424             if ( (res = unlink(fn)) )
00425                ast_log(LOG_WARNING, "unlink(%s) failed: %s\n", fn, strerror(errno));
00426             break;
00427 
00428          case ACTION_RENAME:
00429          case ACTION_COPY: {
00430             char *nfn = build_filename((const char *)arg2, ext);
00431             if (!nfn)
00432                ast_log(LOG_WARNING, "Out of memory\n");
00433             else {
00434                res = action == ACTION_COPY ? copy(fn, nfn) : rename(fn, nfn);
00435                if (res)
00436                   ast_log(LOG_WARNING, "%s(%s,%s) failed: %s\n",
00437                      action == ACTION_COPY ? "copy" : "rename",
00438                       fn, nfn, strerror(errno));
00439                free(nfn);
00440             }
00441              }
00442             break;
00443 
00444          default:
00445             ast_log(LOG_WARNING, "Unknown helper %d\n", action);
00446          }
00447          free(fn);
00448       }
00449    }
00450    AST_RWLIST_UNLOCK(&formats);
00451    return res;
00452 }

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

References ACTION_RENAME, and ast_filehelper().

Referenced by ast_monitor_stop().

00762 {
00763    return ast_filehelper(filename, filename2, fmt, ACTION_RENAME);
00764 }

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

References ast_log(), AST_RWLIST_REMOVE_CURRENT, AST_RWLIST_TRAVERSE_SAFE_BEGIN, AST_RWLIST_TRAVERSE_SAFE_END, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_verbose(), free, LOG_WARNING, ast_format::name, option_verbose, and VERBOSE_PREFIX_2.

00107 {
00108    struct ast_format *tmp;
00109    int res = -1;
00110 
00111    AST_RWLIST_WRLOCK(&formats);
00112    AST_RWLIST_TRAVERSE_SAFE_BEGIN(&formats, tmp, list) {
00113       if (!strcasecmp(name, tmp->name)) {
00114          AST_RWLIST_REMOVE_CURRENT(&formats, list);
00115          free(tmp);
00116          res = 0;
00117       }
00118    }
00119    AST_RWLIST_TRAVERSE_SAFE_END
00120    AST_RWLIST_UNLOCK(&formats);
00121 
00122    if (!res) {
00123       if (option_verbose > 1)
00124          ast_verbose( VERBOSE_PREFIX_2 "Unregistered format %s\n", name);
00125    } else
00126       ast_log(LOG_WARNING, "Tried to unregister format %s, already unregistered\n", name);
00127 
00128    return res;
00129 }

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

References ast_openstream_full().

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

00515 {
00516    return ast_openstream_full(chan, filename, preflang, 0);
00517 }

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

References ACTION_OPEN, ast_deactivate_generator(), ast_filehelper(), AST_FORMAT_AUDIO_MASK, ast_log(), ast_set_write_format(), ast_stopstream(), ast_filestream::buf, fileexists_core(), LOG_WARNING, ast_channel::oldwriteformat, ast_channel::stream, and ast_channel::writeformat.

Referenced by ast_openstream().

00520 {
00521    /* 
00522     * Use fileexists_core() to find a file in a compatible
00523     * language and format, set up a suitable translator,
00524     * and open the stream.
00525     */
00526    int fmts, res, buflen;
00527    char *buf;
00528 
00529    if (!asis) {
00530       /* do this first, otherwise we detect the wrong writeformat */
00531       ast_stopstream(chan);
00532       if (chan->generator)
00533          ast_deactivate_generator(chan);
00534    }
00535    if (preflang == NULL)
00536       preflang = "";
00537    buflen = strlen(preflang) + strlen(filename) + 2;
00538    buf = alloca(buflen);
00539    if (buf == NULL)
00540       return NULL;
00541    fmts = fileexists_core(filename, NULL, preflang, buf, buflen);
00542    if (fmts > 0)
00543       fmts &= AST_FORMAT_AUDIO_MASK;
00544    if (fmts < 1) {
00545       ast_log(LOG_WARNING, "File %s does not exist in any format\n", filename);
00546       return NULL;
00547    }
00548    chan->oldwriteformat = chan->writeformat;
00549    /* Set the channel to a format we can work with */
00550    res = ast_set_write_format(chan, fmts);
00551    res = ast_filehelper(buf, chan, NULL, ACTION_OPEN);
00552    if (res >= 0)
00553       return chan->stream;
00554    return NULL;
00555 }

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

References ACTION_OPEN, ast_filehelper(), AST_FORMAT_MAX_AUDIO, AST_FORMAT_MAX_VIDEO, ast_getformatname(), ast_log(), ast_filestream::buf, fileexists_core(), fmt, format, LOG_WARNING, ast_channel::nativeformats, and ast_channel::vstream.

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

00558 {
00559    /* As above, but for video. But here we don't have translators
00560     * so we must enforce a format.
00561     */
00562    unsigned int format;
00563    char *buf;
00564    int buflen;
00565 
00566    if (preflang == NULL)
00567       preflang = "";
00568    buflen = strlen(preflang) + strlen(filename) + 2;
00569    buf = alloca(buflen);
00570    if (buf == NULL)
00571       return NULL;
00572 
00573    for (format = AST_FORMAT_MAX_AUDIO << 1; format <= AST_FORMAT_MAX_VIDEO; format = format << 1) {
00574       int fd;
00575       const char *fmt;
00576 
00577       if (!(chan->nativeformats & format))
00578          continue;
00579       fmt = ast_getformatname(format);
00580       if ( fileexists_core(filename, fmt, preflang, buf, buflen) < 1)   /* no valid format */
00581          continue;
00582       fd = ast_filehelper(buf, chan, fmt, ACTION_OPEN);
00583       if (fd >= 0)
00584          return chan->vstream;
00585       ast_log(LOG_WARNING, "File %s has video but couldn't be opened\n", filename);
00586    }
00587    return NULL;
00588 }

int ast_playstream struct ast_filestream s  ) 
 

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

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

00658 {
00659    if (s->fmt->format < AST_FORMAT_MAX_AUDIO)
00660       ast_readaudio_callback(s);
00661    else
00662       ast_readvideo_callback(s);
00663    return 0;
00664 }

static int ast_readaudio_callback void *  data  )  [static]
 

Definition at line 599 of file file.c.

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

Referenced by ast_playstream().

00600 {
00601    struct ast_filestream *s = data;
00602    int whennext = 0;
00603 
00604    while (!whennext) {
00605       struct ast_frame *fr = s->fmt->read(s, &whennext);
00606       if (!fr /* stream complete */ || ast_write(s->owner, fr) /* error writing */) {
00607          if (fr)
00608             ast_log(LOG_WARNING, "Failed to write frame\n");
00609          s->owner->streamid = -1;
00610 #ifdef HAVE_ZAPTEL
00611          ast_settimeout(s->owner, 0, NULL, NULL);
00612 #endif         
00613          return 0;
00614       }
00615    }
00616    if (whennext != s->lasttimeout) {
00617 #ifdef HAVE_ZAPTEL
00618       if (s->owner->timingfd > -1)
00619          ast_settimeout(s->owner, whennext, ast_readaudio_callback, s);
00620       else
00621 #endif      
00622          s->owner->streamid = ast_sched_add(s->owner->sched, whennext/8, ast_readaudio_callback, s);
00623       s->lasttimeout = whennext;
00624       return 0;
00625    }
00626    return 1;
00627 }

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

References ast_log(), AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, build_filename(), exts_compare(), ast_filestream::f, ast_filestream::filename, ast_filestream::flags, ast_filestream::fmt, free, get_filestream(), LOG_WARNING, ast_filestream::mode, open_wrapper(), strdup, ast_filestream::trans, and ast_filestream::vfs.

Referenced by cli_audio_convert().

00803 {
00804    FILE *bfile;
00805    struct ast_format *f;
00806    struct ast_filestream *fs = NULL;
00807    char *fn;
00808 
00809    AST_RWLIST_RDLOCK(&formats);
00810 
00811    AST_RWLIST_TRAVERSE(&formats, f, list) {
00812       fs = NULL;
00813       if (!exts_compare(f->exts, type))
00814          continue;
00815 
00816       fn = build_filename(filename, type);
00817       errno = 0;
00818       bfile = fopen(fn, "r");
00819       if (!bfile || (fs = get_filestream(f, bfile)) == NULL ||
00820           open_wrapper(fs) ) {
00821          ast_log(LOG_WARNING, "Unable to open %s\n", fn);
00822          if (fs)
00823             free(fs);
00824          if (bfile)
00825             fclose(bfile);
00826          free(fn);
00827          continue;
00828       }
00829       /* found it */
00830       fs->trans = NULL;
00831       fs->fmt = f;
00832       fs->flags = flags;
00833       fs->mode = mode;
00834       fs->filename = strdup(filename);
00835       fs->vfs = NULL;
00836       break;
00837    }
00838 
00839    AST_RWLIST_UNLOCK(&formats);
00840    if (!fs) 
00841       ast_log(LOG_WARNING, "No such format '%s'\n", type);
00842 
00843    return fs;
00844 }

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

References s.

Referenced by cli_audio_convert(), and moh_files_readframe().

00591 {
00592    struct ast_frame *f = NULL;
00593    int whennext = 0; 
00594    if (s && s->fmt)
00595       f = s->fmt->read(s, &whennext);
00596    return f;
00597 }

static int ast_readvideo_callback void *  data  )  [static]
 

Definition at line 629 of file file.c.

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

Referenced by ast_playstream().

00630 {
00631    struct ast_filestream *s = data;
00632    int whennext = 0;
00633 
00634    while (!whennext) {
00635       struct ast_frame *fr = s->fmt->read(s, &whennext);
00636       if (!fr || ast_write(s->owner, fr)) { /* no stream or error, as above */
00637          if (fr)
00638             ast_log(LOG_WARNING, "Failed to write frame\n");
00639          s->owner->vstreamid = -1;
00640          return 0;
00641       }
00642    }
00643    if (whennext != s->lasttimeout) {
00644       s->owner->vstreamid = ast_sched_add(s->owner->sched, whennext/8, ast_readvideo_callback, s);
00645       s->lasttimeout = whennext;
00646       return 0;
00647    }
00648    return 1;
00649 }

static AST_RWLIST_HEAD_STATIC formats  ,
ast_format 
[static]
 

int ast_seekstream struct ast_filestream fs,
off_t  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 666 of file file.c.

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

Referenced by __ast_read(), ast_control_streamfile(), ast_stream_fastforward(), ast_stream_rewind(), ast_write(), handle_getoption(), handle_recordfile(), and handle_streamfile().

00667 {
00668    return fs->fmt->seek(fs, sample_offset, whence);
00669 }

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

References ast_closestream(), ast_log(), ast_set_write_format(), LOG_WARNING, ast_channel::oldwriteformat, and ast_channel::stream.

Referenced by ast_adsi_transmit_message_full(), ast_control_streamfile(), ast_openstream_full(), ast_play_and_wait(), ast_readstring_full(), ast_say_enumeration_full_da(), ast_say_enumeration_full_de(), ast_say_enumeration_full_en(), ast_say_number_full_cz(), ast_say_number_full_da(), ast_say_number_full_de(), ast_say_number_full_en(), ast_say_number_full_en_GB(), ast_say_number_full_es(), ast_say_number_full_fr(), ast_say_number_full_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(), builtin_blindtransfer(), handle_getoption(), handle_streamfile(), ivr_dispatch(), pbx_builtin_background(), pl_odtworz_plik(), say_character_str_full(), say_digit_str_full(), say_phonetic_str_full(), and waitstream_core().

00132 {
00133    /* Stop a running stream if there is one */
00134    if (tmp->stream) {
00135       ast_closestream(tmp->stream);
00136       tmp->stream = NULL;
00137       if (tmp->oldwriteformat && ast_set_write_format(tmp, tmp->oldwriteformat))
00138          ast_log(LOG_WARNING, "Unable to restore format back to %d\n", tmp->oldwriteformat);
00139    }
00140    return 0;
00141 }

int ast_stream_and_wait struct ast_channel chan,
const char *  file,
const char *  digits
 

Definition at line 1105 of file file.c.

References ast_streamfile(), ast_strlen_zero(), and ast_waitstream().

Referenced by __ast_play_and_record(), ast_record_review(), bridge_playfile(), builtin_atxfer(), builtin_automonitor(), builtin_blindtransfer(), ivr_dispatch(), and park_exec().

01106 {
01107         int res = 0;
01108         if (!ast_strlen_zero(file)) {
01109                 res = ast_streamfile(chan, file, chan->language);
01110                 if (!res)
01111                         res = ast_waitstream(chan, digits);
01112         }
01113         return res;
01114 } 

int ast_stream_fastforward struct ast_filestream fs,
off_t  ms
 

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

Definition at line 681 of file file.c.

References ast_seekstream(), and DEFAULT_SAMPLES_PER_MS.

Referenced by waitstream_core().

00682 {
00683    return ast_seekstream(fs, ms * DEFAULT_SAMPLES_PER_MS, SEEK_CUR);
00684 }

int ast_stream_rewind struct ast_filestream fs,
off_t  ms
 

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

Definition at line 686 of file file.c.

References ast_seekstream(), and DEFAULT_SAMPLES_PER_MS.

Referenced by handle_recordfile(), and waitstream_core().

00687 {
00688    return ast_seekstream(fs, -ms * DEFAULT_SAMPLES_PER_MS, SEEK_CUR);
00689 }

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

References ast_applystream(), ast_getformatname(), ast_getformatname_multiple(), ast_log(), ast_openstream(), ast_openvstream(), ast_playstream(), ast_verbose(), fmt, ast_filestream::fmt, ast_format::format, LOG_DEBUG, LOG_WARNING, ast_channel::nativeformats, option_debug, option_verbose, VERBOSE_PREFIX_3, and ast_filestream::vfs.

Referenced by __login_exec(), agent_call(), ast_app_getdata(), ast_app_getdata_full(), ast_control_streamfile(), ast_play_and_wait(), ast_say_date_da(), ast_say_date_de(), ast_say_date_en(), ast_say_date_fr(), ast_say_date_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_fr(), ast_say_time_gr(), ast_say_time_nl(), ast_say_time_tw(), ast_stream_and_wait(), check_availability(), check_beep(), gr_say_number_female(), handle_recordfile(), park_exec(), pbx_builtin_background(), pl_odtworz_plik(), say_character_str_full(), say_digit_str_full(), say_phonetic_str_full(), ss_thread(), and wait_file().

00772 {
00773    struct ast_filestream *fs;
00774    struct ast_filestream *vfs=NULL;
00775    char fmt[256];
00776 
00777    fs = ast_openstream(chan, filename, preflang);
00778    if (fs)
00779       vfs = ast_openvstream(chan, filename, preflang);
00780    if (vfs) {
00781       if (option_debug)
00782          ast_log(LOG_DEBUG, "Ooh, found a video stream, too, format %s\n", ast_getformatname(vfs->fmt->format));
00783    }
00784    if (fs){
00785       if (ast_applystream(chan, fs))
00786          return -1;
00787       if (vfs && ast_applystream(chan, vfs))
00788          return -1;
00789       if (ast_playstream(fs))
00790          return -1;
00791       if (vfs && ast_playstream(vfs))
00792          return -1;
00793       if (option_verbose > 2)
00794          ast_verbose(VERBOSE_PREFIX_3 "<%s> Playing '%s' (language '%s')\n", chan->name, filename, preflang ? preflang : "default");
00795 
00796       return 0;
00797    }
00798    ast_log(LOG_WARNING, "Unable to open %s (format %s): %s\n", filename, ast_getformatname_multiple(fmt, sizeof(fmt), chan->nativeformats), strerror(errno));
00799    return -1;
00800 }

off_t ast_tellstream struct ast_filestream fs  ) 
 

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

Definition at line 676 of file file.c.

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

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

00677 {
00678    return fs->fmt->tell(fs);
00679 }

int ast_truncstream struct ast_filestream fs  ) 
 

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

Definition at line 671 of file file.c.

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

Referenced by handle_recordfile().

00672 {
00673    return fs->fmt->trunc(fs);
00674 }

int ast_waitstream struct ast_channel c,
const char *  breakon
 

Parameters:
c channel to waitstream on
breakon string of DTMF digits to break upon Begins playback of a stream... Wait for a stream to stop or for any one of a given digit to arrive, Returns 0 if the stream finishes, the character if it was interrupted, and -1 on error

Definition at line 1078 of file file.c.

References waitstream_core().

Referenced by __login_exec(), agent_call(), ast_play_and_wait(), 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(), ast_stream_and_wait(), check_availability(), check_beep(), gr_say_number_female(), handle_recordfile(), park_exec(), pbx_builtin_background(), pl_odtworz_plik(), ss_thread(), and wait_file().

01079 {
01080    return waitstream_core(c, breakon, NULL, NULL, 0, -1, -1, NULL);
01081 }

int ast_waitstream_exten struct ast_channel c,
const char *  context
 

Parameters:
c channel to waitstream on
context string of context to match digits to break upon Begins playback of a stream... Wait for a stream to stop or for any one of a valid extension digit to arrive, Returns 0 if the stream finishes, the character if it was interrupted, and -1 on error

Definition at line 1089 of file file.c.

References ast_channel::context, and waitstream_core().

Referenced by pbx_builtin_background().

01090 {
01091    /* Waitstream, with return in the case of a valid 1 digit extension */
01092    /* in the current or specified context being pressed */
01093 
01094    if (!context)
01095       context = c->context;
01096    return waitstream_core(c, NULL, NULL, NULL, 0,
01097       -1, -1, context);
01098 }

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

Parameters:
c channel to waitstream on
breakon string of DTMF digits to break upon
forward DTMF digit to fast forward upon
rewind DTMF digit to rewind upon
ms How many miliseconds to skip forward/back Begins playback of a stream... Wait for a stream to stop or for any one of a given digit to arrive, Returns 0 if the stream finishes, the character if it was interrupted, and -1 on error

Definition at line 1072 of file file.c.

References waitstream_core().

Referenced by ast_control_streamfile().

01073 {
01074    return waitstream_core(c, breakon, forward, rewind, ms,
01075       -1 /* no audiofd */, -1 /* no cmdfd */, NULL /* no context */);
01076 }

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

Definition at line 1083 of file file.c.

References waitstream_core().

Referenced by ast_readstring_full(), ast_say_enumeration_full_da(), ast_say_enumeration_full_de(), ast_say_enumeration_full_en(), ast_say_number_full_cz(), ast_say_number_full_da(), ast_say_number_full_de(), ast_say_number_full_en(), ast_say_number_full_en_GB(), ast_say_number_full_es(), ast_say_number_full_fr(), ast_say_number_full_gr(), ast_say_number_full_he(), ast_say_number_full_it(), ast_say_number_full_nl(), ast_say_number_full_no(), ast_say_number_full_pt(), ast_say_number_full_ru(), ast_say_number_full_se(), ast_say_number_full_tw(), handle_getoption(), handle_streamfile(), pl_odtworz_plik(), say_character_str_full(), say_digit_str_full(), and say_phonetic_str_full().

01084 {
01085    return waitstream_core(c, breakon, NULL, NULL, 0,
01086       audiofd, cmdfd, NULL /* no context */);
01087 }

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

References ast_log(), ast_opt_cache_record_files, AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_strdupa, ast_filestream::buf, build_filename(), exts_compare(), ast_filestream::f, ast_filestream::filename, ast_filestream::flags, ast_filestream::fmt, free, get_filestream(), LOG_WARNING, ast_filestream::mode, ast_filestream::realfilename, record_cache_dir, rewrite_wrapper(), strdup, ast_filestream::trans, and ast_filestream::vfs.

Referenced by __ast_play_and_record(), ast_monitor_start(), ast_writestream(), cli_audio_convert(), and handle_recordfile().

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

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 143 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, option_debug, ast_frame::subclass, ast_filestream::trans, type, ast_filestream::vfs, and ast_format::write.

Referenced by __ast_read(), ast_write(), ast_writestream(), cli_audio_convert(), and handle_recordfile().

00144 {
00145    int res = -1;
00146    int alt = 0;
00147    if (f->frametype == AST_FRAME_VIDEO) {
00148       if (fs->fmt->format < AST_FORMAT_MAX_AUDIO) {
00149          /* This is the audio portion.  Call the video one... */
00150          if (!fs->vfs && fs->filename) {
00151             const char *type = ast_getformatname(f->subclass & ~0x1);
00152             fs->vfs = ast_writefile(fs->filename, type, NULL, fs->flags, 0, fs->mode);
00153             if (option_debug)
00154                ast_log(LOG_DEBUG, "Opened video output file\n");
00155          }
00156          if (fs->vfs)
00157             return ast_writestream(fs->vfs, f);
00158          /* else ignore */
00159          return 0;            
00160       } else {
00161          /* Might / might not have mark set */
00162          alt = 1;
00163       }
00164    } else if (f->frametype != AST_FRAME_VOICE) {
00165       ast_log(LOG_WARNING, "Tried to write non-voice frame\n");
00166       return -1;
00167    }
00168    if (((fs->fmt->format | alt) & f->subclass) == f->subclass) {
00169       res =  fs->fmt->write(fs, f);
00170       if (res < 0) 
00171          ast_log(LOG_WARNING, "Natural write failed\n");
00172       else if (res > 0)
00173          ast_log(LOG_WARNING, "Huh??\n");
00174    } else {
00175       /* XXX If they try to send us a type of frame that isn't the normal frame, and isn't
00176              the one we've setup a translator for, we do the "wrong thing" XXX */
00177       if (fs->trans && f->subclass != fs->lastwriteformat) {
00178          ast_translator_free_path(fs->trans);
00179          fs->trans = NULL;
00180       }
00181       if (!fs->trans) 
00182          fs->trans = ast_translator_build_path(fs->fmt->format, f->subclass);
00183       if (!fs->trans)
00184          ast_log(LOG_WARNING, "Unable to translate to format %s, source format %s\n",
00185             fs->fmt->name, ast_getformatname(f->subclass));
00186       else {
00187          struct ast_frame *trf;
00188          fs->lastwriteformat = f->subclass;
00189          /* Get the translated frame but don't consume the original in case they're using it on another stream */
00190          trf = ast_translate(fs->trans, f, 0);
00191          if (trf) {
00192             res = fs->fmt->write(fs, trf);
00193             if (res) 
00194                ast_log(LOG_WARNING, "Translated frame write failed\n");
00195          } else
00196             res = 0;
00197       }
00198    }
00199    return res;
00200 }

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

construct a filename. Absolute pathnames are preserved, relative names are prefixed by the sounds/ directory. The wav49 suffix is replaced by 'WAV'. Returns a malloc'ed string to be freed by the caller.

Definition at line 245 of file file.c.

References asprintf, and ast_config_AST_DATA_DIR.

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

00246 {
00247    char *fn = NULL;
00248 
00249    if (!strcmp(ext, "wav49"))
00250       ext = "WAV";
00251 
00252    if (filename[0] == '/')
00253       asprintf(&fn, "%s.%s", filename, ext);
00254    else
00255       asprintf(&fn, "%s/sounds/%s.%s",
00256          ast_config_AST_DATA_DIR, filename, ext);
00257    return fn;
00258 }

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

Definition at line 202 of file file.c.

References AST_FILE_MODE, ast_log(), len, and LOG_WARNING.

Referenced by ast_filehelper(), ast_func_read(), ast_func_write(), and iax2_register().

00203 {
00204    int ifd, ofd, len;
00205    char buf[4096];   /* XXX make it lerger. */
00206 
00207    if ((ifd = open(infile, O_RDONLY)) < 0) {
00208       ast_log(LOG_WARNING, "Unable to open %s in read-only mode\n", infile);
00209       return -1;
00210    }
00211    if ((ofd = open(outfile, O_WRONLY | O_TRUNC | O_CREAT, AST_FILE_MODE)) < 0) {
00212       ast_log(LOG_WARNING, "Unable to open %s in write-only mode\n", outfile);
00213       close(ifd);
00214       return -1;
00215    }
00216    while ( (len = read(ifd, buf, sizeof(buf)) ) ) {
00217       int res;
00218       if (len < 0) {
00219          ast_log(LOG_WARNING, "Read failed on %s: %s\n", infile, strerror(errno));
00220          break;
00221       }
00222       /* XXX handle partial writes */
00223       res = write(ofd, buf, len);
00224       if (res != len) {
00225          ast_log(LOG_WARNING, "Write failed on %s (%d of %d): %s\n", outfile, res, len, strerror(errno));
00226          len = -1; /* error marker */
00227          break;
00228       }
00229    }
00230    close(ifd);
00231    close(ofd);
00232    if (len < 0) {
00233       unlink(outfile);
00234       return -1; /* error */
00235    }
00236    return 0;   /* success */
00237 }

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

Definition at line 262 of file file.c.

References ext, and strsep().

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

00263 {
00264    char tmp[256];
00265    char *stringp = tmp, *ext;
00266 
00267    ast_copy_string(tmp, exts, sizeof(tmp));
00268    while ((ext = strsep(&stringp, "|"))) {
00269       if (!strcmp(ext, type))
00270          return 1;
00271    }
00272 
00273    return 0;
00274 }

static int fileexists_core const char *  filename,
const char *  fmt,
const char *  preflang,
char *  buf,
int  buflen
[static]
 

helper routine to locate a file with a given format and language preference. Try preflang, preflang with stripped '_' suffix, or NULL. In the standard asterisk, language goes just before the last component. In an alternative configuration, the language should be a prefix to the actual filename.

The last parameter(s) point to a buffer of sufficient size, which on success is filled with the matching filename.

Definition at line 465 of file file.c.

References ast_log(), LOG_WARNING, and offset.

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

00467 {
00468    int res = -1;
00469    int langlen;   /* length of language string */
00470    const char *c = strrchr(filename, '/');
00471    int offset = c ? c - filename + 1 : 0; /* points right after the last '/' */
00472 
00473    if (preflang == NULL)
00474       preflang = "";
00475    langlen = strlen(preflang);
00476    
00477    if (buflen < langlen + strlen(filename) + 2) {
00478       ast_log(LOG_WARNING, "buffer too small\n");
00479       buf[0] = '\0'; /* set to empty */
00480       buf = alloca(langlen + strlen(filename) + 2);   /* room for everything */
00481    }
00482    if (buf == NULL)
00483       return 0;
00484    buf[0] = '\0';
00485    for (;;) {
00486       if (ast_language_is_prefix) { /* new layout */
00487          if (langlen) {
00488             strcpy(buf, preflang);
00489             buf[langlen] = '/';
00490             strcpy(buf + langlen + 1, filename);
00491          } else
00492             strcpy(buf, filename);  /* first copy the full string */
00493       } else { /* old layout */
00494          strcpy(buf, filename);  /* first copy the full string */
00495          if (langlen) {
00496             /* insert the language and suffix if needed */
00497             strcpy(buf + offset, preflang);
00498             sprintf(buf + offset + langlen, "/%s", filename + offset);
00499          }
00500       }
00501       res = ast_filehelper(buf, NULL, fmt, ACTION_EXISTS);
00502       if (res > 0)      /* found format */
00503          break;
00504       if (langlen == 0) /* no more formats */
00505          break;
00506       if (preflang[langlen] == '_') /* we are on the local suffix */
00507          langlen = 0;   /* try again with no language */
00508       else
00509          langlen = (c = strchr(preflang, '_')) ? c - preflang : 0;
00510    }
00511    return res;
00512 }

static int fn_wrapper struct ast_filestream s,
const char *  comment,
enum wrap_fn  mode
[static]
 

Definition at line 300 of file file.c.

References ast_log(), ast_module_ref(), LOG_WARNING, ast_format::module, ast_format::name, ast_format::open, ast_format::rewrite, s, and WRAP_OPEN.

Referenced by open_wrapper(), and rewrite_wrapper().

00301 {
00302    struct ast_format *f = s->fmt;
00303    int ret = -1;
00304 
00305    if (mode == WRAP_OPEN && f->open && f->open(s))
00306                 ast_log(LOG_WARNING, "Unable to open format %s\n", f->name);
00307    else if (mode == WRAP_REWRITE && f->rewrite && f->rewrite(s, comment))
00308                 ast_log(LOG_WARNING, "Unable to rewrite format %s\n", f->name);
00309    else {
00310       /* preliminary checks succeed. update usecount */
00311       ast_module_ref(f->module);
00312       ret = 0;
00313    }
00314         return ret;
00315 }

static struct ast_filestream* get_filestream struct ast_format fmt,
FILE *  bfile
[static]
 

Definition at line 276 of file file.c.

References ast_calloc, fmt, and s.

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

00277 {
00278    struct ast_filestream *s;
00279 
00280    int l = sizeof(*s) + fmt->buf_size + fmt->desc_size;  /* total allocation size */
00281    if ( (s = ast_calloc(1, l)) == NULL)
00282       return NULL;
00283    s->fmt = fmt;
00284    s->f = bfile;
00285 
00286    if (fmt->desc_size)
00287       s->private = ((char *)(s+1)) + fmt->buf_size;
00288    if (fmt->buf_size)
00289       s->buf = (char *)(s+1);
00290    s->fr.src = fmt->name;
00291    return s;
00292 }

static int open_wrapper struct ast_filestream s  )  [static]
 

Definition at line 322 of file file.c.

References fn_wrapper(), s, and WRAP_OPEN.

Referenced by ast_filehelper(), and ast_readfile().

00323 {
00324    return fn_wrapper(s, NULL, WRAP_OPEN);
00325 }

static int rewrite_wrapper struct ast_filestream s,
const char *  comment
[static]
 

Definition at line 317 of file file.c.

References fn_wrapper(), and s.

Referenced by ast_writefile().

00318 {
00319    return fn_wrapper(s, comment, WRAP_REWRITE);
00320 }

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

Definition at line 1116 of file file.c.

References ast_cli(), ast_getformatname(), AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_format::exts, ast_format::format, FORMAT, FORMAT2, ast_format::name, RESULT_SHOWUSAGE, and RESULT_SUCCESS.

01117 {
01118 #define FORMAT "%-10s %-10s %-20s\n"
01119 #define FORMAT2 "%-10s %-10s %-20s\n"
01120    struct ast_format *f;
01121    int count_fmt = 0;
01122 
01123    if (argc != 4)
01124       return RESULT_SHOWUSAGE;
01125    ast_cli(fd, FORMAT, "Format", "Name", "Extensions");
01126 
01127    AST_RWLIST_RDLOCK(&formats);
01128    AST_RWLIST_TRAVERSE(&formats, f, list) {
01129       ast_cli(fd, FORMAT2, ast_getformatname(f->format), f->name, f->exts);
01130       count_fmt++;
01131    }
01132    AST_RWLIST_UNLOCK(&formats);
01133    ast_cli(fd, "%d file formats registered.\n", count_fmt);
01134    return RESULT_SUCCESS;
01135 #undef FORMAT
01136 #undef FORMAT2
01137 }

static int waitstream_core struct ast_channel c,
const char *  breakon,
const char *  forward,
const char *  rewind,
int  skip_ms,
int  audiofd,
int  cmdfd,
const char *  context
[static]
 

the core of all waitstream() functions

Definition at line 973 of file file.c.

References ast_channel::_softhangup, AST_CONTROL_ANSWER, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_HANGUP, AST_CONTROL_HOLD, AST_CONTROL_RINGING, AST_CONTROL_UNHOLD, AST_CONTROL_VIDUPDATE, ast_exists_extension(), AST_FRAME_CONTROL, AST_FRAME_DTMF_END, AST_FRAME_VOICE, ast_frfree(), ast_log(), ast_read(), ast_sched_runq(), ast_sched_wait(), ast_stopstream(), ast_stream_fastforward(), ast_stream_rewind(), ast_waitfor(), ast_waitfor_nandfds(), ast_channel::cid, ast_callerid::cid_num, ast_frame::data, ast_frame::datalen, exten, ast_frame::frametype, LOG_WARNING, ast_channel::sched, ast_channel::stream, and ast_frame::subclass.

Referenced by ast_waitstream(), ast_waitstream_exten(), ast_waitstream_fr(), and ast_waitstream_full().

00976 {
00977    if (!breakon)
00978       breakon = "";
00979    if (!forward)
00980       forward = "";
00981    if (!rewind)
00982       rewind = "";
00983    
00984    while (c->stream) {
00985       int res;
00986       int ms = ast_sched_wait(c->sched);
00987       if (ms < 0 && !c->timingfunc) {
00988          ast_stopstream(c);
00989          break;
00990       }
00991       if (ms < 0)
00992          ms = 1000;
00993       if (cmdfd < 0) {
00994          res = ast_waitfor(c, ms);
00995          if (res < 0) {
00996             ast_log(LOG_WARNING, "Select failed (%s)\n", strerror(errno));
00997             return res;
00998          }
00999       } else {
01000          int outfd;
01001          struct ast_channel *rchan = ast_waitfor_nandfds(&c, 1, &cmdfd, (cmdfd > -1) ? 1 : 0, NULL, &outfd, &ms);
01002          if (!rchan && (outfd < 0) && (ms)) {
01003             /* Continue */
01004             if (errno == EINTR)
01005                continue;
01006             ast_log(LOG_WARNING, "Wait failed (%s)\n", strerror(errno));
01007             return -1;
01008          } else if (outfd > -1) { /* this requires cmdfd set */
01009             /* The FD we were watching has something waiting */
01010             return 1;
01011          }
01012          /* if rchan is set, it is 'c' */
01013          res = rchan ? 1 : 0; /* map into 'res' values */
01014       }
01015       if (res > 0) {
01016          struct ast_frame *fr = ast_read(c);
01017          if (!fr)
01018             return -1;
01019          switch (fr->frametype) {
01020          case AST_FRAME_DTMF_END:
01021             if (context) {
01022                const char exten[2] = { fr->subclass, '\0' };
01023                if (ast_exists_extension(c, context, exten, 1, c->cid.cid_num)) {
01024                   ast_frfree(fr);
01025                   return res;
01026                }
01027             } else {
01028                res = fr->subclass;
01029                if (strchr(forward,res)) {
01030                   ast_stream_fastforward(c->stream, skip_ms);
01031                } else if (strchr(rewind,res)) {
01032                   ast_stream_rewind(c->stream, skip_ms);
01033                } else if (strchr(breakon, res)) {
01034                   ast_frfree(fr);
01035                   return res;
01036                }              
01037             }
01038             break;
01039          case AST_FRAME_CONTROL:
01040             switch (fr->subclass) {
01041             case AST_CONTROL_HANGUP:
01042             case AST_CONTROL_BUSY:
01043             case AST_CONTROL_CONGESTION:
01044                ast_frfree(fr);
01045                return -1;
01046             case AST_CONTROL_RINGING:
01047             case AST_CONTROL_ANSWER:
01048             case AST_CONTROL_VIDUPDATE:
01049             case AST_CONTROL_HOLD:
01050             case AST_CONTROL_UNHOLD:
01051                /* Unimportant */
01052                break;
01053             default:
01054                ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", fr->subclass);
01055             }
01056             break;
01057          case AST_FRAME_VOICE:
01058             /* Write audio if appropriate */
01059             if (audiofd > -1)
01060                write(audiofd, fr->data, fr->datalen);
01061          default:
01062             /* Ignore all others */
01063             break;
01064          }
01065          ast_frfree(fr);
01066       }
01067       ast_sched_runq(c->sched);
01068    }
01069    return (c->_softhangup ? -1 : 0);
01070 }


Variable Documentation

int ast_language_is_prefix = 1
 

Definition at line 64 of file file.c.

struct ast_cli_entry cli_file[]
 

Initial value:

 {
   { { "core", "show", "file", "formats" },
   show_file_formats, "Displays file formats",
   show_file_formats_usage },
}

Definition at line 1143 of file file.c.

Referenced by ast_file_init().

const char show_file_formats_usage[] [static]
 

Initial value:

 
"Usage: core show file formats\n"
"       Displays currently registered file formats (if any)\n"

Definition at line 1139 of file file.c.


Asterisk is a trademark for Digium, inc.. | Edvina.net | Asterisk.org | This documentation was generated with Doxygen