[asterisk-commits] qwell: branch group/ast_storage r66876 - in /team/group/ast_storage: include/...

asterisk-commits at lists.digium.com asterisk-commits at lists.digium.com
Fri Jun 1 09:35:23 MST 2007


Author: qwell
Date: Fri Jun  1 11:35:23 2007
New Revision: 66876

URL: http://svn.digium.com/view/asterisk?view=rev&rev=66876
Log:
A bunch of "fixes"..

Also, I didn't really like the way *_get()/*_put() is handled, so I thought about other ways to do it...
This is the first parts of that.  Let's actually return some useful information about multiple files,
 and let something else take care of choosing the right one, based on codec or whatever.
I think this ast_storage_fileinst struct will end up having a fd or something on it, so it can be read
 directly (or indirectly?) without requiring open()/close()/whatever() calls everywhere in the code.

In the put() call, we'll just pass in a similar filelist struct, and let it save them - we could have
 it do the transcoding there as well, just by passing it a single fileinst (or multiple...it can be
 flexible and choose the "best" transcoding path(s)) and a list of formats to make.

odbc is currently broken (hey, at least it compiles..) - will fix that once I get everything worked out

Modified:
    team/group/ast_storage/include/asterisk/file.h
    team/group/ast_storage/include/asterisk/storage.h
    team/group/ast_storage/main/file.c
    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/file.h
URL: http://svn.digium.com/view/asterisk/team/group/ast_storage/include/asterisk/file.h?view=diff&rev=66876&r1=66875&r2=66876
==============================================================================
--- team/group/ast_storage/include/asterisk/file.h (original)
+++ team/group/ast_storage/include/asterisk/file.h Fri Jun  1 11:35:23 2007
@@ -178,6 +178,10 @@
  */
 int ast_stopstream(struct ast_channel *c);
 
+int exts_compare(const char *exts, const char *type);
+
+int ast_getformatbyextension(const char *ext);
+
 /*! Checks for the existence of a given file */
 /*!
  * \param filename name of the file you wish to check, minus the extension

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=66876&r1=66875&r2=66876
==============================================================================
--- team/group/ast_storage/include/asterisk/storage.h (original)
+++ team/group/ast_storage/include/asterisk/storage.h Fri Jun  1 11:35:23 2007
@@ -37,7 +37,7 @@
 	const char *name;
 	struct ast_storage *(*create)(const char *uri);
 	int (*free)(struct ast_storage *st);
-	int (*get)(struct ast_storage *st, const char *objectname, const char *fileformats, char *localfile, size_t localfilesize);
+	struct ast_storage_filelist *(*get)(struct ast_storage *st, const char *objectname, const char *fileformats, char *localfile, size_t localfilesize);
 	int (*put)(struct ast_storage *st, const char *objectname, const char *fileformats, const char *localfile);
 	int (*del)(struct ast_storage *st, const char *objectname, const char *fileformats);
 	void *(*opendir)(struct ast_storage *st, const char *objectpath);
@@ -56,6 +56,26 @@
 struct ast_storage_dirent {
 	char name[256];
 	char format[10];
+};
+
+/* XXX How are we going to handle metadata about the file?
+ * Is there common metadata that we want/need to store?
+ * examples: duration, time created
+ */
+struct ast_storage_metadata {
+	time_t duration;
+	time_t created;
+};
+
+struct ast_storage_fileinst {
+	struct ast_storage_dirent *ent;
+	AST_RWLIST_ENTRY(ast_storage_fileinst) list;
+};
+
+struct ast_storage_filelist {
+	char name[256];
+	struct ast_storage_metadata *metadata;
+	AST_RWLIST_HEAD(, ast_storage_fileinst) files;
 };
 
 int __ast_register_storage(const struct ast_storage_be *e, struct ast_module *mod);
@@ -82,7 +102,7 @@
  * \param localfile Buffer in which to place the name of the resulting temporary file.
  * \param localfilesize Length of the above buffer
  */
