xref: /PHP-8.1/ext/dba/dba_dbm.c (revision 01b3fc03)
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