1 | /* |
2 | +----------------------------------------------------------------------+ |
3 | | PHP Version 5 | |
4 | +----------------------------------------------------------------------+ |
5 | | Copyright (c) 1997-2015 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 | /* $Id$ */ |
20 | |
21 | #include "php.h" |
22 | #include "php_session.h" |
23 | #include "mod_user.h" |
24 | |
25 | ps_module ps_mod_user = { |
26 | PS_MOD_SID(user) |
27 | }; |
28 | |
29 | #define SESS_ZVAL_LONG(val, a) \ |
30 | { \ |
31 | MAKE_STD_ZVAL(a); \ |
32 | ZVAL_LONG(a, val); \ |
33 | } |
34 | |
35 | #define SESS_ZVAL_STRING(vl, a) \ |
36 | { \ |
37 | char *__vl = vl; \ |
38 | SESS_ZVAL_STRINGN(__vl, strlen(__vl), a); \ |
39 | } |
40 | |
41 | #define SESS_ZVAL_STRINGN(vl, ln, a) \ |
42 | { \ |
43 | MAKE_STD_ZVAL(a); \ |
44 | ZVAL_STRINGL(a, vl, ln, 1); \ |
45 | } |
46 | |
47 | static zval *ps_call_handler(zval *func, int argc, zval **argv TSRMLS_DC) |
48 | { |
49 | int i; |
50 | zval *retval = NULL; |
51 | |
52 | MAKE_STD_ZVAL(retval); |
53 | if (call_user_function(EG(function_table), NULL, func, retval, argc, argv TSRMLS_CC) == FAILURE) { |
54 | zval_ptr_dtor(&retval); |
55 | retval = NULL; |
56 | } |
57 | |
58 | for (i = 0; i < argc; i++) { |
59 | zval_ptr_dtor(&argv[i]); |
60 | } |
61 | |
62 | return retval; |
63 | } |
64 | |
65 | #define STDVARS \ |
66 | zval *retval = NULL; \ |
67 | int ret = FAILURE |
68 | |
69 | #define PSF(a) PS(mod_user_names).name.ps_##a |
70 | |
71 | #define FINISH \ |
72 | if (retval) { \ |
73 | convert_to_long(retval); \ |
74 | ret = Z_LVAL_P(retval); \ |
75 | zval_ptr_dtor(&retval); \ |
76 | } \ |
77 | return ret |
78 | |
79 | PS_OPEN_FUNC(user) |
80 | { |
81 | zval *args[2]; |
82 | STDVARS; |
83 | |
84 | if (PSF(open) == NULL) { |
85 | php_error_docref(NULL TSRMLS_CC, E_WARNING, |
86 | "user session functions not defined" ); |
87 | |
88 | return FAILURE; |
89 | } |
90 | |
91 | SESS_ZVAL_STRING((char*)save_path, args[0]); |
92 | SESS_ZVAL_STRING((char*)session_name, args[1]); |
93 | |
94 | retval = ps_call_handler(PSF(open), 2, args TSRMLS_CC); |
95 | PS(mod_user_implemented) = 1; |
96 | |
97 | FINISH; |
98 | } |
99 | |
100 | PS_CLOSE_FUNC(user) |
101 | { |
102 | zend_bool bailout = 0; |
103 | STDVARS; |
104 | |
105 | if (!PS(mod_user_implemented)) { |
106 | /* already closed */ |
107 | return SUCCESS; |
108 | } |
109 | |
110 | zend_try { |
111 | retval = ps_call_handler(PSF(close), 0, NULL TSRMLS_CC); |
112 | } zend_catch { |
113 | bailout = 1; |
114 | } zend_end_try(); |
115 | |
116 | PS(mod_user_implemented) = 0; |
117 | |
118 | if (bailout) { |
119 | if (retval) { |
120 | zval_ptr_dtor(&retval); |
121 | } |
122 | zend_bailout(); |
123 | } |
124 | |
125 | FINISH; |
126 | } |
127 | |
128 | PS_READ_FUNC(user) |
129 | { |
130 | zval *args[1]; |
131 | STDVARS; |
132 | |
133 | SESS_ZVAL_STRING((char*)key, args[0]); |
134 | |
135 | retval = ps_call_handler(PSF(read), 1, args TSRMLS_CC); |
136 | |
137 | if (retval) { |
138 | if (Z_TYPE_P(retval) == IS_STRING) { |
139 | *val = estrndup(Z_STRVAL_P(retval), Z_STRLEN_P(retval)); |
140 | *vallen = Z_STRLEN_P(retval); |
141 | ret = SUCCESS; |
142 | } |
143 | zval_ptr_dtor(&retval); |
144 | } |
145 | |
146 | return ret; |
147 | } |
148 | |
149 | PS_WRITE_FUNC(user) |
150 | { |
151 | zval *args[2]; |
152 | STDVARS; |
153 | |
154 | SESS_ZVAL_STRING((char*)key, args[0]); |
155 | SESS_ZVAL_STRINGN((char*)val, vallen, args[1]); |
156 | |
157 | retval = ps_call_handler(PSF(write), 2, args TSRMLS_CC); |
158 | |
159 | FINISH; |
160 | } |
161 | |
162 | PS_DESTROY_FUNC(user) |
163 | { |
164 | zval *args[1]; |
165 | STDVARS; |
166 | |
167 | SESS_ZVAL_STRING((char*)key, args[0]); |
168 | |
169 | retval = ps_call_handler(PSF(destroy), 1, args TSRMLS_CC); |
170 | |
171 | FINISH; |
172 | } |
173 | |
174 | PS_GC_FUNC(user) |
175 | { |
176 | zval *args[1]; |
177 | STDVARS; |
178 | |
179 | SESS_ZVAL_LONG(maxlifetime, args[0]); |
180 | |
181 | retval = ps_call_handler(PSF(gc), 1, args TSRMLS_CC); |
182 | |
183 | FINISH; |
184 | } |
185 | |
186 | PS_CREATE_SID_FUNC(user) |
187 | { |
188 | /* maintain backwards compatibility */ |
189 | if (PSF(create_sid) != NULL) { |
190 | char *id = NULL; |
191 | zval *retval = NULL; |
192 | |
193 | retval = ps_call_handler(PSF(create_sid), 0, NULL TSRMLS_CC); |
194 | |
195 | if (retval) { |
196 | if (Z_TYPE_P(retval) == IS_STRING) { |
197 | id = estrndup(Z_STRVAL_P(retval), Z_STRLEN_P(retval)); |
198 | } |
199 | zval_ptr_dtor(&retval); |
200 | } |
201 | else { |
202 | php_error_docref(NULL TSRMLS_CC, E_ERROR, "No session id returned by function" ); |
203 | return NULL; |
204 | } |
205 | |
206 | if (!id) { |
207 | php_error_docref(NULL TSRMLS_CC, E_ERROR, "Session id must be a string" ); |
208 | return NULL; |
209 | } |
210 | |
211 | return id; |
212 | } |
213 | |
214 | /* function as defined by PS_MOD */ |
215 | return php_session_create_id(mod_data, newlen TSRMLS_CC); |
216 | } |
217 | |
218 | /* |
219 | * Local variables: |
220 | * tab-width: 4 |
221 | * c-basic-offset: 4 |
222 | * End: |
223 | * vim600: sw=4 ts=4 fdm=marker |
224 | * vim<600: sw=4 ts=4 |
225 | */ |
226 | |