Fri Aug 17 00:17:40 2018

Asterisk developer's documentation


file.c File Reference

Generic File Format Support. More...

#include "asterisk.h"
#include <dirent.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <math.h>
#include "asterisk/_private.h"
#include "asterisk/paths.h"
#include "asterisk/mod_format.h"
#include "asterisk/cli.h"
#include "asterisk/channel.h"
#include "asterisk/sched.h"
#include "asterisk/translate.h"
#include "asterisk/utils.h"
#include "asterisk/lock.h"
#include "asterisk/app.h"
#include "asterisk/pbx.h"
#include "asterisk/linkedlists.h"
#include "asterisk/module.h"
#include "asterisk/astobj2.h"
#include "asterisk/test.h"

Go to the source code of this file.

Data Structures

struct  formats

Defines

#define FORMAT   "%-10s %-10s %-20s\n"
#define FORMAT2   "%-10s %-10s %-20s\n"

Enumerations

enum  file_action {
  ACTION_EXISTS = 1, ACTION_DELETE, ACTION_RENAME, ACTION_OPEN,
  ACTION_COPY
}
enum  fsread_res { FSREAD_FAILURE, FSREAD_SUCCESS_SCHED, FSREAD_SUCCESS_NOSCHED }
enum  wrap_fn { WRAP_OPEN, WRAP_REWRITE }

Functions

int __ast_format_register (const struct ast_format *f, struct ast_module *mod)
 Register a new file format capability. Adds a format to Asterisk's format abilities.
int ast_applystream (struct ast_channel *chan, struct ast_filestream *s)
 Applys a open stream to a channel.
int ast_closestream (struct ast_filestream *f)
 Closes a stream.
int ast_file_init (void)
int ast_filecopy (const char *filename, const char *filename2, const char *fmt)
 Copies a file.
int ast_filedelete (const char *filename, const char *fmt)
 Deletes a file.
int ast_fileexists (const char *filename, const char *fmt, const char *preflang)
 Checks for the existence of a given file.
static format_t ast_filehelper (const char *filename, const void *arg2, const char *fmt, const enum file_action action)
 perform various actions on a file. Second argument arg2 depends on the command: unused for EXISTS and DELETE destination file name (const char *) for COPY and RENAME struct ast_channel * for OPEN if fmt is NULL, OPEN will return the first matching entry, whereas other functions will run on all matching entries.
int ast_filerename (const char *filename, const char *filename2, const char *fmt)
 Renames a file.
char * ast_format_str_reduce (char *fmts)
int ast_format_unregister (const char *name)
 Unregisters a file format.
static int ast_fsread_audio (const void *data)
static int ast_fsread_video (const void *data)
struct ast_filestreamast_openstream (struct ast_channel *chan, const char *filename, const char *preflang)
 Opens stream for use in seeking, playing.
struct ast_filestreamast_openstream_full (struct ast_channel *chan, const char *filename, const char *preflang, int asis)
 Opens stream for use in seeking, playing.
struct ast_filestreamast_openvstream (struct ast_channel *chan, const char *filename, const char *preflang)
 Opens stream for use in seeking, playing.
int ast_playstream (struct ast_filestream *s)
 Play a open stream on a channel.
static enum fsread_res ast_readaudio_callback (struct ast_filestream *s)
struct ast_filestreamast_readfile (const char *filename, const char *type, const char *comment, int flags, int check, mode_t mode)
 Starts reading from a file.
struct ast_frameast_readframe (struct ast_filestream *s)
 Read a frame from a filestream.
static enum fsread_res ast_readvideo_callback (struct ast_filestream *s)
int ast_seekstream (struct ast_filestream *fs, off_t sample_offset, int whence)
 Seeks into stream.
int ast_stopstream (struct ast_channel *tmp)
 Stops a stream.
int ast_stream_and_wait (struct ast_channel *chan, const char *file, const char *digits)
 stream file until digit If the file name is non-empty, try to play it.
int ast_stream_fastforward (struct ast_filestream *fs, off_t ms)
 Fast forward stream ms.
int ast_stream_rewind (struct ast_filestream *fs, off_t ms)
 Rewind stream ms.
int ast_streamfile (struct ast_channel *chan, const char *filename, const char *preflang)
 Streams a file.
