#include <asterisk/sched.h>
#include <asterisk/options.h>
#include <asterisk/translate.h>
+#include <asterisk/utils.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
struct ast_channel *owner;
};
-static pthread_mutex_t formatlock = AST_MUTEX_INITIALIZER;
+AST_MUTEX_DEFINE_STATIC(formatlock);
static struct ast_format *formats = NULL;
char * (*getcomment)(struct ast_filestream *))
{
struct ast_format *tmp;
- if (ast_pthread_mutex_lock(&formatlock)) {
+ if (ast_mutex_lock(&formatlock)) {
ast_log(LOG_WARNING, "Unable to lock format list\n");
return -1;
}
tmp = formats;
while(tmp) {
if (!strcasecmp(name, tmp->name)) {
- ast_pthread_mutex_unlock(&formatlock);
+ ast_mutex_unlock(&formatlock);
ast_log(LOG_WARNING, "Tried to register '%s' format, already registered\n", name);
return -1;
}
tmp = malloc(sizeof(struct ast_format));
if (!tmp) {
ast_log(LOG_WARNING, "Out of memory\n");
- ast_pthread_mutex_unlock(&formatlock);
+ ast_mutex_unlock(&formatlock);
return -1;
}
strncpy(tmp->name, name, sizeof(tmp->name)-1);
tmp->getcomment = getcomment;
tmp->next = formats;
formats = tmp;
- ast_pthread_mutex_unlock(&formatlock);
+ ast_mutex_unlock(&formatlock);
if (option_verbose > 1)
ast_verbose( VERBOSE_PREFIX_2 "Registered file format %s, extension(s) %s\n", name, exts);
return 0;
int ast_format_unregister(char *name)
{
struct ast_format *tmp, *tmpl = NULL;
- if (ast_pthread_mutex_lock(&formatlock)) {
+ if (ast_mutex_lock(&formatlock)) {
ast_log(LOG_WARNING, "Unable to lock format list\n");
return -1;
}
else
formats = tmp->next;
free(tmp);
- ast_pthread_mutex_unlock(&formatlock);
+ ast_mutex_unlock(&formatlock);
if (option_verbose > 1)
ast_verbose( VERBOSE_PREFIX_2 "Unregistered format %s\n", name);
return 0;
}
+ tmpl = tmp;
tmp = tmp->next;
}
ast_log(LOG_WARNING, "Tried to unregister format %s, already unregistered\n", name);
if (!fs->trans)
fs->trans = ast_translator_build_path(fs->fmt->format, f->subclass);
if (!fs->trans)
- ast_log(LOG_WARNING, "Unable to translate to format %s, source format %d\n", fs->fmt->name, f->subclass);
+ ast_log(LOG_WARNING, "Unable to translate to format %s, source format %s\n", fs->fmt->name, ast_getformatname(f->subclass));
else {
fs->lastwriteformat = f->subclass;
res = 0;
static char *build_filename(char *filename, char *ext)
{
char *fn;
- char tmp[AST_CONFIG_MAX_PATH];
+ char tmp[AST_CONFIG_MAX_PATH]="";
snprintf(tmp,sizeof(tmp)-1,"%s/%s",(char *)ast_config_AST_VAR_DIR,"sounds");
fn = malloc(strlen(tmp) + strlen(filename) + strlen(ext) + 10);
if (fn) {
}
+static int exts_compare(char *exts, char *type)
+{
+ char *stringp = NULL, *ext;
+ char tmp[256];
+
+ strncpy(tmp, exts, sizeof(tmp) - 1);
+ stringp = tmp;
+ while ((ext = strsep(&stringp, "|"))) {
+ if (!strcmp(ext, type)) {
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
#define ACTION_EXISTS 1
#define ACTION_DELETE 2
#define ACTION_RENAME 3
if (action == ACTION_OPEN)
ret = -1;
/* Check for a specific format */
- if (ast_pthread_mutex_lock(&formatlock)) {
+ if (ast_mutex_lock(&formatlock)) {
ast_log(LOG_WARNING, "Unable to lock format list\n");
if (action == ACTION_EXISTS)
return 0;
}
f = formats;
while(f) {
- if (!fmt || !strcasecmp(f->name, fmt)) {
+ if (!fmt || exts_compare(f->exts, fmt)) {
char *stringp=NULL;
exts = strdup(f->exts);
/* Try each kind of extension */
chan->vstream = s;
} else {
close(ret);
- ast_log(LOG_WARNING, "Unable to open fd on %s\n", filename);
+ ast_log(LOG_WARNING, "Unable to open fd on %s\n", fn);
}
} else
ast_log(LOG_WARNING, "Couldn't open file %s\n", fn);
}
f = f->next;
}
- ast_pthread_mutex_unlock(&formatlock);
+ ast_mutex_unlock(&formatlock);
if ((action == ACTION_EXISTS) || (action == ACTION_OPEN))
res = ret ? ret : -1;
return res;
*/
int fd = -1;
int fmts = -1;
- char filename2[256];
- char lang2[MAX_LANGUAGE];
+ char filename2[256]="";
+ char filename3[256]="";
+ char *endpart;
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", preflang, filename);
+ if (preflang && !ast_strlen_zero(preflang)) {
+ strncpy(filename3, filename, sizeof(filename3) - 1);
+ endpart = strrchr(filename3, '/');
+ if (endpart) {
+ *endpart = '\0';
+ endpart++;
+ snprintf(filename2, sizeof(filename2), "%s/%s/%s", filename3, preflang, endpart);
+ } else
+ snprintf(filename2, sizeof(filename2), "%s/%s", preflang, filename);
fmts = ast_fileexists(filename2, NULL, NULL);
- if (fmts < 1) {
- strncpy(lang2, preflang, sizeof(lang2)-1);
- snprintf(filename2, sizeof(filename2), "%s/%s", lang2, filename);
- fmts = ast_fileexists(filename2, NULL, NULL);
- }
}
if (fmts < 1) {
strncpy(filename2, filename, sizeof(filename2)-1);
char lang2[MAX_LANGUAGE];
/* XXX H.263 only XXX */
char *fmt = "h263";
- if (preflang && strlen(preflang)) {
+ if (preflang && !ast_strlen_zero(preflang)) {
snprintf(filename2, sizeof(filename2), "%s/%s", preflang, filename);
fmts = ast_fileexists(filename2, fmt, NULL);
if (fmts < 1) {
return NULL;
}
+struct ast_frame *ast_readframe(struct ast_filestream *s)
+{
+ struct ast_frame *f = NULL;
+ int whennext = 0;
+ if (s && s->fmt)
+ f = s->fmt->read(s, &whennext);
+ return f;
+}
+
static int ast_readaudio_callback(void *data)
{
struct ast_filestream *s = data;
}
if (whennext != s->lasttimeout) {
#ifdef ZAPTEL_OPTIMIZATIONS
- if (s->timingfd > -1)
+ if (s->owner->timingfd > -1)
ast_settimeout(s->owner, whennext, ast_readaudio_callback, s);
else
-#else
- s->owner->streamid = ast_sched_add(s->owner->sched, whennext/8, ast_readaudio_callback, s);
#endif
+ s->owner->streamid = ast_sched_add(s->owner->sched, whennext/8, ast_readaudio_callback, s);
s->lasttimeout = whennext;
return 0;
}
f->owner->vstreamid = -1;
}
}
+ /* destroy the translator on exit */
+ if (f->trans) {
+ ast_translator_free_path(f->trans);
+ f->trans = NULL;
+ }
if (f->filename)
free(f->filename);
f->filename = NULL;
char *c;
char lang2[MAX_LANGUAGE];
int res = -1;
- if (preflang && strlen(preflang)) {
+ if (preflang && !ast_strlen_zero(preflang)) {
/* Insert the language between the last two parts of the path */
strncpy(tmp, filename, sizeof(tmp) - 1);
c = strrchr(tmp, '/');
return -1;
#if 1
if (option_verbose > 2)
- ast_verbose(VERBOSE_PREFIX_3 "Playing '%s'\n", filename);
+ ast_verbose(VERBOSE_PREFIX_3 "Playing '%s' (language '%s')\n", filename, preflang ? preflang : "default");
#endif
return 0;
}
- ast_log(LOG_WARNING, "Unable to open %s (format %d): %s\n", filename, chan->nativeformats, strerror(errno));
+ ast_log(LOG_WARNING, "Unable to open %s (format %s): %s\n", filename, ast_getformatname(chan->nativeformats), strerror(errno));
return -1;
}
+struct ast_filestream *ast_readfile(char *filename, char *type, char *comment, int flags, int check, mode_t mode)
+{
+ int fd,myflags = 0;
+ struct ast_format *f;
+ struct ast_filestream *fs=NULL;
+ char *fn;
+ char *ext;
+ if (ast_mutex_lock(&formatlock)) {
+ ast_log(LOG_WARNING, "Unable to lock format list\n");
+ return NULL;
+ }
+ f = formats;
+ while(f) {
+ if (exts_compare(f->exts, type)) {
+ char *stringp=NULL;
+ /* XXX Implement check XXX */
+ ext = strdup(f->exts);
+ stringp=ext;
+ ext = strsep(&stringp, "|");
+ fn = build_filename(filename, ext);
+ fd = open(fn, flags | myflags);
+ if (fd >= 0) {
+ errno = 0;
+ if ((fs = f->open(fd))) {
+ fs->trans = NULL;
+ fs->fmt = f;
+ fs->flags = flags;
+ fs->mode = mode;
+ fs->filename = strdup(filename);
+ fs->vfs = NULL;
+ } else {
+ ast_log(LOG_WARNING, "Unable to open %s\n", fn);
+ close(fd);
+ unlink(fn);
+ }
+ } else if (errno != EEXIST)
+ ast_log(LOG_WARNING, "Unable to open file %s: %s\n", fn, strerror(errno));
+ free(fn);
+ free(ext);
+ break;
+ }
+ f = f->next;
+ }
+ ast_mutex_unlock(&formatlock);
+ if (!f)
+ ast_log(LOG_WARNING, "No such format '%s'\n", type);
+ return fs;
+}
struct ast_filestream *ast_writefile(char *filename, char *type, char *comment, int flags, int check, mode_t mode)
{
- int fd,myflags;
+ int fd,myflags = 0;
struct ast_format *f;
struct ast_filestream *fs=NULL;
char *fn;
char *ext;
- if (ast_pthread_mutex_lock(&formatlock)) {
+ if (ast_mutex_lock(&formatlock)) {
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;
+ if (!(flags & O_APPEND))
+ myflags = O_TRUNC;
+
+ myflags |= O_WRONLY | O_CREAT;
+
f = formats;
while(f) {
- if (!strcasecmp(f->name, type)) {
+ if (exts_compare(f->exts, type)) {
char *stringp=NULL;
/* XXX Implement check XXX */
ext = strdup(f->exts);
stringp=ext;
ext = strsep(&stringp, "|");
fn = build_filename(filename, ext);
- fd = open(fn, flags | myflags | O_WRONLY | O_CREAT, mode);
+ fd = open(fn, flags | myflags, mode);
if (fd >= 0) {
errno = 0;
if ((fs = f->rewrite(fd, comment))) {
}
f = f->next;
}
- ast_pthread_mutex_unlock(&formatlock);
+ ast_mutex_unlock(&formatlock);
if (!f)
ast_log(LOG_WARNING, "No such format '%s'\n", type);
return fs;