Sat Sep 16 05:48:01 2006

Asterisk developer's documentation


file.h File Reference

Generic File Format Support. More...

#include "asterisk/channel.h"
#include "asterisk/frame.h"
#include <fcntl.h>

Go to the source code of this file.

Defines

#define AST_DIGIT_ANY   "0123456789#*ABCD"
#define AST_DIGIT_ANYNUM   "0123456789"
#define AST_RESERVED_POINTERS   20
#define SEEK_FORCECUR   10

Functions

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 *oldname, const char *newname, const char *fmt)
int ast_filedelete (const char *filename, const char *fmt)
int ast_fileexists (const char *filename, const char *fmt, const char *preflang)
int ast_filerename (const char *oldname, const char *newname, const char *fmt)
int ast_format_register (const char *name, const char *exts, int format, struct ast_filestream *(*open)(FILE *f), struct ast_filestream *(*rewrite)(FILE *f, const char *comment), int(*write)(struct ast_filestream *, struct ast_frame *), int(*seek)(struct ast_filestream *, long offset, int whence), int(*trunc)(struct ast_filestream *), long(*tell)(struct ast_filestream *), struct ast_frame *(*read)(struct ast_filestream *, int *timetonext), void(*close)(struct ast_filestream *), char *(*getcomment)(struct ast_filestream *))
int ast_format_unregister (const char *name)
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)
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)
int ast_seekstream (struct ast_filestream *fs, long sample_offset, int whence)
int ast_stopstream (struct ast_channel *c)
int ast_stream_fastforward (struct ast_filestream *fs, long ms)
int ast_stream_rewind (struct ast_filestream *fs, long ms)
int ast_streamfile (struct ast_channel *c, const char *filename, const char *preflang)
long 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 monfd)
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)


Detailed Description

Generic File Format Support.

Definition in file file.h.


Define Documentation

#define AST_DIGIT_ANY   "0123456789#*ABCD"

Convenient for waiting

Definition at line 41 of file file.h.

Referenced by __login_exec(), ast_ivr_menu_run_internal(), ast_play_and_wait(), ast_readstring(), ast_readstring_full(), ast_record_review(), background_file(), bridge_playfile(), builtin_atxfer(), builtin_blindtransfer(), conf_exec(), conf_run(), dial_exec_full(), dictate_exec(), directory_exec(), festival_exec(), get_folder(), ivr_dispatch(), pbx_builtin_background(), play_file(), play_mailbox_owner(), play_message(), play_message_callerid(), play_message_datetime(), play_message_duration(), play_record_review(), retrydial_exec(), say_and_wait(), say_position(), sayunixtime_exec(), try_calling(), vm_intro_gr(), vm_intro_pt(), and wait_file2().

#define AST_DIGIT_ANYNUM   "0123456789"

Definition at line 42 of file file.h.

Referenced by initreqprep().

#define AST_RESERVED_POINTERS   20

Definition at line 312 of file file.h.

#define SEEK_FORCECUR   10

Definition at line 44 of file file.h.

Referenced by ast_read(), ast_write(), au_seek(), g729_seek(), gsm_seek(), ilbc_seek(), pcm_seek(), slinear_seek(), vox_seek(), and wav_seek().


Function Documentation

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

References s.

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

00645 {
00646    s->owner = chan;
00647    return 0;
00648 }

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

References AST_FORMAT_MAX_AUDIO, ast_safe_system(), ast_sched_del(), ast_settimeout(), ast_translator_free_path(), ast_format::close, ast_filestream::filename, ast_filestream::fmt, ast_format::format, free, ast_filestream::owner, ast_filestream::realfilename, ast_channel::sched, ast_channel::stream, ast_channel::streamid, ast_filestream::trans, ast_channel::vstream, and ast_channel::vstreamid.

Referenced by ast_hangup(), ast_moh_files_next(), ast_monitor_start(), ast_monitor_stop(), ast_play_and_prepend(), ast_play_and_record_full(), ast_stopstream(), dictate_exec(), gen_closestream(), handle_recordfile(), launch_monitor_thread(), local_ast_moh_stop(), mixmonitor_thread(), moh_files_release(), and recordthread().

00690 {
00691    char *cmd = NULL;
00692    size_t size = 0;
00693    /* Stop a running stream if there is one */
00694    if (f->owner) {
00695       if (f->fmt->format < AST_FORMAT_MAX_AUDIO) {
00696          f->owner->stream = NULL;
00697          if (f->owner->streamid > -1)
00698             ast_sched_del(f->owner->sched, f->owner->streamid);
00699          f->owner->streamid = -1;
00700 #ifdef ZAPTEL_OPTIMIZATIONS
00701          ast_settimeout(f->owner, 0, NULL, NULL);
00702 #endif         
00703       } else {
00704          f->owner->vstream = NULL;
00705          if (f->owner->vstreamid > -1)
00706             ast_sched_del(f->owner->sched, f->owner->vstreamid);
00707          f->owner->vstreamid = -1;
00708       }
00709    }
00710    /* destroy the translator on exit */
00711    if (f->trans) {
00712       ast_translator_free_path(f->trans);
00713       f->trans = NULL;
00714    }
00715 
00716    if (f->realfilename && f->filename) {
00717          size = strlen(f->filename) + strlen(f->realfilename) + 15;
00718          cmd = alloca(size);
00719          memset(cmd,0,size);
00720          snprintf(cmd,size,"/bin/mv -f %s %s",f->filename,f->realfilename);
00721          ast_safe_system(cmd);
00722    }
00723 
00724    if (f->filename) {
00725       free(f->filename);
00726       f->filename = NULL;
00727    }
00728    if (f->realfilename) {
00729       free(f->realfilename);
00730       f->realfilename = NULL;
00731    }
00732    f->fmt->close(f);
00733    return 0;
00734 }

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

