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