Thu Jul 9 13:41:18 2009

Asterisk developer's documentation


file.c File Reference

Generic File Format Support. More...

#include "asterisk.h"
#include <dirent.h>
#include <sys/stat.h>
#include "asterisk/_private.h"
#include "asterisk/paths.h"
#include "asterisk/mod_format.h"
#include "asterisk/cli.h"
#include "asterisk/channel.h"
#include "asterisk/sched.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 "asterisk/astobj2.h"

Go to the source code of this file.

Data Structures

struct  formats

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  fsread_res { FSREAD_FAILURE, FSREAD_SUCCESS_SCHED, FSREAD_SUCCESS_NOSCHED }
enum  wrap_fn { WRAP_OPEN, WRAP_REWRITE }

Functions

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.
int ast_applystream (struct ast_channel *chan, struct ast_filestream *s)
 Applys a open stream to a channel.
int ast_closestream (struct ast_filestream *f)
 Closes a stream.
int ast_file_init (void)
int ast_filecopy (const char *filename, const char *filename2, const char *fmt)
 Copies a file.
int ast_filedelete (const char *filename, const char *fmt)
 Deletes a file.
int ast_fileexists (const char *filename, const char *fmt, const char *preflang)
 Checks for the existence of a given file.
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)
 Renames a file.
void ast_filestream_frame_freed (struct ast_frame *fr)
 destroy a filestream using an ast_frame as input
int ast_format_unregister (const char *name)
 Unregisters a file format.
static int ast_fsread_audio (const void *data)
static int ast_fsread_video (const void *data)
ast_filestreamast_openstream (struct ast_channel *chan, const char *filename, const char *preflang)
 Opens stream for use in seeking, playing.
ast_filestreamast_openstream_full (struct ast_channel *chan, const char *filename, const char *preflang, int asis)
 Opens stream for use in seeking, playing.
ast_filestreamast_openvstream (struct ast_channel *chan, const char *filename, const char *preflang)
 Opens stream for use in seeking, playing.
int ast_playstream (struct ast_filestream *s)
 Play a open stream on a channel.
static enum fsread_res ast_readaudio_callback (struct ast_filestream *s)
ast_filestreamast_readfile (const char *filename, const char *type, const char *comment, int flags, int check, mode_t mode)
 Starts reading from a file.
ast_frameast_readframe (struct ast_filestream *s)
 Read a frame from a filestream.
static enum fsread_res ast_readvideo_callback (struct ast_filestream *s)
int ast_seekstream (struct ast_filestream *fs, off_t sample_offset, int whence)
 Seeks into stream.
int ast_stopstream (struct ast_channel *tmp)
 Stops a stream.
int ast_stream_and_wait (struct ast_channel *chan, const char *file, const char *digits)
 stream file until digit If the file name is non-empty, try to play it.
int ast_stream_fastforward (struct ast_filestream *fs, off_t ms)
 Fast forward stream ms.
int ast_stream_rewind (struct ast_filestream *fs, off_t ms)
 Rewind stream ms.
int ast_streamfile (struct ast_channel *chan, const char *filename, const char *preflang)
 Streams a file.
off_t ast_tellstream (struct ast_filestream *fs)
 Tell where we are in a stream.
int ast_truncstream (struct ast_filestream *fs)
 Trunc stream at current location.
int ast_waitstream (struct ast_channel *c, const char *breakon)
 Waits for a stream to stop or digit to be pressed.
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.
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.
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)
 Starts writing a file.
