1 : /*
2 : +----------------------------------------------------------------------+
3 : | PHP Version 5 |
4 : +----------------------------------------------------------------------+
5 : | Copyright (c) 1997-2007 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: Marcus Boerger <helly@php.net> |
16 : +----------------------------------------------------------------------+
17 : */
18 :
19 : /* $Id: spl_directory.c,v 1.45.2.27.2.20 2007/04/09 15:34:55 dmitry Exp $ */
20 :
21 : #ifdef HAVE_CONFIG_H
22 : # include "config.h"
23 : #endif
24 :
25 : #include "php.h"
26 : #include "php_ini.h"
27 : #include "ext/standard/info.h"
28 : #include "ext/standard/file.h"
29 : #include "ext/standard/php_string.h"
30 : #include "zend_compile.h"
31 : #include "zend_exceptions.h"
32 : #include "zend_interfaces.h"
33 :
34 : #include "php_spl.h"
35 : #include "spl_functions.h"
36 : #include "spl_engine.h"
37 : #include "spl_iterators.h"
38 : #include "spl_directory.h"
39 : #include "spl_exceptions.h"
40 :
41 : #include "php.h"
42 : #include "fopen_wrappers.h"
43 :
44 : #include "ext/standard/basic_functions.h"
45 : #include "ext/standard/php_filestat.h"
46 :
47 : /* declare the class handlers */
48 : static zend_object_handlers spl_filesystem_object_handlers;
49 :
50 : /* decalre the class entry */
51 : PHPAPI zend_class_entry *spl_ce_SplFileInfo;
52 : PHPAPI zend_class_entry *spl_ce_DirectoryIterator;
53 : PHPAPI zend_class_entry *spl_ce_RecursiveDirectoryIterator;
54 : PHPAPI zend_class_entry *spl_ce_SplFileObject;
55 : PHPAPI zend_class_entry *spl_ce_SplTempFileObject;
56 :
57 : static void spl_filesystem_file_free_line(spl_filesystem_object *intern TSRMLS_DC) /* {{{ */
58 0 : {
59 0 : if (intern->u.file.current_line) {
60 0 : efree(intern->u.file.current_line);
61 0 : intern->u.file.current_line = NULL;
62 : }
63 0 : if (intern->u.file.current_zval) {
64 0 : zval_ptr_dtor(&intern->u.file.current_zval);
65 0 : intern->u.file.current_zval = NULL;
66 : }
67 0 : } /* }}} */
68 :
69 : static void spl_filesystem_object_free_storage(void *object TSRMLS_DC) /* {{{ */
70 0 : {
71 0 : spl_filesystem_object *intern = (spl_filesystem_object*)object;
72 :
73 0 : if (intern->oth_handler && intern->oth_handler->dtor) {
74 0 : intern->oth_handler->dtor(intern TSRMLS_CC);
75 : }
76 :
77 0 : zend_object_std_dtor(&intern->std TSRMLS_CC);
78 :
79 0 : if (intern->path) {
80 0 : efree(intern->path);
81 : }
82 0 : if (intern->file_name) {
83 0 : efree(intern->file_name);
84 : }
85 0 : switch(intern->type) {
86 : case SPL_FS_INFO:
87 0 : break;
88 : case SPL_FS_DIR:
89 0 : if (intern->u.dir.dirp) {
90 0 : php_stream_close(intern->u.dir.dirp);
91 : }
92 0 : if (intern->u.dir.sub_path) {
93 0 : efree(intern->u.dir.sub_path);
94 : }
95 0 : break;
96 : case SPL_FS_FILE:
97 0 : if (intern->u.file.stream) {
98 0 : if (intern->u.file.zcontext) {
99 : /* zend_list_delref(Z_RESVAL_P(intern->zcontext));*/
100 : }
101 0 : if (!intern->u.file.stream->is_persistent) {
102 0 : php_stream_free(intern->u.file.stream, PHP_STREAM_FREE_CLOSE);
103 : } else {
104 0 : php_stream_free(intern->u.file.stream, PHP_STREAM_FREE_CLOSE_PERSISTENT);
105 : }
106 0 : if (intern->u.file.open_mode) {
107 0 : efree(intern->u.file.open_mode);
108 : }
109 : }
110 0 : spl_filesystem_file_free_line(intern TSRMLS_CC);
111 : break;
112 : }
113 0 : efree(object);
114 0 : } /* }}} */
115 :
116 : /* {{{ spl_ce_dir_object_new */
117 : /* creates the object by
118 : - allocating memory
119 : - initializing the object members
120 : - storing the object
121 : - setting it's handlers
122 :
123 : called from
124 : - clone
125 : - new
126 : */
127 : static zend_object_value spl_filesystem_object_new_ex(zend_class_entry *class_type, spl_filesystem_object **obj TSRMLS_DC)
128 0 : {
129 : zend_object_value retval;
130 : spl_filesystem_object *intern;
131 : zval *tmp;
132 :
133 0 : intern = emalloc(sizeof(spl_filesystem_object));
134 0 : memset(intern, 0, sizeof(spl_filesystem_object));
135 : /* intern->type = SPL_FS_INFO; done by set 0 */
136 0 : intern->file_class = spl_ce_SplFileObject;
137 0 : intern->info_class = spl_ce_SplFileInfo;
138 0 : if (obj) *obj = intern;
139 :
140 0 : zend_object_std_init(&intern->std, class_type TSRMLS_CC);
141 0 : zend_hash_copy(intern->std.properties, &class_type->default_properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *));
142 :
143 0 : retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t) zend_objects_destroy_object, (zend_objects_free_object_storage_t) spl_filesystem_object_free_storage, NULL TSRMLS_CC);
144 0 : retval.handlers = &spl_filesystem_object_handlers;
145 0 : return retval;
146 : }
147 : /* }}} */
148 :
149 : /* {{{ spl_filesystem_object_new */
150 : /* See spl_filesystem_object_new_ex */
151 : static zend_object_value spl_filesystem_object_new(zend_class_entry *class_type TSRMLS_DC)
152 0 : {
153 0 : return spl_filesystem_object_new_ex(class_type, NULL TSRMLS_CC);
154 : }
155 : /* }}} */
156 :
157 : static inline void spl_filesystem_object_get_file_name(spl_filesystem_object *intern TSRMLS_DC) /* {{{ */
158 0 : {
159 0 : if (!intern->file_name) {
160 0 : switch (intern->type) {
161 : case SPL_FS_INFO:
162 : case SPL_FS_FILE:
163 0 : php_error_docref(NULL TSRMLS_CC, E_ERROR, "Object not initialized");
164 0 : break;
165 : case SPL_FS_DIR:
166 0 : intern->file_name_len = spprintf(&intern->file_name, 0, "%s%c%s", intern->path, DEFAULT_SLASH, intern->u.dir.entry.d_name);
167 : break;
168 : }
169 : }
170 0 : } /* }}} */
171 :
172 : /* {{{ spl_filesystem_dir_open */
173 : /* open a directory resource */
174 : static void spl_filesystem_dir_open(spl_filesystem_object* intern, char *path TSRMLS_DC)
175 0 : {
176 0 : intern->type = SPL_FS_DIR;
177 0 : intern->path_len = strlen(path);
178 0 : intern->u.dir.dirp = php_stream_opendir(path, ENFORCE_SAFE_MODE|REPORT_ERRORS, NULL);
179 :
180 0 : if (intern->path_len && (path[intern->path_len-1] == '/'
181 : #if defined(PHP_WIN32) || defined(NETWARE)
182 : || path[intern->path_len-1] == '\\'
183 : #endif
184 : )) {
185 0 : intern->path = estrndup(path, --intern->path_len);
186 : } else {
187 0 : intern->path = estrndup(path, intern->path_len);
188 : }
189 0 : intern->u.dir.index = 0;
190 :
191 0 : if (intern->u.dir.dirp == NULL) {
192 : /* throw exception: should've been already happened */
193 0 : intern->u.dir.entry.d_name[0] = '\0';
194 : } else {
195 0 : if (!php_stream_readdir(intern->u.dir.dirp, &intern->u.dir.entry)) {
196 0 : intern->u.dir.entry.d_name[0] = '\0';
197 : }
198 : }
199 0 : }
200 : /* }}} */
201 :
202 : static int spl_filesystem_file_open(spl_filesystem_object *intern, int use_include_path, int silent TSRMLS_DC) /* {{{ */
203 0 : {
204 0 : intern->type = SPL_FS_FILE;
205 0 : intern->u.file.context = php_stream_context_from_zval(intern->u.file.zcontext, 0);
206 0 : intern->u.file.stream = php_stream_open_wrapper_ex(intern->file_name, intern->u.file.open_mode, (use_include_path ? USE_PATH : 0) | ENFORCE_SAFE_MODE | REPORT_ERRORS, NULL, intern->u.file.context);
207 :
208 0 : if (!intern->file_name_len || !intern->u.file.stream) {
209 0 : if (!EG(exception)) {
210 0 : zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC, "Cannot open file '%s'", intern->file_name_len ? intern->file_name : "");
211 : }
212 0 : intern->file_name = NULL; /* until here it is not a copy */
213 0 : intern->u.file.open_mode = NULL;
214 0 : return FAILURE;
215 : }
216 :
217 0 : if (intern->u.file.zcontext) {
218 0 : zend_list_addref(Z_RESVAL_P(intern->u.file.zcontext));
219 : }
220 :
221 0 : if (intern->file_name[intern->file_name_len-1] == '/'
222 : #if defined(PHP_WIN32) || defined(NETWARE)
223 : ||intern->file_name[intern->file_name_len-1] == '\\'
224 : #endif
225 : ) {
226 0 : intern->file_name_len--;
227 : }
228 :
229 0 : intern->file_name = estrndup(intern->file_name, intern->file_name_len);
230 0 : intern->u.file.open_mode = estrndup(intern->u.file.open_mode, intern->u.file.open_mode_len);
231 :
232 : /* avoid reference counting in debug mode, thus do it manually */
233 0 : ZVAL_RESOURCE(&intern->u.file.zresource, php_stream_get_resource_id(intern->u.file.stream));
234 0 : intern->u.file.zresource.refcount = 1;
235 :
236 0 : intern->u.file.delimiter = ',';
237 0 : intern->u.file.enclosure = '"';
238 :
239 0 : zend_hash_find(&intern->std.ce->function_table, "getcurrentline", sizeof("getcurrentline"), (void **) &intern->u.file.func_getCurr);
240 :
241 0 : return SUCCESS;
242 : } /* }}} */
243 :
244 : /* {{{ spl_filesystem_object_clone */
245 : /* Local zend_object_value creation (on stack)
246 : Load the 'other' object
247 : Create a new empty object (See spl_filesystem_object_new_ex)
248 : Open the directory
249 : Clone other members (properties)
250 : */
251 : static zend_object_value spl_filesystem_object_clone(zval *zobject TSRMLS_DC)
252 0 : {
253 : zend_object_value new_obj_val;
254 : zend_object *old_object;
255 : zend_object *new_object;
256 0 : zend_object_handle handle = Z_OBJ_HANDLE_P(zobject);
257 : spl_filesystem_object *intern;
258 : spl_filesystem_object *source;
259 :
260 0 : old_object = zend_objects_get_address(zobject TSRMLS_CC);
261 0 : source = (spl_filesystem_object*)old_object;
262 :
263 0 : new_obj_val = spl_filesystem_object_new_ex(old_object->ce, &intern TSRMLS_CC);
264 0 : new_object = &intern->std;
265 :
266 0 : switch (source->type) {
267 : case SPL_FS_INFO:
268 0 : intern->path_len = source->path_len;
269 0 : intern->path = estrndup(source->path, source->path_len);
270 0 : intern->file_name_len = source->file_name_len;
271 0 : intern->file_name = estrndup(source->file_name, intern->file_name_len);
272 0 : break;
273 : case SPL_FS_DIR:
274 0 : spl_filesystem_dir_open(intern, source->path TSRMLS_CC);
275 0 : break;
276 : case SPL_FS_FILE:
277 0 : php_error_docref(NULL TSRMLS_CC, E_ERROR, "An object of class %s cannot be cloned", old_object->ce->name);
278 : break;
279 : }
280 :
281 0 : intern->file_class = source->file_class;
282 0 : intern->info_class = source->info_class;
283 0 : intern->flags = source->flags;
284 0 : intern->oth = source->oth;
285 0 : intern->oth_handler = source->oth_handler;
286 :
287 0 : zend_objects_clone_members(new_object, new_obj_val, old_object, handle TSRMLS_CC);
288 :
289 0 : if (intern->oth_handler && intern->oth_handler->clone) {
290 0 : intern->oth_handler->clone(source, intern TSRMLS_CC);
291 : }
292 :
293 0 : return new_obj_val;
294 : }
295 : /* }}} */
296 :
297 : void spl_filesystem_info_set_filename(spl_filesystem_object *intern, char *path, int len, int use_copy TSRMLS_DC) /* {{{ */
298 0 : {
299 : char *p1, *p2;
300 :
301 0 : intern->file_name = use_copy ? estrndup(path, len) : path;
302 0 : intern->file_name_len = len;
303 :
304 0 : p1 = strrchr(path, '/');
305 : #if defined(PHP_WIN32) || defined(NETWARE)
306 : p2 = strrchr(path, '\\');
307 : #else
308 0 : p2 = 0;
309 : #endif
310 0 : if (p1 || p2) {
311 0 : intern->path_len = (p1 > p2 ? p1 : p2) - path;
312 : } else {
313 0 : intern->path_len = 0;
314 : }
315 0 : intern->path = estrndup(path, intern->path_len);
316 0 : } /* }}} */
317 :
318 : static spl_filesystem_object * spl_filesystem_object_create_info(spl_filesystem_object *source, char *file_path, int file_path_len, int use_copy, zend_class_entry *ce, zval *return_value TSRMLS_DC) /* {{{ */
319 0 : {
320 : spl_filesystem_object *intern;
321 : zval *arg1;
322 :
323 0 : if (!file_path || !file_path_len) {
324 : #if defined(PHP_WIN32)
325 : zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC, "Cannot create SplFileInfo for empty path");
326 : if (file_path && !use_copy)
327 : {
328 : efree(file_path);
329 : }
330 : return NULL;
331 : #else
332 0 : if (file_path && !use_copy) {
333 0 : efree(file_path);
334 : }
335 0 : use_copy = 1;
336 0 : file_path_len = 1;
337 0 : file_path = "/";
338 : #endif
339 : }
340 :
341 0 : php_set_error_handling(EH_THROW, spl_ce_RuntimeException TSRMLS_CC);
342 :
343 0 : ce = ce ? ce : source->info_class;
344 0 : return_value->value.obj = spl_filesystem_object_new_ex(ce, &intern TSRMLS_CC);
345 0 : Z_TYPE_P(return_value) = IS_OBJECT;
346 :
347 0 : if (ce->constructor->common.scope != spl_ce_SplFileInfo) {
348 0 : MAKE_STD_ZVAL(arg1);
349 0 : ZVAL_STRINGL(arg1, file_path, file_path_len, use_copy);
350 0 : zend_call_method_with_1_params(&return_value, ce, &ce->constructor, "__construct", NULL, arg1);
351 0 : zval_ptr_dtor(&arg1);
352 : } else {
353 0 : spl_filesystem_info_set_filename(intern, file_path, file_path_len, use_copy TSRMLS_CC);
354 : }
355 :
356 0 : php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC);
357 :
358 0 : return intern;
359 : } /* }}} */
360 :
361 : static spl_filesystem_object * spl_filesystem_object_create_type(int ht, spl_filesystem_object *source, int type, zend_class_entry *ce, zval *return_value TSRMLS_DC) /* {{{ */
362 0 : {
363 : spl_filesystem_object *intern;
364 0 : zend_bool use_include_path = 0;
365 : zval *arg1, *arg2;
366 :
367 0 : php_set_error_handling(EH_THROW, spl_ce_RuntimeException TSRMLS_CC);
368 :
369 0 : switch (source->type) {
370 : case SPL_FS_INFO:
371 : case SPL_FS_FILE:
372 0 : break;
373 : case SPL_FS_DIR:
374 0 : if (!source->u.dir.entry.d_name[0]) {
375 0 : zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC, "Could not open file");
376 0 : php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC);
377 0 : return NULL;
378 : }
379 : }
380 :
381 0 : switch (type) {
382 : case SPL_FS_INFO:
383 0 : ce = ce ? ce : source->info_class;
384 0 : return_value->value.obj = spl_filesystem_object_new_ex(ce, &intern TSRMLS_CC);
385 0 : Z_TYPE_P(return_value) = IS_OBJECT;
386 :
387 0 : spl_filesystem_object_get_file_name(source TSRMLS_CC);
388 0 : if (ce->constructor->common.scope != spl_ce_SplFileInfo) {
389 0 : MAKE_STD_ZVAL(arg1);
390 0 : ZVAL_STRINGL(arg1, source->file_name, source->file_name_len, 1);
391 0 : zend_call_method_with_1_params(&return_value, ce, &ce->constructor, "__construct", NULL, arg1);
392 0 : zval_ptr_dtor(&arg1);
393 : } else {
394 0 : intern->file_name = estrndup(source->file_name, source->file_name_len);
395 0 : intern->file_name_len = source->file_name_len;
396 0 : intern->path = estrndup(source->path, source->path_len);
397 0 : intern->path_len = source->path_len;
398 : }
399 0 : break;
400 : case SPL_FS_FILE:
401 0 : ce = ce ? ce : source->file_class;
402 0 : return_value->value.obj = spl_filesystem_object_new_ex(ce, &intern TSRMLS_CC);
403 0 : Z_TYPE_P(return_value) = IS_OBJECT;
404 :
405 0 : spl_filesystem_object_get_file_name(source TSRMLS_CC);
406 :
407 0 : if (ce->constructor->common.scope != spl_ce_SplFileObject) {
408 0 : MAKE_STD_ZVAL(arg1);
409 0 : MAKE_STD_ZVAL(arg2);
410 0 : ZVAL_STRINGL(arg1, source->file_name, source->file_name_len, 1);
411 0 : ZVAL_STRINGL(arg2, "r", 1, 1);
412 0 : zend_call_method_with_2_params(&return_value, ce, &ce->constructor, "__construct", NULL, arg1, arg2);
413 0 : zval_ptr_dtor(&arg1);
414 0 : zval_ptr_dtor(&arg2);
415 : } else {
416 0 : intern->file_name = source->file_name;
417 0 : intern->file_name_len = source->file_name_len;
418 0 : intern->path = estrndup(source->path, source->path_len);
419 0 : intern->path_len = source->path_len;
420 :
421 0 : intern->u.file.open_mode = "r";
422 0 : intern->u.file.open_mode_len = 1;
423 :
424 0 : if (ht && zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|sbr",
425 : &intern->u.file.open_mode, &intern->u.file.open_mode_len,
426 : &use_include_path, &intern->u.file.zcontext) == FAILURE) {
427 0 : php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC);
428 0 : intern->u.file.open_mode = NULL;
429 0 : zval_dtor(return_value);
430 0 : Z_TYPE_P(return_value) = IS_NULL;
431 0 : return NULL;
432 : }
433 :
434 0 : if (spl_filesystem_file_open(intern, use_include_path, 0 TSRMLS_CC) == FAILURE) {
435 0 : php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC);
436 0 : zval_dtor(return_value);
437 0 : Z_TYPE_P(return_value) = IS_NULL;
438 0 : return NULL;
439 : }
440 : }
441 0 : break;
442 : case SPL_FS_DIR:
443 0 : php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC);
444 0 : zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC, "Operation not supported");
445 0 : return NULL;
446 : }
447 0 : php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC);
448 0 : return NULL;
449 : } /* }}} */
450 :
451 : static inline int spl_filesystem_is_dot(const char * d_name) /* {{{ */
452 0 : {
453 0 : return !strcmp(d_name, ".") || !strcmp(d_name, "..");
454 : }
455 : /* }}} */
456 :
457 : static int spl_filesystem_is_invalid_or_dot(const char * d_name) /* {{{ */
458 0 : {
459 0 : return d_name[0] == '\0' || spl_filesystem_is_dot(d_name);
460 : }
461 : /* }}} */
462 :
463 : /* {{{ proto void DirectoryIterator::__construct(string path)
464 : Cronstructs a new dir iterator from a path. */
465 : SPL_METHOD(DirectoryIterator, __construct)
466 0 : {
467 : spl_filesystem_object *intern;
468 : char *path;
469 : int len;
470 :
471 0 : php_set_error_handling(EH_THROW, spl_ce_RuntimeException TSRMLS_CC);
472 :
473 0 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &path, &len) == FAILURE) {
474 0 : php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC);
475 0 : return;
476 : }
477 :
478 0 : if (!len) {
479 0 : php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC);
480 0 : zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC, "Directory name must not be empty.");
481 0 : return;
482 : }
483 :
484 0 : intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
485 0 : spl_filesystem_dir_open(intern, path TSRMLS_CC);
486 0 : intern->u.dir.is_recursive = instanceof_function(intern->std.ce, spl_ce_RecursiveDirectoryIterator TSRMLS_CC) ? 1 : 0;
487 0 : intern->flags = 0;
488 :
489 0 : php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC);
490 : }
491 : /* }}} */
492 :
493 : /* {{{ proto void DirectoryIterator::rewind()
494 : Rewind dir back to the start */
495 : SPL_METHOD(DirectoryIterator, rewind)
496 0 : {
497 0 : spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
498 :
499 0 : intern->u.dir.index = 0;
500 0 : if (intern->u.dir.dirp) {
501 0 : php_stream_rewinddir(intern->u.dir.dirp);
502 : }
503 0 : if (!intern->u.dir.dirp || !php_stream_readdir(intern->u.dir.dirp, &intern->u.dir.entry)) {
504 0 : intern->u.dir.entry.d_name[0] = '\0';
505 : }
506 0 : }
507 : /* }}} */
508 :
509 : /* {{{ proto string DirectoryIterator::key()
510 : Return current dir entry */
511 : SPL_METHOD(DirectoryIterator, key)
512 0 : {
513 0 : spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
514 :
515 0 : if (intern->u.dir.dirp) {
516 0 : RETURN_LONG(intern->u.dir.index);
517 : } else {
518 0 : RETURN_FALSE;
519 : }
520 : }
521 : /* }}} */
522 :
523 : /* {{{ proto DirectoryIterator DirectoryIterator::current()
524 : Return this (needed for Iterator interface) */
525 : SPL_METHOD(DirectoryIterator, current)
526 0 : {
527 0 : RETURN_ZVAL(getThis(), 1, 0);
528 : }
529 : /* }}} */
530 :
531 : /* {{{ proto void DirectoryIterator::next()
532 : Move to next entry */
533 : SPL_METHOD(DirectoryIterator, next)
534 0 : {
535 0 : spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
536 :
537 0 : intern->u.dir.index++;
538 0 : if (!intern->u.dir.dirp || !php_stream_readdir(intern->u.dir.dirp, &intern->u.dir.entry)) {
539 0 : intern->u.dir.entry.d_name[0] = '\0';
540 : }
541 0 : if (intern->file_name) {
542 0 : efree(intern->file_name);
543 0 : intern->file_name = NULL;
544 : }
545 0 : }
546 : /* }}} */
547 :
548 : /* {{{ proto string DirectoryIterator::valid()
549 : Check whether dir contains more entries */
550 : SPL_METHOD(DirectoryIterator, valid)
551 0 : {
552 0 : spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
553 :
554 0 : RETURN_BOOL(intern->u.dir.entry.d_name[0] != '\0');
555 : }
556 : /* }}} */
557 :
558 : /* {{{ proto string SplFileInfo::getPath()
559 : Return the path */
560 : SPL_METHOD(SplFileInfo, getPath)
561 0 : {
562 0 : spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
563 :
564 0 : RETURN_STRING(intern->path, 1);
565 : }
566 : /* }}} */
567 :
568 : /* {{{ proto string SplFileInfo::getFilename()
569 : Return filename only */
570 : SPL_METHOD(SplFileInfo, getFilename)
571 0 : {
572 0 : spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
573 :
574 0 : if (intern->path_len && intern->path_len < intern->file_name_len) {
575 0 : RETURN_STRINGL(intern->file_name + intern->path_len + 1, intern->file_name_len - (intern->path_len + 1), 1);
576 : } else {
577 0 : RETURN_STRINGL(intern->file_name, intern->file_name_len, 1);
578 : }
579 : }
580 : /* }}} */
581 :
582 : /* {{{ proto string DirectoryIterator::getFilename()
583 : Return filename of current dir entry */
584 : SPL_METHOD(DirectoryIterator, getFilename)
585 0 : {
586 0 : spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
587 :
588 0 : RETURN_STRING(intern->u.dir.entry.d_name, 1);
589 : }
590 : /* }}} */
591 :
592 : /* {{{ proto string SplFileInfo::getBasename([string $suffix]) U
593 : Returns filename component of path */
594 : SPL_METHOD(SplFileInfo, getBasename)
595 0 : {
596 0 : spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
597 0 : char *fname, *suffix = 0;
598 : size_t flen;
599 0 : int slen = 0;
600 :
601 0 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &suffix, &slen) == FAILURE) {
602 0 : return;
603 : }
604 :
605 0 : if (intern->path_len && intern->path_len < intern->file_name_len) {
606 0 : fname = intern->file_name + intern->path_len + 1;
607 0 : flen = intern->file_name_len - (intern->path_len + 1);
608 : } else {
609 0 : fname = intern->file_name;
610 0 : flen = intern->file_name_len;
611 : }
612 :
613 0 : php_basename(fname, flen, suffix, slen, &fname, &flen TSRMLS_CC);
614 :
615 0 : RETURN_STRINGL(fname, flen, 0);
616 : }
617 : /* }}}*/
618 :
619 : /* {{{ proto string DirectoryIterator::getBasename([string $suffix]) U
620 : Returns filename component of current dir entry */
621 : SPL_METHOD(DirectoryIterator, getBasename)
622 0 : {
623 0 : spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
624 0 : char *suffix = 0, *fname;
625 0 : int slen = 0;
626 : size_t flen;
627 :
628 0 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &suffix, &slen) == FAILURE) {
629 0 : return;
630 : }
631 :
632 0 : php_basename(intern->u.dir.entry.d_name, strlen(intern->u.dir.entry.d_name), suffix, slen, &fname, &flen TSRMLS_CC);
633 :
634 0 : RETURN_STRINGL(fname, flen, 0);
635 : }
636 : /* }}} */
637 :
638 : /* {{{ proto string SplFileInfo::getPathname()
639 : Return path and filename */
640 : SPL_METHOD(SplFileInfo, getPathname)
641 0 : {
642 0 : spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
643 :
644 0 : switch (intern->type) {
645 : case SPL_FS_INFO:
646 : case SPL_FS_FILE:
647 0 : RETURN_STRINGL(intern->file_name, intern->file_name_len, 1);
648 : case SPL_FS_DIR:
649 0 : if (intern->u.dir.entry.d_name[0]) {
650 0 : spl_filesystem_object_get_file_name(intern TSRMLS_CC);
651 0 : RETURN_STRINGL(intern->file_name, intern->file_name_len, 1);
652 : }
653 : }
654 0 : RETURN_BOOL(0);
655 : }
656 : /* }}} */
657 :
658 : /* {{{ proto string RecursiveDirectoryIterator::key()
659 : Return getPathname() or getFilename() depending on flags */
660 : SPL_METHOD(RecursiveDirectoryIterator, key)
661 0 : {
662 0 : spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
663 :
664 0 : if (intern->flags & SPL_FILE_DIR_KEY_AS_FILENAME) {
665 0 : RETURN_STRING(intern->u.dir.entry.d_name, 1);
666 : } else {
667 0 : spl_filesystem_object_get_file_name(intern TSRMLS_CC);
668 0 : RETURN_STRINGL(intern->file_name, intern->file_name_len, 1);
669 : }
670 : }
671 : /* }}} */
672 :
673 : /* {{{ proto string RecursiveDirectoryIterator::current()
674 : Return getFilename(), getFileInfo() or $this depending on flags */
675 : SPL_METHOD(RecursiveDirectoryIterator, current)
676 0 : {
677 0 : spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
678 :
679 0 : if (intern->flags & SPL_FILE_DIR_CURRENT_AS_PATHNAME) {
680 0 : spl_filesystem_object_get_file_name(intern TSRMLS_CC);
681 0 : RETURN_STRINGL(intern->file_name, intern->file_name_len, 1);
682 0 : } else if (intern->flags & SPL_FILE_DIR_CURRENT_AS_FILEINFO) {
683 0 : spl_filesystem_object_get_file_name(intern TSRMLS_CC);
684 0 : spl_filesystem_object_create_type(0, intern, SPL_FS_INFO, NULL, return_value TSRMLS_CC);
685 : } else {
686 0 : RETURN_ZVAL(getThis(), 1, 0);
687 : /*RETURN_STRING(intern->u.dir.entry.d_name, 1);*/
688 : }
689 : }
690 : /* }}} */
691 :
692 : /* {{{ proto bool DirectoryIterator::isDot()
693 : Returns true if current entry is '.' or '..' */
694 : SPL_METHOD(DirectoryIterator, isDot)
695 0 : {
696 0 : spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
697 :
698 0 : RETURN_BOOL(spl_filesystem_is_dot(intern->u.dir.entry.d_name));
699 : }
700 : /* }}} */
701 :
702 : /* {{{ proto void SplFileInfo::__construct(string file_name)
703 : Cronstructs a new SplFileInfo from a path. */
704 : /* php_set_error_handling() is used to throw exceptions in case
705 : the constructor fails. Here we use this to ensure the object
706 : has a valid directory resource.
707 :
708 : When the constructor gets called the object is already created
709 : by the engine, so we must only call 'additional' initializations.
710 : */
711 : SPL_METHOD(SplFileInfo, __construct)
712 0 : {
713 : spl_filesystem_object *intern;
714 : char *path;
715 : int len;
716 :
717 0 : php_set_error_handling(EH_THROW, spl_ce_RuntimeException TSRMLS_CC);
718 :
719 0 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &path, &len) == FAILURE) {
720 0 : php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC);
721 0 : return;
722 : }
723 :
724 0 : intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
725 :
726 0 : spl_filesystem_info_set_filename(intern, path, len, 1 TSRMLS_CC);
727 :
728 : /* intern->type = SPL_FS_INFO; already set */
729 :
730 0 : php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC);
731 : }
732 : /* }}} */
733 :
734 : /* {{{ FileInfoFunction */
735 : #define FileInfoFunction(func_name, func_num) \
736 : SPL_METHOD(SplFileInfo, func_name) \
737 : { \
738 : spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); \
739 : \
740 : php_set_error_handling(EH_THROW, spl_ce_RuntimeException TSRMLS_CC);\
741 : spl_filesystem_object_get_file_name(intern TSRMLS_CC); \
742 : php_stat(intern->file_name, intern->file_name_len, func_num, return_value TSRMLS_CC); \
743 : php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC);\
744 : }
745 : /* }}} */
746 :
747 : /* {{{ proto int SplFileInfo::getPerms()
748 : Get file permissions */
749 0 : FileInfoFunction(getPerms, FS_PERMS)
750 : /* }}} */
751 :
752 : /* {{{ proto int SplFileInfo::getInode()
753 : Get file inode */
754 0 : FileInfoFunction(getInode, FS_INODE)
755 : /* }}} */
756 :
757 : /* {{{ proto int SplFileInfo::getSize()
758 : Get file size */
759 0 : FileInfoFunction(getSize, FS_SIZE)
760 : /* }}} */
761 :
762 : /* {{{ proto int SplFileInfo::getOwner()
763 : Get file owner */
764 0 : FileInfoFunction(getOwner, FS_OWNER)
765 : /* }}} */
766 :
767 : /* {{{ proto int SplFileInfo::getGroup()
768 : Get file group */
769 0 : FileInfoFunction(getGroup, FS_GROUP)
770 : /* }}} */
771 :
772 : /* {{{ proto int SplFileInfo::getATime()
773 : Get last access time of file */
774 0 : FileInfoFunction(getATime, FS_ATIME)
775 : /* }}} */
776 :
777 : /* {{{ proto int SplFileInfo::getMTime()
778 : Get last modification time of file */
779 0 : FileInfoFunction(getMTime, FS_MTIME)
780 : /* }}} */
781 :
782 : /* {{{ proto int SplFileInfo::getCTime()
783 : Get inode modification time of file */
784 0 : FileInfoFunction(getCTime, FS_CTIME)
785 : /* }}} */
786 :
787 : /* {{{ proto string SplFileInfo::getType()
788 : Get file type */
789 0 : FileInfoFunction(getType, FS_TYPE)
790 : /* }}} */
791 :
792 : /* {{{ proto bool SplFileInfo::isWritable()
793 : Returns true if file can be written */
794 0 : FileInfoFunction(isWritable, FS_IS_W)
795 : /* }}} */
796 :
797 : /* {{{ proto bool SplFileInfo::isReadable()
798 : Returns true if file can be read */
799 0 : FileInfoFunction(isReadable, FS_IS_R)
800 : /* }}} */
801 :
802 : /* {{{ proto bool SplFileInfo::isExecutable()
803 : Returns true if file is executable */
804 0 : FileInfoFunction(isExecutable, FS_IS_X)
805 : /* }}} */
806 :
807 : /* {{{ proto bool SplFileInfo::isFile()
808 : Returns true if file is a regular file */
809 0 : FileInfoFunction(isFile, FS_IS_FILE)
810 : /* }}} */
811 :
812 : /* {{{ proto bool SplFileInfo::isDir()
813 : Returns true if file is directory */
814 0 : FileInfoFunction(isDir, FS_IS_DIR)
815 : /* }}} */
816 :
817 : /* {{{ proto bool SplFileInfo::isLink()
818 : Returns true if file is symbolic link */
819 0 : FileInfoFunction(isLink, FS_IS_LINK)
820 : /* }}} */
821 :
822 : /* {{{ proto string SplFileInfo::getLinkTarget() U
823 : Return the target of a symbolic link */
824 : SPL_METHOD(SplFileInfo, getLinkTarget)
825 0 : {
826 0 : spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
827 : int ret;
828 : char buff[MAXPATHLEN];
829 :
830 0 : php_set_error_handling(EH_THROW, spl_ce_RuntimeException TSRMLS_CC);
831 :
832 0 : ret = readlink(intern->file_name, buff, MAXPATHLEN-1);
833 :
834 0 : if (ret == -1) {
835 0 : zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC, "Unable to read link %s, error: %s", intern->file_name, strerror(errno));
836 0 : RETVAL_FALSE;
837 : } else {
838 : /* Append NULL to the end of the string */
839 0 : buff[ret] = '\0';
840 :
841 0 : RETVAL_STRINGL(buff, ret, 1);
842 : }
843 0 : php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC);
844 0 : }
845 : /* }}} */
846 :
847 : #if (!defined(__BEOS__) && !defined(NETWARE) && HAVE_REALPATH) || defined(ZTS)
848 : /* {{{ proto string SplFileInfo::getRealPath()
849 : Return the resolved path */
850 : SPL_METHOD(SplFileInfo, getRealPath)
851 0 : {
852 0 : spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
853 : char buff[MAXPATHLEN];
854 :
855 0 : php_set_error_handling(EH_THROW, spl_ce_RuntimeException TSRMLS_CC);
856 :
857 0 : if (VCWD_REALPATH(intern->file_name, buff)) {
858 : #ifdef ZTS
859 : if (VCWD_ACCESS(buff, F_OK)) {
860 : RETVAL_FALSE;
861 : } else
862 : #endif
863 0 : RETVAL_STRING(buff, 1);
864 : } else {
865 0 : RETVAL_FALSE;
866 : }
867 0 : php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC);
868 0 : }
869 : /* }}} */
870 : #endif
871 :
872 : /* {{{ proto SplFileObject SplFileInfo::openFile([string mode = 'r' [, bool use_include_path [, resource context]]])
873 : Open the current file */
874 : SPL_METHOD(SplFileInfo, openFile)
875 0 : {
876 0 : spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
877 :
878 0 : spl_filesystem_object_create_type(ht, intern, SPL_FS_FILE, NULL, return_value TSRMLS_CC);
879 0 : }
880 : /* }}} */
881 :
882 : /* {{{ proto void SplFileInfo::setFileClass([string class_name])
883 : Class to use in openFile() */
884 : SPL_METHOD(SplFileInfo, setFileClass)
885 0 : {
886 0 : spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
887 0 : zend_class_entry *ce = spl_ce_SplFileObject;
888 :
889 0 : php_set_error_handling(EH_THROW, spl_ce_UnexpectedValueException TSRMLS_CC);
890 :
891 0 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|C", &ce) == SUCCESS) {
892 0 : intern->file_class = ce;
893 : }
894 :
895 0 : php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC);
896 0 : }
897 : /* }}} */
898 :
899 : /* {{{ proto void SplFileInfo::setInfoClass([string class_name])
900 : Class to use in getFileInfo(), getPathInfo() */
901 : SPL_METHOD(SplFileInfo, setInfoClass)
902 0 : {
903 0 : spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
904 0 : zend_class_entry *ce = spl_ce_SplFileInfo;
905 :
906 0 : php_set_error_handling(EH_THROW, spl_ce_UnexpectedValueException TSRMLS_CC);
907 :
908 0 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|C", &ce) == SUCCESS) {
909 0 : intern->info_class = ce;
910 : }
911 :
912 0 : php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC);
913 0 : }
914 : /* }}} */
915 :
916 : /* {{{ proto SplFileInfo SplFileInfo::getFileInfo([string $class_name])
917 : Get/copy file info */
918 : SPL_METHOD(SplFileInfo, getFileInfo)
919 0 : {
920 0 : spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
921 0 : zend_class_entry *ce = intern->info_class;
922 :
923 0 : php_set_error_handling(EH_THROW, spl_ce_UnexpectedValueException TSRMLS_CC);
924 :
925 0 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|C", &ce) == SUCCESS) {
926 0 : spl_filesystem_object_create_type(ht, intern, SPL_FS_INFO, ce, return_value TSRMLS_CC);
927 : }
928 :
929 0 : php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC);
930 0 : }
931 : /* }}} */
932 :
933 : /* {{{ proto SplFileInfo SplFileInfo::getPathInfo([string $class_name])
934 : Get/copy file info */
935 : SPL_METHOD(SplFileInfo, getPathInfo)
936 0 : {
937 0 : spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
938 0 : zend_class_entry *ce = intern->info_class;
939 :
940 0 : php_set_error_handling(EH_THROW, spl_ce_UnexpectedValueException TSRMLS_CC);
941 :
942 0 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|C", &ce) == SUCCESS) {
943 0 : spl_filesystem_object_create_info(intern, intern->path, intern->path_len, 1, ce, return_value TSRMLS_CC);
944 : }
945 :
946 0 : php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC);
947 0 : }
948 : /* }}} */
949 :
950 : /* {{{ proto void RecursiveDirectoryIterator::__construct(string path [, int flags])
951 : Cronstructs a new dir iterator from a path. */
952 : SPL_METHOD(RecursiveDirectoryIterator, __construct)
953 0 : {
954 : spl_filesystem_object *intern;
955 : char *path;
956 : int len;
957 0 : long flags = SPL_FILE_DIR_CURRENT_AS_FILEINFO;
958 :
959 0 : php_set_error_handling(EH_THROW, spl_ce_UnexpectedValueException TSRMLS_CC);
960 :
961 0 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &path, &len, &flags) == FAILURE) {
962 0 : php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC);
963 0 : return;
964 : }
965 :
966 0 : intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
967 0 : spl_filesystem_dir_open(intern, path TSRMLS_CC);
968 0 : intern->u.dir.is_recursive = instanceof_function(intern->std.ce, spl_ce_RecursiveDirectoryIterator TSRMLS_CC) ? 1 : 0;
969 0 : intern->flags = flags;
970 :
971 0 : php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC);
972 : }
973 : /* }}} */
974 :
975 : /* {{{ proto void RecursiveDirectoryIterator::rewind()
976 : Rewind dir back to the start */
977 : SPL_METHOD(RecursiveDirectoryIterator, rewind)
978 0 : {
979 0 : spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
980 :
981 0 : intern->u.dir.index = 0;
982 0 : if (intern->u.dir.dirp) {
983 0 : php_stream_rewinddir(intern->u.dir.dirp);
984 : }
985 : do {
986 0 : if (!intern->u.dir.dirp || !php_stream_readdir(intern->u.dir.dirp, &intern->u.dir.entry)) {
987 0 : intern->u.dir.entry.d_name[0] = '\0';
988 : }
989 0 : } while (spl_filesystem_is_dot(intern->u.dir.entry.d_name));
990 0 : }
991 : /* }}} */
992 :
993 : /* {{{ proto void RecursiveDirectoryIterator::next()
994 : Move to next entry */
995 : SPL_METHOD(RecursiveDirectoryIterator, next)
996 0 : {
997 0 : spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
998 :
999 0 : intern->u.dir.index++;
1000 : do {
1001 0 : if (!intern->u.dir.dirp || !php_stream_readdir(intern->u.dir.dirp, &intern->u.dir.entry)) {
1002 0 : intern->u.dir.entry.d_name[0] = '\0';
1003 : }
1004 0 : } while (spl_filesystem_is_dot(intern->u.dir.entry.d_name));
1005 0 : if (intern->file_name) {
1006 0 : efree(intern->file_name);
1007 0 : intern->file_name = NULL;
1008 : }
1009 0 : }
1010 : /* }}} */
1011 :
1012 : /* {{{ proto bool RecursiveDirectoryIterator::hasChildren([bool $allow_links = false])
1013 : Returns whether current entry is a directory and not '.' or '..' */
1014 : SPL_METHOD(RecursiveDirectoryIterator, hasChildren)
1015 0 : {
1016 0 : zend_bool allow_links = 0;
1017 0 : spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
1018 :
1019 0 : if (spl_filesystem_is_invalid_or_dot(intern->u.dir.entry.d_name)) {
1020 0 : RETURN_BOOL(0);
1021 : } else {
1022 0 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &allow_links) == FAILURE) {
1023 0 : return;
1024 : }
1025 0 : spl_filesystem_object_get_file_name(intern TSRMLS_CC);
1026 0 : if (!allow_links) {
1027 0 : php_stat(intern->file_name, intern->file_name_len, FS_IS_LINK, return_value TSRMLS_CC);
1028 0 : if (zend_is_true(return_value)) {
1029 0 : RETURN_BOOL(0);
1030 : }
1031 : }
1032 0 : php_stat(intern->file_name, intern->file_name_len, FS_IS_DIR, return_value TSRMLS_CC);
1033 : }
1034 : }
1035 : /* }}} */
1036 :
1037 : /* {{{ proto RecursiveDirectoryIterator DirectoryIterator::getChildren()
1038 : Returns an iterator for the current entry if it is a directory */
1039 : SPL_METHOD(RecursiveDirectoryIterator, getChildren)
1040 0 : {
1041 : zval zpath;
1042 0 : spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
1043 : spl_filesystem_object *subdir;
1044 :
1045 0 : spl_filesystem_object_get_file_name(intern TSRMLS_CC);
1046 :
1047 0 : INIT_PZVAL(&zpath);
1048 0 : ZVAL_STRINGL(&zpath, intern->file_name, intern->file_name_len, 0);
1049 :
1050 0 : spl_instantiate_arg_ex1(spl_ce_RecursiveDirectoryIterator, &return_value, 0, &zpath TSRMLS_CC);
1051 :
1052 0 : subdir = (spl_filesystem_object*)zend_object_store_get_object(return_value TSRMLS_CC);
1053 0 : if (subdir) {
1054 0 : if (intern->u.dir.sub_path && intern->u.dir.sub_path[0]) {
1055 0 : subdir->u.dir.sub_path_len = spprintf(&subdir->u.dir.sub_path, 0, "%s%c%s", intern->u.dir.sub_path, DEFAULT_SLASH, intern->u.dir.entry.d_name);
1056 : } else {
1057 0 : subdir->u.dir.sub_path_len = strlen(intern->u.dir.entry.d_name);
1058 0 : subdir->u.dir.sub_path = estrndup(intern->u.dir.entry.d_name, subdir->u.dir.sub_path_len);
1059 : }
1060 0 : subdir->info_class = intern->info_class;
1061 0 : subdir->file_class = intern->file_class;
1062 0 : subdir->flags = intern->flags;
1063 0 : subdir->oth = intern->oth;
1064 : }
1065 0 : }
1066 : /* }}} */
1067 :
1068 : /* {{{ proto void RecursiveDirectoryIterator::getSubPath()
1069 : Get sub path */
1070 : SPL_METHOD(RecursiveDirectoryIterator, getSubPath)
1071 0 : {
1072 0 : spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
1073 :
1074 0 : if (intern->u.dir.sub_path) {
1075 0 : RETURN_STRINGL(intern->u.dir.sub_path, intern->u.dir.sub_path_len, 1);
1076 : } else {
1077 0 : RETURN_STRINGL("", 0, 1);
1078 : }
1079 : }
1080 : /* }}} */
1081 :
1082 : /* {{{ proto void RecursiveDirectoryIterator::getSubPathname()
1083 : Get sub path and file name */
1084 : SPL_METHOD(RecursiveDirectoryIterator, getSubPathname)
1085 0 : {
1086 0 : spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
1087 : char *sub_name;
1088 : int len;
1089 :
1090 0 : if (intern->u.dir.sub_path) {
1091 0 : len = spprintf(&sub_name, 0, "%s%c%s", intern->u.dir.sub_path, DEFAULT_SLASH, intern->u.dir.entry.d_name);
1092 0 : RETURN_STRINGL(sub_name, len, 0);
1093 : } else {
1094 0 : RETURN_STRING(intern->u.dir.entry.d_name, 1);
1095 : }
1096 : }
1097 : /* }}} */
1098 :
1099 : /* define an overloaded iterator structure */
1100 : typedef struct {
1101 : zend_object_iterator intern;
1102 : zval *current;
1103 : spl_filesystem_object *object;
1104 : } spl_filesystem_dir_it;
1105 :
1106 : /* forward declarations to the iterator handlers */
1107 : static void spl_filesystem_dir_it_dtor(zend_object_iterator *iter TSRMLS_DC);
1108 : static int spl_filesystem_dir_it_valid(zend_object_iterator *iter TSRMLS_DC);
1109 : static void spl_filesystem_dir_it_current_data(zend_object_iterator *iter, zval ***data TSRMLS_DC);
1110 : static int spl_filesystem_dir_it_current_key(zend_object_iterator *iter, char **str_key, uint *str_key_len, ulong *int_key TSRMLS_DC);
1111 : static void spl_filesystem_dir_it_move_forward(zend_object_iterator *iter TSRMLS_DC);
1112 : static void spl_filesystem_dir_it_rewind(zend_object_iterator *iter TSRMLS_DC);
1113 :
1114 : /* iterator handler table */
1115 : zend_object_iterator_funcs spl_filesystem_dir_it_funcs = {
1116 : spl_filesystem_dir_it_dtor,
1117 : spl_filesystem_dir_it_valid,
1118 : spl_filesystem_dir_it_current_data,
1119 : spl_filesystem_dir_it_current_key,
1120 : spl_filesystem_dir_it_move_forward,
1121 : spl_filesystem_dir_it_rewind
1122 : };
1123 :
1124 : /* {{{ spl_ce_dir_get_iterator */
1125 : zend_object_iterator *spl_filesystem_dir_get_iterator(zend_class_entry *ce, zval *object, int by_ref TSRMLS_DC)
1126 0 : {
1127 : spl_filesystem_dir_it *iterator;
1128 : spl_filesystem_object *dir_object;
1129 :
1130 0 : if (by_ref) {
1131 0 : zend_error(E_ERROR, "An iterator cannot be used with foreach by reference");
1132 : }
1133 0 : iterator = emalloc(sizeof(spl_filesystem_dir_it));
1134 0 : dir_object = (spl_filesystem_object*)zend_object_store_get_object(object TSRMLS_CC);
1135 :
1136 0 : object->refcount += 2;;
1137 0 : iterator->intern.data = (void*)object;
1138 0 : iterator->intern.funcs = &spl_filesystem_dir_it_funcs;
1139 0 : iterator->current = object;
1140 0 : iterator->object = dir_object;
1141 :
1142 0 : return (zend_object_iterator*)iterator;
1143 : }
1144 : /* }}} */
1145 :
1146 : /* {{{ spl_filesystem_dir_it_dtor */
1147 : static void spl_filesystem_dir_it_dtor(zend_object_iterator *iter TSRMLS_DC)
1148 0 : {
1149 0 : spl_filesystem_dir_it *iterator = (spl_filesystem_dir_it *)iter;
1150 :
1151 0 : zval_ptr_dtor(&iterator->current);
1152 0 : zval_ptr_dtor((zval**)&iterator->intern.data);
1153 :
1154 0 : efree(iterator);
1155 0 : }
1156 : /* }}} */
1157 :
1158 : /* {{{ spl_filesystem_dir_it_valid */
1159 : static int spl_filesystem_dir_it_valid(zend_object_iterator *iter TSRMLS_DC)
1160 0 : {
1161 0 : spl_filesystem_dir_it *iterator = (spl_filesystem_dir_it *)iter;
1162 0 : spl_filesystem_object *object = iterator->object;
1163 :
1164 0 : return object->u.dir.entry.d_name[0] != '\0' ? SUCCESS : FAILURE;
1165 : }
1166 : /* }}} */
1167 :
1168 :
1169 : /* {{{ spl_filesystem_dir_it_current_data */
1170 : static void spl_filesystem_dir_it_current_data(zend_object_iterator *iter, zval ***data TSRMLS_DC)
1171 0 : {
1172 0 : spl_filesystem_dir_it *iterator = (spl_filesystem_dir_it *)iter;
1173 :
1174 0 : *data = &iterator->current;
1175 0 : }
1176 : /* }}} */
1177 :
1178 : /* {{{ spl_filesystem_dir_it_current_key */
1179 : static int spl_filesystem_dir_it_current_key(zend_object_iterator *iter, char **str_key, uint *str_key_len, ulong *int_key TSRMLS_DC)
1180 0 : {
1181 0 : spl_filesystem_dir_it *iterator = (spl_filesystem_dir_it *)iter;
1182 0 : spl_filesystem_object *object = iterator->object;
1183 :
1184 0 : *int_key = object->u.dir.index;
1185 0 : return HASH_KEY_IS_LONG;
1186 : }
1187 : /* }}} */
1188 :
1189 : /* {{{ spl_filesystem_dir_it_move_forward */
1190 : static void spl_filesystem_dir_it_move_forward(zend_object_iterator *iter TSRMLS_DC)
1191 0 : {
1192 0 : spl_filesystem_dir_it *iterator = (spl_filesystem_dir_it *)iter;
1193 0 : spl_filesystem_object *object = iterator->object;
1194 :
1195 0 : object->u.dir.index++;
1196 0 : if (!object->u.dir.dirp || !php_stream_readdir(object->u.dir.dirp, &object->u.dir.entry)) {
1197 0 : object->u.dir.entry.d_name[0] = '\0';
1198 : }
1199 0 : if (object->file_name) {
1200 0 : efree(object->file_name);
1201 0 : object->file_name = NULL;
1202 : }
1203 0 : }
1204 : /* }}} */
1205 :
1206 : /* {{{ spl_filesystem_dir_it_rewind */
1207 : static void spl_filesystem_dir_it_rewind(zend_object_iterator *iter TSRMLS_DC)
1208 0 : {
1209 0 : spl_filesystem_dir_it *iterator = (spl_filesystem_dir_it *)iter;
1210 0 : spl_filesystem_object *object = iterator->object;
1211 :
1212 0 : object->u.dir.index = 0;
1213 0 : if (object->u.dir.dirp) {
1214 0 : php_stream_rewinddir(object->u.dir.dirp);
1215 : }
1216 0 : if (!object->u.dir.dirp || !php_stream_readdir(object->u.dir.dirp, &object->u.dir.entry)) {
1217 0 : object->u.dir.entry.d_name[0] = '\0';
1218 : }
1219 0 : }
1220 : /* }}} */
1221 :
1222 : /* {{{ spl_filesystem_tree_it_dtor */
1223 : static void spl_filesystem_tree_it_dtor(zend_object_iterator *iter TSRMLS_DC)
1224 0 : {
1225 0 : spl_filesystem_dir_it *iterator = (spl_filesystem_dir_it *)iter;
1226 :
1227 0 : if (iterator->current) {
1228 0 : zval_ptr_dtor(&iterator->current);
1229 : }
1230 0 : zval_ptr_dtor((zval**)&iterator->intern.data);
1231 :
1232 0 : efree(iterator);
1233 0 : }
1234 : /* }}} */
1235 :
1236 : /* {{{ spl_filesystem_tree_it_current_data */
1237 : static void spl_filesystem_tree_it_current_data(zend_object_iterator *iter, zval ***data TSRMLS_DC)
1238 0 : {
1239 0 : spl_filesystem_dir_it *iterator = (spl_filesystem_dir_it *)iter;
1240 0 : spl_filesystem_object *object = iterator->object;
1241 :
1242 0 : if (object->flags & SPL_FILE_DIR_CURRENT_AS_PATHNAME) {
1243 0 : if (!iterator->current) {
1244 0 : ALLOC_INIT_ZVAL(iterator->current);
1245 0 : spl_filesystem_object_get_file_name(object TSRMLS_CC);
1246 0 : ZVAL_STRINGL(iterator->current, object->file_name, object->file_name_len, 1);
1247 : }
1248 0 : *data = &iterator->current;
1249 0 : } else if (object->flags & SPL_FILE_DIR_CURRENT_AS_FILEINFO) {
1250 0 : if (!iterator->current) {
1251 0 : ALLOC_INIT_ZVAL(iterator->current);
1252 0 : spl_filesystem_object_get_file_name(object TSRMLS_CC);
1253 0 : spl_filesystem_object_create_type(0, object, SPL_FS_INFO, NULL, iterator->current TSRMLS_CC);
1254 : }
1255 0 : *data = &iterator->current;
1256 : } else {
1257 0 : *data = (zval**)&iterator->intern.data;
1258 : }
1259 0 : }
1260 : /* }}} */
1261 :
1262 : /* {{{ spl_filesystem_tree_it_current_key */
1263 : static int spl_filesystem_tree_it_current_key(zend_object_iterator *iter, char **str_key, uint *str_key_len, ulong *int_key TSRMLS_DC)
1264 0 : {
1265 0 : spl_filesystem_dir_it *iterator = (spl_filesystem_dir_it *)iter;
1266 0 : spl_filesystem_object *object = iterator->object;
1267 :
1268 0 : if (object->flags & SPL_FILE_DIR_KEY_AS_FILENAME) {
1269 0 : *str_key_len = strlen(object->u.dir.entry.d_name) + 1;
1270 0 : *str_key = estrndup(object->u.dir.entry.d_name, *str_key_len - 1);
1271 : } else {
1272 0 : spl_filesystem_object_get_file_name(object TSRMLS_CC);
1273 0 : *str_key_len = object->file_name_len + 1;
1274 0 : *str_key = estrndup(object->file_name, object->file_name_len);
1275 : }
1276 0 : return HASH_KEY_IS_STRING;
1277 : }
1278 : /* }}} */
1279 :
1280 : /* {{{ spl_filesystem_tree_it_move_forward */
1281 : static void spl_filesystem_tree_it_move_forward(zend_object_iterator *iter TSRMLS_DC)
1282 0 : {
1283 0 : spl_filesystem_dir_it *iterator = (spl_filesystem_dir_it *)iter;
1284 0 : spl_filesystem_object *object = iterator->object;
1285 :
1286 0 : object->u.dir.index++;
1287 : do {
1288 0 : if (!object->u.dir.dirp || !php_stream_readdir(object->u.dir.dirp, &object->u.dir.entry)) {
1289 0 : object->u.dir.entry.d_name[0] = '\0';
1290 : }
1291 0 : } while (spl_filesystem_is_dot(object->u.dir.entry.d_name));
1292 0 : if (object->file_name) {
1293 0 : efree(object->file_name);
1294 0 : object->file_name = NULL;
1295 : }
1296 0 : if (iterator->current) {
1297 0 : zval_ptr_dtor(&iterator->current);
1298 0 : iterator->current = NULL;
1299 : }
1300 0 : }
1301 : /* }}} */
1302 :
1303 : /* {{{ spl_filesystem_tree_it_rewind */
1304 : static void spl_filesystem_tree_it_rewind(zend_object_iterator *iter TSRMLS_DC)
1305 0 : {
1306 0 : spl_filesystem_dir_it *iterator = (spl_filesystem_dir_it *)iter;
1307 0 : spl_filesystem_object *object = iterator->object;
1308 :
1309 0 : object->u.dir.index = 0;
1310 0 : if (object->u.dir.dirp) {
1311 0 : php_stream_rewinddir(object->u.dir.dirp);
1312 : }
1313 : do {
1314 0 : if (!object->u.dir.dirp || !php_stream_readdir(object->u.dir.dirp, &object->u.dir.entry)) {
1315 0 : object->u.dir.entry.d_name[0] = '\0';
1316 : }
1317 0 : } while (spl_filesystem_is_dot(object->u.dir.entry.d_name));
1318 0 : if (iterator->current) {
1319 0 : zval_ptr_dtor(&iterator->current);
1320 0 : iterator->current = NULL;
1321 : }
1322 0 : }
1323 : /* }}} */
1324 :
1325 : /* iterator handler table */
1326 : zend_object_iterator_funcs spl_filesystem_tree_it_funcs = {
1327 : spl_filesystem_tree_it_dtor,
1328 : spl_filesystem_dir_it_valid,
1329 : spl_filesystem_tree_it_current_data,
1330 : spl_filesystem_tree_it_current_key,
1331 : spl_filesystem_tree_it_move_forward,
1332 : spl_filesystem_tree_it_rewind
1333 : };
1334 :
1335 : /* {{{ spl_ce_dir_get_iterator */
1336 : zend_object_iterator *spl_filesystem_tree_get_iterator(zend_class_entry *ce, zval *object, int by_ref TSRMLS_DC)
1337 0 : {
1338 : spl_filesystem_dir_it *iterator;
1339 : spl_filesystem_object *dir_object;
1340 :
1341 0 : if (by_ref) {
1342 0 : zend_error(E_ERROR, "An iterator cannot be used with foreach by reference");
1343 : }
1344 0 : iterator = emalloc(sizeof(spl_filesystem_dir_it));
1345 0 : dir_object = (spl_filesystem_object*)zend_object_store_get_object(object TSRMLS_CC);
1346 :
1347 0 : object->refcount++;
1348 0 : iterator->intern.data = (void*)object;
1349 0 : iterator->intern.funcs = &spl_filesystem_tree_it_funcs;
1350 0 : iterator->current = NULL;
1351 0 : iterator->object = dir_object;
1352 :
1353 0 : return (zend_object_iterator*)iterator;
1354 : }
1355 : /* }}} */
1356 :
1357 : /* {{{ spl_filesystem_object_cast */
1358 : static int spl_filesystem_object_cast(zval *readobj, zval *writeobj, int type TSRMLS_DC)
1359 0 : {
1360 0 : spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(readobj TSRMLS_CC);
1361 :
1362 0 : if (type == IS_STRING) {
1363 0 : switch (intern->type) {
1364 : case SPL_FS_INFO:
1365 : case SPL_FS_FILE:
1366 0 : ZVAL_STRINGL(writeobj, intern->file_name, intern->file_name_len, 1);
1367 0 : return SUCCESS;
1368 : case SPL_FS_DIR:
1369 0 : ZVAL_STRING(writeobj, intern->u.dir.entry.d_name, 1);
1370 0 : return SUCCESS;
1371 : }
1372 : }
1373 0 : ZVAL_NULL(writeobj);
1374 0 : return FAILURE;
1375 : }
1376 : /* }}} */
1377 :
1378 : /* declare method parameters */
1379 : /* supply a name and default to call by parameter */
1380 : static
1381 : ZEND_BEGIN_ARG_INFO(arginfo_info___construct, 0)
1382 : ZEND_ARG_INFO(0, file_name)
1383 : ZEND_END_ARG_INFO()
1384 :
1385 : static
1386 : ZEND_BEGIN_ARG_INFO_EX(arginfo_info_openFile, 0, 0, 0)
1387 : ZEND_ARG_INFO(0, open_mode)
1388 : ZEND_ARG_INFO(0, use_include_path)
1389 : ZEND_ARG_INFO(0, context)
1390 : ZEND_END_ARG_INFO()
1391 :
1392 : static
1393 : ZEND_BEGIN_ARG_INFO_EX(arginfo_info_optinalFileClass, 0, 0, 0)
1394 : ZEND_ARG_INFO(0, class_name)
1395 : ZEND_END_ARG_INFO()
1396 :
1397 : static
1398 : ZEND_BEGIN_ARG_INFO_EX(arginfo_optinalSuffix, 0, 0, 0)
1399 : ZEND_ARG_INFO(0, suffix)
1400 : ZEND_END_ARG_INFO()
1401 :
1402 : /* the method table */
1403 : /* each method can have its own parameters and visibility */
1404 : static zend_function_entry spl_SplFileInfo_functions[] = {
1405 : SPL_ME(SplFileInfo, __construct, arginfo_info___construct, ZEND_ACC_PUBLIC)
1406 : SPL_ME(SplFileInfo, getPath, NULL, ZEND_ACC_PUBLIC)
1407 : SPL_ME(SplFileInfo, getFilename, NULL, ZEND_ACC_PUBLIC)
1408 : SPL_ME(SplFileInfo, getBasename, arginfo_optinalSuffix, ZEND_ACC_PUBLIC)
1409 : SPL_ME(SplFileInfo, getPathname, NULL, ZEND_ACC_PUBLIC)
1410 : SPL_ME(SplFileInfo, getPerms, NULL, ZEND_ACC_PUBLIC)
1411 : SPL_ME(SplFileInfo, getInode, NULL, ZEND_ACC_PUBLIC)
1412 : SPL_ME(SplFileInfo, getSize, NULL, ZEND_ACC_PUBLIC)
1413 : SPL_ME(SplFileInfo, getOwner, NULL, ZEND_ACC_PUBLIC)
1414 : SPL_ME(SplFileInfo, getGroup, NULL, ZEND_ACC_PUBLIC)
1415 : SPL_ME(SplFileInfo, getATime, NULL, ZEND_ACC_PUBLIC)
1416 : SPL_ME(SplFileInfo, getMTime, NULL, ZEND_ACC_PUBLIC)
1417 : SPL_ME(SplFileInfo, getCTime, NULL, ZEND_ACC_PUBLIC)
1418 : SPL_ME(SplFileInfo, getType, NULL, ZEND_ACC_PUBLIC)
1419 : SPL_ME(SplFileInfo, isWritable, NULL, ZEND_ACC_PUBLIC)
1420 : SPL_ME(SplFileInfo, isReadable, NULL, ZEND_ACC_PUBLIC)
1421 : SPL_ME(SplFileInfo, isExecutable, NULL, ZEND_ACC_PUBLIC)
1422 : SPL_ME(SplFileInfo, isFile, NULL, ZEND_ACC_PUBLIC)
1423 : SPL_ME(SplFileInfo, isDir, NULL, ZEND_ACC_PUBLIC)
1424 : SPL_ME(SplFileInfo, isLink, NULL, ZEND_ACC_PUBLIC)
1425 : SPL_ME(SplFileInfo, getLinkTarget, NULL, ZEND_ACC_PUBLIC)
1426 : #if (!defined(__BEOS__) && !defined(NETWARE) && HAVE_REALPATH) || defined(ZTS)
1427 : SPL_ME(SplFileInfo, getRealPath, NULL, ZEND_ACC_PUBLIC)
1428 : #endif
1429 : SPL_ME(SplFileInfo, getFileInfo, arginfo_info_optinalFileClass, ZEND_ACC_PUBLIC)
1430 : SPL_ME(SplFileInfo, getPathInfo, arginfo_info_optinalFileClass, ZEND_ACC_PUBLIC)
1431 : SPL_ME(SplFileInfo, openFile, arginfo_info_openFile, ZEND_ACC_PUBLIC)
1432 : SPL_ME(SplFileInfo, setFileClass, arginfo_info_optinalFileClass, ZEND_ACC_PUBLIC)
1433 : SPL_ME(SplFileInfo, setInfoClass, arginfo_info_optinalFileClass, ZEND_ACC_PUBLIC)
1434 : SPL_MA(SplFileInfo, __toString, SplFileInfo, getPathname, NULL, ZEND_ACC_PUBLIC)
1435 : {NULL, NULL, NULL}
1436 : };
1437 :
1438 : static
1439 : ZEND_BEGIN_ARG_INFO(arginfo_dir___construct, 0)
1440 : ZEND_ARG_INFO(0, path)
1441 : ZEND_END_ARG_INFO()
1442 :
1443 : /* the method table */
1444 : /* each method can have its own parameters and visibility */
1445 : static zend_function_entry spl_DirectoryIterator_functions[] = {
1446 : SPL_ME(DirectoryIterator, __construct, arginfo_dir___construct, ZEND_ACC_PUBLIC)
1447 : SPL_ME(DirectoryIterator, getFilename, NULL, ZEND_ACC_PUBLIC)
1448 : SPL_ME(DirectoryIterator, getBasename, arginfo_optinalSuffix, ZEND_ACC_PUBLIC)
1449 : SPL_ME(DirectoryIterator, isDot, NULL, ZEND_ACC_PUBLIC)
1450 : SPL_ME(DirectoryIterator, rewind, NULL, ZEND_ACC_PUBLIC)
1451 : SPL_ME(DirectoryIterator, valid, NULL, ZEND_ACC_PUBLIC)
1452 : SPL_ME(DirectoryIterator, key, NULL, ZEND_ACC_PUBLIC)
1453 : SPL_ME(DirectoryIterator, current, NULL, ZEND_ACC_PUBLIC)
1454 : SPL_ME(DirectoryIterator, next, NULL, ZEND_ACC_PUBLIC)
1455 : SPL_MA(DirectoryIterator, __toString, DirectoryIterator, getFilename, NULL, ZEND_ACC_PUBLIC)
1456 : {NULL, NULL, NULL}
1457 : };
1458 :
1459 : static
1460 : ZEND_BEGIN_ARG_INFO_EX(arginfo_r_dir___construct, 0, 0, 1)
1461 : ZEND_ARG_INFO(0, path)
1462 : ZEND_ARG_INFO(0, flags)
1463 : ZEND_END_ARG_INFO()
1464 :
1465 : static
1466 : ZEND_BEGIN_ARG_INFO_EX(arginfo_r_dir_hasChildren, 0, 0, 0)
1467 : ZEND_ARG_INFO(0, allow_links)
1468 : ZEND_END_ARG_INFO()
1469 :
1470 : static zend_function_entry spl_RecursiveDirectoryIterator_functions[] = {
1471 : SPL_ME(RecursiveDirectoryIterator, __construct, arginfo_r_dir___construct, ZEND_ACC_PUBLIC)
1472 : SPL_ME(RecursiveDirectoryIterator, rewind, NULL, ZEND_ACC_PUBLIC)
1473 : SPL_ME(RecursiveDirectoryIterator, next, NULL, ZEND_ACC_PUBLIC)
1474 : SPL_ME(RecursiveDirectoryIterator, key, NULL, ZEND_ACC_PUBLIC)
1475 : SPL_ME(RecursiveDirectoryIterator, current, NULL, ZEND_ACC_PUBLIC)
1476 : SPL_ME(RecursiveDirectoryIterator, hasChildren, arginfo_r_dir_hasChildren, ZEND_ACC_PUBLIC)
1477 : SPL_ME(RecursiveDirectoryIterator, getChildren, NULL, ZEND_ACC_PUBLIC)
1478 : SPL_ME(RecursiveDirectoryIterator, getSubPath, NULL, ZEND_ACC_PUBLIC)
1479 : SPL_ME(RecursiveDirectoryIterator, getSubPathname,NULL, ZEND_ACC_PUBLIC)
1480 : {NULL, NULL, NULL}
1481 : };
1482 :
1483 : static int spl_filesystem_file_read(spl_filesystem_object *intern, int silent TSRMLS_DC) /* {{{ */
1484 0 : {
1485 : char *buf;
1486 0 : size_t line_len = 0;
1487 : int len;
1488 0 : long line_add = (intern->u.file.current_line || intern->u.file.current_zval) ? 1 : 0;
1489 :
1490 0 : spl_filesystem_file_free_line(intern TSRMLS_CC);
1491 :
1492 0 : if (php_stream_eof(intern->u.file.stream)) {
1493 0 : if (!silent) {
1494 0 : zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC, "Cannot read from file %s", intern->file_name);
1495 : }
1496 0 : return FAILURE;
1497 : }
1498 :
1499 0 : if (intern->u.file.max_line_len > 0) {
1500 0 : buf = safe_emalloc((intern->u.file.max_line_len + 1), sizeof(char), 0);
1501 0 : if (php_stream_get_line(intern->u.file.stream, buf, intern->u.file.max_line_len, &line_len) == NULL) {
1502 0 : efree(buf);
1503 0 : buf = NULL;
1504 : } else {
1505 0 : buf[line_len] = '\0';
1506 : }
1507 : } else {
1508 0 : buf = php_stream_get_line(intern->u.file.stream, NULL, 0, &line_len);
1509 : }
1510 :
1511 0 : if (!buf) {
1512 0 : intern->u.file.current_line = estrdup("");
1513 0 : intern->u.file.current_line_len = 0;
1514 : } else {
1515 0 : if (intern->flags & SPL_FILE_OBJECT_DROP_NEW_LINE) {
1516 0 : line_len = strcspn(buf, "\r\n");
1517 0 : buf[line_len] = '\0';
1518 : }
1519 :
1520 0 : if (PG(magic_quotes_runtime)) {
1521 0 : buf = php_addslashes(buf, line_len, &len, 1 TSRMLS_CC);
1522 0 : line_len = len;
1523 : }
1524 :
1525 0 : intern->u.file.current_line = buf;
1526 0 : intern->u.file.current_line_len = line_len;
1527 : }
1528 0 : intern->u.file.current_line_num += line_add;
1529 :
1530 0 : return SUCCESS;
1531 : } /* }}} */
1532 :
1533 : static int spl_filesystem_file_call(spl_filesystem_object *intern, zend_function *func_ptr, int pass_num_args, zval *return_value, zval *arg2 TSRMLS_DC) /* {{{ */
1534 0 : {
1535 : zend_fcall_info fci;
1536 : zend_fcall_info_cache fcic;
1537 : zval z_fname;
1538 0 : zval * zresource_ptr = &intern->u.file.zresource, *retval;
1539 : int result;
1540 0 : int num_args = pass_num_args + (arg2 ? 2 : 1);
1541 :
1542 0 : zval ***params = (zval***)safe_emalloc(num_args, sizeof(zval**), 0);
1543 :
1544 0 : params[0] = &zresource_ptr;
1545 :
1546 0 : if (arg2) {
1547 0 : params[1] = &arg2;
1548 : }
1549 :
1550 0 : zend_get_parameters_array_ex(pass_num_args, params+(arg2 ? 2 : 1));
1551 :
1552 0 : ZVAL_STRING(&z_fname, func_ptr->common.function_name, 0);
1553 :
1554 0 : fci.size = sizeof(fci);
1555 0 : fci.function_table = EG(function_table);
1556 0 : fci.object_pp = NULL;
1557 0 : fci.function_name = &z_fname;
1558 0 : fci.retval_ptr_ptr = &retval;
1559 0 : fci.param_count = num_args;
1560 0 : fci.params = params;
1561 0 : fci.no_separation = 1;
1562 0 : fci.symbol_table = NULL;
1563 :
1564 0 : fcic.initialized = 1;
1565 0 : fcic.function_handler = func_ptr;
1566 0 : fcic.calling_scope = NULL;
1567 0 : fcic.object_pp = NULL;
1568 :
1569 0 : result = zend_call_function(&fci, &fcic TSRMLS_CC);
1570 :
1571 0 : ZVAL_ZVAL(return_value, retval, 1, 1);
1572 :
1573 0 : efree(params);
1574 0 : return result;
1575 : } /* }}} */
1576 :
1577 : #define FileFunctionCall(func_name, pass_num_args, arg2) \
1578 : { \
1579 : zend_function *func_ptr; \
1580 : zend_hash_find(EG(function_table), #func_name, sizeof(#func_name), (void **) &func_ptr); \
1581 : spl_filesystem_file_call(intern, func_ptr, pass_num_args, return_value, arg2 TSRMLS_CC); \
1582 : }
1583 :
1584 : static int spl_filesystem_file_read_csv(spl_filesystem_object *intern, char delimiter, char enclosure, zval *return_value TSRMLS_DC) /* {{{ */
1585 0 : {
1586 0 : int ret = SUCCESS;
1587 :
1588 : do {
1589 0 : ret = spl_filesystem_file_read(intern, 1 TSRMLS_CC);
1590 0 : } while (ret == SUCCESS && !intern->u.file.current_line_len && (intern->flags & SPL_FILE_OBJECT_SKIP_EMPTY));
1591 :
1592 0 : if (ret == SUCCESS) {
1593 0 : size_t buf_len = intern->u.file.current_line_len;
1594 0 : char *buf = estrndup(intern->u.file.current_line, buf_len);
1595 :
1596 0 : if (intern->u.file.current_zval) {
1597 0 : zval_ptr_dtor(&intern->u.file.current_zval);
1598 : }
1599 0 : ALLOC_INIT_ZVAL(intern->u.file.current_zval);
1600 :
1601 0 : php_fgetcsv(intern->u.file.stream, delimiter, enclosure, buf_len, buf, intern->u.file.current_zval TSRMLS_CC);
1602 0 : if (return_value) {
1603 0 : if (Z_TYPE_P(return_value) != IS_NULL) {
1604 0 : zval_dtor(return_value);
1605 0 : ZVAL_NULL(return_value);
1606 : }
1607 0 : ZVAL_ZVAL(return_value, intern->u.file.current_zval, 1, 0);
1608 : }
1609 : }
1610 0 : return ret;
1611 : }
1612 : /* }}} */
1613 :
1614 : static int spl_filesystem_file_read_line_ex(zval * this_ptr, spl_filesystem_object *intern, int silent TSRMLS_DC) /* {{{ */
1615 0 : {
1616 0 : zval *retval = NULL;
1617 :
1618 : /* 1) use fgetcsv? 2) overloaded call the function, 3) do it directly */
1619 0 : if (intern->flags & SPL_FILE_OBJECT_READ_CSV || intern->u.file.func_getCurr->common.scope != spl_ce_SplFileObject) {
1620 0 : if (php_stream_eof(intern->u.file.stream)) {
1621 0 : if (!silent) {
1622 0 : zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC, "Cannot read from file %s", intern->file_name);
1623 : }
1624 0 : return FAILURE;
1625 : }
1626 0 : if (intern->flags & SPL_FILE_OBJECT_READ_CSV) {
1627 0 : return spl_filesystem_file_read_csv(intern, intern->u.file.delimiter, intern->u.file.enclosure, NULL TSRMLS_CC);
1628 : } else {
1629 0 : zend_call_method_with_0_params(&this_ptr, Z_OBJCE_P(getThis()), &intern->u.file.func_getCurr, "getCurrentLine", &retval);
1630 : }
1631 0 : if (retval) {
1632 0 : if (intern->u.file.current_line || intern->u.file.current_zval) {
1633 0 : intern->u.file.current_line_num++;
1634 : }
1635 0 : spl_filesystem_file_free_line(intern TSRMLS_CC);
1636 0 : if (Z_TYPE_P(retval) == IS_STRING) {
1637 0 : intern->u.file.current_line = estrndup(Z_STRVAL_P(retval), Z_STRLEN_P(retval));
1638 0 : intern->u.file.current_line_len = Z_STRLEN_P(retval);
1639 : } else {
1640 0 : MAKE_STD_ZVAL(intern->u.file.current_zval);
1641 0 : ZVAL_ZVAL(intern->u.file.current_zval, retval, 1, 0);
1642 : }
1643 0 : zval_ptr_dtor(&retval);
1644 0 : return SUCCESS;
1645 : } else {
1646 0 : return FAILURE;
1647 : }
1648 : } else {
1649 0 : return spl_filesystem_file_read(intern, silent TSRMLS_CC);
1650 : }
1651 : } /* }}} */
1652 :
1653 : static int spl_filesystem_file_is_empty_line(spl_filesystem_object *intern TSRMLS_DC) /* {{{ */
1654 0 : {
1655 0 : if (intern->u.file.current_line) {
1656 0 : return intern->u.file.current_line_len == 0;
1657 0 : } else if (intern->u.file.current_zval) {
1658 0 : switch(Z_TYPE_P(intern->u.file.current_zval)) {
1659 : case IS_STRING:
1660 0 : return Z_STRLEN_P(intern->u.file.current_zval) == 0;
1661 : case IS_ARRAY:
1662 0 : if ((intern->flags & SPL_FILE_OBJECT_READ_CSV)
1663 : && zend_hash_num_elements(Z_ARRVAL_P(intern->u.file.current_zval)) == 1) {
1664 0 : zval ** first = Z_ARRVAL_P(intern->u.file.current_zval)->pListHead->pData;
1665 :
1666 0 : return Z_TYPE_PP(first) == IS_STRING && Z_STRLEN_PP(first) == 0;
1667 : }
1668 0 : return zend_hash_num_elements(Z_ARRVAL_P(intern->u.file.current_zval)) == 0;
1669 : case IS_NULL:
1670 0 : return 1;
1671 : default:
1672 0 : return 0;
1673 : }
1674 : } else {
1675 0 : return 1;
1676 : }
1677 : }
1678 : /* }}} */
1679 :
1680 : static int spl_filesystem_file_read_line(zval * this_ptr, spl_filesystem_object *intern, int silent TSRMLS_DC) /* {{{ */
1681 0 : {
1682 0 : int ret = spl_filesystem_file_read_line_ex(this_ptr, intern, silent TSRMLS_CC);
1683 :
1684 0 : while ((intern->flags & SPL_FILE_OBJECT_SKIP_EMPTY) && ret == SUCCESS && spl_filesystem_file_is_empty_line(intern TSRMLS_CC)) {
1685 0 : spl_filesystem_file_free_line(intern TSRMLS_CC);
1686 0 : ret = spl_filesystem_file_read_line_ex(this_ptr, intern, silent TSRMLS_CC);
1687 : }
1688 :
1689 0 : return ret;
1690 : }
1691 : /* }}} */
1692 :
1693 : static void spl_filesystem_file_rewind(zval * this_ptr, spl_filesystem_object *intern TSRMLS_DC) /* {{{ */
1694 0 : {
1695 0 : if (-1 == php_stream_rewind(intern->u.file.stream)) {
1696 0 : zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC, "Cannot rewind file %s", intern->file_name);
1697 : } else {
1698 0 : spl_filesystem_file_free_line(intern TSRMLS_CC);
1699 0 : intern->u.file.current_line_num = 0;
1700 : }
1701 0 : if (intern->flags & SPL_FILE_OBJECT_READ_AHEAD) {
1702 0 : spl_filesystem_file_read_line(this_ptr, intern, 1 TSRMLS_CC);
1703 : }
1704 0 : } /* }}} */
1705 :
1706 : /* {{{ proto void SplFileObject::__construct(string filename [, string mode = 'r' [, bool use_include_path [, resource context]]]])
1707 : Construct a new file object */
1708 : SPL_METHOD(SplFileObject, __construct)
1709 0 : {
1710 0 : spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
1711 0 : zend_bool use_include_path = 0;
1712 : char *p1, *p2;
1713 :
1714 0 : php_set_error_handling(EH_THROW, spl_ce_RuntimeException TSRMLS_CC);
1715 :
1716 0 : intern->u.file.open_mode = "r";
1717 0 : intern->u.file.open_mode_len = 1;
1718 :
1719 0 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|sbr",
1720 : &intern->file_name, &intern->file_name_len,
1721 : &intern->u.file.open_mode, &intern->u.file.open_mode_len,
1722 : &use_include_path, &intern->u.file.zcontext) == FAILURE) {
1723 0 : php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC);
1724 0 : return;
1725 : }
1726 :
1727 0 : if (spl_filesystem_file_open(intern, use_include_path, 0 TSRMLS_CC) == SUCCESS) {
1728 0 : p1 = strrchr(intern->file_name, '/');
1729 : #if defined(PHP_WIN32) || defined(NETWARE)
1730 : p2 = strrchr(intern->file_name, '\\');
1731 : #else
1732 0 : p2 = 0;
1733 : #endif
1734 0 : if (p1 || p2) {
1735 0 : intern->path_len = (p1 > p2 ? p1 : p2) - intern->file_name;
1736 : } else {
1737 0 : intern->path_len = 0;
1738 : }
1739 0 : intern->path = estrndup(intern->file_name, intern->path_len);
1740 : }
1741 :
1742 0 : php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC);
1743 : } /* }}} */
1744 :
1745 : /* {{{ proto void SplTempFileObject::__construct([int max_memory])
1746 : Construct a new temp file object */
1747 : SPL_METHOD(SplTempFileObject, __construct)
1748 0 : {
1749 0 : long max_memory = PHP_STREAM_MAX_MEM;
1750 : char tmp_fname[48];
1751 0 : spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
1752 :
1753 0 : php_set_error_handling(EH_THROW, spl_ce_RuntimeException TSRMLS_CC);
1754 :
1755 0 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &max_memory) == FAILURE) {
1756 0 : php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC);
1757 0 : return;
1758 : }
1759 :
1760 0 : if (max_memory < 0) {
1761 0 : intern->file_name = "php://memory";
1762 0 : intern->file_name_len = 12;
1763 0 : } else if (ZEND_NUM_ARGS()) {
1764 0 : intern->file_name_len = slprintf(tmp_fname, sizeof(tmp_fname), "php://temp/maxmemory:%ld", max_memory);
1765 0 : intern->file_name = tmp_fname;
1766 : } else {
1767 0 : intern->file_name = "php://temp";
1768 0 : intern->file_name_len = 10;
1769 : }
1770 0 : intern->u.file.open_mode = "wb";
1771 0 : intern->u.file.open_mode_len = 1;
1772 0 : intern->u.file.zcontext = NULL;
1773 :
1774 0 : if (spl_filesystem_file_open(intern, 0, 0 TSRMLS_CC) == SUCCESS) {
1775 0 : intern->path_len = 0;
1776 0 : intern->path = estrndup("", 0);
1777 : }
1778 :
1779 0 : php_set_error_handling(EH_NORMAL, NULL TSRMLS_CC);
1780 : } /* }}} */
1781 :
1782 : /* {{{ proto void SplFileObject::rewind()
1783 : Rewind the file and read the first line */
1784 : SPL_METHOD(SplFileObject, rewind)
1785 0 : {
1786 0 : spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
1787 :
1788 0 : spl_filesystem_file_rewind(getThis(), intern TSRMLS_CC);
1789 0 : } /* }}} */
1790 :
1791 : /* {{{ proto void SplFileObject::eof()
1792 : Return whether end of file is reached */
1793 : SPL_METHOD(SplFileObject, eof)
1794 0 : {
1795 0 : spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
1796 :
1797 0 : RETURN_BOOL(php_stream_eof(intern->u.file.stream));
1798 : } /* }}} */
1799 :
1800 : /* {{{ proto void SplFileObject::valid()
1801 : Return !eof() */
1802 : SPL_METHOD(SplFileObject, valid)
1803 0 : {
1804 0 : spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
1805 :
1806 0 : if (intern->flags & SPL_FILE_OBJECT_READ_AHEAD) {
1807 0 : RETURN_BOOL(intern->u.file.current_line || intern->u.file.current_zval);
1808 : } else {
1809 0 : RETVAL_BOOL(!php_stream_eof(intern->u.file.stream));
1810 : }
1811 : } /* }}} */
1812 :
1813 : /* {{{ proto string SplFileObject::fgets()
1814 : Rturn next line from file */
1815 : SPL_METHOD(SplFileObject, fgets)
1816 0 : {
1817 0 : spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
1818 :
1819 0 : if (spl_filesystem_file_read(intern, 0 TSRMLS_CC) == FAILURE) {
1820 0 : RETURN_FALSE;
1821 : }
1822 0 : RETURN_STRINGL(intern->u.file.current_line, intern->u.file.current_line_len, 1);
1823 : } /* }}} */
1824 :
1825 : /* {{{ proto string SplFileObject::current()
1826 : Return current line from file */
1827 : SPL_METHOD(SplFileObject, current)
1828 0 : {
1829 0 : spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
1830 :
1831 0 : if (!intern->u.file.current_line && !intern->u.file.current_zval) {
1832 0 : spl_filesystem_file_read_line(getThis(), intern, 1 TSRMLS_CC);
1833 : }
1834 0 : if (intern->u.file.current_line && (!(intern->flags & SPL_FILE_OBJECT_READ_CSV) || !intern->u.file.current_zval)) {
1835 0 : RETURN_STRINGL(intern->u.file.current_line, intern->u.file.current_line_len, 1);
1836 0 : } else if (intern->u.file.current_zval) {
1837 0 : RETURN_ZVAL(intern->u.file.current_zval, 1, 0);
1838 : }
1839 0 : RETURN_FALSE;
1840 : } /* }}} */
1841 :
1842 : /* {{{ proto int SplFileObject::key()
1843 : Return line number */
1844 : SPL_METHOD(SplFileObject, key)
1845 0 : {
1846 0 : spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
1847 :
1848 : /* Do not read the next line to support correct counting with fgetc()
1849 : if (!intern->current_line) {
1850 : spl_filesystem_file_read_line(getThis(), intern, 1 TSRMLS_CC);
1851 : } */
1852 0 : RETURN_LONG(intern->u.file.current_line_num);
1853 : } /* }}} */
1854 :
1855 : /* {{{ proto void SplFileObject::next()
1856 : Read next line */
1857 : SPL_METHOD(SplFileObject, next)
1858 0 : {
1859 0 : spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
1860 :
1861 0 : spl_filesystem_file_free_line(intern TSRMLS_CC);
1862 0 : if (intern->flags & SPL_FILE_OBJECT_READ_AHEAD) {
1863 0 : spl_filesystem_file_read_line(getThis(), intern, 1 TSRMLS_CC);
1864 : }
1865 0 : intern->u.file.current_line_num++;
1866 0 : } /* }}} */
1867 :
1868 : /* {{{ proto void SplFileObject::setFlags(int flags)
1869 : Set file handling flags */
1870 : SPL_METHOD(SplFileObject, setFlags)
1871 0 : {
1872 0 : spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
1873 :
1874 0 : zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &intern->flags);
1875 0 : } /* }}} */
1876 :
1877 : /* {{{ proto int SplFileObject::getFlags()
1878 : Get file handling flags */
1879 : SPL_METHOD(SplFileObject, getFlags)
1880 0 : {
1881 0 : spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
1882 :
1883 0 : RETURN_LONG(intern->flags);
1884 : } /* }}} */
1885 :
1886 : /* {{{ proto void SplFileObject::setMaxLineLen(int max_len)
1887 : Set maximum line length */
1888 : SPL_METHOD(SplFileObject, setMaxLineLen)
1889 0 : {
1890 : long max_len;
1891 :
1892 0 : spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
1893 :
1894 0 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &max_len) == FAILURE) {
1895 0 : return;
1896 : }
1897 :
1898 0 : if (max_len < 0) {
1899 0 : zend_throw_exception_ex(spl_ce_DomainException, 0 TSRMLS_CC, "Maximum line length must be greater than or equal zero");
1900 0 : return;
1901 : }
1902 :
1903 0 : intern->u.file.max_line_len = max_len;
1904 : } /* }}} */
1905 :
1906 : /* {{{ proto int SplFileObject::getMaxLineLen()
1907 : Get maximum line length */
1908 : SPL_METHOD(SplFileObject, getMaxLineLen)
1909 0 : {
1910 0 : spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
1911 :
1912 0 : RETURN_LONG((long)intern->u.file.max_line_len);
1913 : } /* }}} */
1914 :
1915 : /* {{{ proto bool SplFileObject::hasChildren()
1916 : Return false */
1917 : SPL_METHOD(SplFileObject, hasChildren)
1918 0 : {
1919 0 : RETURN_FALSE;
1920 : } /* }}} */
1921 :
1922 : /* {{{ proto bool SplFileObject::getChildren()
1923 : Read NULL */
1924 : SPL_METHOD(SplFileObject, getChildren)
1925 0 : {
1926 : /* return NULL */
1927 0 : } /* }}} */
1928 :
1929 : /* {{{ FileFunction */
1930 : #define FileFunction(func_name) \
1931 : SPL_METHOD(SplFileObject, func_name) \
1932 : { \
1933 : spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC); \
1934 : FileFunctionCall(func_name, ZEND_NUM_ARGS(), NULL); \
1935 : }
1936 : /* }}} */
1937 :
1938 : /* {{{ proto array SplFileObject::fgetcsv([string delimiter [, string enclosure]])
1939 : Return current line as csv */
1940 : SPL_METHOD(SplFileObject, fgetcsv)
1941 0 : {
1942 0 : spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
1943 0 : char delimiter = intern->u.file.delimiter, enclosure = intern->u.file.enclosure;
1944 : char *delim, *enclo;
1945 : int d_len, e_len;
1946 :
1947 0 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|ss", &delim, &d_len, &enclo, &e_len) == SUCCESS) {
1948 0 : switch(ZEND_NUM_ARGS())
1949 : {
1950 : case 2:
1951 0 : if (e_len != 1) {
1952 0 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "enclosure must be a character");
1953 0 : RETURN_FALSE;
1954 : }
1955 0 : enclosure = enclo[0];
1956 : /* no break */
1957 : case 1:
1958 0 : if (d_len != 1) {
1959 0 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "delimiter must be a character");
1960 0 : RETURN_FALSE;
1961 : }
1962 0 : delimiter = delim[0];
1963 : /* no break */
1964 : case 0:
1965 : break;
1966 : }
1967 0 : spl_filesystem_file_read_csv(intern, delimiter, enclosure, return_value TSRMLS_CC);
1968 : }
1969 : }
1970 : /* }}} */
1971 :
1972 : /* {{{ proto void SplFileObject::setCsvControl([string delimiter = ',' [, string enclosure = '"']])
1973 : Set the delimiter and enclosure character used in fgetcsv */
1974 : SPL_METHOD(SplFileObject, setCsvControl)
1975 0 : {
1976 0 : spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
1977 0 : char delimiter = ',', enclosure = '"';
1978 : char *delim, *enclo;
1979 : int d_len, e_len;
1980 :
1981 0 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|ss", &delim, &d_len, &enclo, &e_len) == SUCCESS) {
1982 0 : switch(ZEND_NUM_ARGS())
1983 : {
1984 : case 2:
1985 0 : if (e_len != 1) {
1986 0 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "enclosure must be a character");
1987 0 : RETURN_FALSE;
1988 : }
1989 0 : enclosure = enclo[0];
1990 : /* no break */
1991 : case 1:
1992 0 : if (d_len != 1) {
1993 0 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "delimiter must be a character");
1994 0 : RETURN_FALSE;
1995 : }
1996 0 : delimiter = delim[0];
1997 : /* no break */
1998 : case 0:
1999 : break;
2000 : }
2001 0 : intern->u.file.delimiter = delimiter;
2002 0 : intern->u.file.enclosure = enclosure;
2003 : }
2004 : }
2005 : /* }}} */
2006 :
2007 : /* {{{ proto array SplFileObject::getCsvControl()
2008 : Get the delimiter and enclosure character used in fgetcsv */
2009 : SPL_METHOD(SplFileObject, getCsvControl)
2010 0 : {
2011 0 : spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
2012 : char delimiter[2], enclosure[2];
2013 :
2014 0 : array_init(return_value);
2015 :
2016 0 : delimiter[0] = intern->u.file.delimiter;
2017 0 : delimiter[1] = '\0';
2018 0 : enclosure[0] = intern->u.file.enclosure;
2019 0 : enclosure[1] = '\0';
2020 :
2021 0 : add_next_index_string(return_value, delimiter, 1);
2022 0 : add_next_index_string(return_value, enclosure, 1);
2023 0 : }
2024 : /* }}} */
2025 :
2026 : /* {{{ proto bool SplFileObject::flock(int operation [, int &wouldblock])
2027 : Portable file locking */
2028 0 : FileFunction(flock)
2029 : /* }}} */
2030 :
2031 : /* {{{ proto bool SplFileObject::fflush()
2032 : Flush the file */
2033 : SPL_METHOD(SplFileObject, fflush)
2034 0 : {
2035 0 : spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
2036 :
2037 0 : RETURN_BOOL(!php_stream_flush(intern->u.file.stream));
2038 : } /* }}} */
2039 :
2040 :
2041 : /* {{{ proto int SplFileObject::ftell()
2042 : Return current file position */
2043 : SPL_METHOD(SplFileObject, ftell)
2044 0 : {
2045 0 : spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
2046 0 : long ret = php_stream_tell(intern->u.file.stream);
2047 :
2048 0 : if (ret == -1) {
2049 0 : RETURN_FALSE;
2050 : } else {
2051 0 : RETURN_LONG(ret);
2052 : }
2053 : } /* }}} */
2054 :
2055 : /* {{{ proto int SplFileObject::fseek(int pos [, int whence = SEEK_SET])
2056 : Return current file position */
2057 : SPL_METHOD(SplFileObject, fseek)
2058 0 : {
2059 0 : spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
2060 0 : long pos, whence = SEEK_SET;
2061 :
2062 0 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l|l", &pos, &whence) == FAILURE) {
2063 0 : return;
2064 : }
2065 :
2066 0 : spl_filesystem_file_free_line(intern TSRMLS_CC);
2067 0 : RETURN_LONG(php_stream_seek(intern->u.file.stream, pos, whence));
2068 : } /* }}} */
2069 :
2070 : /* {{{ proto int SplFileObject::fgetc()
2071 : Get a character form the file */
2072 : SPL_METHOD(SplFileObject, fgetc)
2073 0 : {
2074 0 : spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
2075 : char buf[2];
2076 : int result;
2077 :
2078 0 : spl_filesystem_file_free_line(intern TSRMLS_CC);
2079 :
2080 0 : result = php_stream_getc(intern->u.file.stream);
2081 :
2082 0 : if (result == EOF) {
2083 0 : RETVAL_FALSE;
2084 : } else {
2085 0 : if (result == '\n') {
2086 0 : intern->u.file.current_line_num++;
2087 : }
2088 0 : buf[0] = result;
2089 0 : buf[1] = '\0';
2090 :
2091 0 : RETURN_STRINGL(buf, 1, 1);
2092 : }
2093 : } /* }}} */
2094 :
2095 : /* {{{ proto string SplFileObject::fgetss([string allowable_tags])
2096 : Get a line from file pointer and strip HTML tags */
2097 : SPL_METHOD(SplFileObject, fgetss)
2098 0 : {
2099 0 : spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
2100 0 : zval *arg2 = NULL;
2101 0 : MAKE_STD_ZVAL(arg2);
2102 0 : ZVAL_LONG(arg2, intern->u.file.max_line_len);
2103 :
2104 0 : spl_filesystem_file_free_line(intern TSRMLS_CC);
2105 0 : intern->u.file.current_line_num++;
2106 :
2107 0 : FileFunctionCall(fgetss, ZEND_NUM_ARGS(), arg2);
2108 :
2109 0 : zval_ptr_dtor(&arg2);
2110 0 : } /* }}} */
2111 :
2112 : /* {{{ proto int SplFileObject::fpassthru()
2113 : Output all remaining data from a file pointer */
2114 : SPL_METHOD(SplFileObject, fpassthru)
2115 0 : {
2116 0 : spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
2117 :
2118 0 : RETURN_LONG(php_stream_passthru(intern->u.file.stream));
2119 : } /* }}} */
2120 :
2121 : /* {{{ proto bool SplFileObject::fscanf(string format [, string ...])
2122 : Implements a mostly ANSI compatible fscanf() */
2123 : SPL_METHOD(SplFileObject, fscanf)
2124 0 : {
2125 0 : spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
2126 :
2127 0 : spl_filesystem_file_free_line(intern TSRMLS_CC);
2128 0 : intern->u.file.current_line_num++;
2129 :
2130 0 : FileFunctionCall(fscanf, ZEND_NUM_ARGS(), NULL);
2131 0 : }
2132 : /* }}} */
2133 :
2134 : /* {{{ proto mixed SplFileObject::fwrite(string str [, int length])
2135 : Binary-safe file write */
2136 : SPL_METHOD(SplFileObject, fwrite)
2137 0 : {
2138 0 : spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
2139 : char *str;
2140 : int str_len;
2141 : int ret;
2142 0 : long length = 0;
2143 :
2144 0 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &str, &str_len, &length) == FAILURE) {
2145 0 : return;
2146 : }
2147 :
2148 0 : if (ZEND_NUM_ARGS() > 1) {
2149 0 : str_len = MAX(0, MIN(length, str_len));
2150 : }
2151 0 : if (!str_len) {
2152 0 : RETURN_LONG(0);
2153 : }
2154 :
2155 0 : if (PG(magic_quotes_runtime)) {
2156 0 : str = estrndup(str, str_len);
2157 0 : php_stripslashes(str, &str_len TSRMLS_CC);
2158 0 : ret = php_stream_write(intern->u.file.stream, str, str_len);
2159 0 : efree(str);
2160 0 : RETURN_LONG(ret);
2161 : }
2162 :
2163 0 : RETURN_LONG(php_stream_write(intern->u.file.stream, str, str_len));
2164 : } /* }}} */
2165 :
2166 : /* {{{ proto bool SplFileObject::fstat()
2167 : Stat() on a filehandle */
2168 0 : FileFunction(fstat)
2169 : /* }}} */
2170 :
2171 : /* {{{ proto bool SplFileObject::ftruncate(int size)
2172 : Truncate file to 'size' length */
2173 : SPL_METHOD(SplFileObject, ftruncate)
2174 0 : {
2175 0 : spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
2176 : long size;
2177 :
2178 0 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &size) == FAILURE) {
2179 0 : return;
2180 : }
2181 :
2182 0 : if (!php_stream_truncate_supported(intern->u.file.stream)) {
2183 0 : zend_throw_exception_ex(spl_ce_LogicException, 0 TSRMLS_CC, "Can't truncate file %s", intern->file_name);
2184 0 : RETURN_FALSE;
2185 : }
2186 :
2187 0 : RETURN_BOOL(0 == php_stream_truncate_set_size(intern->u.file.stream, size));
2188 : } /* }}} */
2189 :
2190 : /* {{{ proto void SplFileObject::seek(int line_pos)
2191 : Seek to specified line */
2192 : SPL_METHOD(SplFileObject, seek)
2193 0 : {
2194 0 : spl_filesystem_object *intern = (spl_filesystem_object*)zend_object_store_get_object(getThis() TSRMLS_CC);
2195 : long line_pos;
2196 :
2197 0 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &line_pos) == FAILURE) {
2198 0 : return;
2199 : }
2200 0 : if (line_pos < 0) {
2201 0 : zend_throw_exception_ex(spl_ce_LogicException, 0 TSRMLS_CC, "Can't seek file %s to negative line %ld", intern->file_name, line_pos);
2202 0 : RETURN_FALSE;
2203 : }
2204 :
2205 0 : spl_filesystem_file_rewind(getThis(), intern TSRMLS_CC);
2206 :
2207 0 : while(intern->u.file.current_line_num < line_pos) {
2208 0 : spl_filesystem_file_read_line(getThis(), intern, 1 TSRMLS_CC);
2209 : }
2210 : } /* }}} */
2211 :
2212 : /* {{{ Function/Class/Method definitions */
2213 : static
2214 : ZEND_BEGIN_ARG_INFO_EX(arginfo_file_object___construct, 0, 0, 1)
2215 : ZEND_ARG_INFO(0, file_name)
2216 : ZEND_ARG_INFO(0, open_mode)
2217 : ZEND_ARG_INFO(0, use_include_path)
2218 : ZEND_ARG_INFO(0, context)
2219 : ZEND_END_ARG_INFO()
2220 :
2221 : static
2222 : ZEND_BEGIN_ARG_INFO(arginfo_file_object_setFlags, 0)
2223 : ZEND_ARG_INFO(0, flags)
2224 : ZEND_END_ARG_INFO()
2225 :
2226 : static
2227 : ZEND_BEGIN_ARG_INFO(arginfo_file_object_setMaxLineLen, 0)
2228 : ZEND_ARG_INFO(0, max_len)
2229 : ZEND_END_ARG_INFO()
2230 :
2231 : static
2232 : ZEND_BEGIN_ARG_INFO_EX(arginfo_file_object_fgetcsv, 0, 0, 0)
2233 : ZEND_ARG_INFO(0, delimiter)
2234 : ZEND_ARG_INFO(0, enclosure)
2235 : ZEND_END_ARG_INFO()
2236 :
2237 : static
2238 : ZEND_BEGIN_ARG_INFO_EX(arginfo_file_object_flock, 0, 0, 1)
2239 : ZEND_ARG_INFO(0, operation)
2240 : ZEND_ARG_INFO(1, wouldblock)
2241 : ZEND_END_ARG_INFO()
2242 :
2243 : static
2244 : ZEND_BEGIN_ARG_INFO_EX(arginfo_file_object_fseek, 0, 0, 1)
2245 : ZEND_ARG_INFO(0, pos)
2246 : ZEND_ARG_INFO(0, whence)
2247 : ZEND_END_ARG_INFO()
2248 :
2249 : static
2250 : ZEND_BEGIN_ARG_INFO_EX(arginfo_file_object_fgetss, 0, 0, 0)
2251 : ZEND_ARG_INFO(0, allowable_tags)
2252 : ZEND_END_ARG_INFO()
2253 :
2254 : static
2255 : ZEND_BEGIN_ARG_INFO_EX(arginfo_file_object_fscanf, 0, 0, 1)
2256 : ZEND_ARG_INFO(0, format)
2257 : ZEND_END_ARG_INFO()
2258 :
2259 : static
2260 : ZEND_BEGIN_ARG_INFO_EX(arginfo_file_object_fwrite, 0, 0, 1)
2261 : ZEND_ARG_INFO(0, str)
2262 : ZEND_ARG_INFO(0, length)
2263 : ZEND_END_ARG_INFO()
2264 :
2265 : static
2266 : ZEND_BEGIN_ARG_INFO_EX(arginfo_file_object_ftruncate, 0, 0, 1)
2267 : ZEND_ARG_INFO(0, size)
2268 : ZEND_END_ARG_INFO()
2269 :
2270 : static
2271 : ZEND_BEGIN_ARG_INFO_EX(arginfo_file_object_seek, 0, 0, 1)
2272 : ZEND_ARG_INFO(0, line_pos)
2273 : ZEND_END_ARG_INFO()
2274 :
2275 : static zend_function_entry spl_SplFileObject_functions[] = {
2276 : SPL_ME(SplFileObject, __construct, arginfo_file_object___construct, ZEND_ACC_PUBLIC)
2277 : SPL_ME(SplFileObject, rewind, NULL, ZEND_ACC_PUBLIC)
2278 : SPL_ME(SplFileObject, eof, NULL, ZEND_ACC_PUBLIC)
2279 : SPL_ME(SplFileObject, valid, NULL, ZEND_ACC_PUBLIC)
2280 : SPL_ME(SplFileObject, fgets, NULL, ZEND_ACC_PUBLIC)
2281 : SPL_ME(SplFileObject, fgetcsv, arginfo_file_object_fgetcsv, ZEND_ACC_PUBLIC)
2282 : SPL_ME(SplFileObject, setCsvControl, arginfo_file_object_fgetcsv, ZEND_ACC_PUBLIC)
2283 : SPL_ME(SplFileObject, getCsvControl, NULL, ZEND_ACC_PUBLIC)
2284 : SPL_ME(SplFileObject, flock, arginfo_file_object_flock, ZEND_ACC_PUBLIC)
2285 : SPL_ME(SplFileObject, fflush, NULL, ZEND_ACC_PUBLIC)
2286 : SPL_ME(SplFileObject, ftell, NULL, ZEND_ACC_PUBLIC)
2287 : SPL_ME(SplFileObject, fseek, arginfo_file_object_fseek, ZEND_ACC_PUBLIC)
2288 : SPL_ME(SplFileObject, fgetc, NULL, ZEND_ACC_PUBLIC)
2289 : SPL_ME(SplFileObject, fpassthru, NULL, ZEND_ACC_PUBLIC)
2290 : SPL_ME(SplFileObject, fgetss, arginfo_file_object_fgetss, ZEND_ACC_PUBLIC)
2291 : SPL_ME(SplFileObject, fscanf, arginfo_file_object_fscanf, ZEND_ACC_PUBLIC)
2292 : SPL_ME(SplFileObject, fwrite, arginfo_file_object_fwrite, ZEND_ACC_PUBLIC)
2293 : SPL_ME(SplFileObject, fstat, NULL, ZEND_ACC_PUBLIC)
2294 : SPL_ME(SplFileObject, ftruncate, arginfo_file_object_ftruncate, ZEND_ACC_PUBLIC)
2295 : SPL_ME(SplFileObject, current, NULL, ZEND_ACC_PUBLIC)
2296 : SPL_ME(SplFileObject, key, NULL, ZEND_ACC_PUBLIC)
2297 : SPL_ME(SplFileObject, next, NULL, ZEND_ACC_PUBLIC)
2298 : SPL_ME(SplFileObject, setFlags, arginfo_file_object_setFlags, ZEND_ACC_PUBLIC)
2299 : SPL_ME(SplFileObject, getFlags, NULL, ZEND_ACC_PUBLIC)
2300 : SPL_ME(SplFileObject, setMaxLineLen, arginfo_file_object_setMaxLineLen, ZEND_ACC_PUBLIC)
2301 : SPL_ME(SplFileObject, getMaxLineLen, NULL, ZEND_ACC_PUBLIC)
2302 : SPL_ME(SplFileObject, hasChildren, NULL, ZEND_ACC_PUBLIC)
2303 : SPL_ME(SplFileObject, getChildren, NULL, ZEND_ACC_PUBLIC)
2304 : SPL_ME(SplFileObject, seek, arginfo_file_object_seek, ZEND_ACC_PUBLIC)
2305 : /* mappings */
2306 : SPL_MA(SplFileObject, getCurrentLine, SplFileObject, fgets, NULL, ZEND_ACC_PUBLIC)
2307 : SPL_MA(SplFileObject, __toString, SplFileObject, current, NULL, ZEND_ACC_PUBLIC)
2308 : {NULL, NULL, NULL}
2309 : };
2310 :
2311 : static
2312 : ZEND_BEGIN_ARG_INFO_EX(arginfo_temp_file_object___construct, 0, 0, 0)
2313 : ZEND_ARG_INFO(0, max_memory)
2314 : ZEND_END_ARG_INFO()
2315 :
2316 : static zend_function_entry spl_SplTempFileObject_functions[] = {
2317 : SPL_ME(SplTempFileObject, __construct, arginfo_temp_file_object___construct, ZEND_ACC_PUBLIC)
2318 : {NULL, NULL, NULL}
2319 : };
2320 : /* }}} */
2321 :
2322 : /* {{{ PHP_MINIT_FUNCTION(spl_directory)
2323 : */
2324 : PHP_MINIT_FUNCTION(spl_directory)
2325 220 : {
2326 220 : REGISTER_SPL_STD_CLASS_EX(SplFileInfo, spl_filesystem_object_new, spl_SplFileInfo_functions);
2327 220 : memcpy(&spl_filesystem_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
2328 220 : spl_filesystem_object_handlers.clone_obj = spl_filesystem_object_clone;
2329 220 : spl_filesystem_object_handlers.cast_object = spl_filesystem_object_cast;
2330 :
2331 220 : REGISTER_SPL_SUB_CLASS_EX(DirectoryIterator, SplFileInfo, spl_filesystem_object_new, spl_DirectoryIterator_functions);
2332 220 : zend_class_implements(spl_ce_DirectoryIterator TSRMLS_CC, 1, zend_ce_iterator);
2333 :
2334 220 : spl_ce_DirectoryIterator->get_iterator = spl_filesystem_dir_get_iterator;
2335 :
2336 220 : REGISTER_SPL_SUB_CLASS_EX(RecursiveDirectoryIterator, DirectoryIterator, spl_filesystem_object_new, spl_RecursiveDirectoryIterator_functions);
2337 220 : REGISTER_SPL_IMPLEMENTS(RecursiveDirectoryIterator, RecursiveIterator);
2338 :
2339 220 : REGISTER_SPL_CLASS_CONST_LONG(RecursiveDirectoryIterator, "CURRENT_MODE_MASK", SPL_FILE_DIR_CURRENT_MODE_MASK);
2340 220 : REGISTER_SPL_CLASS_CONST_LONG(RecursiveDirectoryIterator, "CURRENT_AS_PATHNAME", SPL_FILE_DIR_CURRENT_AS_PATHNAME);
2341 220 : REGISTER_SPL_CLASS_CONST_LONG(RecursiveDirectoryIterator, "CURRENT_AS_FILEINFO", SPL_FILE_DIR_CURRENT_AS_FILEINFO);
2342 220 : REGISTER_SPL_CLASS_CONST_LONG(RecursiveDirectoryIterator, "CURRENT_AS_SELF", 0);
2343 220 : REGISTER_SPL_CLASS_CONST_LONG(RecursiveDirectoryIterator, "KEY_MODE_MASK", SPL_FILE_DIR_KEY_MODE_MASK);
2344 220 : REGISTER_SPL_CLASS_CONST_LONG(RecursiveDirectoryIterator, "KEY_AS_PATHNAME", 0);
2345 220 : REGISTER_SPL_CLASS_CONST_LONG(RecursiveDirectoryIterator, "KEY_AS_FILENAME", SPL_FILE_DIR_KEY_AS_FILENAME);
2346 220 : REGISTER_SPL_CLASS_CONST_LONG(RecursiveDirectoryIterator, "NEW_CURRENT_AND_KEY", SPL_FILE_DIR_KEY_AS_FILENAME|SPL_FILE_DIR_CURRENT_AS_FILEINFO);
2347 :
2348 220 : spl_ce_RecursiveDirectoryIterator->get_iterator = spl_filesystem_tree_get_iterator;
2349 :
2350 220 : REGISTER_SPL_SUB_CLASS_EX(SplFileObject, SplFileInfo, spl_filesystem_object_new, spl_SplFileObject_functions);
2351 220 : REGISTER_SPL_IMPLEMENTS(SplFileObject, RecursiveIterator);
2352 220 : REGISTER_SPL_IMPLEMENTS(SplFileObject, SeekableIterator);
2353 :
2354 220 : REGISTER_SPL_CLASS_CONST_LONG(SplFileObject, "DROP_NEW_LINE", SPL_FILE_OBJECT_DROP_NEW_LINE);
2355 220 : REGISTER_SPL_CLASS_CONST_LONG(SplFileObject, "READ_AHEAD", SPL_FILE_OBJECT_READ_AHEAD);
2356 220 : REGISTER_SPL_CLASS_CONST_LONG(SplFileObject, "SKIP_EMPTY", SPL_FILE_OBJECT_SKIP_EMPTY);
2357 220 : REGISTER_SPL_CLASS_CONST_LONG(SplFileObject, "READ_CSV", SPL_FILE_OBJECT_READ_CSV);
2358 :
2359 220 : REGISTER_SPL_SUB_CLASS_EX(SplTempFileObject, SplFileObject, spl_filesystem_object_new, spl_SplTempFileObject_functions);
2360 220 : return SUCCESS;
2361 : }
2362 : /* }}} */
2363 :
2364 :
2365 : /*
2366 : * Local variables:
2367 : * tab-width: 4
2368 : * c-basic-offset: 4
2369 : * End:
2370 : * vim600: noet sw=4 ts=4 fdm=marker
2371 : * vim<600: noet sw=4 ts=4
2372 : */
|