-int ast_storage_get(struct ast_storage *st, const char *objectname, const char *fileformats, char *localfile, size_t localfilesize);
+struct ast_storage_filelist *ast_storage_get(struct ast_storage *st, const char *objectname, const char *fileformats, char *localfile, size_t localfilesize);
 
 /*! \brief Stores a file into the storage medium
  * \param st Storage instance

Modified: team/group/ast_storage/main/file.c
URL: http://svn.digium.com/view/asterisk/team/group/ast_storage/main/file.c?view=diff&rev=66876&r1=66875&r2=66876
==============================================================================
--- team/group/ast_storage/main/file.c (original)
+++ team/group/ast_storage/main/file.c Fri Jun  1 11:35:23 2007
@@ -264,7 +264,7 @@
 
 /* compare type against the list 'exts' */
 /* XXX need a better algorithm */
-static int exts_compare(const char *exts, const char *type)
+int exts_compare(const char *exts, const char *type)
 {
 	char tmp[256];
 	char *stringp = tmp, *ext;
@@ -276,6 +276,24 @@
 	}
 
 	return 0;
+}
+
+/*!
+ * \brief get the format number for a given extension
+ */
+int ast_getformatbyextension(const char *ext)
+{
+	struct ast_format *fmt;
+	if (!ext)
+		return 0;
+
+	AST_RWLIST_RDLOCK(&formats);
+	AST_RWLIST_TRAVERSE(&formats, fmt, list) {
+		if (exts_compare(fmt->exts, ext))
+			break;
+	}
+	AST_RWLIST_UNLOCK(&formats);
+	return fmt ? fmt->format : 0;
 }
 
 static struct ast_filestream *get_filestream(struct ast_format *fmt, FILE *bfile)

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=66876&r1=66875&r2=66876
==============================================================================
--- team/group/ast_storage/main/storage.c (original)
+++ team/group/ast_storage/main/storage.c Fri Jun  1 11:35:23 2007
@@ -23,12 +23,16 @@
  * \author Mark Spencer <markster at digium.com> 
  */
 
+#include <stdio.h>
+
 #include "asterisk.h"
 
 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 
 #include "asterisk/storage.h"
 #include "asterisk/cli.h"
+#include "asterisk/file.h"
+#include "asterisk/frame.h"
 #include "asterisk/options.h"
 #include "asterisk/linkedlists.h"
 #include "asterisk/module.h"
@@ -120,7 +124,7 @@
 
 	AST_RWLIST_TRAVERSE(&storage_engines, e, list) {
 		if (!strcasecmp(e->name, storage_type))
-			return e->create(uri);
+			return e->create(S_OR(uri, ""));
 	}
 	return NULL;
 }
@@ -130,9 +134,9 @@
 	return st && st->be->free ? st->be->free(st) : -1;
 }
 
-int ast_storage_get(struct ast_storage *st, const char *objectname, const char *fileformats, char *localfile, size_t localfilesize)
-{
-	return st->be->get ? st->be->get(st, objectname, fileformats, localfile, localfilesize) : -1;
+struct ast_storage_filelist *ast_storage_get(struct ast_storage *st, const char *objectname, const char *fileformats, char *localfile, size_t localfilesize)
+{
+	return st->be->get ? st->be->get(st, objectname, fileformats, localfile, localfilesize) : NULL;
 }
 
 int ast_storage_put(struct ast_storage *st, const char *objectname, const char *fileformats, const char *localfile)
@@ -182,6 +186,19 @@
 	return count;
 }
 
+static void destroy_filelist(struct ast_storage_filelist *fl)
+{
+	struct ast_storage_fileinst *fi;
+
+	AST_RWLIST_WRLOCK(&fl->files);
+	AST_RWLIST_TRAVERSE(&fl->files, fi, list) {
+		free(fi->ent);
+		free(fi);
+	}
+	AST_RWLIST_UNLOCK(&fl->files);
+	free(fl);
+}
+
 struct ast_storage_be *ast_storage_getbyname(const char *name)
 {
 	struct ast_storage_be *e;
@@ -196,6 +213,40 @@
 	}
 	AST_RWLIST_UNLOCK(&storage_engines);
 	return e;
