1 /*
2 +----------------------------------------------------------------------+
3 | Copyright (c) The PHP Group |
4 +----------------------------------------------------------------------+
5 | This source file is subject to version 3.01 of the PHP license, |
6 | that is bundled with this package in the file LICENSE, and is |
7 | available through the world-wide-web at the following url: |
8 | https://www.php.net/license/3_01.txt |
9 | If you did not receive a copy of the PHP license and are unable to |
10 | obtain it through the world-wide-web, please send a note to |
11 | license@php.net so we can mail you a copy immediately. |
12 +----------------------------------------------------------------------+
13 | Author: Sascha Schumann <sascha@schumann.cx> |
14 +----------------------------------------------------------------------+
15 */
16
17 #ifdef HAVE_CONFIG_H
18 #include <config.h>
19 #endif
20
21 #include "php.h"
22
23 #ifdef DBA_DBM
24 #include "php_dbm.h"
25
26 #ifdef DBM_INCLUDE_FILE
27 #include DBM_INCLUDE_FILE
28 #endif
29 #ifdef DBA_GDBM
30 #include "php_gdbm.h"
31 #endif
32
33 #include <unistd.h>
34 #include <sys/types.h>
35 #include <sys/stat.h>
36 #include <fcntl.h>
37
38 #define TRUNC_IT(extension, mode) \
39 snprintf(buf, MAXPATHLEN, "%s" extension, ZSTR_VAL(info->path)); \
40 buf[MAXPATHLEN-1] = '\0'; \
41 if((fd = VCWD_OPEN_MODE(buf, O_CREAT | mode | O_WRONLY, filemode)) == -1) \
42 return FAILURE; \
43 close(fd);
44
45
46 typedef struct {
47 datum nextkey;
48 } dba_dbm_data;
49
DBA_OPEN_FUNC(dbm)50 DBA_OPEN_FUNC(dbm)
51 {
52 int fd;
53 int filemode = info->file_permission;
54
55 if(info->mode == DBA_TRUNC) {
56 char buf[MAXPATHLEN];
57
58 /* dbm/ndbm original */
59 TRUNC_IT(".pag", O_TRUNC);
60 TRUNC_IT(".dir", O_TRUNC);
61 }
62
63 if(info->mode == DBA_CREAT) {
64 char buf[MAXPATHLEN];
65
66 TRUNC_IT(".pag", 0);
67 TRUNC_IT(".dir", 0);
68 }
69
70 if(dbminit((char *) ZSTR_VAL(info->path)) == -1) {
71 return FAILURE;
72 }
73
74 info->dbf = pemalloc(sizeof(dba_dbm_data), info->flags&DBA_PERSISTENT);
75 memset(info->dbf, 0, sizeof(dba_dbm_data));
76 return SUCCESS;
77 }
78
DBA_CLOSE_FUNC(dbm)79 DBA_CLOSE_FUNC(dbm)
80 {
81 pefree(info->dbf, info->flags&DBA_PERSISTENT);
82 dbmclose();
83 }
84
DBA_FETCH_FUNC(dbm)85 DBA_FETCH_FUNC(dbm)
86 {
87 datum gval;
88 datum gkey;
89
90 gkey.dptr = ZSTR_VAL(key);
91 gkey.dsize = ZSTR_LEN(key);
92 gval = fetch(gkey);
93 if (gval.dptr) {
94 return zend_string_init(gval.dptr, gval.dsize, /* persistent */ false);
95 }
96 return NULL;
97 }
98
DBA_UPDATE_FUNC(dbm)99 DBA_UPDATE_FUNC(dbm)
100 {
101 datum gval;
102 datum gkey;
103
104 gkey.dptr = ZSTR_VAL(key);
105 gkey.dsize = ZSTR_LEN(key);
106
107 if (mode == 1) { /* insert */
108 gval = fetch(gkey);
109 if (gval.dptr) {
110 return FAILURE;
111 }
112 }
113
114 gval.dptr = ZSTR_VAL(val);
115 gval.dsize = ZSTR_LEN(val);
116
117 return (store(gkey, gval) == -1 ? FAILURE : SUCCESS);
118 }
119
DBA_EXISTS_FUNC(dbm)120 DBA_EXISTS_FUNC(dbm)
121 {
122 datum gval;
123 datum gkey;
124
125 gkey.dptr = ZSTR_VAL(key);
126 gkey.dsize = ZSTR_LEN(key);
127
128 gval = fetch(gkey);
129 if (gval.dptr) {
130 return SUCCESS;
131 }
132 return FAILURE;
133 }
134
DBA_DELETE_FUNC(dbm)135 DBA_DELETE_FUNC(dbm)
136 {
137 datum gkey;
138
139 gkey.dptr = ZSTR_VAL(key);
140 gkey.dsize = ZSTR_LEN(key);
141 return(delete(gkey) == -1 ? FAILURE : SUCCESS);
142 }
143
DBA_FIRSTKEY_FUNC(dbm)144 DBA_FIRSTKEY_FUNC(dbm)
145 {
146 dba_dbm_data *dba = info->dbf;
147 datum gkey;
148 zend_string *key = NULL;
149
150 gkey = firstkey();
151 if (gkey.dptr) {
152 key = zend_string_init(gkey.dptr, gkey.dsize, /* persistent */ false);
153 dba->nextkey = gkey;
154 } else {
155 dba->nextkey.dptr = NULL;
156 }
157 return key;
158 }
159
DBA_NEXTKEY_FUNC(dbm)160 DBA_NEXTKEY_FUNC(dbm)
161 {
162 dba_dbm_data *dba = info->dbf;
163 datum gkey;
164 zend_string *key = NULL;
165
166 if (!dba->nextkey.dptr) { return NULL; }
167
168 gkey = nextkey(dba->nextkey);
169 if (gkey.dptr) {
170 key = zend_string_init(gkey.dptr, gkey.dsize, /* persistent */ false);
171 dba->nextkey = gkey;
172 } else {
173 dba->nextkey.dptr = NULL;
174 }
175 return key;
176 }
177
DBA_OPTIMIZE_FUNC(dbm)178 DBA_OPTIMIZE_FUNC(dbm)
179 {
180 /* dummy */
181 return SUCCESS;
182 }
183
DBA_SYNC_FUNC(dbm)184 DBA_SYNC_FUNC(dbm)
185 {
186 return SUCCESS;
187 }
188
DBA_INFO_FUNC(dbm)189 DBA_INFO_FUNC(dbm)
190 {
191 #ifdef DBA_GDBM
192 if (!strcmp(DBM_VERSION, "GDBM"))
193 {
194 return dba_info_gdbm(hnd, info);
195 }
196 #endif
197 return estrdup(DBM_VERSION);
198 }
199
200 #endif
201