xref: /PHP-7.4/ext/dba/dba_dbm.c (revision 92ac598a)
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