[svn-commits] qwell: branch group/ast_storage r79630 - in /team/group/ast_storage: include/...
SVN commits to the Digium repositories
svn-commits at lists.digium.com
Wed Aug 15 17:33:20 CDT 2007
Author: qwell
Date: Wed Aug 15 17:33:19 2007
New Revision: 79630
URL: http://svn.digium.com/view/asterisk?view=rev&rev=79630
Log:
Fix up API a bunch.
Fix odbc storage get function to return a file list.
"storage show file" CLI command actually works for file/odbc now.
Modified:
team/group/ast_storage/include/asterisk/storage.h
team/group/ast_storage/main/storage.c
team/group/ast_storage/res/res_storage_file.c
team/group/ast_storage/res/res_storage_odbc.c
Modified: team/group/ast_storage/include/asterisk/storage.h
URL: http://svn.digium.com/view/asterisk/team/group/ast_storage/include/asterisk/storage.h?view=diff&rev=79630&r1=79629&r2=79630
==============================================================================
--- team/group/ast_storage/include/asterisk/storage.h (original)
+++ team/group/ast_storage/include/asterisk/storage.h Wed Aug 15 17:33:19 2007
@@ -32,8 +32,7 @@
#endif
struct ast_storage_dirent {
- char name[256];
- char ext[10];
+ char name[PATH_MAX];
int fd;
};
@@ -59,7 +58,6 @@
struct ast_storage_be {
const char *name;
- struct ast_storage_filelist *fl;
struct ast_storage *(*create)(const char *uri);
int (*free)(struct ast_storage *st);
int (*get)(struct ast_storage *st, const char *objectname, const char *exts, char *localfile, size_t localfilesize);
@@ -82,7 +80,10 @@
/* Most specific backends will have longer structures */
struct ast_storage {
- struct ast_storage_be *be;
+ const struct ast_storage_be *be;
+ char path[PATH_MAX];
+ struct ast_storage_filelist *fl;
+ void **xst; /* Backend specific structure */
};
int __ast_register_storage(const struct ast_storage_be *e, struct ast_module *mod);
Modified: team/group/ast_storage/main/storage.c
URL: http://svn.digium.com/view/asterisk/team/group/ast_storage/main/storage.c?view=diff&rev=79630&r1=79629&r2=79630
==============================================================================
--- team/group/ast_storage/main/storage.c (original)
+++ team/group/ast_storage/main/storage.c Wed Aug 15 17:33:19 2007
@@ -47,9 +47,12 @@
static struct ast_storage *se_create_null(const char *uri)
{
+ struct ast_storage *st = ast_calloc(1, sizeof(struct ast_storage));
struct ast_storage_null *nst = ast_calloc(1, sizeof(struct ast_storage_null));
- nst->be = &null_se;
- return ((struct ast_storage *)nst);
+ st->xst = (void *)nst;
+ st->be = &null_se;
+ ast_copy_string(st->path, uri, sizeof(st->path));
+ return st;
}
static int se_free_null(struct ast_storage *st)
@@ -58,7 +61,7 @@
return 0;
}
-int __ast_register_storage(const struct ast_storage_be *e, struct ast_module *mod)
+int __ast_register_storage(const struct ast_storage_be *be, struct ast_module *mod)
{
struct ast_storage_be *tmp;
@@ -67,9 +70,9 @@
return -1;
}
AST_RWLIST_TRAVERSE(&storage_engines, tmp, list) {
- if (!strcasecmp(e->name, tmp->name)) {
+ if (!strcasecmp(be->name, tmp->name)) {
AST_RWLIST_UNLOCK(&storage_engines);
- ast_log(LOG_WARNING, "Tried to register storage engine '%s', already registered\n", e->name);
+ ast_log(LOG_WARNING, "Tried to register storage engine '%s', already registered\n", be->name);
return -1;
}
}
@@ -77,7 +80,7 @@
AST_RWLIST_UNLOCK(&storage_engines);
return -1;
}
- *tmp = *e;
+ *tmp = *be;
tmp->module = mod;
memset(&tmp->list, 0, sizeof(tmp->list));
@@ -85,7 +88,7 @@
AST_RWLIST_INSERT_TAIL(&storage_engines, tmp, list);
AST_RWLIST_UNLOCK(&storage_engines);
if (option_verbose > 1)
- ast_verbose(VERBOSE_PREFIX_2 "Registered storage engine '%s'\n", e->name);
+ ast_verbose(VERBOSE_PREFIX_2 "Registered storage engine '%s'\n", be->name);
return 0;
}
@@ -118,7 +121,7 @@
return res;
}
-static int destroy_filelist(struct ast_storage_filelist *fl)
+static int empty_filelist(struct ast_storage_filelist *fl)
{
struct ast_storage_fileinst *fi;
@@ -126,83 +129,97 @@
return 0;
AST_RWLIST_WRLOCK(&fl->files);
- AST_RWLIST_TRAVERSE(&fl->files, fi, list) {
+ AST_RWLIST_TRAVERSE_SAFE_BEGIN(&fl->files, fi, list) {
+ AST_RWLIST_REMOVE_CURRENT(&fl->files, list);
free(fi->ent);
free(fi);
}
+ AST_RWLIST_TRAVERSE_SAFE_END
AST_RWLIST_UNLOCK(&fl->files);
- free(fl);
return 0;
}
struct ast_storage_be *ast_storage_getbyname(const char *name)
{
- struct ast_storage_be *e;
+ struct ast_storage_be *be;
if (AST_RWLIST_RDLOCK(&storage_engines)) {
ast_log(LOG_WARNING, "Unable to lock storage engine list\n");
return NULL;
}
- AST_RWLIST_TRAVERSE(&storage_engines, e, list) {
- if (!strcasecmp(name, e->name))
+ AST_RWLIST_TRAVERSE(&storage_engines, be, list) {
+ if (!strcasecmp(name, be->name))
break;
}
AST_RWLIST_UNLOCK(&storage_engines);
- return e;
+ return be;
}
struct ast_storage *ast_storage_request(const char *storage_type, const char *uri)
{
- struct ast_storage_be *e;
-
- AST_RWLIST_TRAVERSE(&storage_engines, e, list) {
- if (!strcasecmp(e->name, storage_type))
- return e->create(S_OR(uri, ""));
+ struct ast_storage_be *be;
+ struct ast_storage *st = NULL;
+
+ AST_RWLIST_TRAVERSE(&storage_engines, be, list) {
+ if (!strcasecmp(be->name, storage_type)) {
+ if ((st = be->create(S_OR(uri, ""))))
+ st->fl = ast_calloc(1, sizeof(*st->fl));
+ return st;
+ }
}
return NULL;
}
int ast_storage_release(struct ast_storage *st)
{
- destroy_filelist(st->be->fl);
- return st && st->be->free ? st->be->free(st) : -1;
+ if (st) {
+ empty_filelist(st->fl);
+ free(st->fl);
+ return st->be->free ? st->be->free(st) : -1;
+ } else
+ return -1;
}
int ast_storage_get(struct ast_storage *st, const char *objectname, const char *exts, char *localfile, size_t localfilesize)
{
- return st->be->get ? st->be->get(st, objectname, exts, localfile, localfilesize) : -1;
+ if (st) {
+ /* Empty the file list first, just to be safe */
+ empty_filelist(st->fl);
+ return st->be->get ? st->be->get(st, objectname, exts, localfile, localfilesize) : -1;
+ } else
+ return -1;
}
#if 0
int ast_storage_put(struct ast_storage *st, struct ast_storage_filelist *fl, const char *exts)
{
- return st->be->put ? st->be->put(st, fl, exts) : -1;
+ return st && st->be->put ? st->be->put(st, fl, exts) : -1;
}
#endif
int ast_storage_open(struct ast_storage *st, struct ast_storage_fileinst *fi, int mode)
{
- return st->be->open ? st->be->open(st, fi, mode) : -1;
+ return st && st->be->open ? st->be->open(st, fi, mode) : -1;
}
int ast_storage_close(struct ast_storage *st, struct ast_storage_fileinst *fi)
{
- return st->be->close ? st->be->close(st, fi) : -1;
+ return st && st->be->close ? st->be->close(st, fi) : -1;
}
void *ast_storage_read(struct ast_storage *st, struct ast_storage_fileinst *fi, size_t chunksize)
{
- return st->be->read ? st->be->read(st, fi, chunksize) : NULL;
+ return st && st->be->read ? st->be->read(st, fi, chunksize) : NULL;
}
int ast_storage_write(struct ast_storage *st, struct ast_storage_fileinst *fi, void *data, size_t chunksize)
{
- return st->be->write ? st->be->write(st, fi, data, chunksize) : -1;
+ return st && st->be->write ? st->be->write(st, fi, data, chunksize) : -1;
}
int ast_storage_del(struct ast_storage *st, const char *exts)
{
- return st->be->del ? st->be->del(st, exts) : -1;
+ return st && st->be->del ? st->be->del(st, exts) : -1;
}
int ast_storage_copy(struct ast_storage *st, struct ast_storage_fileinst *from, struct ast_storage_fileinst *to)
@@ -251,7 +268,13 @@
return -1;
while (st->be->readdir(st, dirptr, &dirent) == 0) {
- if (strcmp(dirent.ext, "txt") == 0)
+ char *ext;
+
+ /* Parse out the file extension */
+ if ((ext = strrchr(dirent.name, '.'))) {
+ ext++;
+ }
+ if (strcmp(ext, "txt") == 0)
count++;
}
@@ -261,46 +284,59 @@
static int storage_show_file(int fd, int argc, char *argv[])
{
- struct ast_storage *e;
+ struct ast_storage *st;
struct ast_storage_fileinst *fi;
- char tmp[256];
+ char tmp[PATH_MAX];
char *stringp = tmp;
char *sename;
+ char *fn;
int count_files = 0;
/* XXX We want to remove the need to pass in a char array like this now.. */
- char blah[256];
+ char blah[PATH_MAX];
if (argc != 4)
return RESULT_SHOWUSAGE;
stringp = ast_strdupa(argv[3]);
- sename = strsep(&stringp, ":");
+ if ((fn = strstr(stringp, "://"))) {
+ *fn = '\0';
+ fn += 3;
+ }
+ sename = stringp;
if (!(ast_storage_getbyname(sename))) {
ast_cli(fd, "No storage engine named '%s' found.\n", sename);
return RESULT_SUCCESS;
}
- if (!(e = ast_storage_request(sename, stringp)))
+ if (!(st = ast_storage_request(sename, fn)))
ast_cli(fd, "Could not create storage engine named '%s'.\n", sename);
else {
ast_cli(fd, "File information\n");
/* We don't care about format/extension here, so just send NULL */
- if (!(ast_storage_get(e, stringp, NULL, blah, sizeof(blah)))) {
- AST_RWLIST_TRAVERSE(&e->be->fl->files, fi, list) {
+ if (!(ast_storage_get(st, st->path, NULL, blah, sizeof(blah)))) {
+ AST_RWLIST_TRAVERSE(&st->fl->files, fi, list) {
+ char *ext;
+
+ /* Parse out the file extension */
+ if ((ext = strrchr(fi->ent->name, '.'))) {
+ ext++;
+ }
+
count_files++;
- ast_cli(fd, "Name : '%s'\n", fi->ent->name);
- ast_cli(fd, "Format: '%s'\n", ast_getformatname(ast_getformatbyextension(fi->ent->ext)));
+ ast_cli(fd, "Name : %s\n", fi->ent->name);
+ ast_cli(fd, "Format: %s\n", ast_getformatname(ast_getformatbyextension(ext)));
}
}
ast_cli(fd, "\n");
ast_cli(fd, "Found %d matching file(s).\n", count_files);
}
+ ast_storage_release(st);
return RESULT_SUCCESS;
}
static int storage_show_engines(int fd, int argc, char *argv[])
{
- struct ast_storage_be *e;
+ struct ast_storage_be *be;
int count_se = 0;
if (argc != 3)
@@ -312,8 +348,8 @@
return RESULT_FAILURE;
}
- AST_RWLIST_TRAVERSE(&storage_engines, e, list) {
- ast_cli(fd, "%s\n", e->name);
+ AST_RWLIST_TRAVERSE(&storage_engines, be, list) {
+ ast_cli(fd, "%s\n", be->name);
count_se++;
}
AST_RWLIST_UNLOCK(&storage_engines);
@@ -323,25 +359,28 @@
static int storage_show_engine(int fd, int argc, char *argv[])
{
- struct ast_storage_be *e;
+ struct ast_storage_be *be;
if (argc != 4)
return RESULT_SHOWUSAGE;
- if ((e = ast_storage_getbyname(argv[3]))) {
- ast_cli(fd, "Storage Engine: %s\n", e->name);
- ast_cli(fd, "Can get : %s\n", e->get ? "yes" : "no");
+ if ((be = ast_storage_getbyname(argv[3]))) {
+ ast_cli(fd, "Storage Engine: %s\n", be->name);
+ ast_cli(fd, "Can get : %s\n", be->get ? "yes" : "no");
#if 0
- ast_cli(fd, "Can put : %s\n", e->put ? "yes" : "no");
+ ast_cli(fd, "Can put : %s\n", be->put ? "yes" : "no");
#endif
- ast_cli(fd, "Can del : %s\n", e->del ? "yes" : "no");
- ast_cli(fd, "Can opendir : %s\n", e->opendir ? "yes" : "no");
- ast_cli(fd, "Can readdir : %s\n", e->readdir ? "yes" : "no");
- ast_cli(fd, "Can closedir : %s\n", e->closedir ? "yes" : "no");
- if (e->status) {
+ ast_cli(fd, "Can del : %s\n", be->del ? "yes" : "no");
+ ast_cli(fd, "Can opendir : %s\n", be->opendir ? "yes" : "no");
+ ast_cli(fd, "Can readdir : %s\n", be->readdir ? "yes" : "no");
+ ast_cli(fd, "Can closedir : %s\n", be->closedir ? "yes" : "no");
+ if (be->status) {
ast_cli(fd, "\n");
ast_cli(fd, "Additional status\n");
- e->status((struct ast_storage *)e, fd);
+ /* XXX Need to rethink this.
+ * This requires a struct ast_storage *, and we can't cast to it from ast_storage_be
+ be->status((struct ast_storage *)be, fd);
+ */
}
} else
ast_cli(fd, "No storage engine named '%s' found.\n", argv[3]);
@@ -350,15 +389,15 @@
static char *complete_storage_show_engines(const char *line, const char *word, int pos, int state)
{
- struct ast_storage_be *e;
+ struct ast_storage_be *be;
char *ret = NULL;
int which = 0;
int wordlen = strlen(word);
AST_RWLIST_RDLOCK(&storage_engines);
- AST_RWLIST_TRAVERSE(&storage_engines, e, list) {
- if (!strncasecmp(word, e->name, wordlen) && ++which > state) {
- ret = strdup(e->name);
+ AST_RWLIST_TRAVERSE(&storage_engines, be, list) {
+ if (!strncasecmp(word, be->name, wordlen) && ++which > state) {
+ ret = strdup(be->name);
break;
}
}
@@ -368,7 +407,7 @@
}
char storage_show_file_usage[] =
-"Usage: storage show file <engine:filename>\n"
+"Usage: storage show file <engine://filename>\n"
" Displays information about a file via the storage engine\n";
char storage_show_engines_usage[] =
Modified: team/group/ast_storage/res/res_storage_file.c
URL: http://svn.digium.com/view/asterisk/team/group/ast_storage/res/res_storage_file.c?view=diff&rev=79630&r1=79629&r2=79630
==============================================================================
--- team/group/ast_storage/res/res_storage_file.c (original)
+++ team/group/ast_storage/res/res_storage_file.c Wed Aug 15 17:33:19 2007
@@ -40,42 +40,42 @@
#include "asterisk/file.h"
struct ast_storage_file {
- const struct ast_storage_be *be;
- char rootpath[128];
+ /* Nothing here */
};
struct file_storage_dir {
DIR *dir;
- char path[256];
+ char path[PATH_MAX];
};
static const struct ast_storage_be file_se;
static struct ast_storage *se_create_file(const char *uri)
{
+ struct ast_storage *st = ast_calloc(1, sizeof(struct ast_storage));
struct ast_storage_file *fst = ast_calloc(1, sizeof(struct ast_storage_file));
- struct ast_storage_filelist *fl = ast_calloc(1, sizeof(struct ast_storage_filelist));
- ast_copy_string(fst->rootpath, uri, sizeof(fst->rootpath));
- fst->be = &file_se;
- ((struct ast_storage_be *)fst->be)->fl = fl;
- return ((struct ast_storage *)fst);
+ st->xst = (void *)fst;
+ st->be = &file_se;
+ ast_copy_string(st->path, uri, sizeof(st->path));
+ return st;
}
static int se_free_file(struct ast_storage *st)
{
+ if (st->xst)
+ free(st->xst);
free(st);
return 0;
}
static void *se_opendir_file(struct ast_storage *st, const char *objectpath)
{
- struct ast_storage_file *fst = (struct ast_storage_file *)st;
struct file_storage_dir *dir = ast_calloc(1, sizeof(*dir));
if (objectpath[0] == '/')
ast_copy_string(dir->path, objectpath, sizeof(dir->path));
else
- snprintf(dir->path, sizeof(dir->path), "%s/%s", fst->rootpath, objectpath);
+ snprintf(dir->path, sizeof(dir->path), "%s/%s", st->path, objectpath);
if ((dir->dir = opendir(dir->path)))
return dir;
@@ -89,7 +89,6 @@
{
struct dirent *f;
struct file_storage_dir *dir = dirptr;
- char *ext;
if (dirent == NULL)
return EINVAL;
@@ -98,11 +97,6 @@
if ((f = readdir(dir->dir))) {
ast_copy_string(dirent->name, f->d_name, sizeof(dirent->name));
- /* Parse out the file extension */
- if ((ext = strrchr(dirent->name, '.'))) {
- *ext++ = '\0';
- ast_copy_string(dirent->ext, ext, sizeof(dirent->ext));
- }
return 0;
}
return -1;
@@ -147,11 +141,10 @@
static int se_get_file(struct ast_storage *st, const char *objectname, const char *exts, char *localfile, size_t localfilesize)
{
- struct ast_storage_filelist *fl = NULL;
- struct ast_storage_file *fst = (struct ast_storage_file *)st;
struct file_storage_dir *dir;
struct ast_storage_dirent *dirent;
- char dirname[256], *dirnameptr;
+ struct stat statbuf;
+ char dirname[PATH_MAX], *dirnameptr;
if (ast_strlen_zero(objectname))
return -1;
@@ -159,7 +152,7 @@
if (objectname[0] == '/')
ast_copy_string(localfile, objectname, localfilesize);
else
- snprintf(localfile, localfilesize, "%s/%s", fst->rootpath, objectname);
+ snprintf(localfile, localfilesize, "%s/%s", st->path, objectname);
ast_copy_string(dirname, localfile, sizeof(dirname));
dirnameptr = strrchr(dirname, '/');
@@ -168,22 +161,37 @@
else
return -1;
- fl = ast_calloc(1, sizeof(*fl));
-
if ((dir = se_opendir_file(st, dirname))) {
dirent = ast_calloc(1, sizeof(*dirent));
while ((!se_readdir_file(st, dir, dirent))) {
int found = 0;
-
- if (!ast_strlen_zero(dirent->ext)) {
- char fullfn[256];
- snprintf(fullfn, sizeof(fullfn), "%s.%s", dirent->name, dirent->ext);
+ char *fn = ast_strdupa(dirent->name);
+ char fullfn[PATH_MAX];
+ char *ext = NULL;
+
+ /* Parse out the file extension */
+ if ((ext = strrchr(fn, '.'))) {
+ *ext++ = '\0';
+ }
+
+ if (ext && !strcmp(ext, "txt"))
+ continue;
+
+ snprintf(fullfn, sizeof(fullfn), "%s/%s", dirname, dirent->name);
+
+ if (stat(fullfn, &statbuf))
+ continue;
+
+ if (!S_ISREG(statbuf.st_mode))
+ continue;
+
+ if (!ast_strlen_zero(ext)) {
/* If it's going to be an exact match, we don't care about exts */
- if (!strcmp(fullfn, dirnameptr))
+ if (!strcmp(dirent->name, dirnameptr))
found = 1;
}
- if (!found && !strcmp(dirent->name, dirnameptr)) {
- if (ast_strlen_zero(dirent->ext) || !exts || ast_exts_compare(exts, dirent->ext))
+ if (!found && !strcmp(fn, dirnameptr)) {
+ if (ast_strlen_zero(ext) || !exts || ast_exts_compare(exts, ext))
found = 1;
}
@@ -192,35 +200,32 @@
fi = ast_calloc(1, sizeof(*fi));
fi->ent = ast_calloc(1, sizeof(struct ast_storage_dirent));
ast_copy_string(fi->ent->name, dirent->name, sizeof(fi->ent->name));
- ast_copy_string(fi->ent->ext, dirent->ext, sizeof(fi->ent->ext));
- AST_RWLIST_WRLOCK(&fl->files);
- AST_RWLIST_INSERT_TAIL(&fl->files, fi, list);
- AST_RWLIST_UNLOCK(&fl->files);
+ AST_RWLIST_WRLOCK(&st->fl->files);
+ AST_RWLIST_INSERT_TAIL(&st->fl->files, fi, list);
+ AST_RWLIST_UNLOCK(&st->fl->files);
}
}
free(dirent);
se_closedir_file(st, dir);
} else {
- free(fl);
- return -1;
- }
-
- st->be->fl = fl;
+ return -1;
+ }
+
return 0;
}
#if 0
static int se_put_file(struct ast_storage *st, struct ast_storage_filelist *fl, const char *exts)
{
- struct ast_storage_file *fst = (struct ast_storage_file *)st;
+ struct ast_storage_file *fst = (struct ast_storage_file *)st->xst;
int ifd;
int ofd;
int res = 0;
int len = 0;
- char dest[256];
+ char dest[PATH_MAX];
char buf[4096];
- snprintf(dest, sizeof(dest), "%s/%s", fst->rootpath, fl->name);
+ snprintf(dest, sizeof(dest), "%s/%s", st->path, fl->name);
/* XXX We aren't going to read() directly from the filesystem for put()s.
if ((ifd = open(localfile, O_RDONLY)) < 0) {
@@ -261,13 +266,12 @@
static int se_del_file(struct ast_storage *st, const char *exts)
{
- struct ast_storage_file *fst = (struct ast_storage_file *)st;
- char dest[256];
-
- if (st->be->fl->name[0] == '/')
- return unlink(st->be->fl->name);
+ char dest[PATH_MAX];
+
+ if (st->fl->name[0] == '/')
+ return unlink(st->fl->name);
else {
- snprintf(dest, sizeof(dest), "%s/%s", fst->rootpath, st->be->fl->name);
+ snprintf(dest, sizeof(dest), "%s/%s", st->path, st->fl->name);
return unlink(dest);
}
}
Modified: team/group/ast_storage/res/res_storage_odbc.c
URL: http://svn.digium.com/view/asterisk/team/group/ast_storage/res/res_storage_odbc.c?view=diff&rev=79630&r1=79629&r2=79630
==============================================================================
--- team/group/ast_storage/res/res_storage_odbc.c (original)
+++ team/group/ast_storage/res/res_storage_odbc.c Wed Aug 15 17:33:19 2007
@@ -59,10 +59,8 @@
};
struct ast_storage_odbc {
- const struct ast_storage_be *be;
char odbc_class[128];
char tablename[128];
- char pathname[128];
struct odbc_obj *conn;
AST_RWLIST_HEAD(odbc_columns, columns) columns;
};
@@ -115,9 +113,11 @@
static int se_free_odbc(struct ast_storage *st)
{
- struct ast_storage_odbc *ost = (struct ast_storage_odbc *)st;
- ast_odbc_release_obj(ost->conn);
- free(ost);
+ if (((struct ast_storage_odbc *)st->xst)->conn)
+ ast_odbc_release_obj(((struct ast_storage_odbc *)st->xst)->conn);
+ if (st->xst)
+ free(st->xst);
+ free(st);
return 0;
}
@@ -125,7 +125,8 @@
{
char tmp[256], columnname[80];
int res;
- struct ast_storage_odbc *ost = ast_calloc(1, sizeof(struct ast_storage_odbc));
+ struct ast_storage *st = ast_calloc(1, sizeof(struct ast_storage));
+ struct ast_storage_odbc *ost;
struct columns *entry;
AST_DECLARE_APP_ARGS(args,
AST_APP_ARG(class);
@@ -135,33 +136,39 @@
SQLHSTMT stmt = NULL;
SQLLEN sqlptr;
- if (!ost)
+ if (!st) {
+ se_free_odbc(st);
return NULL;
-
- if (ast_strlen_zero(uri))
+ }
+
+ if (ast_strlen_zero(uri)) {
+ se_free_odbc(st);
return NULL;
+ }
+
+ ost = ast_calloc(1, sizeof(struct ast_storage_odbc));
+ st->xst = (void *)ost;
+ st->be = &odbc_se;
+ ast_copy_string(tmp, uri, sizeof(tmp));
AST_RWLIST_HEAD_INIT(&ost->columns);
- ast_copy_string(tmp, uri, sizeof(tmp));
AST_NONSTANDARD_APP_ARGS(args, tmp, '/');
- ost->be = &odbc_se;
ast_copy_string(ost->odbc_class, args.class, sizeof(ost->odbc_class));
ast_copy_string(ost->tablename, args.tablename, sizeof(ost->tablename));
- ast_copy_string(ost->pathname, args.pathname, sizeof(ost->pathname));
+ ast_copy_string(st->path, args.pathname, sizeof(st->path));
ost->conn = ast_odbc_request_obj(ost->odbc_class, 0);
if (!ost->conn) {
- free(ost);
+ se_free_odbc(st);
return NULL;
}
res = SQLAllocHandle(SQL_HANDLE_STMT, ost->conn->con, &stmt);
if (res != SQL_SUCCESS && res != SQL_SUCCESS_WITH_INFO) {
ast_log(LOG_ERROR, "Allocation of database handle failed.\n");
- ast_odbc_release_obj(ost->conn);
- free(ost);
+ se_free_odbc(st);
return NULL;
}
@@ -169,8 +176,7 @@
res = SQLColumns(stmt, NULL, 0, NULL, 0, (unsigned char *)ost->tablename, SQL_NTS, (unsigned char *)"%", SQL_NTS);
if (res != SQL_SUCCESS && res != SQL_SUCCESS_WITH_INFO) {
ast_log(LOG_ERROR, "Unable to query database columns on table '%s@%s'. Storage method fails.\n", ost->tablename, ost->odbc_class);
- ast_odbc_release_obj(ost->conn);
- free(ost);
+ se_free_odbc(st);
return NULL;
}
@@ -179,7 +185,7 @@
entry = ast_calloc(sizeof(char), sizeof(*entry) + strlen(columnname) + 1);
if (!entry) {
ast_log(LOG_ERROR, "Unable to allocate column entry\n");
- se_free_odbc((struct ast_storage *)ost);
+ se_free_odbc(st);
return NULL;
}
@@ -196,7 +202,7 @@
AST_LIST_INSERT_TAIL(&ost->columns, entry, list);
}
- return ((struct ast_storage *)ost);
+ return st;
}
static void get_path_file(struct ast_storage_odbc *ost, const char *objectname, char *pathname, size_t pathnamesize, char *filename, size_t filenamesize)
@@ -213,12 +219,12 @@
/* Absolute or relative path? */
if (tmp[0] == '/')
- ast_copy_string(pathname, tmp, sizeof(pathname));
+ ast_copy_string(pathname, tmp, pathnamesize);
else
- snprintf(pathname, sizeof(pathname), "%s/%s", ost->pathname, tmp);
+ snprintf(pathname, pathnamesize, "%s/%s", ((struct ast_storage *)ost)->path, tmp);
}
} else {
- ast_copy_string(pathname, ost->pathname, sizeof(pathname));
+ ast_copy_string(pathname, ((struct ast_storage *)ost)->path, pathnamesize);
filename2 = tmp;
}
ast_copy_string(filename, filename2, filenamesize);
@@ -226,12 +232,12 @@
static int se_get_odbc(struct ast_storage *st, const char *objectname, const char *exts, char *localfile, size_t localfilesize)
{
- struct ast_storage_filelist *fl = NULL;
- struct ast_storage_odbc *ost = (struct ast_storage_odbc *)st;
+ struct ast_storage_odbc *ost = (struct ast_storage_odbc *)st->xst;
int res = -1, tempfd, x, gotten = 0;
char sql[128];
char pathname[256], filename[256], reallocalfile[256];
char ext[10], rowdata[256], coltitle[128];
+ char *fext = NULL;
SQLHSTMT stmt;
SQLSMALLINT colcount, collen, datatype;
FILE *txt;
@@ -256,7 +262,15 @@
get_path_file(ost, objectname, pathname, sizeof(pathname), filename, sizeof(filename));
- snprintf(sql, sizeof(sql), "SELECT * FROM %s WHERE pathname=? AND filename=?", ost->tablename);
+ /* Parse out the file extension */
+ if ((fext = strrchr(filename, '.'))) {
+ *fext++ = '\0';
+ }
+
+ if (fext)
+ snprintf(sql, sizeof(sql), "SELECT * FROM %s WHERE pathname=? AND filename=? AND extension=?", ost->tablename);
+ else
+ snprintf(sql, sizeof(sql), "SELECT * FROM %s WHERE pathname=? AND filename=?", ost->tablename);
res = SQLAllocHandle(SQL_HANDLE_STMT, ost->conn->con, &stmt);
if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
@@ -275,6 +289,8 @@
SQLBindParameter(stmt, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, strlen(pathname), 0, (void *)pathname, 0, NULL);
SQLBindParameter(stmt, 2, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, strlen(filename), 0, (void *)filename, 0, NULL);
+ if (fext)
+ SQLBindParameter(stmt, 3, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, strlen(fext), 0, (void *)fext, 0, NULL);
res = ast_odbc_smart_execute(ost->conn, stmt);
if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
@@ -283,6 +299,8 @@
}
while ((res = SQLFetch(stmt)) != SQL_NO_DATA) {
+ struct ast_storage_fileinst *fi;
+ int createdest = 0;
if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
ast_log(LOG_WARNING, "SQL Fetch error!\n[%s]\n", sql);
goto endget;
@@ -316,7 +334,7 @@
void *fdm = NULL;
SQLLEN colsize2;
- if (!ast_strlen_zero(ext)) {
+ if (createdest && !ast_strlen_zero(ext)) {
/* We have an extension, just go ahead and create the destination */
snprintf(reallocalfile, sizeof(reallocalfile), "%s.%s", localfile, ext);
fd = open(reallocalfile, O_CREAT | O_WRONLY | O_EXCL);
@@ -375,6 +393,7 @@
goto endget;
}
if (!strcasecmp(coltitle, "extension")) {
+ ast_copy_string(ext, rowdata, sizeof(ext));
/* Is there a recording waiting for us? */
if (lseek(tempfd, 0, SEEK_CUR) > 0) {
snprintf(reallocalfile, sizeof(reallocalfile), "%s.%s", localfile, rowdata);
@@ -382,13 +401,22 @@
lseek(tempfd, 0, SEEK_SET);
truncate(localfile, 0);
} else
- ast_copy_string(ext, rowdata, sizeof(ext));
+ createdest = 1;
} else if (strcasecmp(coltitle, "filename") && strcasecmp(coltitle, "pathname") && !ast_strlen_zero(rowdata) && !gotten)
fprintf(txt, "%s=%s\n", coltitle, rowdata);
}
if (fd > -1 && fd != tempfd)
close(fd);
}
+ fi = ast_calloc(1, sizeof(*fi));
+ fi->ent = ast_calloc(1, sizeof(struct ast_storage_dirent));
+ if (!ast_strlen_zero(ext))
+ snprintf(fi->ent->name, sizeof(fi->ent->name), "%s.%s", filename, ext);
+ else
+ ast_copy_string(fi->ent->name, filename, sizeof(fi->ent->name));
+ AST_RWLIST_WRLOCK(&st->fl->files);
+ AST_RWLIST_INSERT_TAIL(&st->fl->files, fi, list);
+ AST_RWLIST_UNLOCK(&st->fl->files);
gotten = 1;
}
res = 0;
@@ -399,14 +427,13 @@
/* This is just the temp marker */
unlink(localfile);
- st->be->fl = res ? NULL : fl;
return res;
}
#if 0
static int se_put_odbc(struct ast_storage *st, struct ast_storage_filelist *fl, const char *exts)
{
- struct ast_storage_odbc *ost = (struct ast_storage_odbc *)st;
+ struct ast_storage_odbc *ost = (struct ast_storage_odbc *)st->xst;
int res = -1, x;
struct ast_config *cfg;
struct ast_variable *cfgvar, *var;
@@ -540,11 +567,11 @@
static int se_del_odbc(struct ast_storage *st, const char *exts)
{
char pathname[256], filename[256], sql[256];
- struct ast_storage_odbc *ost = (struct ast_storage_odbc *)st;
+ struct ast_storage_odbc *ost = (struct ast_storage_odbc *)st->xst;
int res;
SQLHSTMT sth;
- get_path_file(ost, st->be->fl->name, pathname, sizeof(pathname), filename, sizeof(filename));
+ get_path_file(ost, st->fl->name, pathname, sizeof(pathname), filename, sizeof(filename));
snprintf(sql, sizeof(sql), "DELETE FROM %s WHERE pathname=? AND filename=?", ost->tablename);
@@ -616,7 +643,7 @@
static int se_status_odbc(struct ast_storage *st, int fd)
{
- struct ast_storage_odbc *ost = (struct ast_storage_odbc *)st;
+ struct ast_storage_odbc *ost = (struct ast_storage_odbc *)st->xst;
ast_cli(fd, "Connected: %s\n", (ost && ost->conn && ost->conn->up) ? "yes" : "no");
return 0;
}
More information about the svn-commits
mailing list