int ast_writestream (struct ast_filestream *fs, struct ast_frame *f)
 Writes a frame to a stream.
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 fileexists_test (const char *filename, const char *fmt, const char *lang, char *buf, int buflen)
static void filestream_destructor (void *arg)
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 char * handle_cli_core_show_file_formats (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static int is_absolute_path (const char *filename)
static int open_wrapper (struct ast_filestream *s)
static int rewrite_wrapper (struct ast_filestream *s, const char *comment)
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 []


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 FORMAT2   "%-10s %-10s %-20s\n"

Referenced by __iax2_show_peers(), _sip_show_peers(), dahdi_show_channels(), dahdi_show_status(), dundi_show_mappings(), dundi_show_peers(), dundi_show_precache(), dundi_show_requests(), dundi_show_trans(), handle_cli_core_show_file_formats(), handle_cli_iax2_show_channels(), handle_cli_iax2_show_registry(), handle_cli_iax2_show_users(), handle_core_show_image_formats(), sip_show_channels(), sip_show_inuse(), sip_show_registry(), and sip_show_tcp().


Enumeration Type Documentation

enum file_action

Enumerator:
ACTION_EXISTS 
ACTION_DELETE 
ACTION_RENAME 
ACTION_OPEN 
ACTION_COPY 

Definition at line 389 of file file.c.

00389                  {
00390    ACTION_EXISTS = 1, /* return matching format if file exists, 0 otherwise */
00391    ACTION_DELETE, /* delete file, return 0 on success, -1 on error */
00392    ACTION_RENAME, /* rename file. return 0 on success, -1 on error */
00393    ACTION_OPEN,
00394    ACTION_COPY /* copy file. return 0 on success, -1 on error */
00395 };

enum fsread_res

Enumerator:
FSREAD_FAILURE 
FSREAD_SUCCESS_SCHED 
FSREAD_SUCCESS_NOSCHED 

Definition at line 702 of file file.c.

00702                 {
00703    FSREAD_FAILURE,
00704    FSREAD_SUCCESS_SCHED,
00705    FSREAD_SUCCESS_NOSCHED,
00706 };

enum wrap_fn

Enumerator:
WRAP_OPEN 
WRAP_REWRITE 

Definition at line 359 of file file.c.

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

Return values:
0 on success
-1 on failure

Definition at line 60 of file file.c.

References ast_calloc, ast_log(), AST_RWLIST_INSERT_HEAD, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_verb, ast_format::buf_size, ast_format::exts, f, ast_format::list, LOG_WARNING, ast_format::module, and ast_format::name.

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

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
Return values:
0 on success.
-1 on failure.

Definition at line 827 of file file.c.

References chan, and s.

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

00828 {
00829    s->owner = chan;
00830    return 0;
00831 }

int ast_closestream ( struct ast_filestream f  ) 

Closes a stream.

Parameters:
f filestream to close Close a playback or recording stream
Return values:
0 on success.
-1 on failure.

Definition at line 870 of file file.c.

References ao2_ref(), AST_FRFLAG_FROM_FILESTREAM, ast_test_flag, and f.

Referenced by __ast_play_and_record(), ast_filehelper(), ast_hangup(), ast_moh_files_next(), ast_monitor_start(), ast_monitor_stop(), ast_readfile(), ast_stopstream(), ast_writefile(), dictate_exec(), filestream_destructor(), gen_closestream(), handle_cli_file_convert(), handle_recordfile(), local_ast_moh_stop(), mixmonitor_ds_close_fs(), and moh_files_release().

00871 {
00872    if (ast_test_flag(&f->fr, AST_FRFLAG_FROM_FILESTREAM)) {
00873       /* If this flag is still set, it essentially means that the reference
00874        * count of f is non-zero. We can't destroy this filestream until
00875        * whatever is using the filestream's frame has finished.
00876        *
00877        * Since this was called, however, we need to remove the reference from
00878        * when this filestream was first allocated. That way, when the embedded
00879        * frame is freed, the refcount will reach 0 and we can finish destroying
00880        * this filestream properly.
00881        */
00882       ao2_ref(f, -1);
00883       return 0;
00884    }
00885    
00886    ao2_ref(f, -1);
00887    return 0;
00888 }

int ast_file_init ( void   ) 

Provided by file.c

Definition at line 1362 of file file.c.

References ast_cli_register_multiple(), and cli_file.

Referenced by main().

01363 {
01364    ast_cli_register_multiple(cli_file, sizeof(cli_file) / sizeof(struct ast_cli_entry));
01365    return 0;
01366 }

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

References ast_filehelper().

Referenced by copy_plain_file(), and vm_forwardoptions().

00919 {
00920    return ast_filehelper(filename, filename2, fmt, ACTION_COPY);
00921 }

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

References ACTION_DELETE, and ast_filehelper().

Referenced by __ast_play_and_record(), announce_thread(), ast_monitor_start(), ast_monitor_stop(), conf_free(), conf_run(), handle_cli_file_convert(), leave_voicemail(), play_mailbox_owner(), play_record_review(), setup_privacy_args(), vm_delete(), and vm_forwardoptions().

00909 {
00910    return ast_filehelper(filename, NULL, fmt, ACTION_DELETE);
00911 }

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

References buf, and fileexists_core().

Referenced by announce_thread(), app_exec(), ast_moh_files_next(), ast_monitor_start(), ast_monitor_stop(), common_exec(), eivr_comm(), forward_message(), invent_message(), leave_voicemail(), minivm_delete_exec(), play_greeting(), play_mailbox_owner(), play_message_callerid(), record_exec(), retrydial_exec(), say_character_str_full(), say_digit_str_full(), say_phonetic_str_full(), setup_privacy_args(), vm_intro(), vm_newuser(), vm_options(), and vm_tempgreeting().

00895 {
00896    char *buf;
00897    int buflen;
00898 
00899    if (preflang == NULL)
00900       preflang = "";
00901    buflen = strlen(preflang) + strlen(filename) + 4;  /* room for everything */
00902    buf = alloca(buflen);
00903    if (buf == NULL)
00904       return 0;
00905    return fileexists_core(filename, fmt, preflang, buf, buflen);
00906 }

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

References ACTION_DELETE, ACTION_EXISTS, ACTION_OPEN, ACTION_RENAME, ast_closestream(), AST_FORMAT_AUDIO_MASK, ast_free, ast_log(), AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_strdupa, build_filename(), chan, copy(), errno, ext, ast_format::exts, exts_compare(), f, ast_format::format, get_filestream(), ast_format::list, 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(), ast_openvstream(), and fileexists_test().

00407 {
00408    struct ast_format *f;
00409    int res = (action == ACTION_EXISTS) ? 0 : -1;
00410 
00411    AST_RWLIST_RDLOCK(&formats);
00412    /* Check for a specific format */
00413    AST_RWLIST_TRAVERSE(&formats, f, list) {
00414       char *stringp, *ext = NULL;
00415 
00416       if (fmt && !exts_compare(f->exts, fmt))
00417          continue;
00418 
00419       /* Look for a file matching the supported extensions.
00420        * The file must exist, and for OPEN, must match
00421        * one of the formats supported by the channel.
00422        */
00423       stringp = ast_strdupa(f->exts);  /* this is in the stack so does not need to be freed */
00424       while ( (ext = strsep(&stringp, "|")) ) {
00425          struct stat st;
00426          char *fn = build_filename(filename, ext);
00427 
00428          if (fn == NULL)
00429             continue;
00430 
00431          if ( stat(fn, &st) ) { /* file not existent */
00432             ast_free(fn);
00433             continue;
00434          }
00435          /* for 'OPEN' we need to be sure that the format matches
00436           * what the channel can process
00437           */
00438          if (action == ACTION_OPEN) {
00439             struct ast_channel *chan = (struct ast_channel *)arg2;
00440             FILE *bfile;
00441             struct ast_filestream *s;
00442 
00443             if ( !(chan->writeformat & f->format) &&
00444                  !(f->format & AST_FORMAT_AUDIO_MASK && fmt)) {
00445                ast_free(fn);
00446                continue;   /* not a supported format */
00447             }
00448             if ( (bfile = fopen(fn, "r")) == NULL) {
00449                ast_free(fn);
00450                continue;   /* cannot open file */
00451             }
00452             s = get_filestream(f, bfile);
00453             if (!s) {
00454                fclose(bfile);
00455                ast_free(fn);  /* cannot allocate descriptor */
00456                continue;
00457             }
00458             if (open_wrapper(s)) {
00459                ast_free(fn);
00460                ast_closestream(s);
00461                continue;   /* cannot run open on file */
00462             }
00463             /* ok this is good for OPEN */
00464             res = 1; /* found */
00465             s->lasttimeout = -1;
00466             s->fmt = f;
00467             s->trans = NULL;
00468             s->filename = NULL;
00469             if (s->fmt->format & AST_FORMAT_AUDIO_MASK) {
00470                if (chan->stream)
00471                   ast_closestream(chan->stream);
00472                chan->stream = s;
00473             } else {
00474                if (chan->vstream)
00475                   ast_closestream(chan->vstream);
00476                chan->vstream = s;
00477             }
00478             ast_free(fn);
00479             break;
00480          }
00481          switch (action) {
00482          case ACTION_OPEN:
00483             break;   /* will never get here */
00484 
00485          case ACTION_EXISTS:  /* return the matching format */
00486             res |= f->format;
00487             break;
00488 
00489          case ACTION_DELETE:
00490             if ( (res = unlink(fn)) )
00491                ast_log(LOG_WARNING, "unlink(%s) failed: %s\n", fn, strerror(errno));
00492             break;
00493 
00494          case ACTION_RENAME:
00495          case ACTION_COPY: {
00496             char *nfn = build_filename((const char *)arg2, ext);
00497             if (!nfn)
00498                ast_log(LOG_WARNING, "Out of memory\n");
00499             else {
00500                res = action == ACTION_COPY ? copy(fn, nfn) : rename(fn, nfn);
00501                if (res)
00502                   ast_log(LOG_WARNING, "%s(%s,%s) failed: %s\n",
00503                      action == ACTION_COPY ? "copy" : "rename",
00504                       fn, nfn, strerror(errno));
00505                ast_free(nfn);
00506             }
00507              }
00508             break;
00509 
00510          default:
00511             ast_log(LOG_WARNING, "Unknown helper %d\n", action);
00512          }
00513          ast_free(fn);
00514       }
00515    }
00516    AST_RWLIST_UNLOCK(&formats);
00517    return res;
00518 }

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

References ACTION_RENAME, and ast_filehelper().

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

00914 {
00915    return ast_filehelper(filename, filename2, fmt, ACTION_RENAME);
00916 }

void ast_filestream_frame_freed ( struct ast_frame fr  ) 

destroy a filestream using an ast_frame as input

This is a hack that is used also by the ast_trans_pvt and ast_dsp structures. When a structure contains an ast_frame pointer as one of its fields. It may be that the frame is still used after the outer structure is freed. This leads to invalid memory accesses. This function allows for us to hold off on destroying the ast_filestream until we are done using the ast_frame pointer that is part of it

Parameters:
fr The ast_frame that is part of an ast_filestream we wish to free.

Definition at line 1294 of file file.c.

References ao2_ref(), ast_clear_flag, AST_FRFLAG_FROM_FILESTREAM, and ast_filestream::fr.

Referenced by __frame_free().

01295 {
01296    struct ast_filestream *fs;
01297 
01298    ast_clear_flag(fr, AST_FRFLAG_FROM_FILESTREAM);
01299 
01300    fs = (struct ast_filestream *) (((char *) fr) - offsetof(struct ast_filestream, fr));
01301 
01302    ao2_ref(fs, -1);
01303 }

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.
Return values:
0 on success
-1 on failure to unregister

Definition at line 97 of file file.c.

References ast_free, ast_log(), AST_RWLIST_REMOVE_CURRENT, AST_RWLIST_TRAVERSE_SAFE_BEGIN, AST_RWLIST_TRAVERSE_SAFE_END, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_verb, ast_format::list, LOG_WARNING, and ast_format::name.

Referenced by unload_module().

00098 {
00099    struct ast_format *tmp;
00100    int res = -1;
00101 
00102    AST_RWLIST_WRLOCK(&formats);
00103    AST_RWLIST_TRAVERSE_SAFE_BEGIN(&formats, tmp, list) {
00104       if (!strcasecmp(name, tmp->name)) {
00105          AST_RWLIST_REMOVE_CURRENT(list);
00106          ast_free(tmp);
00107          res = 0;
00108       }
00109    }
00110    AST_RWLIST_TRAVERSE_SAFE_END;
00111    AST_RWLIST_UNLOCK(&formats);
00112 
00113    if (!res)
00114       ast_verb(2, "Unregistered format %s\n", name);
00115    else
00116       ast_log(LOG_WARNING, "Tried to unregister format %s, already unregistered\n", name);
00117 
00118    return res;
00119 }

static int ast_fsread_audio ( const void *  data  )  [static]

Definition at line 765 of file file.c.

References ast_readaudio_callback(), and FSREAD_SUCCESS_SCHED.

Referenced by ast_readaudio_callback().

00766 {
00767    struct ast_filestream *fs = (struct ast_filestream *)data;
00768    enum fsread_res res;
00769 
00770    res = ast_readaudio_callback(fs);
00771 
00772    if (res == FSREAD_SUCCESS_SCHED)
00773       return 1;
00774    
00775    return 0;
00776 }

static int ast_fsread_video ( const void *  data  )  [static]

Definition at line 814 of file file.c.

References ast_readvideo_callback(), and FSREAD_SUCCESS_SCHED.

Referenced by ast_readvideo_callback().

00815 {
00816    struct ast_filestream *fs = (struct ast_filestream *)data;
00817    enum fsread_res res;
00818 
00819    res = ast_readvideo_callback(fs);
00820 
00821    if (res == FSREAD_SUCCESS_SCHED)
00822       return 1;
00823    
00824    return 0;
00825 }

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

Opens stream for use in seeking, playing.

Parameters:
chan channel to work with
filename to use
preflang prefered language to use
Return values:
a ast_filestream pointer if it opens the file.
NULL on error.

Definition at line 613 of file file.c.

References ast_openstream_full(), and chan.

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

00614 {
00615    return ast_openstream_full(chan, filename, preflang, 0);
00616 }

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

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
Return values:
a ast_filestream pointer if it opens the file.
NULL on error.

Definition at line 618 of file file.c.

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

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

00619 {
00620    /* 
00621     * Use fileexists_core() to find a file in a compatible
00622     * language and format, set up a suitable translator,
00623     * and open the stream.
00624     */
00625    int fmts, res, buflen;
00626    char *buf;
00627 
00628    if (!asis) {
00629       /* do this first, otherwise we detect the wrong writeformat */
00630       ast_stopstream(chan);
00631       if (chan->generator)
00632          ast_deactivate_generator(chan);
00633    }
00634    if (preflang == NULL)
00635       preflang = "";
00636    buflen = strlen(preflang) + strlen(filename) + 4;
00637    buf = alloca(buflen);
00638    if (buf == NULL)
00639       return NULL;
00640    fmts = fileexists_core(filename, NULL, preflang, buf, buflen);
00641    if (fmts > 0)
00642       fmts &= AST_FORMAT_AUDIO_MASK;
00643    if (fmts < 1) {
00644       ast_log(LOG_WARNING, "File %s does not exist in any format\n", filename);
00645       return NULL;
00646    }
00647    chan->oldwriteformat = chan->writeformat;
00648    /* Set the channel to a format we can work with */
00649    res = ast_set_write_format(chan, fmts);
00650    res = ast_filehelper(buf, chan, NULL, ACTION_OPEN);
00651    if (res >= 0)
00652       return chan->stream;
00653    return NULL;
00654 }

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

Opens stream for use in seeking, playing.

Parameters:
chan channel to work with
filename to use
preflang prefered language to use
Return values:
a ast_filestream pointer if it opens the file.
NULL on error.

Definition at line 656 of file file.c.

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

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

00657 {
00658    /* As above, but for video. But here we don't have translators
00659     * so we must enforce a format.
00660     */
00661    unsigned int format;
00662    char *buf;
00663    int buflen;
00664 
00665    if (preflang == NULL)
00666       preflang = "";
00667    buflen = strlen(preflang) + strlen(filename) + 4;
00668    buf = alloca(buflen);
00669    if (buf == NULL)
00670       return NULL;
00671 
00672    for (format = AST_FORMAT_AUDIO_MASK + 1; format <= AST_FORMAT_VIDEO_MASK; format = format << 1) {
00673       int fd;
00674       const char *fmt;
00675 
00676       if (!(chan->nativeformats & format))
00677          continue;
00678       fmt = ast_getformatname(format);
00679       if ( fileexists_core(filename, fmt, preflang, buf, buflen) < 1)   /* no valid format */
00680          continue;
00681       fd = ast_filehelper(buf, chan, fmt, ACTION_OPEN);
00682       if (fd >= 0)
00683          return chan->vstream;
00684       ast_log(LOG_WARNING, "File %s has video but couldn't be opened\n", filename);
00685    }
00686    return NULL;
00687 }

int ast_playstream ( struct ast_filestream s  ) 

Play a open stream on a channel.

Parameters:
s filestream to play
Return values:
0 on success.
-1 on failure.

Definition at line 833 of file file.c.

References AST_FORMAT_AUDIO_MASK, ast_readaudio_callback(), ast_readvideo_callback(), FSREAD_FAILURE, and s.

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

00834 {
00835    enum fsread_res res;
00836 
00837    if (s->fmt->format & AST_FORMAT_AUDIO_MASK)
00838       res = ast_readaudio_callback(s);
00839    else
00840       res = ast_readvideo_callback(s);
00841 
00842    return (res == FSREAD_FAILURE) ? -1 : 0;
00843 }

static enum fsread_res ast_readaudio_callback ( struct ast_filestream s  )  [static]

Definition at line 710 of file file.c.

References ao2_ref(), ast_format_rate(), AST_FRFLAG_FROM_FILESTREAM, ast_frfree, ast_fsread_audio(), ast_log(), ast_sched_add(), ast_set_flag, ast_settimeout(), ast_write(), FSREAD_FAILURE, FSREAD_SUCCESS_NOSCHED, FSREAD_SUCCESS_SCHED, LOG_WARNING, and s.

Referenced by ast_fsread_audio(), and ast_playstream().

00711 {
00712    int whennext = 0;
00713 
00714    while (!whennext) {
00715       struct ast_frame *fr;
00716       
00717       if (s->orig_chan_name && strcasecmp(s->owner->name, s->orig_chan_name))
00718          goto return_failure;
00719       
00720       fr = s->fmt->read(s, &whennext);
00721       if (fr) {
00722          ast_set_flag(fr, AST_FRFLAG_FROM_FILESTREAM);
00723          ao2_ref(s, +1);
00724       }
00725       if (!fr /* stream complete */ || ast_write(s->owner, fr) /* error writing */) {
00726          if (fr) {
00727             ast_log(LOG_WARNING, "Failed to write frame\n");
00728             ast_frfree(fr);
00729          }
00730          goto return_failure;
00731       } 
00732       if (fr) {
00733          ast_frfree(fr);
00734       }
00735    }
00736    if (whennext != s->lasttimeout) {
00737 #ifdef HAVE_DAHDI
00738       if (s->owner->timingfd > -1) {
00739          int dahdi_timer_samples = whennext;
00740          int rate;
00741          /* whennext is in samples, but DAHDI timers operate in 8 kHz samples. */
00742          if ((rate = ast_format_rate(s->fmt->format)) != 8000) {
00743             float factor;
00744             factor = ((float) rate) / ((float) 8000.0); 
00745             dahdi_timer_samples = (int) ( ((float) dahdi_timer_samples) / factor );
00746          }
00747          ast_settimeout(s->owner, dahdi_timer_samples, ast_fsread_audio, s);
00748       } else
00749 #endif      
00750          s->owner->streamid = ast_sched_add(s->owner->sched, 
00751             whennext / (ast_format_rate(s->fmt->format) / 1000), ast_fsread_audio, s);
00752       s->lasttimeout = whennext;
00753       return FSREAD_SUCCESS_NOSCHED;
00754    }
00755    return FSREAD_SUCCESS_SCHED;
00756 
00757 return_failure:
00758    s->owner->streamid = -1;
00759 #ifdef HAVE_DAHDI
00760    ast_settimeout(s->owner, 0, NULL, NULL);
00761 #endif         
00762    return FSREAD_FAILURE;
00763 }

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

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.
Return values:
a struct ast_filestream on success.
NULL on failure.

Definition at line 954 of file file.c.

References ast_closestream(), ast_free, ast_log(), AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_strdup, build_filename(), errno, ast_format::exts, exts_compare(), f, ast_filestream::filename, ast_filestream::flags, ast_filestream::fmt, get_filestream(), LOG_WARNING, ast_filestream::mode, open_wrapper(), ast_filestream::trans, and ast_filestream::vfs.

Referenced by __ast_play_and_record(), and handle_cli_file_convert().

00955 {
00956    FILE *bfile;
00957    struct ast_format *f;
00958    struct ast_filestream *fs = NULL;
00959    char *fn;
00960    int format_found = 0;   
00961 
00962    AST_RWLIST_RDLOCK(&formats);
00963 
00964    AST_RWLIST_TRAVERSE(&formats, f, list) {
00965       fs = NULL;
00966       if (!exts_compare(f->exts, type))
00967          continue;
00968       else 
00969          format_found = 1;
00970 
00971       fn = build_filename(filename, type);
00972       errno = 0;
00973       bfile = fopen(fn, "r");
00974 
00975       if (!bfile || (fs = get_filestream(f, bfile)) == NULL || open_wrapper(fs) ) {
00976          ast_log(LOG_WARNING, "Unable to open %s\n", fn);
00977          if (fs) {
00978             ast_closestream(fs);
00979          }
00980          fs = NULL;
00981          bfile = NULL;
00982          ast_free(fn);
00983          break;            
00984       }
00985       /* found it */
00986       fs->trans = NULL;
00987       fs->fmt = f;
00988       fs->flags = flags;
00989       fs->mode = mode;
00990       fs->filename = ast_strdup(filename);
00991       fs->vfs = NULL;
00992       break;
00993    }
00994 
00995    AST_RWLIST_UNLOCK(&formats);
00996    if (!format_found)
00997       ast_log(LOG_WARNING, "No such format '%s'\n", type);
00998 
00999    return fs;
01000 }

struct ast_frame* ast_readframe ( struct ast_filestream s  ) 

Read a frame from a filestream.

Parameters:
s ast_filestream to act on
Returns:
a frame.
Return values:
NULL if read failed.

Definition at line 689 of file file.c.

References ao2_ref(), AST_FRFLAG_FROM_FILESTREAM, ast_set_flag, f, and s.

Referenced by __ast_play_and_record(), dictate_exec(), gen_readframe(), handle_cli_file_convert(), and moh_files_readframe().

00690 {
00691    struct ast_frame *f = NULL;
00692    int whennext = 0; 
00693    if (s && s->fmt)
00694       f = s->fmt->read(s, &whennext);
00695    if (f) {
00696       ast_set_flag(f, AST_FRFLAG_FROM_FILESTREAM);
00697       ao2_ref(s, +1);
00698    }
00699    return f;
00700 }

static enum fsread_res ast_readvideo_callback ( struct ast_filestream s  )  [static]

Definition at line 780 of file file.c.

References ao2_ref(), ast_format_rate(), AST_FRFLAG_FROM_FILESTREAM, ast_frfree, ast_fsread_video(), ast_log(), ast_sched_add(), ast_set_flag, ast_write(), FSREAD_FAILURE, FSREAD_SUCCESS_NOSCHED, FSREAD_SUCCESS_SCHED, LOG_WARNING, and s.

Referenced by ast_fsread_video(), and ast_playstream().

00781 {
00782    int whennext = 0;
00783 
00784    while (!whennext) {
00785       struct ast_frame *fr = s->fmt->read(s, &whennext);
00786       if (fr) {
00787          ast_set_flag(fr, AST_FRFLAG_FROM_FILESTREAM);
00788          ao2_ref(s, +1);
00789       }
00790       if (!fr /* stream complete */ || ast_write(s->owner, fr) /* error writing */) {
00791          if (fr) {
00792             ast_log(LOG_WARNING, "Failed to write frame\n");
00793             ast_frfree(fr);
00794          }
00795          s->owner->vstreamid = -1;
00796          return FSREAD_FAILURE;
00797       }
00798       if (fr) {
00799          ast_frfree(fr);
00800       }
00801    }
00802 
00803    if (whennext != s->lasttimeout) {
00804       s->owner->vstreamid = ast_sched_add(s->owner->sched, 
00805          whennext / (ast_format_rate(s->fmt->format) / 1000), 
00806          ast_fsread_video, s);
00807       s->lasttimeout = whennext;
00808       return FSREAD_SUCCESS_NOSCHED;
00809    }
00810 
00811    return FSREAD_SUCCESS_SCHED;
00812 }

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
Return values:
0 on success.
-1 on failure.

Definition at line 845 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(), dictate_exec(), handle_getoption(), handle_recordfile(), handle_streamfile(), and speech_streamfile().

00846 {
00847    return fs->fmt->seek(fs, sample_offset, whence);
00848 }

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

Return values:
0 always
Note:
The channel does not need to be locked before calling this function.

Definition at line 121 of file file.c.

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

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_enumeration_full_he(), 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_hu(), 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_th(), ast_say_number_full_tw(), background_detect_exec(), builtin_blindtransfer(), conf_exec(), conf_run(), directory_exec(), handle_getoption(), handle_speechrecognize(), handle_streamfile(), ices_exec(), ivr_dispatch(), minivm_greet_exec(), mp3_exec(), NBScat_exec(), parkandannounce_exec(), pbx_builtin_background(), pl_odtworz_plik(), play_file(), play_mailbox_owner(), playback_exec(), read_exec(), readexten_exec(), recordthread(), rpt_tele_thread(), s_streamwait3(), say_character_str_full(), say_digit_str_full(), say_phonetic_str_full(), saycharstr(), saydigits(), sayfile(), saynum(), select_item_seq(), send_morse(), send_tone_telemetry(), send_waveform_to_channel(), speech_background(), vm_authenticate(), vm_execmain(), wait_for_winner(), waitstream_core(), and zapateller_exec().

00122 {
00123    ast_channel_lock(tmp);
00124 
00125    /* Stop a running stream if there is one */
00126    if (tmp->stream) {
00127       ast_closestream(tmp->stream);
00128       tmp->stream = NULL;
00129       if (tmp->oldwriteformat && ast_set_write_format(tmp, tmp->oldwriteformat))
00130          ast_log(LOG_WARNING, "Unable to restore format back to %d\n", tmp->oldwriteformat);
00131    }
00132    /* Stop the video stream too */
00133    if (tmp->vstream != NULL) {
00134       ast_closestream(tmp->vstream);
00135       tmp->vstream = NULL;
00136    }
00137 
00138    ast_channel_unlock(tmp);
00139 
00140    return 0;
00141 }

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

stream file until digit If the file name is non-empty, try to play it.

Note:
If digits == "" then we can simply check for non-zero.
Returns:
0 if success.
Return values:
-1 if error.
digit if interrupted by a digit.

Definition at line 1310 of file file.c.

References ast_streamfile(), ast_strlen_zero(), ast_waitstream(), chan, and ast_channel::language.

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

01311 {
01312    int res = 0;
01313    if (!ast_strlen_zero(file)) {
01314       res = ast_streamfile(chan, file, chan->language);
01315       if (!res) {
01316          res = ast_waitstream(chan, digits);
01317       }
01318    }
01319    return res;
01320 } 

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
Return values:
0 on success.
-1 on failure.

Definition at line 860 of file file.c.

References ast_seekstream(), and DEFAULT_SAMPLES_PER_MS.

Referenced by waitstream_core().

00861 {
00862    return ast_seekstream(fs, ms * DEFAULT_SAMPLES_PER_MS, SEEK_CUR);
00863 }

int ast_stream_rewind ( struct ast_filestream fs,
off_t  ms 
)

Rewind stream ms.

Parameters:
fs filestream to act on
ms milliseconds to move
Return values:
0 on success.
-1 on failure.

Definition at line 865 of file file.c.

References ast_seekstream(), and DEFAULT_SAMPLES_PER_MS.

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

00866 {
00867    return ast_seekstream(fs, -ms * DEFAULT_SAMPLES_PER_MS, SEEK_CUR);
00868 }

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.
Return values:
0 on success.
-1 on failure.

Definition at line 923 of file file.c.

References ast_applystream(), ast_debug, AST_FLAG_MASQ_NOSTREAM, ast_getformatname(), ast_getformatname_multiple(), ast_log(), ast_openstream(), ast_openvstream(), ast_playstream(), ast_strdup, ast_test_flag, ast_verb, chan, errno, ast_filestream::fmt, ast_format::format, LOG_WARNING, ast_channel::name, ast_channel::nativeformats, ast_filestream::orig_chan_name, ast_filestream::vfs, and ast_channel::writeformat.

Referenced by action_bridge(), agent_call(), announce_thread(), 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_he(), ast_say_date_hu(), ast_say_date_nl(), ast_say_date_th(), 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_from_now_he(), ast_say_datetime_gr(), ast_say_datetime_he(), ast_say_datetime_nl(), ast_say_datetime_pt(), ast_say_datetime_th(), ast_say_datetime_tw(), ast_say_enumeration_full_da(), ast_say_enumeration_full_de(), ast_say_enumeration_full_en(), ast_say_enumeration_full_he(), 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_hu(), 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_th(), 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_hu(), ast_say_time_nl(), ast_say_time_tw(), ast_stream_and_wait(), background_detect_exec(), bridge_exec(), check_availability(), check_beep(), common_exec(), conf_exec(), conf_run(), dial_exec_full(), do_directory(), find_conf_realtime(), forward_message(), gr_say_number_female(), handle_recordfile(), invent_message(), leave_voicemail(), login_exec(), minivm_greet_exec(), page_exec(), park_exec(), parkandannounce_exec(), pbx_builtin_background(), pl_odtworz_plik(), play_and_wait(), play_file(), play_greeting(), play_record_review(), playback_exec(), privacy_exec(), readexten_exec(), retrydial_exec(), rpt_tele_thread(), s_streamwait3(), say_character_str_full(), say_digit_str_full(), say_phonetic_str_full(), sayfile(), select_item_menu(), setup_privacy_args(), ss_thread(), vm_authenticate(), wait_file(), and wait_for_winner().

00924 {
00925    struct ast_filestream *fs;
00926    struct ast_filestream *vfs=NULL;
00927    char fmt[256];
00928 
00929    fs = ast_openstream(chan, filename, preflang);
00930    if (fs)
00931       vfs = ast_openvstream(chan, filename, preflang);
00932    if (vfs) {
00933       ast_debug(1, "Ooh, found a video stream, too, format %s\n", ast_getformatname(vfs->fmt->format));
00934    }
00935    if (fs){
00936       int res;
00937       if (ast_test_flag(chan, AST_FLAG_MASQ_NOSTREAM))
00938          fs->orig_chan_name = ast_strdup(chan->name);
00939       if (ast_applystream(chan, fs))
00940          return -1;
00941       if (vfs && ast_applystream(chan, vfs))
00942          return -1;
00943       res = ast_playstream(fs);
00944       if (!res && vfs)
00945          res = ast_playstream(vfs);
00946       ast_verb(3, "<%s> Playing '%s.%s' (language '%s')\n", chan->name, filename, ast_getformatname(chan->writeformat), preflang ? preflang : "default");
00947 
00948       return res;
00949    }
00950    ast_log(LOG_WARNING, "Unable to open %s (format %s): %s\n", filename, ast_getformatname_multiple(fmt, sizeof(fmt), chan->nativeformats), strerror(errno));
00951    return -1;
00952 }

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

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

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

00856 {
00857    return fs->fmt->tell(fs);
00858 }

int ast_truncstream ( struct ast_filestream fs  ) 

Trunc stream at current location.

Parameters:
fs filestream to act on
Return values:
0 on success.
-1 on failure.

Definition at line 850 of file file.c.

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

Referenced by __ast_play_and_record(), and handle_recordfile().

00851 {
00852    return fs->fmt->trunc(fs);
00853 }

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,
Return values:
0 if the stream finishes
the character if it was interrupted,
-1 on error

Definition at line 1272 of file file.c.

References waitstream_core().

Referenced by action_bridge(), agent_call(), announce_thread(), 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_he(), ast_say_date_hu(), ast_say_date_nl(), ast_say_date_th(), 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_from_now_he(), ast_say_datetime_gr(), ast_say_datetime_he(), ast_say_datetime_nl(), ast_say_datetime_pt(), ast_say_datetime_th(), ast_say_datetime_tw(), ast_say_enumeration_full_da(), ast_say_enumeration_full_de(), ast_say_enumeration_full_en(), ast_say_enumeration_full_he(), 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_hu(), 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_th(), ast_say_number_full_tw(), ast_say_time_de(), ast_say_time_en(), ast_say_time_ge(), ast_say_time_gr(), ast_say_time_he(), ast_say_time_hu(), ast_say_time_nl(), ast_say_time_tw(), ast_stream_and_wait(), bridge_exec(), check_availability(), check_beep(), common_exec(), conf_exec(), conf_run(), dial_exec_full(), directory_exec(), find_conf_realtime(), gr_say_number_female(), handle_recordfile(), invent_message(), leave_voicemail(), login_exec(), minivm_greet_exec(), page_exec(), park_exec(), parkandannounce_exec(), pbx_builtin_background(), pl_odtworz_plik(), play_and_wait(), play_file(), play_greeting(), play_record_review(), playback_exec(), privacy_exec(), retrydial_exec(), rpt_tele_thread(), s_streamwait3(), say_character_str_full(), say_digit_str_full(), say_phonetic_str_full(), saycharstr(), saydigits(), sayfile(), saynum(), select_item_menu(), send_morse(), send_tone_telemetry(), setup_privacy_args(), ss_thread(), vm_authenticate(), and wait_file().

01273 {
01274    return waitstream_core(c, breakon, NULL, NULL, 0, -1, -1, NULL);
01275 }

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,
Return values:
0 if the stream finishes.
the character if it was interrupted.
-1 on error.

Definition at line 1283 of file file.c.

References ast_channel::context, and waitstream_core().

Referenced by pbx_builtin_background().

01284 {
01285    /* Waitstream, with return in the case of a valid 1 digit extension */
01286    /* in the current or specified context being pressed */
01287 
01288    if (!context)
01289       context = c->context;
01290    return waitstream_core(c, NULL, NULL, NULL, 0,
01291       -1, -1, context);
01292 }

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,
Return values:
0 if the stream finishes.
the character if it was interrupted.
-1 on error.

Definition at line 1266 of file file.c.

References waitstream_core().

Referenced by ast_control_streamfile().

01267 {
01268    return waitstream_core(c, breakon, forward, rewind, ms,
01269       -1 /* no audiofd */, -1 /* no cmdfd */, NULL /* no context */);
01270 }

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

Same as waitstream, but with audio output to fd and monitored fd checking.

Returns:
1 if monfd is ready for reading

Definition at line 1277 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_enumeration_full_he(), 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_hu(), 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_th(), 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().

01278 {
01279    return waitstream_core(c, breakon, NULL, NULL, 0,
01280       audiofd, cmdfd, NULL /* no context */);
01281 }

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

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.
Return values:
a struct ast_filestream on success.
NULL on failure.

Definition at line 1002 of file file.c.

References ast_closestream(), ast_free, ast_log(), ast_opt_cache_record_files, AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_strdup, ast_strdupa, buf, build_filename(), errno, ast_format::exts, exts_compare(), f, ast_filestream::filename, ast_filestream::flags, ast_filestream::fmt, get_filestream(), LOG_WARNING, ast_filestream::mode, ast_filestream::realfilename, record_cache_dir, rewrite_wrapper(), ast_format::seek, ast_filestream::trans, and ast_filestream::vfs.

Referenced by __ast_play_and_record(), ast_monitor_start(), ast_writestream(), dictate_exec(), handle_cli_file_convert(), handle_recordfile(), mixmonitor_thread(), and recordthread().

01003 {
01004    int fd, myflags = 0;
01005    /* compiler claims this variable can be used before initialization... */
01006    FILE *bfile = NULL;
01007    struct ast_format *f;
01008    struct ast_filestream *fs = NULL;
01009    char *buf = NULL;
01010    size_t size = 0;
01011    int format_found = 0;
01012 
01013    AST_RWLIST_RDLOCK(&formats);
01014 
01015    /* set the O_TRUNC flag if and only if there is no O_APPEND specified */
01016    /* We really can't use O_APPEND as it will break WAV header updates */
01017    if (flags & O_APPEND) { 
01018       flags &= ~O_APPEND;
01019    } else {
01020       myflags = O_TRUNC;
01021    }
01022    
01023    myflags |= O_WRONLY | O_CREAT;
01024 
01025    /* XXX need to fix this - we should just do the fopen,
01026     * not open followed by fdopen()
01027     */
01028    AST_RWLIST_TRAVERSE(&formats, f, list) {
01029       char *fn, *orig_fn = NULL;
01030       if (fs)
01031          break;
01032 
01033       if (!exts_compare(f->exts, type))
01034          continue;
01035       else
01036          format_found = 1;
01037 
01038       fn = build_filename(filename, type);
01039       fd = open(fn, flags | myflags, mode);
01040       if (fd > -1) {
01041          /* fdopen() the resulting file stream */
01042          bfile = fdopen(fd, ((flags | myflags) & O_RDWR) ? "w+" : "w");
01043          if (!bfile) {
01044             ast_log(LOG_WARNING, "Whoa, fdopen failed: %s!\n", strerror(errno));
01045             close(fd);
01046             fd = -1;
01047          }
01048       }
01049       
01050       if (ast_opt_cache_record_files && (fd > -1)) {
01051          char *c;
01052 
01053          fclose(bfile); /* this also closes fd */
01054          /*
01055            We touch orig_fn just as a place-holder so other things (like vmail) see the file is there.
01056            What we are really doing is writing to record_cache_dir until we are done then we will mv the file into place.
01057          */
01058          orig_fn = ast_strdupa(fn);
01059          for (c = fn; *c; c++)
01060             if (*c == '/')
01061                *c = '_';
01062 
01063          size = strlen(fn) + strlen(record_cache_dir) + 2;
01064          buf = alloca(size);
01065          strcpy(buf, record_cache_dir);
01066          strcat(buf, "/");
01067          strcat(buf, fn);
01068          ast_free(fn);
01069          fn = buf;
01070          fd = open(fn, flags | myflags, mode);
01071          if (fd > -1) {
01072             /* fdopen() the resulting file stream */
01073             bfile = fdopen(fd, ((flags | myflags) & O_RDWR) ? "w+" : "w");
01074             if (!bfile) {
01075                ast_log(LOG_WARNING, "Whoa, fdopen failed: %s!\n", strerror(errno));
01076                close(fd);
01077                fd = -1;
01078             }
01079          }
01080       }
01081       if (fd > -1) {
01082          errno = 0;
01083          fs = get_filestream(f, bfile);
01084          if (!fs || rewrite_wrapper(fs, comment)) {
01085             ast_log(LOG_WARNING, "Unable to rewrite %s\n", fn);
01086             close(fd);
01087             if (orig_fn) {
01088                unlink(fn);
01089                unlink(orig_fn);
01090             }
01091             if (fs) {
01092                ast_closestream(fs);
01093                fs = NULL;
01094             }
01095             continue;
01096          }
01097          fs->trans = NULL;
01098          fs->fmt = f;
01099          fs->flags = flags;
01100          fs->mode = mode;
01101          if (orig_fn) {
01102             fs->realfilename = ast_strdup(orig_fn);
01103             fs->filename = ast_strdup(fn);
01104          } else {
01105             fs->realfilename = NULL;
01106             fs->filename = ast_strdup(filename);
01107          }
01108          fs->vfs = NULL;
01109          /* If truncated, we'll be at the beginning; if not truncated, then append */
01110          f->seek(fs, 0, SEEK_END);
01111       } else if (errno != EEXIST) {
01112          ast_log(LOG_WARNING, "Unable to open file %s: %s\n", fn, strerror(errno));
01113          if (orig_fn)
01114             unlink(orig_fn);
01115       }
01116       /* if buf != NULL then fn is already free and pointing to it */
01117       if (!buf)
01118          ast_free(fn);
01119    }
01120 
01121    AST_RWLIST_UNLOCK(&formats);
01122 
01123    if (!format_found)
01124       ast_log(LOG_WARNING, "No such format '%s'\n", type);
01125 
01126    return fs;
01127 }

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
Return values:
0 on success.
-1 on failure.

Definition at line 143 of file file.c.

References ast_debug, AST_FORMAT_AUDIO_MASK, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_frfree, ast_getformatname(), AST_LIST_NEXT, ast_log(), ast_translate(), ast_translator_build_path(), ast_translator_free_path(), ast_writefile(), ast_writestream(), f, ast_filestream::filename, ast_filestream::flags, ast_filestream::fmt, ast_format::format, ast_frame::frame_list, ast_filestream::lastwriteformat, LOG_WARNING, ast_filestream::mode, ast_format::name, ast_filestream::trans, type, ast_filestream::vfs, and ast_format::write.

Referenced by __ast_play_and_record(), __ast_read(), ast_write(), ast_writestream(), dictate_exec(), handle_cli_file_convert(), handle_recordfile(), mixmonitor_thread(), and recordthread().

00144 {
00145    int res = -1;
00146    int alt = 0;
00147    if (f->frametype == AST_FRAME_VIDEO) {
00148       if (fs->fmt->format & AST_FORMAT_AUDIO_MASK) {
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             ast_debug(1, "Opened video output file\n");
00154          }
00155          if (fs->vfs)
00156             return ast_writestream(fs->vfs, f);
00157          /* else ignore */
00158          return 0;            
00159       } else {
00160          /* Might / might not have mark set */
00161          alt = 1;
00162       }
00163    } else if (f->frametype != AST_FRAME_VOICE) {
00164       ast_log(LOG_WARNING, "Tried to write non-voice frame\n");
00165       return -1;
00166    }
00167    if (((fs->fmt->format | alt) & f->subclass) == f->subclass) {
00168       res =  fs->fmt->write(fs, f);
00169       if (res < 0) 
00170          ast_log(LOG_WARNING, "Natural write failed\n");
00171       else if (res > 0)
00172          ast_log(LOG_WARNING, "Huh??\n");
00173    } else {
00174       /* XXX If they try to send us a type of frame that isn't the normal frame, and isn't
00175              the one we've setup a translator for, we do the "wrong thing" XXX */
00176       if (fs->trans && f->subclass != fs->lastwriteformat) {
00177          ast_translator_free_path(fs->trans);
00178          fs->trans = NULL;
00179       }
00180       if (!fs->trans) 
00181          fs->trans = ast_translator_build_path(fs->fmt->format, f->subclass);
00182       if (!fs->trans)
00183          ast_log(LOG_WARNING, "Unable to translate to format %s, source format %s\n",
00184             fs->fmt->name, ast_getformatname(f->subclass));
00185       else {
00186          struct ast_frame *trf;
00187          fs->lastwriteformat = f->subclass;
00188          /* Get the translated frame but don't consume the original in case they're using it on another stream */
00189          if ((trf = ast_translate(fs->trans, f, 0))) {
00190             struct ast_frame *cur;
00191 
00192             /* the translator may have returned multiple frames, so process them */
00193             for (cur = trf; cur; cur = AST_LIST_NEXT(cur, frame_list)) {
00194                if ((res = fs->fmt->write(fs, trf))) {
00195                   ast_log(LOG_WARNING, "Translated frame write failed\n");
00196                   break;
00197                }
00198             }
00199             ast_frfree(trf);
00200          } else {
00201             res = 0;
00202          }
00203       }
00204    }
00205    return res;
00206 }

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