+}
+
+static int storage_show_file(int fd, int argc, char *argv[])
+{
+	struct ast_storage *e;
+	struct ast_storage_filelist *fl;
+	struct ast_storage_fileinst *fi;
+	char tmp[256];
+	char *stringp = tmp;
+	char *sename;
+	int count_files = 0;
+	/* XXX We want to remove the need to pass in a char array like this now.. */
+	char blah[256];
+	if (argc != 4)
+		return RESULT_SHOWUSAGE;
+
+	stringp = ast_strdupa(argv[3]);
+	sename = strsep(&stringp, ":");
+
+	if ((e = ast_storage_request(sename, NULL))) {
+		ast_cli(fd, "File information\n");
+		/* We don't care about format here, so just send NULL */
+		if ((fl = ast_storage_get(e, stringp, NULL, blah, sizeof(blah)))) {
+			AST_RWLIST_TRAVERSE(&fl->files, fi, list) {
+				count_files++;
+				ast_cli(fd, "Format: %s\n", ast_getformatname(ast_getformatbyextension(fi->ent->format)));
+			}
+			destroy_filelist(fl);
+		}
+		ast_cli(fd, "\n");
+		ast_cli(fd, "Found %d matching file(s).\n", count_files);
+	} else
+		ast_cli(fd, "No storage engine named '%s' found.\n", sename);
+	return RESULT_SUCCESS;
 }
 
 static int show_storage_engines(int fd, int argc, char *argv[])
@@ -241,9 +292,8 @@
 			ast_cli(fd, "Additional status\n");
 			e->status((struct ast_storage *)e, fd);
 		}
-	} else {
+	} else
 		ast_cli(fd, "No storage engine named '%s' found.\n", argv[4]);
-	}
 	return RESULT_SUCCESS;
 }
 
@@ -266,6 +316,10 @@
 	return ret;
 }
 
+char storage_show_file_usage[] =
+"Usage: storage show file <engine:filename>\n"
+"       Displays information about a file via the storage engine\n";
+
 char show_storage_engines_usage[] = 
 "Usage: core show storage engines\n"
 "       Displays currently registered storage engines (if any)\n";
