1 /*
2 +----------------------------------------------------------------------+
3 | PHP Version 5 |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 1997-2016 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: Kristian Koehntopp <kris@koehntopp.de> |
16 +----------------------------------------------------------------------+
17 */
18
19 /* $Id: cde03aacd1a1218dcad9dabc2f284594a0a4aa16 $ */
20
21 /* {{{ includes & prototypes */
22
23 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
26
27 #include "php.h"
28 #include "php_streams.h"
29
30 #if HAVE_LIBRECODE
31
32 /* For recode 3.5 */
33 #if HAVE_BROKEN_RECODE
34 extern char *program_name;
35 char *program_name = "php";
36 #endif
37
38 #ifdef HAVE_STDBOOL_H
39 # include <stdbool.h>
40 #else
41 typedef enum {false = 0, true = 1} bool;
42 #endif
43
44 #include <stdio.h>
45 #include <sys/types.h>
46 #include <unistd.h>
47 #include <recode.h>
48
49 #include "php_recode.h"
50 #include "ext/standard/info.h"
51 #include "ext/standard/file.h"
52 #include "ext/standard/php_string.h"
53
54 /* }}} */
55
56 ZEND_BEGIN_MODULE_GLOBALS(recode)
57 RECODE_OUTER outer;
58 ZEND_END_MODULE_GLOBALS(recode)
59
60 #ifdef ZTS
61 # define ReSG(v) TSRMG(recode_globals_id, zend_recode_globals *, v)
62 #else
63 # define ReSG(v) (recode_globals.v)
64 #endif
65
66 ZEND_DECLARE_MODULE_GLOBALS(recode)
67 static PHP_GINIT_FUNCTION(recode);
68
69 /* {{{ arginfo */
70 ZEND_BEGIN_ARG_INFO_EX(arginfo_recode_string, 0, 0, 2)
71 ZEND_ARG_INFO(0, request)
72 ZEND_ARG_INFO(0, str)
73 ZEND_END_ARG_INFO()
74
75 ZEND_BEGIN_ARG_INFO_EX(arginfo_recode_file, 0, 0, 3)
76 ZEND_ARG_INFO(0, request)
77 ZEND_ARG_INFO(0, input)
78 ZEND_ARG_INFO(0, output)
79 ZEND_END_ARG_INFO()
80 /* }}} */
81
82 /* {{{ module stuff */
83 static const zend_function_entry php_recode_functions[] = {
84 PHP_FE(recode_string, arginfo_recode_string)
85 PHP_FE(recode_file, arginfo_recode_file)
86 PHP_FALIAS(recode, recode_string, arginfo_recode_string)
87 PHP_FE_END
88 };
89
90 zend_module_entry recode_module_entry = {
91 STANDARD_MODULE_HEADER,
92 "recode",
93 php_recode_functions,
94 PHP_MINIT(recode),
95 PHP_MSHUTDOWN(recode),
96 NULL,
97 NULL,
98 PHP_MINFO(recode),
99 NO_VERSION_YET,
100 PHP_MODULE_GLOBALS(recode),
101 PHP_GINIT(recode),
102 NULL,
103 NULL,
104 STANDARD_MODULE_PROPERTIES_EX
105 };
106
107 #ifdef COMPILE_DL_RECODE
108 ZEND_GET_MODULE(recode)
109 #endif
110
PHP_GINIT_FUNCTION(recode)111 static PHP_GINIT_FUNCTION(recode)
112 {
113 recode_globals->outer = NULL;
114 }
115
PHP_MINIT_FUNCTION(recode)116 PHP_MINIT_FUNCTION(recode)
117 {
118 ReSG(outer) = recode_new_outer(false);
119 if (ReSG(outer) == NULL) {
120 return FAILURE;
121 }
122
123 return SUCCESS;
124 }
125
PHP_MSHUTDOWN_FUNCTION(recode)126 PHP_MSHUTDOWN_FUNCTION(recode)
127 {
128 if (ReSG(outer)) {
129 recode_delete_outer(ReSG(outer));
130 }
131 return SUCCESS;
132 }
133
PHP_MINFO_FUNCTION(recode)134 PHP_MINFO_FUNCTION(recode)
135 {
136 php_info_print_table_start();
137 php_info_print_table_row(2, "Recode Support", "enabled");
138 php_info_print_table_row(2, "Revision", "$Id: cde03aacd1a1218dcad9dabc2f284594a0a4aa16 $");
139 php_info_print_table_end();
140 }
141
142 /* {{{ proto string recode_string(string request, string str)
143 Recode string str according to request string */
PHP_FUNCTION(recode_string)144 PHP_FUNCTION(recode_string)
145 {
146 RECODE_REQUEST request = NULL;
147 char *r = NULL;
148 size_t r_len = 0, r_alen = 0;
149 int req_len, str_len;
150 char *req, *str;
151
152 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &req, &req_len, &str, &str_len) == FAILURE) {
153 return;
154 }
155
156 request = recode_new_request(ReSG(outer));
157
158 if (request == NULL) {
159 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot allocate request structure");
160 RETURN_FALSE;
161 }
162
163 if (!recode_scan_request(request, req)) {
164 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Illegal recode request '%s'", req);
165 goto error_exit;
166 }
167
168 recode_buffer_to_buffer(request, str, str_len, &r, &r_len, &r_alen);
169 if (!r) {
170 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Recoding failed.");
171 error_exit:
172 RETVAL_FALSE;
173 } else {
174 RETVAL_STRINGL_CHECK(r, r_len, 1);
175 free(r);
176 }
177
178 recode_delete_request(request);
179
180 return;
181 }
182 /* }}} */
183
184 /* {{{ proto bool recode_file(string request, resource input, resource output)
185 Recode file input into file output according to request */
PHP_FUNCTION(recode_file)186 PHP_FUNCTION(recode_file)
187 {
188 RECODE_REQUEST request = NULL;
189 char *req;
190 int req_len;
191 zval *input, *output;
192 php_stream *instream, *outstream;
193 FILE *in_fp, *out_fp;
194
195 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "srr", &req, &req_len, &input, &output) == FAILURE) {
196 return;
197 }
198
199 php_stream_from_zval(instream, &input);
200 php_stream_from_zval(outstream, &output);
201
202 if (FAILURE == php_stream_cast(instream, PHP_STREAM_AS_STDIO, (void**)&in_fp, REPORT_ERRORS)) {
203 RETURN_FALSE;
204 }
205
206 if (FAILURE == php_stream_cast(outstream, PHP_STREAM_AS_STDIO, (void**)&out_fp, REPORT_ERRORS)) {
207 RETURN_FALSE;
208 }
209
210 request = recode_new_request(ReSG(outer));
211 if (request == NULL) {
212 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot allocate request structure");
213 RETURN_FALSE;
214 }
215
216 if (!recode_scan_request(request, req)) {
217 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Illegal recode request '%s'", req);
218 goto error_exit;
219 }
220
221 if (!recode_file_to_file(request, in_fp, out_fp)) {
222 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Recoding failed.");
223 goto error_exit;
224 }
225
226 recode_delete_request(request);
227 RETURN_TRUE;
228
229 error_exit:
230 recode_delete_request(request);
231 RETURN_FALSE;
232 }
233 /* }}} */
234
235 #endif
236
237 /*
238 * Local variables:
239 * tab-width: 4
240 * c-basic-offset: 4
241 * End:
242 */
243