off_t ast_tellstream (struct ast_filestream *fs)
 Tell where we are in a stream.
int ast_truncstream (struct ast_filestream *fs)
 Trunc stream at current location.
int ast_waitstream (struct ast_channel *c, const char *breakon)
 Waits for a stream to stop or digit to be pressed.
int ast_waitstream_exten (struct ast_channel *c, const char *context)
 Waits for a stream to stop or digit matching a valid one digit exten to be pressed.
int ast_waitstream_fr (struct ast_channel *c, const char *breakon, const char *forward, const char *reverse, int ms)
 Same as waitstream but allows stream to be forwarded or rewound.
int ast_waitstream_full (struct ast_channel *c, const char *breakon, int audiofd, int cmdfd)
struct ast_filestreamast_writefile (const char *filename, const char *type, const char *comment, int flags, int check, mode_t mode)
 Starts writing a file.
int ast_writestream (struct ast_filestream *fs, struct ast_frame *f)
 Writes a frame to a stream.
static char * build_filename (const char *filename, const char *ext)
 construct a filename. Absolute pathnames are preserved, relative names are prefixed by the sounds/ directory. The wav49 suffix is replaced by 'WAV'. Returns a malloc'ed string to be freed by the caller.
static int copy (const char *infile, const char *outfile)
static int exts_compare (const char *exts, const char *type)
static void file_shutdown (void)
static format_t fileexists_core (const char *filename, const char *fmt, const char *preflang, char *buf, int buflen)
 helper routine to locate a file with a given format and language preference. Try preflang, preflang with stripped '_' suffices, or NULL.
