Tue Nov 16 17:07:41 2010

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"

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)
ast_filestreamast_openstream (struct ast_channel *chan, const char *filename, const char *preflang)
ast_filestreamast_openstream_full (struct ast_channel *chan, const char *filename, const char *preflang, int asis)
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)
ast_filestreamast_readfile (const char *filename, const char *type, const char *comment, int flags, int check, mode_t mode)
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)
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
ast_cli_entry cli_file []
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"

Referenced by __iax2_show_peers(), __sip_show_channels(), _sip_show_peers(), dahdi_show_channels(), dahdi_show_status(), dundi_show_mappings(), dundi_show_peers(), dundi_show_precache(), dundi_show_requests(), dundi_show_trans(), iax2_show_channels(), iax2_show_firmware(), iax2_show_registry(), iax2_show_users(), show_file_formats(), show_file_formats_deprecated(), show_image_formats(), show_image_formats_deprecated(), sip_show_inuse(), and sip_show_registry().


Enumeration Type Documentation

enum file_action

Enumerator:
ACTION_EXISTS 
ACTION_DELETE 
ACTION_RENAME 
ACTION_OPEN 
ACTION_COPY 

Definition at line 406 of file file.c.

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

enum fsread_res

Enumerator:
FSREAD_FAILURE 
FSREAD_SUCCESS_SCHED 
FSREAD_SUCCESS_NOSCHED 

Definition at line 741 of file file.c.

00741                 {
00742    FSREAD_FAILURE,
00743    FSREAD_SUCCESS_SCHED,
00744    FSREAD_SUCCESS_NOSCHED,
00745 };

enum wrap_fn

Enumerator:
WRAP_OPEN 
WRAP_REWRITE 

Definition at line 376 of file file.c.

