1 /*
2 +----------------------------------------------------------------------+
3 | PHP Version 7 |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 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 #ifdef HAVE_CONFIG_H
20 #include "config.h"
21 #endif
22
23 #include "php.h"
24
25 #if DBA_DBM
26 #include "php_dbm.h"
27
28 #ifdef DBM_INCLUDE_FILE
29 #include DBM_INCLUDE_FILE
30 #endif
31 #if DBA_GDBM
32 #include "php_gdbm.h"
33 #endif
34
35 #include <unistd.h>
36 #include <sys/types.h>
37 #include <sys/stat.h>
38 #include <fcntl.h>
39
40 #define DBM_DATA dba_dbm_data *dba = info->dbf
41 #define DBM_GKEY datum gkey; gkey.dptr = (char *) key; gkey.dsize = keylen
42
43 #define TRUNC_IT(extension, mode) \
44 snprintf(buf, MAXPATHLEN, "%s" extension, info->path); \
45 buf[MAXPATHLEN-1] = '\0'; \
46 if((fd = VCWD_OPEN_MODE(buf, O_CREAT | mode | O_WRONLY, filemode)) == -1) \
47 return FAILURE; \
48 close(fd);
49
50
51 typedef struct {
52 datum nextkey;
53 } dba_dbm_data;
54
DBA_OPEN_FUNC(dbm)55 DBA_OPEN_FUNC(dbm)
56 {
57 int fd;
58 int filemode = 0644;
59
60 if(info->argc > 0) {
61 filemode = zval_get_long(&info->argv[0]);
62 }
63
64 if(info->mode == DBA_TRUNC) {
65 char buf[MAXPATHLEN];
66
67 /* dbm/ndbm original */
68 TRUNC_IT(".pag", O_TRUNC);
69 TRUNC_IT(".dir", O_TRUNC);
70 }
71
72 if(info->mode == DBA_CREAT) {
73 char buf[MAXPATHLEN];
74
75 TRUNC_IT(".pag", 0);
76 TRUNC_IT(".dir", 0);
77 }
78
79 if(dbminit((char *) info->path) == -1) {
80 return FAILURE;
81 }
82
83 info->dbf = pemalloc(sizeof(dba_dbm_data), info->flags&DBA_PERSISTENT);
84 memset(info->dbf, 0, sizeof(dba_dbm_data));
85 return SUCCESS;
86 }
87
DBA_CLOSE_FUNC(dbm)88 DBA_CLOSE_FUNC(dbm)
89 {
90 pefree(info->dbf, info->flags&DBA_PERSISTENT);
91 dbmclose();
92 }
93
DBA_FETCH_FUNC(dbm)94 DBA_FETCH_FUNC(dbm)
95 {
96 datum gval;
97 char *new = NULL;
98
99 DBM_GKEY;
100 gval = fetch(gkey);
101 if(gval.dptr) {
102 if(newlen) *newlen = gval.dsize;
103 new = estrndup(gval.dptr, gval.dsize);
104 }
105 return new;
106 }
107
DBA_UPDATE_FUNC(dbm)108 DBA_UPDATE_FUNC(dbm)
109 {
110 datum gval;
111
112 DBM_GKEY;
113
114 if (mode == 1) { /* insert */
115 gval = fetch(gkey);
116 if(gval.dptr) {
117 return FAILURE;
118 }
119 }
120
121 gval.dptr = (char *) val;
122 gval.dsize = vallen;
123
124 return (store(gkey, gval) == -1 ? FAILURE : SUCCESS);
125 }
126
DBA_EXISTS_FUNC(dbm)127 DBA_EXISTS_FUNC(dbm)
128 {
129 datum gval;
130 DBM_GKEY;
131
132 gval = fetch(gkey);
133 if(gval.dptr) {
134 return SUCCESS;
135 }
136 return FAILURE;
137 }
138
DBA_DELETE_FUNC(dbm)139 DBA_DELETE_FUNC(dbm)
140 {
141 DBM_GKEY;
142 return(delete(gkey) == -1 ? FAILURE : SUCCESS);
143 }
144
DBA_FIRSTKEY_FUNC(dbm)145 DBA_FIRSTKEY_FUNC(dbm)
146 {
147 DBM_DATA;
148 datum gkey;
149 char *key = NULL;
150
151 gkey = firstkey();
152 if(gkey.dptr) {
153 if(newlen) *newlen = gkey.dsize;
154 key = estrndup(gkey.dptr, gkey.dsize);
155 dba->nextkey = gkey;
156 } else
157 dba->nextkey.dptr = NULL;
158 return key;
159 }
160
DBA_NEXTKEY_FUNC(dbm)161 DBA_NEXTKEY_FUNC(dbm)
162 {
163 DBM_DATA;
164 datum gkey;
165 char *nkey = NULL;
166
167 if(!dba->nextkey.dptr) return NULL;
168
169 gkey = nextkey(dba->nextkey);
170 if(gkey.dptr) {
171 if(newlen) *newlen = gkey.dsize;
172 nkey = estrndup(gkey.dptr, gkey.dsize);
173 dba->nextkey = gkey;
174 } else
175 dba->nextkey.dptr = NULL;
176 return nkey;
177 }
178
DBA_OPTIMIZE_FUNC(dbm)179 DBA_OPTIMIZE_FUNC(dbm)
180 {
181 /* dummy */
182 return SUCCESS;
183 }
184
DBA_SYNC_FUNC(dbm)185 DBA_SYNC_FUNC(dbm)
186 {
187 return SUCCESS;
188 }
189
DBA_INFO_FUNC(dbm)190 DBA_INFO_FUNC(dbm)
191 {
192 #if DBA_GDBM
193 if (!strcmp(DBM_VERSION, "GDBM"))
194 {
195 return dba_info_gdbm(hnd, info);
196 }
197 #endif
198 return estrdup(DBM_VERSION);
199 }
200
201 #endif
202