Mon Jun 27 16:51:14 2011

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"
#include "asterisk/test.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 format_t 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.
char * ast_format_str_reduce (char *fmts)
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 format_t 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 '_' suffices, or NULL.
static format_t 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 struct ast_frameread_frame (struct ast_filestream *s, int *whennext)
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
static struct 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"


Enumeration Type Documentation

enum file_action

Enumerator:
ACTION_EXISTS 
ACTION_DELETE 
ACTION_RENAME 
ACTION_OPEN 
ACTION_COPY 

Definition at line 388 of file file.c.

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

enum fsread_res

Enumerator:
FSREAD_FAILURE 
FSREAD_SUCCESS_SCHED 
FSREAD_SUCCESS_NOSCHED 

Definition at line 724 of file file.c.

00724                 {
00725    FSREAD_FAILURE,
00726    FSREAD_SUCCESS_SCHED,
00727    FSREAD_SUCCESS_NOSCHED,
00728 };

enum wrap_fn

Enumerator:
WRAP_OPEN 
WRAP_REWRITE 

Definition at line 358 of file file.c.

00358 { 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 62 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.

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

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

References ast_filestream::owner.

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

00842 {
00843    s->owner = chan;
00844    return 0;
00845 }

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

References ao2_ref, AST_FORMAT_AUDIO_MASK, AST_SCHED_DEL, ast_settimeout(), f, and ast_format::format.

Referenced by 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(), moh_files_release(), and rpt().

00885 {
00886    /* This used to destroy the filestream, but it now just decrements a refcount.
00887     * We need to force the stream to quit queuing frames now, because we might
00888     * change the writeformat, which could result in a subsequent write error, if
00889     * the format is different. */
00890 
00891    /* Stop a running stream if there is one */
00892    if (f->owner) {
00893       if (f->fmt->format < AST_FORMAT_AUDIO_MASK) {
00894          f->owner->stream = NULL;
00895          AST_SCHED_DEL(f->owner->sched, f->owner->streamid);
00896          ast_settimeout(f->owner, 0, NULL, NULL);
00897       } else {
00898          f->owner->vstream = NULL;
00899          AST_SCHED_DEL(f->owner->sched, f->owner->vstreamid);
00900       }
00901    }
00902 
00903    ao2_ref(f, -1);
00904    return 0;
00905 }

int ast_file_init ( void   ) 

Provided by file.c

Definition at line 1474 of file file.c.

References ARRAY_LEN, ast_cli_register_multiple(), and cli_file.

01475 {
01476    ast_cli_register_multiple(cli_file, ARRAY_LEN(cli_file));
01477    return 0;
01478 }

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

References ast_filehelper().

Referenced by copy_plain_file(), and vm_forwardoptions().

00936 {
00937    return ast_filehelper(filename, filename2, fmt, ACTION_COPY);
00938 }

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

References ACTION_DELETE, and ast_filehelper().

Referenced by announce_thread(), ast_monitor_start(), ast_monitor_stop(), conf_free(), dial_exec_full(), handle_cli_file_convert(), leave_voicemail(), play_record_review(), setup_privacy_args(), and vm_delete().

00926 {
00927    return ast_filehelper(filename, NULL, fmt, ACTION_DELETE);
00928 }

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:
0 if file does not exist, non-zero positive otherwise.

Definition at line 911 of file file.c.

References ast_filestream::buf, and fileexists_core().

Referenced by announce_thread(), app_exec(), ast_moh_files_next(), ast_monitor_start(), ast_monitor_stop(), common_exec(), conf_run(), dial_exec_full(), eivr_comm(), forward_message(), function_playback(), invent_message(), leave_voicemail(), minivm_delete_exec(), play_file(), play_message(), play_message_callerid(), readexten_exec(), 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().

00912 {
00913    char *buf;
00914    int buflen;
00915 
00916    if (preflang == NULL)
00917       preflang = "";
00918    buflen = strlen(preflang) + strlen(filename) + 4;  /* room for everything */
00919    buf = alloca(buflen);
00920    if (buf == NULL)
00921       return 0;
00922    return fileexists_core(filename, fmt, preflang, buf, buflen);
00923 }

static format_t 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 405 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(), copy(), errno, ext, ast_format::exts, exts_compare(), f, ast_filestream::filename, ast_filestream::fmt, ast_format::format, get_filestream(), ast_filestream::lasttimeout, ast_format::list, LOG_WARNING, open_wrapper(), ast_channel::stream, strsep(), ast_filestream::trans, ast_channel::vstream, and ast_channel::writeformat.

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

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

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

References ACTION_RENAME, and ast_filehelper().

Referenced by ast_monitor_stop(), forward_message(), play_record_review(), rename_file(), and vm_forwardoptions().

00931 {
00932    return ast_filehelper(filename, filename2, fmt, ACTION_RENAME);
00933 }

char* ast_format_str_reduce ( char *  fmts  ) 

Parameters:
fmts a format string, this string will be modified
Return values:
NULL error
Returns:
a pointer to the reduced format string, this is a pointer to fmts

Definition at line 1358 of file file.c.

References ast_log(), AST_MAX_FORMATS, AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_strdupa, ast_format::exts, exts_compare(), f, first, len(), ast_format::list, LOG_WARNING, strsep(), and type.

Referenced by load_config().

01359 {
01360    struct ast_format *f;
01361    struct ast_format *fmts_ptr[AST_MAX_FORMATS];
01362    char *fmts_str[AST_MAX_FORMATS];
01363    char *stringp, *type;
01364    char *orig = fmts;
01365    int i, j, x, first, found = 0;
01366    int len = strlen(fmts) + 1;
01367    int res;
01368 
01369    if (AST_RWLIST_RDLOCK(&formats)) {
01370       ast_log(LOG_WARNING, "Unable to lock format list\n");
01371       return NULL;
01372    }
01373 
01374    stringp = ast_strdupa(fmts);
01375 
01376    for (x = 0; (type = strsep(&stringp, "|")) && x < AST_MAX_FORMATS; x++) {
01377       AST_RWLIST_TRAVERSE(&formats, f, list) {
01378          if (exts_compare(f->exts, type)) {
01379             found = 1;
01380             break;
01381          }
01382       }
01383 
01384       fmts_str[x] = type;
01385       if (found) {
01386          fmts_ptr[x] = f;
01387       } else {
01388          fmts_ptr[x] = NULL;
01389       }
01390    }
01391    AST_RWLIST_UNLOCK(&formats);
01392 
01393    first = 1;
01394    for (i = 0; i < x; i++) {
01395       /* ignore invalid entries */
01396       if (!fmts_ptr[i]) {
01397          ast_log(LOG_WARNING, "ignoring unknown format '%s'\n", fmts_str[i]);
01398          continue;
01399       }
01400 
01401       /* special handling for the first entry */
01402       if (first) {
01403          res = snprintf(fmts, len, "%s", fmts_str[i]);
01404          fmts += res;
01405          len -= res;
01406          first = 0;
01407          continue;
01408       }
01409 
01410       found = 0;
01411       for (j = 0; j < i; j++) {
01412          /* this is a duplicate */
01413          if (fmts_ptr[j] == fmts_ptr[i]) {
01414             found = 1;
01415             break;
01416          }
01417       }
01418 
01419       if (!found) {
01420          res = snprintf(fmts, len, "|%s", fmts_str[i]);
01421          fmts += res;
01422          len -= res;
01423       }
01424    }
01425 
01426    if (first) {
01427       ast_log(LOG_WARNING, "no known formats found in format list (%s)\n", orig);
01428       return NULL;
01429    }
01430 
01431    return orig;
01432 }

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

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

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

Definition at line 781 of file file.c.

References ast_readaudio_callback(), and FSREAD_SUCCESS_SCHED.

Referenced by ast_readaudio_callback().

00782 {
00783    struct ast_filestream *fs = (struct ast_filestream *)data;
00784    enum fsread_res res;
00785 
00786    res = ast_readaudio_callback(fs);
00787 
00788    if (res == FSREAD_SUCCESS_SCHED)
00789       return 1;
00790    
00791    return 0;
00792 }

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

Definition at line 828 of file file.c.

References ast_readvideo_callback(), and FSREAD_SUCCESS_SCHED.

Referenced by ast_readvideo_callback().

00829 {
00830    struct ast_filestream *fs = (struct ast_filestream *)data;
00831    enum fsread_res res;
00832 
00833    res = ast_readvideo_callback(fs);
00834 
00835    if (res == FSREAD_SUCCESS_SCHED)
00836       return 1;
00837    
00838    return 0;
00839 }

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

References ast_openstream_full().

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

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

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

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

Referenced by ast_openstream(), and gen_nextfile().

00618 {
00619    /* 
00620     * Use fileexists_core() to find a file in a compatible
00621     * language and format, set up a suitable translator,
00622     * and open the stream.
00623     */
00624    format_t fmts, res;
00625    int 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    if (res == -1) {  /* No format available that works with this channel */
00651       return NULL;
00652    }
00653    res = ast_filehelper(buf, chan, NULL, ACTION_OPEN);
00654    if (res >= 0)
00655       return chan->stream;
00656    return NULL;
00657 }

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

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

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

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

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

References AST_FORMAT_AUDIO_MASK, ast_readaudio_callback(), ast_readvideo_callback(), ast_filestream::fmt, ast_format::format, and FSREAD_FAILURE.

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

00848 {
00849    enum fsread_res res;
00850 
00851    if (s->fmt->format & AST_FORMAT_AUDIO_MASK)
00852       res = ast_readaudio_callback(s);
00853    else
00854       res = ast_readvideo_callback(s);
00855 
00856    return (res == FSREAD_FAILURE) ? -1 : 0;
00857 }

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

Definition at line 732 of file file.c.

References ast_format_rate(), ast_frfree, ast_fsread_audio(), ast_log(), ast_sched_add(), ast_settimeout(), ast_write(), ast_filestream::fmt, ast_format::format, FSREAD_FAILURE, FSREAD_SUCCESS_NOSCHED, FSREAD_SUCCESS_SCHED, ast_filestream::lasttimeout, LOG_WARNING, ast_channel::name, ast_filestream::orig_chan_name, ast_filestream::owner, read_frame(), ast_channel::sched, ast_channel::streamid, and ast_channel::timingfd.

Referenced by ast_fsread_audio(), and ast_playstream().

00733 {
00734    int whennext = 0;
00735 
00736    while (!whennext) {
00737       struct ast_frame *fr;
00738 
00739       if (s->orig_chan_name && strcasecmp(s->owner->name, s->orig_chan_name)) {
00740          goto return_failure;
00741       }
00742 
00743       fr = read_frame(s, &whennext);
00744 
00745       if (!fr /* stream complete */ || ast_write(s->owner, fr) /* error writing */) {
00746          if (fr) {
00747             ast_log(LOG_WARNING, "Failed to write frame\n");
00748             ast_frfree(fr);
00749          }
00750          goto return_failure;
00751       } 
00752 
00753       if (fr) {
00754          ast_frfree(fr);
00755       }
00756    }
00757 
00758    if (whennext != s->lasttimeout) {
00759       if (s->owner->timingfd > -1) {
00760          float samp_rate = (float) ast_format_rate(s->fmt->format);
00761          unsigned int rate;
00762 
00763          rate = (unsigned int) roundf(samp_rate / ((float) whennext));
00764 
00765          ast_settimeout(s->owner, rate, ast_fsread_audio, s);
00766       } else {
00767          s->owner->streamid = ast_sched_add(s->owner->sched, 
00768             whennext / (ast_format_rate(s->fmt->format) / 1000), ast_fsread_audio, s);
00769       }
00770       s->lasttimeout = whennext;
00771       return FSREAD_SUCCESS_NOSCHED;
00772    }
00773    return FSREAD_SUCCESS_SCHED;
00774 
00775 return_failure:
00776    s->owner->streamid = -1;
00777    ast_settimeout(s->owner, 0, NULL, NULL);
00778    return FSREAD_FAILURE;
00779 }

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 984 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 handle_cli_file_convert().

00985 {
00986    FILE *bfile;
00987    struct ast_format *f;
00988    struct ast_filestream *fs = NULL;
00989    char *fn;
00990    int format_found = 0;   
00991 
00992    AST_RWLIST_RDLOCK(&formats);
00993 
00994    AST_RWLIST_TRAVERSE(&formats, f, list) {
00995       fs = NULL;
00996       if (!exts_compare(f->exts, type))
00997          continue;
00998       else 
00999          format_found = 1;
01000 
01001       fn = build_filename(filename, type);
01002       errno = 0;
01003       bfile = fopen(fn, "r");
01004 
01005       if (!bfile || (fs = get_filestream(f, bfile)) == NULL || open_wrapper(fs) ) {
01006          ast_log(LOG_WARNING, "Unable to open %s\n", fn);
01007          if (fs) {
01008             ast_closestream(fs);
01009          }
01010          fs = NULL;
01011          bfile = NULL;
01012          ast_free(fn);
01013          break;            
01014       }
01015       /* found it */
01016       fs->trans = NULL;
01017       fs->fmt = f;
01018       fs->flags = flags;
01019       fs->mode = mode;
01020       fs->filename = ast_strdup(filename);
01021       fs->vfs = NULL;
01022       break;
01023    }
01024 
01025    AST_RWLIST_UNLOCK(&formats);
01026    if (!format_found)
01027       ast_log(LOG_WARNING, "No such format '%s'\n", type);
01028 
01029    return fs;
01030 }

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

References read_frame().

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

00718 {
00719    int whennext = 0;
00720 
00721    return read_frame(s, &whennext);
00722 }

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

Definition at line 796 of file file.c.

References ast_format_rate(), ast_frfree, ast_fsread_video(), ast_log(), ast_sched_add(), ast_write(), ast_filestream::fmt, ast_format::format, FSREAD_FAILURE, FSREAD_SUCCESS_NOSCHED, FSREAD_SUCCESS_SCHED, ast_filestream::lasttimeout, LOG_WARNING, ast_filestream::owner, read_frame(), ast_channel::sched, and ast_channel::vstreamid.

Referenced by ast_fsread_video(), and ast_playstream().

00797 {
00798    int whennext = 0;
00799 
00800    while (!whennext) {
00801       struct ast_frame *fr = read_frame(s, &whennext);
00802 
00803       if (!fr /* stream complete */ || ast_write(s->owner, fr) /* error writing */) {
00804          if (fr) {
00805             ast_log(LOG_WARNING, "Failed to write frame\n");
00806             ast_frfree(fr);
00807          }
00808          s->owner->vstreamid = -1;
00809          return FSREAD_FAILURE;
00810       }
00811 
00812       if (fr) {
00813          ast_frfree(fr);
00814       }
00815    }
00816 
00817    if (whennext != s->lasttimeout) {
00818       s->owner->vstreamid = ast_sched_add(s->owner->sched, 
00819          whennext / (ast_format_rate(s->fmt->format) / 1000), 
00820          ast_fsread_video, s);
00821       s->lasttimeout = whennext;
00822       return FSREAD_SUCCESS_NOSCHED;
00823    }
00824 
00825    return FSREAD_SUCCESS_SCHED;
00826 }

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

00860 {
00861    return fs->fmt->seek(fs, sample_offset, whence);
00862 }

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

References ast_channel_lock, ast_channel_unlock, ast_closestream(), ast_getformatname(), 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_enumeration_full_vi(), ast_say_number_full_cs(), ast_say_number_full_da(), ast_say_number_full_de(), ast_say_number_full_en(), ast_say_number_full_en_GB(), ast_say_number_full_es(), ast_say_number_full_fr(), ast_say_number_full_gr(), ast_say_number_full_he(), ast_say_number_full_hu(), ast_say_number_full_it(), ast_say_number_full_ka(), 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_ur(), ast_say_number_full_vi(), ast_say_number_full_zh(), background_detect_exec(), builtin_blindtransfer(), conf_exec(), conf_run(), dial_exec_full(), directory_exec(), grab_transfer(), handle_getoption(), handle_speechrecognize(), handle_streamfile(), ices_exec(), ivr_dispatch(), menu_callback(), 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().

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

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

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

Referenced by __ast_play_and_record(), announce_user_count(), app_exec(), ast_pickup_call(), ast_record_review(), bridge_playfile(), builtin_atxfer(), builtin_automixmonitor(), builtin_blindtransfer(), confbridge_exec(), directory_exec(), feature_attended_transfer(), feature_blind_transfer(), forward_message(), grab_transfer(), invent_message(), ivr_dispatch(), join_conference_bridge(), masq_park_call(), menu_callback(), park_exec_full(), play_mailbox_owner(), play_message_callerid(), play_message_in_bridged_call(), play_prompt_to_channel(), play_record_review(), play_sound_file(), sayname(), select_item_seq(), vmsayname_exec(), and wait_file2().

01347 {
01348    int res = 0;
01349    if (!ast_strlen_zero(file)) {
01350       res = ast_streamfile(chan, file, chan->language);
01351       if (!res) {
01352          res = ast_waitstream(chan, digits);
01353       }
01354    }
01355    return res;
01356 } 

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

References ast_seekstream(), and DEFAULT_SAMPLES_PER_MS.

Referenced by waitstream_core().

00875 {
00876    return ast_seekstream(fs, ms * DEFAULT_SAMPLES_PER_MS, SEEK_CUR);
00877 }

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

References ast_seekstream(), and DEFAULT_SAMPLES_PER_MS.

Referenced by handle_recordfile(), and waitstream_core().

00880 {
00881    return ast_seekstream(fs, -ms * DEFAULT_SAMPLES_PER_MS, SEEK_CUR);
00882 }

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 940 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, errno, ast_filestream::f, 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 __analog_ss_thread(), action_bridge(), agent_call(), analog_ss_thread(), 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_gr(), ast_say_date_he(), ast_say_date_hu(), ast_say_date_ka(), 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_he(), ast_say_datetime_from_now_ka(), ast_say_datetime_gr(), ast_say_datetime_he(), ast_say_datetime_nl(), ast_say_datetime_pt(), ast_say_datetime_th(), ast_say_datetime_zh(), ast_say_enumeration_full_da(), ast_say_enumeration_full_de(), ast_say_enumeration_full_en(), ast_say_enumeration_full_he(), ast_say_enumeration_full_vi(), ast_say_number_full_cs(), ast_say_number_full_da(), ast_say_number_full_de(), ast_say_number_full_en(), ast_say_number_full_en_GB(), ast_say_number_full_es(), ast_say_number_full_fr(), ast_say_number_full_gr(), ast_say_number_full_he(), ast_say_number_full_hu(), ast_say_number_full_it(), ast_say_number_full_ka(), 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_ur(), ast_say_number_full_vi(), ast_say_number_full_zh(), ast_say_time_de(), ast_say_time_en(), ast_say_time_fr(), ast_say_time_gr(), ast_say_time_hu(), ast_say_time_ka(), ast_say_time_nl(), ast_say_time_zh(), 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(), local_attended_transfer(), login_exec(), menu_callback(), 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(), vm_authenticate(), wait_file(), and wait_for_winner().

00941 {
00942    struct ast_filestream *fs;
00943    struct ast_filestream *vfs=NULL;
00944    char fmt[256];
00945    int seekattempt;
00946    int res;
00947 
00948    fs = ast_openstream(chan, filename, preflang);
00949    if (!fs) {
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    }
00953 
00954    /* check to see if there is any data present (not a zero length file),
00955     * done this way because there is no where for ast_openstream_full to
00956     * return the file had no data. */
00957    seekattempt = fseek(fs->f, -1, SEEK_END);
00958    if (seekattempt && errno == EINVAL) {
00959       /* Zero-length file, as opposed to a pipe */
00960       return 0;
00961    } else {
00962       ast_seekstream(fs, 0, SEEK_SET);
00963    }
00964 
00965    vfs = ast_openvstream(chan, filename, preflang);
00966    if (vfs) {
00967       ast_debug(1, "Ooh, found a video stream, too, format %s\n", ast_getformatname(vfs->fmt->format));
00968    }
00969 
00970    if (ast_test_flag(chan, AST_FLAG_MASQ_NOSTREAM))
00971       fs->orig_chan_name = ast_strdup(chan->name);
00972    if (ast_applystream(chan, fs))
00973       return -1;
00974    if (vfs && ast_applystream(chan, vfs))
00975       return -1;
00976    res = ast_playstream(fs);
00977    if (!res && vfs)
00978       res = ast_playstream(vfs);
00979    ast_verb(3, "<%s> Playing '%s.%s' (language '%s')\n", chan->name, filename, ast_getformatname(chan->writeformat), preflang ? preflang : "default");
00980 
00981    return res;
00982 }

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

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

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

00870 {
00871    return fs->fmt->tell(fs);
00872 }

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

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

Referenced by handle_recordfile().

00865 {
00866    return fs->fmt->trunc(fs);
00867 }

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

References waitstream_core().

Referenced by __analog_ss_thread(), action_bridge(), agent_call(), analog_ss_thread(), 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_gr(), ast_say_date_he(), ast_say_date_hu(), ast_say_date_ka(), 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_he(), ast_say_datetime_from_now_ka(), ast_say_datetime_gr(), ast_say_datetime_he(), ast_say_datetime_nl(), ast_say_datetime_pt(), ast_say_datetime_th(), ast_say_datetime_zh(), ast_say_enumeration_full_da(), ast_say_enumeration_full_de(), ast_say_enumeration_full_en(), ast_say_enumeration_full_he(), ast_say_enumeration_full_vi(), ast_say_number_full_cs(), ast_say_number_full_da(), ast_say_number_full_de(), ast_say_number_full_en(), ast_say_number_full_en_GB(), ast_say_number_full_es(), ast_say_number_full_fr(), ast_say_number_full_gr(), ast_say_number_full_he(), ast_say_number_full_hu(), ast_say_number_full_it(), ast_say_number_full_ka(), 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_ur(), ast_say_number_full_vi(), ast_say_number_full_zh(), ast_say_time_de(), ast_say_time_en(), ast_say_time_gr(), ast_say_time_he(), ast_say_time_hu(), ast_say_time_ka(), ast_say_time_nl(), ast_say_time_zh(), ast_stream_and_wait(), bridge_exec(), check_availability(), check_beep(), common_exec(), conf_exec(), conf_run(), directory_exec(), find_conf_realtime(), gr_say_number_female(), handle_recordfile(), invent_message(), leave_voicemail(), local_attended_transfer(), login_exec(), menu_callback(), 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(), vm_authenticate(), and wait_file().

01320 {
01321    return waitstream_core(c, breakon, NULL, NULL, 0, -1, -1, NULL);
01322 }

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

References ast_channel::context, and waitstream_core().

Referenced by pbx_builtin_background().

01331 {
01332    /* Waitstream, with return in the case of a valid 1 digit extension */
01333    /* in the current or specified context being pressed */
01334 
01335    if (!context)
01336       context = c->context;
01337    return waitstream_core(c, NULL, NULL, NULL, 0,
01338       -1, -1, context);
01339 }

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

References waitstream_core().

Referenced by ast_control_streamfile().

01314 {
01315    return waitstream_core(c, breakon, forward, reverse, ms,
01316       -1 /* no audiofd */, -1 /* no cmdfd */, NULL /* no context */);
01317 }

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 1324 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_enumeration_full_vi(), ast_say_number_full_cs(), ast_say_number_full_da(), ast_say_number_full_de(), ast_say_number_full_en(), ast_say_number_full_en_GB(), ast_say_number_full_es(), ast_say_number_full_fr(), ast_say_number_full_gr(), ast_say_number_full_he(), ast_say_number_full_hu(), ast_say_number_full_it(), ast_say_number_full_ka(), 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_ur(), ast_say_number_full_vi(), ast_say_number_full_zh(), handle_getoption(), handle_streamfile(), pl_odtworz_plik(), s_streamwait3(), say_character_str_full(), say_digit_str_full(), and say_phonetic_str_full().

01325 {
01326    return waitstream_core(c, breakon, NULL, NULL, 0,
01327       audiofd, cmdfd, NULL /* no context */);
01328 }

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 1032 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, ast_filestream::buf, build_filename(), errno, ast_format::exts, exts_compare(), ast_filestream::f, 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().

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

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 145 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_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().

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

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

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

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

Definition at line 210 of file file.c.

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

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

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

Definition at line 277 of file file.c.

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

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

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

static format_t 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 '_' suffices, or NULL.

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, and fileexists_test().

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

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

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

Definition at line 528 of file file.c.

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

Referenced by fileexists_core().

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

static void filestream_destructor ( void *  arg  )  [static]

Definition at line 291 of file file.c.

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

Referenced by get_filestream().

00292 {
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          ast_settimeout(f->owner, 0, NULL, NULL);
00301       } else {
00302          f->owner->vstream = NULL;
00303          AST_SCHED_DEL(f->owner->sched, f->owner->vstreamid);
00304       }
00305    }
00306    /* destroy the translator on exit */
00307    if (f->trans)
00308       ast_translator_free_path(f->trans);
00309 
00310    if (f->realfilename && f->filename) {
00311       if (ast_safe_fork(0) == 0) {
00312          execl("/bin/mv", "mv", "-f", f->filename, f->realfilename, SENTINEL);
00313       }
00314    }
00315 
00316    if (f->filename)
00317       free(f->filename);
00318    if (f->realfilename)
00319       free(f->realfilename);
00320    if (f->fmt->close) {
00321       void (*closefn)(struct ast_filestream *) = f->fmt->close;
00322       closefn(f);
00323    }
00324    if (f->f)
00325       fclose(f->f);
00326    if (f->vfs)
00327       ast_closestream(f->vfs);
00328    if (f->write_buffer) {
00329       ast_free(f->write_buffer);
00330    }
00331    if (f->orig_chan_name)
00332       free((void *) f->orig_chan_name);
00333    ast_module_unref(f->fmt->module);
00334 }

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

