Mon Mar 19 11:30:47 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 407 of file file.c.

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

enum fsread_res

Enumerator:
FSREAD_FAILURE 
FSREAD_SUCCESS_SCHED 
FSREAD_SUCCESS_NOSCHED 

Definition at line 743 of file file.c.

00743                 {
00744    FSREAD_FAILURE,
00745    FSREAD_SUCCESS_SCHED,
00746    FSREAD_SUCCESS_NOSCHED,
00747 };

enum wrap_fn

Enumerator:
WRAP_OPEN 
WRAP_REWRITE 

Definition at line 377 of file file.c.

00377 { 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 63 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.

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

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

References ast_filestream::owner.

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

00861 {
00862    s->owner = chan;
00863    return 0;
00864 }

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

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

int ast_file_init ( void   ) 

Provided by file.c

Definition at line 1489 of file file.c.

References ARRAY_LEN, ast_cli_register_multiple(), and cli_file.

01490 {
01491    ast_cli_register_multiple(cli_file, ARRAY_LEN(cli_file));
01492    return 0;
01493 }

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

References ast_filehelper().

Referenced by copy_plain_file(), and vm_forwardoptions().

00943 {
00944    return ast_filehelper(filename, filename2, fmt, ACTION_COPY);
00945 }

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

00933 {
00934    return ast_filehelper(filename, NULL, fmt, ACTION_DELETE);
00935 }

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 918 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(), get_folder(), 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().

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

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

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

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

00938 {
00939    return ast_filehelper(filename, filename2, fmt, ACTION_RENAME);
00940 }

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

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

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

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

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

Definition at line 800 of file file.c.

References ast_readaudio_callback(), and FSREAD_SUCCESS_SCHED.

Referenced by ast_readaudio_callback().

00801 {
00802    struct ast_filestream *fs = (struct ast_filestream *)data;
00803    enum fsread_res res;
00804 
00805    res = ast_readaudio_callback(fs);
00806 
00807    if (res == FSREAD_SUCCESS_SCHED)
00808       return 1;
00809    
00810    return 0;
00811 }

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

Definition at line 847 of file file.c.

References ast_readvideo_callback(), and FSREAD_SUCCESS_SCHED.

Referenced by ast_readvideo_callback().

00848 {
00849    struct ast_filestream *fs = (struct ast_filestream *)data;
00850    enum fsread_res res;
00851 
00852    res = ast_readvideo_callback(fs);
00853 
00854    if (res == FSREAD_SUCCESS_SCHED)
00855       return 1;
00856    
00857    return 0;
00858 }

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

References ast_openstream_full().

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

00632 {
00633    return ast_openstream_full(chan, filename, preflang, 0);
00634 }

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

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

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

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

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

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

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

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

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

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

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

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

References read_frame().

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

00737 {
00738    int whennext = 0;
00739 
00740    return read_frame(s, &whennext);
00741 }

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

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

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

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

00879 {
00880    return fs->fmt->seek(fs, sample_offset, whence);
00881 }

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

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

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

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

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

References ast_seekstream(), and DEFAULT_SAMPLES_PER_MS.

Referenced by waitstream_core().

00894 {
00895    return ast_seekstream(fs, ms * DEFAULT_SAMPLES_PER_MS, SEEK_CUR);
00896 }

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

References ast_seekstream(), and DEFAULT_SAMPLES_PER_MS.

Referenced by handle_recordfile(), and waitstream_core().

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

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

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

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

00889 {
00890    return fs->fmt->tell(fs);
00891 }

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

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

Referenced by handle_recordfile().

00884 {
00885    return fs->fmt->trunc(fs);
00886 }

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

01334 {
01335    return waitstream_core(c, breakon, NULL, NULL, 0, -1, -1, NULL);
01336 }

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

References ast_channel::context, and waitstream_core().

Referenced by pbx_builtin_background().

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

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

References waitstream_core().

Referenced by ast_control_streamfile().

01328 {
01329    return waitstream_core(c, breakon, forward, reverse, ms,
01330       -1 /* no audiofd */, -1 /* no cmdfd */, NULL /* no context */);
01331 }

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

01339 {
01340    return waitstream_core(c, breakon, NULL, NULL, 0,
01341       audiofd, cmdfd, NULL /* no context */);
01342 }

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

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

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

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

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

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

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

Definition at line 211 of file file.c.

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

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

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

Definition at line 278 of file file.c.

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

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

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

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

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

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

Definition at line 547 of file file.c.

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

Referenced by fileexists_core().

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

static void filestream_close ( struct ast_filestream f  )  [static]

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

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 if (f->fmt->format & AST_FORMAT_VIDEO_MASK) {
00302          f->owner->vstream = NULL;
00303          AST_SCHED_DEL(f->owner->sched, f->owner->vstreamid);
00304       } else {
00305          ast_log(AST_LOG_WARNING, "Unable to schedule deletion of filestream with unsupported type %s\n", f->fmt->name);
00306       }
00307    }
00308 }

static void filestream_destructor ( void *  arg  )  [static]

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

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

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

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

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

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

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

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

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

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

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

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

Definition at line 542 of file file.c.

Referenced by fileexists_test().

00543 {
00544    return filename[0] == '/';
00545 }

static int open_wrapper ( struct ast_filestream s  )  [static]

Definition at line 402 of file file.c.

References fn_wrapper(), and WRAP_OPEN.

Referenced by ast_filehelper(), and ast_readfile().

00403 {
00404    return fn_wrapper(s, NULL, WRAP_OPEN);
00405 }

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

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

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

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

Definition at line 397 of file file.c.

References fn_wrapper().

Referenced by ast_writefile().

00398 {
00399    return fn_wrapper(s, comment, WRAP_REWRITE);
00400 }

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

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


Variable Documentation

int ast_language_is_prefix = 1

Definition at line 59 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 1485 of file file.c.

Referenced by ast_file_init().


Generated on Mon Mar 19 11:30:47 2012 for Asterisk - The Open Source Telephony Project by  doxygen 1.4.7