@@ -275,6 +329,10 @@
 "       Displays capabilities of requested storage engine\n";
 
 struct ast_cli_entry cli_storage[] = {
+	{ { "storage", "show", "file", NULL },
+	storage_show_file, "Displays information for a file",
+	storage_show_file_usage },
+
 	{ { "core", "show", "storage", "engines" },
 	show_storage_engines, "Displays storage engines",
 	show_storage_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=66876&r1=66875&r2=66876
==============================================================================
--- team/group/ast_storage/res/res_storage_file.c (original)
+++ team/group/ast_storage/res/res_storage_file.c Fri Jun  1 11:35:23 2007
@@ -27,15 +27,18 @@
 
 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 
-#include "asterisk/storage.h"
-#include "asterisk/module.h"
 #include <sys/types.h>
 #include <sys/stat.h>
+#include <stdio.h>
 #include <dirent.h>
 #include <fcntl.h>
 #include <unistd.h>
 #include <errno.h>
 
+#include "asterisk/storage.h"
+#include "asterisk/module.h"
+#include "asterisk/file.h"
+
 struct ast_storage_file {
 	const struct ast_storage_be *be;
 	char rootpath[128];
@@ -51,7 +54,7 @@
 static struct ast_storage *se_create_file(const char *uri)
 {
 	struct ast_storage_file *fst = ast_calloc(1, sizeof(struct ast_storage_file));
-	ast_copy_string(fst->rootpath, uri + 6, sizeof(fst->rootpath));
+	ast_copy_string(fst->rootpath, uri, sizeof(fst->rootpath));
 	fst->be = &file_se;
 	return ((struct ast_storage *)fst);
 }
@@ -62,36 +65,114 @@
 	return 0;
 }
 
-static int se_get_file(struct ast_storage *st, const char *objectname, const char *fileformats, char *localfile, size_t localfilesize)
-{
-	struct ast_storage_file *fst = (struct ast_storage_file *)st;
+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);
+
+	if ((dir->dir = opendir(dir->path)))
+		return dir;
+	else {
+		free(dir);
+		return NULL;
+	}
+}
+
+static int se_readdir_file(struct ast_storage *st, void *dirptr, struct ast_storage_dirent *dirent)
+{
+	struct dirent *f;
+	struct file_storage_dir *dir = dirptr;
+	char *fmt;
+
+	if (dirent == NULL)
+		return EINVAL;
+
+	memset(dirent, 0, sizeof(*dirent));
+
+	if ((f = readdir(dir->dir))) {
+		ast_copy_string(dirent->name, f->d_name, sizeof(dirent->name));
+		/* Parse out the file format */
+		if ((fmt = strrchr(dirent->name, '.'))) {
+			*fmt++ = '\0';
+			ast_copy_string(dirent->format, fmt, sizeof(dirent->format));
+		}
+		return 0;
+	}
+	return -1;
+}
+
+static int se_closedir_file(struct ast_storage *st, void *dirptr)
+{
+	struct file_storage_dir *dir = dirptr;
+	if (dir == NULL)
+		return EINVAL;
+	closedir(dir->dir);
+	free(dir);
+	return 0;
+}
+
+static struct ast_storage_filelist *se_get_file(struct ast_storage *st, const char *objectname, const char *fileformats, 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;
-	DIR *dir;
-	struct dirent *dirent;
-	int res = -1;
-
-	snprintf(localfile, localfilesize, "%s/%s", fst->rootpath, objectname);
-
-	/* Ensure the file exists. */
-	/* NOTE: while this is similar to a function already in main/file.c,
-	 * this has to remain coded here, because the version in file.c will
-	 * eventually depend upon this one. */
+
+	if (objectname[0] == '/')
+		ast_copy_string(localfile, objectname, localfilesize);
+	else
+		snprintf(localfile, localfilesize, "%s/%s", fst->rootpath, objectname);
+
 	ast_copy_string(dirname, localfile, sizeof(dirname));
 	dirnameptr = strrchr(dirname, '/');
 	if (dirnameptr)
 		*dirnameptr++ = '\0';
 	else
-		return -1;
-	dir = opendir(dirname);
-	while ((dirent = readdir(dir))) {
-		if (!strcmp(dirent->d_name, dirnameptr)) {
-			res = 0;
-			break;
-		}
-	}
-	closedir(dir);
-
-	return res;
+		return NULL;
+
+	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->format)) {
+				char fullfn[256];
+				snprintf(fullfn, sizeof(fullfn), "%s.%s", dirent->name, dirent->format);
+				/* If it's going to be an exact match, we don't care about fileformats */
+				if (!strcmp(fullfn, dirnameptr))
+					found = 1;
+			}
+			if (!found && !strcmp(dirent->name, dirnameptr)) {
+				if (ast_strlen_zero(dirent->format) || !fileformats || exts_compare(fileformats, dirent->format))
+					found = 1;
+			}
+
+			if (found) {
+				struct ast_storage_fileinst *fi;
+				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->format, dirent->format, sizeof(fi->ent->format));
+				AST_RWLIST_WRLOCK(&fl->files);
+				AST_RWLIST_INSERT_TAIL(&fl->files, fi, list);
+				AST_RWLIST_UNLOCK(&fl->files);
+			}
+		}
+		free(dirent);
+		se_closedir_file(st, dir);
+	} else {
+		free(fl);
+		return NULL;
+	}
+
+	return fl;
 }
 
 static int se_put_file(struct ast_storage *st, const char *objectname, const char *fileformats, const char *localfile)
