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 19typedef 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 49typedef struct { 50 char *dptr; 51 int dsize; 52} datum; 53 54EXTCONST 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 */ 75extern DBM *sdbm_open proto((char *, int, int)); 76extern void sdbm_close proto((DBM *)); 77extern datum sdbm_fetch proto((DBM *, datum)); 78extern int sdbm_delete proto((DBM *, datum)); 79extern int sdbm_store proto((DBM *, datum, datum, int)); 80extern datum sdbm_firstkey proto((DBM *)); 81extern datum sdbm_nextkey proto((DBM *)); 82extern int sdbm_exists proto((DBM *, datum)); 83 84/* 85 * other 86 */ 87extern DBM *sdbm_prep proto((char *, char *, int, int)); 88extern 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 182Malloc_t Perl_malloc proto((MEM_SIZE nbytes)); 183Malloc_t Perl_calloc proto((MEM_SIZE elements, MEM_SIZE size)); 184Malloc_t Perl_realloc proto((Malloc_t where, MEM_SIZE nbytes)); 185Free_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