summaryrefslogtreecommitdiff
path: root/Src/Modules/db_gdbm.c
diff options
context:
space:
mode:
Diffstat (limited to 'Src/Modules/db_gdbm.c')
-rw-r--r--Src/Modules/db_gdbm.c240
1 files changed, 240 insertions, 0 deletions
diff --git a/Src/Modules/db_gdbm.c b/Src/Modules/db_gdbm.c
new file mode 100644
index 000000000..f0915e0a8
--- /dev/null
+++ b/Src/Modules/db_gdbm.c
@@ -0,0 +1,240 @@
+/*
+ * db_gdbm.c - bindings for gdbm
+ *
+ * This file is part of zsh, the Z shell.
+ *
+ * Copyright (c) 2008 Clint Adams
+ * All rights reserved.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and to distribute modified versions of this software for any
+ * purpose, provided that the above copyright notice and the following
+ * two paragraphs appear in all copies of this software.
+ *
+ * In no event shall Clint Adams or the Zsh Development
+ * Group be liable to any party for direct, indirect, special, incidental, or
+ * consequential damages arising out of the use of this software and its
+ * documentation, even if Peter Stephenson, Sven Wischnowsky and the Zsh
+ * Development Group have been advised of the possibility of such damage.
+ *
+ * Clint Adams and the Zsh Development Group
+ * specifically disclaim any warranties, including, but not limited to, the
+ * implied warranties of merchantability and fitness for a particular purpose.
+ * The software provided hereunder is on an "as is" basis, and Peter
+ * Stephenson, Sven Wischnowsky and the Zsh Development Group have no
+ * obligation to provide maintenance, support, updates, enhancements, or
+ * modifications.
+ *
+ */
+
+#include "db_gdbm.mdh"
+#include "db_gdbm.pro"
+
+/*
+ * Make sure we have all the bits I'm using for memory mapping, otherwise
+ * I don't know what I'm doing.
+ */
+#if defined(HAVE_GDBM_H) && defined(HAVE_GDBM_OPEN)
+
+#include <gdbm.h>
+
+static const struct gsu_hash gdbm_gsu =
+{ gdbmgetfn, gdbmsetfn, gdbmunsetfn };
+
+static struct builtin bintab[] = {
+ BUILTIN("ztie", 0, bin_ztie, 1, -1, 0, "d:f:", NULL),
+ BUILTIN("zuntie", 0, bin_zuntie, 1, -1, 0, NULL, NULL),
+};
+
+GDBM_FILE dbf = NULL;
+Param tied_param;
+
+/**/
+static int
+bin_ztie(char *nam, char **args, Options ops, UNUSED(int func))
+{
+ char *resource_name, *pmname;
+
+ if(!OPT_ISSET(ops,'d')) {
+ zwarnnam(nam, "you must pass `-d db/gdbm' to ztie", NULL);
+ return 1;
+ }
+ if(!OPT_ISSET(ops,'f')) {
+ zwarnnam(nam, "you must pass `-f' with a filename to ztie", NULL);
+ return 1;
+ }
+
+ /* Here should be a lookup of the backend type against
+ * a registry.
+ */
+
+ if(dbf) {
+ zwarnnam(nam, "something is already ztied and this implementation is flawed", NULL);
+ return 1;
+ }
+
+ pmname = ztrdup(*args);
+
+ resource_name = OPT_ARG(ops, 'f');
+
+ if (!(tied_param = createspecialhash(pmname, &getgdbmnode, &scangdbmkeys, PM_SPECIAL | PM_HASHED))) {
+ zwarnnam(nam, "cannot create the requested parameter name", NULL);
+ return 1;
+ }
+
+ dbf = gdbm_open(resource_name, 0, GDBM_WRCREAT | GDBM_SYNC, 0666, 0);
+ if(!dbf) {
+ zwarnnam(nam, "error opening database file %s", resource_name);
+ return 1;
+ }
+
+ return 0;
+}
+
+/**/
+static int
+bin_zuntie(char *nam, char **args, Options ops, UNUSED(int func))
+{
+ paramtab->removenode(paramtab, tied_param->node.nam);
+ free(tied_param);
+ tied_param = NULL;
+ gdbm_close(dbf);
+ dbf = NULL;
+
+ return 0;
+}
+
+
+/**/
+static char *
+gdbmgetfn(Param pm)
+{
+return;
+}
+
+/**/
+static void
+gdbmsetfn(Param pm, char **key)
+{
+return;
+}
+
+/**/
+static void
+gdbmunsetfn(Param pm, int um)
+{
+return;
+}
+
+/**/
+static HashNode
+getgdbmnode(UNUSED(HashTable ht), const char *name)
+{
+ int len, ret;
+ char *nameu;
+ datum content, key;
+ Param pm = NULL;
+
+ nameu = dupstring(name);
+ unmetafy(nameu, &len);
+ key.dptr = nameu;
+
+ pm = (Param) hcalloc(sizeof(struct param));
+ pm->node.nam = nameu;
+ pm->node.flags = PM_SCALAR;
+
+ ret = gdbm_exists(dbf, key);
+ if(!ret) {
+ pm->u.str = dupstring("");
+ pm->node.flags |= PM_UNSET;
+ } else {
+ content = gdbm_fetch(dbf, key);
+
+ pm->u.str = content.dptr;
+ pm->gsu.s = &nullsetscalar_gsu;
+ }
+ return &pm->node;
+}
+
+/**/
+static void
+scangdbmkeys(UNUSED(HashTable ht), ScanFunc func, int flags)
+{
+ Param pm = NULL;
+ datum key, content;
+
+ pm = (Param) hcalloc(sizeof(struct param));
+
+ pm->node.flags = PM_SCALAR;
+ pm->gsu.s = &nullsetscalar_gsu;
+
+ key = gdbm_firstkey(dbf);
+
+ while(key.dptr) {
+ content = gdbm_fetch(dbf, key);
+
+ pm->u.str = content.dptr;
+ pm->gsu.s = &nullsetscalar_gsu;
+
+ func(&pm->node, flags);
+
+ key = gdbm_nextkey(dbf, key);
+ }
+
+}
+
+#else
+# error no gdbm
+#endif /* have gdbm */
+
+static struct features module_features = {
+ bintab, sizeof(bintab)/sizeof(*bintab),
+ NULL, 0,
+ NULL, 0,
+ NULL, 0,
+ 0
+};
+
+/**/
+int
+setup_(UNUSED(Module m))
+{
+ return 0;
+}
+
+/**/
+int
+features_(Module m, char ***features)
+{
+ *features = featuresarray(m, &module_features);
+ return 0;
+}
+
+/**/
+int
+enables_(Module m, int **enables)
+{
+ return handlefeatures(m, &module_features, enables);
+}
+
+/**/
+int
+boot_(UNUSED(Module m))
+{
+ return 0;
+}
+
+/**/
+int
+cleanup_(UNUSED(Module m))
+{
+ return setfeatureenables(m, &module_features, NULL);
+}
+
+/**/
+int
+finish_(UNUSED(Module m))
+{
+ return 0;
+}