PageRenderTime 44ms CodeModel.GetById 16ms RepoModel.GetById 1ms app.codeStats 0ms

/main/streams/glob_wrapper.c

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