[asterisk-commits] tilghman: branch group/ast_storage r48342 - in
/team/group/ast_storage: inclu...
asterisk-commits at lists.digium.com
asterisk-commits at lists.digium.com
Wed Dec 6 17:55:46 MST 2006
Author: tilghman
Date: Wed Dec 6 18:55:45 2006
New Revision: 48342
URL: http://svn.digium.com/view/asterisk?view=rev&rev=48342
Log:
Add directory reading APIs
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=48342&r1=48341&r2=48342
==============================================================================
--- team/group/ast_storage/include/asterisk/storage.h (original)
+++ team/group/ast_storage/include/asterisk/storage.h Wed Dec 6 18:55:45 2006
@@ -31,15 +31,18 @@
extern "C" {
#endif
+struct ast_storage_dirent;
+
struct ast_storage_be {
const char *name;
struct ast_storage *(*new)(const char *uri);
int (*free)(struct ast_storage *st);
- int (*get)(struct ast_storage *st, const char *objectname, char *localfile, size_t localfilesize);
- int (*put)(struct ast_storage *st, const char *objectname, const char *localfile);
- int (*delete)(struct ast_storage *st, const char *objectname);
- int (*count)(struct ast_storage *st, const char *objectpath);
- int (*parseoptions)(struct ast_storage *st, const char *var, const char *value);
+ int (*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 (*delete)(struct ast_storage *st, const char *objectname, const char *fileformats);
+ void *(*opendir)(struct ast_storage *st, const char *objectpath);
+ int (*readdir)(struct ast_storage *st, void *dirptr, struct ast_storage_dirent *dirent);
+ int (*closedir)(struct ast_storage *st, void *dirptr);
AST_LIST_ENTRY(ast_storage_be) list;
struct ast_module *module;
};
@@ -47,6 +50,11 @@
/* Most specific backends will have longer structures */
struct ast_storage {
struct ast_storage_be *be;
+};
+
+struct ast_storage_dirent {
+ char name[256];
+ char format[10];
};
int __ast_register_storage(const struct ast_storage_be *e, struct ast_module *mod);
@@ -58,10 +66,7 @@
/*! \brief Retrieves an instance of a storage method
* \param storage_type Name of the backend
- * \param root Backend specific parameter. Generally is a hostname or path.
- * \param auth Backend specific parameter. Generally is the user in an authentication scheme.
- * \param passwd Backend specific parameter. Generally is the password in an authentication scheme.
- * \param flags Backend specific parameter
+ * \param uri Backend specific URI to the resource
*/
struct ast_storage *ast_storage_request(const char *storage_type, const char *uri);
@@ -72,23 +77,46 @@
/*! \brief Retrieves a file from the storage medium
* \param st Storage instance
* \param objectname Logical name of the file
+ * \param fileformats Formats to retrieve
* \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, char *localfile, size_t localfilesize);
+int 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
* \param objectname Logical name of the file
+ * \param fileformats Formats to store
* \param localfile Location of the file to store
*/
-int ast_storage_put(struct ast_storage *st, const char *objectname, const char *localfile);
+int ast_storage_put(struct ast_storage *st, const char *objectname, const char *fileformats, const char *localfile);
/*! \brief Removes a file from the storage medium
* \param st Storage instance
* \param objectname Logical name of the file
+ * \param fileformats Formats to delete
*/
-int ast_storage_delete(struct ast_storage *st, const char *objectname);
+int ast_storage_delete(struct ast_storage *st, const char *objectname, const char *fileformats);
+
+/*! \brief Starts retrieval of objects in a resource path
+ * \param st Storage instance
+ * \param pathname Logical name of the path
+ * \return Pointer identifying this listing, or NULL on error.
+ */
+void *ast_storage_opendir(struct ast_storage *st, const char *objectname);
+
+/*! \brief Retrieves an objectname from a previously opened path
+ * \param st Storage instance
+ * \param dirptr Pointer returned by ast_storage_opendir
+ * \param dirent Pointer to a storage area for the object
+ */
+int ast_storage_readdir(struct ast_storage *st, void *dirptr, struct ast_storage_dirent *dirent);
+
+/*! \brief Ends retrieval of objects in a resource path
+ * \param st Storage instance
+ * \param dirptr Pointer returned by ast_storage_opendir
+ */
+int ast_storage_closedir(struct ast_storage *st, void *dirptr);
/*! \brief Retrieves a count of objects at a particular path
* \param st Storage instance
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=48342&r1=48341&r2=48342
==============================================================================
--- team/group/ast_storage/main/storage.c (original)
+++ team/group/ast_storage/main/storage.c Wed Dec 6 18:55:45 2006
@@ -111,29 +111,56 @@
return st && st->be->free ? st->be->free(st) : -1;
}
-int ast_storage_get(struct ast_storage *st, const char *objectname, char *localfile, size_t localfilesize)
-{
- return st->be->get ? st->be->get(st, objectname, localfile, localfilesize) : -1;
-}
-
-int ast_storage_put(struct ast_storage *st, const char *objectname, const char *localfile)
-{
- return st->be->put ? st->be->put(st, objectname, localfile) : -1;
-}
-
-int ast_storage_delete(struct ast_storage *st, const char *objectname)
-{
- return st->be->delete ? st->be->delete(st, objectname) : -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;
+}
+
+int ast_storage_put(struct ast_storage *st, const char *objectname, const char *fileformats, const char *localfile)
+{
+ return st->be->put ? st->be->put(st, objectname, fileformats, localfile) : -1;
+}
+
+int ast_storage_delete(struct ast_storage *st, const char *objectname, const char *fileformats)
+{
+ return st->be->delete ? st->be->delete(st, objectname, fileformats) : -1;
+}
+
+void *ast_storage_opendir(struct ast_storage *st, const char *objectpath)
+{
+ return st->be->opendir ? st->be->opendir(st, objectpath) : NULL;
+}
+
+int ast_storage_readdir(struct ast_storage *st, void *dirptr, struct ast_storage_dirent *dirent)
+{
+ return st->be->readdir ? st->be->readdir(st, dirptr, dirent) : -1;
+}
+
+int ast_storage_closedir(struct ast_storage *st, void *dirptr)
+{
+ return st->be->closedir ? st->be->closedir(st, dirptr) : -1;
}
int ast_storage_count(struct ast_storage *st, const char *objectpath)
{
- return st->be->count ? st->be->count(st, objectpath) : -1;
-}
-
-int ast_storage_parseoptions(struct ast_storage *st, const char *var, const char *value)
-{
- return st->be->parseoptions ? st->be->parseoptions(st, var, value) : -1;
+ void *dirptr;
+ struct ast_storage_dirent dirent;
+ int count = 0;
+
+ if (!(st->be->opendir && st->be->readdir && st->be->closedir))
+ return -1;
+
+ dirptr = st->be->opendir(st, objectpath);
+ if (!dirptr)
+ return -1;
+
+ while (st->be->readdir(st, dirptr, &dirent) == 0) {
+ if (strcmp(dirent.format, "txt") == 0)
+ count++;
+ }
+
+ st->be->closedir(st, dirptr);
+ return count;
}
static int show_storage_engines(int fd, int argc, char *argv[])
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=48342&r1=48341&r2=48342
==============================================================================
--- team/group/ast_storage/res/res_storage_file.c (original)
+++ team/group/ast_storage/res/res_storage_file.c Wed Dec 6 18:55:45 2006
@@ -41,6 +41,11 @@
char rootpath[128];
};
+struct file_storage_dir {
+ DIR *dir;
+ char path[256];
+};
+
static const struct ast_storage_be file_se;
static struct ast_storage *se_new_file(const char *uri)
@@ -57,7 +62,7 @@
return 0;
}
-static int se_get_file(struct ast_storage *st, const char *objectname, char *localfile, size_t localfilesize)
+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;
char dirname[256], *dirnameptr;
@@ -89,7 +94,7 @@
return res;
}
-static int se_put_file(struct ast_storage *st, const char *objectname, const char *localfile)
+static int se_put_file(struct ast_storage *st, const char *objectname, const char *fileformats, const char *localfile)
{
struct ast_storage_file *fst = (struct ast_storage_file *)st;
int ifd;
@@ -133,35 +138,66 @@
return res;
}
-static int se_delete_file(struct ast_storage *st, const char *objectname)
+static int se_delete_file(struct ast_storage *st, const char *objectname, const char *fileformats)
{
struct ast_storage_file *fst = (struct ast_storage_file *)st;
char dest[256];
- snprintf(dest, sizeof(dest), "%s/%s", fst->rootpath, objectname);
- return unlink(dest);
-}
-
-static int se_count_file(struct ast_storage *st, const char *objectpath)
-{
- struct ast_storage_file *fst = (struct ast_storage_file *)st;
- char dest[256];
- DIR *dir;
- struct dirent *dirent;
- int count = 0;
- snprintf(dest, sizeof(dest), "%s/%s", fst->rootpath, objectpath);
- dir = opendir(dest);
- while ((dirent = readdir(dir))) {
- /* Probably not exactly correct */
- if (strncmp(dirent->d_name, ".", 1) != 0)
- count++;
- }
- closedir(dir);
-
+
+ if (objectname[0] == '/')
+ return unlink(objectname);
+ else {
+ 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 = malloc(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_parseoptions_file(struct ast_storage *st, const char *var, const char *value)
-{
+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;
}
@@ -172,8 +208,9 @@
.get = se_get_file,
.put = se_put_file,
.delete = se_delete_file,
- .count = se_count_file,
- .parseoptions = se_parseoptions_file,
+ .opendir = se_opendir_file,
+ .readdir = se_readdir_file,
+ .closedir = se_closedir_file,
};
static int load_module(void)
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=48342&r1=48341&r2=48342
==============================================================================
--- team/group/ast_storage/res/res_storage_odbc.c (original)
+++ team/group/ast_storage/res/res_storage_odbc.c Wed Dec 6 18:55:45 2006
@@ -41,15 +41,15 @@
#include <fcntl.h>
#include <errno.h>
-/* Number of bytes to transfer when moving a large field */
-#define CHUNKSIZE 65536
-
struct ast_storage_odbc {
const struct ast_storage_be *be;
char odbc_class[128];
char tablename[128];
char pathname[128];
struct odbc_obj *conn;
+};
+
+struct odbc_storage_dir {
SQLHSTMT sth;
};
@@ -126,8 +126,6 @@
static int se_free_odbc(struct ast_storage *st)
{
struct ast_storage_odbc *ost = (struct ast_storage_odbc *)st;
- if (ost->sth)
- SQLFreeHandle(SQL_HANDLE_STMT, ost->sth);
ast_odbc_release_obj(ost->conn);
free(ost);
return 0;
@@ -158,7 +156,7 @@
ast_copy_string(filename, filename2, filenamesize);
}
-static int se_get_odbc(struct ast_storage *st, const char *objectname, char *localfile, size_t localfilesize)
+static int se_get_odbc(struct ast_storage *st, const char *objectname, const char *fileformats, char *localfile, size_t localfilesize)
{
struct ast_storage_odbc *ost = (struct ast_storage_odbc *)st;
int res = -1, tempfd, x, gotten = 0;
@@ -241,6 +239,7 @@
if (!strcasecmp(coltitle, "recording")) {
int fdlen;
+ int chunksize = 0x4000000; /* Try 64MB chunks initially */
off_t chunk_offset;
void *fdm = NULL;
SQLINTEGER colsize2;
@@ -273,13 +272,20 @@
}
/* Grab data in 64k chunks */
- for (chunk_offset = 0; chunk_offset < fdlen; chunk_offset += CHUNKSIZE) {
- /* Add one to the CHUNKSIZE, because ODBC always adds a terminating NULL */
- if ((fdm = mmap(NULL, CHUNKSIZE + 1, PROT_READ | PROT_WRITE, MAP_SHARED, fd, chunk_offset)) == (void *)-1) {
- ast_log(LOG_WARNING, "Could not mmap the output file: %s (%d)\n", strerror(errno), errno);
- goto endget;
+ for (chunk_offset = 0; chunk_offset < fdlen; chunk_offset += chunksize) {
+ /* Add one to the chunksize, because ODBC always adds a terminating NULL */
+ if ((fdm = mmap(NULL, chunksize + 1, PROT_READ | PROT_WRITE, MAP_SHARED, fd, chunk_offset)) == (void *)-1) {
+ /* Reduce chunk size and try again */
+ chunk_offset--;
+ chunksize >>= 1;
+ /* Don't try anything less than 2k */
+ if (chunksize < 2048) {
+ ast_log(LOG_WARNING, "Could not mmap the output file: %s (%d)\n", strerror(errno), errno);
+ goto endget;
+ }
+ continue;
} else {
- res = SQLGetData(stmt, x + 1, SQL_BINARY, fdm, CHUNKSIZE + 1, NULL);
+ res = SQLGetData(stmt, x + 1, SQL_BINARY, fdm, chunksize + 1, NULL);
munmap(fdm, 0);
if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
ast_log(LOG_WARNING, "SQL Get Data error!\n[%s]\n\n", sql);
@@ -324,7 +330,7 @@
return res ? -1 : 0;
}
-static int se_put_odbc(struct ast_storage *st, const char *objectname, const char *localfile)
+static int se_put_odbc(struct ast_storage *st, const char *objectname, const char *fileformats, const char *localfile)
{
struct ast_storage_odbc *ost = (struct ast_storage_odbc *)st;
int res = -1, x;
@@ -337,6 +343,7 @@
SQLHSTMT stmt = NULL;
DIR *dir;
struct dirent *dirent;
+ int chunksize = 0x4000000; /* 64 MB initially */
snprintf(reallocalfile, sizeof(reallocalfile), "%s.txt", localfile);
cfg = ast_config_load(reallocalfile);
@@ -425,14 +432,19 @@
res = SQLExecute(stmt);
if (res == SQL_NEED_DATA) {
- for (offset = 0; offset < filesize; offset += CHUNKSIZE) {
- void *fdm = mmap(NULL, CHUNKSIZE + 1, PROT_READ, MAP_SHARED, fd, offset);
+ for (offset = 0; offset < filesize; offset += chunksize) {
+ void *fdm = mmap(NULL, chunksize + 1, PROT_READ, MAP_SHARED, fd, offset);
if (fdm == (void *)-1) {
- ast_log(LOG_ERROR, "Unable to mmap file %s: %s (%d)\n", reallocalfile, strerror(errno), errno);
- goto endput;
+ offset--;
+ chunksize >>= 1;
+ if (chunksize < 2048) {
+ ast_log(LOG_ERROR, "Unable to mmap file %s: %s (%d)\n", reallocalfile, strerror(errno), errno);
+ goto endput;
+ }
+ continue;
}
- SQLPutData(stmt, fdm, CHUNKSIZE);
- munmap(fdm, 0);
+ SQLPutData(stmt, fdm, chunksize + offset > filesize ? filesize - offset : chunksize);
+ munmap(fdm, chunksize);
}
} else if ((res != SQL_SUCCESS) && (res != SQL_SUCCESS_WITH_INFO)) {
ast_log(LOG_WARNING, "SQL Execute error!\n[%s]\n", sql);
@@ -450,7 +462,7 @@
return res ? -1 : 0;
}
-static int se_delete_odbc(struct ast_storage *st, const char *objectname)
+static int se_delete_odbc(struct ast_storage *st, const char *objectname, const char *fileformats)
{
char pathname[256], filename[256], sql[256];
struct ast_storage_odbc *ost = (struct ast_storage_odbc *)st;
@@ -488,14 +500,19 @@
return res ? -1 : 0;
}
-static int se_count_odbc(struct ast_storage *st, const char *objectpath)
+static void *se_opendir_odbc(struct ast_storage *st, const char *objectpath)
+{
+ return NULL;
+}
+
+static int se_readdir_odbc(struct ast_storage *st, void *dirptr, struct ast_storage_dirent *dirent)
{
return -1;
}
-static int se_parseoptions_odbc(struct ast_storage *st, const char *var, const char *value)
-{
- return 0;
+static int se_closedir_odbc(struct ast_storage *st, void *dirptr)
+{
+ return -1;
}
static const struct ast_storage_be odbc_se = {
@@ -505,8 +522,9 @@
.get = se_get_odbc,
.put = se_put_odbc,
.delete = se_delete_odbc,
- .count = se_count_odbc,
- .parseoptions = se_parseoptions_odbc,
+ .opendir = se_opendir_odbc,
+ .readdir = se_readdir_odbc,
+ .closedir = se_closedir_odbc,
};
static int load_module(void)
More information about the asterisk-commits
mailing list