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