References asprintf, ast_config_AST_DATA_DIR, ast_log(), errno, and LOG_WARNING.

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

00252 {
00253    char *fn = NULL;
00254 
00255    if (!strcmp(ext, "wav49"))
00256       ext = "WAV";
00257 
00258    if (filename[0] == '/') {
00259       if (asprintf(&fn, "%s.%s", filename, ext) < 0) {
00260          ast_log(LOG_WARNING, "asprintf() failed: %s\n", strerror(errno));
00261          fn = NULL;
00262       }
00263    } else {
00264       if (asprintf(&fn, "%s/sounds/%s.%s",
00265               ast_config_AST_DATA_DIR, filename, ext) < 0) {
00266          ast_log(LOG_WARNING, "asprintf() failed: %s\n", strerror(errno));
00267          fn = NULL;
00268       }
00269    }
00270    return fn;
00271 }

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

Definition at line 208 of file file.c.

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

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

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

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

Definition at line 275 of file file.c.

References ast_copy_string(), ext, and strsep().

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

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

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

References ast_strdupa, ast_strlen_zero(), DEFAULT_LANGUAGE, fileexists_test(), and strsep().

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

00564 {
00565    int res = -1;
00566    char *lang = NULL;
00567 
00568    if (buf == NULL) {
00569       return -1;
00570    }
00571 
00572    /* We try languages in the following order:
00573     *    preflang (may include dialect)
00574     *    lang (preflang without dialect - if any)
00575     *    <none>
00576     *    default (unless the same as preflang or lang without dialect)
00577     */
00578 
00579    /* Try preferred language */
00580    if (!ast_strlen_zero(preflang)) {
00581       /* try the preflang exactly as it was requested */
00582       if ((res = fileexists_test(filename, fmt, preflang, buf, buflen)) > 0) {
00583          return res;
00584       } else {
00585          /* try without a dialect */
00586          char *postfix = NULL;
00587          postfix = lang = ast_strdupa(preflang);
00588 
00589          strsep(&postfix, "_");
00590          if (postfix) {
00591             if ((res = fileexists_test(filename, fmt, lang, buf, buflen)) > 0) {
00592                return res;
00593             }
00594          }
00595       }
00596    }
00597 
00598    /* Try without any language */
00599    if ((res = fileexists_test(filename, fmt, NULL, buf, buflen)) > 0) {
00600       return res;
00601    }
00602 
00603    /* Finally try the default language unless it was already tried before */
00604    if ((ast_strlen_zero(preflang) || strcmp(preflang, DEFAULT_LANGUAGE)) && (ast_strlen_zero(lang) || strcmp(lang, DEFAULT_LANGUAGE))) {
00605       if ((res = fileexists_test(filename, fmt, DEFAULT_LANGUAGE, buf, buflen)) > 0) {
00606          return res;
00607       }
00608    }
00609 
00610    return 0;
00611 }

