xref: /PHP-7.1/ext/dba/dba_gdbm.c (revision ccd4716e)
1 /*
2    +----------------------------------------------------------------------+
3    | PHP Version 7                                                        |
4    +----------------------------------------------------------------------+
5    | Copyright (c) 1997-2018 The PHP Group                                |
6    +----------------------------------------------------------------------+
7    | This source file is subject to version 3.01 of the PHP license,      |
8    | that is bundled with this package in the file LICENSE, and is        |
9    | available through the world-wide-web at the following url:           |
10    | http://www.php.net/license/3_01.txt                                  |
11    | If you did not receive a copy of the PHP license and are unable to   |
12    | obtain it through the world-wide-web, please send a note to          |
13    | license@php.net so we can mail you a copy immediately.               |
14    +----------------------------------------------------------------------+
15    | Author: Sascha Schumann <sascha@schumann.cx>                         |
16    +----------------------------------------------------------------------+
17  */
18 
19 /* $Id$ */
20 
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
24 
25 #include "php.h"
26 
27 #if DBA_GDBM
28 #include "php_gdbm.h"
29 
30 #ifdef GDBM_INCLUDE_FILE
31 #include GDBM_INCLUDE_FILE
32 #endif
33 
34 #define GDBM_DATA dba_gdbm_data *dba = info->dbf
35 #define GDBM_GKEY datum gkey; gkey.dptr = (char *) key; gkey.dsize = keylen
36 
37 typedef struct {
38 	GDBM_FILE dbf;
39 	datum nextkey;
40 } dba_gdbm_data;
41 
DBA_OPEN_FUNC(gdbm)42 DBA_OPEN_FUNC(gdbm)
43 {
44 	GDBM_FILE dbf;
45 	int gmode = 0;
46 	int filemode = 0644;
47 
48 	gmode = info->mode == DBA_READER ? GDBM_READER :
49 		info->mode == DBA_WRITER ? GDBM_WRITER :
50 		info->mode == DBA_CREAT  ? GDBM_WRCREAT :
51 		info->mode == DBA_TRUNC ? GDBM_NEWDB : -1;
52 
53 	if(gmode == -1)
54 		return FAILURE; /* not possible */
55 
56 	if(info->argc > 0) {
57 		convert_to_long_ex(&info->argv[0]);
58 		filemode = Z_LVAL(info->argv[0]);
59 	}
60 
61 	dbf = gdbm_open(info->path, 0, gmode, filemode, NULL);
62 
63 	if(dbf) {
64 		info->dbf = pemalloc(sizeof(dba_gdbm_data), info->flags&DBA_PERSISTENT);
65 		memset(info->dbf, 0, sizeof(dba_gdbm_data));
66 		((dba_gdbm_data *) info->dbf)->dbf = dbf;
67 		return SUCCESS;
68 	}
69 	*error = gdbm_strerror(gdbm_errno);
70 	return FAILURE;
71 }
72 
DBA_CLOSE_FUNC(gdbm)73 DBA_CLOSE_FUNC(gdbm)
74 {
75 	GDBM_DATA;
76 
77 	if(dba->nextkey.dptr) free(dba->nextkey.dptr);
78 	gdbm_close(dba->dbf);
79 	pefree(dba, info->flags&DBA_PERSISTENT);
80 }
81 
DBA_FETCH_FUNC(gdbm)82 DBA_FETCH_FUNC(gdbm)
83 {
84 	GDBM_DATA;
85 	datum gval;
86 	char *new = NULL;
87 
88 	GDBM_GKEY;
89 	gval = gdbm_fetch(dba->dbf, gkey);
90 	if(gval.dptr) {
91 		if(newlen) *newlen = gval.dsize;
92 		new = estrndup(gval.dptr, gval.dsize);
93 		free(gval.dptr);
94 	}
95 	return new;
96 }
97 
DBA_UPDATE_FUNC(gdbm)98 DBA_UPDATE_FUNC(gdbm)
99 {
100 	datum gval;
101 	GDBM_DATA;
102 
103 	GDBM_GKEY;
104 	gval.dptr = (char *) val;
105 	gval.dsize = vallen;
106 
107 	switch (gdbm_store(dba->dbf, gkey, gval, mode == 1 ? GDBM_INSERT : GDBM_REPLACE)) {
108 		case 0:
109 			return SUCCESS;
110 		case 1:
111 			return FAILURE;
112 		case -1:
113 			php_error_docref2(NULL, key, val, E_WARNING, "%s", gdbm_strerror(gdbm_errno));
114 			return FAILURE;
115 		default:
116 			php_error_docref2(NULL, key, val, E_WARNING, "Unknown return value");
117 			return FAILURE;
118 	}
119 }
120 
DBA_EXISTS_FUNC(gdbm)121 DBA_EXISTS_FUNC(gdbm)
122 {
123 	GDBM_DATA;
124 	GDBM_GKEY;
125 
126 	return gdbm_exists(dba->dbf, gkey) ? SUCCESS : FAILURE;
127 }
128 
DBA_DELETE_FUNC(gdbm)129 DBA_DELETE_FUNC(gdbm)
130 {
131 	GDBM_DATA;
132 	GDBM_GKEY;
133 
134 	return gdbm_delete(dba->dbf, gkey) == -1 ? FAILURE : SUCCESS;
135 }
136 
DBA_FIRSTKEY_FUNC(gdbm)137 DBA_FIRSTKEY_FUNC(gdbm)
138 {
139 	GDBM_DATA;
140 	datum gkey;
141 	char *key = NULL;
142 
143 	if(dba->nextkey.dptr) {
144 		free(dba->nextkey.dptr);
145 	}
146 
147 	gkey = gdbm_firstkey(dba->dbf);
148 	if(gkey.dptr) {
149 		key = estrndup(gkey.dptr, gkey.dsize);
150 		if(newlen) *newlen = gkey.dsize;
151 		dba->nextkey = gkey;
152 	} else {
153 		dba->nextkey.dptr = NULL;
154 	}
155 	return key;
156 }
157 
DBA_NEXTKEY_FUNC(gdbm)158 DBA_NEXTKEY_FUNC(gdbm)
159 {
160 	GDBM_DATA;
161 	char *nkey = NULL;
162 	datum gkey;
163 
164 	if(!dba->nextkey.dptr) return NULL;
165 
166 	gkey = gdbm_nextkey(dba->dbf, dba->nextkey);
167 	free(dba->nextkey.dptr);
168 	if(gkey.dptr) {
169 		nkey = estrndup(gkey.dptr, gkey.dsize);
170 		if(newlen) *newlen = gkey.dsize;
171 		dba->nextkey = gkey;
172 	} else {
173 		dba->nextkey.dptr = NULL;
174 	}
175 	return nkey;
176 }
177 
DBA_OPTIMIZE_FUNC(gdbm)178 DBA_OPTIMIZE_FUNC(gdbm)
179 {
180 	GDBM_DATA;
181 	gdbm_reorganize(dba->dbf);
182 	return SUCCESS;
183 }
184 
DBA_SYNC_FUNC(gdbm)185 DBA_SYNC_FUNC(gdbm)
186 {
187 	GDBM_DATA;
188 
189 	gdbm_sync(dba->dbf);
190 	return SUCCESS;
191 }
192 
DBA_INFO_FUNC(gdbm)193 DBA_INFO_FUNC(gdbm)
194 {
195 	return estrdup(gdbm_version);
196 }
197 
198 #endif
199 
200 /*
201  * Local variables:
202  * tab-width: 4
203  * c-basic-offset: 4
204  * End:
205  * vim600: sw=4 ts=4 fdm=marker
206  * vim<600: sw=4 ts=4
207  */
208