[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