References ast_cli_register(), and show_file.

Referenced by main().

01291 {
01292    ast_cli_register(&show_file);
01293    return 0;
01294 }

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

References ACTION_COPY, and ast_filehelper().

Referenced by copy_file().

00796 {
00797    return ast_filehelper(filename, filename2, fmt, ACTION_COPY);
00798 }

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

References ACTION_DELETE, and ast_filehelper().

Referenced by ast_monitor_start(), ast_monitor_stop(), ast_play_and_prepend(), dial_exec_full(), leave_voicemail(), play_mailbox_owner(), and vm_delete().

00786 {
00787    return ast_filehelper(filename, NULL, fmt, ACTION_DELETE);
00788 }

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

References ACTION_EXISTS, ast_filehelper(), ast_strlen_zero(), MAX_LANGUAGE, and strsep().

Referenced by app_exec(), ast_moh_files_next(), ast_monitor_start(), ast_monitor_stop(), ast_openstream_full(), ast_openvstream(), chanspy_exec(), conf_run(), dial_exec_full(), invent_message(), last_message_index(), leave_voicemail(), play_mailbox_owner(), play_message_callerid(), record_exec(), rxfax_exec(), and vm_tempgreeting().

00738 {
00739    char filename2[256];
00740    char tmp[256];
00741    char *postfix;
00742    char *prefix;
00743    char *c;
00744    char lang2[MAX_LANGUAGE];
00745    int res = -1;
00746    if (!ast_strlen_zero(preflang)) {
00747       /* Insert the language between the last two parts of the path */
00748       ast_copy_string(tmp, filename, sizeof(tmp));
00749       c = strrchr(tmp, '/');
00750       if (c) {
00751          *c = '\0';
00752          postfix = c+1;
00753          prefix = tmp;
00754          snprintf(filename2, sizeof(filename2), "%s/%s/%s", prefix, preflang, postfix);
00755       } else {
00756          postfix = tmp;
00757          prefix="";
00758          snprintf(filename2, sizeof(filename2), "%s/%s", preflang, postfix);
00759       }
00760       res = ast_filehelper(filename2, NULL, fmt, ACTION_EXISTS);
00761       if (res < 1) {
00762          char *stringp=NULL;
00763          ast_copy_string(lang2, preflang, sizeof(lang2));
00764          stringp=lang2;
00765          strsep(&stringp, "_");
00766          /* If language is a specific locality of a language (like es_MX), strip the locality and try again */
00767          if (strcmp(lang2, preflang)) {
00768             if (ast_strlen_zero(prefix)) {
00769                snprintf(filename2, sizeof(filename2), "%s/%s", lang2, postfix);
00770             } else {
00771                snprintf(filename2, sizeof(filename2), "%s/%s/%s", prefix, lang2, postfix);
00772             }
00773             res = ast_filehelper(filename2, NULL, fmt, ACTION_EXISTS);
00774          }
00775       }
00776    }
00777 
00778    /* Fallback to no language (usually winds up being American English) */
00779    if (res < 1) {
00780       res = ast_filehelper(filename, NULL, fmt, ACTION_EXISTS);
00781    }
00782    return res;
00783 }

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

References ACTION_RENAME, and ast_filehelper().

Referenced by ast_monitor_stop(), ast_play_and_prepend(), leave_voicemail(), and rename_file().

00791 {
00792    return ast_filehelper(filename, filename2, fmt, ACTION_RENAME);
00793 }

int ast_format_register ( const char *  name,
const char *  exts,
int  format,
struct ast_filestream *(*)(FILE *f)  open,
struct ast_filestream *(*)(FILE *f, const char *comment)  rewrite,
int(*)(struct ast_filestream *, struct ast_frame *)  write,
int(*)(struct ast_filestream *, long offset, int whence)  seek,
int(*)(struct ast_filestream *)  trunc,
long(*)(struct ast_filestream *)  tell,
struct ast_frame *(*)(struct ast_filestream *, int *timetonext)  read,
void(*)(struct ast_filestream *)  close,
char *(*)(struct ast_filestream *)  getcomment 
)

Register a new file format capability Adds a format to asterisk's format abilities. Fill in the fields, and it will work. For examples, look at some of the various format code. returns 0 on success, -1 on failure

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

References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_verbose(), formats, free, LOG_WARNING, ast_format::name, ast_format::next, option_verbose, and VERBOSE_PREFIX_2.

Referenced by unload_module().

00157 {
00158    struct ast_format *tmp, *tmpl = NULL;
00159    if (ast_mutex_lock(&formatlock)) {
00160       ast_log(LOG_WARNING, "Unable to lock format list\n");
00161       return -1;
00162    }
00163    tmp = formats;
00164    while(tmp) {
00165       if (!strcasecmp(name, tmp->name)) {
00166          if (tmpl) 
00167             tmpl->next = tmp->next;
00168          else
00169             formats = tmp->next;
00170          free(tmp);
00171          ast_mutex_unlock(&formatlock);
00172          if (option_verbose > 1)
00173             ast_verbose( VERBOSE_PREFIX_2 "Unregistered format %s\n", name);
00174          return 0;
00175       }
00176       tmpl = tmp;
00177       tmp = tmp->next;
00178    }
00179    ast_mutex_unlock(&formatlock);
00180    ast_log(LOG_WARNING, "Tried to unregister format %s, already unregistered\n", name);
00181    return -1;
00182 }

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

