xref: /netbsd-src/external/ibm-public/postfix/dist/src/util/dict_alloc.c (revision bdc22b2e01993381dcefeff2bc9b56ca75a4235c)
1 /*	$NetBSD: dict_alloc.c,v 1.2 2017/02/14 01:16:49 christos Exp $	*/
2 
3 /*++
4 /* NAME
5 /*	dict_alloc 3
6 /* SUMMARY
7 /*	dictionary memory manager
8 /* SYNOPSIS
9 /*	#include <dict.h>
10 /*
11 /*	DICT	*dict_alloc(dict_type, dict_name, size)
12 /*	const char *dict_type;
13 /*	const char *dict_name;
14 /*	ssize_t	size;
15 /*
16 /*	void	dict_free(dict)
17 /*	DICT	*ptr;
18 /*
19 /*	void	dict_jmp_alloc(dict)
20 /*	DICT	*ptr;
21 /* DESCRIPTION
22 /*	dict_alloc() allocates memory for a dictionary structure of
23 /*	\fIsize\fR bytes, initializes all generic dictionary
24 /*	properties to default settings,
25 /*	and installs default methods that do not support any operation.
26 /*	The caller is supposed to override the default methods with
27 /*	ones that it supports.
28 /*	The purpose of the default methods is to trap an attempt to
29 /*	invoke an unsupported method.
30 /*
31 /*	One exception is the default lock function.  When the
32 /*	dictionary provides a file handle for locking, the default
33 /*	lock function returns the result from myflock with the
34 /*	locking method specified in the lock_type member, otherwise
35 /*	it returns 0. Presently, the lock function is used only to
36 /*	implement the DICT_FLAG_OPEN_LOCK feature (lock the database
37 /*	exclusively after it is opened) for databases that are not
38 /*	multi-writer safe.
39 /*
40 /*	dict_free() releases memory and cleans up after dict_alloc().
41 /*	It is up to the caller to dispose of any memory that was allocated
42 /*	by the caller.
43 /*
44 /*	dict_jmp_alloc() implements preliminary support for exception
45 /*	handling. This will eventually be built into dict_alloc().
46 /*
47 /*	Arguments:
48 /* .IP dict_type
49 /*	The official name for this type of dictionary, as used by
50 /*	dict_open(3) etc. This is stored under the \fBtype\fR
51 /*	member.
52 /* .IP dict_name
53 /*	Dictionary name. This is stored as the \fBname\fR member.
54 /* .IP size
55 /*	The size in bytes of the dictionary subclass structure instance.
56 /* SEE ALSO
57 /*	dict(3)
58 /* DIAGNOSTICS
59 /*	Fatal errors: the process invokes a default method.
60 /* LICENSE
61 /* .ad
62 /* .fi
63 /*	The Secure Mailer license must be distributed with this software.
64 /* AUTHOR(S)
65 /*	Wietse Venema
66 /*	IBM T.J. Watson Research
67 /*	P.O. Box 704
68 /*	Yorktown Heights, NY 10598, USA
69 /*--*/
70 
71 /* System libraries. */
72 
73 #include "sys_defs.h"
74 
75 /* Utility library. */
76 
77 #include "msg.h"
78 #include "mymalloc.h"
79 #include "myflock.h"
80 #include "dict.h"
81 
82 /* dict_default_lookup - trap unimplemented operation */
83 
84 static const char *dict_default_lookup(DICT *dict, const char *unused_key)
85 {
86     msg_fatal("table %s:%s: lookup operation is not supported",
87 	      dict->type, dict->name);
88 }
89 
90 /* dict_default_update - trap unimplemented operation */
91 
92 static int dict_default_update(DICT *dict, const char *unused_key,
93 			               const char *unused_value)
94 {
95     msg_fatal("table %s:%s: update operation is not supported",
96 	      dict->type, dict->name);
97 }
98 
99 /* dict_default_delete - trap unimplemented operation */
100 
101 static int dict_default_delete(DICT *dict, const char *unused_key)
102 {
103     msg_fatal("table %s:%s: delete operation is not supported",
104 	      dict->type, dict->name);
105 }
106 
107 /* dict_default_sequence - trap unimplemented operation */
108 
109 static int dict_default_sequence(DICT *dict, int unused_function,
110 		         const char **unused_key, const char **unused_value)
111 {
112     msg_fatal("table %s:%s: sequence operation is not supported",
113 	      dict->type, dict->name);
114 }
115 
116 /* dict_default_lock - default lock handler */
117 
118 static int dict_default_lock(DICT *dict, int operation)
119 {
120     if (dict->lock_fd >= 0) {
121 	return (myflock(dict->lock_fd, dict->lock_type, operation));
122     } else {
123 	return (0);
124     }
125 }
126 
127 /* dict_default_close - trap unimplemented operation */
128 
129 static void dict_default_close(DICT *dict)
130 {
131     msg_fatal("table %s:%s: close operation is not supported",
132 	      dict->type, dict->name);
133 }
134 
135 /* dict_alloc - allocate dictionary object, initialize super-class */
136 
137 DICT   *dict_alloc(const char *dict_type, const char *dict_name, ssize_t size)
138 {
139     DICT   *dict = (DICT *) mymalloc(size);
140 
141     dict->type = mystrdup(dict_type);
142     dict->name = mystrdup(dict_name);
143     dict->flags = DICT_FLAG_FIXED;
144     dict->lookup = dict_default_lookup;
145     dict->update = dict_default_update;
146     dict->delete = dict_default_delete;
147     dict->sequence = dict_default_sequence;
148     dict->close = dict_default_close;
149     dict->lock = dict_default_lock;
150     dict->lock_type = INTERNAL_LOCK;
151     dict->lock_fd = -1;
152     dict->stat_fd = -1;
153     dict->mtime = 0;
154     dict->fold_buf = 0;
155     dict->owner.status = DICT_OWNER_UNKNOWN;
156     dict->owner.uid = INT_MAX;
157     dict->error = DICT_ERR_NONE;
158     dict->jbuf = 0;
159     dict->utf8_backup = 0;
160     return dict;
161 }
162 
163 /* dict_free - super-class destructor */
164 
165 void    dict_free(DICT *dict)
166 {
167     myfree(dict->type);
168     myfree(dict->name);
169     if (dict->jbuf)
170 	myfree((void *) dict->jbuf);
171     if (dict->utf8_backup)
172 	myfree((void *) dict->utf8_backup);
173     myfree((void *) dict);
174 }
175 
176  /*
177   * TODO: add a dict_flags() argument to dict_alloc() and handle jump buffer
178   * allocation there.
179   */
180 
181 /* dict_jmp_alloc - enable exception handling */
182 
183 void    dict_jmp_alloc(DICT *dict)
184 {
185     if (dict->jbuf == 0)
186 	dict->jbuf = (DICT_JMP_BUF *) mymalloc(sizeof(DICT_JMP_BUF));
187 }
188