static int fileexists_test ( const char *  filename,
const char *  fmt,
const char *  lang,
char *  buf,
int  buflen 
) [static]

Definition at line 525 of file file.c.

References ACTION_EXISTS, ast_filehelper(), and is_absolute_path().

Referenced by fileexists_core().

00527 {
00528    if (buf == NULL) {
00529       return -1;
00530    }
00531 
00532    if (ast_language_is_prefix && !is_absolute_path(filename)) { /* new layout */
00533       if (lang) {
00534          snprintf(buf, buflen, "%s/%s", lang, filename);
00535       } else {
00536          snprintf(buf, buflen, "%s", filename);
00537       }
00538    } else { /* old layout */
00539       strcpy(buf, filename);  /* first copy the full string */
00540       if (lang) {
00541          /* insert the language and suffix if needed */
00542          const char *c = strrchr(filename, '/');
00543          int offset = c ? c - filename + 1 : 0; /* points right after the last '/' */
00544          snprintf(buf + offset, buflen - offset, "%s/%s", lang, filename + offset);
00545       }
00546    }
00547 
00548    return ast_filehelper(buf, NULL, fmt, ACTION_EXISTS);
00549 }

static void filestream_destructor ( void *  arg  )  [static]

Definition at line 289 of file file.c.

References ast_closestream(), AST_FORMAT_AUDIO_MASK, ast_module_unref(), ast_safe_system(), AST_SCHED_DEL, ast_settimeout(), ast_translator_free_path(), ast_format::close, f, ast_format::format, free, and ast_format::module.

