1 /* 2 * sdbm - ndbm work-alike hashed database library 3 * based on Per-Ake Larson's Dynamic Hashing algorithms. BIT 18 (1978). 4 * author: oz@nexus.yorku.ca 5 * status: public domain. 6 */ 7 #define DBLKSIZ 4096 8 #define PBLKSIZ 1024 9 #define PAIRMAX 1008 /* arbitrary on PBLKSIZ-N */ 10 #define SPLTMAX 10 /* maximum allowed splits */ 11 /* for a single insertion */ 12 #ifdef VMS 13 #define DIRFEXT ".sdbm_dir" 14 #else 15 #define DIRFEXT ".dir" 16 #endif 17 #define PAGFEXT ".pag" 18 19 typedef struct { 20 int dirf; /* directory file descriptor */ 21 int pagf; /* page file descriptor */ 22 int flags; /* status/error flags, see below */ 23 long maxbno; /* size of dirfile in bits */ 24 long curbit; /* current bit number */ 25 long hmask; /* current hash mask */ 26 long blkptr; /* current block for nextkey */ 27 int keyptr; /* current key for nextkey */ 28 long blkno; /* current page to read/write */ 29 long pagbno; /* current page in pagbuf */ 30 char pagbuf[PBLKSIZ]; /* page file block buffer */ 31 long dirbno; /* current block in dirbuf */ 32 char dirbuf[DBLKSIZ]; /* directory file block buffer */ 33 } DBM; 34 35 #define DBM_RDONLY 0x1 /* data base open read-only */ 36 #define DBM_IOERR 0x2 /* data base I/O error */ 37 38 /* 39 * utility macros 40 */ 41 #define sdbm_rdonly(db) ((db)->flags & DBM_RDONLY) 42 #define sdbm_error(db) ((db)->flags & DBM_IOERR) 43 44 #define sdbm_clearerr(db) ((db)->flags &= ~DBM_IOERR) /* ouch */ 45 46 #define sdbm_dirfno(db) ((db)->dirf) 47 #define sdbm_pagfno(db) ((db)->pagf) 48 49 typedef struct { 50 char *dptr; 51 int dsize; 52 } datum; 53 54 EXTCONST datum nullitem 55 #ifdef DOINIT 56 = {0, 0} 57 #endif 58 ; 59 60 #if defined(__STDC__) || defined(__cplusplus) || defined(CAN_PROTOTYPE) 61 #define proto(p) p 62 #else 63 #define proto(p) () 64 #endif 65 66 /* 67 * flags to sdbm_store 68 */ 69 #define DBM_INSERT 0 70 #define DBM_REPLACE 1 71 72 /* 73 * ndbm interface 74 */ 75 extern DBM *sdbm_open proto((char *, int, int)); 76 extern void sdbm_close proto((DBM *)); 77 extern datum sdbm_fetch proto((DBM *, datum)); 78 extern int sdbm_delete proto((DBM *, datum)); 79 extern int sdbm_store proto((DBM *, datum, datum, int)); 80 extern datum sdbm_firstkey proto((DBM *)); 81 extern datum sdbm_nextkey proto((DBM *)); 82 extern int sdbm_exists proto((DBM *, datum)); 83 84 /* 85 * other 86 */ 87 extern DBM *sdbm_prep proto((char *, char *, int, int)); 88 extern long sdbm_hash proto((char *, int)); 89 90 #ifndef SDBM_ONLY 91 #define dbm_open sdbm_open 92 #define dbm_close sdbm_close 93 #define dbm_fetch sdbm_fetch 94 #define dbm_store sdbm_store 95 #define dbm_delete sdbm_delete 96 #define dbm_firstkey sdbm_firstkey 97 #define dbm_nextkey sdbm_nextkey 98 #define dbm_error sdbm_error 99 #define dbm_clearerr sdbm_clearerr 100 #endif 101 102 /* Most of the following is stolen from perl.h. We don't include 103 perl.h here because we just want the portability parts of perl.h, 104 not everything else. 105 */ 106 #ifndef H_PERL /* Include guard */ 107 #include "embed.h" /* Follow all the global renamings. */ 108 109 /* 110 * The following contortions are brought to you on behalf of all the 111 * standards, semi-standards, de facto standards, not-so-de-facto standards 112 * of the world, as well as all the other botches anyone ever thought of. 113 * The basic theory is that if we work hard enough here, the rest of the 114 * code can be a lot prettier. Well, so much for theory. Sorry, Henry... 115 */ 116 117 #include <errno.h> 118 #ifdef HAS_SOCKET 119 # ifdef I_NET_ERRNO 120 # include <net/errno.h> 121 # endif 122 #endif 123 124 #if defined(__STDC__) || defined(_AIX) || defined(__stdc__) || defined(__cplusplus) 125 # define STANDARD_C 1 126 #endif 127 128 #include <stdio.h> 129 #include <ctype.h> 130 #include <setjmp.h> 131 132 #if defined(I_UNISTD) 133 #include <unistd.h> 134 #endif 135 136 #ifdef VMS 137 # include <file.h> 138 # include <unixio.h> 139 #endif 140 141 #ifdef I_SYS_PARAM 142 # if !defined(MSDOS) && !defined(WIN32) && !defined(VMS) 143 # ifdef PARAM_NEEDS_TYPES 144 # include <sys/types.h> 145 # endif 146 # include <sys/param.h> 147 # endif 148 #endif 149 150 #ifndef _TYPES_ /* If types.h defines this it's easy. */ 151 # ifndef major /* Does everyone's types.h define this? */ 152 # include <sys/types.h> 153 # endif 154 #endif 155 156 #include <sys/stat.h> 157 158 #ifndef SEEK_SET 159 # ifdef L_SET 160 # define SEEK_SET L_SET 161 # else 162 # define SEEK_SET 0 /* Wild guess. */ 163 # endif 164 #endif 165 166 /* Use all the "standard" definitions? */ 167 #if defined(STANDARD_C) && defined(I_STDLIB) 168 # include <stdlib.h> 169 #endif /* STANDARD_C */ 170 171 #define MEM_SIZE Size_t 172 173 /* This comes after <stdlib.h> so we don't try to change the standard 174 * library prototypes; we'll use our own instead. */ 175 176 #if defined(MYMALLOC) && !defined(PERL_POLLUTE_MALLOC) 177 # define malloc Perl_malloc 178 # define calloc Perl_calloc 179 # define realloc Perl_realloc 180 # define free Perl_mfree 181 182 Malloc_t Perl_malloc proto((MEM_SIZE nbytes)); 183 Malloc_t Perl_calloc proto((MEM_SIZE elements, MEM_SIZE size)); 184 Malloc_t Perl_realloc proto((Malloc_t where, MEM_SIZE nbytes)); 185 Free_t Perl_mfree proto((Malloc_t where)); 186 #endif /* MYMALLOC */ 187 188 #ifdef I_STRING 189 # ifndef __ultrix__ 190 # include <string.h> 191 # endif 192 #else 193 # include <strings.h> 194 #endif 195 196 #ifdef I_MEMORY 197 #include <memory.h> 198 #endif 199 200 #ifdef __cplusplus 201 #define HAS_MEMCPY 202 #endif 203 204 #ifdef HAS_MEMCPY 205 # if !defined(STANDARD_C) && !defined(I_STRING) && !defined(I_MEMORY) 206 # ifndef memcpy 207 extern char * memcpy proto((char*, char*, int)); 208 # endif 209 # endif 210 #else 211 # ifndef memcpy 212 # ifdef HAS_BCOPY 213 # define memcpy(d,s,l) bcopy(s,d,l) 214 # else 215 # define memcpy(d,s,l) my_bcopy(s,d,l) 216 # endif 217 # endif 218 #endif /* HAS_MEMCPY */ 219 220 #ifdef HAS_MEMSET 221 # if !defined(STANDARD_C) && !defined(I_STRING) && !defined(I_MEMORY) 222 # ifndef memset 223 extern char *memset proto((char*, int, int)); 224 # endif 225 # endif 226 # define memzero(d,l) memset(d,0,l) 227 #else 228 # ifndef memzero 229 # ifdef HAS_BZERO 230 # define memzero(d,l) bzero(d,l) 231 # else 232 # define memzero(d,l) my_bzero(d,l) 233 # endif 234 # endif 235 #endif /* HAS_MEMSET */ 236 237 #if defined(mips) && defined(ultrix) && !defined(__STDC__) 238 # undef HAS_MEMCMP 239 #endif 240 241 #if defined(HAS_MEMCMP) && defined(HAS_SANE_MEMCMP) 242 # if !defined(STANDARD_C) && !defined(I_STRING) && !defined(I_MEMORY) 243 # ifndef memcmp 244 extern int memcmp proto((char*, char*, int)); 245 # endif 246 # endif 247 # ifdef BUGGY_MSC 248 # pragma function(memcmp) 249 # endif 250 #else 251 # ifndef memcmp 252 /* maybe we should have included the full embedding header... */ 253 # ifdef NO_EMBED 254 # define memcmp my_memcmp 255 # else 256 # define memcmp Perl_my_memcmp 257 # endif 258 #ifndef __cplusplus 259 extern int memcmp proto((char*, char*, int)); 260 #endif 261 # endif 262 #endif /* HAS_MEMCMP */ 263 264 #ifndef HAS_BCMP 265 # ifndef bcmp 266 # define bcmp(s1,s2,l) memcmp(s1,s2,l) 267 # endif 268 #endif /* !HAS_BCMP */ 269 270 #ifdef HAS_MEMCMP 271 # define memNE(s1,s2,l) (memcmp(s1,s2,l)) 272 # define memEQ(s1,s2,l) (!memcmp(s1,s2,l)) 273 #else 274 # define memNE(s1,s2,l) (bcmp(s1,s2,l)) 275 # define memEQ(s1,s2,l) (!bcmp(s1,s2,l)) 276 #endif 277 278 #ifdef I_NETINET_IN 279 # ifdef VMS 280 # include <in.h> 281 # else 282 # include <netinet/in.h> 283 # endif 284 #endif 285 286 #endif /* Include guard */ 287 288