Definition at line 360 of file file.c.

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

Referenced by open_wrapper(), and rewrite_wrapper().

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

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

Definition at line 336 of file file.c.

References ast_filestream::_private, ao2_alloc, ast_filestream::buf, ast_format::buf_size, ast_format::desc_size, ast_filestream::f, filestream_destructor(), ast_filestream::fmt, ast_filestream::fr, ast_format::name, and ast_frame::src.

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

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

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

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

01435 {
01436 #define FORMAT "%-10s %-10s %-20s\n"
01437 #define FORMAT2 "%-10s %-10s %-20s\n"
01438    struct ast_format *f;
01439    int count_fmt = 0;
01440 
01441    switch (cmd) {
01442    case CLI_INIT:
01443       e->command = "core show file formats";
01444       e->usage =
01445          "Usage: core show file formats\n"
01446          "       Displays currently registered file formats (if any).\n";
01447       return NULL;
01448    case CLI_GENERATE:
01449       return NULL;
01450    }
01451 
01452    if (a->argc != 4)
01453       return CLI_SHOWUSAGE;
01454 
01455    ast_cli(a->fd, FORMAT, "Format", "Name", "Extensions");
01456    ast_cli(a->fd, FORMAT, "------", "----", "----------");
01457 
01458    AST_RWLIST_RDLOCK(&formats);
01459    AST_RWLIST_TRAVERSE(&formats, f, list) {
01460       ast_cli(a->fd, FORMAT2, ast_getformatname(f->format), f->name, f->exts);
01461       count_fmt++;
01462    }
01463    AST_RWLIST_UNLOCK(&formats);
01464    ast_cli(a->fd, "%d file formats registered.\n", count_fmt);
01465    return CLI_SUCCESS;
01466 #undef FORMAT
01467 #undef FORMAT2
01468 }

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

