Mon Oct 8 12:39:22 2012

Asterisk developer's documentation


file.c File Reference

Generic File Format Support. More...

#include "asterisk.h"
#include <dirent.h>
#include <sys/stat.h>
#include <sys/wait.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_close (struct ast_filestream *f)
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 411 of file file.c.

00411                  {
00412    ACTION_EXISTS = 1, /* return matching format if file exists, 0 otherwise */
00413    ACTION_DELETE, /* delete file, return 0 on success, -1 on error */
00414    ACTION_RENAME, /* rename file. return 0 on success, -1 on error */
00415    ACTION_OPEN,
00416    ACTION_COPY /* copy file. return 0 on success, -1 on error */
00417 };

enum fsread_res

Enumerator:
FSREAD_FAILURE 
FSREAD_SUCCESS_SCHED 
FSREAD_SUCCESS_NOSCHED 

Definition at line 747 of file file.c.

00747                 {
00748    FSREAD_FAILURE,
00749    FSREAD_SUCCESS_SCHED,
00750    FSREAD_SUCCESS_NOSCHED,
00751 };

enum wrap_fn

Enumerator:
WRAP_OPEN 
WRAP_REWRITE 

Definition at line 381 of file file.c.

00381 { 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 67 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.

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

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

References ast_filestream::owner.

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

00865 {
00866    s->owner = chan;
00867    return 0;
00868 }

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

References ao2_ref, f, and filestream_close().

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

00908 {
00909    /* This used to destroy the filestream, but it now just decrements a refcount.
00910     * We close the stream in order to quit queuing frames now, because we might
00911     * change the writeformat, which could result in a subsequent write error, if
00912     * the format is different. */
00913    filestream_close(f);
00914    ao2_ref(f, -1);
00915    return 0;
00916 }

int ast_file_init ( void   ) 

Provided by file.c

Definition at line 1493 of file file.c.

References ARRAY_LEN, ast_cli_register_multiple(), and cli_file.

01494 {
01495    ast_cli_register_multiple(cli_file, ARRAY_LEN(cli_file));
01496    return 0;
01497 }

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

References ast_filehelper().

Referenced by copy_plain_file(), and vm_forwardoptions().

00947 {
00948    return ast_filehelper(filename, filename2, fmt, ACTION_COPY);
00949 }

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

00937 {
00938    return ast_filehelper(filename, NULL, fmt, ACTION_DELETE);
00939 }

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 922 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(), get_folder(), invent_message(), leave_voicemail(), minivm_delete_exec(), play_file(), play_message(), play_message_callerid(), readexten_exec(), record_exec(), retrydial_exec(), say_character_str_full(), say_digit_str_full(), say_phonetic_str_full(), sayname(), setup_privacy_args(), vm_intro(), vm_newuser(), vm_options(), and vm_tempgreeting().

00923 {
00924    char *buf;
00925    int buflen;
00926 
00927    if (preflang == NULL)
00928       preflang = "";
00929    buflen = strlen(preflang) + strlen(filename) + 4;  /* room for everything */
00930    buf = alloca(buflen);
00931    if (buf == NULL)
00932       return 0;
00933    return fileexists_core(filename, fmt, preflang, buf, buflen);
00934 }

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

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

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

00942 {
00943    return ast_filehelper(filename, filename2, fmt, ACTION_RENAME);
00944 }

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 1377 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 actual_load_config().

01378 {
01379    struct ast_format *f;
01380    struct ast_format *fmts_ptr[AST_MAX_FORMATS];
01381    char *fmts_str[AST_MAX_FORMATS];
01382    char *stringp, *type;
01383    char *orig = fmts;
01384    int i, j, x, first, found = 0;
01385    int len = strlen(fmts) + 1;
01386    int res;
01387 
01388    if (AST_RWLIST_RDLOCK(&formats)) {
01389       ast_log(LOG_WARNING, "Unable to lock format list\n");
01390       return NULL;
01391    }
01392 
01393    stringp = ast_strdupa(fmts);
01394 
01395    for (x = 0; (type = strsep(&stringp, "|")) && x < AST_MAX_FORMATS; x++) {
01396       AST_RWLIST_TRAVERSE(&formats, f, list) {
01397          if (exts_compare(f->exts, type)) {
01398             found = 1;
01399             break;
01400          }
01401       }
01402 
01403       fmts_str[x] = type;
01404       if (found) {
01405          fmts_ptr[x] = f;
01406       } else {
01407          fmts_ptr[x] = NULL;
01408       }
01409    }
01410    AST_RWLIST_UNLOCK(&formats);
01411 
01412    first = 1;
01413    for (i = 0; i < x; i++) {
01414       /* ignore invalid entries */
01415       if (!fmts_ptr[i]) {
01416          ast_log(LOG_WARNING, "ignoring unknown format '%s'\n", fmts_str[i]);
01417          continue;
01418       }
01419 
01420       /* special handling for the first entry */
01421       if (first) {
01422          res = snprintf(fmts, len, "%s", fmts_str[i]);
01423          fmts += res;
01424          len -= res;
01425          first = 0;
01426          continue;
01427       }
01428 
01429       found = 0;
01430       for (j = 0; j < i; j++) {
01431          /* this is a duplicate */
01432          if (fmts_ptr[j] == fmts_ptr[i]) {
01433             found = 1;
01434             break;
01435          }
01436       }
01437 
01438       if (!found) {
01439          res = snprintf(fmts, len, "|%s", fmts_str[i]);
01440          fmts += res;
01441          len -= res;
01442       }
01443    }
01444 
01445    if (first) {
01446       ast_log(LOG_WARNING, "no known formats found in format list (%s)\n", orig);
01447       return NULL;
01448    }
01449 
01450    return orig;
01451 }

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

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

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

Definition at line 804 of file file.c.

References ast_readaudio_callback(), and FSREAD_SUCCESS_SCHED.

Referenced by ast_readaudio_callback().

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

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

Definition at line 851 of file file.c.

References ast_readvideo_callback(), and FSREAD_SUCCESS_SCHED.

Referenced by ast_readvideo_callback().

00852 {
00853    struct ast_filestream *fs = (struct ast_filestream *)data;
00854    enum fsread_res res;
00855 
00856    res = ast_readvideo_callback(fs);
00857 
00858    if (res == FSREAD_SUCCESS_SCHED)
00859       return 1;
00860    
00861    return 0;
00862 }

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

References ast_openstream_full().

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

00636 {
00637    return ast_openstream_full(chan, filename, preflang, 0);
00638 }

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

00641 {
00642    /* 
00643     * Use fileexists_core() to find a file in a compatible
00644     * language and format, set up a suitable translator,
00645     * and open the stream.
00646     */
00647    format_t fmts, res;
00648    int buflen;
00649    char *buf;
00650 
00651    if (!asis) {
00652       /* do this first, otherwise we detect the wrong writeformat */
00653       ast_stopstream(chan);
00654       if (chan->generator)
00655          ast_deactivate_generator(chan);
00656    }
00657    if (preflang == NULL)
00658       preflang = "";
00659    buflen = strlen(preflang) + strlen(filename) + 4;
00660    buf = alloca(buflen);
00661    if (buf == NULL)
00662       return NULL;
00663    fmts = fileexists_core(filename, NULL, preflang, buf, buflen);
00664    if (fmts > 0)
00665       fmts &= AST_FORMAT_AUDIO_MASK;
00666    if (fmts < 1) {
00667       ast_log(LOG_WARNING, "File %s does not exist in any format\n", filename);
00668       return NULL;
00669    }
00670    chan->oldwriteformat = chan->writeformat;
00671    /* Set the channel to a format we can work with */
00672    res = ast_set_write_format(chan, fmts);
00673    if (res == -1) {  /* No format available that works with this channel */
00674       return NULL;
00675    }
00676    res = ast_filehelper(buf, chan, NULL, ACTION_OPEN);
00677    if (res >= 0)
00678       return chan->stream;
00679    return NULL;
00680 }

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

References ACTION_OPEN, ast_filehelper(), AST_FORMAT_FIRST_VIDEO_BIT, 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().

00683 {
00684    /* As above, but for video. But here we don't have translators
00685     * so we must enforce a format.
00686     */
00687    format_t format;
00688    char *buf;
00689    int buflen;
00690 
00691    if (preflang == NULL)
00692       preflang = "";
00693    buflen = strlen(preflang) + strlen(filename) + 4;
00694    buf = alloca(buflen);
00695    if (buf == NULL)
00696       return NULL;
00697 
00698    for (format = AST_FORMAT_FIRST_VIDEO_BIT; format <= AST_FORMAT_VIDEO_MASK; format = format << 1) {
00699       int fd;
00700       const char *fmt;
00701 
00702       if (!(chan->nativeformats & format))
00703          continue;
00704       fmt = ast_getformatname(format);
00705       if ( fileexists_core(filename, fmt, preflang, buf, buflen) < 1)   /* no valid format */
00706          continue;
00707       fd = ast_filehelper(buf, chan, fmt, ACTION_OPEN);
00708       if (fd >= 0)
00709          return chan->vstream;
00710       ast_log(LOG_WARNING, "File %s has video but couldn't be opened\n", filename);
00711    }
00712    return NULL;
00713 }

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

00871 {
00872    enum fsread_res res;
00873 
00874    if (s->fmt->format & AST_FORMAT_AUDIO_MASK)
00875       res = ast_readaudio_callback(s);
00876    else
00877       res = ast_readvideo_callback(s);
00878 
00879    return (res == FSREAD_FAILURE) ? -1 : 0;
00880 }

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

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

00756 {
00757    int whennext = 0;
00758 
00759    while (!whennext) {
00760       struct ast_frame *fr;
00761 
00762       if (s->orig_chan_name && strcasecmp(s->owner->name, s->orig_chan_name)) {
00763          goto return_failure;
00764       }
00765 
00766       fr = read_frame(s, &whennext);
00767 
00768       if (!fr /* stream complete */ || ast_write(s->owner, fr) /* error writing */) {
00769          if (fr) {
00770             ast_log(LOG_WARNING, "Failed to write frame\n");
00771             ast_frfree(fr);
00772          }
00773          goto return_failure;
00774       } 
00775 
00776       if (fr) {
00777          ast_frfree(fr);
00778       }
00779    }
00780 
00781    if (whennext != s->lasttimeout) {
00782       if (s->owner->timingfd > -1) {
00783          float samp_rate = (float) ast_format_rate(s->fmt->format);
00784          unsigned int rate;
00785 
00786          rate = (unsigned int) roundf(samp_rate / ((float) whennext));
00787 
00788          ast_settimeout(s->owner, rate, ast_fsread_audio, s);
00789       } else {
00790          s->owner->streamid = ast_sched_add(s->owner->sched, 
00791             whennext / (ast_format_rate(s->fmt->format) / 1000), ast_fsread_audio, s);
00792       }
00793       s->lasttimeout = whennext;
00794       return FSREAD_SUCCESS_NOSCHED;
00795    }
00796    return FSREAD_SUCCESS_SCHED;
00797 
00798 return_failure:
00799    s->owner->streamid = -1;
00800    ast_settimeout(s->owner, 0, NULL, NULL);
00801    return FSREAD_FAILURE;
00802 }

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

01002 {
01003    FILE *bfile;
01004    struct ast_format *f;
01005    struct ast_filestream *fs = NULL;
01006    char *fn;
01007    int format_found = 0;   
01008 
01009    AST_RWLIST_RDLOCK(&formats);
01010 
01011    AST_RWLIST_TRAVERSE(&formats, f, list) {
01012       fs = NULL;
01013       if (!exts_compare(f->exts, type))
01014          continue;
01015       else 
01016          format_found = 1;
01017 
01018       fn = build_filename(filename, type);
01019       errno = 0;
01020       bfile = fopen(fn, "r");
01021 
01022       if (!bfile || (fs = get_filestream(f, bfile)) == NULL || open_wrapper(fs) ) {
01023          ast_log(LOG_WARNING, "Unable to open %s\n", fn);
01024          if (fs) {
01025             ast_closestream(fs);
01026          }
01027          fs = NULL;
01028          bfile = NULL;
01029          ast_free(fn);
01030          break;            
01031       }
01032       /* found it */
01033       fs->trans = NULL;
01034       fs->fmt = f;
01035       fs->flags = flags;
01036       fs->mode = mode;
01037       fs->filename = ast_strdup(filename);
01038       fs->vfs = NULL;
01039       break;
01040    }
01041 
01042    AST_RWLIST_UNLOCK(&formats);
01043    if (!format_found)
01044       ast_log(LOG_WARNING, "No such format '%s'\n", type);
01045 
01046    return fs;
01047 }

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

References read_frame().

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

00741 {
00742    int whennext = 0;
00743 
00744    return read_frame(s, &whennext);
00745 }

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

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

00820 {
00821    int whennext = 0;
00822 
00823    while (!whennext) {
00824       struct ast_frame *fr = read_frame(s, &whennext);
00825 
00826       if (!fr /* stream complete */ || ast_write(s->owner, fr) /* error writing */) {
00827          if (fr) {
00828             ast_log(LOG_WARNING, "Failed to write frame\n");
00829             ast_frfree(fr);
00830          }
00831          s->owner->vstreamid = -1;
00832          return FSREAD_FAILURE;
00833       }
00834 
00835       if (fr) {
00836          ast_frfree(fr);
00837       }
00838    }
00839 
00840    if (whennext != s->lasttimeout) {
00841       s->owner->vstreamid = ast_sched_add(s->owner->sched, 
00842          whennext / (ast_format_rate(s->fmt->format) / 1000), 
00843          ast_fsread_video, s);
00844       s->lasttimeout = whennext;
00845       return FSREAD_SUCCESS_NOSCHED;
00846    }
00847 
00848    return FSREAD_SUCCESS_SCHED;
00849 }

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

00883 {
00884    return fs->fmt->seek(fs, sample_offset, whence);
00885 }

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 128 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 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(), 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(), s_streamwait3(), say_character_str_full(), say_digit_str_full(), say_phonetic_str_full(), select_item_seq(), send_waveform_to_channel(), speech_background(), vm_authenticate(), vm_execmain(), wait_for_winner(), waitstream_core(), and zapateller_exec().

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

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

References ast_streamfile(), ast_strlen_zero(), ast_test_suite_event_notify, 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_call_exec(), parked_call_exec(), play_mailbox_owner(), play_message_callerid(), play_message_on_chan(), play_prompt_to_channel(), play_record_review(), play_sound_file(), sayname(), select_item_seq(), vm_forwardoptions(), vmsayname_exec(), wait_file2(), and xfer_park_call_helper().

01365 {
01366    int res = 0;
01367    if (!ast_strlen_zero(file)) {
01368       ast_test_suite_event_notify("PLAYBACK", "Message: %s", file);
01369       res = ast_streamfile(chan, file, chan->language);
01370       if (!res) {
01371          res = ast_waitstream(chan, digits);
01372       }
01373    }
01374    return res;
01375 } 

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

References ast_seekstream(), and DEFAULT_SAMPLES_PER_MS.

Referenced by waitstream_core().

00898 {
00899    return ast_seekstream(fs, ms * DEFAULT_SAMPLES_PER_MS, SEEK_CUR);
00900 }

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

References ast_seekstream(), and DEFAULT_SAMPLES_PER_MS.

Referenced by handle_recordfile(), and waitstream_core().

00903 {
00904    return ast_seekstream(fs, -ms * DEFAULT_SAMPLES_PER_MS, SEEK_CUR);
00905 }

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 951 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(), parkandannounce_exec(), pbx_builtin_background(), pl_odtworz_plik(), play_and_wait(), play_file(), play_record_review(), playback_exec(), privacy_exec(), readexten_exec(), retrydial_exec(), s_streamwait3(), say_character_str_full(), say_digit_str_full(), say_phonetic_str_full(), select_item_menu(), setup_privacy_args(), vm_authenticate(), wait_file(), and wait_for_winner().

00952 {
00953    struct ast_filestream *fs;
00954    struct ast_filestream *vfs=NULL;
00955    char fmt[256];
00956    off_t pos;
00957    int seekattempt;
00958    int res;
00959 
00960    fs = ast_openstream(chan, filename, preflang);
00961    if (!fs) {
00962       ast_log(LOG_WARNING, "Unable to open %s (format %s): %s\n", filename, ast_getformatname_multiple(fmt, sizeof(fmt), chan->nativeformats), strerror(errno));
00963       return -1;
00964    }
00965 
00966    /* check to see if there is any data present (not a zero length file),
00967     * done this way because there is no where for ast_openstream_full to
00968     * return the file had no data. */
00969    pos = ftello(fs->f);
00970    seekattempt = fseeko(fs->f, -1, SEEK_END);
00971    if (seekattempt) {
00972       if (errno == EINVAL) {
00973          /* Zero-length file, as opposed to a pipe */
00974          return 0;
00975       } else {
00976          ast_seekstream(fs, 0, SEEK_SET);
00977       }
00978    } else {
00979       fseeko(fs->f, pos, SEEK_SET);
00980    }
00981 
00982    vfs = ast_openvstream(chan, filename, preflang);
00983    if (vfs) {
00984       ast_debug(1, "Ooh, found a video stream, too, format %s\n", ast_getformatname(vfs->fmt->format));
00985    }
00986 
00987    if (ast_test_flag(chan, AST_FLAG_MASQ_NOSTREAM))
00988       fs->orig_chan_name = ast_strdup(chan->name);
00989    if (ast_applystream(chan, fs))
00990       return -1;
00991    if (vfs && ast_applystream(chan, vfs))
00992       return -1;
00993    res = ast_playstream(fs);
00994    if (!res && vfs)
00995       res = ast_playstream(vfs);
00996    ast_verb(3, "<%s> Playing '%s.%s' (language '%s')\n", chan->name, filename, ast_getformatname(chan->writeformat), preflang ? preflang : "default");
00997 
00998    return res;
00999 }

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

00893 {
00894    return fs->fmt->tell(fs);
00895 }

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

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

Referenced by handle_recordfile().

00888 {
00889    return fs->fmt->trunc(fs);
00890 }

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 1337 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(), parkandannounce_exec(), pbx_builtin_background(), pl_odtworz_plik(), play_and_wait(), play_file(), play_record_review(), playback_exec(), privacy_exec(), retrydial_exec(), s_streamwait3(), say_character_str_full(), say_digit_str_full(), say_phonetic_str_full(), select_item_menu(), setup_privacy_args(), vm_authenticate(), and wait_file().

01338 {
01339    return waitstream_core(c, breakon, NULL, NULL, 0, -1, -1, NULL);
01340 }

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

References ast_channel::context, and waitstream_core().

Referenced by pbx_builtin_background().

01349 {
01350    /* Waitstream, with return in the case of a valid 1 digit extension */
01351    /* in the current or specified context being pressed */
01352 
01353    if (!context)
01354       context = c->context;
01355    return waitstream_core(c, NULL, NULL, NULL, 0,
01356       -1, -1, context);
01357 }

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

References waitstream_core().

Referenced by ast_control_streamfile().

01332 {
01333    return waitstream_core(c, breakon, forward, reverse, ms,
01334       -1 /* no audiofd */, -1 /* no cmdfd */, NULL /* no context */);
01335 }

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

01343 {
01344    return waitstream_core(c, breakon, NULL, NULL, 0,
01345       audiofd, cmdfd, NULL /* no context */);
01346 }

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

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

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

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

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

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

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

Definition at line 215 of file file.c.

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

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

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

Definition at line 282 of file file.c.

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

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

00283 {
00284    char tmp[256];
00285    char *stringp = tmp, *ext;
00286 
00287    ast_copy_string(tmp, exts, sizeof(tmp));
00288    while ((ext = strsep(&stringp, "|"))) {
00289       if (!strcmp(ext, type))
00290          return 1;
00291    }
00292 
00293    return 0;
00294 }

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

00587 {
00588    format_t res = -1;
00589    char *lang;
00590 
00591    if (buf == NULL) {
00592       return -1;
00593    }
00594 
00595    /* We try languages in the following order:
00596     *    preflang (may include dialect and style codes)
00597     *    lang (preflang without dialect - if any)
00598     *    <none>
00599     *    default (unless the same as preflang or lang without dialect)
00600     */
00601 
00602    lang = ast_strdupa(preflang);
00603 
00604    /* Try preferred language, including removing any style or dialect codes */
00605    while (!ast_strlen_zero(lang)) {
00606       char *end;
00607 
00608       if ((res = fileexists_test(filename, fmt, lang, buf, buflen)) > 0) {
00609          return res;
00610       }
00611 
00612       if ((end = strrchr(lang, '_')) != NULL) {
00613          *end = '\0';
00614          continue;
00615       }
00616 
00617       break;
00618    }
00619 
00620    /* Try without any language */
00621    if ((res = fileexists_test(filename, fmt, NULL, buf, buflen)) > 0) {
00622       return res;
00623    }
00624 
00625    /* Finally try the default language unless it was already tried before */
00626    if ((ast_strlen_zero(preflang) || strcmp(preflang, DEFAULT_LANGUAGE)) && (ast_strlen_zero(lang) || strcmp(lang, DEFAULT_LANGUAGE))) {
00627       if ((res = fileexists_test(filename, fmt, DEFAULT_LANGUAGE, buf, buflen)) > 0) {
00628          return res;
00629       }
00630    }
00631 
00632    return 0;
00633 }

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

Definition at line 551 of file file.c.

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

Referenced by fileexists_core().

00553 {
00554    if (buf == NULL) {
00555       return -1;
00556    }
00557 
00558    if (ast_language_is_prefix && !is_absolute_path(filename)) { /* new layout */
00559       if (lang) {
00560          snprintf(buf, buflen, "%s/%s", lang, filename);
00561       } else {
00562          snprintf(buf, buflen, "%s", filename);
00563       }
00564    } else { /* old layout */
00565       strcpy(buf, filename);  /* first copy the full string */
00566       if (lang) {
00567          /* insert the language and suffix if needed */
00568          const char *c = strrchr(filename, '/');
00569          int offset = c ? c - filename + 1 : 0; /* points right after the last '/' */
00570          snprintf(buf + offset, buflen - offset, "%s/%s", lang, filename + offset);
00571       }
00572    }
00573 
00574    return ast_filehelper(buf, NULL, fmt, ACTION_EXISTS);
00575 }

static void filestream_close ( struct ast_filestream f  )  [static]

Definition at line 297 of file file.c.

References AST_FORMAT_AUDIO_MASK, AST_FORMAT_VIDEO_MASK, ast_log(), AST_LOG_WARNING, AST_SCHED_DEL, ast_settimeout(), f, ast_format::format, and ast_format::name.

Referenced by ast_closestream(), and filestream_destructor().

00298 {
00299    /* Stop a running stream if there is one */
00300    if (f->owner) {
00301       if (f->fmt->format & AST_FORMAT_AUDIO_MASK) {
00302          f->owner->stream = NULL;
00303          AST_SCHED_DEL(f->owner->sched, f->owner->streamid);
00304          ast_settimeout(f->owner, 0, NULL, NULL);
00305       } else if (f->fmt->format & AST_FORMAT_VIDEO_MASK) {
00306          f->owner->vstream = NULL;
00307          AST_SCHED_DEL(f->owner->sched, f->owner->vstreamid);
00308       } else {
00309          ast_log(AST_LOG_WARNING, "Unable to schedule deletion of filestream with unsupported type %s\n", f->fmt->name);
00310       }
00311    }
00312 }

static void filestream_destructor ( void *  arg  )  [static]

Definition at line 314 of file file.c.

References ast_closestream(), ast_free, ast_module_unref(), ast_safe_fork(), ast_translator_free_path(), ast_format::close, f, filestream_close(), free, ast_format::module, SENTINEL, and status.

Referenced by get_filestream().

00315 {
00316    struct ast_filestream *f = arg;
00317    int status;
00318    int pid = -1;
00319 
00320    /* Stop a running stream if there is one */
00321    filestream_close(f);
00322 
00323    /* destroy the translator on exit */
00324    if (f->trans)
00325       ast_translator_free_path(f->trans);
00326 
00327    if (f->realfilename && f->filename) {
00328       pid = ast_safe_fork(0);
00329       if (!pid) {
00330          execl("/bin/mv", "mv", "-f", f->filename, f->realfilename, SENTINEL);
00331          _exit(1);
00332       }
00333       else if (pid > 0) {
00334          /* Block the parent until the move is complete.*/
00335          waitpid(pid, &status, 0);
00336       }
00337    }
00338 
00339    if (f->filename)
00340       free(f->filename);
00341    if (f->realfilename)
00342       free(f->realfilename);
00343    if (f->fmt->close) {
00344       void (*closefn)(struct ast_filestream *) = f->fmt->close;
00345       closefn(f);
00346    }
00347    if (f->f)
00348       fclose(f->f);
00349    if (f->vfs)
00350       ast_closestream(f->vfs);
00351    if (f->write_buffer) {
00352       ast_free(f->write_buffer);
00353    }
00354    if (f->orig_chan_name)
00355       free((void *) f->orig_chan_name);
00356    ast_module_unref(f->fmt->module);
00357 }

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

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

00384 {
00385    struct ast_format *f = s->fmt;
00386    int ret = -1;
00387    int (*openfn)(struct ast_filestream *s);
00388 
00389    if (mode == WRAP_OPEN && (openfn = f->open) && openfn(s))
00390       ast_log(LOG_WARNING, "Unable to open format %s\n", f->name);
00391    else if (mode == WRAP_REWRITE && f->rewrite && f->rewrite(s, comment))
00392       ast_log(LOG_WARNING, "Unable to rewrite format %s\n", f->name);
00393    else {
00394       /* preliminary checks succeed. update usecount */
00395       ast_module_ref(f->module);
00396       ret = 0;
00397    }
00398    return ret;
00399 }

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

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

00360 {
00361    struct ast_filestream *s;
00362 
00363    int l = sizeof(*s) + fmt->buf_size + fmt->desc_size;  /* total allocation size */
00364    if ( (s = ao2_alloc(l, filestream_destructor)) == NULL)
00365       return NULL;
00366    s->fmt = fmt;
00367    s->f = bfile;
00368 
00369    if (fmt->desc_size)
00370       s->_private = ((char *)(s + 1)) + fmt->buf_size;
00371    if (fmt->buf_size)
00372       s->buf = (char *)(s + 1);
00373    s->fr.src = fmt->name;
00374    return s;
00375 }

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

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

01454 {
01455 #define FORMAT "%-10s %-10s %-20s\n"
01456 #define FORMAT2 "%-10s %-10s %-20s\n"
01457    struct ast_format *f;
01458    int count_fmt = 0;
01459 
01460    switch (cmd) {
01461    case CLI_INIT:
01462       e->command = "core show file formats";
01463       e->usage =
01464          "Usage: core show file formats\n"
01465          "       Displays currently registered file formats (if any).\n";
01466       return NULL;
01467    case CLI_GENERATE:
01468       return NULL;
01469    }
01470 
01471    if (a->argc != 4)
01472       return CLI_SHOWUSAGE;
01473 
01474    ast_cli(a->fd, FORMAT, "Format", "Name", "Extensions");
01475    ast_cli(a->fd, FORMAT, "------", "----", "----------");
01476 
01477    AST_RWLIST_RDLOCK(&formats);
01478    AST_RWLIST_TRAVERSE(&formats, f, list) {
01479       ast_cli(a->fd, FORMAT2, ast_getformatname(f->format), f->name, f->exts);
01480       count_fmt++;
01481    }
01482    AST_RWLIST_UNLOCK(&formats);
01483    ast_cli(a->fd, "%d file formats registered.\n", count_fmt);
01484    return CLI_SUCCESS;
01485 #undef FORMAT
01486 #undef FORMAT2
01487 }

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

Definition at line 546 of file file.c.

Referenced by fileexists_test().

00547 {
00548    return filename[0] == '/';
00549 }

static int open_wrapper ( struct ast_filestream s  )  [static]

Definition at line 406 of file file.c.

References fn_wrapper(), and WRAP_OPEN.

Referenced by ast_filehelper(), and ast_readfile().

00407 {
00408    return fn_wrapper(s, NULL, WRAP_OPEN);
00409 }

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

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

00716 {
00717    struct ast_frame *fr, *new_fr;
00718 
00719    if (!s || !s->fmt) {
00720       return NULL;
00721    }
00722 
00723    if (!(fr = s->fmt->read(s, whennext))) {
00724       return NULL;
00725    }
00726 
00727    if (!(new_fr = ast_frisolate(fr))) {
00728       ast_frfree(fr);
00729       return NULL;
00730    }
00731 
00732    if (new_fr != fr) {
00733       ast_frfree(fr);
00734       fr = new_fr;
00735    }
00736 
00737    return fr;
00738 }

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

Definition at line 401 of file file.c.

References fn_wrapper().

Referenced by ast_writefile().

00402 {
00403    return fn_wrapper(s, comment, WRAP_REWRITE);
00404 }

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 1184 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_UPDATE_RTP_PEER, 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().

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


Variable Documentation

int ast_language_is_prefix = 1

Definition at line 63 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 1489 of file file.c.

Referenced by ast_file_init().


Generated on Mon Oct 8 12:39:22 2012 for Asterisk - The Open Source Telephony Project by  doxygen 1.4.7