Thu Oct 11 06:43:29 2012

Asterisk developer's documentation


file.c File Reference

Generic File Format Support. More...

#include "asterisk.h"
#include <sys/types.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <fcntl.h>
#include <dirent.h>
#include <sys/stat.h>
#include "asterisk/frame.h"
#include "asterisk/file.h"
#include "asterisk/cli.h"
#include "asterisk/logger.h"
#include "asterisk/channel.h"
#include "asterisk/sched.h"
#include "asterisk/options.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/dahdi_compat.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 FORMAT   "%-10s %-10s %-20s\n"
#define FORMAT2   "%-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)
int ast_applystream (struct ast_channel *chan, struct ast_filestream *s)
int ast_closestream (struct ast_filestream *f)
int ast_file_init (void)
int ast_filecopy (const char *filename, const char *filename2, const char *fmt)
int ast_filedelete (const char *filename, const char *fmt)
int ast_fileexists (const char *filename, const char *fmt, const char *preflang)
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)
char * ast_format_str_reduce (char *fmts)
int ast_format_unregister (const char *name)
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)
struct ast_filestreamast_openstream_full (struct ast_channel *chan, const char *filename, const char *preflang, int asis)
struct ast_filestreamast_openvstream (struct ast_channel *chan, const char *filename, const char *preflang)
int ast_playstream (struct ast_filestream *s)
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)
struct ast_frameast_readframe (struct ast_filestream *s)
static enum fsread_res ast_readvideo_callback (struct ast_filestream *s)
int ast_seekstream (struct ast_filestream *fs, off_t sample_offset, int whence)
int ast_stopstream (struct ast_channel *tmp)
 Stops a stream.
int ast_stream_and_wait (struct ast_channel *chan, const char *file, const char *language, const char *digits)
int ast_stream_fastforward (struct ast_filestream *fs, off_t ms)
int ast_stream_rewind (struct ast_filestream *fs, off_t ms)
int ast_streamfile (struct ast_channel *chan, const char *filename, const char *preflang)
off_t ast_tellstream (struct ast_filestream *fs)
int ast_truncstream (struct ast_filestream *fs)
int ast_waitstream (struct ast_channel *c, const char *breakon)
int ast_waitstream_exten (struct ast_channel *c, const char *context)
int ast_waitstream_fr (struct ast_channel *c, const char *breakon, const char *forward, const char *rewind, int ms)
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)
int ast_writestream (struct ast_filestream *fs, struct ast_frame *f)
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 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 show_file_formats (int fd, int argc, char *argv[])
static int show_file_formats_deprecated (int fd, int argc, char *argv[])
static int waitstream_core (struct ast_channel *c, const char *breakon, const char *forward, const char *rewind, int skip_ms, int audiofd, int cmdfd, const char *context)
 the core of all waitstream() functions

Variables

int ast_language_is_prefix
struct ast_cli_entry cli_file []
struct ast_cli_entry cli_show_file_formats_deprecated
char show_file_formats_usage []


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 FORMAT   "%-10s %-10s %-20s\n"

#define FORMAT2   "%-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 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 745 of file file.c.

00745                 {
00746    FSREAD_FAILURE,
00747    FSREAD_SUCCESS_SCHED,
00748    FSREAD_SUCCESS_NOSCHED,
00749 };

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. returns 0 on success, -1 on failure

Definition at line 70 of file file.c.

References ast_calloc, AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_verbose(), ast_format::buf_size, ast_format::exts, ast_format::list, LOG_WARNING, ast_format::module, ast_format::name, option_verbose, and VERBOSE_PREFIX_2.

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

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 Returns 0 for success, -1 on failure

Definition at line 869 of file file.c.

References ast_filestream::owner.

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

00870 {
00871    s->owner = chan;
00872    return 0;
00873 }

int ast_closestream ( struct ast_filestream f  ) 

Closes a stream

Parameters:
f filestream to close Close a playback or recording stream Returns 0 on success, -1 on failure

Definition at line 912 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(), cli_audio_convert(), cli_audio_convert_deprecated(), dictate_exec(), filestream_destructor(), gen_closestream(), handle_recordfile(), local_ast_moh_stop(), mixmonitor_ds_close_fs(), moh_files_release(), record_exec(), recordthread(), and rpt().