References ast_openstream_full().

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

00466 {
00467    return ast_openstream_full(chan, filename, preflang, 0);
00468 }

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

References ACTION_OPEN, ast_deactivate_generator(), ast_fileexists(), ast_filehelper(), ast_log(), ast_set_write_format(), ast_stopstream(), ast_strlen_zero(), LOG_WARNING, ast_channel::oldwriteformat, and ast_channel::writeformat.

Referenced by ast_openstream(), and gen_nextfile().

00471 {
00472    /* This is a fairly complex routine.  Essentially we should do 
00473       the following:
00474       
00475       1) Find which file handlers produce our type of format.
00476       2) Look for a filename which it can handle.
00477       3) If we find one, then great.  
00478       4) If not, see what files are there
00479       5) See what we can actually support
00480       6) Choose the one with the least costly translator path and
00481           set it up.
00482          
00483    */
00484    int fmts = -1;
00485    char filename2[256]="";
00486    char filename3[256];
00487    char *endpart;
00488    int res;
00489 
00490    if (!asis) {
00491       /* do this first, otherwise we detect the wrong writeformat */
00492       ast_stopstream(chan);
00493       if (chan->generator)
00494          ast_deactivate_generator(chan);
00495    }
00496    if (!ast_strlen_zero(preflang)) {
00497       ast_copy_string(filename3, filename, sizeof(filename3));
00498       endpart = strrchr(filename3, '/');
00499       if (endpart) {
00500          *endpart = '\0';
00501          endpart++;
00502          snprintf(filename2, sizeof(filename2), "%s/%s/%s", filename3, preflang, endpart);
00503       } else
00504          snprintf(filename2, sizeof(filename2), "%s/%s", preflang, filename);
00505       fmts = ast_fileexists(filename2, NULL, NULL);
00506    }
00507    if (fmts < 1) {
00508       ast_copy_string(filename2, filename, sizeof(filename2));
00509       fmts = ast_fileexists(filename2, NULL, NULL);
00510    }
00511    if (fmts < 1) {
00512       ast_log(LOG_WARNING, "File %s does not exist in any format\n", filename);
00513       return NULL;
00514    }
00515    chan->oldwriteformat = chan->writeformat;
00516    /* Set the channel to a format we can work with */
00517    res = ast_set_write_format(chan, fmts);
00518    
00519    res = ast_filehelper(filename2, (char *)chan, NULL, ACTION_OPEN);
00520    if (res >= 0)
00521       return chan->stream;
00522    return NULL;
00523 }

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

References ACTION_OPEN, ast_fileexists(), ast_filehelper(), ast_log(), ast_strlen_zero(), fmt, LOG_WARNING, and MAX_LANGUAGE.

Referenced by ast_streamfile().

00526 {
00527    /* This is a fairly complex routine.  Essentially we should do 
00528       the following:
00529       
00530       1) Find which file handlers produce our type of format.
00531       2) Look for a filename which it can handle.
00532       3) If we find one, then great.  
00533       4) If not, see what files are there
00534       5) See what we can actually support
00535       6) Choose the one with the least costly translator path and
00536           set it up.
00537          
00538    */
00539    int fd = -1;
00540    int fmts = -1;
00541    char filename2[256];
00542    char lang2[MAX_LANGUAGE];
00543    /* XXX H.263 only XXX */
00544    char *fmt = "h263";
00545    if (!ast_strlen_zero(preflang)) {
00546       snprintf(filename2, sizeof(filename2), "%s/%s", preflang, filename);
00547       fmts = ast_fileexists(filename2, fmt, NULL);
00548       if (fmts < 1) {
00549          ast_copy_string(lang2, preflang, sizeof(lang2));
00550          snprintf(filename2, sizeof(filename2), "%s/%s", lang2, filename);
00551          fmts = ast_fileexists(filename2, fmt, NULL);
00552       }
00553    }
00554    if (fmts < 1) {
00555       ast_copy_string(filename2, filename, sizeof(filename2));
00556       fmts = ast_fileexists(filename2, fmt, NULL);
00557    }
00558    if (fmts < 1) {
00559       return NULL;
00560    }
00561    fd = ast_filehelper(filename2, (char *)chan, fmt, ACTION_OPEN);
00562    if (fd >= 0)
00563       return chan->vstream;
00564    ast_log(LOG_WARNING, "File %s has video but couldn't be opened\n", filename);
00565    return NULL;
00566 }

int ast_playstream ( struct ast_filestream s  ) 

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

Definition at line 650 of file file.c.

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

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

00651 {
00652    if (s->fmt->format < AST_FORMAT_MAX_AUDIO)
00653       ast_readaudio_callback(s);
00654    else
00655       ast_readvideo_callback(s);
00656    return 0;
00657 }

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

References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), build_filename(), exts_compare(), ast_filestream::f, ast_filestream::filename, ast_filestream::flags, ast_filestream::fmt, formats, free, LOG_WARNING, ast_filestream::mode, strdup, ast_filestream::trans, and ast_filestream::vfs.

Referenced by ast_play_and_prepend().