Referenced by get_filestream().

00290 {
00291    char *cmd = NULL;
00292    size_t size = 0;
00293    struct ast_filestream *f = arg;
00294 
00295    /* Stop a running stream if there is one */
00296    if (f->owner) {
00297       if (f->fmt->format < AST_FORMAT_AUDIO_MASK) {
00298          f->owner->stream = NULL;
00299          AST_SCHED_DEL(f->owner->sched, f->owner->streamid);
00300 #ifdef HAVE_DAHDI
00301          ast_settimeout(f->owner, 0, NULL, NULL);
00302 #endif         
00303       } else {
00304          f->owner->vstream = NULL;
00305          AST_SCHED_DEL(f->owner->sched, f->owner->vstreamid);
00306       }
00307    }
00308    /* destroy the translator on exit */
00309    if (f->trans)
00310       ast_translator_free_path(f->trans);
00311 
00312    if (f->realfilename && f->filename) {
00313          size = strlen(f->filename) + strlen(f->realfilename) + 15;
00314          cmd = alloca(size);
00315          memset(cmd,0,size);
00316          snprintf(cmd,size,"/bin/mv -f %s %s",f->filename,f->realfilename);
00317          ast_safe_system(cmd);
00318    }
00319 
00320    if (f->filename)
00321       free(f->filename);
00322    if (f->realfilename)
00323       free(f->realfilename);
00324    if (f->fmt->close) {
00325       void (*closefn)(struct ast_filestream *) = f->fmt->close;
00326       closefn(f);
00327    }
00328    if (f->f)
00329       fclose(f->f);
00330    if (f->vfs)
00331       ast_closestream(f->vfs);
00332    if (f->orig_chan_name)
00333       free((void *) f->orig_chan_name);
00334    ast_module_unref(f->fmt->module);
00335 }

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