00913 {
00914    /* This used to destroy the filestream, but it now just decrements a refcount.
00915     * We need to force the stream to quit queuing frames now, because we might
00916     * change the writeformat, which could result in a subsequent write error, if
00917     * the format is different. */
00918 
00919    /* Stop a running stream if there is one */
00920    if (f->owner) {
00921       if (f->fmt->format < AST_FORMAT_AUDIO_MASK) {
00922          f->owner->stream = NULL;
00923          AST_SCHED_DEL(f->owner->sched, f->owner->streamid);
00924          ast_settimeout(f->owner, 0, NULL, NULL);
00925       } else {
00926          f->owner->vstream = NULL;
00927          AST_SCHED_DEL(f->owner->sched, f->owner->vstreamid);
00928       }
00929    }
00930 
00931    ao2_ref(f, -1);
00932    return 0;
00933 }

int ast_file_init ( void   ) 

Initialize file stuff

Initializes all the various file stuff. Basically just registers the cli stuff Returns 0 all the time

Definition at line 1511 of file file.c.

References ast_cli_register_multiple().

Referenced by main().

01512 {
01513    ast_cli_register_multiple(cli_file, sizeof(cli_file) / sizeof(struct ast_cli_entry));
01514    return 0;
01515 }

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

References ACTION_COPY, and ast_filehelper().

Referenced by copy_plain_file(), and vm_forwardoptions().

00964 {
00965    return ast_filehelper(filename, filename2, fmt, ACTION_COPY);
00966 }

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

References ACTION_DELETE, and ast_filehelper().

Referenced by __ast_play_and_record(), announce_thread(), ast_monitor_start(), ast_monitor_stop(), cli_audio_convert(), cli_audio_convert_deprecated(), conf_free(), conf_run(), leave_voicemail(), play_mailbox_owner(), play_record_review(), and vm_delete().

00954 {
00955    return ast_filehelper(filename, NULL, fmt, ACTION_DELETE);
00956 }

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 939 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(), forward_message(), leave_voicemail(), play_file(), play_greeting(), play_mailbox_owner(), play_message_callerid(), record_exec(), retrydial_exec(), say_character_str_full(), say_digit_str_full(), say_phonetic_str_full(), vm_intro(), vm_newuser(), vm_options(), and vm_tempgreeting().

00940 {
00941    char *buf;
00942    int buflen;
00943 
00944    if (preflang == NULL)
00945       preflang = "";
00946    buflen = strlen(preflang) + strlen(filename) + 4;  /* room for everything */
00947    buf = alloca(buflen);
00948    if (buf == NULL)
00949       return 0;
00950    return fileexists_core(filename, fmt, preflang, buf, buflen);
00951 }

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

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

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

00959 {
00960    return ast_filehelper(filename, filename2, fmt, ACTION_RENAME);
00961 }

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

References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), AST_MAX_FORMATS, ast_strdupa, ast_format::exts, exts_compare(), f, first, len(), ast_format::list, LOG_WARNING, and type.

Referenced by load_config().

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

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. Returns 0 on success, -1 on failure to unregister

Definition at line 111 of file file.c.

References AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_log(), ast_verbose(), free, ast_format::list, LOG_WARNING, ast_format::name, option_verbose, and VERBOSE_PREFIX_2.

Referenced by unload_module().

00112 {
00113    struct ast_format *tmp;
00114    int res = -1;
00115 
00116    if (AST_LIST_LOCK(&formats)) {
00117       ast_log(LOG_WARNING, "Unable to lock format list\n");
00118       return -1;
00119    }
00120    AST_LIST_TRAVERSE_SAFE_BEGIN(&formats, tmp, list) {
00121       if (!strcasecmp(name, tmp->name)) {
00122          AST_LIST_REMOVE_CURRENT(&formats, list);
00123          free(tmp);
00124          res = 0;
00125       }
00126    }
00127    AST_LIST_TRAVERSE_SAFE_END
00128    AST_LIST_UNLOCK(&formats);
00129 
00130    if (!res) {
00131       if (option_verbose > 1)
00132          ast_verbose( VERBOSE_PREFIX_2 "Unregistered format %s\n", name);
00133    } else
00134       ast_log(LOG_WARNING, "Tried to unregister format %s, already unregistered\n", name);
00135 
00136    return res;
00137 }

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

