Wed Aug 15 01:25:07 2007

Asterisk developer's documentation


file.c File Reference

Generic File Format Support. More...

#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 FORMAT   "%-10s %-10s %-20s\n"
#define FORMAT2   "%-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)
static AST_LIST_HEAD_STATIC (formats, ast_format)
struct ast_filestreamast_openstream (struct ast_channel *chan, const char *filename, const char *preflang)
struct ast_filestreamast_openstream_full (struct ast_channel *chan, const char *filename, const char *preflang, int asis)
struct 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)
struct ast_filestreamast_readfile (const char *filename, const char *type, const char *comment, int flags, int check, mode_t mode)
struct ast_frameast_readframe (struct ast_filestream *s)
static int ast_readvideo_callback (void *data)
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 *language, 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)
struct 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_filestream
get_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 show_file_formats_deprecated (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
struct ast_cli_entry cli_file []
struct ast_cli_entry cli_show_file_formats_deprecated
char show_file_formats_usage []


Detailed Description

Generic File Format Support.

Author:
Mark Spencer <markster@digium.com>

Definition in file file.c.


Define Documentation

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

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

#define FORMAT2   "%-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_file_formats_deprecated(), show_image_formats(), show_image_formats_deprecated(), sip_show_inuse(), sip_show_registry(), zap_show_channels(), and zap_show_status().


Enumeration Type Documentation

enum file_action

Enumerator:
ACTION_EXISTS 
ACTION_DELETE 
ACTION_RENAME 
ACTION_OPEN 
ACTION_COPY 

Definition at line 337 of file file.c.

00337                  {
00338    ACTION_EXISTS = 1, /* return matching format if file exists, 0 otherwise */
00339    ACTION_DELETE, /* delete file, return 0 on success, -1 on error */
00340    ACTION_RENAME, /* rename file. return 0 on success, -1 on error */
00341    ACTION_OPEN,
00342    ACTION_COPY /* copy file. return 0 on success, -1 on error */
00343 };

enum wrap_fn

Enumerator:
WRAP_OPEN 
WRAP_REWRITE 

Definition at line 308 of file file.c.

00308 { 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.

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

int ast_applystream ( struct ast_channel chan,
struct ast_filestream s 
)

Applys a open stream to a channel.

Parameters:
chan channel to work
s ast_filestream to apply Returns 0 for success, -1 on failure

Definition at line 669 of file file.c.

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

00670 {
00671    s->owner = chan;
00672    return 0;
00673 }

int ast_closestream ( struct ast_filestream f  ) 

Closes a stream

Parameters:
f filestream to close Close a playback or recording stream Returns 0 on success, -1 on failure

Definition at line 709 of file file.c.

Referenced by __ast_play_and_record(), ast_closestream(), ast_filehelper(), ast_hangup(), ast_moh_files_next(), ast_monitor_start(), ast_monitor_stop(), ast_stopstream(), channel_spy(), cli_audio_convert(), cli_audio_convert_deprecated(), dictate_exec(), gen_closestream(), handle_recordfile(), local_ast_moh_stop(), mixmonitor_thread(), moh_files_release(), record_exec(), recordthread(), and rpt().

00710 {
00711    char *cmd = NULL;
00712    size_t size = 0;
00713    /* Stop a running stream if there is one */
00714    if (f->owner) {
00715       if (f->fmt->format < AST_FORMAT_MAX_AUDIO) {
00716          f->owner->stream = NULL;
00717          if (f->owner->streamid > -1)
00718             ast_sched_del(f->owner->sched, f->owner->streamid);
00719          f->owner->streamid = -1;
00720 #ifdef HAVE_ZAPTEL
00721          ast_settimeout(f->owner, 0, NULL, NULL);
00722 #endif         
00723       } else {
00724          f->owner->vstream = NULL;
00725          if (f->owner->vstreamid > -1)
00726             ast_sched_del(f->owner->sched, f->owner->vstreamid);
00727          f->owner->vstreamid = -1;
00728       }
00729    }
00730    /* destroy the translator on exit */
00731    if (f->trans)
00732       ast_translator_free_path(f->trans);
00733 
00734    if (f->realfilename && f->filename) {
00735          size = strlen(f->filename) + strlen(f->realfilename) + 15;
00736          cmd = alloca(size);
00737          memset(cmd,0,size);
00738          snprintf(cmd,size,"/bin/mv -f %s %s",f->filename,f->realfilename);
00739          ast_safe_system(cmd);
00740    }
00741 
00742    if (f->filename)
00743       free(f->filename);
00744    if (f->realfilename)
00745       free(f->realfilename);
00746    if (f->fmt->close)
00747       f->fmt->close(f);
00748    fclose(f->f);
00749    if (f->vfs)
00750       ast_closestream(f->vfs);
00751    ast_module_unref(f->fmt->module);
00752    free(f);
00753    return 0;
00754 }

int ast_file_init ( void   ) 

Initialize file stuff

Initializes all the various file stuff. Basically just registers the cli stuff Returns 0 all the time

Definition at line 1210 of file file.c.

Referenced by main().

01211 {
01212    ast_cli_register_multiple(cli_file, sizeof(cli_file) / sizeof(struct ast_cli_entry));
01213    return 0;
01214 }

int ast_filecopy ( const char *  oldname,
const char *  newname,
const char *  fmt 
)

Copies a file

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

Referenced by copy_file().

00785 {
00786    return ast_filehelper(filename, filename2, fmt, ACTION_COPY);
00787 }

int ast_filedelete ( const char *  filename,
const char *  fmt 
)

Deletes a file

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

Referenced by __ast_play_and_record(), ast_monitor_start(), ast_monitor_stop(), cli_audio_convert(), cli_audio_convert_deprecated(), conf_run(), leave_voicemail(), play_mailbox_owner(), play_record_review(), and vm_delete().

00775 {
00776    return ast_filehelper(filename, NULL, fmt, ACTION_DELETE);
00777 }

int ast_fileexists ( const char *  filename,
const char *  fmt,
const char *  preflang 
)

Checks for the existence of a given file

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

Referenced by app_exec(), ast_moh_files_next(), ast_monitor_start(), ast_monitor_stop(), common_exec(), conf_run(), invent_message(), last_message_index(), leave_voicemail(), play_mailbox_owner(), play_message_callerid(), record_exec(), retrydial_exec(), say_character_str_full(), say_digit_str_full(), say_phonetic_str_full(), vm_intro(), vm_newuser(), and vm_tempgreeting().

00761 {
00762    char *buf;
00763    int buflen;
00764 
00765    if (preflang == NULL)
00766       preflang = "";
00767    buflen = strlen(preflang) + strlen(filename) + 2;  /* room for everything */
00768    buf = alloca(buflen);
00769    if (buf == NULL)
00770       return 0;
00771    return fileexists_core(filename, fmt, preflang, buf, buflen);
00772 }

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

References ACTION_COPY, ACTION_DELETE, ACTION_EXISTS, ACTION_OPEN, ACTION_RENAME, ast_closestream(), AST_FORMAT_MAX_AUDIO, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_strdupa, build_filename(), copy(), ext, ast_format::exts, exts_compare(), f, ast_filestream::filename, ast_filestream::fmt, ast_format::format, free, get_filestream(), ast_filestream::lasttimeout, LOG_WARNING, open_wrapper(), s, ast_channel::stream, strsep(), ast_filestream::trans, ast_channel::vstream, and ast_channel::writeformat.

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

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

int ast_filerename ( const char *  oldname,
const char *  newname,
const char *  fmt 
)

Renames a file

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

Referenced by __ast_play_and_record(), ast_monitor_stop(), leave_voicemail(), play_record_review(), and rename_file().

00780 {
00781    return ast_filehelper(filename, filename2, fmt, ACTION_RENAME);
00782 }

int ast_format_unregister ( const char *  name  ) 

Unregisters a file format

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

Referenced by unload_module().

00110 {
00111    struct ast_format *tmp;
00112    int res = -1;
00113 
00114    if (AST_LIST_LOCK(&formats)) {
00115       ast_log(LOG_WARNING, "Unable to lock format list\n");
00116       return -1;
00117    }
00118    AST_LIST_TRAVERSE_SAFE_BEGIN(&formats, tmp, list) {
00119       if (!strcasecmp(name, tmp->name)) {
00120          AST_LIST_REMOVE_CURRENT(&formats, list);
00121          free(tmp);
00122          res = 0;
00123       }
00124    }
00125    AST_LIST_TRAVERSE_SAFE_END
00126    AST_LIST_UNLOCK(&formats);
00127 
00128    if (!res) {
00129       if (option_verbose > 1)
00130          ast_verbose( VERBOSE_PREFIX_2 "Unregistered format %s\n", name);
00131    } else
00132       ast_log(LOG_WARNING, "Tried to unregister format %s, already unregistered\n", name);
00133 
00134    return res;
00135 }

static AST_LIST_HEAD_STATIC ( formats  ,
ast_format   
) [static]

struct ast_filestream* ast_openstream ( struct ast_channel chan,
const char *  filename,
const char *  preflang 
) [read]

Opens stream for use in seeking, playing

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

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

00533 {
00534    return ast_openstream_full(chan, filename, preflang, 0);
00535 }

struct ast_filestream* ast_openstream_full ( struct ast_channel chan,
const char *  filename,
const char *  preflang,
int  asis 
) [read]

Opens stream for use in seeking, playing

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

Referenced by ast_moh_files_next(), ast_openstream(), channel_spy(), and gen_nextfile().

00538 {
00539    /* 
00540     * Use fileexists_core() to find a file in a compatible
00541     * language and format, set up a suitable translator,
00542     * and open the stream.
00543     */
00544    int fmts, res, buflen;
00545    char *buf;
00546 
00547    if (!asis) {
00548       /* do this first, otherwise we detect the wrong writeformat */
00549       ast_stopstream(chan);
00550       if (chan->generator)
00551          ast_deactivate_generator(chan);
00552    }
00553    if (preflang == NULL)
00554       preflang = "";
00555    buflen = strlen(preflang) + strlen(filename) + 2;
00556    buf = alloca(buflen);
00557    if (buf == NULL)
00558       return NULL;
00559    fmts = fileexists_core(filename, NULL, preflang, buf, buflen);
00560    if (fmts > 0)
00561       fmts &= AST_FORMAT_AUDIO_MASK;
00562    if (fmts < 1) {
00563       ast_log(LOG_WARNING, "File %s does not exist in any format\n", filename);
00564       return NULL;
00565    }
00566    chan->oldwriteformat = chan->writeformat;
00567    /* Set the channel to a format we can work with */
00568    res = ast_set_write_format(chan, fmts);
00569    res = ast_filehelper(buf, chan, NULL, ACTION_OPEN);
00570    if (res >= 0)
00571       return chan->stream;
00572    return NULL;
00573 }

struct ast_filestream* ast_openvstream ( struct ast_channel chan,
const char *  filename,
const char *  preflang 
) [read]

Opens stream for use in seeking, playing

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

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

00576 {
00577    /* As above, but for video. But here we don't have translators
00578     * so we must enforce a format.
00579     */
00580    unsigned int format;
00581    char *buf;
00582    int buflen;
00583 
00584    if (preflang == NULL)
00585       preflang = "";
00586    buflen = strlen(preflang) + strlen(filename) + 2;
00587    buf = alloca(buflen);
00588    if (buf == NULL)
00589       return NULL;
00590 
00591    for (format = AST_FORMAT_MAX_AUDIO << 1; format <= AST_FORMAT_MAX_VIDEO; format = format << 1) {
00592       int fd;
00593       const char *fmt;
00594 
00595       if (!(chan->nativeformats & format))
00596          continue;
00597       fmt = ast_getformatname(format);
00598       if ( fileexists_core(filename, fmt, preflang, buf, buflen) < 1)   /* no valid format */
00599          continue;
00600       fd = ast_filehelper(buf, chan, fmt, ACTION_OPEN);
00601       if (fd >= 0)
00602          return chan->vstream;
00603       ast_log(LOG_WARNING, "File %s has video but couldn't be opened\n", filename);
00604    }
00605    return NULL;
00606 }

int ast_playstream ( struct ast_filestream s  ) 

play a open stream on a channel.

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

Definition at line 675 of file file.c.

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

00676 {
00677    if (s->fmt->format < AST_FORMAT_MAX_AUDIO)
00678       ast_readaudio_callback(s);
00679    else
00680       ast_readvideo_callback(s);
00681    return 0;
00682 }

static int ast_readaudio_callback ( void *  data  )  [static]

Definition at line 617 of file file.c.

References ast_log(), ast_sched_add(), ast_settimeout(), ast_write(), ast_filestream::fmt, ast_filestream::lasttimeout, LOG_WARNING, ast_filestream::owner, ast_format::read, s, ast_channel::sched, ast_channel::streamid, and ast_channel::timingfd.

Referenced by ast_playstream().

00618 {
00619    struct ast_filestream *s = data;
00620    int whennext = 0;
00621 
00622    while(!whennext) {
00623       struct ast_frame *fr = s->fmt->read(s, &whennext);
00624       if (!fr /* stream complete */ || ast_write(s->owner, fr) /* error writing */) {
00625          if (fr)
00626             ast_log(LOG_WARNING, "Failed to write frame\n");
00627          s->owner->streamid = -1;
00628 #ifdef HAVE_ZAPTEL
00629          ast_settimeout(s->owner, 0, NULL, NULL);
00630 #endif         
00631          return 0;
00632       }
00633    }
00634    if (whennext != s->lasttimeout) {
00635 #ifdef HAVE_ZAPTEL
00636       if (s->owner->timingfd > -1)
00637          ast_settimeout(s->owner, whennext, ast_readaudio_callback, s);
00638       else
00639 #endif      
00640          s->owner->streamid = ast_sched_add(s->owner->sched, whennext/8, ast_readaudio_callback, s);
00641       s->lasttimeout = whennext;
00642       return 0;
00643    }
00644    return 1;
00645 }

struct ast_filestream* ast_readfile ( const char *  filename,
const char *  type,
const char *  comment,
int  flags,
int  check,
mode_t  mode 
) [read]

Starts reading from a file

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

Referenced by __ast_play_and_record(), cli_audio_convert(), and cli_audio_convert_deprecated().

00818 {
00819    FILE *bfile;
00820    struct ast_format *f;
00821    struct ast_filestream *fs = NULL;
00822    char *fn;
00823 
00824    if (AST_LIST_LOCK(&formats)) {
00825       ast_log(LOG_WARNING, "Unable to lock format list\n");
00826       return NULL;
00827    }
00828 
00829    AST_LIST_TRAVERSE(&formats, f, list) {
00830       fs = NULL;
00831       if (!exts_compare(f->exts, type))
00832          continue;
00833 
00834       fn = build_filename(filename, type);
00835       errno = 0;
00836       bfile = fopen(fn, "r");
00837       if (!bfile || (fs = get_filestream(f, bfile)) == NULL ||
00838           open_wrapper(fs) ) {
00839          ast_log(LOG_WARNING, "Unable to open %s\n", fn);
00840          if (fs)
00841             ast_free(fs);
00842          if (bfile)
00843             fclose(bfile);
00844          free(fn);
00845          continue;
00846       }
00847       /* found it */
00848       fs->trans = NULL;
00849       fs->fmt = f;
00850       fs->flags = flags;
00851       fs->mode = mode;
00852       fs->filename = strdup(filename);
00853       fs->vfs = NULL;
00854       break;
00855    }
00856 
00857    AST_LIST_UNLOCK(&formats);
00858    if (!fs) 
00859       ast_log(LOG_WARNING, "No such format '%s'\n", type);
00860 
00861    return fs;
00862 }

struct ast_frame* ast_readframe ( struct ast_filestream s  )  [read]

Read a frame from a filestream

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

Definition at line 608 of file file.c.

Referenced by __ast_play_and_record(), channel_spy(), cli_audio_convert(), cli_audio_convert_deprecated(), dictate_exec(), gen_readframe(), and moh_files_readframe().

00609 {
00610    struct ast_frame *f = NULL;
00611    int whennext = 0; 
00612    if (s && s->fmt)
00613       f = s->fmt->read(s, &whennext);
00614    return f;
00615 }

static int ast_readvideo_callback ( void *  data  )  [static]

Definition at line 647 of file file.c.

References ast_log(), ast_sched_add(), ast_write(), ast_filestream::fmt, ast_filestream::lasttimeout, LOG_WARNING, ast_filestream::owner, ast_format::read, s, ast_channel::sched, and ast_channel::vstreamid.

Referenced by ast_playstream().

00648 {
00649    struct ast_filestream *s = data;
00650    int whennext = 0;
00651 
00652    while (!whennext) {
00653       struct ast_frame *fr = s->fmt->read(s, &whennext);
00654       if (!fr || ast_write(s->owner, fr)) { /* no stream or error, as above */
00655          if (fr)
00656             ast_log(LOG_WARNING, "Failed to write frame\n");
00657          s->owner->vstreamid = -1;
00658          return 0;
00659       }
00660    }
00661    if (whennext != s->lasttimeout) {
00662       s->owner->vstreamid = ast_sched_add(s->owner->sched, whennext/8, ast_readvideo_callback, s);
00663       s->lasttimeout = whennext;
00664       return 0;
00665    }
00666    return 1;
00667 }

int ast_seekstream ( struct ast_filestream fs,
off_t  sample_offset,
int  whence 
)

Seeks into stream

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

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

00685 {
00686    return fs->fmt->seek(fs, sample_offset, whence);
00687 }

int ast_stopstream ( struct ast_channel c  ) 

Stops a stream

Parameters:
c The channel you wish to stop playback on Stop playback of a stream Returns 0 regardless

Definition at line 137 of file file.c.

Referenced by app_exec(), 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_ge(), 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(), background_detect_exec(), builtin_blindtransfer(), conf_exec(), conf_run(), directory_exec(), handle_getoption(), handle_streamfile(), ices_exec(), ivr_dispatch(), leave_voicemail(), mp3_exec(), NBScat_exec(), parkandannounce_exec(), pbx_builtin_background(), pl_odtworz_plik(), play_file(), play_mailbox_owner(), playback_exec(), queue_exec(), read_exec(), record_exec(), recordthread(), rpt_tele_thread(), s_streamwait3(), say_character_str_full(), say_digit_str_full(), say_phonetic_str_full(), saycharstr(), sayfile(), saynum(), send_morse(), send_tone_telemetry(), send_waveform_to_channel(), speech_background(), vm_authenticate(), vm_execmain(), wait_for_winner(), waitstream_core(), and zapateller_exec().

00138 {
00139    /* Stop a running stream if there is one */
00140    if (tmp->stream) {
00141       ast_closestream(tmp->stream);
00142       tmp->stream = NULL;
00143       if (tmp->oldwriteformat && ast_set_write_format(tmp, tmp->oldwriteformat))
00144          ast_log(LOG_WARNING, "Unable to restore format back to %d\n", tmp->oldwriteformat);
00145    }
00146    /* Stop the video stream too */
00147    if (tmp->vstream != NULL) {
00148       ast_closestream(tmp->vstream);
00149       tmp->vstream = NULL;
00150    }
00151    return 0;
00152 }

int ast_stream_and_wait ( struct ast_channel chan,
const char *  file,
const char *  language,
const char *  digits 
)

Definition at line 1129 of file file.c.

Referenced by __ast_play_and_record(), app_exec(), ast_record_review(), bridge_playfile(), builtin_atxfer(), builtin_automonitor(), builtin_blindtransfer(), directory_exec(), invent_message(), ivr_dispatch(), leave_voicemail(), park_exec(), play_mailbox_owner(), play_message_callerid(), play_record_review(), and wait_file2().

01131 {
01132         int res = 0;
01133         if (!ast_strlen_zero(file)) {
01134                 res =  ast_streamfile(chan, file, language);
01135                 if (!res)
01136                         res = ast_waitstream(chan, digits);
01137         }
01138         return res;
01139 } 

int ast_stream_fastforward ( struct ast_filestream fs,
off_t  ms 
)

Fast forward stream ms

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

Definition at line 699 of file file.c.

Referenced by waitstream_core().

00700 {
00701    return ast_seekstream(fs, ms * DEFAULT_SAMPLES_PER_MS, SEEK_CUR);
00702 }

int ast_stream_rewind ( struct ast_filestream fs,
off_t  ms 
)

Rewind stream ms

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

Definition at line 704 of file file.c.

Referenced by __ast_play_and_record(), handle_recordfile(), record_exec(), and waitstream_core().

00705 {
00706    return ast_seekstream(fs, -ms * DEFAULT_SAMPLES_PER_MS, SEEK_CUR);
00707 }

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

Streams a file

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

Referenced by __login_exec(), agent_call(), app_exec(), 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_ge(), 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_from_now_ge(), 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_ge(), 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_ge(), ast_say_time_gr(), ast_say_time_nl(), ast_say_time_tw(), ast_stream_and_wait(), auth_exec(), background_detect_exec(), check_availability(), check_beep(), common_exec(), conf_exec(), conf_run(), do_directory(), forward_message(), gr_say_number_female(), handle_recordfile(), leave_voicemail(), page_exec(), park_exec(), parkandannounce_exec(), pbx_builtin_background(), pl_odtworz_plik(), play_and_wait(), play_file(), playback_exec(), privacy_exec(), record_exec(), retrydial_exec(), rpt_tele_thread(), s_streamwait3(), say_character_str_full(), say_digit_str_full(), say_phonetic_str_full(), sayfile(), ss_thread(), vm_authenticate(), wait_file(), and wait_for_winner().

00790 {
00791    struct ast_filestream *fs;
00792    struct ast_filestream *vfs=NULL;
00793    char fmt[256];
00794 
00795    fs = ast_openstream(chan, filename, preflang);
00796    if (fs)
00797       vfs = ast_openvstream(chan, filename, preflang);
00798    if (vfs)
00799       ast_log(LOG_DEBUG, "Ooh, found a video stream, too, format %s\n", ast_getformatname(vfs->fmt->format));
00800    if (fs){
00801       if (ast_applystream(chan, fs))
00802          return -1;
00803       if (vfs && ast_applystream(chan, vfs))
00804          return -1;
00805       ast_playstream(fs);
00806       if (vfs)
00807          ast_playstream(vfs);
00808       if (option_verbose > 2)
00809          ast_verbose(VERBOSE_PREFIX_3 "<%s> Playing '%s' (language '%s')\n", chan->name, filename, preflang ? preflang : "default");
00810 
00811       return 0;
00812    }
00813    ast_log(LOG_WARNING, "Unable to open %s (format %s): %s\n", filename, ast_getformatname_multiple(fmt, sizeof(fmt), chan->nativeformats), strerror(errno));
00814    return -1;
00815 }

off_t ast_tellstream ( struct ast_filestream fs  ) 

Tell where we are in a stream

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

Definition at line 694 of file file.c.

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

00695 {
00696    return fs->fmt->tell(fs);
00697 }

int ast_truncstream ( struct ast_filestream fs  ) 

Trunc stream at current location

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

Definition at line 689 of file file.c.

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

00690 {
00691    return fs->fmt->trunc(fs);
00692 }

int ast_waitstream ( struct ast_channel c,
const char *  breakon 
)

Waits for a stream to stop or digit to be pressed

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

Referenced by __login_exec(), agent_call(), app_exec(), ast_play_and_wait(), ast_say_date_da(), ast_say_date_de(), ast_say_date_en(), ast_say_date_fr(), ast_say_date_ge(), 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_from_now_ge(), 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_ge(), 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_ge(), ast_say_time_gr(), ast_say_time_nl(), ast_say_time_tw(), ast_stream_and_wait(), auth_exec(), check_availability(), check_beep(), common_exec(), conf_exec(), conf_run(), directory_exec(), gr_say_number_female(), handle_recordfile(), leave_voicemail(), page_exec(), park_exec(), parkandannounce_exec(), pbx_builtin_background(), pl_odtworz_plik(), play_and_wait(), play_file(), playback_exec(), privacy_exec(), record_exec(), retrydial_exec(), rpt_tele_thread(), s_streamwait3(), say_character_str_full(), say_digit_str_full(), say_phonetic_str_full(), saycharstr(), sayfile(), saynum(), send_morse(), send_tone_telemetry(), ss_thread(), vm_authenticate(), and wait_file().

01103 {
01104    return waitstream_core(c, breakon, NULL, NULL, 0, -1, -1, NULL);
01105 }

int ast_waitstream_exten ( struct ast_channel c,
const char *  context 
)

Waits for a stream to stop or digit matching a valid one digit exten to be pressed

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

Referenced by pbx_builtin_background().

01114 {
01115    /* Waitstream, with return in the case of a valid 1 digit extension */
01116    /* in the current or specified context being pressed */
01117 
01118    if (!context)
01119       context = c->context;
01120    return waitstream_core(c, NULL, NULL, NULL, 0,
01121       -1, -1, context);
01122 }

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

Same as waitstream but allows stream to be forwarded or rewound

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

Referenced by ast_control_streamfile().

01097 {
01098    return waitstream_core(c, breakon, forward, rewind, ms,
01099       -1 /* no audiofd */, -1 /* no cmdfd */, NULL /* no context */);
01100 }

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

Definition at line 1107 of file file.c.

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_ge(), 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(), s_streamwait3(), say_character_str_full(), say_digit_str_full(), and say_phonetic_str_full().

01108 {
01109    return waitstream_core(c, breakon, NULL, NULL, 0,
01110       audiofd, cmdfd, NULL /* no context */);
01111 }

struct ast_filestream* ast_writefile ( const char *  filename,
const char *  type,
const char *  comment,
int  flags,
int  check,
mode_t  mode 
) [read]

Starts writing a file

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

Referenced by __ast_play_and_record(), ast_monitor_start(), ast_writestream(), cli_audio_convert(), cli_audio_convert_deprecated(), dictate_exec(), handle_recordfile(), mixmonitor_thread(), record_exec(), recordthread(), and rpt().

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

int ast_writestream ( struct ast_filestream fs,
struct ast_frame f 
)

Writes a frame to a stream

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

Referenced by __ast_play_and_record(), __ast_read(), ast_write(), ast_writestream(), cli_audio_convert(), cli_audio_convert_deprecated(), dictate_exec(), handle_recordfile(), mixmonitor_thread(), record_exec(), recordthread(), and rpt().

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

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

References asprintf, and ast_config_AST_DATA_DIR.

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

00256 {
00257    char *fn = NULL;
00258 
00259    if (!strcmp(ext, "wav49"))
00260       ext = "WAV";
00261 
00262    if (filename[0] == '/')
00263       asprintf(&fn, "%s.%s", filename, ext);
00264    else
00265       asprintf(&fn, "%s/sounds/%s.%s",
00266          ast_config_AST_DATA_DIR, filename, ext);
00267    return fn;
00268 }

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

Definition at line 212 of file file.c.

References ast_log(), len, and LOG_WARNING.

Referenced by action_getvar(), ast_filehelper(), copy_file(), and iax2_register().

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

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

Definition at line 272 of file file.c.

References ext, and strsep().

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

00273 {
00274    char tmp[256];
00275    char *stringp = tmp, *ext;
00276 
00277    ast_copy_string(tmp, exts, sizeof(tmp));
00278    while ((ext = strsep(&stringp, "|"))) {
00279       if (!strcmp(ext, type))
00280          return 1;
00281    }
00282 
00283    return 0;
00284 }

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

References ACTION_EXISTS, ast_filehelper(), ast_log(), LOG_WARNING, and offset.

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

00485 {
00486    int res = -1;
00487    int langlen;   /* length of language string */
00488    const char *c = strrchr(filename, '/');
00489    int offset = c ? c - filename + 1 : 0; /* points right after the last '/' */
00490 
00491    if (preflang == NULL)
00492       preflang = "";
00493    langlen = strlen(preflang);
00494    
00495    if (buflen < langlen + strlen(filename) + 2) {
00496       ast_log(LOG_WARNING, "buffer too small\n");
00497       buf[0] = '\0'; /* set to empty */
00498       buf = alloca(langlen + strlen(filename) + 2);   /* room for everything */
00499    }
00500    if (buf == NULL)
00501       return 0;
00502    buf[0] = '\0';
00503    for (;;) {
00504       if (ast_language_is_prefix) { /* new layout */
00505          if (langlen) {
00506             strcpy(buf, preflang);
00507             buf[langlen] = '/';
00508             strcpy(buf + langlen + 1, filename);
00509          } else
00510             strcpy(buf, filename);  /* first copy the full string */
00511       } else { /* old layout */
00512          strcpy(buf, filename);  /* first copy the full string */
00513          if (langlen) {
00514             /* insert the language and suffix if needed */
00515             strcpy(buf + offset, preflang);
00516             sprintf(buf + offset + langlen, "/%s", filename + offset);
00517          }
00518       }
00519       res = ast_filehelper(buf, NULL, fmt, ACTION_EXISTS);
00520       if (res > 0)      /* found format */
00521          break;
00522       if (langlen == 0) /* no more formats */
00523          break;
00524       if (preflang[langlen] == '_') /* we are on the local suffix */
00525          langlen = 0;   /* try again with no language */
00526       else
00527          langlen = (c = strchr(preflang, '_')) ? c - preflang : 0;
00528    }
00529    return res;
00530 }

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

Definition at line 310 of file file.c.

References ast_log(), ast_module_ref(), f, ast_filestream::fmt, LOG_WARNING, ast_format::module, ast_format::name, ast_format::open, ast_format::rewrite, WRAP_OPEN, and WRAP_REWRITE.

Referenced by open_wrapper(), and rewrite_wrapper().

00311 {
00312    struct ast_format *f = s->fmt;
00313    int ret = -1;
00314 
00315    if (mode == WRAP_OPEN && f->open && f->open(s))
00316                 ast_log(LOG_WARNING, "Unable to open format %s\n", f->name);
00317    else if (mode == WRAP_REWRITE && f->rewrite && f->rewrite(s, comment))
00318                 ast_log(LOG_WARNING, "Unable to rewrite format %s\n", f->name);
00319    else {
00320       /* preliminary checks succeed. update usecount */
00321       ast_module_ref(f->module);
00322       ret = 0;
00323    }
00324         return ret;
00325 }

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

Definition at line 286 of file file.c.

References ast_calloc, ast_filestream::buf, ast_format::buf_size, ast_format::desc_size, ast_filestream::f, ast_filestream::fmt, ast_filestream::fr, ast_format::name, ast_filestream::private, s, and ast_frame::src.

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

00287 {
00288    struct ast_filestream *s;
00289 
00290    int l = sizeof(*s) + fmt->buf_size + fmt->desc_size;  /* total allocation size */
00291    if ( (s = ast_calloc(1, l)) == NULL)
00292       return NULL;
00293    s->fmt = fmt;
00294    s->f = bfile;
00295 
00296    if (fmt->desc_size)
00297       s->private = ((char *)(s+1)) + fmt->buf_size;
00298    if (fmt->buf_size)
00299       s->buf = (char *)(s+1);
00300    s->fr.src = fmt->name;
00301    return s;
00302 }

static int open_wrapper ( struct ast_filestream s  )  [static]

Definition at line 332 of file file.c.

References fn_wrapper(), and WRAP_OPEN.

Referenced by ast_filehelper(), and ast_readfile().

00333 {
00334    return fn_wrapper(s, NULL, WRAP_OPEN);
00335 }

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

Definition at line 327 of file file.c.

References fn_wrapper(), and WRAP_REWRITE.

Referenced by ast_writefile().

00328 {
00329    return fn_wrapper(s, comment, WRAP_REWRITE);
00330 }

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

Definition at line 1141 of file file.c.

References ast_cli(), ast_getformatname(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_format::exts, f, ast_format::format, FORMAT, FORMAT2, LOG_WARNING, ast_format::name, RESULT_SHOWUSAGE, and RESULT_SUCCESS.

01142 {
01143 #define FORMAT "%-10s %-10s %-20s\n"
01144 #define FORMAT2 "%-10s %-10s %-20s\n"
01145    struct ast_format *f;
01146    int count_fmt = 0;
01147 
01148    if (argc != 4)
01149       return RESULT_SHOWUSAGE;
01150    ast_cli(fd, FORMAT, "Format", "Name", "Extensions");
01151            
01152    if (AST_LIST_LOCK(&formats)) {
01153       ast_log(LOG_WARNING, "Unable to lock format list\n");
01154       return -1;
01155    }
01156 
01157    AST_LIST_TRAVERSE(&formats, f, list) {
01158       ast_cli(fd, FORMAT2, ast_getformatname(f->format), f->name, f->exts);
01159       count_fmt++;
01160    }
01161    AST_LIST_UNLOCK(&formats);
01162    ast_cli(fd, "%d file formats registered.\n", count_fmt);
01163    return RESULT_SUCCESS;
01164 #undef FORMAT
01165 #undef FORMAT2
01166 }

static int show_file_formats_deprecated ( int  fd,
int  argc,
char *  argv[] 
) [static]

Definition at line 1168 of file file.c.

References ast_cli(), ast_getformatname(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_format::exts, f, ast_format::format, FORMAT, FORMAT2, LOG_WARNING, ast_format::name, RESULT_SHOWUSAGE, and RESULT_SUCCESS.

01169 {
01170 #define FORMAT "%-10s %-10s %-20s\n"
01171 #define FORMAT2 "%-10s %-10s %-20s\n"
01172    struct ast_format *f;
01173    int count_fmt = 0;
01174    
01175    if (argc != 3)
01176       return RESULT_SHOWUSAGE;
01177    ast_cli(fd, FORMAT, "Format", "Name", "Extensions");
01178    
01179    if (AST_LIST_LOCK(&formats)) {
01180       ast_log(LOG_WARNING, "Unable to lock format list\n");
01181       return -1;
01182    }
01183    
01184    AST_LIST_TRAVERSE(&formats, f, list) {
01185       ast_cli(fd, FORMAT2, ast_getformatname(f->format), f->name, f->exts);
01186       count_fmt++;
01187    }
01188    AST_LIST_UNLOCK(&formats);
01189    ast_cli(fd, "%d file formats registered.\n", count_fmt);
01190    return RESULT_SUCCESS;
01191 #undef FORMAT
01192 #undef FORMAT2
01193 }

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

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


Variable Documentation

int ast_language_is_prefix

Definition at line 64 of file file.c.

Referenced by ast_readconfig().

struct ast_cli_entry cli_file[]

Initial value:

 {
   { { "core", "show", "file", "formats" },
   show_file_formats, "Displays file formats",
   show_file_formats_usage, NULL, &cli_show_file_formats_deprecated },
}

Definition at line 1204 of file file.c.

struct ast_cli_entry cli_show_file_formats_deprecated

Initial value:

 {
   { "show", "file", "formats" },
   show_file_formats_deprecated, NULL,
   NULL }

Definition at line 1199 of file file.c.

char show_file_formats_usage[]

Initial value:

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

Definition at line 1195 of file file.c.


Generated on Wed Aug 15 01:25:07 2007 for Asterisk - the Open Source PBX by  doxygen 1.5.3