Annotation of embedaddon/php/main/streams/glob_wrapper.c, revision 1.1.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>