Definition at line 809 of file file.c.

References ast_readaudio_callback(), and FSREAD_SUCCESS_SCHED.

Referenced by ast_readaudio_callback().

00810 {
00811    struct ast_filestream *fs = (struct ast_filestream *)data;
00812    enum fsread_res res;
00813 
00814    res = ast_readaudio_callback(fs);
00815 
00816    if (res == FSREAD_SUCCESS_SCHED)
00817       return 1;
00818    
00819    return 0;
00820 }

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

Definition at line 856 of file file.c.

References ast_readvideo_callback(), and FSREAD_SUCCESS_SCHED.

Referenced by ast_readvideo_callback().

00857 {
00858    struct ast_filestream *fs = (struct ast_filestream *)data;
00859    enum fsread_res res;
00860 
00861    res = ast_readvideo_callback(fs);
00862 
00863    if (res == FSREAD_SUCCESS_SCHED)
00864       return 1;
00865    
00866    return 0;
00867 }

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 Returns a ast_filestream pointer if it opens the file, NULL on error

Definition at line 634 of file file.c.

References ast_openstream_full().

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

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

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 Returns a ast_filestream pointer if it opens the file, NULL on error

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

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

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 Returns a ast_filestream pointer if it opens the file, NULL on error

Definition at line 680 of file file.c.

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

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

int ast_playstream ( struct ast_filestream s  ) 

play a open stream on a channel.

Parameters:
s filestream to play Returns 0 for success, -1 on failure

Definition at line 875 of file file.c.

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

00876 {
00877    enum fsread_res res;
00878 
00879    if (s->fmt->format < AST_FORMAT_MAX_AUDIO)
00880       res = ast_readaudio_callback(s);
00881    else
00882       res = ast_readvideo_callback(s);
00883 
00884    return (res == FSREAD_FAILURE) ? -1 : 0;
00885 }

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

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

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

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. Returns a struct ast_filestream on success, NULL on failure

Definition at line 999 of file file.c.

References ast_closestream(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), build_filename(), errno, ast_format::exts, exts_compare(), f, ast_filestream::filename, ast_filestream::flags, ast_filestream::fmt, free, get_filestream(), LOG_WARNING, ast_filestream::mode, open_wrapper(), strdup, ast_filestream::trans, and ast_filestream::vfs.

Referenced by __ast_play_and_record(), cli_audio_convert(), and cli_audio_convert_deprecated().

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

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 or NULL if read failed

Definition at line 738 of file file.c.

References read_frame().

Referenced by __ast_play_and_record(), cli_audio_convert(), cli_audio_convert_deprecated(), dictate_exec(), gen_readframe(), and moh_files_readframe().

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

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

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

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

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 Returns 0 for success, or -1 for error

Definition at line 887 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_write(), dictate_exec(), handle_getoption(), handle_recordfile(), and handle_streamfile().

00888 {
00889    return fs->fmt->seek(fs, sample_offset, whence);
00890 }

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 139 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_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_zh(), background_detect_exec(), builtin_blindtransfer(), conf_exec(), conf_run(), directory_exec(), handle_getoption(), handle_streamfile(), ices_exec(), ivr_dispatch(), leave_voicemail(), mp3_exec(), NBScat_exec(), parkandannounce_exec(), pbx_builtin_background(), pl_odtworz_plik(), play_file(), play_mailbox_owner(), playback_exec(), queue_exec(), read_exec(), record_exec(), recordthread(), rpt_tele_thread(), s_streamwait3(), say_character_str_full(), say_digit_str_full(), say_phonetic_str_full(), saycharstr(), sayfile(), saynum(), send_morse(), send_tone_telemetry(), send_waveform_to_channel(), speech_background(), vm_authenticate(), vm_execmain(), wait_for_winner(), waitstream_core(), and zapateller_exec().

