1 #include "EXTERN.h"
2 #include "perl.h"
3 #include "XSUB.h"
4 #undef NDBM_HEADER_USES_PROTOTYPES
5 #if defined(I_GDBM_NDBM)
6 #  ifdef GDBM_NDBM_H_USES_PROTOTYPES
7 #    define NDBM_HEADER_USES_PROTOTYPES
8 START_EXTERN_C
9 #  endif
10 #  include <gdbm-ndbm.h> /* Debian compatibility version */
11 #elif defined(I_GDBMNDBM)
12 #  ifdef GDBMNDBM_H_USES_PROTOTYPES
13 #    define NDBM_HEADER_USES_PROTOTYPES
14 START_EXTERN_C
15 #  endif
16 #  include <gdbm/ndbm.h> /* RedHat compatibility version */
17 #elif defined(I_NDBM)
18 #  ifdef NDBM_H_USES_PROTOTYPES
19 #    define NDBM_HEADER_USES_PROTOTYPES
20 START_EXTERN_C
21 #  endif
22 #  include <ndbm.h>
23 #endif
24 #ifdef NDBM_HEADER_USES_PROTOTYPES
25 END_EXTERN_C
26 #endif
27 
28 typedef struct {
29 	DBM * 	dbp ;
30 	SV *    filter_fetch_key ;
31 	SV *    filter_store_key ;
32 	SV *    filter_fetch_value ;
33 	SV *    filter_store_value ;
34 	int     filtering ;
35 	} NDBM_File_type;
36 
37 typedef NDBM_File_type * NDBM_File ;
38 typedef datum datum_key ;
39 typedef datum datum_value ;
40 
41 
42 #if defined(__cplusplus) && !defined(NDBM_HEADER_USES_PROTOTYPES)
43 /* gdbm's header file used for compatibility with gdbm */
44 /* isn't compatible to C++ syntax, so we need these */
45 /* declarations to make everyone happy. */
46 EXTERN_C DBM *dbm_open(const char *, int, mode_t);
47 EXTERN_C void dbm_close(DBM *);
48 EXTERN_C datum dbm_fetch(DBM *, datum);
49 EXTERN_C int dbm_store(DBM *, datum, datum, int);
50 EXTERN_C int dbm_delete(DBM *, datum);
51 EXTERN_C datum dbm_firstkey(DBM *);
52 EXTERN_C datum dbm_nextkey(DBM *);
53 #endif
54 
55 MODULE = NDBM_File	PACKAGE = NDBM_File	PREFIX = ndbm_
56 
57 NDBM_File
58 ndbm_TIEHASH(dbtype, filename, flags, mode)
59 	char *		dbtype
60 	char *		filename
61 	int		flags
62 	int		mode
63 	CODE:
64 	{
65 	    DBM * 	dbp ;
66 
67 	    RETVAL = NULL ;
68 	    if ((dbp =  dbm_open(filename, flags, mode))) {
69 	        RETVAL = (NDBM_File)safemalloc(sizeof(NDBM_File_type)) ;
70     	        Zero(RETVAL, 1, NDBM_File_type) ;
71 		RETVAL->dbp = dbp ;
72 	    }
73 
74 	}
75 	OUTPUT:
76 	  RETVAL
77 
78 void
79 ndbm_DESTROY(db)
80 	NDBM_File	db
81 	CODE:
82 	dbm_close(db->dbp);
83 	safefree(db);
84 
85 #define ndbm_FETCH(db,key)			dbm_fetch(db->dbp,key)
86 datum_value
87 ndbm_FETCH(db, key)
88 	NDBM_File	db
89 	datum_key	key
90 
91 #define ndbm_STORE(db,key,value,flags)		dbm_store(db->dbp,key,value,flags)
92 int
93 ndbm_STORE(db, key, value, flags = DBM_REPLACE)
94 	NDBM_File	db
95 	datum_key	key
96 	datum_value	value
97 	int		flags
98     CLEANUP:
99 	if (RETVAL) {
100 	    if (RETVAL < 0 && errno == EPERM)
101 		croak("No write permission to ndbm file");
102 	    croak("ndbm store returned %d, errno %d, key \"%s\"",
103 			RETVAL,errno,key.dptr);
104 	    dbm_clearerr(db->dbp);
105 	}
106 
107 #define ndbm_DELETE(db,key)			dbm_delete(db->dbp,key)
108 int
109 ndbm_DELETE(db, key)
110 	NDBM_File	db
111 	datum_key	key
112 
113 #define ndbm_FIRSTKEY(db)			dbm_firstkey(db->dbp)
114 datum_key
115 ndbm_FIRSTKEY(db)
116 	NDBM_File	db
117 
118 #define ndbm_NEXTKEY(db,key)			dbm_nextkey(db->dbp)
119 datum_key
120 ndbm_NEXTKEY(db, key)
121 	NDBM_File	db
122 	datum_key	key = NO_INIT
123 
124 #define ndbm_error(db)				dbm_error(db->dbp)
125 int
126 ndbm_error(db)
127 	NDBM_File	db
128 
129 #define ndbm_clearerr(db)			dbm_clearerr(db->dbp)
130 void
131 ndbm_clearerr(db)
132 	NDBM_File	db
133 
134 
135 SV *
136 filter_fetch_key(db, code)
137 	NDBM_File	db
138 	SV *		code
139 	SV *		RETVAL = &PL_sv_undef ;
140 	CODE:
141 	    DBM_setFilter(db->filter_fetch_key, code) ;
142 
143 SV *
144 filter_store_key(db, code)
145 	NDBM_File	db
146 	SV *		code
147 	SV *		RETVAL =  &PL_sv_undef ;
148 	CODE:
149 	    DBM_setFilter(db->filter_store_key, code) ;
150 
151 SV *
152 filter_fetch_value(db, code)
153 	NDBM_File	db
154 	SV *		code
155 	SV *		RETVAL =  &PL_sv_undef ;
156 	CODE:
157 	    DBM_setFilter(db->filter_fetch_value, code) ;
158 
159 SV *
160 filter_store_value(db, code)
161 	NDBM_File	db
162 	SV *		code
163 	SV *		RETVAL =  &PL_sv_undef ;
164 	CODE:
165 	    DBM_setFilter(db->filter_store_value, code) ;
166 
167