diff options
author | Lorry Tar Creator <lorry-tar-importer@baserock.org> | 2013-03-14 05:42:27 +0000 |
---|---|---|
committer | <> | 2013-04-03 16:25:08 +0000 |
commit | c4dd7a1a684490673e25aaf4fabec5df138854c4 (patch) | |
tree | 4d57c44caae4480efff02b90b9be86f44bf25409 /main/streams/glob_wrapper.c | |
download | php2-master.tar.gz |
Imported from /home/lorry/working-area/delta_php2/php-5.4.13.tar.bz2.HEADphp-5.4.13master
Diffstat (limited to 'main/streams/glob_wrapper.c')
-rw-r--r-- | main/streams/glob_wrapper.c | 291 |
1 files changed, 291 insertions, 0 deletions
diff --git a/main/streams/glob_wrapper.c b/main/streams/glob_wrapper.c new file mode 100644 index 0000000..9c051a5 --- /dev/null +++ b/main/streams/glob_wrapper.c @@ -0,0 +1,291 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2013 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Authors: Marcus Boerger <helly@php.net> | + +----------------------------------------------------------------------+ + */ + +/* $Id$ */ + +#include "php.h" +#include "php_streams_int.h" + +#ifdef HAVE_GLOB +# ifndef PHP_WIN32 +# include <glob.h> +# else +# include "win32/glob.h" +# endif +#endif + +#ifdef HAVE_GLOB +#ifndef GLOB_ONLYDIR +#define GLOB_ONLYDIR (1<<30) +#define GLOB_FLAGMASK (~GLOB_ONLYDIR) +#else +#define GLOB_FLAGMASK (~0) +#endif + +typedef struct { + glob_t glob; + size_t index; + int flags; + char *path; + size_t path_len; + char *pattern; + size_t pattern_len; +} glob_s_t; + +PHPAPI char* _php_glob_stream_get_path(php_stream *stream, int copy, int *plen STREAMS_DC TSRMLS_DC) /* {{{ */ +{ + glob_s_t *pglob = (glob_s_t *)stream->abstract; + + if (pglob && pglob->path) { + if (plen) { + *plen = pglob->path_len; + } + if (copy) { + return estrndup(pglob->path, pglob->path_len); + } else { + return pglob->path; + } + } else { + if (plen) { + *plen = 0; + } + return NULL; + } +} +/* }}} */ + +PHPAPI char* _php_glob_stream_get_pattern(php_stream *stream, int copy, int *plen STREAMS_DC TSRMLS_DC) /* {{{ */ +{ + glob_s_t *pglob = (glob_s_t *)stream->abstract; + + if (pglob && pglob->pattern) { + if (plen) { + *plen = pglob->pattern_len; + } + if (copy) { + return estrndup(pglob->pattern, pglob->pattern_len); + } else { + return pglob->pattern; + } + } else { + if (plen) { + *plen = 0; + } + return NULL; + } +} +/* }}} */ + +PHPAPI int _php_glob_stream_get_count(php_stream *stream, int *pflags STREAMS_DC TSRMLS_DC) /* {{{ */ +{ + glob_s_t *pglob = (glob_s_t *)stream->abstract; + + if (pglob) { + if (pflags) { + *pflags = pglob->flags; + } + return pglob->glob.gl_pathc; + } else { + if (pflags) { + *pflags = 0; + } + return 0; + } +} +/* }}} */ + +static void php_glob_stream_path_split(glob_s_t *pglob, char *path, int get_path, char **p_file TSRMLS_DC) /* {{{ */ +{ + char *pos, *gpath = path; + + if ((pos = strrchr(path, '/')) != NULL) { + path = pos+1; + } +#if defined(PHP_WIN32) || defined(NETWARE) + if ((pos = strrchr(path, '\\')) != NULL) { + path = pos+1; + } +#endif + + *p_file = path; + + if (get_path) { + if (pglob->path) { + efree(pglob->path); + } + if (path != gpath) { + path--; + } + pglob->path_len = path - gpath; + pglob->path = estrndup(gpath, pglob->path_len); + } +} +/* }}} */ + +static size_t php_glob_stream_read(php_stream *stream, char *buf, size_t count TSRMLS_DC) /* {{{ */ +{ + glob_s_t *pglob = (glob_s_t *)stream->abstract; + php_stream_dirent *ent = (php_stream_dirent*)buf; + char *path; + + /* avoid problems if someone mis-uses the stream */ + if (count == sizeof(php_stream_dirent) && pglob) { + if (pglob->index < (size_t)pglob->glob.gl_pathc) { + php_glob_stream_path_split(pglob, pglob->glob.gl_pathv[pglob->index++], pglob->flags & GLOB_APPEND, &path TSRMLS_CC); + PHP_STRLCPY(ent->d_name, path, sizeof(ent->d_name), strlen(path)); + return sizeof(php_stream_dirent); + } + pglob->index = pglob->glob.gl_pathc; + if (pglob->path) { + efree(pglob->path); + pglob->path = NULL; + } + } + + return 0; +} +/* }}} */ + +static int php_glob_stream_close(php_stream *stream, int close_handle TSRMLS_DC) /* {{{ */ +{ + glob_s_t *pglob = (glob_s_t *)stream->abstract; + + if (pglob) { + pglob->index = 0; + globfree(&pglob->glob); + if (pglob->path) { + efree(pglob->path); + } + if (pglob->pattern) { + efree(pglob->pattern); + } + } + efree(stream->abstract); + return 0; +} +/* {{{ */ + +static int php_glob_stream_rewind(php_stream *stream, off_t offset, int whence, off_t *newoffs TSRMLS_DC) /* {{{ */ +{ + glob_s_t *pglob = (glob_s_t *)stream->abstract; + + if (pglob) { + pglob->index = 0; + if (pglob->path) { + efree(pglob->path); + pglob->path = NULL; + } + } + return 0; +} +/* }}} */ + +php_stream_ops php_glob_stream_ops = { + NULL, php_glob_stream_read, + php_glob_stream_close, NULL, + "glob", + php_glob_stream_rewind, + NULL, /* cast */ + NULL, /* stat */ + NULL /* set_option */ +}; + + /* {{{ php_glob_stream_opener */ +static php_stream *php_glob_stream_opener(php_stream_wrapper *wrapper, char *path, char *mode, + int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC) +{ + glob_s_t *pglob; + int ret; + char *tmp, *pos; + + if (((options & STREAM_DISABLE_OPEN_BASEDIR) == 0) && php_check_open_basedir(path TSRMLS_CC)) { + return NULL; + } + + if (!strncmp(path, "glob://", sizeof("glob://")-1)) { + path += sizeof("glob://")-1; + if (opened_path) { + *opened_path = estrdup(path); + } + } + + pglob = ecalloc(sizeof(*pglob), 1); + + if (0 != (ret = glob(path, pglob->flags & GLOB_FLAGMASK, NULL, &pglob->glob))) { +#ifdef GLOB_NOMATCH + if (GLOB_NOMATCH != ret) +#endif + { + efree(pglob); + return NULL; + } + } + + pos = path; + if ((tmp = strrchr(pos, '/')) != NULL) { + pos = tmp+1; + } +#if defined(PHP_WIN32) || defined(NETWARE) + if ((tmp = strrchr(pos, '\\')) != NULL) { + pos = tmp+1; + } +#endif + + pglob->pattern_len = strlen(pos); + pglob->pattern = estrndup(pos, pglob->pattern_len); + + pglob->flags |= GLOB_APPEND; + + if (pglob->glob.gl_pathc) { + php_glob_stream_path_split(pglob, pglob->glob.gl_pathv[0], 1, &tmp TSRMLS_CC); + } else { + php_glob_stream_path_split(pglob, path, 1, &tmp TSRMLS_CC); + } + + return php_stream_alloc(&php_glob_stream_ops, pglob, 0, mode); +} +/* }}} */ + +static php_stream_wrapper_ops php_glob_stream_wrapper_ops = { + NULL, + NULL, + NULL, + NULL, + php_glob_stream_opener, + "glob", + NULL, + NULL, + NULL, + NULL +}; + +php_stream_wrapper php_glob_stream_wrapper = { + &php_glob_stream_wrapper_ops, + NULL, + 0 +}; +#endif /* HAVE_GLOB */ + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: noet sw=4 ts=4 fdm=marker + * vim<600: noet sw=4 ts=4 + */ |