Definition at line 361 of file file.c.

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

00362 {
00363    struct ast_format *f = s->fmt;
00364    int ret = -1;
00365    int (*openfn)(struct ast_filestream *s);
00366 
00367    if (mode == WRAP_OPEN && (openfn = f->open) && openfn(s))
00368       ast_log(LOG_WARNING, "Unable to open format %s\n", f->name);
00369    else if (mode == WRAP_REWRITE && f->rewrite && f->rewrite(s, comment))
00370       ast_log(LOG_WARNING, "Unable to rewrite format %s\n", f->name);
00371    else {
00372       /* preliminary checks succeed. update usecount */
00373       ast_module_ref(f->module);
00374       ret = 0;
00375    }
00376    return ret;
00377 }

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

Definition at line 337 of file file.c.

References ao2_alloc(), ast_format::buf_size, ast_format::desc_size, filestream_destructor(), ast_filestream::fmt, ast_format::name, and s.

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

00338 {
00339    struct ast_filestream *s;
00340 
00341    int l = sizeof(*s) + fmt->buf_size + fmt->desc_size;  /* total allocation size */
00342    if ( (s = ao2_alloc(l, filestream_destructor)) == NULL)
00343       return NULL;
00344    s->fmt = fmt;
00345    s->f = bfile;
00346 
00347    if (fmt->desc_size)
00348       s->_private = ((char *)(s + 1)) + fmt->buf_size;
00349    if (fmt->buf_size)
00350       s->buf = (char *)(s + 1);
00351    s->fr.src = fmt->name;
00352    return s;
00353 }

