xref: /PHP-5.5/ext/recode/recode.c (revision 73c1be26)
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: Kristian Koehntopp <kris@koehntopp.de>					      |
16    +----------------------------------------------------------------------+
17  */
18 
19 /* $Id: d95ffdf43fdab6078875dc99d333da459d8d8cd6 $ */
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: d95ffdf43fdab6078875dc99d333da459d8d8cd6 $");
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(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