00829 {
00830    FILE *bfile;
00831    struct ast_format *f;
00832    struct ast_filestream *fs = NULL;
00833    char *fn;
00834 
00835    if (ast_mutex_lock(&formatlock)) {
00836       ast_log(LOG_WARNING, "Unable to lock format list\n");
00837       return NULL;
00838    }
00839 
00840    for (f = formats; f && !fs; f = f->next) {
00841       if (!exts_compare(f->exts, type))
00842          continue;
00843 
00844       fn = build_filename(filename, type);
00845       bfile = fopen(fn, "r");
00846       if (bfile) {
00847          errno = 0;
00848 
00849          if (!(fs = f->open(bfile))) {
00850             ast_log(LOG_WARNING, "Unable to open %s\n", fn);
00851             fclose(bfile);
00852             free(fn);
00853             continue;
00854          }
00855 
00856          fs->trans = NULL;
00857          fs->fmt = f;
00858          fs->flags = flags;
00859          fs->mode = mode;
00860          fs->filename = strdup(filename);
00861          fs->vfs = NULL;
00862       } else if (errno != EEXIST)
00863          ast_log(LOG_WARNING, "Unable to open file %s: %s\n", fn, strerror(errno));
00864       free(fn);
00865    }
00866 
00867    ast_mutex_unlock(&formatlock);
00868    if (!fs) 
00869       ast_log(LOG_WARNING, "No such format '%s'\n", type);
00870 
00871    return fs;
00872 }

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

References s.

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

00569 {
00570    struct ast_frame *f = NULL;
00571    int whennext = 0; 
00572    if (s && s->fmt)
00573       f = s->fmt->read(s, &whennext);
00574    return f;
00575 }

