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

Go to the source code of this file.
Data Structures | |
| struct | formats |
Defines | |
| #define | FORMAT "%-10s %-10s %-20s\n" |
| #define | FORMAT2 "%-10s %-10s %-20s\n" |
Enumerations | |
| enum | file_action { ACTION_EXISTS = 1, ACTION_DELETE, ACTION_RENAME, ACTION_OPEN, ACTION_COPY } |
| enum | fsread_res { FSREAD_FAILURE, FSREAD_SUCCESS_SCHED, FSREAD_SUCCESS_NOSCHED } |
| enum | wrap_fn { WRAP_OPEN, WRAP_REWRITE } |
Functions | |
| int | __ast_format_register (const struct ast_format *f, struct ast_module *mod) |
| Register a new file format capability. Adds a format to Asterisk's format abilities. | |
| static void | __fini_formats (void) |
| static void | __init_formats (void) |
| int | ast_applystream (struct ast_channel *chan, struct ast_filestream *s) |
| Applys a open stream to a channel. | |
| int | ast_closestream (struct ast_filestream *f) |
| Closes a stream. | |
| int | ast_file_init (void) |
| int | ast_filecopy (const char *filename, const char *filename2, const char *fmt) |
| Copies a file. | |
| int | ast_filedelete (const char *filename, const char *fmt) |
| Deletes a file. | |
| int | ast_fileexists (const char *filename, const char *fmt, const char *preflang) |
| Checks for the existence of a given file. | |
| static int | ast_filehelper (const char *filename, const void *arg2, const char *fmt, const enum file_action action) |
| perform various actions on a file. Second argument arg2 depends on the command: unused for EXISTS and DELETE destination file name (const char *) for COPY and RENAME struct ast_channel * for OPEN if fmt is NULL, OPEN will return the first matching entry, whereas other functions will run on all matching entries. | |
| int | ast_filerename (const char *filename, const char *filename2, const char *fmt) |
| Renames a file. | |
| char * | ast_format_str_reduce (char *fmts) |
| int | ast_format_unregister (const char *name) |
| Unregisters a file format. | |
| static int | ast_fsread_audio (const void *data) |
| static int | ast_fsread_video (const void *data) |
| struct ast_filestream * | ast_openstream (struct ast_channel *chan, const char *filename, const char *preflang) |
| Opens stream for use in seeking, playing. | |
| struct ast_filestream * | ast_openstream_full (struct ast_channel *chan, const char *filename, const char *preflang, int asis) |
| Opens stream for use in seeking, playing. | |
| struct ast_filestream * | ast_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_filestream * | ast_readfile (const char *filename, const char *type, const char *comment, int flags, int check, mode_t mode) |
| Starts reading from a file. | |
| struct ast_frame * | ast_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_filestream * | ast_writefile (const char *filename, const char *type, const char *comment, int flags, int check, mode_t mode) |
| Starts writing a file. | |
| int | ast_writestream (struct ast_filestream *fs, struct ast_frame *f) |
| Writes a frame to a stream. | |
| static char * | build_filename (const char *filename, const char *ext) |
| construct a filename. Absolute pathnames are preserved, relative names are prefixed by the sounds/ directory. The wav49 suffix is replaced by 'WAV'. Returns a malloc'ed string to be freed by the caller. | |
| static int | copy (const char *infile, const char *outfile) |
| static int | exts_compare (const char *exts, const char *type) |
| static int | fileexists_core (const char *filename, const char *fmt, const char *preflang, char *buf, int buflen) |
| helper routine to locate a file with a given format and language preference. Try preflang, preflang with stripped '_' suffix, or NULL. In the standard asterisk, language goes just before the last component. In an alternative configuration, the language should be a prefix to the actual filename. | |
| static int | fileexists_test (const char *filename, const char *fmt, const char *lang, char *buf, int buflen) |
| static void | filestream_destructor (void *arg) |
| static int | fn_wrapper (struct ast_filestream *s, const char *comment, enum wrap_fn mode) |
| static struct ast_filestream * | get_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_frame * | read_frame (struct ast_filestream *s, int *whennext) |
| static int | rewrite_wrapper (struct ast_filestream *s, const char *comment) |
| static int | waitstream_core (struct ast_channel *c, const char *breakon, const char *forward, const char *reverse, int skip_ms, int audiofd, int cmdfd, const char *context) |
| the core of all waitstream() functions | |
Variables | |
| int | ast_language_is_prefix = 1 |
| struct ast_cli_entry | cli_file [] |
Definition in file file.c.
| #define FORMAT "%-10s %-10s %-20s\n" |
| #define FORMAT2 "%-10s %-10s %-20s\n" |
| enum file_action |
Definition at line 391 of file file.c.
00391 { 00392 ACTION_EXISTS = 1, /* return matching format if file exists, 0 otherwise */ 00393 ACTION_DELETE, /* delete file, return 0 on success, -1 on error */ 00394 ACTION_RENAME, /* rename file. return 0 on success, -1 on error */ 00395 ACTION_OPEN, 00396 ACTION_COPY /* copy file. return 0 on success, -1 on error */ 00397 };
| enum fsread_res |
Definition at line 730 of file file.c.
00730 { 00731 FSREAD_FAILURE, 00732 FSREAD_SUCCESS_SCHED, 00733 FSREAD_SUCCESS_NOSCHED, 00734 };
| enum wrap_fn |
| 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.
| 0 | on success | |
| -1 | on failure |
Definition at line 61 of file file.c.
References ast_calloc, ast_log(), AST_RWLIST_INSERT_HEAD, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_verb, ast_format::buf_size, ast_format::exts, ast_format::list, LOG_WARNING, ast_format::module, and ast_format::name.
00062 { 00063 struct ast_format *tmp; 00064 00065 AST_RWLIST_WRLOCK(&formats); 00066 AST_RWLIST_TRAVERSE(&formats, tmp, list) { 00067 if (!strcasecmp(f->name, tmp->name)) { 00068 AST_RWLIST_UNLOCK(&formats); 00069 ast_log(LOG_WARNING, "Tried to register '%s' format, already registered\n", f->name); 00070 return -1; 00071 } 00072 } 00073 if (!(tmp = ast_calloc(1, sizeof(*tmp)))) { 00074 AST_RWLIST_UNLOCK(&formats); 00075 return -1; 00076 } 00077 *tmp = *f; 00078 tmp->module = mod; 00079 if (tmp->buf_size) { 00080 /* 00081 * Align buf_size properly, rounding up to the machine-specific 00082 * alignment for pointers. 00083 */ 00084 struct _test_align { void *a, *b; } p; 00085 int align = (char *)&p.b - (char *)&p.a; 00086 tmp->buf_size = ((f->buf_size + align - 1) / align) * align; 00087 } 00088 00089 memset(&tmp->list, 0, sizeof(tmp->list)); 00090 00091 AST_RWLIST_INSERT_HEAD(&formats, tmp, list); 00092 AST_RWLIST_UNLOCK(&formats); 00093 ast_verb(2, "Registered file format %s, extension(s) %s\n", f->name, f->exts); 00094 00095 return 0; 00096 }
| int ast_applystream | ( | struct ast_channel * | chan, | |
| struct ast_filestream * | s | |||
| ) |
Applys a open stream to a channel.
| chan | channel to work | |
| s | ast_filestream to apply |
| 0 | on success. | |
| -1 | on failure. |
Definition at line 847 of file file.c.
References ast_filestream::owner.
Referenced by ast_streamfile(), handle_getoption(), handle_recordfile(), handle_streamfile(), and speech_streamfile().
00848 { 00849 s->owner = chan; 00850 return 0; 00851 }
| int ast_closestream | ( | struct ast_filestream * | f | ) |
Closes a stream.
| f | filestream to close Close a playback or recording stream |
| 0 | on success. | |
| -1 | on failure. |
Definition at line 890 of file file.c.
References ao2_ref, AST_FORMAT_AUDIO_MASK, AST_SCHED_DEL, ast_settimeout(), ast_filestream::fmt, ast_format::format, ast_filestream::owner, ast_channel::sched, ast_channel::stream, ast_channel::streamid, ast_channel::vstream, and ast_channel::vstreamid.
Referenced by __ast_play_and_record(), ast_filehelper(), ast_hangup(), ast_moh_files_next(), ast_monitor_start(), ast_monitor_stop(), ast_readfile(), ast_stopstream(), ast_writefile(), dictate_exec(), filestream_destructor(), gen_closestream(), handle_cli_file_convert(), handle_recordfile(), local_ast_moh_stop(), mixmonitor_ds_close_fs(), moh_files_release(), record_exec(), recordthread(), and rpt().
00891 { 00892 /* This used to destroy the filestream, but it now just decrements a refcount. 00893 * We need to force the stream to quit queuing frames now, because we might 00894 * change the writeformat, which could result in a subsequent write error, if 00895 * the format is different. */ 00896 00897 /* Stop a running stream if there is one */ 00898 if (f->owner) { 00899 if (f->fmt->format < AST_FORMAT_AUDIO_MASK) { 00900 f->owner->stream = NULL; 00901 AST_SCHED_DEL(f->owner->sched, f->owner->streamid); 00902 ast_settimeout(f->owner, 0, NULL, NULL); 00903 } else { 00904 f->owner->vstream = NULL; 00905 AST_SCHED_DEL(f->owner->sched, f->owner->vstreamid); 00906 } 00907 } 00908 00909 ao2_ref(f, -1); 00910 return 0; 00911 }
| int ast_file_init | ( | void | ) |
Provided by file.c
Definition at line 1476 of file file.c.
References ARRAY_LEN, and ast_cli_register_multiple().
Referenced by main().
01477 { 01478 ast_cli_register_multiple(cli_file, ARRAY_LEN(cli_file)); 01479 return 0; 01480 }
| int ast_filecopy | ( | const char * | oldname, | |
| const char * | newname, | |||
| const char * | fmt | |||
| ) |
Copies a file.
| 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.
| 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.
| 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. |
Definition at line 917 of file file.c.
References buf, and fileexists_core().
Referenced by announce_thread(), app_exec(), ast_moh_files_next(), ast_monitor_start(), ast_monitor_stop(), common_exec(), dial_exec_full(), eivr_comm(), forward_message(), function_playback(), invent_message(), leave_voicemail(), minivm_delete_exec(), play_file(), play_message(), play_message_callerid(), record_exec(), retrydial_exec(), rpt_tele_thread(), say_character_str_full(), say_digit_str_full(), say_phonetic_str_full(), sayname(), saynode(), setup_privacy_args(), vm_intro(), vm_newuser(), vm_options(), and vm_tempgreeting().
00918 { 00919 char *buf; 00920 int buflen; 00921 00922 if (preflang == NULL) 00923 preflang = ""; 00924 buflen = strlen(preflang) + strlen(filename) + 4; /* room for everything */ 00925 buf = alloca(buflen); 00926 if (buf == NULL) 00927 return 0; 00928 return fileexists_core(filename, fmt, preflang, buf, buflen); 00929 }
| static int ast_filehelper | ( | const char * | filename, | |
| const void * | arg2, | |||
| const char * | fmt, | |||
| const enum file_action | action | |||
| ) | [static] |
perform various actions on a file. Second argument arg2 depends on the command: unused for EXISTS and DELETE destination file name (const char *) for COPY and RENAME struct ast_channel * for OPEN if fmt is NULL, OPEN will return the first matching entry, whereas other functions will run on all matching entries.
Definition at line 408 of file file.c.
References ACTION_COPY, ACTION_DELETE, ACTION_EXISTS, ACTION_OPEN, ACTION_RENAME, ast_closestream(), AST_FORMAT_AUDIO_MASK, AST_FORMAT_VIDEO_MASK, ast_free, ast_log(), AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_strdupa, build_filename(), chan, copy(), errno, ext, ast_format::exts, exts_compare(), f, ast_filestream::filename, ast_filestream::fmt, ast_format::format, get_filestream(), ast_filestream::lasttimeout, ast_format::list, LOG_WARNING, open_wrapper(), s, ast_channel::stream, strsep(), ast_filestream::trans, ast_channel::vstream, and ast_channel::writeformat.
Referenced by ast_filecopy(), ast_filedelete(), ast_filerename(), ast_openstream_full(), ast_openvstream(), and fileexists_test().
00409 { 00410 struct ast_format *f; 00411 int res = (action == ACTION_EXISTS) ? 0 : -1; 00412 00413 AST_RWLIST_RDLOCK(&formats); 00414 /* Check for a specific format */ 00415 AST_RWLIST_TRAVERSE(&formats, f, list) { 00416 char *stringp, *ext = NULL; 00417 00418 if (fmt && !exts_compare(f->exts, fmt)) 00419 continue; 00420 00421 /* Look for a file matching the supported extensions. 00422 * The file must exist, and for OPEN, must match 00423 * one of the formats supported by the channel. 00424 */ 00425 stringp = ast_strdupa(f->exts); /* this is in the stack so does not need to be freed */ 00426 while ( (ext = strsep(&stringp, "|")) ) { 00427 struct stat st; 00428 char *fn = build_filename(filename, ext); 00429 00430 if (fn == NULL) 00431 continue; 00432 00433 if ( stat(fn, &st) ) { /* file not existent */ 00434 ast_free(fn); 00435 continue; 00436 } 00437 /* for 'OPEN' we need to be sure that the format matches 00438 * what the channel can process 00439 */ 00440 if (action == ACTION_OPEN) { 00441 struct ast_channel *chan = (struct ast_channel *)arg2; 00442 FILE *bfile; 00443 struct ast_filestream *s; 00444 00445 if ( !(chan->writeformat & f->format) && 00446 !((f->format & AST_FORMAT_AUDIO_MASK && fmt) || 00447 (f->format & AST_FORMAT_VIDEO_MASK && fmt))) { 00448 ast_free(fn); 00449 continue; /* not a supported format */ 00450 } 00451 if ( (bfile = fopen(fn, "r")) == NULL) { 00452 ast_free(fn); 00453 continue; /* cannot open file */ 00454 } 00455 s = get_filestream(f, bfile); 00456 if (!s) { 00457 fclose(bfile); 00458 ast_free(fn); /* cannot allocate descriptor */ 00459 continue; 00460 } 00461 if (open_wrapper(s)) { 00462 ast_free(fn); 00463 ast_closestream(s); 00464 continue; /* cannot run open on file */ 00465 } 00466 if (st.st_size == 0) { 00467 ast_log(LOG_WARNING, "File %s detected to have zero size.\n", fn); 00468 } 00469 /* ok this is good for OPEN */ 00470 res = 1; /* found */ 00471 s->lasttimeout = -1; 00472 s->fmt = f; 00473 s->trans = NULL; 00474 s->filename = NULL; 00475 if (s->fmt->format & AST_FORMAT_AUDIO_MASK) { 00476 if (chan->stream) 00477 ast_closestream(chan->stream); 00478 chan->stream = s; 00479 } else { 00480 if (chan->vstream) 00481 ast_closestream(chan->vstream); 00482 chan->vstream = s; 00483 } 00484 ast_free(fn); 00485 break; 00486 } 00487 switch (action) { 00488 case ACTION_OPEN: 00489 break; /* will never get here */ 00490 00491 case ACTION_EXISTS: /* return the matching format */ 00492 res |= f->format; 00493 break; 00494 00495 case ACTION_DELETE: 00496 if ( (res = unlink(fn)) ) 00497 ast_log(LOG_WARNING, "unlink(%s) failed: %s\n", fn, strerror(errno)); 00498 break; 00499 00500 case ACTION_RENAME: 00501 case ACTION_COPY: { 00502 char *nfn = build_filename((const char *)arg2, ext); 00503 if (!nfn) 00504 ast_log(LOG_WARNING, "Out of memory\n"); 00505 else { 00506 res = action == ACTION_COPY ? copy(fn, nfn) : rename(fn, nfn); 00507 if (res) 00508 ast_log(LOG_WARNING, "%s(%s,%s) failed: %s\n", 00509 action == ACTION_COPY ? "copy" : "rename", 00510 fn, nfn, strerror(errno)); 00511 ast_free(nfn); 00512 } 00513 } 00514 break; 00515 00516 default: 00517 ast_log(LOG_WARNING, "Unknown helper %d\n", action); 00518 } 00519 ast_free(fn); 00520 } 00521 } 00522 AST_RWLIST_UNLOCK(&formats); 00523 return res; 00524 }
| int ast_filerename | ( | const char * | oldname, | |
| const char * | newname, | |||
| const char * | fmt | |||
| ) |
Renames a file.
| 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 |
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.
| fmts | a format string, this string will be modified |
| NULL | error |
Definition at line 1360 of file file.c.
References ast_log(), AST_MAX_FORMATS, AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_strdupa, ast_format::exts, exts_compare(), f, first, len(), ast_format::list, LOG_WARNING, strsep(), and type.
Referenced by load_config().
01361 { 01362 struct ast_format *f; 01363 struct ast_format *fmts_ptr[AST_MAX_FORMATS]; 01364 char *fmts_str[AST_MAX_FORMATS]; 01365 char *stringp, *type; 01366 char *orig = fmts; 01367 int i, j, x, first, found = 0; 01368 int len = strlen(fmts) + 1; 01369 int res; 01370 01371 if (AST_RWLIST_RDLOCK(&formats)) { 01372 ast_log(LOG_WARNING, "Unable to lock format list\n"); 01373 return NULL; 01374 } 01375 01376 stringp = ast_strdupa(fmts); 01377 01378 for (x = 0; (type = strsep(&stringp, "|")) && x < AST_MAX_FORMATS; x++) { 01379 AST_RWLIST_TRAVERSE(&formats, f, list) { 01380 if (exts_compare(f->exts, type)) { 01381 found = 1; 01382 break; 01383 } 01384 } 01385 01386 fmts_str[x] = type; 01387 if (found) { 01388 fmts_ptr[x] = f; 01389 } else { 01390 fmts_ptr[x] = NULL; 01391 } 01392 } 01393 AST_RWLIST_UNLOCK(&formats); 01394 01395 first = 1; 01396 for (i = 0; i < x; i++) { 01397 /* ignore invalid entries */ 01398 if (!fmts_ptr[i]) { 01399 ast_log(LOG_WARNING, "ignoring unknown format '%s'\n", fmts_str[i]); 01400 continue; 01401 } 01402 01403 /* special handling for the first entry */ 01404 if (first) { 01405 res = snprintf(fmts, len, "%s", fmts_str[i]); 01406 fmts += res; 01407 len -= res; 01408 first = 0; 01409 continue; 01410 } 01411 01412 found = 0; 01413 for (j = 0; j < i; j++) { 01414 /* this is a duplicate */ 01415 if (fmts_ptr[j] == fmts_ptr[i]) { 01416 found = 1; 01417 break; 01418 } 01419 } 01420 01421 if (!found) { 01422 res = snprintf(fmts, len, "|%s", fmts_str[i]); 01423 fmts += res; 01424 len -= res; 01425 } 01426 } 01427 01428 if (first) { 01429 ast_log(LOG_WARNING, "no known formats found in format list (%s)\n", orig); 01430 return NULL; 01431 } 01432 01433 return orig; 01434 }
| int ast_format_unregister | ( | const char * | name | ) |
Unregisters a file format.
| name | the name of the format you wish to unregister Unregisters a format based on the name of the format. |
| 0 | on success | |
| -1 | on failure to unregister |
Definition at line 98 of file file.c.
References ast_free, ast_log(), AST_RWLIST_REMOVE_CURRENT, AST_RWLIST_TRAVERSE_SAFE_BEGIN, AST_RWLIST_TRAVERSE_SAFE_END, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_verb, ast_format::list, LOG_WARNING, and ast_format::name.
Referenced by unload_module().
00099 { 00100 struct ast_format *tmp; 00101 int res = -1; 00102 00103 AST_RWLIST_WRLOCK(&formats); 00104 AST_RWLIST_TRAVERSE_SAFE_BEGIN(&formats, tmp, list) { 00105 if (!strcasecmp(name, tmp->name)) { 00106 AST_RWLIST_REMOVE_CURRENT(list); 00107 ast_free(tmp); 00108 res = 0; 00109 } 00110 } 00111 AST_RWLIST_TRAVERSE_SAFE_END; 00112 AST_RWLIST_UNLOCK(&formats); 00113 00114 if (!res) 00115 ast_verb(2, "Unregistered format %s\n", name); 00116 else 00117 ast_log(LOG_WARNING, "Tried to unregister format %s, already unregistered\n", name); 00118 00119 return res; 00120 }
| static int ast_fsread_audio | ( | const void * | data | ) | [static] |
Definition at line 787 of file file.c.
References ast_readaudio_callback(), and FSREAD_SUCCESS_SCHED.
Referenced by ast_readaudio_callback().
00788 { 00789 struct ast_filestream *fs = (struct ast_filestream *)data; 00790 enum fsread_res res; 00791 00792 res = ast_readaudio_callback(fs); 00793 00794 if (res == FSREAD_SUCCESS_SCHED) 00795 return 1; 00796 00797 return 0; 00798 }
| static int ast_fsread_video | ( | const void * | data | ) | [static] |
Definition at line 834 of file file.c.
References ast_readvideo_callback(), and FSREAD_SUCCESS_SCHED.
Referenced by ast_readvideo_callback().
00835 { 00836 struct ast_filestream *fs = (struct ast_filestream *)data; 00837 enum fsread_res res; 00838 00839 res = ast_readvideo_callback(fs); 00840 00841 if (res == FSREAD_SUCCESS_SCHED) 00842 return 1; 00843 00844 return 0; 00845 }
| struct ast_filestream* ast_openstream | ( | struct ast_channel * | chan, | |
| const char * | filename, | |||
| const char * | preflang | |||
| ) | [read] |
Opens stream for use in seeking, playing.
| chan | channel to work with | |
| filename | to use | |
| preflang | prefered language to use |
| a | ast_filestream pointer if it opens the file. | |
| NULL | on error. |
Definition at line 619 of file file.c.
References ast_openstream_full().
Referenced by ast_streamfile(), dictate_exec(), handle_getoption(), handle_streamfile(), and speech_streamfile().
00620 { 00621 return ast_openstream_full(chan, filename, preflang, 0); 00622 }
| struct ast_filestream* ast_openstream_full | ( | struct ast_channel * | chan, | |
| const char * | filename, | |||
| const char * | preflang, | |||
| int | asis | |||
| ) | [read] |
Opens stream for use in seeking, playing.
| chan | channel to work with | |
| filename | to use | |
| preflang | prefered language to use | |
| asis | if set, don't clear generators |
| a | ast_filestream pointer if it opens the file. | |
| NULL | on error. |
Definition at line 624 of file file.c.
References ACTION_OPEN, ast_deactivate_generator(), ast_filehelper(), AST_FORMAT_AUDIO_MASK, ast_log(), ast_set_write_format(), ast_stopstream(), buf, fileexists_core(), ast_channel::generator, LOG_WARNING, ast_channel::oldwriteformat, ast_channel::stream, and ast_channel::writeformat.
Referenced by ast_moh_files_next(), ast_openstream(), and gen_nextfile().
00625 { 00626 /* 00627 * Use fileexists_core() to find a file in a compatible 00628 * language and format, set up a suitable translator, 00629 * and open the stream. 00630 */ 00631 int fmts, res, buflen; 00632 char *buf; 00633 00634 if (!asis) { 00635 /* do this first, otherwise we detect the wrong writeformat */ 00636 ast_stopstream(chan); 00637 if (chan->generator) 00638 ast_deactivate_generator(chan); 00639 } 00640 if (preflang == NULL) 00641 preflang = ""; 00642 buflen = strlen(preflang) + strlen(filename) + 4; 00643 buf = alloca(buflen); 00644 if (buf == NULL) 00645 return NULL; 00646 fmts = fileexists_core(filename, NULL, preflang, buf, buflen); 00647 if (fmts > 0) 00648 fmts &= AST_FORMAT_AUDIO_MASK; 00649 if (fmts < 1) { 00650 ast_log(LOG_WARNING, "File %s does not exist in any format\n", filename); 00651 return NULL; 00652 } 00653 chan->oldwriteformat = chan->writeformat; 00654 /* Set the channel to a format we can work with */ 00655 res = ast_set_write_format(chan, fmts); 00656 if (res == -1) { /* No format available that works with this channel */ 00657 return NULL; 00658 } 00659 res = ast_filehelper(buf, chan, NULL, ACTION_OPEN); 00660 if (res >= 0) 00661 return chan->stream; 00662 return NULL; 00663 }
| struct ast_filestream* ast_openvstream | ( | struct ast_channel * | chan, | |
| const char * | filename, | |||
| const char * | preflang | |||
| ) | [read] |
Opens stream for use in seeking, playing.
| chan | channel to work with | |
| filename | to use | |
| preflang | prefered language to use |
| a | ast_filestream pointer if it opens the file. | |
| NULL | on error. |
Definition at line 665 of file file.c.
References ACTION_OPEN, ast_filehelper(), AST_FORMAT_AUDIO_MASK, AST_FORMAT_VIDEO_MASK, ast_getformatname(), ast_log(), buf, fileexists_core(), ast_filestream::fmt, format, LOG_WARNING, ast_channel::nativeformats, and ast_channel::vstream.
Referenced by ast_streamfile(), handle_getoption(), and handle_streamfile().
00666 { 00667 /* As above, but for video. But here we don't have translators 00668 * so we must enforce a format. 00669 */ 00670 unsigned int format; 00671 char *buf; 00672 int buflen; 00673 00674 if (preflang == NULL) 00675 preflang = ""; 00676 buflen = strlen(preflang) + strlen(filename) + 4; 00677 buf = alloca(buflen); 00678 if (buf == NULL) 00679 return NULL; 00680 00681 for (format = AST_FORMAT_AUDIO_MASK + 1; format <= AST_FORMAT_VIDEO_MASK; format = format << 1) { 00682 int fd; 00683 const char *fmt; 00684 00685 if (!(chan->nativeformats & format)) 00686 continue; 00687 fmt = ast_getformatname(format); 00688 if ( fileexists_core(filename, fmt, preflang, buf, buflen) < 1) /* no valid format */ 00689 continue; 00690 fd = ast_filehelper(buf, chan, fmt, ACTION_OPEN); 00691 if (fd >= 0) 00692 return chan->vstream; 00693 ast_log(LOG_WARNING, "File %s has video but couldn't be opened\n", filename); 00694 } 00695 return NULL; 00696 }
| int ast_playstream | ( | struct ast_filestream * | s | ) |
Play a open stream on a channel.
| s | filestream to play |
| 0 | on success. | |
| -1 | on failure. |
Definition at line 853 of file file.c.
References AST_FORMAT_AUDIO_MASK, ast_readaudio_callback(), ast_readvideo_callback(), ast_filestream::fmt, ast_format::format, and FSREAD_FAILURE.
Referenced by ast_streamfile(), handle_getoption(), handle_streamfile(), and speech_streamfile().
00854 { 00855 enum fsread_res res; 00856 00857 if (s->fmt->format & AST_FORMAT_AUDIO_MASK) 00858 res = ast_readaudio_callback(s); 00859 else 00860 res = ast_readvideo_callback(s); 00861 00862 return (res == FSREAD_FAILURE) ? -1 : 0; 00863 }
| static enum fsread_res ast_readaudio_callback | ( | struct ast_filestream * | s | ) | [static] |
Definition at line 738 of file file.c.
References ast_format_rate(), ast_frfree, ast_fsread_audio(), ast_log(), ast_sched_add(), ast_settimeout(), ast_write(), ast_filestream::fmt, ast_format::format, FSREAD_FAILURE, FSREAD_SUCCESS_NOSCHED, FSREAD_SUCCESS_SCHED, ast_filestream::lasttimeout, LOG_WARNING, ast_channel::name, ast_filestream::orig_chan_name, ast_filestream::owner, read_frame(), ast_channel::sched, ast_channel::streamid, and ast_channel::timingfd.
Referenced by ast_fsread_audio(), and ast_playstream().
00739 { 00740 int whennext = 0; 00741 00742 while (!whennext) { 00743 struct ast_frame *fr; 00744 00745 if (s->orig_chan_name && strcasecmp(s->owner->name, s->orig_chan_name)) { 00746 goto return_failure; 00747 } 00748 00749 fr = read_frame(s, &whennext); 00750 00751 if (!fr /* stream complete */ || ast_write(s->owner, fr) /* error writing */) { 00752 if (fr) { 00753 ast_log(LOG_WARNING, "Failed to write frame\n"); 00754 ast_frfree(fr); 00755 } 00756 goto return_failure; 00757 } 00758 00759 if (fr) { 00760 ast_frfree(fr); 00761 } 00762 } 00763 00764 if (whennext != s->lasttimeout) { 00765 if (s->owner->timingfd > -1) { 00766 float samp_rate = (float) ast_format_rate(s->fmt->format); 00767 unsigned int rate; 00768 00769 rate = (unsigned int) roundf(samp_rate / ((float) whennext)); 00770 00771 ast_settimeout(s->owner, rate, ast_fsread_audio, s); 00772 } else { 00773 s->owner->streamid = ast_sched_add(s->owner->sched, 00774 whennext / (ast_format_rate(s->fmt->format) / 1000), ast_fsread_audio, s); 00775 } 00776 s->lasttimeout = whennext; 00777 return FSREAD_SUCCESS_NOSCHED; 00778 } 00779 return FSREAD_SUCCESS_SCHED; 00780 00781 return_failure: 00782 s->owner->streamid = -1; 00783 ast_settimeout(s->owner, 0, NULL, NULL); 00784 return FSREAD_FAILURE; 00785 }
| struct ast_filestream* ast_readfile | ( | const char * | filename, | |
| const char * | type, | |||
| const char * | comment, | |||
| int | flags, | |||
| int | check, | |||
| mode_t | mode | |||
| ) | [read] |
Starts reading from a file.
| 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. |
| a | struct ast_filestream on success. | |
| NULL | on failure. |
Definition at line 990 of file file.c.
References ast_closestream(), ast_free, ast_log(), AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_strdup, build_filename(), errno, ast_format::exts, exts_compare(), f, ast_filestream::filename, ast_filestream::flags, ast_filestream::fmt, get_filestream(), LOG_WARNING, ast_filestream::mode, open_wrapper(), ast_filestream::trans, and ast_filestream::vfs.
Referenced by __ast_play_and_record(), and handle_cli_file_convert().
00991 { 00992 FILE *bfile; 00993 struct ast_format *f; 00994 struct ast_filestream *fs = NULL; 00995 char *fn; 00996 int format_found = 0; 00997 00998 AST_RWLIST_RDLOCK(&formats); 00999 01000 AST_RWLIST_TRAVERSE(&formats, f, list) { 01001 fs = NULL; 01002 if (!exts_compare(f->exts, type)) 01003 continue; 01004 else 01005 format_found = 1; 01006 01007 fn = build_filename(filename, type); 01008 errno = 0; 01009 bfile = fopen(fn, "r"); 01010 01011 if (!bfile || (fs = get_filestream(f, bfile)) == NULL || open_wrapper(fs) ) { 01012 ast_log(LOG_WARNING, "Unable to open %s\n", fn); 01013 if (fs) { 01014 ast_closestream(fs); 01015 } 01016 fs = NULL; 01017 bfile = NULL; 01018 ast_free(fn); 01019 break; 01020 } 01021 /* found it */ 01022 fs->trans = NULL; 01023 fs->fmt = f; 01024 fs->flags = flags; 01025 fs->mode = mode; 01026 fs->filename = ast_strdup(filename); 01027 fs->vfs = NULL; 01028 break; 01029 } 01030 01031 AST_RWLIST_UNLOCK(&formats); 01032 if (!format_found) 01033 ast_log(LOG_WARNING, "No such format '%s'\n", type); 01034 01035 return fs; 01036 }
| struct ast_frame* ast_readframe | ( | struct ast_filestream * | s | ) | [read] |
Read a frame from a filestream.
| s | ast_filestream to act on |
| NULL | if read failed. |
Definition at line 723 of file file.c.
References read_frame().
Referenced by __ast_play_and_record(), dictate_exec(), gen_readframe(), handle_cli_file_convert(), and moh_files_readframe().
00724 { 00725 int whennext = 0; 00726 00727 return read_frame(s, &whennext); 00728 }
| static enum fsread_res ast_readvideo_callback | ( | struct ast_filestream * | s | ) | [static] |
Definition at line 802 of file file.c.
References ast_format_rate(), ast_frfree, ast_fsread_video(), ast_log(), ast_sched_add(), ast_write(), ast_filestream::fmt, ast_format::format, FSREAD_FAILURE, FSREAD_SUCCESS_NOSCHED, FSREAD_SUCCESS_SCHED, ast_filestream::lasttimeout, LOG_WARNING, ast_filestream::owner, read_frame(), ast_channel::sched, and ast_channel::vstreamid.
Referenced by ast_fsread_video(), and ast_playstream().
00803 { 00804 int whennext = 0; 00805 00806 while (!whennext) { 00807 struct ast_frame *fr = read_frame(s, &whennext); 00808 00809 if (!fr /* stream complete */ || ast_write(s->owner, fr) /* error writing */) { 00810 if (fr) { 00811 ast_log(LOG_WARNING, "Failed to write frame\n"); 00812 ast_frfree(fr); 00813 } 00814 s->owner->vstreamid = -1; 00815 return FSREAD_FAILURE; 00816 } 00817 00818 if (fr) { 00819 ast_frfree(fr); 00820 } 00821 } 00822 00823 if (whennext != s->lasttimeout) { 00824 s->owner->vstreamid = ast_sched_add(s->owner->sched, 00825 whennext / (ast_format_rate(s->fmt->format) / 1000), 00826 ast_fsread_video, s); 00827 s->lasttimeout = whennext; 00828 return FSREAD_SUCCESS_NOSCHED; 00829 } 00830 00831 return FSREAD_SUCCESS_SCHED; 00832 }
| int ast_seekstream | ( | struct ast_filestream * | fs, | |
| off_t | sample_offset, | |||
| int | whence | |||
| ) |
Seeks into stream.
| fs | ast_filestream to perform seek on | |
| sample_offset | numbers of samples to seek | |
| whence | SEEK_SET, SEEK_CUR, SEEK_END |
| 0 | on success. | |
| -1 | on failure. |
Definition at line 865 of file file.c.
References ast_filestream::fmt, and ast_format::seek.
Referenced by __ast_read(), ast_control_streamfile(), ast_moh_files_next(), ast_stream_fastforward(), ast_stream_rewind(), ast_streamfile(), ast_write(), dictate_exec(), handle_getoption(), handle_recordfile(), handle_streamfile(), and speech_streamfile().
| int ast_stopstream | ( | struct ast_channel * | c | ) |
Stops a stream.
| c | The channel you wish to stop playback on |
| 0 | always |
Definition at line 122 of file file.c.
References ast_channel_lock, ast_channel_unlock, ast_closestream(), ast_log(), ast_set_write_format(), LOG_WARNING, ast_channel::oldwriteformat, ast_channel::stream, and ast_channel::vstream.
Referenced by _ast_adsi_transmit_message_full(), ast_control_streamfile(), ast_openstream_full(), ast_play_and_wait(), ast_readstring_full(), ast_say_enumeration_full_da(), ast_say_enumeration_full_de(), ast_say_enumeration_full_en(), ast_say_enumeration_full_he(), ast_say_number_full_cs(), ast_say_number_full_da(), ast_say_number_full_de(), ast_say_number_full_en(), ast_say_number_full_en_GB(), ast_say_number_full_es(), ast_say_number_full_fr(), ast_say_number_full_gr(), ast_say_number_full_he(), ast_say_number_full_hu(), ast_say_number_full_it(), ast_say_number_full_ka(), ast_say_number_full_nl(), ast_say_number_full_no(), ast_say_number_full_pt(), ast_say_number_full_ru(), ast_say_number_full_se(), ast_say_number_full_th(), ast_say_number_full_zh(), background_detect_exec(), builtin_blindtransfer(), conf_exec(), conf_run(), dial_exec_full(), directory_exec(), grab_transfer(), handle_getoption(), handle_speechrecognize(), handle_streamfile(), ices_exec(), ivr_dispatch(), leave_voicemail(), menu_callback(), minivm_greet_exec(), mp3_exec(), NBScat_exec(), parkandannounce_exec(), pbx_builtin_background(), pl_odtworz_plik(), play_file(), play_mailbox_owner(), playback_exec(), queue_exec(), read_exec(), readexten_exec(), record_exec(), recordthread(), rpt_tele_thread(), s_streamwait3(), say_character_str_full(), say_digit_str_full(), say_phonetic_str_full(), saycharstr(), sayfile(), saynum(), select_item_seq(), send_morse(), send_tone_telemetry(), send_waveform_to_channel(), speech_background(), vm_authenticate(), vm_execmain(), wait_for_winner(), waitstream_core(), and zapateller_exec().
00123 { 00124 ast_channel_lock(tmp); 00125 00126 /* Stop a running stream if there is one */ 00127 if (tmp->stream) { 00128 ast_closestream(tmp->stream); 00129 tmp->stream = NULL; 00130 if (tmp->oldwriteformat && ast_set_write_format(tmp, tmp->oldwriteformat)) 00131 ast_log(LOG_WARNING, "Unable to restore format back to %d\n", tmp->oldwriteformat); 00132 } 00133 /* Stop the video stream too */ 00134 if (tmp->vstream != NULL) { 00135 ast_closestream(tmp->vstream); 00136 tmp->vstream = NULL; 00137 } 00138 00139 ast_channel_unlock(tmp); 00140 00141 return 0; 00142 }
| int ast_stream_and_wait | ( | struct ast_channel * | chan, | |
| const char * | file, | |||
| const char * | digits | |||
| ) |
stream file until digit If the file name is non-empty, try to play it.
| -1 | if error. | |
| digit | if interrupted by a digit. |
Definition at line 1348 of file file.c.
References ast_streamfile(), ast_strlen_zero(), ast_waitstream(), and ast_channel::language.
Referenced by __ast_play_and_record(), announce_user_count(), app_exec(), ast_pickup_call(), ast_record_review(), bridge_playfile(), builtin_atxfer(), builtin_automixmonitor(), builtin_blindtransfer(), confbridge_exec(), directory_exec(), feature_attended_transfer(), feature_blind_transfer(), forward_message(), grab_transfer(), invent_message(), ivr_dispatch(), join_conference_bridge(), leave_voicemail(), masq_park_call(), menu_callback(), park_exec_full(), play_mailbox_owner(), play_message_callerid(), play_message_in_bridged_call(), play_prompt_to_channel(), play_record_review(), play_sound_file(), sayname(), select_item_seq(), and wait_file2().
01349 { 01350 int res = 0; 01351 if (!ast_strlen_zero(file)) { 01352 res = ast_streamfile(chan, file, chan->language); 01353 if (!res) { 01354 res = ast_waitstream(chan, digits); 01355 } 01356 } 01357 return res; 01358 }
| int ast_stream_fastforward | ( | struct ast_filestream * | fs, | |
| off_t | ms | |||
| ) |
Fast forward stream ms.
| fs | filestream to act on | |
| ms | milliseconds to move |
| 0 | on success. | |
| -1 | on failure. |
Definition at line 880 of file file.c.
References ast_seekstream(), and DEFAULT_SAMPLES_PER_MS.
Referenced by waitstream_core().
00881 { 00882 return ast_seekstream(fs, ms * DEFAULT_SAMPLES_PER_MS, SEEK_CUR); 00883 }
| int ast_stream_rewind | ( | struct ast_filestream * | fs, | |
| off_t | ms | |||
| ) |
Rewind stream ms.
| fs | filestream to act on | |
| ms | milliseconds to move |
| 0 | on success. | |
| -1 | on failure. |
Definition at line 885 of file file.c.
References ast_seekstream(), and DEFAULT_SAMPLES_PER_MS.
Referenced by __ast_play_and_record(), handle_recordfile(), record_exec(), and waitstream_core().
00886 { 00887 return ast_seekstream(fs, -ms * DEFAULT_SAMPLES_PER_MS, SEEK_CUR); 00888 }
| int ast_streamfile | ( | struct ast_channel * | c, | |
| const char * | filename, | |||
| const char * | preflang | |||
| ) |
Streams a file.
| 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. |
| 0 | on success. | |
| -1 | on failure. |
Definition at line 946 of file file.c.
References ast_applystream(), ast_debug, AST_FLAG_MASQ_NOSTREAM, ast_getformatname(), ast_getformatname_multiple(), ast_log(), ast_openstream(), ast_openvstream(), ast_playstream(), ast_seekstream(), ast_strdup, ast_test_flag, ast_verb, errno, ast_filestream::f, ast_filestream::fmt, ast_format::format, LOG_WARNING, ast_channel::name, ast_channel::nativeformats, ast_filestream::orig_chan_name, ast_filestream::vfs, and ast_channel::writeformat.
Referenced by action_bridge(), agent_call(), announce_thread(), app_exec(), ast_app_getdata(), ast_app_getdata_full(), ast_control_streamfile(), ast_play_and_wait(), ast_say_date_da(), ast_say_date_de(), ast_say_date_en(), ast_say_date_fr(), ast_say_date_gr(), ast_say_date_he(), ast_say_date_hu(), ast_say_date_ka(), ast_say_date_nl(), ast_say_date_th(), ast_say_date_with_format_gr(), ast_say_datetime_en(), ast_say_datetime_fr(), ast_say_datetime_from_now_en(), ast_say_datetime_from_now_fr(), ast_say_datetime_from_now_he(), ast_say_datetime_from_now_ka(), ast_say_datetime_gr(), ast_say_datetime_he(), ast_say_datetime_nl(), ast_say_datetime_pt(), ast_say_datetime_th(), ast_say_datetime_zh(), ast_say_enumeration_full_da(), ast_say_enumeration_full_de(), ast_say_enumeration_full_en(), ast_say_enumeration_full_he(), ast_say_number_full_cs(), ast_say_number_full_da(), ast_say_number_full_de(), ast_say_number_full_en(), ast_say_number_full_en_GB(), ast_say_number_full_es(), ast_say_number_full_fr(), ast_say_number_full_gr(), ast_say_number_full_he(), ast_say_number_full_hu(), ast_say_number_full_it(), ast_say_number_full_ka(), ast_say_number_full_nl(), ast_say_number_full_no(), ast_say_number_full_pt(), ast_say_number_full_ru(), ast_say_number_full_se(), ast_say_number_full_th(), ast_say_number_full_zh(), ast_say_time_de(), ast_say_time_en(), ast_say_time_fr(), ast_say_time_gr(), ast_say_time_hu(), ast_say_time_ka(), ast_say_time_nl(), ast_say_time_zh(), ast_stream_and_wait(), auth_exec(), background_detect_exec(), bridge_exec(), check_availability(), check_beep(), common_exec(), conf_exec(), conf_run(), dial_exec_full(), do_directory(), find_conf_realtime(), forward_message(), gr_say_number_female(), handle_recordfile(), invent_message(), leave_voicemail(), local_attended_transfer(), login_exec(), menu_callback(), minivm_greet_exec(), page_exec(), park_exec_full(), parkandannounce_exec(), pbx_builtin_background(), pl_odtworz_plik(), play_and_wait(), play_file(), play_record_review(), playback_exec(), privacy_exec(), readexten_exec(), record_exec(), retrydial_exec(), rpt_tele_thread(), s_streamwait3(), say_character_str_full(), say_digit_str_full(), say_phonetic_str_full(), sayfile(), select_item_menu(), setup_privacy_args(), ss_thread(), vm_authenticate(), wait_file(), and wait_for_winner().
00947 { 00948 struct ast_filestream *fs; 00949 struct ast_filestream *vfs=NULL; 00950 char fmt[256]; 00951 int seekattempt; 00952 int res; 00953 00954 fs = ast_openstream(chan, filename, preflang); 00955 if (!fs) { 00956 ast_log(LOG_WARNING, "Unable to open %s (format %s): %s\n", filename, ast_getformatname_multiple(fmt, sizeof(fmt), chan->nativeformats), strerror(errno)); 00957 return -1; 00958 } 00959 00960 /* check to see if there is any data present (not a zero length file), 00961 * done this way because there is no where for ast_openstream_full to 00962 * return the file had no data. */ 00963 seekattempt = fseek(fs->f, -1, SEEK_END); 00964 if (seekattempt && errno == EINVAL) { 00965 /* Zero-length file, as opposed to a pipe */ 00966 return 0; 00967 } else { 00968 ast_seekstream(fs, 0, SEEK_SET); 00969 } 00970 00971 vfs = ast_openvstream(chan, filename, preflang); 00972 if (vfs) { 00973 ast_debug(1, "Ooh, found a video stream, too, format %s\n", ast_getformatname(vfs->fmt->format)); 00974 } 00975 00976 if (ast_test_flag(chan, AST_FLAG_MASQ_NOSTREAM)) 00977 fs->orig_chan_name = ast_strdup(chan->name); 00978 if (ast_applystream(chan, fs)) 00979 return -1; 00980 if (vfs && ast_applystream(chan, vfs)) 00981 return -1; 00982 res = ast_playstream(fs); 00983 if (!res && vfs) 00984 res = ast_playstream(vfs); 00985 ast_verb(3, "<%s> Playing '%s.%s' (language '%s')\n", chan->name, filename, ast_getformatname(chan->writeformat), preflang ? preflang : "default"); 00986 00987 return res; 00988 }
| off_t ast_tellstream | ( | struct ast_filestream * | fs | ) |
Tell where we are in a stream.
| fs | fs to act on |
Definition at line 875 of file file.c.
References ast_filestream::fmt, and ast_format::tell.
Referenced by __ast_play_and_record(), ast_control_streamfile(), handle_getoption(), handle_recordfile(), handle_speechrecognize(), and handle_streamfile().
| int ast_truncstream | ( | struct ast_filestream * | fs | ) |
Trunc stream at current location.
| fs | filestream to act on |
| 0 | on success. | |
| -1 | on failure. |
Definition at line 870 of file file.c.
References ast_filestream::fmt, and ast_format::trunc.
Referenced by __ast_play_and_record(), handle_recordfile(), and record_exec().
| int ast_waitstream | ( | struct ast_channel * | c, | |
| const char * | breakon | |||
| ) |
Waits for a stream to stop or digit to be pressed.
| 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, |
| 0 | if the stream finishes | |
| the | character if it was interrupted, | |
| -1 | on error |
Definition at line 1321 of file file.c.
References waitstream_core().
Referenced by action_bridge(), agent_call(), announce_thread(), app_exec(), ast_play_and_wait(), ast_say_date_da(), ast_say_date_de(), ast_say_date_en(), ast_say_date_fr(), ast_say_date_gr(), ast_say_date_he(), ast_say_date_hu(), ast_say_date_ka(), ast_say_date_nl(), ast_say_date_th(), ast_say_date_with_format_gr(), ast_say_datetime_en(), ast_say_datetime_fr(), ast_say_datetime_from_now_en(), ast_say_datetime_from_now_fr(), ast_say_datetime_from_now_he(), ast_say_datetime_from_now_ka(), ast_say_datetime_gr(), ast_say_datetime_he(), ast_say_datetime_nl(), ast_say_datetime_pt(), ast_say_datetime_th(), ast_say_datetime_zh(), ast_say_enumeration_full_da(), ast_say_enumeration_full_de(), ast_say_enumeration_full_en(), ast_say_enumeration_full_he(), ast_say_number_full_cs(), ast_say_number_full_da(), ast_say_number_full_de(), ast_say_number_full_en(), ast_say_number_full_en_GB(), ast_say_number_full_es(), ast_say_number_full_fr(), ast_say_number_full_gr(), ast_say_number_full_he(), ast_say_number_full_hu(), ast_say_number_full_it(), ast_say_number_full_ka(), ast_say_number_full_nl(), ast_say_number_full_no(), ast_say_number_full_pt(), ast_say_number_full_ru(), ast_say_number_full_se(), ast_say_number_full_th(), ast_say_number_full_zh(), ast_say_time_de(), ast_say_time_en(), ast_say_time_gr(), ast_say_time_he(), ast_say_time_hu(), ast_say_time_ka(), ast_say_time_nl(), ast_say_time_zh(), ast_stream_and_wait(), auth_exec(), bridge_exec(), check_availability(), check_beep(), common_exec(), conf_exec(), conf_run(), directory_exec(), find_conf_realtime(), gr_say_number_female(), handle_recordfile(), invent_message(), leave_voicemail(), local_attended_transfer(), login_exec(), menu_callback(), minivm_greet_exec(), page_exec(), park_exec_full(), parkandannounce_exec(), pbx_builtin_background(), pl_odtworz_plik(), play_and_wait(), play_file(), play_record_review(), playback_exec(), privacy_exec(), record_exec(), retrydial_exec(), rpt_tele_thread(), s_streamwait3(), say_character_str_full(), say_digit_str_full(), say_phonetic_str_full(), saycharstr(), sayfile(), saynum(), select_item_menu(), send_morse(), send_tone_telemetry(), setup_privacy_args(), ss_thread(), vm_authenticate(), and wait_file().
01322 { 01323 return waitstream_core(c, breakon, NULL, NULL, 0, -1, -1, NULL); 01324 }
| int ast_waitstream_exten | ( | struct ast_channel * | c, | |
| const char * | context | |||
| ) |
Waits for a stream to stop or digit matching a valid one digit exten to be pressed.
| 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, |
| 0 | if the stream finishes. | |
| the | character if it was interrupted. | |
| -1 | on error. |
Definition at line 1332 of file file.c.
References ast_channel::context, and waitstream_core().
Referenced by pbx_builtin_background().
01333 { 01334 /* Waitstream, with return in the case of a valid 1 digit extension */ 01335 /* in the current or specified context being pressed */ 01336 01337 if (!context) 01338 context = c->context; 01339 return waitstream_core(c, NULL, NULL, NULL, 0, 01340 -1, -1, context); 01341 }
| int ast_waitstream_fr | ( | struct ast_channel * | c, | |
| const char * | breakon, | |||
| const char * | forward, | |||
| const char * | rewind, | |||
| int | ms | |||
| ) |
Same as waitstream but allows stream to be forwarded or rewound.
| 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, |
| 0 | if the stream finishes. | |
| the | character if it was interrupted. | |
| -1 | on error. |
Definition at line 1315 of file file.c.
References waitstream_core().
Referenced by ast_control_streamfile().
01316 { 01317 return waitstream_core(c, breakon, forward, reverse, ms, 01318 -1 /* no audiofd */, -1 /* no cmdfd */, NULL /* no context */); 01319 }
| int ast_waitstream_full | ( | struct ast_channel * | c, | |
| const char * | breakon, | |||
| int | audiofd, | |||
| int | monfd | |||
| ) |
Same as waitstream, but with audio output to fd and monitored fd checking.
Definition at line 1326 of file file.c.
References waitstream_core().
Referenced by ast_readstring_full(), ast_say_enumeration_full_da(), ast_say_enumeration_full_de(), ast_say_enumeration_full_en(), ast_say_enumeration_full_he(), ast_say_number_full_cs(), ast_say_number_full_da(), ast_say_number_full_de(), ast_say_number_full_en(), ast_say_number_full_en_GB(), ast_say_number_full_es(), ast_say_number_full_fr(), ast_say_number_full_gr(), ast_say_number_full_he(), ast_say_number_full_hu(), ast_say_number_full_it(), ast_say_number_full_ka(), ast_say_number_full_nl(), ast_say_number_full_no(), ast_say_number_full_pt(), ast_say_number_full_ru(), ast_say_number_full_se(), ast_say_number_full_th(), ast_say_number_full_zh(), handle_getoption(), handle_streamfile(), pl_odtworz_plik(), s_streamwait3(), say_character_str_full(), say_digit_str_full(), and say_phonetic_str_full().
01327 { 01328 return waitstream_core(c, breakon, NULL, NULL, 0, 01329 audiofd, cmdfd, NULL /* no context */); 01330 }
| 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.
| 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. |
| a | struct ast_filestream on success. | |
| NULL | on failure. |
Definition at line 1038 of file file.c.
References ast_closestream(), ast_free, ast_log(), ast_malloc, ast_opt_cache_record_files, AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_strdup, ast_strdupa, buf, build_filename(), errno, ast_format::exts, exts_compare(), ast_filestream::f, f, ast_filestream::filename, ast_filestream::flags, ast_filestream::fmt, get_filestream(), LOG_WARNING, ast_filestream::mode, ast_filestream::realfilename, record_cache_dir, rewrite_wrapper(), ast_format::seek, ast_filestream::trans, ast_filestream::vfs, and ast_filestream::write_buffer.
Referenced by __ast_play_and_record(), ast_monitor_start(), ast_writestream(), dictate_exec(), handle_cli_file_convert(), handle_recordfile(), mixmonitor_thread(), record_exec(), recordthread(), and rpt().
01039 { 01040 int fd, myflags = 0; 01041 /* compiler claims this variable can be used before initialization... */ 01042 FILE *bfile = NULL; 01043 struct ast_format *f; 01044 struct ast_filestream *fs = NULL; 01045 char *buf = NULL; 01046 size_t size = 0; 01047 int format_found = 0; 01048 01049 AST_RWLIST_RDLOCK(&formats); 01050 01051 /* set the O_TRUNC flag if and only if there is no O_APPEND specified */ 01052 /* We really can't use O_APPEND as it will break WAV header updates */ 01053 if (flags & O_APPEND) { 01054 flags &= ~O_APPEND; 01055 } else { 01056 myflags = O_TRUNC; 01057 } 01058 01059 myflags |= O_WRONLY | O_CREAT; 01060 01061 /* XXX need to fix this - we should just do the fopen, 01062 * not open followed by fdopen() 01063 */ 01064 AST_RWLIST_TRAVERSE(&formats, f, list) { 01065 char *fn, *orig_fn = NULL; 01066 if (fs) 01067 break; 01068 01069 if (!exts_compare(f->exts, type)) 01070 continue; 01071 else 01072 format_found = 1; 01073 01074 fn = build_filename(filename, type); 01075 fd = open(fn, flags | myflags, mode); 01076 if (fd > -1) { 01077 /* fdopen() the resulting file stream */ 01078 bfile = fdopen(fd, ((flags | myflags) & O_RDWR) ? "w+" : "w"); 01079 if (!bfile) { 01080 ast_log(LOG_WARNING, "Whoa, fdopen failed: %s!\n", strerror(errno)); 01081 close(fd); 01082 fd = -1; 01083 } 01084 } 01085 01086 if (ast_opt_cache_record_files && (fd > -1)) { 01087 char *c; 01088 01089 fclose(bfile); /* this also closes fd */ 01090 /* 01091 We touch orig_fn just as a place-holder so other things (like vmail) see the file is there. 01092 What we are really doing is writing to record_cache_dir until we are done then we will mv the file into place. 01093 */ 01094 orig_fn = ast_strdupa(fn); 01095 for (c = fn; *c; c++) 01096 if (*c == '/') 01097 *c = '_'; 01098 01099 size = strlen(fn) + strlen(record_cache_dir) + 2; 01100 buf = alloca(size); 01101 strcpy(buf, record_cache_dir); 01102 strcat(buf, "/"); 01103 strcat(buf, fn); 01104 ast_free(fn); 01105 fn = buf; 01106 fd = open(fn, flags | myflags, mode); 01107 if (fd > -1) { 01108 /* fdopen() the resulting file stream */ 01109 bfile = fdopen(fd, ((flags | myflags) & O_RDWR) ? "w+" : "w"); 01110 if (!bfile) { 01111 ast_log(LOG_WARNING, "Whoa, fdopen failed: %s!\n", strerror(errno)); 01112 close(fd); 01113 fd = -1; 01114 } 01115 } 01116 } 01117 if (fd > -1) { 01118 errno = 0; 01119 fs = get_filestream(f, bfile); 01120 if (fs) { 01121 if ((fs->write_buffer = ast_malloc(32768))) { 01122 setvbuf(fs->f, fs->write_buffer, _IOFBF, 32768); 01123 } 01124 } 01125 if (!fs || rewrite_wrapper(fs, comment)) { 01126 ast_log(LOG_WARNING, "Unable to rewrite %s\n", fn); 01127 close(fd); 01128 if (orig_fn) { 01129 unlink(fn); 01130 unlink(orig_fn); 01131 } 01132 if (fs) { 01133 ast_closestream(fs); 01134 fs = NULL; 01135 } 01136 continue; 01137 } 01138 fs->trans = NULL; 01139 fs->fmt = f; 01140 fs->flags = flags; 01141 fs->mode = mode; 01142 if (orig_fn) { 01143 fs->realfilename = ast_strdup(orig_fn); 01144 fs->filename = ast_strdup(fn); 01145 } else { 01146 fs->realfilename = NULL; 01147 fs->filename = ast_strdup(filename); 01148 } 01149 fs->vfs = NULL; 01150 /* If truncated, we'll be at the beginning; if not truncated, then append */ 01151 f->seek(fs, 0, SEEK_END); 01152 } else if (errno != EEXIST) { 01153 ast_log(LOG_WARNING, "Unable to open file %s: %s\n", fn, strerror(errno)); 01154 if (orig_fn) 01155 unlink(orig_fn); 01156 } 01157 /* if buf != NULL then fn is already free and pointing to it */ 01158 if (!buf) 01159 ast_free(fn); 01160 } 01161 01162 AST_RWLIST_UNLOCK(&formats); 01163 01164 if (!format_found) 01165 ast_log(LOG_WARNING, "No such format '%s'\n", type); 01166 01167 return fs; 01168 }
| int ast_writestream | ( | struct ast_filestream * | fs, | |
| struct ast_frame * | f | |||
| ) |
Writes a frame to a stream.
| 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 |
| 0 | on success. | |
| -1 | on failure. |
Definition at line 144 of file file.c.
References ast_debug, AST_FORMAT_AUDIO_MASK, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_frfree, ast_getformatname(), AST_LIST_NEXT, ast_log(), ast_translate(), ast_translator_build_path(), ast_translator_free_path(), ast_writefile(), ast_writestream(), ast_filestream::filename, ast_filestream::flags, ast_filestream::fmt, ast_format::format, ast_frame::frametype, ast_filestream::lastwriteformat, LOG_WARNING, ast_filestream::mode, ast_format::name, ast_frame::subclass, ast_filestream::trans, type, ast_filestream::vfs, and ast_format::write.
Referenced by __ast_play_and_record(), __ast_read(), ast_write(), ast_writestream(), dictate_exec(), handle_cli_file_convert(), handle_recordfile(), mixmonitor_thread(), record_exec(), recordthread(), and rpt().
00145 { 00146 int res = -1; 00147 int alt = 0; 00148 if (f->frametype == AST_FRAME_VIDEO) { 00149 if (fs->fmt->format & AST_FORMAT_AUDIO_MASK) { 00150 /* This is the audio portion. Call the video one... */ 00151 if (!fs->vfs && fs->filename) { 00152 const char *type = ast_getformatname(f->subclass & ~0x1); 00153 fs->vfs = ast_writefile(fs->filename, type, NULL, fs->flags, 0, fs->mode); 00154 ast_debug(1, "Opened video output file\n"); 00155 } 00156 if (fs->vfs) 00157 return ast_writestream(fs->vfs, f); 00158 /* else ignore */ 00159 return 0; 00160 } else { 00161 /* Might / might not have mark set */ 00162 alt = 1; 00163 } 00164 } else if (f->frametype != AST_FRAME_VOICE) { 00165 ast_log(LOG_WARNING, "Tried to write non-voice frame\n"); 00166 return -1; 00167 } 00168 if (((fs->fmt->format | alt) & f->subclass) == f->subclass) { 00169 res = fs->fmt->write(fs, f); 00170 if (res < 0) 00171 ast_log(LOG_WARNING, "Natural write failed\n"); 00172 else if (res > 0) 00173 ast_log(LOG_WARNING, "Huh??\n"); 00174 } else { 00175 /* XXX If they try to send us a type of frame that isn't the normal frame, and isn't 00176 the one we've setup a translator for, we do the "wrong thing" XXX */ 00177 if (fs->trans && f->subclass != fs->lastwriteformat) { 00178 ast_translator_free_path(fs->trans); 00179 fs->trans = NULL; 00180 } 00181 if (!fs->trans) 00182 fs->trans = ast_translator_build_path(fs->fmt->format, f->subclass); 00183 if (!fs->trans) 00184 ast_log(LOG_WARNING, "Unable to translate to format %s, source format %s\n", 00185 fs->fmt->name, ast_getformatname(f->subclass)); 00186 else { 00187 struct ast_frame *trf; 00188 fs->lastwriteformat = f->subclass; 00189 /* Get the translated frame but don't consume the original in case they're using it on another stream */ 00190 if ((trf = ast_translate(fs->trans, f, 0))) { 00191 struct ast_frame *cur; 00192 00193 /* the translator may have returned multiple frames, so process them */ 00194 for (cur = trf; cur; cur = AST_LIST_NEXT(cur, frame_list)) { 00195 if ((res = fs->fmt->write(fs, trf))) { 00196 ast_log(LOG_WARNING, "Translated frame write failed\n"); 00197 break; 00198 } 00199 } 00200 ast_frfree(trf); 00201 } else { 00202 res = 0; 00203 } 00204 } 00205 } 00206 return res; 00207 }
| static char* build_filename | ( | const char * | filename, | |
| const char * | ext | |||
| ) | [static] |
construct a filename. Absolute pathnames are preserved, relative names are prefixed by the sounds/ directory. The wav49 suffix is replaced by 'WAV'. Returns a malloc'ed string to be freed by the caller.
Definition at line 252 of file file.c.
References asprintf, ast_config_AST_DATA_DIR, ast_log(), errno, and LOG_WARNING.
Referenced by ast_filehelper(), ast_readfile(), and ast_writefile().
00253 { 00254 char *fn = NULL; 00255 00256 if (!strcmp(ext, "wav49")) 00257 ext = "WAV"; 00258 00259 if (filename[0] == '/') { 00260 if (asprintf(&fn, "%s.%s", filename, ext) < 0) { 00261 ast_log(LOG_WARNING, "asprintf() failed: %s\n", strerror(errno)); 00262 fn = NULL; 00263 } 00264 } else { 00265 if (asprintf(&fn, "%s/sounds/%s.%s", 00266 ast_config_AST_DATA_DIR, filename, ext) < 0) { 00267 ast_log(LOG_WARNING, "asprintf() failed: %s\n", strerror(errno)); 00268 fn = NULL; 00269 } 00270 } 00271 return fn; 00272 }
| static int copy | ( | const char * | infile, | |
| const char * | outfile | |||
| ) | [static] |
Definition at line 209 of file file.c.
References AST_FILE_MODE, ast_log(), buf, errno, len(), and LOG_WARNING.
00210 { 00211 int ifd, ofd, len; 00212 char buf[4096]; /* XXX make it lerger. */ 00213 00214 if ((ifd = open(infile, O_RDONLY)) < 0) { 00215 ast_log(LOG_WARNING, "Unable to open %s in read-only mode\n", infile); 00216 return -1; 00217 } 00218 if ((ofd = open(outfile, O_WRONLY | O_TRUNC | O_CREAT, AST_FILE_MODE)) < 0) { 00219 ast_log(LOG_WARNING, "Unable to open %s in write-only mode\n", outfile); 00220 close(ifd); 00221 return -1; 00222 } 00223 while ( (len = read(ifd, buf, sizeof(buf)) ) ) { 00224 int res; 00225 if (len < 0) { 00226 ast_log(LOG_WARNING, "Read failed on %s: %s\n", infile, strerror(errno)); 00227 break; 00228 } 00229 /* XXX handle partial writes */ 00230 res = write(ofd, buf, len); 00231 if (res != len) { 00232 ast_log(LOG_WARNING, "Write failed on %s (%d of %d): %s\n", outfile, res, len, strerror(errno)); 00233 len = -1; /* error marker */ 00234 break; 00235 } 00236 } 00237 close(ifd); 00238 close(ofd); 00239 if (len < 0) { 00240 unlink(outfile); 00241 return -1; /* error */ 00242 } 00243 return 0; /* success */ 00244 }
| static int exts_compare | ( | const char * | exts, | |
| const char * | type | |||
| ) | [static] |
Definition at line 276 of file file.c.
References ast_copy_string(), ext, and strsep().
Referenced by ast_filehelper(), ast_format_str_reduce(), ast_readfile(), and ast_writefile().
00277 { 00278 char tmp[256]; 00279 char *stringp = tmp, *ext; 00280 00281 ast_copy_string(tmp, exts, sizeof(tmp)); 00282 while ((ext = strsep(&stringp, "|"))) { 00283 if (!strcmp(ext, type)) 00284 return 1; 00285 } 00286 00287 return 0; 00288 }
| static int fileexists_core | ( | const char * | filename, | |
| const char * | fmt, | |||
| const char * | preflang, | |||
| char * | buf, | |||
| int | buflen | |||
| ) | [static] |
helper routine to locate a file with a given format and language preference. Try preflang, preflang with stripped '_' suffix, or NULL. In the standard asterisk, language goes just before the last component. In an alternative configuration, the language should be a prefix to the actual filename.
The last parameter(s) point to a buffer of sufficient size, which on success is filled with the matching filename.
Definition at line 568 of file file.c.
References ast_strdupa, ast_strlen_zero(), DEFAULT_LANGUAGE, fileexists_test(), and strsep().
Referenced by ast_fileexists(), ast_openstream_full(), and ast_openvstream().
00570 { 00571 int res = -1; 00572 char *lang = NULL; 00573 00574 if (buf == NULL) { 00575 return -1; 00576 } 00577 00578 /* We try languages in the following order: 00579 * preflang (may include dialect) 00580 * lang (preflang without dialect - if any) 00581 * <none> 00582 * default (unless the same as preflang or lang without dialect) 00583 */ 00584 00585 /* Try preferred language */ 00586 if (!ast_strlen_zero(preflang)) { 00587 /* try the preflang exactly as it was requested */ 00588 if ((res = fileexists_test(filename, fmt, preflang, buf, buflen)) > 0) { 00589 return res; 00590 } else { 00591 /* try without a dialect */ 00592 char *postfix = NULL; 00593 postfix = lang = ast_strdupa(preflang); 00594 00595 strsep(&postfix, "_"); 00596 if (postfix) { 00597 if ((res = fileexists_test(filename, fmt, lang, buf, buflen)) > 0) { 00598 return res; 00599 } 00600 } 00601 } 00602 } 00603 00604 /* Try without any language */ 00605 if ((res = fileexists_test(filename, fmt, NULL, buf, buflen)) > 0) { 00606 return res; 00607 } 00608 00609 /* Finally try the default language unless it was already tried before */ 00610 if ((ast_strlen_zero(preflang) || strcmp(preflang, DEFAULT_LANGUAGE)) && (ast_strlen_zero(lang) || strcmp(lang, DEFAULT_LANGUAGE))) { 00611 if ((res = fileexists_test(filename, fmt, DEFAULT_LANGUAGE, buf, buflen)) > 0) { 00612 return res; 00613 } 00614 } 00615 00616 return 0; 00617 }
| static int fileexists_test | ( | const char * | filename, | |
| const char * | fmt, | |||
| const char * | lang, | |||
| char * | buf, | |||
| int | buflen | |||
| ) | [static] |
Definition at line 531 of file file.c.
References ACTION_EXISTS, ast_filehelper(), and is_absolute_path().
Referenced by fileexists_core().
00533 { 00534 if (buf == NULL) { 00535 return -1; 00536 } 00537 00538 if (ast_language_is_prefix && !is_absolute_path(filename)) { /* new layout */ 00539 if (lang) { 00540 snprintf(buf, buflen, "%s/%s", lang, filename); 00541 } else { 00542 snprintf(buf, buflen, "%s", filename); 00543 } 00544 } else { /* old layout */ 00545 strcpy(buf, filename); /* first copy the full string */ 00546 if (lang) { 00547 /* insert the language and suffix if needed */ 00548 const char *c = strrchr(filename, '/'); 00549 int offset = c ? c - filename + 1 : 0; /* points right after the last '/' */ 00550 snprintf(buf + offset, buflen - offset, "%s/%s", lang, filename + offset); 00551 } 00552 } 00553 00554 return ast_filehelper(buf, NULL, fmt, ACTION_EXISTS); 00555 }
| static void filestream_destructor | ( | void * | arg | ) | [static] |
Definition at line 290 of file file.c.
References ast_closestream(), AST_FORMAT_AUDIO_MASK, ast_free, ast_module_unref(), ast_safe_system(), AST_SCHED_DEL, ast_settimeout(), ast_translator_free_path(), ast_format::close, ast_filestream::f, f, ast_filestream::filename, ast_filestream::fmt, ast_format::format, free, ast_format::module, ast_filestream::orig_chan_name, ast_filestream::owner, ast_filestream::realfilename, ast_channel::sched, ast_channel::stream, ast_channel::streamid, ast_filestream::trans, ast_filestream::vfs, ast_channel::vstream, ast_channel::vstreamid, and ast_filestream::write_buffer.
Referenced by get_filestream().
00291 { 00292 char *cmd = NULL; 00293 size_t size = 0; 00294 struct ast_filestream *f = arg; 00295 00296 /* Stop a running stream if there is one */ 00297 if (f->owner) { 00298 if (f->fmt->format < AST_FORMAT_AUDIO_MASK) { 00299 f->owner->stream = NULL; 00300 AST_SCHED_DEL(f->owner->sched, f->owner->streamid); 00301 ast_settimeout(f->owner, 0, NULL, NULL); 00302 } else { 00303 f->owner->vstream = NULL; 00304 AST_SCHED_DEL(f->owner->sched, f->owner->vstreamid); 00305 } 00306 } 00307 /* destroy the translator on exit */ 00308 if (f->trans) 00309 ast_translator_free_path(f->trans); 00310 00311 if (f->realfilename && f->filename) { 00312 size = strlen(f->filename) + strlen(f->realfilename) + 15; 00313 cmd = alloca(size); 00314 memset(cmd,0,size); 00315 snprintf(cmd,size,"/bin/mv -f %s %s",f->filename,f->realfilename); 00316 ast_safe_system(cmd); 00317 } 00318 00319 if (f->filename) 00320 free(f->filename); 00321 if (f->realfilename) 00322 free(f->realfilename); 00323 if (f->fmt->close) { 00324 void (*closefn)(struct ast_filestream *) = f->fmt->close; 00325 closefn(f); 00326 } 00327 if (f->f) 00328 fclose(f->f); 00329 if (f->vfs) 00330 ast_closestream(f->vfs); 00331 if (f->write_buffer) { 00332 ast_free(f->write_buffer); 00333 } 00334 if (f->orig_chan_name) 00335 free((void *) f->orig_chan_name); 00336 ast_module_unref(f->fmt->module); 00337 }
| static int fn_wrapper | ( | struct ast_filestream * | s, | |
| const char * | comment, | |||
| enum wrap_fn | mode | |||
| ) | [static] |
Definition at line 363 of file file.c.
References ast_log(), ast_module_ref(), f, ast_filestream::fmt, LOG_WARNING, ast_format::module, ast_format::name, ast_format::open, ast_format::rewrite, WRAP_OPEN, and WRAP_REWRITE.
Referenced by open_wrapper(), and rewrite_wrapper().
00364 { 00365 struct ast_format *f = s->fmt; 00366 int ret = -1; 00367 int (*openfn)(struct ast_filestream *s); 00368 00369 if (mode == WRAP_OPEN && (openfn = f->open) && openfn(s)) 00370 ast_log(LOG_WARNING, "Unable to open format %s\n", f->name); 00371 else if (mode == WRAP_REWRITE && f->rewrite && f->rewrite(s, comment)) 00372 ast_log(LOG_WARNING, "Unable to rewrite format %s\n", f->name); 00373 else { 00374 /* preliminary checks succeed. update usecount */ 00375 ast_module_ref(f->module); 00376 ret = 0; 00377 } 00378 return ret; 00379 }
| static struct ast_filestream* get_filestream | ( | struct ast_format * | fmt, | |
| FILE * | bfile | |||
| ) | [static, read] |
Definition at line 339 of file file.c.
References ast_filestream::_private, ao2_alloc, ast_filestream::buf, ast_format::buf_size, ast_format::desc_size, ast_filestream::f, filestream_destructor(), ast_filestream::fmt, ast_filestream::fr, ast_format::name, s, and ast_frame::src.
Referenced by ast_filehelper(), ast_readfile(), and ast_writefile().
00340 { 00341 struct ast_filestream *s; 00342 00343 int l = sizeof(*s) + fmt->buf_size + fmt->desc_size; /* total allocation size */ 00344 if ( (s = ao2_alloc(l, filestream_destructor)) == NULL) 00345 return NULL; 00346 s->fmt = fmt; 00347 s->f = bfile; 00348 00349 if (fmt->desc_size) 00350 s->_private = ((char *)(s + 1)) + fmt->buf_size; 00351 if (fmt->buf_size) 00352 s->buf = (char *)(s + 1); 00353 s->fr.src = fmt->name; 00354 return s; 00355 }
| static char* handle_cli_core_show_file_formats | ( | struct ast_cli_entry * | e, | |
| int | cmd, | |||
| struct ast_cli_args * | a | |||
| ) | [static] |
Definition at line 1436 of file file.c.
References ast_cli_args::argc, ast_cli(), ast_getformatname(), AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_format::exts, f, ast_cli_args::fd, ast_format::format, FORMAT, FORMAT2, ast_format::list, ast_format::name, and ast_cli_entry::usage.
01437 { 01438 #define FORMAT "%-10s %-10s %-20s\n" 01439 #define FORMAT2 "%-10s %-10s %-20s\n" 01440 struct ast_format *f; 01441 int count_fmt = 0; 01442 01443 switch (cmd) { 01444 case CLI_INIT: 01445 e->command = "core show file formats"; 01446 e->usage = 01447 "Usage: core show file formats\n" 01448 " Displays currently registered file formats (if any).\n"; 01449 return NULL; 01450 case CLI_GENERATE: 01451 return NULL; 01452 } 01453 01454 if (a->argc != 4) 01455 return CLI_SHOWUSAGE; 01456 01457 ast_cli(a->fd, FORMAT, "Format", "Name", "Extensions"); 01458 ast_cli(a->fd, FORMAT, "------", "----", "----------"); 01459 01460 AST_RWLIST_RDLOCK(&formats); 01461 AST_RWLIST_TRAVERSE(&formats, f, list) { 01462 ast_cli(a->fd, FORMAT2, ast_getformatname(f->format), f->name, f->exts); 01463 count_fmt++; 01464 } 01465 AST_RWLIST_UNLOCK(&formats); 01466 ast_cli(a->fd, "%d file formats registered.\n", count_fmt); 01467 return CLI_SUCCESS; 01468 #undef FORMAT 01469 #undef FORMAT2 01470 }
| static int is_absolute_path | ( | const char * | filename | ) | [static] |
| static int open_wrapper | ( | struct ast_filestream * | s | ) | [static] |
Definition at line 386 of file file.c.
References fn_wrapper(), and WRAP_OPEN.
Referenced by ast_filehelper(), and ast_readfile().
00387 { 00388 return fn_wrapper(s, NULL, WRAP_OPEN); 00389 }
| static struct ast_frame* read_frame | ( | struct ast_filestream * | s, | |
| int * | whennext | |||
| ) | [static, read] |
Definition at line 698 of file file.c.
References ast_frfree, ast_frisolate(), ast_filestream::fmt, and ast_format::read.
Referenced by ast_audiohook_read_frame(), ast_readaudio_callback(), ast_readframe(), and ast_readvideo_callback().
00699 { 00700 struct ast_frame *fr, *new_fr; 00701 00702 if (!s || !s->fmt) { 00703 return NULL; 00704 } 00705 00706 if (!(fr = s->fmt->read(s, whennext))) { 00707 return NULL; 00708 } 00709 00710 if (!(new_fr = ast_frisolate(fr))) { 00711 ast_frfree(fr); 00712 return NULL; 00713 } 00714 00715 if (new_fr != fr) { 00716 ast_frfree(fr); 00717 fr = new_fr; 00718 } 00719 00720 return fr; 00721 }
| static int rewrite_wrapper | ( | struct ast_filestream * | s, | |
| const char * | comment | |||
| ) | [static] |
Definition at line 381 of file file.c.
References fn_wrapper(), and WRAP_REWRITE.
Referenced by ast_writefile().
00382 { 00383 return fn_wrapper(s, comment, WRAP_REWRITE); 00384 }
| static int waitstream_core | ( | struct ast_channel * | c, | |
| const char * | breakon, | |||
| const char * | forward, | |||
| const char * | reverse, | |||
| int | skip_ms, | |||
| int | audiofd, | |||
| int | cmdfd, | |||
| const char * | context | |||
| ) | [static] |
the core of all waitstream() functions
Definition at line 1173 of file file.c.
References ast_channel::_softhangup, ast_clear_flag, AST_CONTROL_ANSWER, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_HANGUP, AST_CONTROL_HOLD, AST_CONTROL_RINGING, AST_CONTROL_SRCCHANGE, AST_CONTROL_SRCUPDATE, AST_CONTROL_UNHOLD, AST_CONTROL_VIDUPDATE, ast_exists_extension(), AST_FLAG_END_DTMF_ONLY, AST_FLAG_MASQ_NOSTREAM, AST_FRAME_CONTROL, AST_FRAME_DTMF_END, AST_FRAME_VOICE, ast_frfree, ast_log(), ast_read(), ast_sched_runq(), ast_sched_wait(), ast_set_flag, ast_stopstream(), ast_strdupa, ast_stream_fastforward(), ast_stream_rewind(), ast_test_flag, ast_waitfor(), ast_waitfor_nandfds(), ast_channel::cid, ast_callerid::cid_num, ast_frame::data, ast_frame::datalen, errno, exten, ast_filestream::f, ast_frame::frametype, LOG_WARNING, ast_channel::name, ast_filestream::orig_chan_name, ast_frame::ptr, ast_channel::sched, ast_channel::stream, and ast_frame::subclass.
Referenced by ast_waitstream(), ast_waitstream_exten(), ast_waitstream_fr(), and ast_waitstream_full().
01176 { 01177 const char *orig_chan_name = NULL; 01178 int err = 0; 01179 01180 if (!breakon) 01181 breakon = ""; 01182 if (!forward) 01183 forward = ""; 01184 if (!reverse) 01185 reverse = ""; 01186 01187 /* Switch the channel to end DTMF frame only. waitstream_core doesn't care about the start of DTMF. */ 01188 ast_set_flag(c, AST_FLAG_END_DTMF_ONLY); 01189 01190 if (ast_test_flag(c, AST_FLAG_MASQ_NOSTREAM)) 01191 orig_chan_name = ast_strdupa(c->name); 01192 01193 while (c->stream) { 01194 int res; 01195 int ms; 01196 01197 if (orig_chan_name && strcasecmp(orig_chan_name, c->name)) { 01198 ast_stopstream(c); 01199 err = 1; 01200 break; 01201 } 01202 01203 ms = ast_sched_wait(c->sched); 01204 01205 if (ms < 0 && !c->timingfunc) { 01206 ast_stopstream(c); 01207 break; 01208 } 01209 if (ms < 0) 01210 ms = 1000; 01211 if (cmdfd < 0) { 01212 res = ast_waitfor(c, ms); 01213 if (res < 0) { 01214 ast_log(LOG_WARNING, "Select failed (%s)\n", strerror(errno)); 01215 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 01216 return res; 01217 } 01218 } else { 01219 int outfd; 01220 struct ast_channel *rchan = ast_waitfor_nandfds(&c, 1, &cmdfd, (cmdfd > -1) ? 1 : 0, NULL, &outfd, &ms); 01221 if (!rchan && (outfd < 0) && (ms)) { 01222 /* Continue */ 01223 if (errno == EINTR) 01224 continue; 01225 ast_log(LOG_WARNING, "Wait failed (%s)\n", strerror(errno)); 01226 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 01227 return -1; 01228 } else if (outfd > -1) { /* this requires cmdfd set */ 01229 /* The FD we were watching has something waiting */ 01230 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 01231 return 1; 01232 } 01233 /* if rchan is set, it is 'c' */ 01234 res = rchan ? 1 : 0; /* map into 'res' values */ 01235 } 01236 if (res > 0) { 01237 struct ast_frame *fr = ast_read(c); 01238 if (!fr) { 01239 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 01240 return -1; 01241 } 01242 switch (fr->frametype) { 01243 case AST_FRAME_DTMF_END: 01244 if (context) { 01245 const char exten[2] = { fr->subclass, '\0' }; 01246 if (ast_exists_extension(c, context, exten, 1, c->cid.cid_num)) { 01247 res = fr->subclass; 01248 ast_frfree(fr); 01249 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 01250 return res; 01251 } 01252 } else { 01253 res = fr->subclass; 01254 if (strchr(forward, res)) { 01255 int eoftest; 01256 ast_stream_fastforward(c->stream, skip_ms); 01257 eoftest = fgetc(c->stream->f); 01258 if (feof(c->stream->f)) { 01259 ast_stream_rewind(c->stream, skip_ms); 01260 } else { 01261 ungetc(eoftest, c->stream->f); 01262 } 01263 } else if (strchr(reverse, res)) { 01264 ast_stream_rewind(c->stream, skip_ms); 01265 } else if (strchr(breakon, res)) { 01266 ast_frfree(fr); 01267 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 01268 return res; 01269 } 01270 } 01271 break; 01272 case AST_FRAME_CONTROL: 01273 switch (fr->subclass) { 01274 case AST_CONTROL_HANGUP: 01275 case AST_CONTROL_BUSY: 01276 case AST_CONTROL_CONGESTION: 01277 ast_frfree(fr); 01278 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 01279 return -1; 01280 case AST_CONTROL_RINGING: 01281 case AST_CONTROL_ANSWER: 01282 case AST_CONTROL_VIDUPDATE: 01283 case AST_CONTROL_SRCUPDATE: 01284 case AST_CONTROL_SRCCHANGE: 01285 case AST_CONTROL_HOLD: 01286 case AST_CONTROL_UNHOLD: 01287 case -1: 01288 /* Unimportant */ 01289 break; 01290 default: 01291 ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", fr->subclass); 01292 } 01293 break; 01294 case AST_FRAME_VOICE: 01295 /* Write audio if appropriate */ 01296 if (audiofd > -1) { 01297 if (write(audiofd, fr->data.ptr, fr->datalen) < 0) { 01298 ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno)); 01299 } 01300 } 01301 default: 01302 /* Ignore all others */ 01303 break; 01304 } 01305 ast_frfree(fr); 01306 } 01307 ast_sched_runq(c->sched); 01308 } 01309 01310 ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY); 01311 01312 return (err || c->_softhangup) ? -1 : 0; 01313 }
| int ast_language_is_prefix = 1 |
Definition at line 57 of file file.c.
Referenced by ast_readconfig(), handle_show_settings(), and main().
| struct ast_cli_entry cli_file[] |
Initial value:
{
AST_CLI_DEFINE(handle_cli_core_show_file_formats, "Displays file formats")
}
1.5.6