@@ -149,56 +230,6 @@
 		snprintf(dest, sizeof(dest), "%s/%s", fst->rootpath, objectname);
 		return unlink(dest);
 	}
-}
-
-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);
-
-	if ((dir->dir = opendir(dir->path)))
-		return dir;
-	else {
-		free(dir);
-		return NULL;
-	}
-}
-
-static int se_readdir_file(struct ast_storage *st, void *dirptr, struct ast_storage_dirent *dirent)
-{
-	struct dirent *f;
-	struct file_storage_dir *dir = dirptr;
-	char *fmt;
-
-	if (dirent == NULL)
-		return EINVAL;
-
-	memset(dirent, 0, sizeof(*dirent));
-
-	if ((f = readdir(dir->dir))) {
-		/* Parse out the file format */
-		ast_copy_string(dirent->name, f->d_name, sizeof(dirent->name));
-		if ((fmt = strrchr(dirent->name, '.'))) {
-			*fmt++ = '\0';
-			ast_copy_string(dirent->format, fmt, sizeof(dirent->format));
-		}
-	}
-	return 0;
-}
-
-static int se_closedir_file(struct ast_storage *st, void *dirptr)
-{
-	struct file_storage_dir *dir = dirptr;
-	if (dir == NULL)
-		return EINVAL;
-	closedir(dir->dir);
-	free(dir);
-	return 0;
 }
 
 static const struct ast_storage_be file_se = {

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=66876&r1=66875&r2=66876
==============================================================================
--- team/group/ast_storage/res/res_storage_odbc.c (original)
+++ team/group/ast_storage/res/res_storage_odbc.c Fri Jun  1 11:35:23 2007
@@ -138,10 +138,12 @@
 	if (!ost)
 		return NULL;
 
+	if (ast_strlen_zero(uri))
+		return NULL;
+
 	AST_RWLIST_HEAD_INIT(&ost->columns);
 
-	/* odbc:// */
-	ast_copy_string(tmp, uri + 7, sizeof(tmp));
+	ast_copy_string(tmp, uri, sizeof(tmp));
 	AST_NONSTANDARD_APP_ARGS(args, tmp, '/');
 
 	ost->be = &odbc_se;
@@ -221,8 +223,9 @@
 	ast_copy_string(filename, filename2, filenamesize);
 }
 
-static int se_get_odbc(struct ast_storage *st, const char *objectname, const char *fileformats, char *localfile, size_t localfilesize)
-{
+static struct ast_storage_filelist *se_get_odbc(struct ast_storage *st, const char *objectname, const char *fileformats, char *localfile, size_t localfilesize)
+{
+	struct ast_storage_filelist *fl = NULL;
 	struct ast_storage_odbc *ost = (struct ast_storage_odbc *)st;
 	int res = -1, tempfd, x, gotten = 0;
 	char sql[128];
@@ -235,14 +238,14 @@
 	ast_copy_string(localfile, "/var/tmp/XXXXXX", localfilesize);
 	tempfd = mkstemp(localfile);
 	if (tempfd == -1)
-		return -1;
+		return NULL;
 
 	snprintf(reallocalfile, sizeof(reallocalfile), "%s.txt", localfile);
 	txt = fopen(reallocalfile, "w");
 	if (!txt) {
 		close(tempfd);
 		unlink(localfile);
-		return -1;
+		return NULL;
 	}
 
 	fprintf(txt, "[info]\n");
@@ -257,7 +260,7 @@
 		fclose(txt);
 		close(tempfd);
 		unlink(localfile);
-		return -1;
+		return NULL;
 	}
 
 	res = SQLPrepare(stmt, (unsigned char *)sql, SQL_NTS);
@@ -392,7 +395,7 @@
 	/* This is just the temp marker */
 	unlink(localfile);
 
-	return res ? -1 : 0;
+	return res ? NULL : fl;
 }
 
 static int se_put_odbc(struct ast_storage *st, const char *objectname, const char *fileformats, const char *localfile)



More information about the asterisk-commits mailing list