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