[asterisk-commits] ivaxer: branch ivaxer/ast_storage r266436 - /team/ivaxer/ast_storage/res/
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Sat May 29 11:54:33 CDT 2010
Author: ivaxer
Date: Sat May 29 11:54:30 2010
New Revision: 266436
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=266436
Log:
Imported res_storage_file.c from team/group/ast_storage branch
Added:
team/ivaxer/ast_storage/res/res_storage_file.c (with props)
Added: team/ivaxer/ast_storage/res/res_storage_file.c
URL: http://svnview.digium.com/svn/asterisk/team/ivaxer/ast_storage/res/res_storage_file.c?view=auto&rev=266436
==============================================================================
--- team/ivaxer/ast_storage/res/res_storage_file.c (added)
+++ team/ivaxer/ast_storage/res/res_storage_file.c Sat May 29 11:54:30 2010
@@ -1,0 +1,307 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2006, Digium, Inc.
+ *
+ * Jason Parker <jparker at digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*! \file
+ *
+ * \brief Files based storage engine
+ * \author Jason Parker <jparker at digium.com>
+ * \ingroup res
+ */
+
+#include "asterisk.h"
+
+ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
+
+#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 {
+ /* Nothing here */
+};
+
+struct file_storage_dir {
+ DIR *dir;
+ 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));
+ 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 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", st->path, 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;
+
+ 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));
+ 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 void *se_read_file(struct ast_storage *st, struct ast_storage_fileinst *fi, size_t chunksize)
+{
+ void *data = NULL;
+ int res = 0;
+ res = read(fi->ent->fd, data, chunksize);
+ return res >= 0 ? data : NULL;
+}
+
+static int se_write_file(struct ast_storage *st, struct ast_storage_fileinst *fi, void *data, size_t chunksize)
+{
+ int len = 0;
+ len = write(fi->ent->fd, data, chunksize);
+ return len;
+}
+
+static int se_open_file(struct ast_storage *st, struct ast_storage_fileinst *fi, mode_t mode)
+{
+ fi->ent->fd = open(fi->ent->name, O_RDWR | O_CREAT, mode);
+ return fi->ent->fd;
+}
+
+static int se_close_file(struct ast_storage *st, struct ast_storage_fileinst *fi)
+{
+ fi->ent->fd = close(fi->ent->fd);
+ return fi->ent->fd;
+}
+
+static int se_get_file(struct ast_storage *st, const char *objectname, const char *exts, char *localfile, size_t localfilesize)
+{
+ struct file_storage_dir *dir;
+ struct ast_storage_dirent *dirent;
+ struct stat statbuf;
+ char dirname[PATH_MAX], *dirnameptr;
+
+ if (ast_strlen_zero(objectname))
+ return -1;
+
+ if (objectname[0] == '/')
+ ast_copy_string(localfile, objectname, localfilesize);
+ else
+ snprintf(localfile, localfilesize, "%s/%s", st->path, objectname);
+
+ ast_copy_string(dirname, localfile, sizeof(dirname));
+ dirnameptr = strrchr(dirname, '/');
+ if (dirnameptr)
+ *dirnameptr++ = '\0';
+ else
+ return -1;
+
+ if ((dir = se_opendir_file(st, dirname))) {
+ dirent = ast_calloc(1, sizeof(*dirent));
+ while ((!se_readdir_file(st, dir, dirent))) {
+ int found = 0;
+ 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(dirent->name, dirnameptr))
+ found = 1;
+ }
+ if (!found && !strcmp(fn, dirnameptr)) {
+ if (ast_strlen_zero(ext) || !exts || ast_exts_compare(exts, ext))
+ 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_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 {
+ 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->xst;
+ int ifd;
+ int ofd;
+ int res = 0;
+ int len = 0;
+ char dest[PATH_MAX];
+ char buf[4096];
+
+ 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) {
+ ast_log(LOG_WARNING, "Unable to open %s in read-only mode\n", localfile);
+ return -1;
+ }
+*/
+ if ((ofd = open(dest, O_WRONLY | O_TRUNC | O_CREAT, 0666)) < 0) {
+ ast_log(LOG_WARNING, "Unable to open %s in write-only mode\n", dest);
+ close(ifd);
+ return -1;
+ }
+ do {
+ /* XXX No direct read()ing
+ len = read(ifd, buf, sizeof(buf));
+ if (len < 0) {
+ ast_log(LOG_WARNING, "Read failed on %s: %s\n", localfile, strerror(errno));
+ close(ifd);
+ close(ofd);
+ unlink(dest);
+ }
+ */
+ if (len) {
+ res = write(ofd, buf, len);
+ if (errno == ENOMEM || errno == ENOSPC || res != len) {
+ ast_log(LOG_WARNING, "Write failed on %s (%d of %d): %s\n", dest, res, len, strerror(errno));
+ close(ifd);
+ close(ofd);
+ unlink(dest);
+ }
+ }
+ } while (len);
+ close(ifd);
+ close(ofd);
+ return res;
+}
+#endif
+
+static int se_del_file(struct ast_storage *st, const char *exts)
+{
+ char dest[PATH_MAX];
+
+ if (st->fl->name[0] == '/')
+ return unlink(st->fl->name);
+ else {
+ snprintf(dest, sizeof(dest), "%s/%s", st->path, st->fl->name);
+ return unlink(dest);
+ }
+}
+
+static const struct ast_storage_be file_se = {
+ .name = "file",
+ .create = se_create_file,
+ .free = se_free_file,
+ .get = se_get_file,
+#if 0
+ .put = se_put_file,
+#endif
+ .open = se_open_file,
+ .close = se_close_file,
+ .read = se_read_file,
+ .write = se_write_file,
+ .del = se_del_file,
+ .opendir = se_opendir_file,
+ .readdir = se_readdir_file,
+ .closedir = se_closedir_file,
+};
+
+static int load_module(void)
+{
+ return ast_register_storage(&file_se);
+}
+
+static int unload_module(void)
+{
+ return ast_unregister_storage(file_se.name);
+}
+
+AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Files based storage engine");
Propchange: team/ivaxer/ast_storage/res/res_storage_file.c
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: team/ivaxer/ast_storage/res/res_storage_file.c
------------------------------------------------------------------------------
svn:keywords = 'Author Date Id Revision'
Propchange: team/ivaxer/ast_storage/res/res_storage_file.c
------------------------------------------------------------------------------
svn:mime-type = text/plain
More information about the asterisk-commits
mailing list