Return to glob_wrapper.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / php / main / streams |
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: */