about summary refs log tree commit diff
path: root/Src/Modules/db_gdbm.c
diff options
context:
space:
mode:
authorClint Adams <clint@users.sourceforge.net>2008-07-21 00:55:15 +0000
committerClint Adams <clint@users.sourceforge.net>2008-07-21 00:55:15 +0000
commit9f42d3211e9c8dce63f59d0cc5fd40a221384026 (patch)
tree52c3cf33c66523f3038bac00e955114e1ae37122 /Src/Modules/db_gdbm.c
parentdd96cace750cfb6f90b4769c1cb9648bd895596a (diff)
downloadzsh-9f42d3211e9c8dce63f59d0cc5fd40a221384026.tar.gz
zsh-9f42d3211e9c8dce63f59d0cc5fd40a221384026.tar.xz
zsh-9f42d3211e9c8dce63f59d0cc5fd40a221384026.zip
25319: fix zuntie, add -f option to ztie.
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;
+}