00140 {
00141    ast_channel_lock(tmp);
00142 
00143    /* Stop a running stream if there is one */
00144    if (tmp->stream) {
00145       ast_closestream(tmp->stream);
00146       tmp->stream = NULL;
00147       if (tmp->oldwriteformat && ast_set_write_format(tmp, tmp->oldwriteformat))
00148          ast_log(LOG_WARNING, "Unable to restore format back to %d\n", tmp->oldwriteformat);
00149    }
00150    /* Stop the video stream too */
00151    if (tmp->vstream != NULL) {
00152       ast_closestream(tmp->vstream);
00153       tmp->vstream = NULL;
00154    }
00155 
00156    ast_channel_unlock(tmp);
00157 
00158    return 0;
00159 }

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

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 Returns 0 for success, or -1 for error

Definition at line 902 of file file.c.

References ast_seekstream(), and DEFAULT_SAMPLES_PER_MS.

Referenced by waitstream_core().

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

int ast_stream_rewind ( struct ast_filestream fs,
off_t  ms 
)

Rewind stream ms

Parameters:
fs filestream to act on
ms milliseconds to move Returns 0 for success, or -1 for error

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

00908 {
00909    return ast_seekstream(fs, -ms * DEFAULT_SAMPLES_PER_MS, SEEK_CUR);
00910 }

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. Returns 0 on success, or -1 on failure.

Definition at line 968 of file file.c.

References ast_applystream(), AST_FLAG_MASQ_NOSTREAM, ast_getformatname(), ast_getformatname_multiple(), ast_log(), ast_openstream(), ast_openvstream(), ast_playstream(), ast_strdup, ast_test_flag, ast_verbose(), errno, ast_filestream::fmt, ast_format::format, LOG_DEBUG, LOG_WARNING, ast_channel::name, ast_channel::nativeformats, option_verbose, ast_filestream::orig_chan_name, VERBOSE_PREFIX_3, and ast_filestream::vfs.

Referenced by __login_exec(), 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_ka(), ast_say_date_nl(), 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_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_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_zh(), ast_say_time_de(), ast_say_time_en(), ast_say_time_fr(), ast_say_time_gr(), ast_say_time_ka(), ast_say_time_nl(), ast_say_time_zh(), ast_stream_and_wait(), auth_exec(), background_detect_exec(), check_availability(), check_beep(), common_exec(), conf_exec(), conf_run(), do_directory(), forward_message(), gr_say_number_female(), handle_recordfile(), leave_voicemail(), page_exec(), park_exec(), parkandannounce_exec(), pbx_builtin_background(), pl_odtworz_plik(), play_and_wait(), play_file(), play_greeting(), 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(), sayfile(), ss_thread(), vm_authenticate(), wait_file(), and wait_for_winner().

00969 {
00970    struct ast_filestream *fs;
00971    struct ast_filestream *vfs=NULL;
00972    char fmt[256];
00973 
00974    fs = ast_openstream(chan, filename, preflang);
00975    if (fs)
00976       vfs = ast_openvstream(chan, filename, preflang);
00977    if (vfs)
00978       ast_log(LOG_DEBUG, "Ooh, found a video stream, too, format %s\n", ast_getformatname(vfs->fmt->format));
00979    if (fs){
00980       int res;
00981       if (ast_test_flag(chan, AST_FLAG_MASQ_NOSTREAM))
00982          fs->orig_chan_name = ast_strdup(chan->name);
00983       if (ast_applystream(chan, fs))
00984          return -1;
00985       if (vfs && ast_applystream(chan, vfs))
00986          return -1;
00987       res = ast_playstream(fs);
00988       if (!res && vfs)
00989          res = ast_playstream(vfs);
00990       if (option_verbose > 2)
00991          ast_verbose(VERBOSE_PREFIX_3 "<%s> Playing '%s' (language '%s')\n", chan->name, filename, preflang ? preflang : "default");
00992 
00993       return res;
00994    }
00995    ast_log(LOG_WARNING, "Unable to open %s (format %s): %s\n", filename, ast_getformatname_multiple(fmt, sizeof(fmt), chan->nativeformats), strerror(errno));
00996    return -1;
00997 }

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

