Fri Jul 24 00:41:43 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 <math.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 *reverse, 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 *reverse, 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_channelstats(), 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 382 of file file.c.

00382                  {
00383    ACTION_EXISTS = 1, /* return matching format if file exists, 0 otherwise */
00384    ACTION_DELETE, /* delete file, return 0 on success, -1 on error */
00385    ACTION_RENAME, /* rename file. return 0 on success, -1 on error */
00386    ACTION_OPEN,
00387    ACTION_COPY /* copy file. return 0 on success, -1 on error */
00388 };

enum fsread_res

Enumerator:
FSREAD_FAILURE 
FSREAD_SUCCESS_SCHED 
FSREAD_SUCCESS_NOSCHED 

Definition at line 699 of file file.c.

00699                 {
00700    FSREAD_FAILURE,
00701    FSREAD_SUCCESS_SCHED,
00702    FSREAD_SUCCESS_NOSCHED,
00703 };

enum wrap_fn

Enumerator:
WRAP_OPEN 
WRAP_REWRITE 

Definition at line 352 of file file.c.

00352 { 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 61 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.

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

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

References chan, and s.

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

00819 {
00820    s->owner = chan;
00821    return 0;
00822 }

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 861 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_thread(), moh_files_release(), and rpt().

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

int ast_file_init ( void   ) 

Provided by file.c

Definition at line 1369 of file file.c.

References ast_cli_register_multiple(), and cli_file.

Referenced by main().

01370 {
01371    ast_cli_register_multiple(cli_file, sizeof(cli_file) / sizeof(struct ast_cli_entry));
01372    return 0;
01373 }

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

References ast_filehelper().

Referenced by copy_plain_file(), and vm_forwardoptions().

00910 {
00911    return ast_filehelper(filename, filename2, fmt, ACTION_COPY);
00912 }

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 899 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_record_review(), setup_privacy_args(), vm_delete(), and vm_forwardoptions().

00900 {
00901    return ast_filehelper(filename, NULL, fmt, ACTION_DELETE);
00902 }

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 885 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(), function_playback(), invent_message(), leave_voicemail(), minivm_delete_exec(), play_message(), play_message_callerid(), record_exec(), retrydial_exec(), rpt_tele_thread(), say_character_str_full(), say_digit_str_full(), say_phonetic_str_full(), sayname(), saynode(), setup_privacy_args(), vm_intro(), vm_newuser(), vm_options(), and vm_tempgreeting().

00886 {
00887    char *buf;
00888    int buflen;
00889 
00890    if (preflang == NULL)
00891       preflang = "";
00892    buflen = strlen(preflang) + strlen(filename) + 4;  /* room for everything */
00893    buf = alloca(buflen);
00894    if (buf == NULL)
00895       return 0;
00896    return fileexists_core(filename, fmt, preflang, buf, buflen);
00897 }

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

References ACTION_DELETE, ACTION_EXISTS, ACTION_OPEN, ACTION_RENAME, ast_closestream(), AST_FORMAT_AUDIO_MASK, AST_FORMAT_VIDEO_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().

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

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

References ACTION_RENAME, and ast_filehelper().

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

00905 {
00906    return ast_filehelper(filename, filename2, fmt, ACTION_RENAME);
00907 }

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

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

Referenced by ast_frame_free().

01302 {
01303    struct ast_filestream *fs;
01304 
01305    ast_clear_flag(fr, AST_FRFLAG_FROM_FILESTREAM);
01306 
01307    fs = (struct ast_filestream *) (((char *) fr) - offsetof(struct ast_filestream, fr));
01308 
01309    ao2_ref(fs, -1);
01310 }

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

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

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

Definition at line 756 of file file.c.

References ast_readaudio_callback(), and FSREAD_SUCCESS_SCHED.

Referenced by ast_readaudio_callback().

00757 {
00758    struct ast_filestream *fs = (struct ast_filestream *)data;
00759    enum fsread_res res;
00760 
00761    res = ast_readaudio_callback(fs);
00762 
00763    if (res == FSREAD_SUCCESS_SCHED)
00764       return 1;
00765    
00766    return 0;
00767 }

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

Definition at line 805 of file file.c.

References ast_readvideo_callback(), and FSREAD_SUCCESS_SCHED.

Referenced by ast_readvideo_callback().

00806 {
00807    struct ast_filestream *fs = (struct ast_filestream *)data;
00808    enum fsread_res res;
00809 
00810    res = ast_readvideo_callback(fs);
00811 
00812    if (res == FSREAD_SUCCESS_SCHED)
00813       return 1;
00814    
00815    return 0;
00816 }

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

References ast_openstream_full(), and chan.

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

00611 {
00612    return ast_openstream_full(chan, filename, preflang, 0);
00613 }

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

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

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

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

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

00825 {
00826    enum fsread_res res;
00827 
00828    if (s->fmt->format & AST_FORMAT_AUDIO_MASK)
00829       res = ast_readaudio_callback(s);
00830    else
00831       res = ast_readvideo_callback(s);
00832 
00833    return (res == FSREAD_FAILURE) ? -1 : 0;
00834 }

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

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

00708 {
00709    int whennext = 0;
00710 
00711    while (!whennext) {
00712       struct ast_frame *fr;
00713       
00714       if (s->orig_chan_name && strcasecmp(s->owner->name, s->orig_chan_name))
00715          goto return_failure;
00716       
00717       fr = s->fmt->read(s, &whennext);
00718       if (fr) {
00719          ast_set_flag(fr, AST_FRFLAG_FROM_FILESTREAM);
00720          ao2_ref(s, +1);
00721       }
00722       if (!fr /* stream complete */ || ast_write(s->owner, fr) /* error writing */) {
00723          if (fr) {
00724             ast_log(LOG_WARNING, "Failed to write frame\n");
00725             ast_frfree(fr);
00726          }
00727          goto return_failure;
00728       } 
00729       if (fr) {
00730          ast_frfree(fr);
00731       }
00732    }
00733    if (whennext != s->lasttimeout) {
00734       if (s->owner->timingfd > -1) {
00735          float samp_rate = (float) ast_format_rate(s->fmt->format);
00736          unsigned int rate;
00737 
00738          rate = (unsigned int) roundf(samp_rate / ((float) whennext));
00739 
00740          ast_settimeout(s->owner, rate, ast_fsread_audio, s);
00741       } else {
00742          s->owner->streamid = ast_sched_add(s->owner->sched, 
00743             whennext / (ast_format_rate(s->fmt->format) / 1000), ast_fsread_audio, s);
00744       }
00745       s->lasttimeout = whennext;
00746       return FSREAD_SUCCESS_NOSCHED;
00747    }
00748    return FSREAD_SUCCESS_SCHED;
00749 
00750 return_failure:
00751    s->owner->streamid = -1;
00752    ast_settimeout(s->owner, 0, NULL, NULL);
00753    return FSREAD_FAILURE;
00754 }

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

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

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

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

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

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

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

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 836 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_streamfile(), ast_write(), dictate_exec(), handle_getoption(), handle_recordfile(), handle_streamfile(), and speech_streamfile().

00837 {
00838    return fs->fmt->seek(fs, sample_offset, whence);
00839 }

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 122 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(), leave_voicemail(), 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(), 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().

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

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 1317 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_blindtransfer(), directory_exec(), forward_message(), invent_message(), ivr_dispatch(), leave_voicemail(), masq_park_call(), park_exec_full(), play_mailbox_owner(), play_message_callerid(), play_message_in_bridged_call(), play_record_review(), sayname(), select_item_seq(), and wait_file2().

01318 {
01319    int res = 0;
01320    if (!ast_strlen_zero(file)) {
01321       res = ast_streamfile(chan, file, chan->language);
01322       if (!res) {
01323          res = ast_waitstream(chan, digits);
01324       }
01325    }
01326    return res;
01327 } 

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

References ast_seekstream(), and DEFAULT_SAMPLES_PER_MS.

Referenced by waitstream_core().

00852 {
00853    return ast_seekstream(fs, ms * DEFAULT_SAMPLES_PER_MS, SEEK_CUR);
00854 }

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

References ast_seekstream(), and DEFAULT_SAMPLES_PER_MS.

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

00857 {
00858    return ast_seekstream(fs, -ms * DEFAULT_SAMPLES_PER_MS, SEEK_CUR);
00859 }

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 914 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_seekstream(), ast_strdup, ast_test_flag, ast_verb, chan, errno, ast_filestream::f, ast_filestream::fmt, ast_format::format, LOG_WARNING, ast_channel::name, ast_channel::nativeformats, 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_full(), parkandannounce_exec(), pbx_builtin_background(), pl_odtworz_plik(), play_and_wait(), play_file(), 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().

00915 {
00916    struct ast_filestream *fs;
00917    struct ast_filestream *vfs=NULL;
00918    char fmt[256];
00919    int seekattempt;
00920    int res;
00921 
00922    fs = ast_openstream(chan, filename, preflang);
00923    if (!fs) {
00924       ast_log(LOG_WARNING, "Unable to open %s (format %s): %s\n", filename, ast_getformatname_multiple(fmt, sizeof(fmt), chan->nativeformats), strerror(errno));
00925       return -1;
00926    }
00927 
00928    /* check to see if there is any data present (not a zero length file),
00929     * done this way because there is no where for ast_openstream_full to
00930     * return the file had no data. */
00931    seekattempt = fseek(fs->f, -1, SEEK_END);
00932    if (!seekattempt)
00933       ast_seekstream(fs, 0, SEEK_SET);
00934    else
00935       return 0;
00936 
00937    vfs = ast_openvstream(chan, filename, preflang);
00938    if (vfs) {
00939       ast_debug(1, "Ooh, found a video stream, too, format %s\n", ast_getformatname(vfs->fmt->format));
00940    }
00941 
00942    if (ast_test_flag(chan, AST_FLAG_MASQ_NOSTREAM))
00943       fs->orig_chan_name = ast_strdup(chan->name);
00944    if (ast_applystream(chan, fs))
00945       return -1;
00946    if (vfs && ast_applystream(chan, vfs))
00947       return -1;
00948    res = ast_playstream(fs);
00949    if (!res && vfs)
00950       res = ast_playstream(vfs);
00951    ast_verb(3, "<%s> Playing '%s.%s' (language '%s')\n", chan->name, filename, ast_getformatname(chan->writeformat), preflang ? preflang : "default");
00952 
00953    return res;
00954 }

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

00847 {
00848    return fs->fmt->tell(fs);
00849 }

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

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

Referenced by __ast_play_and_record(), and handle_recordfile().

00842 {
00843    return fs->fmt->trunc(fs);
00844 }

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 1279 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_full(), parkandannounce_exec(), pbx_builtin_background(), pl_odtworz_plik(), play_and_wait(), play_file(), 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(), sayfile(), saynum(), select_item_menu(), send_morse(), send_tone_telemetry(), setup_privacy_args(), ss_thread(), vm_authenticate(), and wait_file().

01280 {
01281    return waitstream_core(c, breakon, NULL, NULL, 0, -1, -1, NULL);
01282 }

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

References ast_channel::context, and waitstream_core().

Referenced by pbx_builtin_background().

01291 {
01292    /* Waitstream, with return in the case of a valid 1 digit extension */
01293    /* in the current or specified context being pressed */
01294 
01295    if (!context)
01296       context = c->context;
01297    return waitstream_core(c, NULL, NULL, NULL, 0,
01298       -1, -1, context);
01299 }

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

References waitstream_core().

Referenced by ast_control_streamfile().

01274 {
01275    return waitstream_core(c, breakon, forward, reverse, ms,
01276       -1 /* no audiofd */, -1 /* no cmdfd */, NULL /* no context */);
01277 }

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

01285 {
01286    return waitstream_core(c, breakon, NULL, NULL, 0,
01287       audiofd, cmdfd, NULL /* no context */);
01288 }

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

References ast_closestream(), ast_free, ast_log(), ast_malloc, 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::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, ast_filestream::vfs, and ast_filestream::write_buffer.

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

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

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

References ast_debug, AST_FORMAT_AUDIO_MASK, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_frfree, ast_getformatname(), 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_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(), recordthread(), and rpt().

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

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

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

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

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

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

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

Definition at line 270 of file file.c.

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

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

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

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

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

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

Definition at line 522 of file file.c.

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

Referenced by fileexists_core().

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

static void filestream_destructor ( void *  arg  )  [static]

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

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

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

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

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

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

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

00331 {
00332    struct ast_filestream *s;
00333 
00334    int l = sizeof(*s) + fmt->buf_size + fmt->desc_size;  /* total allocation size */
00335    if ( (s = ao2_alloc(l, filestream_destructor)) == NULL)
00336       return NULL;
00337    s->fmt = fmt;
00338    s->f = bfile;
00339 
00340    if (fmt->desc_size)
00341       s->_private = ((char *)(s + 1)) + fmt->buf_size;
00342    if (fmt->buf_size)
00343       s->buf = (char *)(s + 1);
00344    s->fr.src = fmt->name;
00345    return s;
00346 }

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

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

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

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

Definition at line 517 of file file.c.

Referenced by fileexists_test().

00518 {
00519    return filename[0] == '/';
00520 }

static int open_wrapper ( struct ast_filestream s  )  [static]

Definition at line 377 of file file.c.

References fn_wrapper(), s, and WRAP_OPEN.

Referenced by ast_filehelper(), and ast_readfile().

00378 {
00379    return fn_wrapper(s, NULL, WRAP_OPEN);
00380 }

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

Definition at line 372 of file file.c.

References fn_wrapper(), and s.

Referenced by ast_writefile().

00373 {
00374    return fn_wrapper(s, comment, WRAP_REWRITE);
00375 }

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

the core of all waitstream() functions

Definition at line 1139 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_frame::ptr, ast_channel::sched, ast_channel::stream, and ast_frame::subclass.

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

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


Variable Documentation

int ast_language_is_prefix = 1

Definition at line 57 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 1365 of file file.c.

Referenced by ast_file_init().


Generated on Fri Jul 24 00:41:43 2009 for Asterisk - the Open Source PBX by  doxygen 1.4.7