Annotation of embedaddon/php/main/streams/glob_wrapper.c, revision 1.1
1.1 ! misho 1: /*
! 2: +----------------------------------------------------------------------+
! 3: | PHP Version 5 |
! 4: +----------------------------------------------------------------------+
! 5: | Copyright (c) 1997-2012 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: | Authors: Marcus Boerger <helly@php.net> |
! 16: +----------------------------------------------------------------------+
! 17: */
! 18:
! 19: /* $Id: glob_wrapper.c 321634 2012-01-01 13:15:04Z felipe $ */
! 20:
! 21: #include "php.h"
! 22: #include "php_streams_int.h"
! 23:
! 24: #ifdef HAVE_GLOB
! 25: # ifndef PHP_WIN32
! 26: # include <glob.h>
! 27: # else
! 28: # include "win32/glob.h"
! 29: # endif
! 30: #endif
! 31:
! 32: #ifdef HAVE_GLOB
! 33: #ifndef GLOB_ONLYDIR
! 34: #define GLOB_ONLYDIR (1<<30)
! 35: #define GLOB_FLAGMASK (~GLOB_ONLYDIR)
! 36: #else
! 37: #define GLOB_FLAGMASK (~0)
! 38: #endif
! 39:
! 40: typedef struct {
! 41: glob_t glob;
! 42: size_t index;
! 43: int flags;
! 44: char *path;
! 45: size_t path_len;
! 46: char *pattern;
! 47: size_t pattern_len;
! 48: } glob_s_t;
! 49:
! 50: PHPAPI char* _php_glob_stream_get_path(php_stream *stream, int copy, int *plen STREAMS_DC TSRMLS_DC) /* {{{ */
! 51: {
! 52: glob_s_t *pglob = (glob_s_t *)stream->abstract;
! 53:
! 54: if (pglob && pglob->path) {
! 55: if (plen) {
! 56: *plen = pglob->path_len;
! 57: }
! 58: if (copy) {
! 59: return estrndup(pglob->path, pglob->path_len);
! 60: } else {
! 61: return pglob->path;
! 62: }
! 63: } else {
! 64: if (plen) {
! 65: *plen = 0;
! 66: }
! 67: return NULL;
! 68: }
! 69: }
! 70: /* }}} */
! 71:
! 72: PHPAPI char* _php_glob_stream_get_pattern(php_stream *stream, int copy, int *plen STREAMS_DC TSRMLS_DC) /* {{{ */
! 73: {
! 74: glob_s_t *pglob = (glob_s_t *)stream->abstract;
! 75:
! 76: if (pglob && pglob->pattern) {
! 77: if (plen) {
! 78: *plen = pglob->pattern_len;
! 79: }
! 80: if (copy) {
! 81: return estrndup(pglob->pattern, pglob->pattern_len);
! 82: } else {
! 83: return pglob->pattern;
! 84: }
! 85: } else {
! 86: if (plen) {
! 87: *plen = 0;
! 88: }
! 89: return NULL;
! 90: }
! 91: }
! 92: /* }}} */
! 93:
! 94: PHPAPI int _php_glob_stream_get_count(php_stream *stream, int *pflags STREAMS_DC TSRMLS_DC) /* {{{ */
! 95: {
! 96: glob_s_t *pglob = (glob_s_t *)stream->abstract;
! 97:
! 98: if (pglob) {
! 99: if (pflags) {
! 100: *pflags = pglob->flags;
! 101: }
! 102: return pglob->glob.gl_pathc;
! 103: } else {
! 104: if (pflags) {
! 105: *pflags = 0;
! 106: }
! 107: return 0;
! 108: }
! 109: }
! 110: /* }}} */
! 111:
! 112: static void php_glob_stream_path_split(glob_s_t *pglob, char *path, int get_path, char **p_file TSRMLS_DC) /* {{{ */
! 113: {
! 114: char *pos, *gpath = path;
! 115:
! 116: if ((pos = strrchr(path, '/')) != NULL) {
! 117: path = pos+1;
! 118: }
! 119: #if defined(PHP_WIN32) || defined(NETWARE)
! 120: if ((pos = strrchr(path, '\\')) != NULL) {
! 121: path = pos+1;
! 122: }
! 123: #endif
! 124:
! 125: *p_file = path;
! 126:
! 127: if (get_path) {
! 128: if (pglob->path) {
! 129: efree(pglob->path);
! 130: }
! 131: if (path != gpath) {
! 132: path--;
! 133: }
! 134: pglob->path_len = path - gpath;
! 135: pglob->path = estrndup(gpath, pglob->path_len);
! 136: }
! 137: }
! 138: /* }}} */
! 139:
! 140: static size_t php_glob_stream_read(php_stream *stream, char *buf, size_t count TSRMLS_DC) /* {{{ */
! 141: {
! 142: glob_s_t *pglob = (glob_s_t *)stream->abstract;
! 143: php_stream_dirent *ent = (php_stream_dirent*)buf;
! 144: char *path;
! 145:
! 146: /* avoid problems if someone mis-uses the stream */
! 147: if (count == sizeof(php_stream_dirent) && pglob) {
! 148: if (pglob->index < pglob->glob.gl_pathc) {
! 149: php_glob_stream_path_split(pglob, pglob->glob.gl_pathv[pglob->index++], pglob->flags & GLOB_APPEND, &path TSRMLS_CC);
! 150: PHP_STRLCPY(ent->d_name, path, sizeof(ent->d_name), strlen(path));
! 151: return sizeof(php_stream_dirent);
! 152: }
! 153: pglob->index = pglob->glob.gl_pathc;
! 154: if (pglob->path) {
! 155: efree(pglob->path);
! 156: pglob->path = NULL;
! 157: }
! 158: }
! 159:
! 160: return 0;
! 161: }
! 162: /* }}} */
! 163:
! 164: static int php_glob_stream_close(php_stream *stream, int close_handle TSRMLS_DC) /* {{{ */
! 165: {
! 166: glob_s_t *pglob = (glob_s_t *)stream->abstract;
! 167:
! 168: if (pglob) {
! 169: pglob->index = 0;
! 170: globfree(&pglob->glob);
! 171: if (pglob->path) {
! 172: efree(pglob->path);
! 173: }
! 174: if (pglob->pattern) {
! 175: efree(pglob->pattern);
! 176: }
! 177: }
! 178: efree(stream->abstract);
! 179: return 0;
! 180: }
! 181: /* {{{ */
! 182:
! 183: static int php_glob_stream_rewind(php_stream *stream, off_t offset, int whence, off_t *newoffs TSRMLS_DC) /* {{{ */
! 184: {
! 185: glob_s_t *pglob = (glob_s_t *)stream->abstract;
! 186:
! 187: if (pglob) {
! 188: pglob->index = 0;
! 189: if (pglob->path) {
! 190: efree(pglob->path);
! 191: pglob->path = NULL;
! 192: }
! 193: }
! 194: return 0;
! 195: }
! 196: /* }}} */
! 197:
! 198: php_stream_ops php_glob_stream_ops = {
! 199: NULL, php_glob_stream_read,
! 200: php_glob_stream_close, NULL,
! 201: "glob",
! 202: php_glob_stream_rewind,
! 203: NULL, /* cast */
! 204: NULL, /* stat */
! 205: NULL /* set_option */
! 206: };
! 207:
! 208: /* {{{ php_glob_stream_opener */
! 209: static php_stream *php_glob_stream_opener(php_stream_wrapper *wrapper, char *path, char *mode,
! 210: int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC)
! 211: {
! 212: glob_s_t *pglob;
! 213: int ret;
! 214: char *tmp, *pos;
! 215:
! 216: if (((options & STREAM_DISABLE_OPEN_BASEDIR) == 0) && php_check_open_basedir(path TSRMLS_CC)) {
! 217: return NULL;
! 218: }
! 219:
! 220: if (!strncmp(path, "glob://", sizeof("glob://")-1)) {
! 221: path += sizeof("glob://")-1;
! 222: if (opened_path) {
! 223: *opened_path = estrdup(path);
! 224: }
! 225: }
! 226:
! 227: pglob = ecalloc(sizeof(*pglob), 1);
! 228:
! 229: if (0 != (ret = glob(path, pglob->flags & GLOB_FLAGMASK, NULL, &pglob->glob))) {
! 230: #ifdef GLOB_NOMATCH
! 231: if (GLOB_NOMATCH != ret)
! 232: #endif
! 233: {
! 234: efree(pglob);
! 235: return NULL;
! 236: }
! 237: }
! 238:
! 239: pos = path;
! 240: if ((tmp = strrchr(pos, '/')) != NULL) {
! 241: pos = tmp+1;
! 242: }
! 243: #if defined(PHP_WIN32) || defined(NETWARE)
! 244: if ((tmp = strrchr(pos, '\\')) != NULL) {
! 245: pos = tmp+1;
! 246: }
! 247: #endif
! 248:
! 249: pglob->pattern_len = strlen(pos);
! 250: pglob->pattern = estrndup(pos, pglob->pattern_len);
! 251:
! 252: pglob->flags |= GLOB_APPEND;
! 253:
! 254: if (pglob->glob.gl_pathc) {
! 255: php_glob_stream_path_split(pglob, pglob->glob.gl_pathv[0], 1, &tmp TSRMLS_CC);
! 256: } else {
! 257: php_glob_stream_path_split(pglob, path, 1, &tmp TSRMLS_CC);
! 258: }
! 259:
! 260: return php_stream_alloc(&php_glob_stream_ops, pglob, 0, mode);
! 261: }
! 262: /* }}} */
! 263:
! 264: static php_stream_wrapper_ops php_glob_stream_wrapper_ops = {
! 265: NULL,
! 266: NULL,
! 267: NULL,
! 268: NULL,
! 269: php_glob_stream_opener,
! 270: "glob",
! 271: NULL,
! 272: NULL,
! 273: NULL,
! 274: NULL
! 275: };
! 276:
! 277: php_stream_wrapper php_glob_stream_wrapper = {
! 278: &php_glob_stream_wrapper_ops,
! 279: NULL,
! 280: 0
! 281: };
! 282: #endif /* HAVE_GLOB */
! 283:
! 284: /*
! 285: * Local variables:
! 286: * tab-width: 4
! 287: * c-basic-offset: 4
! 288: * End:
! 289: * vim600: noet sw=4 ts=4 fdm=marker
! 290: * vim<600: noet sw=4 ts=4
! 291: */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>