Definition at line 523 of file file.c.

Referenced by fileexists_test().

00524 {
00525    return filename[0] == '/';
00526 }

static int open_wrapper ( struct ast_filestream s  )  [static]

Definition at line 383 of file file.c.

References fn_wrapper(), and WRAP_OPEN.

Referenced by ast_filehelper(), and ast_readfile().

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

static struct ast_frame* read_frame ( struct ast_filestream s,
int *  whennext 
) [static]

Definition at line 692 of file file.c.

References ast_frfree, ast_frisolate(), ast_filestream::fmt, and ast_format::read.

Referenced by ast_audiohook_read_frame(), ast_readaudio_callback(), ast_readframe(), and ast_readvideo_callback().

00693 {
00694    struct ast_frame *fr, *new_fr;
00695 
00696    if (!s || !s->fmt) {
00697       return NULL;
00698    }
00699 
00700    if (!(fr = s->fmt->read(s, whennext))) {
00701       return NULL;
00702    }
00703 
00704    if (!(new_fr = ast_frisolate(fr))) {
00705       ast_frfree(fr);
00706       return NULL;
00707    }
00708 
00709    if (new_fr != fr) {
00710       ast_frfree(fr);
00711       fr = new_fr;
00712    }
00713 
00714    return fr;
00715 }

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