static format_t fileexists_test (const char *filename, const char *fmt, const char *lang, char *buf, int buflen)
static void filestream_close (struct ast_filestream *f)
static void filestream_destructor (void *arg)
static int fn_wrapper (struct ast_filestream *s, const char *comment, enum wrap_fn mode)
static struct ast_filestreamget_filestream (struct ast_format *fmt, FILE *bfile)
static char * handle_cli_core_show_file_formats (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static int is_absolute_path (const char *filename)
static int open_wrapper (struct ast_filestream *s)
static struct ast_frameread_frame (struct ast_filestream *s, int *whennext)
static int rewrite_wrapper (struct ast_filestream *s, const char *comment)
static int waitstream_core (struct ast_channel *c, const char *breakon, const char *forward, const char *reverse, int skip_ms, int audiofd, int cmdfd, const char *context)
 the core of all waitstream() functions

Variables

int ast_language_is_prefix = 1
static struct ast_cli_entry cli_file []

Detailed Description

Generic File Format Support.

Author:
Mark Spencer <markster@digium.com>

Definition in file file.c.


Define Documentation

#define FORMAT   "%-10s %-10s %-20s\n"
#define FORMAT2   "%-10s %-10s %-20s\n"

Enumeration Type Documentation

Enumerator:
ACTION_EXISTS 
ACTION_DELETE 
ACTION_RENAME 
ACTION_OPEN 
ACTION_COPY 

Definition at line 412 of file file.c.

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

enum fsread_res
Enumerator:
FSREAD_FAILURE 
FSREAD_SUCCESS_SCHED 
FSREAD_SUCCESS_NOSCHED 

Definition at line 744 of file file.c.

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

enum wrap_fn
Enumerator:
WRAP_OPEN 
WRAP_REWRITE 

Definition at line 382 of file file.c.

00382 { WRAP_OPEN, WRAP_REWRITE };


Function Documentation

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

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

Return values:
0 on success
-1 on failure

Definition at line 67 of file file.c.

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

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

int ast_applystream ( struct ast_channel chan,
struct ast_filestream s 
)

Applys a open stream to a channel.

Parameters:
chan channel to work
s ast_filestream to apply
Return values:
0 on success.
-1 on failure.

Definition at line 861 of file file.c.

References ast_filestream::owner.

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

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

int ast_closestream ( struct ast_filestream f  ) 

Closes a stream.

Parameters:
f filestream to close Close a playback or recording stream
Return values:
0 on success.
-1 on failure.

Definition at line 904 of file file.c.

References ao2_ref, and filestream_close().

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

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

int ast_file_init ( void   ) 

Provided by file.c

Definition at line 1503 of file file.c.

References ARRAY_LEN, ast_cli_register_multiple(), ast_register_atexit(), and file_shutdown().

Referenced by main().

01504 {
01505    ast_cli_register_multiple(cli_file, ARRAY_LEN(cli_file));
01506    ast_register_atexit(file_shutdown);
01507    return 0;
01508 }

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

Copies a file.

Parameters:
oldname name of the file you wish to copy (minus extension)
newname name you wish the file to be copied to (minus extension)
fmt the format of the file Copy a given file in a given format, or if fmt is NULL, then do so for all

Definition at line 941 of file file.c.

References ACTION_COPY, and ast_filehelper().

Referenced by copy_plain_file(), and vm_forwardoptions().

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

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

Deletes a file.

Parameters:
filename name of the file you wish to delete (minus the extension)
fmt of the file Delete a given file in a given format, or if fmt is NULL, then do so for all

Definition at line 931 of file file.c.

References ACTION_DELETE, and ast_filehelper().

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

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

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

Checks for the existence of a given file.

Parameters:
filename name of the file you wish to check, minus the extension
fmt the format you wish to check (the extension)
preflang (the preferred language you wisht to find the file in) See if a given file exists in a given format. If fmt is NULL, any format is accepted.
Returns:
0 if file does not exist, non-zero positive otherwise.

Definition at line 919 of file file.c.

References ast_alloca, ast_filestream::buf, and fileexists_core().

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

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

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

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

Definition at line 429 of file file.c.

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

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

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

Renames a file.

Parameters:
oldname the name of the file you wish to act upon (minus the extension)
newname the name you wish to rename the file to (minus the extension)
fmt the format of the file Rename a given file in a given format, or if fmt is NULL, then do so for all
Returns:
-1 on failure

Definition at line 936 of file file.c.

References ACTION_RENAME, and ast_filehelper().

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

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

char* ast_format_str_reduce ( char *  fmts  ) 

Remove duplicate formats from a format string.

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

Definition at line 1382 of file file.c.

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

Referenced by actual_load_config().

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

int ast_format_unregister ( const char *  name  ) 

Unregisters a file format.

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

Definition at line 104 of file file.c.

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

Referenced by unload_module().

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

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

Definition at line 801 of file file.c.

References ast_readaudio_callback(), and FSREAD_SUCCESS_SCHED.

Referenced by ast_readaudio_callback().

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

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

Definition at line 848 of file file.c.

References ast_readvideo_callback(), and FSREAD_SUCCESS_SCHED.

Referenced by ast_readvideo_callback().

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

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

Opens stream for use in seeking, playing.

Parameters:
chan channel to work with
filename to use
preflang prefered language to use
Return values:
a ast_filestream pointer if it opens the file.
NULL on error.

Definition at line 636 of file file.c.

References ast_openstream_full().

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

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

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

Opens stream for use in seeking, playing.

Parameters:
chan channel to work with
filename to use
preflang prefered language to use
asis if set, don't clear generators
Return values:
a ast_filestream pointer if it opens the file.
NULL on error.

Definition at line 641 of file file.c.

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

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

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

Opens stream for use in seeking, playing.

Parameters:
chan channel to work with
filename to use
preflang prefered language to use
Return values:
a ast_filestream pointer if it opens the file.
NULL on error.

Definition at line 681 of file file.c.

References ACTION_OPEN, ast_alloca, ast_filehelper(), AST_FORMAT_FIRST_VIDEO_BIT, AST_FORMAT_VIDEO_MASK, ast_getformatname(), ast_log(), ast_filestream::buf, fileexists_core(), ast_filestream::fmt, format, LOG_WARNING, ast_channel::nativeformats, and ast_channel::vstream.

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

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

int ast_playstream ( struct ast_filestream s  ) 

Play a open stream on a channel.

Parameters:
s filestream to play
Return values:
0 on success.
-1 on failure.

Definition at line 867 of file file.c.

References AST_FORMAT_AUDIO_MASK, ast_readaudio_callback(), ast_readvideo_callback(), ast_filestream::fmt, ast_format::format, and FSREAD_FAILURE.

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

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

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

Definition at line 752 of file file.c.

References ast_format_rate(), ast_frfree, ast_fsread_audio(), ast_log(), ast_sched_add(), ast_settimeout(), ast_settimeout_full(), ast_write(), ast_filestream::fmt, ast_format::format, FSREAD_FAILURE, FSREAD_SUCCESS_NOSCHED, FSREAD_SUCCESS_SCHED, ast_filestream::lasttimeout, LOG_WARNING, 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().

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

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

Starts reading from a file.

Parameters:
filename the name of the file to read from
type format of file you wish to read from
comment comment to go with
flags file flags
check (unimplemented, hence negligible)
mode Open mode Open an incoming file stream. flags are flags for the open() command, and if check is non-zero, then it will not read a file if there are any files that start with that name and have an extension Please note, this is a blocking function. Program execution will not return until ast_waitstream completes it's execution.
Return values:
a struct ast_filestream on success.
NULL on failure.

Definition at line 997 of file file.c.

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

Referenced by __ast_play_and_record(), and handle_cli_file_convert().

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

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

Read a frame from a filestream.

Parameters:
s ast_filestream to act on
Returns:
a frame.
Return values:
NULL if read failed.

Definition at line 737 of file file.c.

References read_frame().

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

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

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

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

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

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

Seeks into stream.

Parameters:
fs ast_filestream to perform seek on
sample_offset numbers of samples to seek
whence SEEK_SET, SEEK_CUR, SEEK_END
Return values:
0 on success.
-1 on failure.

Definition at line 879 of file file.c.

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

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

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

int ast_stopstream ( struct ast_channel c  ) 

Stops a stream.

Parameters:
c The channel you wish to stop playback on

Stop playback of a stream

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

Definition at line 128 of file file.c.

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

Referenced by adsi_transmit_message_full(), ast_control_streamfile(), ast_openstream_full(), ast_play_and_wait(), ast_readstring_full(), ast_say_enumeration_full_da(), ast_say_enumeration_full_de(), ast_say_enumeration_full_en(), ast_say_enumeration_full_he(), ast_say_enumeration_full_vi(), ast_say_number_full_cs(), ast_say_number_full_da(), ast_say_number_full_de(), ast_say_number_full_en(), ast_say_number_full_en_GB(), ast_say_number_full_es(), ast_say_number_full_fr(), ast_say_number_full_gr(), ast_say_number_full_he(), ast_say_number_full_hu(), ast_say_number_full_it(), ast_say_number_full_ka(), ast_say_number_full_nl(), ast_say_number_full_no(), ast_say_number_full_pt(), ast_say_number_full_ru(), ast_say_number_full_se(), ast_say_number_full_th(), ast_say_number_full_ur(), ast_say_number_full_vi(), ast_say_number_full_zh(), background_detect_exec(), conf_exec(), conf_run(), dial_exec_full(), directory_exec(), grab_transfer(), handle_getoption(), handle_speechrecognize(), handle_streamfile(), ices_exec(), ivr_dispatch(), leave_voicemail(), meetme_menu_admin(), meetme_menu_admin_extended(), menu_callback(), minivm_greet_exec(), mp3_exec(), NBScat_exec(), parkandannounce_exec(), pbx_builtin_background(), pl_odtworz_plik(), play_file(), play_mailbox_owner(), playback_exec(), queue_exec(), read_exec(), readexten_exec(), record_exec(), recordthread(), s_streamwait3(), say_character_str_full(), say_digit_str_full(), say_phonetic_str_full(), select_item_seq(), send_waveform_to_channel(), speech_background(), vm_authenticate(), vm_execmain(), wait_for_winner(), waitstream_core(), and zapateller_exec().

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

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

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

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

Definition at line 1370 of file file.c.

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

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

01371 {
01372    int res = 0;
01373    if (!ast_strlen_zero(file)) {
01374       res = ast_streamfile(chan, file, chan->language);
01375       if (!res) {
01376          res = ast_waitstream(chan, digits);
01377       }
01378    }
01379    return res;
01380 } 

int ast_stream_fastforward ( struct ast_filestream fs,
off_t  ms 
)

Fast forward stream ms.

Parameters:
fs filestream to act on
ms milliseconds to move
Return values:
0 on success.
-1 on failure.

Definition at line 894 of file file.c.

References ast_seekstream(), and DEFAULT_SAMPLES_PER_MS.

Referenced by waitstream_core().

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

int ast_stream_rewind ( struct ast_filestream fs,
off_t  ms 
)

Rewind stream ms.

Parameters:
fs filestream to act on
ms milliseconds to move
Return values:
0 on success.
-1 on failure.

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

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

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

Streams a file.

Parameters:
c channel to stream the file to
filename the name of the file you wish to stream, minus the extension
preflang the preferred language you wish to have the file streamed to you in Prepares a channel for the streaming of a file. To start the stream, afterward do a ast_waitstream() on the channel Also, it will stop any existing streams on the channel.
Return values:
0 on success.
-1 on failure.

Definition at line 946 of file file.c.

References ast_applystream(), ast_debug, AST_FLAG_MASQ_NOSTREAM, ast_getformatname(), ast_getformatname_multiple(), ast_log(), ast_openstream(), ast_openvstream(), ast_playstream(), ast_seekstream(), ast_strdup, ast_test_flag, ast_test_suite_event_notify, ast_verb, errno, ast_filestream::f, ast_filestream::fmt, ast_format::format, LOG_WARNING, ast_channel::nativeformats, ast_filestream::orig_chan_name, ast_filestream::vfs, and ast_channel::writeformat.

Referenced by __analog_ss_thread(), action_bridge(), agent_call(), analog_ss_thread(), announce_thread(), app_exec(), ast_app_getdata(), ast_app_getdata_full(), ast_control_streamfile(), ast_play_and_wait(), ast_say_date_da(), ast_say_date_de(), ast_say_date_en(), ast_say_date_fr(), ast_say_date_gr(), ast_say_date_he(), ast_say_date_hu(), ast_say_date_ka(), ast_say_date_nl(), ast_say_date_th(), ast_say_date_with_format_gr(), ast_say_datetime_en(), ast_say_datetime_fr(), ast_say_datetime_from_now_en(), ast_say_datetime_from_now_fr(), ast_say_datetime_from_now_he(), ast_say_datetime_from_now_ka(), ast_say_datetime_gr(), ast_say_datetime_he(), ast_say_datetime_nl(), ast_say_datetime_pt(), ast_say_datetime_th(), ast_say_datetime_zh(), ast_say_enumeration_full_da(), ast_say_enumeration_full_de(), ast_say_enumeration_full_en(), ast_say_enumeration_full_he(), ast_say_enumeration_full_vi(), ast_say_number_full_cs(), ast_say_number_full_da(), ast_say_number_full_de(), ast_say_number_full_en(), ast_say_number_full_en_GB(), ast_say_number_full_es(), ast_say_number_full_fr(), ast_say_number_full_gr(), ast_say_number_full_he(), ast_say_number_full_hu(), ast_say_number_full_it(), ast_say_number_full_ka(), ast_say_number_full_nl(), ast_say_number_full_no(), ast_say_number_full_pt(), ast_say_number_full_ru(), ast_say_number_full_se(), ast_say_number_full_th(), ast_say_number_full_ur(), ast_say_number_full_vi(), ast_say_number_full_zh(), ast_say_time_de(), ast_say_time_en(), ast_say_time_fr(), ast_say_time_gr(), ast_say_time_hu(), ast_say_time_ka(), ast_say_time_nl(), ast_say_time_zh(), ast_stream_and_wait(), auth_exec(), background_detect_exec(), bridge_exec(), check_availability(), check_beep(), common_exec(), conf_exec(), conf_run(), dial_exec_full(), do_directory(), find_conf_realtime(), forward_message(), gr_say_number_female(), handle_recordfile(), invent_message(), leave_voicemail(), local_attended_transfer(), login_exec(), meetme_menu_admin(), meetme_menu_admin_extended(), meetme_menu_normal(), menu_callback(), minivm_greet_exec(), page_exec(), parkandannounce_exec(), pbx_builtin_background(), pl_odtworz_plik(), play_and_wait(), play_file(), play_record_review(), playback_exec(), privacy_exec(), readexten_exec(), record_exec(), retrydial_exec(), s_streamwait3(), say_character_str_full(), say_digit_str_full(), say_phonetic_str_full(), select_item_menu(), setup_privacy_args(), vm_authenticate(), wait_file(), and wait_for_winner().

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

off_t ast_tellstream ( struct ast_filestream fs  ) 

Tell where we are in a stream.

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

Definition at line 889 of file file.c.

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

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

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

int ast_truncstream ( struct ast_filestream fs  ) 

Trunc stream at current location.

Parameters:
fs filestream to act on
Return values:
0 on success.
-1 on failure.

Definition at line 884 of file file.c.

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

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

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

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

Waits for a stream to stop or digit to be pressed.

Parameters:
c channel to waitstream on
breakon string of DTMF digits to break upon Begins playback of a stream... Wait for a stream to stop or for any one of a given digit to arrive,
Return values:
0 if the stream finishes
the character if it was interrupted,
-1 on error

Definition at line 1343 of file file.c.

References waitstream_core().

Referenced by __analog_ss_thread(), action_bridge(), agent_call(), analog_ss_thread(), announce_thread(), app_exec(), ast_play_and_wait(), ast_say_date_da(), ast_say_date_de(), ast_say_date_en(), ast_say_date_fr(), ast_say_date_gr(), ast_say_date_he(), ast_say_date_hu(), ast_say_date_ka(), ast_say_date_nl(), ast_say_date_th(), ast_say_date_with_format_gr(), ast_say_datetime_en(), ast_say_datetime_fr(), ast_say_datetime_from_now_en(), ast_say_datetime_from_now_fr(), ast_say_datetime_from_now_he(), ast_say_datetime_from_now_ka(), ast_say_datetime_gr(), ast_say_datetime_he(), ast_say_datetime_nl(), ast_say_datetime_pt(), ast_say_datetime_th(), ast_say_datetime_zh(), ast_say_enumeration_full_da(), ast_say_enumeration_full_de(), ast_say_enumeration_full_en(), ast_say_enumeration_full_he(), ast_say_enumeration_full_vi(), ast_say_number_full_cs(), ast_say_number_full_da(), ast_say_number_full_de(), ast_say_number_full_en(), ast_say_number_full_en_GB(), ast_say_number_full_es(), ast_say_number_full_fr(), ast_say_number_full_gr(), ast_say_number_full_he(), ast_say_number_full_hu(), ast_say_number_full_it(), ast_say_number_full_ka(), ast_say_number_full_nl(), ast_say_number_full_no(), ast_say_number_full_pt(), ast_say_number_full_ru(), ast_say_number_full_se(), ast_say_number_full_th(), ast_say_number_full_ur(), ast_say_number_full_vi(), ast_say_number_full_zh(), ast_say_time_de(), ast_say_time_en(), ast_say_time_gr(), ast_say_time_he(), ast_say_time_hu(), ast_say_time_ka(), ast_say_time_nl(), ast_say_time_zh(), ast_stream_and_wait(), auth_exec(), bridge_exec(), check_availability(), check_beep(), common_exec(), conf_exec(), conf_run(), directory_exec(), find_conf_realtime(), gr_say_number_female(), handle_recordfile(), invent_message(), leave_voicemail(), local_attended_transfer(), login_exec(), meetme_menu_admin(), meetme_menu_admin_extended(), meetme_menu_normal(), menu_callback(), minivm_greet_exec(), page_exec(), parkandannounce_exec(), pbx_builtin_background(), pl_odtworz_plik(), play_and_wait(), play_file(), play_record_review(), playback_exec(), privacy_exec(), record_exec(), retrydial_exec(), s_streamwait3(), say_character_str_full(), say_digit_str_full(), say_phonetic_str_full(), select_item_menu(), setup_privacy_args(), vm_authenticate(), and wait_file().

01344 {
01345    return waitstream_core(c, breakon, NULL, NULL, 0, -1, -1, NULL);
01346 }

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

Waits for a stream to stop or digit matching a valid one digit exten to be pressed.

Parameters:
c channel to waitstream on
context string of context to match digits to break upon Begins playback of a stream... Wait for a stream to stop or for any one of a valid extension digit to arrive,
Return values:
0 if the stream finishes.
the character if it was interrupted.
-1 on error.

Definition at line 1354 of file file.c.

References ast_channel::context, and waitstream_core().

Referenced by pbx_builtin_background().

01355 {
01356    /* Waitstream, with return in the case of a valid 1 digit extension */
01357    /* in the current or specified context being pressed */
01358 
01359    if (!context)
01360       context = c->context;
01361    return waitstream_core(c, NULL, NULL, NULL, 0,
01362       -1, -1, context);
01363 }

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

Same as waitstream but allows stream to be forwarded or rewound.

Parameters:
c channel to waitstream on
breakon string of DTMF digits to break upon
forward DTMF digit to fast forward upon
rewind DTMF digit to rewind upon
ms How many miliseconds to skip forward/back Begins playback of a stream... Wait for a stream to stop or for any one of a given digit to arrive,
Return values:
0 if the stream finishes.
the character if it was interrupted.
-1 on error.

Definition at line 1337 of file file.c.

References waitstream_core().

Referenced by ast_control_streamfile().

01338 {
01339    return waitstream_core(c, breakon, forward, reverse, ms,
01340       -1 /* no audiofd */, -1 /* no cmdfd */, NULL /* no context */);
01341 }

int ast_waitstream_full ( struct ast_channel c,
const char *  breakon,
int  audiofd,
int  monfd 
)
struct ast_filestream* ast_writefile ( const char *  filename,
const char *  type,
const char *  comment,
int  flags,
int  check,
mode_t  mode 
) [read]

Starts writing a file.

Parameters:
filename the name of the file to write to
type format of file you wish to write out to
comment comment to go with
flags output file flags
check (unimplemented, hence negligible)
mode Open mode Create an outgoing file stream. oflags are flags for the open() command, and if check is non-zero, then it will not write a file if there are any files that start with that name and have an extension Please note, this is a blocking function. Program execution will not return until ast_waitstream completes it's execution.
Return values:
a struct ast_filestream on success.
NULL on failure.

Definition at line 1049 of file file.c.

References ast_alloca, ast_closestream(), ast_free, ast_log(), ast_malloc, ast_opt_cache_record_files, AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_strdup, ast_strdupa, ast_filestream::buf, build_filename(), errno, ast_format::exts, exts_compare(), ast_filestream::f, f, ast_filestream::filename, ast_filestream::flags, ast_filestream::fmt, get_filestream(), LOG_WARNING, ast_filestream::mode, ast_filestream::realfilename, record_cache_dir, rewrite_wrapper(), ast_format::seek, ast_filestream::trans, ast_filestream::vfs, and ast_filestream::write_buffer.

Referenced by __ast_play_and_record(), ast_monitor_start(), ast_writestream(), dictate_exec(), handle_cli_file_convert(), handle_recordfile(), mixmonitor_thread(), record_exec(), and recordthread().

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

int ast_writestream ( struct ast_filestream fs,
struct ast_frame f 
)

Writes a frame to a stream.

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

Definition at line 150 of file file.c.

References ast_debug, AST_FORMAT_AUDIO_MASK, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_frfree, ast_getformatname(), AST_LIST_NEXT, ast_log(), ast_translate(), ast_translator_build_path(), ast_translator_free_path(), ast_writefile(), ast_writestream(), ast_frame_subclass::codec, ast_filestream::filename, ast_filestream::flags, ast_filestream::fmt, ast_format::format, ast_frame::frametype, ast_filestream::lastwriteformat, LOG_WARNING, ast_filestream::mode, ast_format::name, ast_frame::subclass, ast_filestream::trans, type, ast_filestream::vfs, and ast_format::write.

Referenced by __ast_play_and_record(), __ast_read(), ast_write(), ast_writestream(), dictate_exec(), handle_cli_file_convert(), handle_recordfile(), mixmonitor_thread(), record_exec(), and recordthread().

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

static char* build_filename ( const char *  filename,
const char *  ext 
) [static]

construct a filename. Absolute pathnames are preserved, relative names are prefixed by the sounds/ directory. The wav49 suffix is replaced by 'WAV'. Returns a malloc'ed string to be freed by the caller.

Definition at line 258 of file file.c.

References ast_asprintf, and ast_config_AST_DATA_DIR.

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

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

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

Definition at line 215 of file file.c.

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

Referenced by ast_filehelper().

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

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

Definition at line 280 of file file.c.

References ast_copy_string(), and ext.

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

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

static void file_shutdown ( void   )  [static]

Definition at line 1498 of file file.c.

References ARRAY_LEN, and ast_cli_unregister_multiple().

Referenced by ast_file_init().

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

helper routine to locate a file with a given format and language preference. Try preflang, preflang with stripped '_' suffices, or NULL.

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

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

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

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

Definition at line 552 of file file.c.

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

Referenced by fileexists_core().

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

static void filestream_close ( struct ast_filestream f  )  [static]

Definition at line 295 of file file.c.

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

Referenced by ast_closestream(), and filestream_destructor().

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

static void filestream_destructor ( void *  arg  )  [static]

Definition at line 312 of file file.c.

References ast_closestream(), ast_free, ast_module_unref(), ast_safe_fork(), ast_translator_free_path(), ast_format::close, ast_filestream::f, f, ast_filestream::filename, filestream_close(), ast_filestream::fmt, free, ast_format::module, ast_filestream::orig_chan_name, ast_filestream::realfilename, SENTINEL, status, ast_filestream::trans, ast_filestream::vfs, and ast_filestream::write_buffer.

Referenced by get_filestream().

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

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

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

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

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

Definition at line 360 of file file.c.

References ast_filestream::_private, ao2_alloc, ast_filestream::buf, ast_format::buf_size, ast_format::desc_size, ast_filestream::f, filestream_destructor(), ast_filestream::fmt, ast_filestream::fr, ast_format::name, and ast_frame::src.

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

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

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

Definition at line 1458 of file file.c.

References ast_cli_args::argc, ast_cli(), ast_getformatname(), AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_format::exts, f, ast_cli_args::fd, ast_format::format, FORMAT, FORMAT2, ast_format::list, ast_format::name, and ast_cli_entry::usage.

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

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

Definition at line 547 of file file.c.

Referenced by fileexists_test().

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

static int open_wrapper ( struct ast_filestream s  )  [static]

Definition at line 407 of file file.c.

References fn_wrapper(), and WRAP_OPEN.

Referenced by ast_filehelper(), and ast_readfile().

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

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

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

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

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

Definition at line 402 of file file.c.

References fn_wrapper(), and WRAP_REWRITE.

Referenced by ast_writefile().

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

static int waitstream_core ( struct ast_channel c,
const char *  breakon,
const char *  forward,
const char *  reverse,
int  skip_ms,
int  audiofd,
int  cmdfd,
const char *  context 
) [static]

the core of all waitstream() functions

Definition at line 1190 of file file.c.

References ast_channel::_softhangup, ast_clear_flag, AST_CONTROL_ANSWER, AST_CONTROL_AOC, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_CONNECTED_LINE, AST_CONTROL_HANGUP, AST_CONTROL_HOLD, AST_CONTROL_REDIRECTING, AST_CONTROL_RINGING, AST_CONTROL_SRCCHANGE, AST_CONTROL_SRCUPDATE, AST_CONTROL_UNHOLD, AST_CONTROL_UPDATE_RTP_PEER, AST_CONTROL_VIDUPDATE, ast_exists_extension(), AST_FLAG_END_DTMF_ONLY, AST_FLAG_MASQ_NOSTREAM, AST_FRAME_CONTROL, AST_FRAME_DTMF_END, AST_FRAME_VOICE, ast_frfree, ast_log(), ast_read(), ast_sched_runq(), ast_sched_wait(), ast_set_flag, ast_stopstream(), ast_strdupa, ast_stream_fastforward(), ast_stream_rewind(), ast_test_flag, ast_waitfor(), ast_waitfor_nandfds(), ast_channel::caller, ast_frame::data, ast_frame::datalen, errno, exten, ast_filestream::f, ast_frame::frametype, ast_party_caller::id, ast_frame_subclass::integer, LOG_WARNING, ast_party_id::number, ast_filestream::orig_chan_name, ast_frame::ptr, S_COR, ast_channel::sched, ast_party_number::str, ast_channel::stream, ast_frame::subclass, and ast_party_number::valid.

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

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


Variable Documentation

Definition at line 63 of file file.c.

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

struct ast_cli_entry cli_file[] [static]
Initial value:
 {
   AST_CLI_DEFINE(handle_cli_core_show_file_formats, "Displays file formats")
}

Definition at line 1494 of file file.c.


Generated on 17 Aug 2018 for Asterisk - The Open Source Telephony Project by  doxygen 1.6.1