1*33881f77Schristos /* $NetBSD: dict_alloc.c,v 1.3 2020/03/18 19:05:21 christos Exp $ */
241fbaed0Stron
341fbaed0Stron /*++
441fbaed0Stron /* NAME
541fbaed0Stron /* dict_alloc 3
641fbaed0Stron /* SUMMARY
741fbaed0Stron /* dictionary memory manager
841fbaed0Stron /* SYNOPSIS
941fbaed0Stron /* #include <dict.h>
1041fbaed0Stron /*
1141fbaed0Stron /* DICT *dict_alloc(dict_type, dict_name, size)
1241fbaed0Stron /* const char *dict_type;
1341fbaed0Stron /* const char *dict_name;
1441fbaed0Stron /* ssize_t size;
1541fbaed0Stron /*
1641fbaed0Stron /* void dict_free(dict)
1741fbaed0Stron /* DICT *ptr;
1816d67a18Stron /*
1916d67a18Stron /* void dict_jmp_alloc(dict)
2016d67a18Stron /* DICT *ptr;
2141fbaed0Stron /* DESCRIPTION
2241fbaed0Stron /* dict_alloc() allocates memory for a dictionary structure of
2341fbaed0Stron /* \fIsize\fR bytes, initializes all generic dictionary
2441fbaed0Stron /* properties to default settings,
2541fbaed0Stron /* and installs default methods that do not support any operation.
2641fbaed0Stron /* The caller is supposed to override the default methods with
2741fbaed0Stron /* ones that it supports.
2841fbaed0Stron /* The purpose of the default methods is to trap an attempt to
2941fbaed0Stron /* invoke an unsupported method.
3041fbaed0Stron /*
31e6ca80d4Stron /* One exception is the default lock function. When the
32e6ca80d4Stron /* dictionary provides a file handle for locking, the default
3316d67a18Stron /* lock function returns the result from myflock with the
3416d67a18Stron /* locking method specified in the lock_type member, otherwise
35e6ca80d4Stron /* it returns 0. Presently, the lock function is used only to
36e6ca80d4Stron /* implement the DICT_FLAG_OPEN_LOCK feature (lock the database
37e6ca80d4Stron /* exclusively after it is opened) for databases that are not
38e6ca80d4Stron /* multi-writer safe.
39e6ca80d4Stron /*
4041fbaed0Stron /* dict_free() releases memory and cleans up after dict_alloc().
4141fbaed0Stron /* It is up to the caller to dispose of any memory that was allocated
4241fbaed0Stron /* by the caller.
4341fbaed0Stron /*
4416d67a18Stron /* dict_jmp_alloc() implements preliminary support for exception
4516d67a18Stron /* handling. This will eventually be built into dict_alloc().
4616d67a18Stron /*
4741fbaed0Stron /* Arguments:
4841fbaed0Stron /* .IP dict_type
4941fbaed0Stron /* The official name for this type of dictionary, as used by
5041fbaed0Stron /* dict_open(3) etc. This is stored under the \fBtype\fR
5141fbaed0Stron /* member.
5241fbaed0Stron /* .IP dict_name
5341fbaed0Stron /* Dictionary name. This is stored as the \fBname\fR member.
5441fbaed0Stron /* .IP size
5541fbaed0Stron /* The size in bytes of the dictionary subclass structure instance.
5641fbaed0Stron /* SEE ALSO
5741fbaed0Stron /* dict(3)
5841fbaed0Stron /* DIAGNOSTICS
5941fbaed0Stron /* Fatal errors: the process invokes a default method.
6041fbaed0Stron /* LICENSE
6141fbaed0Stron /* .ad
6241fbaed0Stron /* .fi
6341fbaed0Stron /* The Secure Mailer license must be distributed with this software.
6441fbaed0Stron /* AUTHOR(S)
6541fbaed0Stron /* Wietse Venema
6641fbaed0Stron /* IBM T.J. Watson Research
6741fbaed0Stron /* P.O. Box 704
6841fbaed0Stron /* Yorktown Heights, NY 10598, USA
69*33881f77Schristos /*
70*33881f77Schristos /* Wietse Venema
71*33881f77Schristos /* Google, Inc.
72*33881f77Schristos /* 111 8th Avenue
73*33881f77Schristos /* New York, NY 10011, USA
7441fbaed0Stron /*--*/
7541fbaed0Stron
7641fbaed0Stron /* System libraries. */
7741fbaed0Stron
7841fbaed0Stron #include "sys_defs.h"
7941fbaed0Stron
8041fbaed0Stron /* Utility library. */
8141fbaed0Stron
8241fbaed0Stron #include "msg.h"
8341fbaed0Stron #include "mymalloc.h"
84e6ca80d4Stron #include "myflock.h"
8541fbaed0Stron #include "dict.h"
8641fbaed0Stron
8741fbaed0Stron /* dict_default_lookup - trap unimplemented operation */
8841fbaed0Stron
dict_default_lookup(DICT * dict,const char * unused_key)8941fbaed0Stron static const char *dict_default_lookup(DICT *dict, const char *unused_key)
9041fbaed0Stron {
91a30b880eStron msg_fatal("table %s:%s: lookup operation is not supported",
9241fbaed0Stron dict->type, dict->name);
9341fbaed0Stron }
9441fbaed0Stron
9541fbaed0Stron /* dict_default_update - trap unimplemented operation */
9641fbaed0Stron
dict_default_update(DICT * dict,const char * unused_key,const char * unused_value)97a30b880eStron static int dict_default_update(DICT *dict, const char *unused_key,
9841fbaed0Stron const char *unused_value)
9941fbaed0Stron {
100a30b880eStron msg_fatal("table %s:%s: update operation is not supported",
10141fbaed0Stron dict->type, dict->name);
10241fbaed0Stron }
10341fbaed0Stron
10441fbaed0Stron /* dict_default_delete - trap unimplemented operation */
10541fbaed0Stron
dict_default_delete(DICT * dict,const char * unused_key)10641fbaed0Stron static int dict_default_delete(DICT *dict, const char *unused_key)
10741fbaed0Stron {
108a30b880eStron msg_fatal("table %s:%s: delete operation is not supported",
10941fbaed0Stron dict->type, dict->name);
11041fbaed0Stron }
11141fbaed0Stron
11241fbaed0Stron /* dict_default_sequence - trap unimplemented operation */
11341fbaed0Stron
dict_default_sequence(DICT * dict,int unused_function,const char ** unused_key,const char ** unused_value)11441fbaed0Stron static int dict_default_sequence(DICT *dict, int unused_function,
11541fbaed0Stron const char **unused_key, const char **unused_value)
11641fbaed0Stron {
117a30b880eStron msg_fatal("table %s:%s: sequence operation is not supported",
11841fbaed0Stron dict->type, dict->name);
11941fbaed0Stron }
12041fbaed0Stron
121e6ca80d4Stron /* dict_default_lock - default lock handler */
122e6ca80d4Stron
dict_default_lock(DICT * dict,int operation)123e6ca80d4Stron static int dict_default_lock(DICT *dict, int operation)
124e6ca80d4Stron {
125e6ca80d4Stron if (dict->lock_fd >= 0) {
12616d67a18Stron return (myflock(dict->lock_fd, dict->lock_type, operation));
127e6ca80d4Stron } else {
128e6ca80d4Stron return (0);
129e6ca80d4Stron }
130e6ca80d4Stron }
131e6ca80d4Stron
13241fbaed0Stron /* dict_default_close - trap unimplemented operation */
13341fbaed0Stron
dict_default_close(DICT * dict)13441fbaed0Stron static void dict_default_close(DICT *dict)
13541fbaed0Stron {
136a30b880eStron msg_fatal("table %s:%s: close operation is not supported",
13741fbaed0Stron dict->type, dict->name);
13841fbaed0Stron }
13941fbaed0Stron
14041fbaed0Stron /* dict_alloc - allocate dictionary object, initialize super-class */
14141fbaed0Stron
dict_alloc(const char * dict_type,const char * dict_name,ssize_t size)14241fbaed0Stron DICT *dict_alloc(const char *dict_type, const char *dict_name, ssize_t size)
14341fbaed0Stron {
14441fbaed0Stron DICT *dict = (DICT *) mymalloc(size);
14541fbaed0Stron
14641fbaed0Stron dict->type = mystrdup(dict_type);
14741fbaed0Stron dict->name = mystrdup(dict_name);
14841fbaed0Stron dict->flags = DICT_FLAG_FIXED;
14941fbaed0Stron dict->lookup = dict_default_lookup;
15041fbaed0Stron dict->update = dict_default_update;
15141fbaed0Stron dict->delete = dict_default_delete;
15241fbaed0Stron dict->sequence = dict_default_sequence;
15341fbaed0Stron dict->close = dict_default_close;
154e6ca80d4Stron dict->lock = dict_default_lock;
15516d67a18Stron dict->lock_type = INTERNAL_LOCK;
15641fbaed0Stron dict->lock_fd = -1;
15741fbaed0Stron dict->stat_fd = -1;
15841fbaed0Stron dict->mtime = 0;
15941fbaed0Stron dict->fold_buf = 0;
160a30b880eStron dict->owner.status = DICT_OWNER_UNKNOWN;
161e262b48eSchristos dict->owner.uid = INT_MAX;
162a30b880eStron dict->error = DICT_ERR_NONE;
16316d67a18Stron dict->jbuf = 0;
164e262b48eSchristos dict->utf8_backup = 0;
165*33881f77Schristos dict->file_buf = 0;
166*33881f77Schristos dict->file_b64 = 0;
16741fbaed0Stron return dict;
16841fbaed0Stron }
16941fbaed0Stron
17041fbaed0Stron /* dict_free - super-class destructor */
17141fbaed0Stron
dict_free(DICT * dict)17241fbaed0Stron void dict_free(DICT *dict)
17341fbaed0Stron {
17441fbaed0Stron myfree(dict->type);
17541fbaed0Stron myfree(dict->name);
17616d67a18Stron if (dict->jbuf)
177e262b48eSchristos myfree((void *) dict->jbuf);
178e262b48eSchristos if (dict->utf8_backup)
179e262b48eSchristos myfree((void *) dict->utf8_backup);
180*33881f77Schristos if (dict->file_buf)
181*33881f77Schristos vstring_free(dict->file_buf);
182*33881f77Schristos if (dict->file_b64)
183*33881f77Schristos vstring_free(dict->file_b64);
184e262b48eSchristos myfree((void *) dict);
18541fbaed0Stron }
18616d67a18Stron
18716d67a18Stron /*
18816d67a18Stron * TODO: add a dict_flags() argument to dict_alloc() and handle jump buffer
18916d67a18Stron * allocation there.
19016d67a18Stron */
19116d67a18Stron
19216d67a18Stron /* dict_jmp_alloc - enable exception handling */
19316d67a18Stron
dict_jmp_alloc(DICT * dict)19416d67a18Stron void dict_jmp_alloc(DICT *dict)
19516d67a18Stron {
19616d67a18Stron if (dict->jbuf == 0)
19716d67a18Stron dict->jbuf = (DICT_JMP_BUF *) mymalloc(sizeof(DICT_JMP_BUF));
19816d67a18Stron }
199