summaryrefslogtreecommitdiffstats
path: root/src/util/dict_alloc.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/util/dict_alloc.c196
1 files changed, 196 insertions, 0 deletions
diff --git a/src/util/dict_alloc.c b/src/util/dict_alloc.c
new file mode 100644
index 0000000..3285a38
--- /dev/null
+++ b/src/util/dict_alloc.c
@@ -0,0 +1,196 @@
+/*++
+/* NAME
+/* dict_alloc 3
+/* SUMMARY
+/* dictionary memory manager
+/* SYNOPSIS
+/* #include <dict.h>
+/*
+/* DICT *dict_alloc(dict_type, dict_name, size)
+/* const char *dict_type;
+/* const char *dict_name;
+/* ssize_t size;
+/*
+/* void dict_free(dict)
+/* DICT *ptr;
+/*
+/* void dict_jmp_alloc(dict)
+/* DICT *ptr;
+/* DESCRIPTION
+/* dict_alloc() allocates memory for a dictionary structure of
+/* \fIsize\fR bytes, initializes all generic dictionary
+/* properties to default settings,
+/* and installs default methods that do not support any operation.
+/* The caller is supposed to override the default methods with
+/* ones that it supports.
+/* The purpose of the default methods is to trap an attempt to
+/* invoke an unsupported method.
+/*
+/* One exception is the default lock function. When the
+/* dictionary provides a file handle for locking, the default
+/* lock function returns the result from myflock with the
+/* locking method specified in the lock_type member, otherwise
+/* it returns 0. Presently, the lock function is used only to
+/* implement the DICT_FLAG_OPEN_LOCK feature (lock the database
+/* exclusively after it is opened) for databases that are not
+/* multi-writer safe.
+/*
+/* dict_free() releases memory and cleans up after dict_alloc().
+/* It is up to the caller to dispose of any memory that was allocated
+/* by the caller.
+/*
+/* dict_jmp_alloc() implements preliminary support for exception
+/* handling. This will eventually be built into dict_alloc().
+/*
+/* Arguments:
+/* .IP dict_type
+/* The official name for this type of dictionary, as used by
+/* dict_open(3) etc. This is stored under the \fBtype\fR
+/* member.
+/* .IP dict_name
+/* Dictionary name. This is stored as the \fBname\fR member.
+/* .IP size
+/* The size in bytes of the dictionary subclass structure instance.
+/* SEE ALSO
+/* dict(3)
+/* DIAGNOSTICS
+/* Fatal errors: the process invokes a default method.
+/* LICENSE
+/* .ad
+/* .fi
+/* The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/* Wietse Venema
+/* IBM T.J. Watson Research
+/* P.O. Box 704
+/* Yorktown Heights, NY 10598, USA
+/*
+/* Wietse Venema
+/* Google, Inc.
+/* 111 8th Avenue
+/* New York, NY 10011, USA
+/*--*/
+
+/* System libraries. */
+
+#include "sys_defs.h"
+
+/* Utility library. */
+
+#include "msg.h"
+#include "mymalloc.h"
+#include "myflock.h"
+#include "dict.h"
+
+/* dict_default_lookup - trap unimplemented operation */
+
+static const char *dict_default_lookup(DICT *dict, const char *unused_key)
+{
+ msg_fatal("table %s:%s: lookup operation is not supported",
+ dict->type, dict->name);
+}
+
+/* dict_default_update - trap unimplemented operation */
+
+static int dict_default_update(DICT *dict, const char *unused_key,
+ const char *unused_value)
+{
+ msg_fatal("table %s:%s: update operation is not supported",
+ dict->type, dict->name);
+}
+
+/* dict_default_delete - trap unimplemented operation */
+
+static int dict_default_delete(DICT *dict, const char *unused_key)
+{
+ msg_fatal("table %s:%s: delete operation is not supported",
+ dict->type, dict->name);
+}
+
+/* dict_default_sequence - trap unimplemented operation */
+
+static int dict_default_sequence(DICT *dict, int unused_function,
+ const char **unused_key, const char **unused_value)
+{
+ msg_fatal("table %s:%s: sequence operation is not supported",
+ dict->type, dict->name);
+}
+
+/* dict_default_lock - default lock handler */
+
+static int dict_default_lock(DICT *dict, int operation)
+{
+ if (dict->lock_fd >= 0) {
+ return (myflock(dict->lock_fd, dict->lock_type, operation));
+ } else {
+ return (0);
+ }
+}
+
+/* dict_default_close - trap unimplemented operation */
+
+static void dict_default_close(DICT *dict)
+{
+ msg_fatal("table %s:%s: close operation is not supported",
+ dict->type, dict->name);
+}
+
+/* dict_alloc - allocate dictionary object, initialize super-class */
+
+DICT *dict_alloc(const char *dict_type, const char *dict_name, ssize_t size)
+{
+ DICT *dict = (DICT *) mymalloc(size);
+
+ dict->type = mystrdup(dict_type);
+ dict->name = mystrdup(dict_name);
+ dict->flags = DICT_FLAG_FIXED;
+ dict->lookup = dict_default_lookup;
+ dict->update = dict_default_update;
+ dict->delete = dict_default_delete;
+ dict->sequence = dict_default_sequence;
+ dict->close = dict_default_close;
+ dict->lock = dict_default_lock;
+ dict->lock_type = INTERNAL_LOCK;
+ dict->lock_fd = -1;
+ dict->stat_fd = -1;
+ dict->mtime = 0;
+ dict->fold_buf = 0;
+ dict->owner.status = DICT_OWNER_UNKNOWN;
+ dict->owner.uid = INT_MAX;
+ dict->error = DICT_ERR_NONE;
+ dict->jbuf = 0;
+ dict->utf8_backup = 0;
+ dict->file_buf = 0;
+ dict->file_b64 = 0;
+ return dict;
+}
+
+/* dict_free - super-class destructor */
+
+void dict_free(DICT *dict)
+{
+ myfree(dict->type);
+ myfree(dict->name);
+ if (dict->jbuf)
+ myfree((void *) dict->jbuf);
+ if (dict->utf8_backup)
+ myfree((void *) dict->utf8_backup);
+ if (dict->file_buf)
+ vstring_free(dict->file_buf);
+ if (dict->file_b64)
+ vstring_free(dict->file_b64);
+ myfree((void *) dict);
+}
+
+ /*
+ * TODO: add a dict_flags() argument to dict_alloc() and handle jump buffer
+ * allocation there.
+ */
+
+/* dict_jmp_alloc - enable exception handling */
+
+void dict_jmp_alloc(DICT *dict)
+{
+ if (dict->jbuf == 0)
+ dict->jbuf = (DICT_JMP_BUF *) mymalloc(sizeof(DICT_JMP_BUF));
+}