static char* handle_cli_core_show_file_formats ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 1322 of file file.c.

References ast_cli_args::argc, ast_cli(), ast_getformatname(), AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_format::exts, f, ast_cli_args::fd, ast_format::format, FORMAT, FORMAT2, ast_format::list, ast_format::name, and ast_cli_entry::usage.

01323 {
01324 #define FORMAT "%-10s %-10s %-20s\n"
01325 #define FORMAT2 "%-10s %-10s %-20s\n"
01326    struct ast_format *f;
01327    int count_fmt = 0;
01328 
01329    switch (cmd) {
01330    case CLI_INIT:
01331       e->command = "core show file formats";
01332       e->usage =
01333          "Usage: core show file formats\n"
01334          "       Displays currently registered file formats (if any).\n";
01335       return NULL;
01336    case CLI_GENERATE:
01337       return NULL;
01338    }
01339 
01340    if (a->argc != 4)
01341       return CLI_SHOWUSAGE;
01342 
01343    ast_cli(a->fd, FORMAT, "Format", "Name", "Extensions");
01344    ast_cli(a->fd, FORMAT, "------", "----", "----------");
01345 
01346    AST_RWLIST_RDLOCK(&formats);
01347    AST_RWLIST_TRAVERSE(&formats, f, list) {
01348       ast_cli(a->fd, FORMAT2, ast_getformatname(f->format), f->name, f->exts);
01349       count_fmt++;
01350    }
01351    AST_RWLIST_UNLOCK(&formats);
01352    ast_cli(a->fd, "%d file formats registered.\n", count_fmt);
01353    return CLI_SUCCESS;
01354 #undef FORMAT
01355 #undef FORMAT2
01356 }

