1 : /*
2 : +----------------------------------------------------------------------+
3 : | PHP Version 6 |
4 : +----------------------------------------------------------------------+
5 : | Copyright (c) 1997-2009 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: mod_user.c 280728 2009-05-18 16:09:51Z jani $ */
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(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_UTF8_STRINGL(a, vl, ln, ZSTR_DUPLICATE); \
45 : }
46 :
47 : static zval *ps_call_handler(zval *func, int argc, zval **argv TSRMLS_DC)
48 66 : {
49 : int i;
50 66 : zval *retval = NULL;
51 :
52 66 : MAKE_STD_ZVAL(retval);
53 66 : if (call_user_function(EG(function_table), NULL, func, retval, argc, argv TSRMLS_CC) == FAILURE) {
54 2 : zval_ptr_dtor(&retval);
55 2 : retval = NULL;
56 : }
57 :
58 144 : for (i = 0; i < argc; i++) {
59 78 : zval_ptr_dtor(&argv[i]);
60 : }
61 :
62 66 : return retval;
63 : }
64 :
65 : #define STDVARS1 \
66 : zval *retval; \
67 : int ret = FAILURE
68 :
69 : #define STDVARS \
70 : STDVARS1; \
71 : char *mdata = PS_GET_MOD_DATA(); \
72 : if (!mdata) { return FAILURE; }
73 :
74 : #define PSF(a) PS(mod_user_names).name.ps_##a
75 :
76 : #define FINISH \
77 : if (retval) { \
78 : convert_to_long(retval); \
79 : ret = Z_LVAL_P(retval); \
80 : zval_ptr_dtor(&retval); \
81 : } \
82 : return ret
83 :
84 : PS_OPEN_FUNC(user)
85 16 : {
86 : zval *args[2];
87 : static char dummy = 0;
88 16 : STDVARS1;
89 :
90 16 : SESS_ZVAL_STRING((char*)save_path, args[0]);
91 16 : SESS_ZVAL_STRING((char*)session_name, args[1]);
92 :
93 16 : retval = ps_call_handler(PSF(open), 2, args TSRMLS_CC);
94 16 : if (retval) {
95 : /* This is necessary to fool the session module. Yes, it's safe to
96 : * use a static. Neither mod_user nor the session module itself will
97 : * ever touch this pointer. It could be set to 0xDEADBEEF for all the
98 : * difference it makes, but for the sake of paranoia it's set to some
99 : * valid value. */
100 16 : PS_SET_MOD_DATA(&dummy);
101 : }
102 :
103 16 : FINISH;
104 : }
105 :
106 : PS_CLOSE_FUNC(user)
107 16 : {
108 16 : STDVARS1;
109 :
110 16 : retval = ps_call_handler(PSF(close), 0, NULL TSRMLS_CC);
111 :
112 16 : PS_SET_MOD_DATA(NULL);
113 :
114 16 : FINISH;
115 : }
116 :
117 : PS_READ_FUNC(user)
118 16 : {
119 : zval *args[1];
120 16 : STDVARS;
121 :
122 16 : SESS_ZVAL_STRING((char*)key, args[0]);
123 :
124 16 : retval = ps_call_handler(PSF(read), 1, args TSRMLS_CC);
125 :
126 16 : if (retval) {
127 14 : if (Z_TYPE_P(retval) == IS_STRING) {
128 0 : *val = estrndup(Z_STRVAL_P(retval), Z_STRLEN_P(retval));
129 0 : *vallen = Z_STRLEN_P(retval);
130 0 : ret = SUCCESS;
131 14 : } else if (Z_TYPE_P(retval) == IS_UNICODE) {
132 11 : char *sval = NULL;
133 : int slen;
134 11 : UErrorCode status = U_ZERO_ERROR;
135 :
136 11 : zend_unicode_to_string_ex(UG(utf8_conv), &sval, &slen, Z_USTRVAL_P(retval), Z_USTRLEN_P(retval), &status);
137 11 : if (U_FAILURE(status)) {
138 0 : if (sval) {
139 0 : efree(sval);
140 : }
141 : } else {
142 11 : *val = sval;
143 11 : *vallen = slen;
144 11 : ret = SUCCESS;
145 : }
146 : }
147 14 : zval_ptr_dtor(&retval);
148 : }
149 :
150 16 : return ret;
151 : }
152 :
153 : PS_WRITE_FUNC(user)
154 12 : {
155 : zval *args[2];
156 12 : STDVARS;
157 :
158 12 : SESS_ZVAL_STRING((char*)key, args[0]);
159 12 : SESS_ZVAL_STRINGN((char*)val, vallen, args[1]);
160 :
161 12 : retval = ps_call_handler(PSF(write), 2, args TSRMLS_CC);
162 :
163 12 : FINISH;
164 : }
165 :
166 : PS_DESTROY_FUNC(user)
167 4 : {
168 : zval *args[1];
169 4 : STDVARS;
170 :
171 4 : SESS_ZVAL_STRING((char*)key, args[0]);
172 :
173 4 : retval = ps_call_handler(PSF(destroy), 1, args TSRMLS_CC);
174 :
175 4 : FINISH;
176 : }
177 :
178 : PS_GC_FUNC(user)
179 2 : {
180 : zval *args[1];
181 2 : STDVARS;
182 :
183 2 : SESS_ZVAL_LONG(maxlifetime, args[0]);
184 :
185 2 : retval = ps_call_handler(PSF(gc), 1, args TSRMLS_CC);
186 :
187 2 : FINISH;
188 : }
189 :
190 : /*
191 : * Local variables:
192 : * tab-width: 4
193 : * c-basic-offset: 4
194 : * End:
195 : * vim600: sw=4 ts=4 fdm=marker
196 : * vim<600: sw=4 ts=4
197 : */
|