Definition at line 378 of file file.c.

References fn_wrapper().

Referenced by ast_writefile().

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

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

References ast_channel::_softhangup, ast_clear_flag, AST_CONTROL_ANSWER, AST_CONTROL_AOC, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_CONNECTED_LINE, AST_CONTROL_HANGUP, AST_CONTROL_HOLD, AST_CONTROL_REDIRECTING, AST_CONTROL_RINGING, AST_CONTROL_SRCCHANGE, 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::caller, ast_frame::data, ast_frame::datalen, errno, exten, ast_filestream::f, ast_frame::frametype, ast_party_caller::id, ast_frame_subclass::integer, LOG_WARNING, ast_channel::name, ast_party_id::number, ast_filestream::orig_chan_name, ast_frame::ptr, S_COR, ast_channel::sched, ast_party_number::str, ast_channel::stream, ast_frame::subclass, and ast_party_number::valid.

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

01170 {
01171    const char *orig_chan_name = NULL;
01172    int err = 0;
01173 
01174    if (!breakon)
01175       breakon = "";
01176    if (!forward)
01177       forward = "";
01178    if (!reverse)
01179       reverse = "";
01180 
01181    /* Switch the channel to end DTMF frame only. waitstream_core doesn't care about the start of DTMF. */
01182    ast_set_flag(c, AST_FLAG_END_DTMF_ONLY);
01183 
01184    if (ast_test_flag(c, AST_FLAG_MASQ_NOSTREAM))
01185       orig_chan_name = ast_strdupa(c->name);
01186 
01187    while (c->stream) {
01188       int res;
01189       int ms;
01190 
01191       if (orig_chan_name && strcasecmp(orig_chan_name, c->name)) {
01192          ast_stopstream(c);
01193          err = 1;
01194          break;
01195       }
01196 
01197       ms = ast_sched_wait(c->sched);
01198 
01199       if (ms < 0 && !c->timingfunc) {
01200          ast_stopstream(c);
01201          break;
01202       }
01203       if (ms < 0)
01204          ms = 1000;
01205       if (cmdfd < 0) {
01206          res = ast_waitfor(c, ms);
01207          if (res < 0) {
01208             ast_log(LOG_WARNING, "Select failed (%s)\n", strerror(errno));
01209             ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
01210             return res;
01211          }
01212       } else {
01213          int outfd;
01214          struct ast_channel *rchan = ast_waitfor_nandfds(&c, 1, &cmdfd, (cmdfd > -1) ? 1 : 0, NULL, &outfd, &ms);
01215          if (!rchan && (outfd < 0) && (ms)) {
01216             /* Continue */
01217             if (errno == EINTR)
01218                continue;
01219             ast_log(LOG_WARNING, "Wait failed (%s)\n", strerror(errno));
01220             ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
01221             return -1;
01222          } else if (outfd > -1) { /* this requires cmdfd set */
01223             /* The FD we were watching has something waiting */
01224             ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
01225             return 1;
01226          }
01227          /* if rchan is set, it is 'c' */
01228          res = rchan ? 1 : 0; /* map into 'res' values */
01229       }
01230       if (res > 0) {
01231          struct ast_frame *fr = ast_read(c);
01232          if (!fr) {
01233             ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
01234             return -1;
01235          }
01236          switch (fr->frametype) {
01237          case AST_FRAME_DTMF_END:
01238             if (context) {
01239                const char exten[2] = { fr->subclass.integer, '\0' };
01240                if (ast_exists_extension(c, context, exten, 1,
01241                   S_COR(c->caller.id.number.valid, c->caller.id.number.str, NULL))) {
01242                   res = fr->subclass.integer;
01243                   ast_frfree(fr);
01244                   ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
01245                   return res;
01246                }
01247             } else {
01248                res = fr->subclass.integer;
01249                if (strchr(forward, res)) {
01250                   int eoftest;
01251                   ast_stream_fastforward(c->stream, skip_ms);
01252                   eoftest = fgetc(c->stream->f);
01253                   if (feof(c->stream->f)) {
01254                      ast_stream_rewind(c->stream, skip_ms);
01255                   } else {
01256                      ungetc(eoftest, c->stream->f);
01257                   }
01258                } else if (strchr(reverse, res)) {
01259                   ast_stream_rewind(c->stream, skip_ms);
01260                } else if (strchr(breakon, res)) {
01261                   ast_frfree(fr);
01262                   ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
01263                   return res;
01264                }              
01265             }
01266             break;
01267          case AST_FRAME_CONTROL:
01268             switch (fr->subclass.integer) {
01269             case AST_CONTROL_HANGUP:
01270             case AST_CONTROL_BUSY:
01271             case AST_CONTROL_CONGESTION:
01272                ast_frfree(fr);
01273                ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
01274                return -1;
01275             case AST_CONTROL_RINGING:
01276             case AST_CONTROL_ANSWER:
01277             case AST_CONTROL_VIDUPDATE:
01278             case AST_CONTROL_SRCUPDATE:
01279             case AST_CONTROL_SRCCHANGE:
01280             case AST_CONTROL_HOLD:
01281             case AST_CONTROL_UNHOLD:
01282             case AST_CONTROL_CONNECTED_LINE:
01283             case AST_CONTROL_REDIRECTING:
01284             case AST_CONTROL_AOC:
01285             case -1:
01286                /* Unimportant */
01287                break;
01288             default:
01289                ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", fr->subclass.integer);
01290             }
01291             break;
01292          case AST_FRAME_VOICE:
01293             /* Write audio if appropriate */
01294             if (audiofd > -1) {
01295                if (write(audiofd, fr->data.ptr, fr->datalen) < 0) {
01296                   ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
01297                }
01298             }
01299          default:
01300             /* Ignore all others */
01301             break;
01302          }
01303          ast_frfree(fr);
01304       }
01305       ast_sched_runq(c->sched);
01306    }
01307 
01308    ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
01309 
01310    return (err || c->_softhangup) ? -1 : 0;
01311 }


Variable Documentation

int ast_language_is_prefix = 1

Definition at line 58 of file file.c.

Referenced by handle_show_settings(), and main().

struct ast_cli_entry cli_file[] [static]

Initial value:

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

Definition at line 1470 of file file.c.

Referenced by ast_file_init().


Generated on Mon Jun 27 16:51:14 2011 for Asterisk - The Open Source Telephony Project by  doxygen 1.4.7