Thu Oct 11 06:48:50 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 <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 dependency graph for file.c:

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.
static void __fini_formats (void)
static void __init_formats (void)
int ast_applystream (struct ast_channel *chan, struct ast_filestream *s)
 Applys a open stream to a channel.
int ast_closestream (struct ast_filestream *f)
 Closes a stream.
int ast_file_init (void)
int ast_filecopy (const char *filename, const char *filename2, const char *fmt)
 Copies a file.
int ast_filedelete (const char *filename, const char *fmt)
 Deletes a file.
int ast_fileexists (const char *filename, const char *fmt, const char *preflang)
 Checks for the existence of a given file.
static int ast_filehelper (const char *filename, const void *arg2, const char *fmt, const enum file_action action)
 perform various actions on a file. Second argument arg2 depends on the command: unused for EXISTS and DELETE destination file name (const char *) for COPY and RENAME struct ast_channel * for OPEN if fmt is NULL, OPEN will return the first matching entry, whereas other functions will run on all matching entries.
int ast_filerename (const char *filename, const char *filename2, const char *fmt)
 Renames a file.
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)
struct ast_filestreamast_openstream (struct ast_channel *chan, const char *filename, const char *preflang)
 Opens stream for use in seeking, playing.
struct ast_filestreamast_openstream_full (struct ast_channel *chan, const char *filename, const char *preflang, int asis)
 Opens stream for use in seeking, playing.
struct 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)
struct ast_filestreamast_readfile (const char *filename, const char *type, const char *comment, int flags, int check, mode_t mode)
 Starts reading from a file.
struct 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)
struct ast_filestreamast_writefile (const char *filename, const char *type, const char *comment, int flags, int check, mode_t mode)
 Starts writing a file.
int ast_writestream (struct ast_filestream *fs, struct ast_frame *f)
 Writes a frame to a stream.
static char * build_filename (const char *filename, const char *ext)
 construct a filename. Absolute pathnames are preserved, relative names are prefixed by the sounds/ directory. The wav49 suffix is replaced by 'WAV'. Returns a malloc'ed string to be freed by the caller.
static int copy (const char *infile, const char *outfile)
static int exts_compare (const char *exts, const char *type)
static int fileexists_core (const char *filename, const char *fmt, const char *preflang, char *buf, int buflen)
 helper routine to locate a file with a given format and language preference. Try preflang, preflang with stripped '_' suffix, or NULL. In the standard asterisk, language goes just before the last component. In an alternative configuration, the language should be a prefix to the actual filename.
