xref: /netbsd-src/external/ibm-public/postfix/dist/src/util/dict_alloc.c (revision 33881f779a77dce6440bdc44610d94de75bebefe)
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