xref: /netbsd-src/external/ibm-public/postfix/dist/src/util/dict_alloc.c (revision 33881f779a77dce6440bdc44610d94de75bebefe)
1 /*	$NetBSD: dict_alloc.c,v 1.3 2020/03/18 19:05:21 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 /*	Wietse Venema
71 /*	Google, Inc.
72 /*	111 8th Avenue
73 /*	New York, NY 10011, USA
74 /*--*/
75 
76 /* System libraries. */
77 
78 #include "sys_defs.h"
79 
80 /* Utility library. */
81 
82 #include "msg.h"
83 #include "mymalloc.h"
84 #include "myflock.h"
85 #include "dict.h"
86 
87 /* dict_default_lookup - trap unimplemented operation */
88 
dict_default_lookup(DICT * dict,const char * unused_key)89 static const char *dict_default_lookup(DICT *dict, const char *unused_key)
90 {
91     msg_fatal("table %s:%s: lookup operation is not supported",
92 	      dict->type, dict->name);
93 }
94 
95 /* dict_default_update - trap unimplemented operation */
96 
dict_default_update(DICT * dict,const char * unused_key,const char * unused_value)97 static int dict_default_update(DICT *dict, const char *unused_key,
98 			               const char *unused_value)
99 {
100     msg_fatal("table %s:%s: update operation is not supported",
101 	      dict->type, dict->name);
102 }
103 
104 /* dict_default_delete - trap unimplemented operation */
105 
dict_default_delete(DICT * dict,const char * unused_key)106 static int dict_default_delete(DICT *dict, const char *unused_key)
107 {
108     msg_fatal("table %s:%s: delete operation is not supported",
109 	      dict->type, dict->name);
110 }
111 
112 /* dict_default_sequence - trap unimplemented operation */
113 
dict_default_sequence(DICT * dict,int unused_function,const char ** unused_key,const char ** unused_value)114 static int dict_default_sequence(DICT *dict, int unused_function,
115 		         const char **unused_key, const char **unused_value)
116 {
117     msg_fatal("table %s:%s: sequence operation is not supported",
118 	      dict->type, dict->name);
119 }
120 
121 /* dict_default_lock - default lock handler */
122 
dict_default_lock(DICT * dict,int operation)123 static int dict_default_lock(DICT *dict, int operation)
124 {
125     if (dict->lock_fd >= 0) {
126 	return (myflock(dict->lock_fd, dict->lock_type, operation));
127     } else {
128 	return (0);
129     }
130 }
131 
132 /* dict_default_close - trap unimplemented operation */
133 
dict_default_close(DICT * dict)134 static void dict_default_close(DICT *dict)
135 {
136     msg_fatal("table %s:%s: close operation is not supported",
137 	      dict->type, dict->name);
138 }
139 
140 /* dict_alloc - allocate dictionary object, initialize super-class */
141 
dict_alloc(const char * dict_type,const char * dict_name,ssize_t size)142 DICT   *dict_alloc(const char *dict_type, const char *dict_name, ssize_t size)
143 {
144     DICT   *dict = (DICT *) mymalloc(size);
145 
146     dict->type = mystrdup(dict_type);
147     dict->name = mystrdup(dict_name);
148     dict->flags = DICT_FLAG_FIXED;
149     dict->lookup = dict_default_lookup;
150     dict->update = dict_default_update;
151     dict->delete = dict_default_delete;
152     dict->sequence = dict_default_sequence;
153     dict->close = dict_default_close;
154     dict->lock = dict_default_lock;
155     dict->lock_type = INTERNAL_LOCK;
156     dict->lock_fd = -1;
157     dict->stat_fd = -1;
158     dict->mtime = 0;
159     dict->fold_buf = 0;
160     dict->owner.status = DICT_OWNER_UNKNOWN;
161     dict->owner.uid = INT_MAX;
162     dict->error = DICT_ERR_NONE;
163     dict->jbuf = 0;
164     dict->utf8_backup = 0;
165     dict->file_buf = 0;
166     dict->file_b64 = 0;
167     return dict;
168 }
169 
170 /* dict_free - super-class destructor */
171 
dict_free(DICT * dict)172 void    dict_free(DICT *dict)
173 {
174     myfree(dict->type);
175     myfree(dict->name);
176     if (dict->jbuf)
177 	myfree((void *) dict->jbuf);
178     if (dict->utf8_backup)
179 	myfree((void *) dict->utf8_backup);
180     if (dict->file_buf)
181 	vstring_free(dict->file_buf);
182     if (dict->file_b64)
183 	vstring_free(dict->file_b64);
184     myfree((void *) dict);
185 }
186 
187  /*
188   * TODO: add a dict_flags() argument to dict_alloc() and handle jump buffer
189   * allocation there.
190   */
191 
192 /* dict_jmp_alloc - enable exception handling */
193 
dict_jmp_alloc(DICT * dict)194 void    dict_jmp_alloc(DICT *dict)
195 {
196     if (dict->jbuf == 0)
197 	dict->jbuf = (DICT_JMP_BUF *) mymalloc(sizeof(DICT_JMP_BUF));
198 }
199