int ast_seekstream ( struct ast_filestream fs,
long  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 659 of file file.c.

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

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

00660 {
00661    return fs->fmt->seek(fs, sample_offset, whence);
00662 }

int ast_stopstream ( struct ast_channel c  ) 

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

Definition at line 184 of file file.c.

References ast_closestream(), 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(), ast_readstring_full(), ast_say_character_str_full(), ast_say_digit_str_full(), ast_say_enumeration_full_da(), ast_say_enumeration_full_de(), ast_say_enumeration_full_en(), ast_say_number_full_cz(), 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_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_tw(), ast_say_phonetic_str_full(), ast_waitstream(), ast_waitstream_exten(), ast_waitstream_fr(), ast_waitstream_full(), background_detect_exec(), background_file(), 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(), saycharstr(), sayfile(), saynum(), send_morse(), send_tone_telemetry(), send_waveform_to_channel(), vm_authenticate(), vm_execmain(), and zapateller_exec().

00185 {
00186    /* Stop a running stream if there is one */
00187    if (tmp->vstream) {
00188       ast_closestream(tmp->vstream);
00189       tmp->vstream = NULL;
00190    }
00191    if (tmp->stream) {
00192       ast_closestream(tmp->stream);
00193       tmp->stream = NULL;
00194       if (tmp->oldwriteformat && ast_set_write_format(tmp, tmp->oldwriteformat))
00195          ast_log(LOG_WARNING, "Unable to restore format back to %d\n", tmp->oldwriteformat);
00196    }
00197    return 0;
00198 }

int ast_stream_fastforward ( struct ast_filestream fs,
long  ms 
)

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

Definition at line 674 of file file.c.

References ast_seekstream(), and ast_frame::samples.

Referenced by ast_waitstream_fr().

00675 {
00676    /* I think this is right, 8000 samples per second, 1000 ms a second so 8
00677     * samples per ms  */
00678    long samples = ms * 8;
00679    return ast_seekstream(fs, samples, SEEK_CUR);
00680 }

int ast_stream_rewind ( struct ast_filestream fs,
long  ms 
)

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

Definition at line 682 of file file.c.

References ast_seekstream(), and ast_frame::samples.

Referenced by ast_play_and_prepend(), ast_play_and_record_full(), ast_waitstream_fr(), and handle_recordfile().

00683 {
00684    long samples = ms * 8;
00685    samples = samples * -1;
00686    return ast_seekstream(fs, samples, SEEK_CUR);
00687 }

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

References ast_applystream(), ast_getformatname(), ast_log(), ast_openstream(), ast_openvstream(), ast_playstream(), ast_verbose(), LOG_DEBUG, LOG_WARNING, ast_channel::nativeformats, option_verbose, VERBOSE_PREFIX_3, and ast_filestream::vfs.

Referenced by __login_exec(), agent_call(), ast_app_getdata(), ast_app_getdata_full(), ast_app_getvoice(), ast_control_streamfile(), ast_play_and_prepend(), ast_play_and_record_full(), ast_play_and_wait(), ast_record_review(), ast_say_character_str_full(), ast_say_date_da(), ast_say_date_de(), ast_say_date_en(), ast_say_date_fr(), ast_say_date_gr(), 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_gr(), ast_say_datetime_nl(), ast_say_datetime_pt(), ast_say_datetime_tw(), ast_say_digit_str_full(), ast_say_enumeration_full_da(), ast_say_enumeration_full_de(), ast_say_enumeration_full_en(), ast_say_number_full_cz(), 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_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_tw(), ast_say_phonetic_str_full(), ast_say_time_de(), ast_say_time_en(), ast_say_time_fr(), ast_say_time_gr(), ast_say_time_nl(), ast_say_time_tw(), auth_exec(), background_detect_exec(), background_file(), bridge_playfile(), builtin_atxfer(), builtin_automonitor(), builtin_blindtransfer(), chanspy_exec(), check_availability(), check_beep(), conf_exec(), conf_run(), dial_exec_full(), directory_exec(), do_directory(), forward_message(), gr_say_number_female(), handle_recordfile(), invent_message(), ivr_dispatch(), leave_voicemail(), page_exec(), park_exec(), parkandannounce_exec(), pbx_builtin_background(), pl_odtworz_plik(), play_and_wait(), play_file(), play_mailbox_owner(), play_message_callerid(), play_record_review(), playback_exec(), privacy_exec(), retrydial_exec(), rpt_tele_thread(), sayfile(), ss_thread(), vm_authenticate(), wait_file(), and wait_file2().

00801 {
00802    struct ast_filestream *fs;
00803    struct ast_filestream *vfs;
00804 
00805    fs = ast_openstream(chan, filename, preflang);
00806    vfs = ast_openvstream(chan, filename, preflang);
00807    if (vfs)
00808       ast_log(LOG_DEBUG, "Ooh, found a video stream, too\n");
00809    if (fs){
00810       if (ast_applystream(chan, fs))
00811          return -1;
00812       if (vfs && ast_applystream(chan, vfs))
00813          return -1;
00814       if (ast_playstream(fs))
00815          return -1;
00816       if (vfs && ast_playstream(vfs))
00817          return -1;
00818 #if 1
00819       if (option_verbose > 2)
00820          ast_verbose(VERBOSE_PREFIX_3 "Playing '%s' (language '%s')\n", filename, preflang ? preflang : "default");
00821 #endif
00822       return 0;
00823    }
00824    ast_log(LOG_WARNING, "Unable to open %s (format %s): %s\n", filename, ast_getformatname(chan->nativeformats), strerror(errno));
00825    return -1;
00826 }

long ast_tellstream ( struct ast_filestream fs  ) 

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

Definition at line 669 of file file.c.

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

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

00670 {
00671    return fs->fmt->tell(fs);
00672 }

int ast_truncstream ( struct ast_filestream fs  ) 

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

Definition at line 664 of file file.c.

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

Referenced by ast_play_and_prepend(), ast_play_and_record_full(), and handle_recordfile().

00665 {
00666    return fs->fmt->trunc(fs);
00667 }

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

Parameters:
c channel to waitstram 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 993 of file file.c.

References ast_channel::_softhangup, AST_CONTROL_ANSWER, AST_CONTROL_HANGUP, AST_CONTROL_RINGING, AST_CONTROL_VIDUPDATE, AST_FRAME_CONTROL, AST_FRAME_DTMF, ast_frfree(), ast_log(), ast_read(), ast_sched_runq(), ast_sched_wait(), ast_stopstream(), ast_waitfor(), ast_frame::frametype, LOG_DEBUG, LOG_WARNING, ast_channel::sched, ast_channel::stream, ast_frame::subclass, and ast_channel::timingfunc.

Referenced by __login_exec(), agent_call(), ast_app_getvoice(), ast_play_and_prepend(), ast_play_and_record_full(), ast_play_and_wait(), ast_readstring(), ast_record_review(), ast_say_date_da(), ast_say_date_de(), ast_say_date_en(), ast_say_date_fr(), ast_say_date_gr(), 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_gr(), ast_say_datetime_nl(), ast_say_datetime_pt(), ast_say_datetime_tw(), ast_say_enumeration_full_da(), ast_say_enumeration_full_de(), ast_say_enumeration_full_en(), ast_say_number_full_cz(), 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_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_tw(), ast_say_time_de(), ast_say_time_en(), ast_say_time_gr(), ast_say_time_nl(), ast_say_time_tw(), auth_exec(), background_file(), bridge_playfile(), builtin_atxfer(), builtin_automonitor(), builtin_blindtransfer(), chanspy_exec(), check_availability(), check_beep(), conf_exec(), conf_run(), dial_exec_full(), directory_exec(), gr_say_number_female(), handle_recordfile(), invent_message(), ivr_dispatch(), leave_voicemail(), page_exec(), park_exec(), parkandannounce_exec(), pbx_builtin_background(), pl_odtworz_plik(), play_and_wait(), play_file(), play_mailbox_owner(), play_message_callerid(), play_record_review(), playback_exec(), privacy_exec(), retrydial_exec(), rpt_tele_thread(), saycharstr(), sayfile(), saynum(), send_morse(), send_tone_telemetry(), ss_thread(), vm_authenticate(), wait_file(), and wait_file2().

00994 {
00995    /* XXX Maybe I should just front-end ast_waitstream_full ? XXX */
00996    int res;
00997    struct ast_frame *fr;
00998    if (!breakon) breakon = "";
00999    while(c->stream) {
01000       res = ast_sched_wait(c->sched);
01001       if ((res < 0) && !c->timingfunc) {
01002          ast_stopstream(c);
01003          break;
01004       }
01005       if (res < 0)
01006          res = 1000;
01007       res = ast_waitfor(c, res);
01008       if (res < 0) {
01009          ast_log(LOG_WARNING, "Select failed (%s)\n", strerror(errno));
01010          return res;
01011       } else if (res > 0) {
01012          fr = ast_read(c);
01013          if (!fr) {
01014 #if 0
01015             ast_log(LOG_DEBUG, "Got hung up\n");
01016 #endif
01017             return -1;
01018          }
01019          
01020          switch(fr->frametype) {
01021          case AST_FRAME_DTMF:
01022             res = fr->subclass;
01023             if (strchr(breakon, res)) {
01024                ast_frfree(fr);
01025                return res;
01026             }
01027             break;
01028          case AST_FRAME_CONTROL:
01029             switch(fr->subclass) {
01030             case AST_CONTROL_HANGUP:
01031                ast_frfree(fr);
01032                return -1;
01033             case AST_CONTROL_RINGING:
01034             case AST_CONTROL_ANSWER:
01035             case AST_CONTROL_VIDUPDATE:
01036                /* Unimportant */
01037                break;
01038             default:
01039                ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", fr->subclass);
01040             }
01041          }
01042          /* Ignore */
01043          ast_frfree(fr);
01044       }
01045       ast_sched_runq(c->sched);
01046    }
01047    return (c->_softhangup ? -1 : 0);
01048 }

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

Parameters:
c channel to waitstram 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 1190 of file file.c.

References ast_channel::_softhangup, AST_CONTROL_ANSWER, AST_CONTROL_HANGUP, AST_CONTROL_RINGING, ast_exists_extension(), AST_FRAME_CONTROL, AST_FRAME_DTMF, ast_frfree(), ast_log(), AST_MAX_EXTENSION, ast_read(), ast_sched_runq(), ast_sched_wait(), ast_stopstream(), ast_waitfor(), ast_channel::cid, ast_callerid::cid_num, ast_channel::context, exten, ast_frame::frametype, LOG_DEBUG, LOG_WARNING, ast_channel::sched, ast_channel::stream, ast_frame::subclass, and ast_channel::timingfunc.

Referenced by pbx_builtin_background().

01191 {
01192    /* Waitstream, with return in the case of a valid 1 digit extension */
01193    /* in the current or specified context being pressed */
01194    /* XXX Maybe I should just front-end ast_waitstream_full ? XXX */
01195    int res;
01196    struct ast_frame *fr;
01197    char exten[AST_MAX_EXTENSION];
01198 
01199    if (!context) context = c->context;
01200    while(c->stream) {
01201       res = ast_sched_wait(c->sched);
01202       if ((res < 0) && !c->timingfunc) {
01203          ast_stopstream(c);
01204          break;
01205       }
01206       if (res < 0)
01207          res = 1000;
01208       res = ast_waitfor(c, res);
01209       if (res < 0) {
01210          ast_log(LOG_WARNING, "Select failed (%s)\n", strerror(errno));
01211          return res;
01212       } else if (res > 0) {
01213          fr = ast_read(c);
01214          if (!fr) {
01215 #if 0
01216             ast_log(LOG_DEBUG, "Got hung up\n");
01217 #endif
01218             return -1;
01219          }
01220          
01221          switch(fr->frametype) {
01222          case AST_FRAME_DTMF:
01223             res = fr->subclass;
01224             snprintf(exten, sizeof(exten), "%c", res);
01225             if (ast_exists_extension(c, context, exten, 1, c->cid.cid_num)) {
01226                ast_frfree(fr);
01227                return res;
01228             }
01229             break;
01230          case AST_FRAME_CONTROL:
01231             switch(fr->subclass) {
01232             case AST_CONTROL_HANGUP:
01233                ast_frfree(fr);
01234                return -1;
01235             case AST_CONTROL_RINGING:
01236             case AST_CONTROL_ANSWER:
01237                /* Unimportant */
01238                break;
01239             default:
01240                ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", fr->subclass);
01241             }
01242          }
01243          /* Ignore */
01244          ast_frfree(fr);
01245       }
01246       ast_sched_runq(c->sched);
01247    }
01248    return (c->_softhangup ? -1 : 0);
01249 }

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

Parameters:
c channel to waitstram 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 1050 of file file.c.

References ast_channel::_softhangup, AST_CONTROL_ANSWER, AST_CONTROL_HANGUP, AST_CONTROL_RINGING, AST_FRAME_CONTROL, AST_FRAME_DTMF, ast_frfree(), ast_log(), ast_read(), ast_sched_runq(), ast_sched_wait(), ast_stopstream(), ast_stream_fastforward(), ast_stream_rewind(), ast_waitfor(), ast_frame::frametype, LOG_DEBUG, LOG_WARNING, ast_channel::sched, ast_channel::stream, ast_frame::subclass, and ast_channel::timingfunc.

Referenced by ast_control_streamfile().

01051 {
01052    int res;
01053    struct ast_frame *fr;
01054 
01055    if (!breakon)
01056          breakon = "";
01057    if (!forward)
01058          forward = "";
01059    if (!rewind)
01060          rewind = "";
01061    
01062    while(c->stream) {
01063       res = ast_sched_wait(c->sched);
01064       if ((res < 0) && !c->timingfunc) {
01065          ast_stopstream(c);
01066          break;
01067       }
01068       if (res < 0)
01069          res = 1000;
01070       res = ast_waitfor(c, res);
01071       if (res < 0) {
01072          ast_log(LOG_WARNING, "Select failed (%s)\n", strerror(errno));
01073          return res;
01074       } else
01075       if (res > 0) {
01076          fr = ast_read(c);
01077          if (!fr) {
01078 #if 0
01079             ast_log(LOG_DEBUG, "Got hung up\n");
01080 #endif
01081             return -1;
01082          }
01083          
01084          switch(fr->frametype) {
01085          case AST_FRAME_DTMF:
01086             res = fr->subclass;
01087             if (strchr(forward,res)) {
01088                ast_stream_fastforward(c->stream, ms);
01089             } else if (strchr(rewind,res)) {
01090                ast_stream_rewind(c->stream, ms);
01091             } else if (strchr(breakon, res)) {
01092                ast_frfree(fr);
01093                return res;
01094             }              
01095             break;
01096          case AST_FRAME_CONTROL:
01097             switch(fr->subclass) {
01098             case AST_CONTROL_HANGUP:
01099                ast_frfree(fr);
01100                return -1;
01101             case AST_CONTROL_RINGING:
01102             case AST_CONTROL_ANSWER:
01103                /* Unimportant */
01104                break;
01105             default:
01106                ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", fr->subclass);
01107             }
01108          }
01109          /* Ignore */
01110          ast_frfree(fr);
01111       } else
01112          ast_sched_runq(c->sched);
01113    
01114       
01115    }
01116    return (c->_softhangup ? -1 : 0);
01117 }

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

Definition at line 1119 of file file.c.

References ast_channel::_softhangup, AST_CONTROL_ANSWER, AST_CONTROL_HANGUP, AST_CONTROL_RINGING, AST_FRAME_CONTROL, AST_FRAME_DTMF, AST_FRAME_VOICE, ast_frfree(), ast_log(), ast_read(), ast_sched_runq(), ast_sched_wait(), ast_stopstream(), ast_waitfor_nandfds(), ast_frame::data, ast_frame::datalen, ast_frame::frametype, LOG_DEBUG, LOG_WARNING, ast_channel::sched, ast_channel::stream, ast_frame::subclass, and ast_channel::timingfunc.

Referenced by ast_readstring_full(), ast_say_character_str_full(), ast_say_digit_str_full(), ast_say_enumeration_full_da(), ast_say_enumeration_full_de(), ast_say_enumeration_full_en(), ast_say_number_full_cz(), 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_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_tw(), ast_say_phonetic_str_full(), handle_getoption(), handle_streamfile(), and pl_odtworz_plik().

01120 {
01121    int res;
01122    int ms;
01123    int outfd;
01124    struct ast_frame *fr;
01125    struct ast_channel *rchan;
01126 
01127    if (!breakon)
01128       breakon = "";
01129    
01130    while(c->stream) {
01131       ms = ast_sched_wait(c->sched);
01132       if ((ms < 0) && !c->timingfunc) {
01133          ast_stopstream(c);
01134          break;
01135       }
01136       if (ms < 0)
01137          ms = 1000;
01138       rchan = ast_waitfor_nandfds(&c, 1, &cmdfd, (cmdfd > -1) ? 1 : 0, NULL, &outfd, &ms);
01139       if (!rchan && (outfd < 0) && (ms)) {
01140          /* Continue */
01141          if (errno == EINTR)
01142             continue;
01143          ast_log(LOG_WARNING, "Wait failed (%s)\n", strerror(errno));
01144          return -1;
01145       } else if (outfd > -1) {
01146          /* The FD we were watching has something waiting */
01147          return 1;
01148       } else if (rchan) {
01149          fr = ast_read(c);
01150          if (!fr) {
01151 #if 0
01152             ast_log(LOG_DEBUG, "Got hung up\n");
01153 #endif
01154             return -1;
01155          }
01156          
01157          switch(fr->frametype) {
01158          case AST_FRAME_DTMF:
01159             res = fr->subclass;
01160             if (strchr(breakon, res)) {
01161                ast_frfree(fr);
01162                return res;
01163             }
01164             break;
01165          case AST_FRAME_CONTROL:
01166             switch(fr->subclass) {
01167             case AST_CONTROL_HANGUP:
01168                ast_frfree(fr);
01169                return -1;
01170             case AST_CONTROL_RINGING:
01171             case AST_CONTROL_ANSWER:
01172                /* Unimportant */
01173                break;
01174             default:
01175                ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", fr->subclass);
01176             }
01177          case AST_FRAME_VOICE:
01178             /* Write audio if appropriate */
01179             if (audiofd > -1)
01180                write(audiofd, fr->data, fr->datalen);
01181          }
01182          /* Ignore */
01183          ast_frfree(fr);
01184       }
01185       ast_sched_runq(c->sched);
01186    }
01187    return (c->_softhangup ? -1 : 0);
01188 }

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

References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_strdupa, ast_filestream::buf, build_filename(), exts_compare(), ast_filestream::f, ast_filestream::filename, ast_filestream::flags, ast_filestream::fmt, formats, free, LOG_WARNING, ast_filestream::mode, option_cache_record_files, ast_filestream::realfilename, record_cache_dir, strdup, ast_filestream::trans, and ast_filestream::vfs.

Referenced by ast_app_getvoice(), ast_monitor_start(), ast_play_and_prepend(), ast_play_and_record_full(), ast_writestream(), dictate_exec(), handle_recordfile(), launch_monitor_thread(), and recordthread().

00875 {
00876    int fd, myflags = 0;
00877    /* compiler claims this variable can be used before initialization... */
00878    FILE *bfile = NULL;
00879    struct ast_format *f;
00880    struct ast_filestream *fs = NULL;
00881    char *fn, *orig_fn = NULL;
00882    char *buf = NULL;
00883    size_t size = 0;
00884    int format_found = 0;
00885 
00886    if (ast_mutex_lock(&formatlock)) {
00887       ast_log(LOG_WARNING, "Unable to lock format list\n");
00888       return NULL;
00889    }
00890 
00891    /* set the O_TRUNC flag if and only if there is no O_APPEND specified */
00892    if (flags & O_APPEND) { 
00893       /* We really can't use O_APPEND as it will break WAV header updates */
00894       flags &= ~O_APPEND;
00895    } else {
00896       myflags = O_TRUNC;
00897    }
00898    
00899    myflags |= O_WRONLY | O_CREAT;
00900 
00901    for (f = formats; f && !fs; f = f->next) {
00902       if (!exts_compare(f->exts, type))
00903          continue;
00904       else
00905          format_found = 1;
00906 
00907       fn = build_filename(filename, type);
00908       fd = open(fn, flags | myflags, mode);
00909       if (fd > -1) {
00910          /* fdopen() the resulting file stream */
00911          bfile = fdopen(fd, ((flags | myflags) & O_RDWR) ? "w+" : "w");
00912          if (!bfile) {
00913             ast_log(LOG_WARNING, "Whoa, fdopen failed: %s!\n", strerror(errno));
00914             close(fd);
00915             fd = -1;
00916          }
00917       }
00918       
00919       if (option_cache_record_files && (fd > -1)) {
00920          char *c;
00921 
00922          fclose(bfile);
00923          /*
00924            We touch orig_fn just as a place-holder so other things (like vmail) see the file is there.
00925            What we are really doing is writing to record_cache_dir until we are done then we will mv the file into place.
00926          */
00927          orig_fn = ast_strdupa(fn);
00928          for (c = fn; *c; c++)
00929             if (*c == '/')
00930                *c = '_';
00931 
00932          size = strlen(fn) + strlen(record_cache_dir) + 2;
00933          buf = alloca(size);
00934          strcpy(buf, record_cache_dir);
00935          strcat(buf, "/");
00936          strcat(buf, fn);
00937          free(fn);
00938          fn = buf;
00939          fd = open(fn, flags | myflags, mode);
00940          if (fd > -1) {
00941             /* fdopen() the resulting file stream */
00942             bfile = fdopen(fd, ((flags | myflags) & O_RDWR) ? "w+" : "w");
00943             if (!bfile) {
00944                ast_log(LOG_WARNING, "Whoa, fdopen failed: %s!\n", strerror(errno));
00945                close(fd);
00946                fd = -1;
00947             }
00948          }
00949       }
00950       if (fd > -1) {
00951          errno = 0;
00952          if ((fs = f->rewrite(bfile, comment))) {
00953             fs->trans = NULL;
00954             fs->fmt = f;
00955             fs->flags = flags;
00956             fs->mode = mode;
00957             if (orig_fn) {
00958                fs->realfilename = strdup(orig_fn);
00959                fs->filename = strdup(fn);
00960             } else {
00961                fs->realfilename = NULL;
00962                fs->filename = strdup(filename);
00963             }
00964             fs->vfs = NULL;
00965             /* If truncated, we'll be at the beginning; if not truncated, then append */
00966             f->seek(fs, 0, SEEK_END);
00967          } else {
00968             ast_log(LOG_WARNING, "Unable to rewrite %s\n", fn);
00969             close(fd);
00970             if (orig_fn) {
00971                unlink(fn);
00972                unlink(orig_fn);
00973             }
00974          }
00975       } else if (errno != EEXIST) {
00976          ast_log(LOG_WARNING, "Unable to open file %s: %s\n", fn, strerror(errno));
00977          if (orig_fn)
00978             unlink(orig_fn);
00979       }
00980       /* if buf != NULL then fn is already free and pointing to it */
00981       if (!buf)
00982          free(fn);
00983    }
00984 
00985    ast_mutex_unlock(&formatlock);
00986 
00987    if (!format_found)
00988       ast_log(LOG_WARNING, "No such format '%s'\n", type);
00989 
00990    return fs;
00991 }

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

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

Referenced by ast_app_getvoice(), ast_play_and_prepend(), ast_play_and_record_full(), ast_read(), ast_write(), ast_writestream(), dictate_exec(), handle_recordfile(), mixmonitor_thread(), and recordthread().

00201 {
00202    struct ast_frame *trf;
00203    int res = -1;
00204    int alt=0;
00205    if (f->frametype == AST_FRAME_VIDEO) {
00206       if (fs->fmt->format < AST_FORMAT_MAX_AUDIO) {
00207          /* This is the audio portion.  Call the video one... */
00208          if (!fs->vfs && fs->filename) {
00209             /* XXX Support other video formats XXX */
00210             const char *type = "h263";
00211             fs->vfs = ast_writefile(fs->filename, type, NULL, fs->flags, 0, fs->mode);
00212             ast_log(LOG_DEBUG, "Opened video output file\n");
00213          }
00214          if (fs->vfs)
00215             return ast_writestream(fs->vfs, f);
00216          /* Ignore */
00217          return 0;            
00218       } else {
00219          /* Might / might not have mark set */
00220          alt = 1;
00221       }
00222    } else if (f->frametype != AST_FRAME_VOICE) {
00223       ast_log(LOG_WARNING, "Tried to write non-voice frame\n");
00224       return -1;
00225    }
00226    if (((fs->fmt->format | alt) & f->subclass) == f->subclass) {
00227       res =  fs->fmt->write(fs, f);
00228       if (res < 0) 
00229          ast_log(LOG_WARNING, "Natural write failed\n");
00230       if (res > 0)
00231          ast_log(LOG_WARNING, "Huh??\n");
00232       return res;
00233    } else {
00234       /* XXX If they try to send us a type of frame that isn't the normal frame, and isn't
00235              the one we've setup a translator for, we do the "wrong thing" XXX */
00236       if (fs->trans && (f->subclass != fs->lastwriteformat)) {
00237          ast_translator_free_path(fs->trans);
00238          fs->trans = NULL;
00239       }
00240       if (!fs->trans) 
00241          fs->trans = ast_translator_build_path(fs->fmt->format, f->subclass);
00242       if (!fs->trans)
00243          ast_log(LOG_WARNING, "Unable to translate to format %s, source format %s\n", fs->fmt->name, ast_getformatname(f->subclass));
00244       else {
00245          fs->lastwriteformat = f->subclass;
00246          res = 0;
00247          /* Get the translated frame but don't consume the original in case they're using it on another stream */
00248          trf = ast_translate(fs->trans, f, 0);
00249          if (trf) {
00250             res = fs->fmt->write(fs, trf);
00251             if (res) 
00252                ast_log(LOG_WARNING, "Translated frame write failed\n");
00253          } else
00254             res = 0;
00255       }
00256       return res;
00257    }
00258 }


Generated on Sat Sep 16 05:48:01 2006 for Asterisk - the Open Source PBX by  doxygen 1.4.7