Annotation of embedaddon/php/ext/phar/func_interceptors.c, revision 1.1.1.1
1.1 misho 1: /*
2: +----------------------------------------------------------------------+
3: | phar php single-file executable PHP extension |
4: +----------------------------------------------------------------------+
5: | Copyright (c) 2005-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: Gregory Beaver <cellog@php.net> |
16: +----------------------------------------------------------------------+
17: */
18:
19: /* $Id: func_interceptors.c 321634 2012-01-01 13:15:04Z felipe $ */
20:
21: #include "phar_internal.h"
22:
23: #define PHAR_FUNC(name) \
24: static PHP_NAMED_FUNCTION(name)
25:
26: PHAR_FUNC(phar_opendir) /* {{{ */
27: {
28: char *filename;
29: int filename_len;
30: zval *zcontext = NULL;
31:
32: if (!PHAR_G(intercepted)) {
33: goto skip_phar;
34: }
35:
36: if ((PHAR_GLOBALS->phar_fname_map.arBuckets && !zend_hash_num_elements(&(PHAR_GLOBALS->phar_fname_map)))
37: && !cached_phars.arBuckets) {
38: goto skip_phar;
39: }
40:
41: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|z", &filename, &filename_len, &zcontext) == FAILURE) {
42: return;
43: }
44:
45: if (!IS_ABSOLUTE_PATH(filename, filename_len) && !strstr(filename, "://")) {
46: char *arch, *entry, *fname;
47: int arch_len, entry_len, fname_len;
48: fname = zend_get_executed_filename(TSRMLS_C);
49:
50: /* we are checking for existence of a file within the relative path. Chances are good that this is
51: retrieving something from within the phar archive */
52:
53: if (strncasecmp(fname, "phar://", 7)) {
54: goto skip_phar;
55: }
56: fname_len = strlen(fname);
57: if (SUCCESS == phar_split_fname(fname, fname_len, &arch, &arch_len, &entry, &entry_len, 2, 0 TSRMLS_CC)) {
58: php_stream_context *context = NULL;
59: php_stream *stream;
60: char *name;
61:
62: efree(entry);
63: entry = estrndup(filename, filename_len);
64: /* fopen within phar, if :// is not in the url, then prepend phar://<archive>/ */
65: entry_len = filename_len;
66: /* retrieving a file within the current directory, so use this if possible */
67: entry = phar_fix_filepath(entry, &entry_len, 1 TSRMLS_CC);
68:
69: if (entry[0] == '/') {
70: spprintf(&name, 4096, "phar://%s%s", arch, entry);
71: } else {
72: spprintf(&name, 4096, "phar://%s/%s", arch, entry);
73: }
74: efree(entry);
75: efree(arch);
76: if (zcontext) {
77: context = php_stream_context_from_zval(zcontext, 0);
78: }
79: stream = php_stream_opendir(name, REPORT_ERRORS, context);
80: efree(name);
81: if (!stream) {
82: RETURN_FALSE;
83: }
84: php_stream_to_zval(stream, return_value);
85: return;
86: }
87: }
88: skip_phar:
89: PHAR_G(orig_opendir)(INTERNAL_FUNCTION_PARAM_PASSTHRU);
90: return;
91: }
92: /* }}} */
93:
94: PHAR_FUNC(phar_file_get_contents) /* {{{ */
95: {
96: char *filename;
97: int filename_len;
98: char *contents;
99: zend_bool use_include_path = 0;
100: php_stream *stream;
101: int len;
102: long offset = -1;
103: long maxlen = PHP_STREAM_COPY_ALL;
104: zval *zcontext = NULL;
105:
106: if (!PHAR_G(intercepted)) {
107: goto skip_phar;
108: }
109:
110: if ((PHAR_GLOBALS->phar_fname_map.arBuckets && !zend_hash_num_elements(&(PHAR_GLOBALS->phar_fname_map)))
111: && !cached_phars.arBuckets) {
112: goto skip_phar;
113: }
114:
115: /* Parse arguments */
116: if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "s|br!ll", &filename, &filename_len, &use_include_path, &zcontext, &offset, &maxlen) == FAILURE) {
117: goto skip_phar;
118: }
119:
120: if (use_include_path || (!IS_ABSOLUTE_PATH(filename, filename_len) && !strstr(filename, "://"))) {
121: char *arch, *entry, *fname;
122: int arch_len, entry_len, fname_len;
123: php_stream_context *context = NULL;
124:
125: fname = zend_get_executed_filename(TSRMLS_C);
126:
127: if (strncasecmp(fname, "phar://", 7)) {
128: goto skip_phar;
129: }
130: fname_len = strlen(fname);
131: if (SUCCESS == phar_split_fname(fname, fname_len, &arch, &arch_len, &entry, &entry_len, 2, 0 TSRMLS_CC)) {
132: char *name;
133: phar_archive_data *phar;
134:
135: efree(entry);
136: entry = filename;
137: /* fopen within phar, if :// is not in the url, then prepend phar://<archive>/ */
138: entry_len = filename_len;
139:
140: if (ZEND_NUM_ARGS() == 5 && maxlen < 0) {
141: efree(arch);
142: php_error_docref(NULL TSRMLS_CC, E_WARNING, "length must be greater than or equal to zero");
143: RETURN_FALSE;
144: }
145:
146: /* retrieving a file defaults to within the current directory, so use this if possible */
147: if (FAILURE == phar_get_archive(&phar, arch, arch_len, NULL, 0, NULL TSRMLS_CC)) {
148: efree(arch);
149: goto skip_phar;
150: }
151: if (use_include_path) {
152: if ((entry = phar_find_in_include_path(entry, entry_len, NULL TSRMLS_CC))) {
153: name = entry;
154: goto phar_it;
155: } else {
156: /* this file is not in the phar, use the original path */
157: efree(arch);
158: goto skip_phar;
159: }
160: } else {
161: entry = phar_fix_filepath(estrndup(entry, entry_len), &entry_len, 1 TSRMLS_CC);
162: if (entry[0] == '/') {
163: if (!zend_hash_exists(&(phar->manifest), entry + 1, entry_len - 1)) {
164: /* this file is not in the phar, use the original path */
165: notfound:
166: efree(arch);
167: efree(entry);
168: goto skip_phar;
169: }
170: } else {
171: if (!zend_hash_exists(&(phar->manifest), entry, entry_len)) {
172: goto notfound;
173: }
174: }
175: /* auto-convert to phar:// */
176: if (entry[0] == '/') {
177: spprintf(&name, 4096, "phar://%s%s", arch, entry);
178: } else {
179: spprintf(&name, 4096, "phar://%s/%s", arch, entry);
180: }
181: if (entry != filename) {
182: efree(entry);
183: }
184: }
185:
186: phar_it:
187: efree(arch);
188: if (zcontext) {
189: context = php_stream_context_from_zval(zcontext, 0);
190: }
191: stream = php_stream_open_wrapper_ex(name, "rb", 0 | REPORT_ERRORS, NULL, context);
192: efree(name);
193:
194: if (!stream) {
195: RETURN_FALSE;
196: }
197:
198: if (offset > 0 && php_stream_seek(stream, offset, SEEK_SET) < 0) {
199: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to seek to position %ld in the stream", offset);
200: php_stream_close(stream);
201: RETURN_FALSE;
202: }
203:
204: /* uses mmap if possible */
205: if ((len = php_stream_copy_to_mem(stream, &contents, maxlen, 0)) > 0) {
206: #if PHP_MAJOR_VERSION < 6
207: if (PG(magic_quotes_runtime)) {
208: int newlen;
209: contents = php_addslashes(contents, len, &newlen, 1 TSRMLS_CC); /* 1 = free source string */
210: len = newlen;
211: }
212: #endif
213: RETVAL_STRINGL(contents, len, 0);
214: } else if (len == 0) {
215: RETVAL_EMPTY_STRING();
216: } else {
217: RETVAL_FALSE;
218: }
219:
220: php_stream_close(stream);
221: return;
222: }
223: }
224: skip_phar:
225: PHAR_G(orig_file_get_contents)(INTERNAL_FUNCTION_PARAM_PASSTHRU);
226: return;
227: }
228: /* }}} */
229:
230: PHAR_FUNC(phar_readfile) /* {{{ */
231: {
232: char *filename;
233: int filename_len;
234: int size = 0;
235: zend_bool use_include_path = 0;
236: zval *zcontext = NULL;
237: php_stream *stream;
238:
239: if (!PHAR_G(intercepted)) {
240: goto skip_phar;
241: }
242:
243: if ((PHAR_GLOBALS->phar_fname_map.arBuckets && !zend_hash_num_elements(&(PHAR_GLOBALS->phar_fname_map)))
244: && !cached_phars.arBuckets) {
245: goto skip_phar;
246: }
247: if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "s|br!", &filename, &filename_len, &use_include_path, &zcontext) == FAILURE) {
248: goto skip_phar;
249: }
250: if (use_include_path || (!IS_ABSOLUTE_PATH(filename, filename_len) && !strstr(filename, "://"))) {
251: char *arch, *entry, *fname;
252: int arch_len, entry_len, fname_len;
253: php_stream_context *context = NULL;
254: char *name;
255: phar_archive_data *phar;
256: fname = zend_get_executed_filename(TSRMLS_C);
257:
258: if (strncasecmp(fname, "phar://", 7)) {
259: goto skip_phar;
260: }
261: fname_len = strlen(fname);
262: if (FAILURE == phar_split_fname(fname, fname_len, &arch, &arch_len, &entry, &entry_len, 2, 0 TSRMLS_CC)) {
263: goto skip_phar;
264: }
265:
266: efree(entry);
267: entry = filename;
268: /* fopen within phar, if :// is not in the url, then prepend phar://<archive>/ */
269: entry_len = filename_len;
270: /* retrieving a file defaults to within the current directory, so use this if possible */
271: if (FAILURE == phar_get_archive(&phar, arch, arch_len, NULL, 0, NULL TSRMLS_CC)) {
272: efree(arch);
273: goto skip_phar;
274: }
275: if (use_include_path) {
276: if (!(entry = phar_find_in_include_path(entry, entry_len, NULL TSRMLS_CC))) {
277: /* this file is not in the phar, use the original path */
278: efree(arch);
279: goto skip_phar;
280: } else {
281: name = entry;
282: }
283: } else {
284: entry = phar_fix_filepath(estrndup(entry, entry_len), &entry_len, 1 TSRMLS_CC);
285: if (entry[0] == '/') {
286: if (!zend_hash_exists(&(phar->manifest), entry + 1, entry_len - 1)) {
287: /* this file is not in the phar, use the original path */
288: notfound:
289: efree(entry);
290: efree(arch);
291: goto skip_phar;
292: }
293: } else {
294: if (!zend_hash_exists(&(phar->manifest), entry, entry_len)) {
295: goto notfound;
296: }
297: }
298: /* auto-convert to phar:// */
299: if (entry[0] == '/') {
300: spprintf(&name, 4096, "phar://%s%s", arch, entry);
301: } else {
302: spprintf(&name, 4096, "phar://%s/%s", arch, entry);
303: }
304: efree(entry);
305: }
306:
307: efree(arch);
308: context = php_stream_context_from_zval(zcontext, 0);
309: stream = php_stream_open_wrapper_ex(name, "rb", 0 | REPORT_ERRORS, NULL, context);
310: efree(name);
311: if (stream == NULL) {
312: RETURN_FALSE;
313: }
314: size = php_stream_passthru(stream);
315: php_stream_close(stream);
316: RETURN_LONG(size);
317: }
318:
319: skip_phar:
320: PHAR_G(orig_readfile)(INTERNAL_FUNCTION_PARAM_PASSTHRU);
321: return;
322:
323: }
324: /* }}} */
325:
326: PHAR_FUNC(phar_fopen) /* {{{ */
327: {
328: char *filename, *mode;
329: int filename_len, mode_len;
330: zend_bool use_include_path = 0;
331: zval *zcontext = NULL;
332: php_stream *stream;
333:
334: if (!PHAR_G(intercepted)) {
335: goto skip_phar;
336: }
337:
338: if ((PHAR_GLOBALS->phar_fname_map.arBuckets && !zend_hash_num_elements(&(PHAR_GLOBALS->phar_fname_map)))
339: && !cached_phars.arBuckets) {
340: /* no need to check, include_path not even specified in fopen/ no active phars */
341: goto skip_phar;
342: }
343: if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "ss|br", &filename, &filename_len, &mode, &mode_len, &use_include_path, &zcontext) == FAILURE) {
344: goto skip_phar;
345: }
346: if (use_include_path || (!IS_ABSOLUTE_PATH(filename, filename_len) && !strstr(filename, "://"))) {
347: char *arch, *entry, *fname;
348: int arch_len, entry_len, fname_len;
349: php_stream_context *context = NULL;
350: char *name;
351: phar_archive_data *phar;
352: fname = zend_get_executed_filename(TSRMLS_C);
353:
354: if (strncasecmp(fname, "phar://", 7)) {
355: goto skip_phar;
356: }
357: fname_len = strlen(fname);
358: if (FAILURE == phar_split_fname(fname, fname_len, &arch, &arch_len, &entry, &entry_len, 2, 0 TSRMLS_CC)) {
359: goto skip_phar;
360: }
361:
362: efree(entry);
363: entry = filename;
364: /* fopen within phar, if :// is not in the url, then prepend phar://<archive>/ */
365: entry_len = filename_len;
366: /* retrieving a file defaults to within the current directory, so use this if possible */
367: if (FAILURE == phar_get_archive(&phar, arch, arch_len, NULL, 0, NULL TSRMLS_CC)) {
368: efree(arch);
369: goto skip_phar;
370: }
371: if (use_include_path) {
372: if (!(entry = phar_find_in_include_path(entry, entry_len, NULL TSRMLS_CC))) {
373: /* this file is not in the phar, use the original path */
374: efree(arch);
375: goto skip_phar;
376: } else {
377: name = entry;
378: }
379: } else {
380: entry = phar_fix_filepath(estrndup(entry, entry_len), &entry_len, 1 TSRMLS_CC);
381: if (entry[0] == '/') {
382: if (!zend_hash_exists(&(phar->manifest), entry + 1, entry_len - 1)) {
383: /* this file is not in the phar, use the original path */
384: notfound:
385: efree(entry);
386: efree(arch);
387: goto skip_phar;
388: }
389: } else {
390: if (!zend_hash_exists(&(phar->manifest), entry, entry_len)) {
391: /* this file is not in the phar, use the original path */
392: goto notfound;
393: }
394: }
395: /* auto-convert to phar:// */
396: if (entry[0] == '/') {
397: spprintf(&name, 4096, "phar://%s%s", arch, entry);
398: } else {
399: spprintf(&name, 4096, "phar://%s/%s", arch, entry);
400: }
401: efree(entry);
402: }
403:
404: efree(arch);
405: context = php_stream_context_from_zval(zcontext, 0);
406: stream = php_stream_open_wrapper_ex(name, mode, 0 | REPORT_ERRORS, NULL, context);
407: efree(name);
408: if (stream == NULL) {
409: RETURN_FALSE;
410: }
411: php_stream_to_zval(stream, return_value);
412: if (zcontext) {
413: zend_list_addref(Z_RESVAL_P(zcontext));
414: }
415: return;
416: }
417: skip_phar:
418: PHAR_G(orig_fopen)(INTERNAL_FUNCTION_PARAM_PASSTHRU);
419: return;
420: }
421: /* }}} */
422:
423: #ifndef S_ISDIR
424: #define S_ISDIR(mode) (((mode)&S_IFMT) == S_IFDIR)
425: #endif
426: #ifndef S_ISREG
427: #define S_ISREG(mode) (((mode)&S_IFMT) == S_IFREG)
428: #endif
429: #ifndef S_ISLNK
430: #define S_ISLNK(mode) (((mode)&S_IFMT) == S_IFLNK)
431: #endif
432:
433: #define S_IXROOT ( S_IXUSR | S_IXGRP | S_IXOTH )
434:
435: #define IS_LINK_OPERATION(__t) ((__t) == FS_TYPE || (__t) == FS_IS_LINK || (__t) == FS_LSTAT)
436: #define IS_EXISTS_CHECK(__t) ((__t) == FS_EXISTS || (__t) == FS_IS_W || (__t) == FS_IS_R || (__t) == FS_IS_X || (__t) == FS_IS_FILE || (__t) == FS_IS_DIR || (__t) == FS_IS_LINK)
437: #define IS_ABLE_CHECK(__t) ((__t) == FS_IS_R || (__t) == FS_IS_W || (__t) == FS_IS_X)
438: #define IS_ACCESS_CHECK(__t) (IS_ABLE_CHECK(type) || (__t) == FS_EXISTS)
439:
440: /* {{{ php_stat
441: */
442: static void phar_fancy_stat(struct stat *stat_sb, int type, zval *return_value TSRMLS_DC)
443: {
444: zval *stat_dev, *stat_ino, *stat_mode, *stat_nlink, *stat_uid, *stat_gid, *stat_rdev,
445: *stat_size, *stat_atime, *stat_mtime, *stat_ctime, *stat_blksize, *stat_blocks;
446: int rmask=S_IROTH, wmask=S_IWOTH, xmask=S_IXOTH; /* access rights defaults to other */
447: char *stat_sb_names[13] = {
448: "dev", "ino", "mode", "nlink", "uid", "gid", "rdev",
449: "size", "atime", "mtime", "ctime", "blksize", "blocks"
450: };
451:
452: #ifndef NETWARE
453: if (type >= FS_IS_W && type <= FS_IS_X) {
454: if(stat_sb->st_uid==getuid()) {
455: rmask=S_IRUSR;
456: wmask=S_IWUSR;
457: xmask=S_IXUSR;
458: } else if(stat_sb->st_gid==getgid()) {
459: rmask=S_IRGRP;
460: wmask=S_IWGRP;
461: xmask=S_IXGRP;
462: } else {
463: int groups, n, i;
464: gid_t *gids;
465:
466: groups = getgroups(0, NULL);
467: if(groups > 0) {
468: gids=(gid_t *)safe_emalloc(groups, sizeof(gid_t), 0);
469: n=getgroups(groups, gids);
470: for(i=0;i<n;++i){
471: if(stat_sb->st_gid==gids[i]) {
472: rmask=S_IRGRP;
473: wmask=S_IWGRP;
474: xmask=S_IXGRP;
475: break;
476: }
477: }
478: efree(gids);
479: }
480: }
481: }
482: #endif
483:
484: switch (type) {
485: case FS_PERMS:
486: RETURN_LONG((long)stat_sb->st_mode);
487: case FS_INODE:
488: RETURN_LONG((long)stat_sb->st_ino);
489: case FS_SIZE:
490: RETURN_LONG((long)stat_sb->st_size);
491: case FS_OWNER:
492: RETURN_LONG((long)stat_sb->st_uid);
493: case FS_GROUP:
494: RETURN_LONG((long)stat_sb->st_gid);
495: case FS_ATIME:
496: #ifdef NETWARE
497: RETURN_LONG((long)stat_sb->st_atime.tv_sec);
498: #else
499: RETURN_LONG((long)stat_sb->st_atime);
500: #endif
501: case FS_MTIME:
502: #ifdef NETWARE
503: RETURN_LONG((long)stat_sb->st_mtime.tv_sec);
504: #else
505: RETURN_LONG((long)stat_sb->st_mtime);
506: #endif
507: case FS_CTIME:
508: #ifdef NETWARE
509: RETURN_LONG((long)stat_sb->st_ctime.tv_sec);
510: #else
511: RETURN_LONG((long)stat_sb->st_ctime);
512: #endif
513: case FS_TYPE:
514: if (S_ISLNK(stat_sb->st_mode)) {
515: RETURN_STRING("link", 1);
516: }
517: switch(stat_sb->st_mode & S_IFMT) {
518: case S_IFDIR: RETURN_STRING("dir", 1);
519: case S_IFREG: RETURN_STRING("file", 1);
520: }
521: php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Unknown file type (%u)", stat_sb->st_mode & S_IFMT);
522: RETURN_STRING("unknown", 1);
523: case FS_IS_W:
524: RETURN_BOOL((stat_sb->st_mode & wmask) != 0);
525: case FS_IS_R:
526: RETURN_BOOL((stat_sb->st_mode&rmask)!=0);
527: case FS_IS_X:
528: RETURN_BOOL((stat_sb->st_mode&xmask)!=0 && !S_ISDIR(stat_sb->st_mode));
529: case FS_IS_FILE:
530: RETURN_BOOL(S_ISREG(stat_sb->st_mode));
531: case FS_IS_DIR:
532: RETURN_BOOL(S_ISDIR(stat_sb->st_mode));
533: case FS_IS_LINK:
534: RETURN_BOOL(S_ISLNK(stat_sb->st_mode));
535: case FS_EXISTS:
536: RETURN_TRUE; /* the false case was done earlier */
537: case FS_LSTAT:
538: /* FALLTHROUGH */
539: case FS_STAT:
540: array_init(return_value);
541:
542: MAKE_LONG_ZVAL_INCREF(stat_dev, stat_sb->st_dev);
543: MAKE_LONG_ZVAL_INCREF(stat_ino, stat_sb->st_ino);
544: MAKE_LONG_ZVAL_INCREF(stat_mode, stat_sb->st_mode);
545: MAKE_LONG_ZVAL_INCREF(stat_nlink, stat_sb->st_nlink);
546: MAKE_LONG_ZVAL_INCREF(stat_uid, stat_sb->st_uid);
547: MAKE_LONG_ZVAL_INCREF(stat_gid, stat_sb->st_gid);
548: #ifdef HAVE_ST_RDEV
549: MAKE_LONG_ZVAL_INCREF(stat_rdev, stat_sb->st_rdev);
550: #else
551: MAKE_LONG_ZVAL_INCREF(stat_rdev, -1);
552: #endif
553: MAKE_LONG_ZVAL_INCREF(stat_size, stat_sb->st_size);
554: #ifdef NETWARE
555: MAKE_LONG_ZVAL_INCREF(stat_atime, (stat_sb->st_atime).tv_sec);
556: MAKE_LONG_ZVAL_INCREF(stat_mtime, (stat_sb->st_mtime).tv_sec);
557: MAKE_LONG_ZVAL_INCREF(stat_ctime, (stat_sb->st_ctime).tv_sec);
558: #else
559: MAKE_LONG_ZVAL_INCREF(stat_atime, stat_sb->st_atime);
560: MAKE_LONG_ZVAL_INCREF(stat_mtime, stat_sb->st_mtime);
561: MAKE_LONG_ZVAL_INCREF(stat_ctime, stat_sb->st_ctime);
562: #endif
563: #ifdef HAVE_ST_BLKSIZE
564: MAKE_LONG_ZVAL_INCREF(stat_blksize, stat_sb->st_blksize);
565: #else
566: MAKE_LONG_ZVAL_INCREF(stat_blksize,-1);
567: #endif
568: #ifdef HAVE_ST_BLOCKS
569: MAKE_LONG_ZVAL_INCREF(stat_blocks, stat_sb->st_blocks);
570: #else
571: MAKE_LONG_ZVAL_INCREF(stat_blocks,-1);
572: #endif
573: /* Store numeric indexes in propper order */
574: zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_dev, sizeof(zval *), NULL);
575: zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_ino, sizeof(zval *), NULL);
576: zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_mode, sizeof(zval *), NULL);
577: zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_nlink, sizeof(zval *), NULL);
578: zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_uid, sizeof(zval *), NULL);
579: zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_gid, sizeof(zval *), NULL);
580:
581: zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_rdev, sizeof(zval *), NULL);
582: zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_size, sizeof(zval *), NULL);
583: zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_atime, sizeof(zval *), NULL);
584: zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_mtime, sizeof(zval *), NULL);
585: zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_ctime, sizeof(zval *), NULL);
586: zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_blksize, sizeof(zval *), NULL);
587: zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_blocks, sizeof(zval *), NULL);
588:
589: /* Store string indexes referencing the same zval*/
590: zend_hash_update(HASH_OF(return_value), stat_sb_names[0], strlen(stat_sb_names[0])+1, (void *) &stat_dev, sizeof(zval *), NULL);
591: zend_hash_update(HASH_OF(return_value), stat_sb_names[1], strlen(stat_sb_names[1])+1, (void *) &stat_ino, sizeof(zval *), NULL);
592: zend_hash_update(HASH_OF(return_value), stat_sb_names[2], strlen(stat_sb_names[2])+1, (void *) &stat_mode, sizeof(zval *), NULL);
593: zend_hash_update(HASH_OF(return_value), stat_sb_names[3], strlen(stat_sb_names[3])+1, (void *) &stat_nlink, sizeof(zval *), NULL);
594: zend_hash_update(HASH_OF(return_value), stat_sb_names[4], strlen(stat_sb_names[4])+1, (void *) &stat_uid, sizeof(zval *), NULL);
595: zend_hash_update(HASH_OF(return_value), stat_sb_names[5], strlen(stat_sb_names[5])+1, (void *) &stat_gid, sizeof(zval *), NULL);
596: zend_hash_update(HASH_OF(return_value), stat_sb_names[6], strlen(stat_sb_names[6])+1, (void *) &stat_rdev, sizeof(zval *), NULL);
597: zend_hash_update(HASH_OF(return_value), stat_sb_names[7], strlen(stat_sb_names[7])+1, (void *) &stat_size, sizeof(zval *), NULL);
598: zend_hash_update(HASH_OF(return_value), stat_sb_names[8], strlen(stat_sb_names[8])+1, (void *) &stat_atime, sizeof(zval *), NULL);
599: zend_hash_update(HASH_OF(return_value), stat_sb_names[9], strlen(stat_sb_names[9])+1, (void *) &stat_mtime, sizeof(zval *), NULL);
600: zend_hash_update(HASH_OF(return_value), stat_sb_names[10], strlen(stat_sb_names[10])+1, (void *) &stat_ctime, sizeof(zval *), NULL);
601: zend_hash_update(HASH_OF(return_value), stat_sb_names[11], strlen(stat_sb_names[11])+1, (void *) &stat_blksize, sizeof(zval *), NULL);
602: zend_hash_update(HASH_OF(return_value), stat_sb_names[12], strlen(stat_sb_names[12])+1, (void *) &stat_blocks, sizeof(zval *), NULL);
603:
604: return;
605: }
606: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Didn't understand stat call");
607: RETURN_FALSE;
608: }
609: /* }}} */
610:
611: static void phar_file_stat(const char *filename, php_stat_len filename_length, int type, void (*orig_stat_func)(INTERNAL_FUNCTION_PARAMETERS), INTERNAL_FUNCTION_PARAMETERS) /* {{{ */
612: {
613: if (!filename_length) {
614: RETURN_FALSE;
615: }
616:
617: if (!IS_ABSOLUTE_PATH(filename, filename_length) && !strstr(filename, "://")) {
618: char *arch, *entry, *fname;
619: int arch_len, entry_len, fname_len;
620: struct stat sb = {0};
621: phar_entry_info *data = NULL;
622: phar_archive_data *phar;
623:
624: fname = zend_get_executed_filename(TSRMLS_C);
625:
626: /* we are checking for existence of a file within the relative path. Chances are good that this is
627: retrieving something from within the phar archive */
628:
629: if (strncasecmp(fname, "phar://", 7)) {
630: goto skip_phar;
631: }
632: fname_len = strlen(fname);
633: if (PHAR_G(last_phar) && fname_len - 7 >= PHAR_G(last_phar_name_len) && !memcmp(fname + 7, PHAR_G(last_phar_name), PHAR_G(last_phar_name_len))) {
634: arch = estrndup(PHAR_G(last_phar_name), PHAR_G(last_phar_name_len));
635: arch_len = PHAR_G(last_phar_name_len);
636: entry = estrndup(filename, filename_length);
637: /* fopen within phar, if :// is not in the url, then prepend phar://<archive>/ */
638: entry_len = (int) filename_length;
639: phar = PHAR_G(last_phar);
640: goto splitted;
641: }
642: if (SUCCESS == phar_split_fname(fname, fname_len, &arch, &arch_len, &entry, &entry_len, 2, 0 TSRMLS_CC)) {
643:
644: efree(entry);
645: entry = estrndup(filename, filename_length);
646: /* fopen within phar, if :// is not in the url, then prepend phar://<archive>/ */
647: entry_len = (int) filename_length;
648: if (FAILURE == phar_get_archive(&phar, arch, arch_len, NULL, 0, NULL TSRMLS_CC)) {
649: efree(arch);
650: efree(entry);
651: goto skip_phar;
652: }
653: splitted:
654: entry = phar_fix_filepath(entry, &entry_len, 1 TSRMLS_CC);
655: if (entry[0] == '/') {
656: if (SUCCESS == zend_hash_find(&(phar->manifest), entry + 1, entry_len - 1, (void **) &data)) {
657: efree(entry);
658: goto stat_entry;
659: }
660: goto notfound;
661: }
662: if (SUCCESS == zend_hash_find(&(phar->manifest), entry, entry_len, (void **) &data)) {
663: efree(entry);
664: goto stat_entry;
665: }
666: if (zend_hash_exists(&(phar->virtual_dirs), entry, entry_len)) {
667: efree(entry);
668: efree(arch);
669: if (IS_EXISTS_CHECK(type)) {
670: RETURN_TRUE;
671: }
672: sb.st_size = 0;
673: sb.st_mode = 0777;
674: sb.st_mode |= S_IFDIR; /* regular directory */
675: #ifdef NETWARE
676: sb.st_mtime.tv_sec = phar->max_timestamp;
677: sb.st_atime.tv_sec = phar->max_timestamp;
678: sb.st_ctime.tv_sec = phar->max_timestamp;
679: #else
680: sb.st_mtime = phar->max_timestamp;
681: sb.st_atime = phar->max_timestamp;
682: sb.st_ctime = phar->max_timestamp;
683: #endif
684: goto statme_baby;
685: } else {
686: char *save;
687: int save_len;
688:
689: notfound:
690: efree(entry);
691: save = PHAR_G(cwd);
692: save_len = PHAR_G(cwd_len);
693: /* this file is not in the current directory, use the original path */
694: entry = estrndup(filename, filename_length);
695: entry_len = filename_length;
696: PHAR_G(cwd) = "/";
697: PHAR_G(cwd_len) = 0;
698: /* clean path without cwd */
699: entry = phar_fix_filepath(entry, &entry_len, 1 TSRMLS_CC);
700: if (SUCCESS == zend_hash_find(&(phar->manifest), entry + 1, entry_len - 1, (void **) &data)) {
701: PHAR_G(cwd) = save;
702: PHAR_G(cwd_len) = save_len;
703: efree(entry);
704: if (IS_EXISTS_CHECK(type)) {
705: efree(arch);
706: RETURN_TRUE;
707: }
708: goto stat_entry;
709: }
710: if (zend_hash_exists(&(phar->virtual_dirs), entry + 1, entry_len - 1)) {
711: PHAR_G(cwd) = save;
712: PHAR_G(cwd_len) = save_len;
713: efree(entry);
714: efree(arch);
715: if (IS_EXISTS_CHECK(type)) {
716: RETURN_TRUE;
717: }
718: sb.st_size = 0;
719: sb.st_mode = 0777;
720: sb.st_mode |= S_IFDIR; /* regular directory */
721: #ifdef NETWARE
722: sb.st_mtime.tv_sec = phar->max_timestamp;
723: sb.st_atime.tv_sec = phar->max_timestamp;
724: sb.st_ctime.tv_sec = phar->max_timestamp;
725: #else
726: sb.st_mtime = phar->max_timestamp;
727: sb.st_atime = phar->max_timestamp;
728: sb.st_ctime = phar->max_timestamp;
729: #endif
730: goto statme_baby;
731: }
732: PHAR_G(cwd) = save;
733: PHAR_G(cwd_len) = save_len;
734: efree(entry);
735: efree(arch);
736: /* Error Occured */
737: if (!IS_EXISTS_CHECK(type)) {
738: php_error_docref(NULL TSRMLS_CC, E_WARNING, "%sstat failed for %s", IS_LINK_OPERATION(type) ? "L" : "", filename);
739: }
740: RETURN_FALSE;
741: }
742: stat_entry:
743: efree(arch);
744: if (!data->is_dir) {
745: sb.st_size = data->uncompressed_filesize;
746: sb.st_mode = data->flags & PHAR_ENT_PERM_MASK;
747: if (data->link) {
748: sb.st_mode |= S_IFREG|S_IFLNK; /* regular file */
749: } else {
750: sb.st_mode |= S_IFREG; /* regular file */
751: }
752: /* timestamp is just the timestamp when this was added to the phar */
753: #ifdef NETWARE
754: sb.st_mtime.tv_sec = data->timestamp;
755: sb.st_atime.tv_sec = data->timestamp;
756: sb.st_ctime.tv_sec = data->timestamp;
757: #else
758: sb.st_mtime = data->timestamp;
759: sb.st_atime = data->timestamp;
760: sb.st_ctime = data->timestamp;
761: #endif
762: } else {
763: sb.st_size = 0;
764: sb.st_mode = data->flags & PHAR_ENT_PERM_MASK;
765: sb.st_mode |= S_IFDIR; /* regular directory */
766: if (data->link) {
767: sb.st_mode |= S_IFLNK;
768: }
769: /* timestamp is just the timestamp when this was added to the phar */
770: #ifdef NETWARE
771: sb.st_mtime.tv_sec = data->timestamp;
772: sb.st_atime.tv_sec = data->timestamp;
773: sb.st_ctime.tv_sec = data->timestamp;
774: #else
775: sb.st_mtime = data->timestamp;
776: sb.st_atime = data->timestamp;
777: sb.st_ctime = data->timestamp;
778: #endif
779: }
780:
781: statme_baby:
782: if (!phar->is_writeable) {
783: sb.st_mode = (sb.st_mode & 0555) | (sb.st_mode & ~0777);
784: }
785:
786: sb.st_nlink = 1;
787: sb.st_rdev = -1;
788: /* this is only for APC, so use /dev/null device - no chance of conflict there! */
789: sb.st_dev = 0xc;
790: /* generate unique inode number for alias/filename, so no phars will conflict */
791: if (data) {
792: sb.st_ino = data->inode;
793: }
794: #ifndef PHP_WIN32
795: sb.st_blksize = -1;
796: sb.st_blocks = -1;
797: #endif
798: phar_fancy_stat(&sb, type, return_value TSRMLS_CC);
799: return;
800: }
801: }
802: skip_phar:
803: orig_stat_func(INTERNAL_FUNCTION_PARAM_PASSTHRU);
804: return;
805: }
806: /* }}} */
807:
808: #define PharFileFunction(fname, funcnum, orig) \
809: void fname(INTERNAL_FUNCTION_PARAMETERS) { \
810: if (!PHAR_G(intercepted)) { \
811: PHAR_G(orig)(INTERNAL_FUNCTION_PARAM_PASSTHRU); \
812: } else { \
813: char *filename; \
814: int filename_len; \
815: \
816: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &filename, &filename_len) == FAILURE) { \
817: return; \
818: } \
819: \
820: phar_file_stat(filename, (php_stat_len) filename_len, funcnum, PHAR_G(orig), INTERNAL_FUNCTION_PARAM_PASSTHRU); \
821: } \
822: }
823: /* }}} */
824:
825: /* {{{ proto int fileperms(string filename)
826: Get file permissions */
827: PharFileFunction(phar_fileperms, FS_PERMS, orig_fileperms)
828: /* }}} */
829:
830: /* {{{ proto int fileinode(string filename)
831: Get file inode */
832: PharFileFunction(phar_fileinode, FS_INODE, orig_fileinode)
833: /* }}} */
834:
835: /* {{{ proto int filesize(string filename)
836: Get file size */
837: PharFileFunction(phar_filesize, FS_SIZE, orig_filesize)
838: /* }}} */
839:
840: /* {{{ proto int fileowner(string filename)
841: Get file owner */
842: PharFileFunction(phar_fileowner, FS_OWNER, orig_fileowner)
843: /* }}} */
844:
845: /* {{{ proto int filegroup(string filename)
846: Get file group */
847: PharFileFunction(phar_filegroup, FS_GROUP, orig_filegroup)
848: /* }}} */
849:
850: /* {{{ proto int fileatime(string filename)
851: Get last access time of file */
852: PharFileFunction(phar_fileatime, FS_ATIME, orig_fileatime)
853: /* }}} */
854:
855: /* {{{ proto int filemtime(string filename)
856: Get last modification time of file */
857: PharFileFunction(phar_filemtime, FS_MTIME, orig_filemtime)
858: /* }}} */
859:
860: /* {{{ proto int filectime(string filename)
861: Get inode modification time of file */
862: PharFileFunction(phar_filectime, FS_CTIME, orig_filectime)
863: /* }}} */
864:
865: /* {{{ proto string filetype(string filename)
866: Get file type */
867: PharFileFunction(phar_filetype, FS_TYPE, orig_filetype)
868: /* }}} */
869:
870: /* {{{ proto bool is_writable(string filename)
871: Returns true if file can be written */
872: PharFileFunction(phar_is_writable, FS_IS_W, orig_is_writable)
873: /* }}} */
874:
875: /* {{{ proto bool is_readable(string filename)
876: Returns true if file can be read */
877: PharFileFunction(phar_is_readable, FS_IS_R, orig_is_readable)
878: /* }}} */
879:
880: /* {{{ proto bool is_executable(string filename)
881: Returns true if file is executable */
882: PharFileFunction(phar_is_executable, FS_IS_X, orig_is_executable)
883: /* }}} */
884:
885: /* {{{ proto bool file_exists(string filename)
886: Returns true if filename exists */
887: PharFileFunction(phar_file_exists, FS_EXISTS, orig_file_exists)
888: /* }}} */
889:
890: /* {{{ proto bool is_dir(string filename)
891: Returns true if file is directory */
892: PharFileFunction(phar_is_dir, FS_IS_DIR, orig_is_dir)
893: /* }}} */
894:
895: PHAR_FUNC(phar_is_file) /* {{{ */
896: {
897: char *filename;
898: int filename_len;
899:
900: if (!PHAR_G(intercepted)) {
901: goto skip_phar;
902: }
903:
904: if ((PHAR_GLOBALS->phar_fname_map.arBuckets && !zend_hash_num_elements(&(PHAR_GLOBALS->phar_fname_map)))
905: && !cached_phars.arBuckets) {
906: goto skip_phar;
907: }
908: if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "s", &filename, &filename_len) == FAILURE) {
909: goto skip_phar;
910: }
911: if (!IS_ABSOLUTE_PATH(filename, filename_len) && !strstr(filename, "://")) {
912: char *arch, *entry, *fname;
913: int arch_len, entry_len, fname_len;
914: fname = zend_get_executed_filename(TSRMLS_C);
915:
916: /* we are checking for existence of a file within the relative path. Chances are good that this is
917: retrieving something from within the phar archive */
918:
919: if (strncasecmp(fname, "phar://", 7)) {
920: goto skip_phar;
921: }
922: fname_len = strlen(fname);
923: if (SUCCESS == phar_split_fname(fname, fname_len, &arch, &arch_len, &entry, &entry_len, 2, 0 TSRMLS_CC)) {
924: phar_archive_data *phar;
925:
926: efree(entry);
927: entry = filename;
928: /* fopen within phar, if :// is not in the url, then prepend phar://<archive>/ */
929: entry_len = filename_len;
930: /* retrieving a file within the current directory, so use this if possible */
931: if (SUCCESS == phar_get_archive(&phar, arch, arch_len, NULL, 0, NULL TSRMLS_CC)) {
932: phar_entry_info *etemp;
933:
934: entry = phar_fix_filepath(estrndup(entry, entry_len), &entry_len, 1 TSRMLS_CC);
935: if (entry[0] == '/') {
936: if (SUCCESS == zend_hash_find(&(phar->manifest), entry + 1, entry_len - 1, (void **) &etemp)) {
937: /* this file is not in the current directory, use the original path */
938: found_it:
939: efree(entry);
940: efree(arch);
941: RETURN_BOOL(!etemp->is_dir);
942: }
943: } else {
944: if (SUCCESS == zend_hash_find(&(phar->manifest), entry, entry_len, (void **) &etemp)) {
945: goto found_it;
946: }
947: }
948: }
949: if (entry != filename) {
950: efree(entry);
951: }
952: efree(arch);
953: RETURN_FALSE;
954: }
955: }
956: skip_phar:
957: PHAR_G(orig_is_file)(INTERNAL_FUNCTION_PARAM_PASSTHRU);
958: return;
959: }
960: /* }}} */
961:
962: PHAR_FUNC(phar_is_link) /* {{{ */
963: {
964: char *filename;
965: int filename_len;
966:
967: if (!PHAR_G(intercepted)) {
968: goto skip_phar;
969: }
970:
971: if ((PHAR_GLOBALS->phar_fname_map.arBuckets && !zend_hash_num_elements(&(PHAR_GLOBALS->phar_fname_map)))
972: && !cached_phars.arBuckets) {
973: goto skip_phar;
974: }
975: if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "s", &filename, &filename_len) == FAILURE) {
976: goto skip_phar;
977: }
978: if (!IS_ABSOLUTE_PATH(filename, filename_len) && !strstr(filename, "://")) {
979: char *arch, *entry, *fname;
980: int arch_len, entry_len, fname_len;
981: fname = zend_get_executed_filename(TSRMLS_C);
982:
983: /* we are checking for existence of a file within the relative path. Chances are good that this is
984: retrieving something from within the phar archive */
985:
986: if (strncasecmp(fname, "phar://", 7)) {
987: goto skip_phar;
988: }
989: fname_len = strlen(fname);
990: if (SUCCESS == phar_split_fname(fname, fname_len, &arch, &arch_len, &entry, &entry_len, 2, 0 TSRMLS_CC)) {
991: phar_archive_data *phar;
992:
993: efree(entry);
994: entry = filename;
995: /* fopen within phar, if :// is not in the url, then prepend phar://<archive>/ */
996: entry_len = filename_len;
997: /* retrieving a file within the current directory, so use this if possible */
998: if (SUCCESS == phar_get_archive(&phar, arch, arch_len, NULL, 0, NULL TSRMLS_CC)) {
999: phar_entry_info *etemp;
1000:
1001: entry = phar_fix_filepath(estrndup(entry, entry_len), &entry_len, 1 TSRMLS_CC);
1002: if (entry[0] == '/') {
1003: if (SUCCESS == zend_hash_find(&(phar->manifest), entry + 1, entry_len - 1, (void **) &etemp)) {
1004: /* this file is not in the current directory, use the original path */
1005: found_it:
1006: efree(entry);
1007: efree(arch);
1008: RETURN_BOOL(etemp->link);
1009: }
1010: } else {
1011: if (SUCCESS == zend_hash_find(&(phar->manifest), entry, entry_len, (void **) &etemp)) {
1012: goto found_it;
1013: }
1014: }
1015: }
1016: efree(entry);
1017: efree(arch);
1018: RETURN_FALSE;
1019: }
1020: }
1021: skip_phar:
1022: PHAR_G(orig_is_link)(INTERNAL_FUNCTION_PARAM_PASSTHRU);
1023: return;
1024: }
1025: /* }}} */
1026:
1027: /* {{{ proto array lstat(string filename)
1028: Give information about a file or symbolic link */
1029: PharFileFunction(phar_lstat, FS_LSTAT, orig_lstat)
1030: /* }}} */
1031:
1032: /* {{{ proto array stat(string filename)
1033: Give information about a file */
1034: PharFileFunction(phar_stat, FS_STAT, orig_stat)
1035: /* }}} */
1036:
1037: /* {{{ void phar_intercept_functions(TSRMLS_D) */
1038: void phar_intercept_functions(TSRMLS_D)
1039: {
1040: if (!PHAR_G(request_init)) {
1041: PHAR_G(cwd) = NULL;
1042: PHAR_G(cwd_len) = 0;
1043: }
1044: PHAR_G(intercepted) = 1;
1045: }
1046: /* }}} */
1047:
1048: /* {{{ void phar_release_functions(TSRMLS_D) */
1049: void phar_release_functions(TSRMLS_D)
1050: {
1051: PHAR_G(intercepted) = 0;
1052: }
1053: /* }}} */
1054:
1055: /* {{{ void phar_intercept_functions_init(TSRMLS_D) */
1056: #define PHAR_INTERCEPT(func) \
1057: PHAR_G(orig_##func) = NULL; \
1058: if (SUCCESS == zend_hash_find(CG(function_table), #func, sizeof(#func), (void **)&orig)) { \
1059: PHAR_G(orig_##func) = orig->internal_function.handler; \
1060: orig->internal_function.handler = phar_##func; \
1061: }
1062:
1063: void phar_intercept_functions_init(TSRMLS_D)
1064: {
1065: zend_function *orig;
1066:
1067: PHAR_INTERCEPT(fopen);
1068: PHAR_INTERCEPT(file_get_contents);
1069: PHAR_INTERCEPT(is_file);
1070: PHAR_INTERCEPT(is_link);
1071: PHAR_INTERCEPT(is_dir);
1072: PHAR_INTERCEPT(opendir);
1073: PHAR_INTERCEPT(file_exists);
1074: PHAR_INTERCEPT(fileperms);
1075: PHAR_INTERCEPT(fileinode);
1076: PHAR_INTERCEPT(filesize);
1077: PHAR_INTERCEPT(fileowner);
1078: PHAR_INTERCEPT(filegroup);
1079: PHAR_INTERCEPT(fileatime);
1080: PHAR_INTERCEPT(filemtime);
1081: PHAR_INTERCEPT(filectime);
1082: PHAR_INTERCEPT(filetype);
1083: PHAR_INTERCEPT(is_writable);
1084: PHAR_INTERCEPT(is_readable);
1085: PHAR_INTERCEPT(is_executable);
1086: PHAR_INTERCEPT(lstat);
1087: PHAR_INTERCEPT(stat);
1088: PHAR_INTERCEPT(readfile);
1089: PHAR_G(intercepted) = 0;
1090: }
1091: /* }}} */
1092:
1093: /* {{{ void phar_intercept_functions_shutdown(TSRMLS_D) */
1094: #define PHAR_RELEASE(func) \
1095: if (PHAR_G(orig_##func) && SUCCESS == zend_hash_find(CG(function_table), #func, sizeof(#func), (void **)&orig)) { \
1096: orig->internal_function.handler = PHAR_G(orig_##func); \
1097: } \
1098: PHAR_G(orig_##func) = NULL;
1099:
1100: void phar_intercept_functions_shutdown(TSRMLS_D)
1101: {
1102: zend_function *orig;
1103:
1104: PHAR_RELEASE(fopen);
1105: PHAR_RELEASE(file_get_contents);
1106: PHAR_RELEASE(is_file);
1107: PHAR_RELEASE(is_dir);
1108: PHAR_RELEASE(opendir);
1109: PHAR_RELEASE(file_exists);
1110: PHAR_RELEASE(fileperms);
1111: PHAR_RELEASE(fileinode);
1112: PHAR_RELEASE(filesize);
1113: PHAR_RELEASE(fileowner);
1114: PHAR_RELEASE(filegroup);
1115: PHAR_RELEASE(fileatime);
1116: PHAR_RELEASE(filemtime);
1117: PHAR_RELEASE(filectime);
1118: PHAR_RELEASE(filetype);
1119: PHAR_RELEASE(is_writable);
1120: PHAR_RELEASE(is_readable);
1121: PHAR_RELEASE(is_executable);
1122: PHAR_RELEASE(lstat);
1123: PHAR_RELEASE(stat);
1124: PHAR_RELEASE(readfile);
1125: PHAR_G(intercepted) = 0;
1126: }
1127: /* }}} */
1128:
1129: static struct _phar_orig_functions {
1130: void (*orig_fopen)(INTERNAL_FUNCTION_PARAMETERS);
1131: void (*orig_file_get_contents)(INTERNAL_FUNCTION_PARAMETERS);
1132: void (*orig_is_file)(INTERNAL_FUNCTION_PARAMETERS);
1133: void (*orig_is_link)(INTERNAL_FUNCTION_PARAMETERS);
1134: void (*orig_is_dir)(INTERNAL_FUNCTION_PARAMETERS);
1135: void (*orig_opendir)(INTERNAL_FUNCTION_PARAMETERS);
1136: void (*orig_file_exists)(INTERNAL_FUNCTION_PARAMETERS);
1137: void (*orig_fileperms)(INTERNAL_FUNCTION_PARAMETERS);
1138: void (*orig_fileinode)(INTERNAL_FUNCTION_PARAMETERS);
1139: void (*orig_filesize)(INTERNAL_FUNCTION_PARAMETERS);
1140: void (*orig_fileowner)(INTERNAL_FUNCTION_PARAMETERS);
1141: void (*orig_filegroup)(INTERNAL_FUNCTION_PARAMETERS);
1142: void (*orig_fileatime)(INTERNAL_FUNCTION_PARAMETERS);
1143: void (*orig_filemtime)(INTERNAL_FUNCTION_PARAMETERS);
1144: void (*orig_filectime)(INTERNAL_FUNCTION_PARAMETERS);
1145: void (*orig_filetype)(INTERNAL_FUNCTION_PARAMETERS);
1146: void (*orig_is_writable)(INTERNAL_FUNCTION_PARAMETERS);
1147: void (*orig_is_readable)(INTERNAL_FUNCTION_PARAMETERS);
1148: void (*orig_is_executable)(INTERNAL_FUNCTION_PARAMETERS);
1149: void (*orig_lstat)(INTERNAL_FUNCTION_PARAMETERS);
1150: void (*orig_readfile)(INTERNAL_FUNCTION_PARAMETERS);
1151: void (*orig_stat)(INTERNAL_FUNCTION_PARAMETERS);
1152: } phar_orig_functions = {NULL};
1153:
1154: void phar_save_orig_functions(TSRMLS_D) /* {{{ */
1155: {
1156: phar_orig_functions.orig_fopen = PHAR_G(orig_fopen);
1157: phar_orig_functions.orig_file_get_contents = PHAR_G(orig_file_get_contents);
1158: phar_orig_functions.orig_is_file = PHAR_G(orig_is_file);
1159: phar_orig_functions.orig_is_link = PHAR_G(orig_is_link);
1160: phar_orig_functions.orig_is_dir = PHAR_G(orig_is_dir);
1161: phar_orig_functions.orig_opendir = PHAR_G(orig_opendir);
1162: phar_orig_functions.orig_file_exists = PHAR_G(orig_file_exists);
1163: phar_orig_functions.orig_fileperms = PHAR_G(orig_fileperms);
1164: phar_orig_functions.orig_fileinode = PHAR_G(orig_fileinode);
1165: phar_orig_functions.orig_filesize = PHAR_G(orig_filesize);
1166: phar_orig_functions.orig_fileowner = PHAR_G(orig_fileowner);
1167: phar_orig_functions.orig_filegroup = PHAR_G(orig_filegroup);
1168: phar_orig_functions.orig_fileatime = PHAR_G(orig_fileatime);
1169: phar_orig_functions.orig_filemtime = PHAR_G(orig_filemtime);
1170: phar_orig_functions.orig_filectime = PHAR_G(orig_filectime);
1171: phar_orig_functions.orig_filetype = PHAR_G(orig_filetype);
1172: phar_orig_functions.orig_is_writable = PHAR_G(orig_is_writable);
1173: phar_orig_functions.orig_is_readable = PHAR_G(orig_is_readable);
1174: phar_orig_functions.orig_is_executable = PHAR_G(orig_is_executable);
1175: phar_orig_functions.orig_lstat = PHAR_G(orig_lstat);
1176: phar_orig_functions.orig_readfile = PHAR_G(orig_readfile);
1177: phar_orig_functions.orig_stat = PHAR_G(orig_stat);
1178: }
1179: /* }}} */
1180:
1181: void phar_restore_orig_functions(TSRMLS_D) /* {{{ */
1182: {
1183: PHAR_G(orig_fopen) = phar_orig_functions.orig_fopen;
1184: PHAR_G(orig_file_get_contents) = phar_orig_functions.orig_file_get_contents;
1185: PHAR_G(orig_is_file) = phar_orig_functions.orig_is_file;
1186: PHAR_G(orig_is_link) = phar_orig_functions.orig_is_link;
1187: PHAR_G(orig_is_dir) = phar_orig_functions.orig_is_dir;
1188: PHAR_G(orig_opendir) = phar_orig_functions.orig_opendir;
1189: PHAR_G(orig_file_exists) = phar_orig_functions.orig_file_exists;
1190: PHAR_G(orig_fileperms) = phar_orig_functions.orig_fileperms;
1191: PHAR_G(orig_fileinode) = phar_orig_functions.orig_fileinode;
1192: PHAR_G(orig_filesize) = phar_orig_functions.orig_filesize;
1193: PHAR_G(orig_fileowner) = phar_orig_functions.orig_fileowner;
1194: PHAR_G(orig_filegroup) = phar_orig_functions.orig_filegroup;
1195: PHAR_G(orig_fileatime) = phar_orig_functions.orig_fileatime;
1196: PHAR_G(orig_filemtime) = phar_orig_functions.orig_filemtime;
1197: PHAR_G(orig_filectime) = phar_orig_functions.orig_filectime;
1198: PHAR_G(orig_filetype) = phar_orig_functions.orig_filetype;
1199: PHAR_G(orig_is_writable) = phar_orig_functions.orig_is_writable;
1200: PHAR_G(orig_is_readable) = phar_orig_functions.orig_is_readable;
1201: PHAR_G(orig_is_executable) = phar_orig_functions.orig_is_executable;
1202: PHAR_G(orig_lstat) = phar_orig_functions.orig_lstat;
1203: PHAR_G(orig_readfile) = phar_orig_functions.orig_readfile;
1204: PHAR_G(orig_stat) = phar_orig_functions.orig_stat;
1205: }
1206: /* }}} */
1207:
1208: /*
1209: * Local variables:
1210: * tab-width: 4
1211: * c-basic-offset: 4
1212: * End:
1213: * vim600: noet sw=4 ts=4 fdm=marker
1214: * vim<600: noet sw=4 ts=4
1215: */
1216:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>