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