00376 { 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 69 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, f, ast_format::list, LOG_WARNING, ast_format::module, ast_format::name, option_verbose, and VERBOSE_PREFIX_2.

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

int ast_applystream ( struct ast_channel chan,
struct ast_filestream s 
)

Parameters:
chan channel to work
s ast_filestream to apply Returns 0 for success, -1 on failure

Definition at line 865 of file file.c.

References s.

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

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

int ast_closestream ( struct ast_filestream f  ) 

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

Definition at line 908 of file file.c.

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

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

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

int ast_file_init ( void   ) 

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

Definition at line 1505 of file file.c.

References ast_cli_register_multiple(), and cli_file.

Referenced by main().

01506 {
01507    ast_cli_register_multiple(cli_file, sizeof(cli_file) / sizeof(struct ast_cli_entry));
01508    return 0;
01509 }

int ast_filecopy ( const char *  oldname,
const char *  newname,
const char *  fmt 
)

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

References ast_filehelper().

Referenced by copy_plain_file(), and vm_forwardoptions().

00960 {
00961    return ast_filehelper(filename, filename2, fmt, ACTION_COPY);
00962 }

int ast_filedelete ( const char *  filename,
const char *  fmt 
)

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 949 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(), leave_voicemail(), play_mailbox_owner(), play_record_review(), vm_delete(), and vm_forwardoptions().

00950 {
00951    return ast_filehelper(filename, NULL, fmt, ACTION_DELETE);
00952 }

int ast_fileexists ( const char *  filename,
const char *  fmt,
const char *  preflang 
)

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

Definition at line 935 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(), last_message_index(), leave_voicemail(), 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().

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

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

References 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_format::format, free, get_filestream(), ast_format::list, LOG_WARNING, open_wrapper(), s, ast_channel::stream, ast_channel::vstream, and ast_channel::writeformat.

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

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

int ast_filerename ( const char *  oldname,
const char *  newname,
const char *  fmt 
)

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

References ACTION_RENAME, and ast_filehelper().

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

00955 {
00956    return ast_filehelper(filename, filename2, fmt, ACTION_RENAME);
00957 }

char* ast_format_str_reduce ( char *  fmts  ) 

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

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

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

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

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

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

Definition at line 805 of file file.c.

References ast_readaudio_callback(), and FSREAD_SUCCESS_SCHED.

Referenced by ast_readaudio_callback().

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

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

Definition at line 852 of file file.c.

References ast_readvideo_callback(), and FSREAD_SUCCESS_SCHED.

Referenced by ast_readvideo_callback().

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

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

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

References ast_openstream_full().

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

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

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

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

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

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

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

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

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

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

int ast_playstream ( struct ast_filestream s  ) 

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

Definition at line 871 of file file.c.

References AST_FORMAT_MAX_AUDIO, ast_readaudio_callback(), ast_readvideo_callback(), FSREAD_FAILURE, and s.

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

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

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

Definition at line 749 of file file.c.

References ast_format_rate(), ast_frfree, ast_fsread_audio(), ast_log(), ast_sched_add(), ast_settimeout(), ast_write(), FSREAD_FAILURE, FSREAD_SUCCESS_NOSCHED, FSREAD_SUCCESS_SCHED, LOG_WARNING, read_frame(), and s.

Referenced by ast_fsread_audio(), and ast_playstream().

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

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

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

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

struct ast_frame* ast_readframe ( struct ast_filestream s  ) 

Parameters:
s ast_filestream to act on Returns a frame or NULL if read failed

Definition at line 734 of file file.c.

References read_frame(), and s.

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

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

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

Definition at line 820 of file file.c.

References ast_format_rate(), ast_frfree, ast_fsread_video(), ast_log(), ast_sched_add(), ast_write(), FSREAD_FAILURE, FSREAD_SUCCESS_NOSCHED, FSREAD_SUCCESS_SCHED, LOG_WARNING, read_frame(), and s.

Referenced by ast_fsread_video(), and ast_playstream().

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

int ast_seekstream ( struct ast_filestream fs,
off_t  sample_offset,
int  whence 
)

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

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

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

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

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

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

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

Definition at line 1351 of file file.c.

References ast_streamfile(), ast_strlen_zero(), and ast_waitstream().

Referenced by __ast_play_and_record(), app_exec(), ast_record_review(), bridge_playfile(), builtin_automonitor(), builtin_blindtransfer(), directory_exec(), do_atxfer(), invent_message(), ivr_dispatch(), leave_voicemail(), masq_park_call(), park_exec(), play_mailbox_owner(), play_message_callerid(), play_record_review(), and wait_file2().

01353 {
01354         int res = 0;
01355         if (!ast_strlen_zero(file)) {
01356                 res =  ast_streamfile(chan, file, language);
01357                 if (!res)
01358                         res = ast_waitstream(chan, digits);
01359         }
01360         return res;
01361 } 

int ast_stream_fastforward ( struct ast_filestream fs,
off_t  ms 
)

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

Definition at line 898 of file file.c.

References ast_seekstream(), and DEFAULT_SAMPLES_PER_MS.

Referenced by waitstream_core().

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

int ast_stream_rewind ( struct ast_filestream fs,
off_t  ms 
)

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

Definition at line 903 of file file.c.

References ast_seekstream(), and DEFAULT_SAMPLES_PER_MS.

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

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

int ast_streamfile ( struct ast_channel c,
const char *  filename,
const char *  preflang 
)

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

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

off_t ast_tellstream ( struct ast_filestream fs  ) 

Parameters:
fs fs to act on Returns a long as a sample offset into stream

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

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

int ast_truncstream ( struct ast_filestream fs  ) 

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

Definition at line 888 of file file.c.

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

Referenced by __ast_play_and_record(), and handle_recordfile().

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

int ast_waitstream ( struct ast_channel c,
const char *  breakon 
)

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

01325 {
01326    return waitstream_core(c, breakon, NULL, NULL, 0, -1, -1, NULL);
01327 }

int ast_waitstream_exten ( struct ast_channel c,
const char *  context 
)

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

References ast_channel::context, and waitstream_core().

Referenced by pbx_builtin_background().

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

int ast_waitstream_fr ( struct ast_channel c,
const char *  breakon,
const char *  forward,
const char *  rewind,
int  ms 
)

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

References waitstream_core().

Referenced by ast_control_streamfile().

01319 {
01320    return waitstream_core(c, breakon, forward, rewind, ms,
01321       -1 /* no audiofd */, -1 /* no cmdfd */, NULL /* no context */);
01322 }

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

Definition at line 1329 of file file.c.

References waitstream_core().

Referenced by ast_readstring_full(), ast_say_enumeration_full_da(), ast_say_enumeration_full_de(), ast_say_enumeration_full_en(), ast_say_enumeration_full_he(), ast_say_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(), handle_getoption(), handle_streamfile(), pl_odtworz_plik(), s_streamwait3(), say_character_str_full(), say_digit_str_full(), and say_phonetic_str_full().

01330 {
01331    return waitstream_core(c, breakon, NULL, NULL, 0,
01332       audiofd, cmdfd, NULL /* no context */);
01333 }

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

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

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

int ast_writestream ( struct ast_filestream fs,
struct ast_frame f 
)

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 160 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(), f, ast_filestream::filename, ast_filestream::flags, ast_filestream::fmt, ast_format::format, ast_frame::frame_list, ast_filestream::lastwriteformat, LOG_DEBUG, LOG_WARNING, ast_filestream::mode, ast_format::name, ast_filestream::trans, type, ast_filestream::vfs, and ast_format::write.

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

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

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

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

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

Definition at line 225 of file file.c.

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

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

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

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

Definition at line 292 of file file.c.

References ast_copy_string(), and ext.

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

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

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

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

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

Definition at line 545 of file file.c.

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

Referenced by fileexists_core().

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

static void filestream_destructor ( void *  arg  )  [static]

Definition at line 306 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, f, ast_format::format, free, and ast_format::module.

Referenced by get_filestream().

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

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

Definition at line 378 of file file.c.

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

Referenced by open_wrapper(), and rewrite_wrapper().

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

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

Definition at line 354 of file file.c.

References ao2_alloc(), ast_format::buf_size, ast_format::desc_size, filestream_destructor(), ast_filestream::fmt, ast_format::name, and s.

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

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

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

Definition at line 540 of file file.c.

Referenced by fileexists_test().

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

static int open_wrapper ( struct ast_filestream s  )  [static]

Definition at line 401 of file file.c.

References fn_wrapper(), s, and WRAP_OPEN.

Referenced by ast_filehelper(), and ast_readfile().

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

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

Definition at line 709 of file file.c.

References ast_frfree, ast_frisolate(), and s.

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

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

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

Definition at line 396 of file file.c.

References fn_wrapper(), and s.

Referenced by ast_writefile().

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

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

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

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    if (argc != 4)
01444       return RESULT_SHOWUSAGE;
01445    ast_cli(fd, FORMAT, "Format", "Name", "Extensions");
01446            
01447    if (AST_LIST_LOCK(&formats)) {
01448       ast_log(LOG_WARNING, "Unable to lock format list\n");
01449       return -1;
01450    }
01451 
01452    AST_LIST_TRAVERSE(&formats, f, list) {
01453       ast_cli(fd, FORMAT2, ast_getformatname(f->format), f->name, f->exts);
01454       count_fmt++;
01455    }
01456    AST_LIST_UNLOCK(&formats);
01457    ast_cli(fd, "%d file formats registered.\n", count_fmt);
01458    return RESULT_SUCCESS;
01459 #undef FORMAT
01460 #undef FORMAT2
01461 }

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

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

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

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 1176 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_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_RINGING, 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().

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


Variable Documentation

int ast_language_is_prefix

Definition at line 65 of file file.c.

Referenced by handle_show_settings().

struct ast_cli_entry cli_file[]

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

Referenced by ast_file_init().

struct ast_cli_entry cli_show_file_formats_deprecated

Initial value:

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

Definition at line 1494 of file file.c.

char show_file_formats_usage[]

Initial value:

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

Definition at line 1490 of file file.c.


Generated on Tue Nov 16 17:07:41 2010 for Asterisk - the Open Source PBX by  doxygen 1.4.7