00898 {
00899    return fs->fmt->tell(fs);
00900 }

int ast_truncstream ( struct ast_filestream fs  ) 

Trunc stream at current location

Parameters:
fs filestream to act on Returns 0 for success, or -1 for error

Definition at line 892 of file file.c.

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

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

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

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, Returns 0 if the stream finishes, the character if it was interrupted, and -1 on error

Definition at line 1327 of file file.c.

References waitstream_core().

Referenced by __login_exec(), 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_ka(), ast_say_date_nl(), 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_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_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_zh(), ast_say_time_de(), ast_say_time_en(), ast_say_time_gr(), ast_say_time_he(), ast_say_time_ka(), ast_say_time_nl(), ast_say_time_zh(), ast_stream_and_wait(), auth_exec(), check_availability(), check_beep(), common_exec(), conf_exec(), conf_run(), directory_exec(), gr_say_number_female(), handle_recordfile(), leave_voicemail(), page_exec(), park_exec(), parkandannounce_exec(), pbx_builtin_background(), pl_odtworz_plik(), play_and_wait(), play_file(), play_greeting(), 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(), send_morse(), send_tone_telemetry(), ss_thread(), vm_authenticate(), and wait_file().

01328 {
01329    return waitstream_core(c, breakon, NULL, NULL, 0, -1, -1, NULL);
01330 }

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, Returns 0 if the stream finishes, the character if it was interrupted, and -1 on error

Definition at line 1338 of file file.c.

References ast_channel::context, and waitstream_core().

Referenced by pbx_builtin_background().

01339 {
01340    /* Waitstream, with return in the case of a valid 1 digit extension */
01341    /* in the current or specified context being pressed */
01342 
01343    if (!context)
01344       context = c->context;
01345    return waitstream_core(c, NULL, NULL, NULL, 0,
01346       -1, -1, context);
01347 }

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, Returns 0 if the stream finishes, the character if it was interrupted, and -1 on error

Definition at line 1321 of file file.c.

References waitstream_core().

Referenced by ast_control_streamfile().

01322 {
01323    return waitstream_core(c, breakon, forward, rewind, ms,
01324       -1 /* no audiofd */, -1 /* no cmdfd */, NULL /* no context */);
01325 }

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

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. Returns a struct ast_filestream on success, NULL on failure

Definition at line 1047 of file file.c.

