![]() ![]() | ![]() |
1.1 misho 1: /*
2: +----------------------------------------------------------------------+
3: | PHP Version 5 |
4: +----------------------------------------------------------------------+
1.1.1.4 ! misho 5: | Copyright (c) 1997-2014 The PHP Group |
1.1 misho 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:
1.1.1.2 misho 19: /* $Id$ */
1.1 misho 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) {
1.1.1.2 misho 148: if (pglob->index < (size_t)pglob->glob.gl_pathc) {
1.1 misho 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: */