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