static int fileexists_test (const char *filename, const char *fmt, const char *lang, char *buf, int buflen)
static void filestream_destructor (void *arg)
static int fn_wrapper (struct ast_filestream *s, const char *comment, enum wrap_fn mode)
static struct ast_filestreamget_filestream (struct ast_format *fmt, FILE *bfile)
static char * handle_cli_core_show_file_formats (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static int is_absolute_path (const char *filename)
static int open_wrapper (struct ast_filestream *s)
static 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
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

Enumerator:
ACTION_EXISTS 
ACTION_DELETE 
ACTION_RENAME 
ACTION_OPEN 
ACTION_COPY 

Definition at line 391 of file file.c.

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

enum fsread_res

Enumerator:
FSREAD_FAILURE 
FSREAD_SUCCESS_SCHED 
FSREAD_SUCCESS_NOSCHED 

Definition at line 730 of file file.c.

00730                 {
00731    FSREAD_FAILURE,
00732    FSREAD_SUCCESS_SCHED,
00733    FSREAD_SUCCESS_NOSCHED,
00734 };

enum wrap_fn

Enumerator:
WRAP_OPEN 
WRAP_REWRITE 

Definition at line 361 of file file.c.

00361 { WRAP_OPEN, WRAP_REWRITE };


Function Documentation

int __ast_format_register ( const struct ast_format f,
struct ast_module mod 
)

Register a new file format capability. Adds a format to Asterisk's format abilities.

Return values:
0 on success
-1 on failure

Definition at line 61 of file file.c.

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

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

static void __fini_formats ( void   )  [static]

Definition at line 59 of file file.c.

00062 {

static void __init_formats ( void   )  [static]

Definition at line 59 of file file.c.

00062 {

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

References ast_filestream::owner.

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

00848 {
00849    s->owner = chan;
00850    return 0;
00851 }

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

References ao2_ref, AST_FORMAT_AUDIO_MASK, AST_SCHED_DEL, ast_settimeout(), ast_filestream::fmt, ast_format::format, ast_filestream::owner, ast_channel::sched, ast_channel::stream, ast_channel::streamid, ast_channel::vstream, and ast_channel::vstreamid.

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

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

int ast_file_init ( void   ) 

Provided by file.c

Definition at line 1476 of file file.c.

References ARRAY_LEN, and ast_cli_register_multiple().

Referenced by main().

01477 {
01478    ast_cli_register_multiple(cli_file, ARRAY_LEN(cli_file));
01479    return 0;
01480 }

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

References ACTION_COPY, and ast_filehelper().

Referenced by copy_plain_file(), and vm_forwardoptions().

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

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

References ACTION_DELETE, and ast_filehelper().

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

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

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

References buf, and fileexists_core().

Referenced by announce_thread(), app_exec(), ast_moh_files_next(), ast_monitor_start(), ast_monitor_stop(), common_exec(), dial_exec_full(), eivr_comm(), forward_message(), function_playback(), invent_message(), leave_voicemail(), minivm_delete_exec(), play_file(), play_message(), play_message_callerid(), record_exec(), retrydial_exec(), rpt_tele_thread(), say_character_str_full(), say_digit_str_full(), say_phonetic_str_full(), sayname(), saynode(), setup_privacy_args(), vm_intro(), vm_newuser(), vm_options(), and vm_tempgreeting().

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

static int ast_filehelper ( const char *  filename,
const void *  arg2,
const char *  fmt,
const enum file_action  action 
) [static]

perform various actions on a file. Second argument arg2 depends on the command: unused for EXISTS and DELETE destination file name (const char *) for COPY and RENAME struct ast_channel * for OPEN if fmt is NULL, OPEN will return the first matching entry, whereas other functions will run on all matching entries.

Definition at line 408 of file file.c.

References ACTION_COPY, ACTION_DELETE, ACTION_EXISTS, ACTION_OPEN, ACTION_RENAME, ast_closestream(), AST_FORMAT_AUDIO_MASK, AST_FORMAT_VIDEO_MASK, ast_free, ast_log(), AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_strdupa, build_filename(), chan, copy(), errno, ext, ast_format::exts, exts_compare(), f, ast_filestream::filename, ast_filestream::fmt, ast_format::format, get_filestream(), ast_filestream::lasttimeout, ast_format::list, LOG_WARNING, open_wrapper(), s, 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().

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

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

References ACTION_RENAME, and ast_filehelper().

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

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

char* ast_format_str_reduce ( char *  fmts  ) 

Remove duplicate formats from a format string.

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

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

Referenced by load_config().

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

int ast_format_unregister ( const char *  name  ) 

Unregisters a file format.

Parameters:
name the name of the format you wish to unregister Unregisters a format based on the name of the format.
Return values:
0 on success
-1 on failure to unregister

Definition at line 98 of file file.c.

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

Referenced by unload_module().

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

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

Definition at line 787 of file file.c.

References ast_readaudio_callback(), and FSREAD_SUCCESS_SCHED.

Referenced by ast_readaudio_callback().

00788 {
00789    struct ast_filestream *fs = (struct ast_filestream *)data;
00790    enum fsread_res res;
00791 
00792    res = ast_readaudio_callback(fs);
00793 
00794    if (res == FSREAD_SUCCESS_SCHED)
00795       return 1;
00796    
00797    return 0;
00798 }

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

Definition at line 834 of file file.c.

References ast_readvideo_callback(), and FSREAD_SUCCESS_SCHED.

Referenced by ast_readvideo_callback().

00835 {
00836    struct ast_filestream *fs = (struct ast_filestream *)data;
00837    enum fsread_res res;
00838 
00839    res = ast_readvideo_callback(fs);
00840 
00841    if (res == FSREAD_SUCCESS_SCHED)
00842       return 1;
00843    
00844    return 0;
00845 }

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

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

References ast_openstream_full().

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

00620 {
00621    return ast_openstream_full(chan, filename, preflang, 0);
00622 }

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

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

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

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

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

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

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

References ACTION_OPEN, ast_filehelper(), AST_FORMAT_AUDIO_MASK, AST_FORMAT_VIDEO_MASK, ast_getformatname(), ast_log(), 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().

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

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

00854 {
00855    enum fsread_res res;
00856 
00857    if (s->fmt->format & AST_FORMAT_AUDIO_MASK)
00858       res = ast_readaudio_callback(s);
00859    else
00860       res = ast_readvideo_callback(s);
00861 
00862    return (res == FSREAD_FAILURE) ? -1 : 0;
00863 }

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

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

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

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

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

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

Referenced by __ast_play_and_record(), and handle_cli_file_convert().

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

struct ast_frame* ast_readframe ( struct ast_filestream s  )  [read]

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

References read_frame().

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

00724 {
00725    int whennext = 0;
00726 
00727    return read_frame(s, &whennext);
00728 }

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

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

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

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

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

Referenced by __ast_read(), ast_control_streamfile(), ast_moh_files_next(), ast_stream_fastforward(), ast_stream_rewind(), ast_streamfile(), ast_write(), dictate_exec(), handle_getoption(), handle_recordfile(), handle_streamfile(), and speech_streamfile().

00866 {
00867    return fs->fmt->seek(fs, sample_offset, whence);
00868 }

int ast_stopstream ( struct ast_channel c  ) 

Stops a stream.

Parameters:
c The channel you wish to stop playback on
Stop playback of a stream

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

Definition at line 122 of file file.c.

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

Referenced by _ast_adsi_transmit_message_full(), ast_control_streamfile(), ast_openstream_full(), ast_play_and_wait(), ast_readstring_full(), ast_say_enumeration_full_da(), ast_say_enumeration_full_de(), ast_say_enumeration_full_en(), ast_say_enumeration_full_he(), ast_say_number_full_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_zh(), background_detect_exec(), builtin_blindtransfer(), conf_exec(), conf_run(), dial_exec_full(), directory_exec(), grab_transfer(), handle_getoption(), handle_speechrecognize(), handle_streamfile(), ices_exec(), ivr_dispatch(), leave_voicemail(), menu_callback(), minivm_greet_exec(), mp3_exec(), NBScat_exec(), parkandannounce_exec(), pbx_builtin_background(), pl_odtworz_plik(), play_file(), play_mailbox_owner(), playback_exec(), queue_exec(), read_exec(), readexten_exec(), record_exec(), recordthread(), rpt_tele_thread(), s_streamwait3(), say_character_str_full(), say_digit_str_full(), say_phonetic_str_full(), saycharstr(), sayfile(), saynum(), select_item_seq(), send_morse(), send_tone_telemetry(), send_waveform_to_channel(), speech_background(), vm_authenticate(), vm_execmain(), wait_for_winner(), waitstream_core(), and zapateller_exec().

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

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

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

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

Definition at line 1348 of file file.c.

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

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

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

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

References ast_seekstream(), and DEFAULT_SAMPLES_PER_MS.

Referenced by waitstream_core().

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

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

References ast_seekstream(), and DEFAULT_SAMPLES_PER_MS.

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

00886 {
00887    return ast_seekstream(fs, -ms * DEFAULT_SAMPLES_PER_MS, SEEK_CUR);
00888 }

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 946 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 action_bridge(), agent_call(), announce_thread(), app_exec(), ast_app_getdata(), ast_app_getdata_full(), ast_control_streamfile(), ast_play_and_wait(), ast_say_date_da(), ast_say_date_de(), ast_say_date_en(), ast_say_date_fr(), ast_say_date_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_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_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(), auth_exec(), background_detect_exec(), bridge_exec(), check_availability(), check_beep(), common_exec(), conf_exec(), conf_run(), dial_exec_full(), do_directory(), find_conf_realtime(), forward_message(), gr_say_number_female(), handle_recordfile(), invent_message(), leave_voicemail(), local_attended_transfer(), login_exec(), menu_callback(), minivm_greet_exec(), page_exec(), park_exec_full(), parkandannounce_exec(), pbx_builtin_background(), pl_odtworz_plik(), play_and_wait(), play_file(), play_record_review(), playback_exec(), privacy_exec(), readexten_exec(), record_exec(), retrydial_exec(), rpt_tele_thread(), s_streamwait3(), say_character_str_full(), say_digit_str_full(), say_phonetic_str_full(), sayfile(), select_item_menu(), setup_privacy_args(), ss_thread(), vm_authenticate(), wait_file(), and wait_for_winner().

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

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

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

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

00876 {
00877    return fs->fmt->tell(fs);
00878 }

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

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

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

00871 {
00872    return fs->fmt->trunc(fs);
00873 }

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

References waitstream_core().

Referenced by action_bridge(), agent_call(), announce_thread(), app_exec(), ast_play_and_wait(), ast_say_date_da(), ast_say_date_de(), ast_say_date_en(), ast_say_date_fr(), ast_say_date_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_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_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(), auth_exec(), bridge_exec(), check_availability(), check_beep(), common_exec(), conf_exec(), conf_run(), directory_exec(), find_conf_realtime(), gr_say_number_female(), handle_recordfile(), invent_message(), leave_voicemail(), local_attended_transfer(), login_exec(), menu_callback(), minivm_greet_exec(), page_exec(), park_exec_full(), parkandannounce_exec(), pbx_builtin_background(), pl_odtworz_plik(), play_and_wait(), play_file(), play_record_review(), playback_exec(), privacy_exec(), record_exec(), retrydial_exec(), rpt_tele_thread(), s_streamwait3(), say_character_str_full(), say_digit_str_full(), say_phonetic_str_full(), saycharstr(), sayfile(), saynum(), select_item_menu(), send_morse(), send_tone_telemetry(), setup_privacy_args(), ss_thread(), vm_authenticate(), and wait_file().

01322 {
01323    return waitstream_core(c, breakon, NULL, NULL, 0, -1, -1, NULL);
01324 }

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

References ast_channel::context, and waitstream_core().

Referenced by pbx_builtin_background().

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

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

References waitstream_core().

Referenced by ast_control_streamfile().

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

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

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

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

References ast_closestream(), ast_free, ast_log(), ast_malloc, ast_opt_cache_record_files, AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_strdup, ast_strdupa, buf, build_filename(), errno, ast_format::exts, exts_compare(), 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(), record_exec(), recordthread(), and rpt().

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

int ast_writestream ( struct ast_filestream fs,
struct ast_frame f 
)

Writes a frame to a stream.

Parameters:
fs filestream to write to
f frame to write to the filestream Send a frame to a filestream -- note: does NOT free the frame, call ast_frfree manually
Return values:
0 on success.
-1 on failure.

Definition at line 144 of file file.c.

References ast_debug, AST_FORMAT_AUDIO_MASK, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_frfree, ast_getformatname(), AST_LIST_NEXT, ast_log(), ast_translate(), ast_translator_build_path(), ast_translator_free_path(), ast_writefile(), ast_writestream(), ast_filestream::filename, ast_filestream::flags, ast_filestream::fmt, ast_format::format, ast_frame::frametype, ast_filestream::lastwriteformat, LOG_WARNING, ast_filestream::mode, ast_format::name, ast_frame::subclass, 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(), record_exec(), recordthread(), and rpt().

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

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

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

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

Definition at line 209 of file file.c.

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

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

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

Definition at line 276 of file file.c.

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

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

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

static int fileexists_core ( const char *  filename,
const char *  fmt,
const char *  preflang,
char *  buf,
int  buflen 
) [static]

helper routine to locate a file with a given format and language preference. Try preflang, preflang with stripped '_' suffix, or NULL. In the standard asterisk, language goes just before the last component. In an alternative configuration, the language should be a prefix to the actual filename.

The last parameter(s) point to a buffer of sufficient size, which on success is filled with the matching filename.

Definition at line 568 of file file.c.

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

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

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

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

Definition at line 531 of file file.c.

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

Referenced by fileexists_core().

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

static void filestream_destructor ( void *  arg  )  [static]

Definition at line 290 of file file.c.

References ast_closestream(), AST_FORMAT_AUDIO_MASK, ast_free, ast_module_unref(), ast_safe_system(), AST_SCHED_DEL, ast_settimeout(), ast_translator_free_path(), ast_format::close, ast_filestream::f, f, ast_filestream::filename, ast_filestream::fmt, ast_format::format, free, ast_format::module, ast_filestream::orig_chan_name, ast_filestream::owner, ast_filestream::realfilename, ast_channel::sched, ast_channel::stream, ast_channel::streamid, ast_filestream::trans, ast_filestream::vfs, ast_channel::vstream, ast_channel::vstreamid, and ast_filestream::write_buffer.

Referenced by get_filestream().

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

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

Definition at line 363 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, WRAP_OPEN, and WRAP_REWRITE.

Referenced by open_wrapper(), and rewrite_wrapper().

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

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

Definition at line 339 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, s, and ast_frame::src.

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

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

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

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

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

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

Definition at line 526 of file file.c.

Referenced by fileexists_test().

00527 {
00528    return filename[0] == '/';
00529 }

static int open_wrapper ( struct ast_filestream s  )  [static]

Definition at line 386 of file file.c.

References fn_wrapper(), and WRAP_OPEN.

Referenced by ast_filehelper(), and ast_readfile().

00387 {
00388    return fn_wrapper(s, NULL, WRAP_OPEN);
00389 }

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

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

00699 {
00700    struct ast_frame *fr, *new_fr;
00701 
00702    if (!s || !s->fmt) {
00703       return NULL;
00704    }
00705 
00706    if (!(fr = s->fmt->read(s, whennext))) {
00707       return NULL;
00708    }
00709 
00710    if (!(new_fr = ast_frisolate(fr))) {
00711       ast_frfree(fr);
00712       return NULL;
00713    }
00714 
00715    if (new_fr != fr) {
00716       ast_frfree(fr);
00717       fr = new_fr;
00718    }
00719 
00720    return fr;
00721 }

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

Definition at line 381 of file file.c.

References fn_wrapper(), and WRAP_REWRITE.

Referenced by ast_writefile().

00382 {
00383    return fn_wrapper(s, comment, WRAP_REWRITE);
00384 }

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

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

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

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


Variable Documentation

Definition at line 57 of file file.c.

Referenced by ast_readconfig(), handle_show_settings(), and main().

Initial value:

 {
   AST_CLI_DEFINE(handle_cli_core_show_file_formats, "Displays file formats")
}

Definition at line 1472 of file file.c.


Generated on Thu Oct 11 06:48:50 2012 for Asterisk - the Open Source PBX by  doxygen 1.5.6