References ast_closestream(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_opt_cache_record_files, ast_strdupa, ast_filestream::buf, build_filename(), errno, ast_format::exts, exts_compare(), f, ast_filestream::filename, ast_filestream::flags, ast_filestream::fmt, free, get_filestream(), LOG_WARNING, ast_filestream::mode, ast_filestream::realfilename, record_cache_dir, rewrite_wrapper(), ast_format::seek, strdup, ast_filestream::trans, and ast_filestream::vfs.

Referenced by __ast_play_and_record(), ast_monitor_start(), ast_writestream(), cli_audio_convert(), cli_audio_convert_deprecated(), dictate_exec(), handle_recordfile(), mixmonitor_thread(), record_exec(), recordthread(), and rpt().

01048 {
01049    int fd, myflags = 0;
01050    /* compiler claims this variable can be used before initialization... */
01051    FILE *bfile = NULL;
01052    struct ast_format *f;
01053    struct ast_filestream *fs = NULL;
01054    char *buf = NULL;
01055    size_t size = 0;
01056    int format_found = 0;
01057 
01058    if (AST_LIST_LOCK(&formats)) {
01059       ast_log(LOG_WARNING, "Unable to lock format list\n");
01060       return NULL;
01061    }
01062 
01063    /* set the O_TRUNC flag if and only if there is no O_APPEND specified */
01064    /* We really can't use O_APPEND as it will break WAV header updates */
01065    if (flags & O_APPEND) { 
01066       flags &= ~O_APPEND;
01067    } else {
01068       myflags = O_TRUNC;
01069    }
01070    
01071    myflags |= O_WRONLY | O_CREAT;
01072 
01073    /* XXX need to fix this - we should just do the fopen,
01074     * not open followed by fdopen()
01075     */
01076    AST_LIST_TRAVERSE(&formats, f, list) {
01077       char *fn, *orig_fn = NULL;
01078       if (fs)
01079          break;
01080 
01081       if (!exts_compare(f->exts, type))
01082          continue;
01083       else
01084          format_found = 1;
01085 
01086       fn = build_filename(filename, type);
01087       fd = open(fn, flags | myflags, mode);
01088       if (fd > -1) {
01089          /* fdopen() the resulting file stream */
01090          bfile = fdopen(fd, ((flags | myflags) & O_RDWR) ? "w+" : "w");
01091          if (!bfile) {
01092             ast_log(LOG_WARNING, "Whoa, fdopen failed: %s!\n", strerror(errno));
01093             close(fd);
01094             fd = -1;
01095          }
01096       }
01097       
01098       if (ast_opt_cache_record_files && (fd > -1)) {
01099          char *c;
01100 
01101          fclose(bfile); /* this also closes fd */
01102          /*
01103            We touch orig_fn just as a place-holder so other things (like vmail) see the file is there.
01104            What we are really doing is writing to record_cache_dir until we are done then we will mv the file into place.
01105          */
01106          orig_fn = ast_strdupa(fn);
01107          for (c = fn; *c; c++)
01108             if (*c == '/')
01109                *c = '_';
01110 
01111          size = strlen(fn) + strlen(record_cache_dir) + 2;
01112          buf = alloca(size);
01113          strcpy(buf, record_cache_dir);
01114          strcat(buf, "/");
01115          strcat(buf, fn);
01116          free(fn);
01117          fn = buf;
01118          fd = open(fn, flags | myflags, mode);
01119          if (fd > -1) {
01120             /* fdopen() the resulting file stream */
01121             bfile = fdopen(fd, ((flags | myflags) & O_RDWR) ? "w+" : "w");
01122             if (!bfile) {
01123                ast_log(LOG_WARNING, "Whoa, fdopen failed: %s!\n", strerror(errno));
01124                close(fd);
01125                fd = -1;
01126             }
01127          }
01128       }
01129       if (fd > -1) {
01130          errno = 0;
01131          fs = get_filestream(f, bfile);
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 = strdup(orig_fn);
01151             fs->filename = strdup(fn);
01152          } else {
01153             fs->realfilename = NULL;
01154             fs->filename = 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          free(fn);
01167    }
01168 
01169    AST_LIST_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 Returns 0 on success, -1 on failure.

Definition at line 161 of file file.c.

References AST_FORMAT_MAX_AUDIO, 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_DEBUG, 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(), cli_audio_convert(), cli_audio_convert_deprecated(), dictate_exec(), handle_recordfile(), mixmonitor_thread(), record_exec(), recordthread(), and rpt().

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

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

00270 {
00271    char *fn = NULL;
00272 
00273    if (!strcmp(ext, "wav49"))
00274       ext = "WAV";
00275 
00276    if (filename[0] == '/') {
00277       if (asprintf(&fn, "%s.%s", filename, ext) < 0) {
00278          ast_log(LOG_WARNING, "asprintf() failed: %s\n", strerror(errno));
00279          fn = NULL;
00280       }
00281    } else {
00282       if (asprintf(&fn, "%s/sounds/%s.%s",
00283               ast_config_AST_DATA_DIR, filename, ext) < 0) {
00284          ast_log(LOG_WARNING, "asprintf() failed: %s\n", strerror(errno));
00285          fn = NULL;
00286       }
00287    }
00288    return fn;
00289 }

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

Definition at line 226 of file file.c.

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

Referenced by action_getvar(), ast_filehelper(), copy_plain_file(), iax2_register(), and vm_forwardoptions().

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

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

Definition at line 293 of file file.c.

References ast_copy_string(), and ext.

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

00294 {
00295    char tmp[256];
00296    char *stringp = tmp, *ext;
00297 
00298    ast_copy_string(tmp, exts, sizeof(tmp));
00299    while ((ext = strsep(&stringp, "|"))) {
00300       if (!strcmp(ext, type))
00301          return 1;
00302    }
00303 
00304    return 0;
00305 }

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

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

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

Definition at line 546 of file file.c.

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

Referenced by fileexists_core().

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

static void filestream_destructor ( void *  arg  )  [static]

Definition at line 307 of file file.c.

References ast_closestream(), AST_FORMAT_MAX_AUDIO, 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, and ast_channel::vstreamid.

Referenced by get_filestream().

00308 {
00309    char *cmd = NULL;
00310    size_t size = 0;
00311    struct ast_filestream *f = arg;
00312 
00313    /* Stop a running stream if there is one */
00314    if (f->owner) {
00315       if (f->fmt->format < AST_FORMAT_MAX_AUDIO) {
00316          f->owner->stream = NULL;
00317          AST_SCHED_DEL(f->owner->sched, f->owner->streamid);
00318 #ifdef HAVE_DAHDI
00319          ast_settimeout(f->owner, 0, NULL, NULL);
00320 #endif         
00321       } else {
00322          f->owner->vstream = NULL;
00323          AST_SCHED_DEL(f->owner->sched, f->owner->vstreamid);
00324       }
00325    }
00326    /* destroy the translator on exit */
00327    if (f->trans)
00328       ast_translator_free_path(f->trans);
00329 
00330    if (f->realfilename && f->filename) {
00331          size = strlen(f->filename) + strlen(f->realfilename) + 15;
00332          cmd = alloca(size);
00333          memset(cmd,0,size);
00334          snprintf(cmd,size,"/bin/mv -f %s %s",f->filename,f->realfilename);
00335          ast_safe_system(cmd);
00336    }
00337 
00338    if (f->filename)
00339       free(f->filename);
00340    if (f->realfilename)
00341       free(f->realfilename);
00342    if (f->fmt->close) {
00343       void (*closefn)(struct ast_filestream *) = f->fmt->close;
00344       closefn(f);
00345    }
00346    if (f->f)
00347       fclose(f->f);
00348    if (f->vfs)
00349       ast_closestream(f->vfs);
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, WRAP_OPEN, and WRAP_REWRITE.

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, read]

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, s, 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 int is_absolute_path ( const char *  filename  )  [static]

Definition at line 541 of file file.c.

Referenced by fileexists_test().

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

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, read]

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

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

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

Definition at line 397 of file file.c.

References fn_wrapper(), and WRAP_REWRITE.

Referenced by ast_writefile().

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

static int show_file_formats ( int  fd,
int  argc,
char *  argv[] 
) [static]

Definition at line 1442 of file file.c.

References ast_cli(), ast_getformatname(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_format::exts, f, ast_format::format, FORMAT, FORMAT2, ast_format::list, LOG_WARNING, ast_format::name, RESULT_SHOWUSAGE, and RESULT_SUCCESS.

01443 {
01444 #define FORMAT "%-10s %-10s %-20s\n"
01445 #define FORMAT2 "%-10s %-10s %-20s\n"
01446    struct ast_format *f;
01447    int count_fmt = 0;
01448 
01449    if (argc != 4)
01450       return RESULT_SHOWUSAGE;
01451    ast_cli(fd, FORMAT, "Format", "Name", "Extensions");
01452            
01453    if (AST_LIST_LOCK(&formats)) {
01454       ast_log(LOG_WARNING, "Unable to lock format list\n");
01455       return -1;
01456    }
01457 
01458    AST_LIST_TRAVERSE(&formats, f, list) {
01459       ast_cli(fd, FORMAT2, ast_getformatname(f->format), f->name, f->exts);
01460       count_fmt++;
01461    }
01462    AST_LIST_UNLOCK(&formats);
01463    ast_cli(fd, "%d file formats registered.\n", count_fmt);
01464    return RESULT_SUCCESS;
01465 #undef FORMAT
01466 #undef FORMAT2
01467 }

static int show_file_formats_deprecated ( int  fd,
int  argc,
char *  argv[] 
) [static]

Definition at line 1469 of file file.c.

References ast_cli(), ast_getformatname(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_format::exts, f, ast_format::format, FORMAT, FORMAT2, ast_format::list, LOG_WARNING, ast_format::name, RESULT_SHOWUSAGE, and RESULT_SUCCESS.

01470 {
01471 #define FORMAT "%-10s %-10s %-20s\n"
01472 #define FORMAT2 "%-10s %-10s %-20s\n"
01473    struct ast_format *f;
01474    int count_fmt = 0;
01475    
01476    if (argc != 3)
01477       return RESULT_SHOWUSAGE;
01478    ast_cli(fd, FORMAT, "Format", "Name", "Extensions");
01479    
01480    if (AST_LIST_LOCK(&formats)) {
01481       ast_log(LOG_WARNING, "Unable to lock format list\n");
01482       return -1;
01483    }
01484    
01485    AST_LIST_TRAVERSE(&formats, f, list) {
01486       ast_cli(fd, FORMAT2, ast_getformatname(f->format), f->name, f->exts);
01487       count_fmt++;
01488    }
01489    AST_LIST_UNLOCK(&formats);
01490    ast_cli(fd, "%d file formats registered.\n", count_fmt);
01491    return RESULT_SUCCESS;
01492 #undef FORMAT
01493 #undef FORMAT2
01494 }

static int waitstream_core ( struct ast_channel c,
const char *  breakon,
const char *  forward,
const char *  rewind,
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_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_channel::sched, ast_channel::stream, and ast_frame::subclass.

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 (!rewind)
01192       rewind = "";
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, '\0' };
01253                if (ast_exists_extension(c, context, exten, 1, c->cid.cid_num)) {
01254                   res = fr->subclass;
01255                   ast_frfree(fr);
01256                   ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
01257                   return res;
01258                }
01259             } else {
01260                res = fr->subclass;
01261                if (strchr(forward,res)) {
01262                   int eoftest;
01263                   ast_stream_fastforward(c->stream, skip_ms);
01264                   eoftest = fgetc(c->stream->f);
01265                   if (feof(c->stream->f)) {
01266                      ast_stream_rewind(c->stream, skip_ms);
01267                   } else {
01268                      ungetc(eoftest, c->stream->f);
01269                   }
01270                } else if (strchr(rewind,res)) {
01271                   ast_stream_rewind(c->stream, skip_ms);
01272                } else if (strchr(breakon, res)) {
01273                   ast_frfree(fr);
01274                   ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
01275                   return res;
01276                }              
01277             }
01278             break;
01279          case AST_FRAME_CONTROL:
01280             switch(fr->subclass) {
01281             case AST_CONTROL_HANGUP:
01282             case AST_CONTROL_BUSY:
01283             case AST_CONTROL_CONGESTION:
01284                ast_frfree(fr);
01285                ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
01286                return -1;
01287             case AST_CONTROL_RINGING:
01288             case AST_CONTROL_ANSWER:
01289             case AST_CONTROL_VIDUPDATE:
01290             case AST_CONTROL_SRCUPDATE:
01291             case AST_CONTROL_SRCCHANGE:
01292             case AST_CONTROL_HOLD:
01293             case AST_CONTROL_UNHOLD:
01294                /* Unimportant */
01295                break;
01296             default:
01297                ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", fr->subclass);
01298             }
01299             break;
01300          case AST_FRAME_VOICE:
01301             /* Write audio if appropriate */
01302             if (audiofd > -1) {
01303                if (write(audiofd, fr->data, fr->datalen) < 0) {
01304                   ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
01305                }
01306             }
01307          default:
01308             /* Ignore all others */
01309             break;
01310          }
01311          ast_frfree(fr);
01312       }
01313       ast_sched_runq(c->sched);
01314    }
01315 
01316    ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
01317 
01318    return (err || c->_softhangup) ? -1 : 0;
01319 }


Variable Documentation

Definition at line 66 of file file.c.

Referenced by ast_readconfig().

Initial value:

 {
   { { "core", "show", "file", "formats" },
   show_file_formats, "Displays file formats",
   show_file_formats_usage, NULL, &cli_show_file_formats_deprecated },
}

Definition at line 1505 of file file.c.

Initial value:

 {
   { "show", "file", "formats" },
   show_file_formats_deprecated, NULL,
   NULL }

Definition at line 1500 of file file.c.

Initial value:

 
"Usage: core show file formats\n"
"       Displays currently registered file formats (if any)\n"

Definition at line 1496 of file file.c.


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