static int is_absolute_path ( const char *  filename  )  [static]

Definition at line 520 of file file.c.

Referenced by fileexists_test().

00521 {
00522    return filename[0] == '/';
00523 }

static int open_wrapper ( struct ast_filestream s  )  [static]

Definition at line 384 of file file.c.

References fn_wrapper(), s, and WRAP_OPEN.

Referenced by ast_filehelper(), and ast_readfile().

00385 {
00386    return fn_wrapper(s, NULL, WRAP_OPEN);
00387 }

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

Definition at line 379 of file file.c.

References fn_wrapper(), and s.

Referenced by ast_writefile().

00380 {
00381    return fn_wrapper(s, comment, WRAP_REWRITE);
00382 }

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

References ast_channel::_softhangup, ast_clear_flag, AST_CONTROL_ANSWER, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_HANGUP, AST_CONTROL_HOLD, AST_CONTROL_RINGING, AST_CONTROL_SRCUPDATE, AST_CONTROL_UNHOLD, AST_CONTROL_VIDUPDATE, ast_exists_extension(), AST_FLAG_END_DTMF_ONLY, AST_FLAG_MASQ_NOSTREAM, AST_FRAME_CONTROL, AST_FRAME_DTMF_END, AST_FRAME_VOICE, ast_frfree, ast_log(), ast_read(), ast_sched_runq(), ast_sched_wait(), ast_set_flag, ast_stopstream(), ast_strdupa, ast_stream_fastforward(), ast_stream_rewind(), ast_test_flag, ast_waitfor(), ast_waitfor_nandfds(), ast_channel::cid, ast_callerid::cid_num, ast_frame::data, ast_frame::datalen, errno, exten, ast_frame::frametype, LOG_WARNING, ast_channel::name, ast_filestream::orig_chan_name, ast_channel::sched, ast_channel::stream, and ast_frame::subclass.

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

01135 {
01136    const char *orig_chan_name = NULL;
01137    int err = 0;
01138 
01139    if (!breakon)
01140       breakon = "";
01141    if (!forward)
01142       forward = "";
01143    if (!rewind)
01144       rewind = "";
01145 
01146    /* Switch the channel to end DTMF frame only. waitstream_core doesn't care about the start of DTMF. */
01147    ast_set_flag(c, AST_FLAG_END_DTMF_ONLY);
01148 
01149    if (ast_test_flag(c, AST_FLAG_MASQ_NOSTREAM))
01150       orig_chan_name = ast_strdupa(c->name);
01151 
01152    while (c->stream) {
01153       int res;
01154       int ms;
01155 
01156       if (orig_chan_name && strcasecmp(orig_chan_name, c->name)) {
01157          ast_stopstream(c);
01158          err = 1;
01159          break;
01160       }
01161 
01162       ms = ast_sched_wait(c->sched);
01163 
01164       if (ms < 0 && !c->timingfunc) {
01165          ast_stopstream(c);
01166          break;
01167       }
01168       if (ms < 0)
01169          ms = 1000;
01170       if (cmdfd < 0) {
01171          res = ast_waitfor(c, ms);
01172          if (res < 0) {
01173             ast_log(LOG_WARNING, "Select failed (%s)\n", strerror(errno));
01174             ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
01175             return res;
01176          }
01177       } else {
01178          int outfd;
01179          struct ast_channel *rchan = ast_waitfor_nandfds(&c, 1, &cmdfd, (cmdfd > -1) ? 1 : 0, NULL, &outfd, &ms);
01180          if (!rchan && (outfd < 0) && (ms)) {
01181             /* Continue */
01182             if (errno == EINTR)
01183                continue;
01184             ast_log(LOG_WARNING, "Wait failed (%s)\n", strerror(errno));
01185             ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
01186             return -1;
01187          } else if (outfd > -1) { /* this requires cmdfd set */
01188             /* The FD we were watching has something waiting */
01189             ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
01190             return 1;
01191          }
01192          /* if rchan is set, it is 'c' */
01193          res = rchan ? 1 : 0; /* map into 'res' values */
01194       }
01195       if (res > 0) {
01196          struct ast_frame *fr = ast_read(c);
01197          if (!fr) {
01198             ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
01199             return -1;
01200          }
01201          switch (fr->frametype) {
01202          case AST_FRAME_DTMF_END:
01203             if (context) {
01204                const char exten[2] = { fr->subclass, '\0' };
01205                if (ast_exists_extension(c, context, exten, 1, c->cid.cid_num)) {
01206                   res = fr->subclass;
01207                   ast_frfree(fr);
01208                   ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
01209                   return res;
01210                }
01211             } else {
01212                res = fr->subclass;
01213                if (strchr(forward, res)) {
01214                   ast_stream_fastforward(c->stream, skip_ms);
01215                } else if (strchr(rewind, res)) {
01216                   ast_stream_rewind(c->stream, skip_ms);
01217                } else if (strchr(breakon, res)) {
01218                   ast_frfree(fr);
01219                   ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
01220                   return res;
01221                }              
01222             }
01223             break;
01224          case AST_FRAME_CONTROL:
01225             switch (fr->subclass) {
01226             case AST_CONTROL_HANGUP:
01227             case AST_CONTROL_BUSY:
01228             case AST_CONTROL_CONGESTION:
01229                ast_frfree(fr);
01230                ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
01231                return -1;
01232             case AST_CONTROL_RINGING:
01233             case AST_CONTROL_ANSWER:
01234             case AST_CONTROL_VIDUPDATE:
01235             case AST_CONTROL_SRCUPDATE:
01236             case AST_CONTROL_HOLD:
01237             case AST_CONTROL_UNHOLD:
01238             case -1:
01239                /* Unimportant */
01240                break;
01241             default:
01242                ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", fr->subclass);
01243             }
01244             break;
01245          case AST_FRAME_VOICE:
01246             /* Write audio if appropriate */
01247             if (audiofd > -1) {
01248                if (write(audiofd, fr->data, fr->datalen) < 0) {
01249                   ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
01250                }
01251             }
01252          default:
01253             /* Ignore all others */
01254             break;
01255          }
01256          ast_frfree(fr);
01257       }
01258       ast_sched_runq(c->sched);
01259    }
01260 
01261    ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
01262 
01263    return (err || c->_softhangup) ? -1 : 0;
01264 }


Variable Documentation

int ast_language_is_prefix = 1

Definition at line 56 of file file.c.

Referenced by handle_show_settings(), and main().

struct ast_cli_entry cli_file[]

Initial value:

 {
   { .handler =  handle_cli_core_show_file_formats , .summary =  "Displays file formats" ,__VA_ARGS__ }
}

Definition at line 1358 of file file.c.

Referenced by ast_file_init().


Generated on Thu Jul 9 13:41:18 2009 for Asterisk - the Open Source PBX by  doxygen 1.4.7