diff options
author | markster <markster@f38db490-d61c-443f-a65b-d21fe96a405b> | 2003-02-06 22:11:43 +0000 |
---|---|---|
committer | markster <markster@f38db490-d61c-443f-a65b-d21fe96a405b> | 2003-02-06 22:11:43 +0000 |
commit | 8b1f06abb435a2aa00d7b5d1e8dd1588bf895483 (patch) | |
tree | 8220ad163713cb38240eb18c24be25aa88b28865 /file.c | |
parent | 12b57158d66873fd353d3ae66662e205bd96debb (diff) |
Version 0.3.0 from FTP
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@608 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'file.c')
-rwxr-xr-x | file.c | 233 |
1 files changed, 169 insertions, 64 deletions
@@ -1,4 +1,4 @@ -/* +/*m * Asterisk -- A telephony toolkit for Linux. * * Generic File Format Support. @@ -28,6 +28,7 @@ #include <dirent.h> #include <sys/stat.h> #include "asterisk.h" +#include "astconf.h" struct ast_format { /* Name of format */ @@ -43,8 +44,16 @@ struct ast_format { struct ast_filestream * (*rewrite)(int fd, char *comment); /* Apply a reading filestream to a channel */ int (*apply)(struct ast_channel *, struct ast_filestream *); + /* play filestream on a channel */ + int (*play)(struct ast_filestream *); /* Write a frame to a channel */ int (*write)(struct ast_filestream *, struct ast_frame *); + /* seek num samples into file, whence(think normal seek) */ + int (*seek)(struct ast_filestream *, long offset, int whence); + /* trunc file to current position */ + int (*trunc)(struct ast_filestream *fs); + /* tell current position */ + long (*tell)(struct ast_filestream *fs); /* Read the next frame from the filestream (if available) */ struct ast_frame * (*read)(struct ast_filestream *); /* Close file, and destroy filestream structure */ @@ -71,7 +80,11 @@ int ast_format_register(char *name, char *exts, int format, struct ast_filestream * (*open)(int fd), struct ast_filestream * (*rewrite)(int fd, char *comment), int (*apply)(struct ast_channel *, struct ast_filestream *), + int (*play)(struct ast_filestream *), int (*write)(struct ast_filestream *, struct ast_frame *), + int (*seek)(struct ast_filestream *, long sample_offset, int whence), + int (*trunc)(struct ast_filestream *), + long (*tell)(struct ast_filestream *), struct ast_frame * (*read)(struct ast_filestream *), void (*close)(struct ast_filestream *), char * (*getcomment)(struct ast_filestream *)) @@ -101,8 +114,12 @@ int ast_format_register(char *name, char *exts, int format, tmp->open = open; tmp->rewrite = rewrite; tmp->apply = apply; + tmp->play = play; tmp->read = read; tmp->write = write; + tmp->seek = seek; + tmp->trunc = trunc; + tmp->tell = tell; tmp->close = close; tmp->format = format; tmp->getcomment = getcomment; @@ -151,13 +168,6 @@ int ast_stopstream(struct ast_channel *tmp) return 0; } -int ast_closestream(struct ast_filestream *f) -{ - /* Stop a running stream if there is one */ - f->fmt->close(f); - return 0; -} - int ast_writestream(struct ast_filestream *fs, struct ast_frame *f) { struct ast_frame *trf; @@ -237,12 +247,14 @@ static int copy(char *infile, char *outfile) static char *build_filename(char *filename, char *ext) { char *fn; - fn = malloc(strlen(AST_SOUNDS) + strlen(filename) + strlen(ext) + 10); + char tmp[AST_CONFIG_MAX_PATH]; + snprintf((char *)tmp,sizeof(tmp)-1,"%s/%s",(char *)ast_config_AST_VAR_DIR,"sounds"); + fn = malloc(strlen(tmp) + strlen(filename) + strlen(ext) + 10); if (fn) { if (filename[0] == '/') sprintf(fn, "%s.%s", filename, ext); else - sprintf(fn, "%s/%s.%s", AST_SOUNDS, filename, ext); + sprintf(fn, "%s/%s.%s", (char *)tmp, filename, ext); } return fn; @@ -281,9 +293,11 @@ static int ast_filehelper(char *filename, char *filename2, char *fmt, int action f = formats; while(f) { if (!fmt || !strcasecmp(f->name, fmt)) { + char *stringp=NULL; exts = strdup(f->exts); /* Try each kind of extension */ - ext = strtok(exts, "|"); + stringp=exts; + ext = strsep(&stringp, "|"); do { fn = build_filename(filename, ext); if (fn) { @@ -327,13 +341,6 @@ static int ast_filehelper(char *filename, char *filename2, char *fmt, int action s->fmt = f; s->trans = NULL; chan->stream = s; - if (f->apply(chan, s)) { - f->close(s); - chan->stream = NULL; - ast_log(LOG_WARNING, "Unable to apply stream to channel %s\n", chan->name); - close(ret); - ret = 0; - } } else { close(ret); ast_log(LOG_WARNING, "Unable to open fd on %s\n", filename); @@ -351,7 +358,7 @@ static int ast_filehelper(char *filename, char *filename2, char *fmt, int action } free(fn); } - ext = strtok(NULL, "|"); + ext = strsep(&stringp, "|"); } while(ext); free(exts); } @@ -363,45 +370,7 @@ static int ast_filehelper(char *filename, char *filename2, char *fmt, int action return res; } -int ast_fileexists(char *filename, char *fmt, char *preflang) -{ - char filename2[256]; - char lang2[MAX_LANGUAGE]; - int res = -1; - if (preflang && strlen(preflang)) { - snprintf(filename2, sizeof(filename2), "%s-%s", filename, preflang); - res = ast_filehelper(filename2, NULL, fmt, ACTION_EXISTS); - if (res < 1) { - strncpy(lang2, preflang, sizeof(lang2)-1); - strtok(lang2, "_"); - if (strcmp(lang2, preflang)) { - snprintf(filename2, sizeof(filename2), "%s-%s", filename, lang2); - res = ast_filehelper(filename2, NULL, fmt, ACTION_EXISTS); - } - } - } - if (res < 1) { - res = ast_filehelper(filename, NULL, fmt, ACTION_EXISTS); - } - return res; -} - -int ast_filedelete(char *filename, char *fmt) -{ - return ast_filehelper(filename, NULL, fmt, ACTION_DELETE); -} - -int ast_filerename(char *filename, char *filename2, char *fmt) -{ - return ast_filehelper(filename, filename2, fmt, ACTION_RENAME); -} - -int ast_filecopy(char *filename, char *filename2, char *fmt) -{ - return ast_filehelper(filename, filename2, fmt, ACTION_COPY); -} - -int ast_streamfile(struct ast_channel *chan, char *filename, char *preflang) +struct ast_filestream *ast_openstream(struct ast_channel *chan, char *filename, char *preflang) { /* This is a fairly complex routine. Essentially we should do the following: @@ -421,6 +390,9 @@ int ast_streamfile(struct ast_channel *chan, char *filename, char *preflang) char lang2[MAX_LANGUAGE]; int res; ast_stopstream(chan); + /* do this first, otherwise we detect the wrong writeformat */ + if (chan->generator) + ast_deactivate_generator(chan); if (preflang && strlen(preflang)) { snprintf(filename2, sizeof(filename2), "%s-%s", filename, preflang); fmts = ast_fileexists(filename2, NULL, NULL); @@ -436,17 +408,145 @@ int ast_streamfile(struct ast_channel *chan, char *filename, char *preflang) } if (fmts < 1) { ast_log(LOG_WARNING, "File %s does not exist in any format\n", filename); - return -1; + return NULL; } chan->oldwriteformat = chan->writeformat; /* Set the channel to a format we can work with */ res = ast_set_write_format(chan, fmts); fd = ast_filehelper(filename2, (char *)chan, NULL, ACTION_OPEN); - if (fd >= 0) { + if(fd >= 0) + return chan->stream; + return NULL; +} + +int ast_applystream(struct ast_channel *chan, struct ast_filestream *s) +{ + if(chan->stream->fmt->apply(chan,s)){ + chan->stream->fmt->close(s); + chan->stream = NULL; + ast_log(LOG_WARNING, "Unable to apply stream to channel %s\n", chan->name); + return -1; + } + return 0; +} + +int ast_playstream(struct ast_filestream *s) +{ + if(s->fmt->play(s)){ + ast_closestream(s); + ast_log(LOG_WARNING, "Unable to start playing stream\n"); + return -1; + } + return 0; +} + +int ast_seekstream(struct ast_filestream *fs, long sample_offset, int whence) +{ + return fs->fmt->seek(fs, sample_offset, whence); +} + +int ast_truncstream(struct ast_filestream *fs) +{ + return fs->fmt->trunc(fs); +} + +long ast_tellstream(struct ast_filestream *fs) +{ + return fs->fmt->tell(fs); +} + +int ast_stream_fastforward(struct ast_filestream *fs, long ms) +{ + /* I think this is right, 8000 samples per second, 1000 ms a second so 8 + * samples per ms */ + long samples = ms * 8; + return ast_seekstream(fs, samples, SEEK_CUR); +} + +int ast_stream_rewind(struct ast_filestream *fs, long ms) +{ + long samples = ms * 8; + samples = samples * -1; + return ast_seekstream(fs, samples, SEEK_CUR); +} + +int ast_closestream(struct ast_filestream *f) +{ + /* Stop a running stream if there is one */ + f->fmt->close(f); + return 0; +} + + +int ast_fileexists(char *filename, char *fmt, char *preflang) +{ + char filename2[256]; + char tmp[256]; + char *postfix; + char *prefix; + char *c; + char lang2[MAX_LANGUAGE]; + int res = -1; + if (preflang && strlen(preflang)) { + /* Insert the language between the last two parts of the path */ + strncpy(tmp, filename, sizeof(tmp) - 1); + c = strrchr(tmp, '/'); + if (c) { + *c = '\0'; + postfix = c+1; + prefix = tmp; + } else { + postfix = tmp; + prefix=""; + } + snprintf(filename2, sizeof(filename2), "%s/%s/%s", prefix, preflang, postfix); + res = ast_filehelper(filename2, NULL, fmt, ACTION_EXISTS); + if (res < 1) { + char *stringp=NULL; + strncpy(lang2, preflang, sizeof(lang2)-1); + stringp=lang2; + strsep(&stringp, "_"); + if (strcmp(lang2, preflang)) { + snprintf(filename2, sizeof(filename2), "%s/%s/%s", prefix, lang2, postfix); + res = ast_filehelper(filename2, NULL, fmt, ACTION_EXISTS); + } + } + } + if (res < 1) { + res = ast_filehelper(filename, NULL, fmt, ACTION_EXISTS); + } + return res; +} + +int ast_filedelete(char *filename, char *fmt) +{ + return ast_filehelper(filename, NULL, fmt, ACTION_DELETE); +} + +int ast_filerename(char *filename, char *filename2, char *fmt) +{ + return ast_filehelper(filename, filename2, fmt, ACTION_RENAME); +} + +int ast_filecopy(char *filename, char *filename2, char *fmt) +{ + return ast_filehelper(filename, filename2, fmt, ACTION_COPY); +} + +int ast_streamfile(struct ast_channel *chan, char *filename, char *preflang) +{ + struct ast_filestream *fs; + + fs = ast_openstream(chan, filename, preflang); + if(fs){ + if(ast_applystream(chan, fs)) + return -1; + if(ast_playstream(fs)) + return -1; #if 1 if (option_verbose > 2) - ast_verbose(VERBOSE_PREFIX_3 "Playing '%s'\n", filename2); + ast_verbose(VERBOSE_PREFIX_3 "Playing '%s'\n", filename); #endif return 0; } @@ -457,7 +557,7 @@ int ast_streamfile(struct ast_channel *chan, char *filename, char *preflang) struct ast_filestream *ast_writefile(char *filename, char *type, char *comment, int flags, int check, mode_t mode) { - int fd; + int fd,myflags; struct ast_format *f; struct ast_filestream *fs=NULL; char *fn; @@ -466,14 +566,19 @@ struct ast_filestream *ast_writefile(char *filename, char *type, char *comment, ast_log(LOG_WARNING, "Unable to lock format list\n"); return NULL; } + myflags = 0; + /* set the O_TRUNC flag if and only if there is no O_APPEND specified */ + //if (!(flags & O_APPEND)) myflags = O_TRUNC; f = formats; while(f) { if (!strcasecmp(f->name, type)) { + char *stringp=NULL; /* XXX Implement check XXX */ ext = strdup(f->exts); - ext = strtok(ext, "|"); + stringp=ext; + ext = strsep(&stringp, "|"); fn = build_filename(filename, ext); - fd = open(fn, flags | O_WRONLY | O_CREAT, mode); + fd = open(fn, flags | myflags | O_WRONLY | O_CREAT, mode); if (fd >= 0) { errno = 0; if ((fs = f->rewrite(fd, comment))) { |