root/main/streams/glob_wrapper.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. _php_glob_stream_get_path
  2. _php_glob_stream_get_pattern
  3. _php_glob_stream_get_count
  4. php_glob_stream_path_split
  5. php_glob_stream_read
  6. php_glob_stream_close
  7. php_glob_stream_rewind
  8. php_glob_stream_opener

   1 /*
   2    +----------------------------------------------------------------------+
   3    | PHP Version 7                                                        |
   4    +----------------------------------------------------------------------+
   5    | Copyright (c) 1997-2016 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$ */
  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, size_t *plen STREAMS_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, size_t *plen STREAMS_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) /* {{{ */
  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, const char *path, int get_path, const char **p_file) /* {{{ */
 113 {
 114         const 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) /* {{{ */
 141 {
 142         glob_s_t *pglob = (glob_s_t *)stream->abstract;
 143         php_stream_dirent *ent = (php_stream_dirent*)buf;
 144         const char *path;
 145 
 146         /* avoid problems if someone mis-uses the stream */
 147         if (count == sizeof(php_stream_dirent) && pglob) {
 148                 if (pglob->index < (size_t)pglob->glob.gl_pathc) {
 149                         php_glob_stream_path_split(pglob, pglob->glob.gl_pathv[pglob->index++], pglob->flags & GLOB_APPEND, &path);
 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)  /* {{{ */
 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, zend_off_t offset, int whence, zend_off_t *newoffs) /* {{{ */
 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, const char *path, const char *mode,
 210                 int options, zend_string **opened_path, php_stream_context *context STREAMS_DC)
 211 {
 212         glob_s_t *pglob;
 213         int ret;
 214         const char *tmp, *pos;
 215 
 216         if (((options & STREAM_DISABLE_OPEN_BASEDIR) == 0) && php_check_open_basedir(path)) {
 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 = zend_string_init(path, strlen(path), 0);
 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);
 256         } else {
 257                 php_glob_stream_path_split(pglob, path, 1, &tmp);
 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  */

/* [<][>][^][v][top][bottom][index][help] */