Back to index

php5  5.3.10
glob_wrapper.c
Go to the documentation of this file.
00001 /*
00002    +----------------------------------------------------------------------+
00003    | PHP Version 5                                                        |
00004    +----------------------------------------------------------------------+
00005    | Copyright (c) 1997-2012 The PHP Group                                |
00006    +----------------------------------------------------------------------+
00007    | This source file is subject to version 3.01 of the PHP license,      |
00008    | that is bundled with this package in the file LICENSE, and is        |
00009    | available through the world-wide-web at the following url:           |
00010    | http://www.php.net/license/3_01.txt                                  |
00011    | If you did not receive a copy of the PHP license and are unable to   |
00012    | obtain it through the world-wide-web, please send a note to          |
00013    | license@php.net so we can mail you a copy immediately.               |
00014    +----------------------------------------------------------------------+
00015    | Authors: Marcus Boerger <helly@php.net>                              |
00016    +----------------------------------------------------------------------+
00017  */
00018 
00019 /* $Id: glob_wrapper.c 321634 2012-01-01 13:15:04Z felipe $ */
00020 
00021 #include "php.h"
00022 #include "php_streams_int.h"
00023 
00024 #ifdef HAVE_GLOB
00025 # ifndef PHP_WIN32
00026 #  include <glob.h>
00027 # else
00028 #  include "win32/glob.h"
00029 # endif
00030 #endif
00031 
00032 #ifdef HAVE_GLOB
00033 #ifndef GLOB_ONLYDIR
00034 #define GLOB_ONLYDIR (1<<30)
00035 #define GLOB_FLAGMASK (~GLOB_ONLYDIR)
00036 #else
00037 #define GLOB_FLAGMASK (~0)
00038 #endif
00039 
00040 typedef struct {
00041        glob_t   glob;
00042        size_t   index;
00043        int      flags;
00044        char     *path;
00045        size_t   path_len;
00046        char     *pattern;
00047        size_t   pattern_len;
00048 } glob_s_t;
00049 
00050 PHPAPI char* _php_glob_stream_get_path(php_stream *stream, int copy, int *plen STREAMS_DC TSRMLS_DC) /* {{{ */
00051 {
00052        glob_s_t *pglob = (glob_s_t *)stream->abstract;
00053 
00054        if (pglob && pglob->path) {
00055               if (plen) {
00056                      *plen = pglob->path_len;
00057               }
00058               if (copy) {
00059                      return estrndup(pglob->path, pglob->path_len);
00060               } else {
00061                      return pglob->path;
00062               }
00063        } else {
00064               if (plen) {
00065                      *plen = 0;
00066               }
00067               return NULL;
00068        }
00069 }
00070 /* }}} */
00071 
00072 PHPAPI char* _php_glob_stream_get_pattern(php_stream *stream, int copy, int *plen STREAMS_DC TSRMLS_DC) /* {{{ */
00073 {
00074        glob_s_t *pglob = (glob_s_t *)stream->abstract;
00075        
00076        if (pglob && pglob->pattern) {
00077               if (plen) {
00078                      *plen = pglob->pattern_len;
00079               }
00080               if (copy) {
00081                      return estrndup(pglob->pattern, pglob->pattern_len);
00082               } else {
00083                      return pglob->pattern;
00084               }
00085        } else {
00086               if (plen) {
00087                      *plen = 0;
00088               }
00089               return NULL;
00090        }
00091 }
00092 /* }}} */
00093 
00094 PHPAPI int _php_glob_stream_get_count(php_stream *stream, int *pflags STREAMS_DC TSRMLS_DC) /* {{{ */
00095 {
00096        glob_s_t *pglob = (glob_s_t *)stream->abstract;
00097 
00098        if (pglob) {
00099               if (pflags) {
00100                      *pflags = pglob->flags;
00101               }
00102               return pglob->glob.gl_pathc;
00103        } else {
00104               if (pflags) {
00105                      *pflags = 0;
00106               }
00107               return 0;
00108        }
00109 }
00110 /* }}} */
00111 
00112 static void php_glob_stream_path_split(glob_s_t *pglob, char *path, int get_path, char **p_file TSRMLS_DC) /* {{{ */
00113 {
00114        char *pos, *gpath = path;
00115 
00116        if ((pos = strrchr(path, '/')) != NULL) {
00117               path = pos+1;
00118        }
00119 #if defined(PHP_WIN32) || defined(NETWARE)
00120        if ((pos = strrchr(path, '\\')) != NULL) {
00121               path = pos+1;
00122        }
00123 #endif
00124 
00125        *p_file = path;
00126 
00127        if (get_path) {
00128               if (pglob->path) {
00129                      efree(pglob->path);
00130               }
00131               if (path != gpath) {
00132                      path--;
00133               }
00134               pglob->path_len = path - gpath;
00135               pglob->path = estrndup(gpath, pglob->path_len);
00136        }
00137 }
00138 /* }}} */
00139 
00140 static size_t php_glob_stream_read(php_stream *stream, char *buf, size_t count TSRMLS_DC) /* {{{ */
00141 {
00142        glob_s_t *pglob = (glob_s_t *)stream->abstract;
00143        php_stream_dirent *ent = (php_stream_dirent*)buf;
00144        char *path;
00145 
00146        /* avoid problems if someone mis-uses the stream */
00147        if (count == sizeof(php_stream_dirent) && pglob) {
00148               if (pglob->index < pglob->glob.gl_pathc) {
00149                      php_glob_stream_path_split(pglob, pglob->glob.gl_pathv[pglob->index++], pglob->flags & GLOB_APPEND, &path TSRMLS_CC);
00150                      PHP_STRLCPY(ent->d_name, path, sizeof(ent->d_name), strlen(path));
00151                      return sizeof(php_stream_dirent);
00152               }
00153               pglob->index = pglob->glob.gl_pathc;
00154               if (pglob->path) {
00155                      efree(pglob->path);
00156                      pglob->path = NULL;
00157               }
00158        }
00159 
00160        return 0;
00161 }
00162 /* }}} */
00163 
00164 static int php_glob_stream_close(php_stream *stream, int close_handle TSRMLS_DC)  /* {{{ */
00165 {
00166        glob_s_t *pglob = (glob_s_t *)stream->abstract;
00167 
00168        if (pglob) {
00169               pglob->index = 0;
00170               globfree(&pglob->glob);
00171               if (pglob->path) {
00172                      efree(pglob->path);
00173               }
00174               if (pglob->pattern) {
00175                      efree(pglob->pattern);
00176               }
00177        }
00178        efree(stream->abstract);
00179        return 0;
00180 }
00181 /* {{{ */
00182 
00183 static int php_glob_stream_rewind(php_stream *stream, off_t offset, int whence, off_t *newoffs TSRMLS_DC) /* {{{ */
00184 {
00185        glob_s_t *pglob = (glob_s_t *)stream->abstract;
00186 
00187        if (pglob) {
00188               pglob->index = 0;
00189               if (pglob->path) {
00190                      efree(pglob->path);
00191                      pglob->path = NULL;
00192               }
00193        }
00194        return 0;
00195 }
00196 /* }}} */
00197 
00198 php_stream_ops  php_glob_stream_ops = {
00199        NULL, php_glob_stream_read,
00200        php_glob_stream_close, NULL,
00201        "glob",
00202        php_glob_stream_rewind,
00203        NULL, /* cast */
00204        NULL, /* stat */
00205        NULL  /* set_option */
00206 };
00207 
00208  /* {{{ php_glob_stream_opener */
00209 static php_stream *php_glob_stream_opener(php_stream_wrapper *wrapper, char *path, char *mode,
00210               int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC)
00211 {
00212        glob_s_t *pglob;
00213        int ret;
00214        char *tmp, *pos;
00215 
00216        if (((options & STREAM_DISABLE_OPEN_BASEDIR) == 0) && php_check_open_basedir(path TSRMLS_CC)) {
00217               return NULL;
00218        }
00219 
00220        if (!strncmp(path, "glob://", sizeof("glob://")-1)) {
00221               path += sizeof("glob://")-1;
00222               if (opened_path) {
00223                      *opened_path = estrdup(path);
00224               }
00225        }
00226 
00227        pglob = ecalloc(sizeof(*pglob), 1);
00228        
00229        if (0 != (ret = glob(path, pglob->flags & GLOB_FLAGMASK, NULL, &pglob->glob))) {
00230 #ifdef GLOB_NOMATCH
00231               if (GLOB_NOMATCH != ret)
00232 #endif
00233               {
00234                      efree(pglob);
00235                      return NULL;
00236               }
00237        }
00238 
00239        pos = path;
00240        if ((tmp = strrchr(pos, '/')) != NULL) {
00241               pos = tmp+1;
00242        }
00243 #if defined(PHP_WIN32) || defined(NETWARE)
00244        if ((tmp = strrchr(pos, '\\')) != NULL) {
00245               pos = tmp+1;
00246        }
00247 #endif
00248 
00249        pglob->pattern_len = strlen(pos);
00250        pglob->pattern = estrndup(pos, pglob->pattern_len);
00251 
00252        pglob->flags |= GLOB_APPEND;
00253 
00254        if (pglob->glob.gl_pathc) {
00255               php_glob_stream_path_split(pglob, pglob->glob.gl_pathv[0], 1, &tmp TSRMLS_CC);
00256        } else {
00257               php_glob_stream_path_split(pglob, path, 1, &tmp TSRMLS_CC);
00258        }
00259 
00260        return php_stream_alloc(&php_glob_stream_ops, pglob, 0, mode);
00261 }
00262 /* }}} */
00263 
00264 static php_stream_wrapper_ops  php_glob_stream_wrapper_ops = {
00265        NULL,
00266        NULL,
00267        NULL,
00268        NULL,
00269        php_glob_stream_opener,
00270        "glob",
00271        NULL,
00272        NULL,
00273        NULL,
00274        NULL
00275 };
00276 
00277 php_stream_wrapper  php_glob_stream_wrapper = {
00278        &php_glob_stream_wrapper_ops,
00279        NULL,
00280        0
00281 };
00282 #endif /* HAVE_GLOB */
00283 
00284 /*
00285  * Local variables:
00286  * tab-width: 4
00287  * c-basic-offset: 4
00288  * End:
00289  * vim600: noet sw=4 ts=4 fdm=marker
00290  * vim<600: noet sw=4 ts=4
00291  */