]> granicus.if.org Git - php/commitdiff
add Phar::mount() to manually mount a file or directory
authorGreg Beaver <cellog@php.net>
Mon, 18 Feb 2008 04:32:50 +0000 (04:32 +0000)
committerGreg Beaver <cellog@php.net>
Mon, 18 Feb 2008 04:32:50 +0000 (04:32 +0000)
# TODO: implement directory mounting.  Involves scanning paths that are not exact matches for a partial match.
# this also means maintaining a per-phar hash of mounted directories for quick matching

ext/phar/phar.c
ext/phar/phar_internal.h
ext/phar/phar_object.c
ext/phar/util.c

index d86856f9a992356ffb51c02dd53cc1af6f1a4feb..46177a0a8096d26dd05f1bb06c11fb1c921712ad 100644 (file)
@@ -2568,7 +2568,7 @@ int phar_zend_open(const char *filename, zend_file_handle *handle TSRMLS_DC) /*
                                        if (!(entry = phar_find_in_include_path(entry, old, *pphar TSRMLS_CC))) {
                                                /* this file is not in the phar, use the original path */
                                                if (SUCCESS == phar_orig_zend_open(filename, handle TSRMLS_CC)) {
-                                                       if (filename[0] != '.' && SUCCESS == phar_mount_entry(*pphar, handle->opened_path ? handle->opened_path : filename, strlen(handle->opened_path ? handle->opened_path : filename), filename, strlen(filename), 0)) {
+                                                       if (SUCCESS == phar_mount_entry(*pphar, handle->opened_path ? handle->opened_path : (char *) filename, strlen(handle->opened_path ? handle->opened_path : filename), (char *) filename, strlen(filename))) {
                                                                entry = (char *) filename;
                                                                goto dopharthing;
                                                        }
index e25640204904a205c5757f75117d5ebcf8ac29cc..5679b140f256c9db0b791b8b64b4e260ca8b017a 100755 (executable)
@@ -372,6 +372,7 @@ char *phar_create_default_stub(const char *index_php, const char *web_index, siz
 char * phar_decompress_filter(phar_entry_info * entry, int return_unknown);
 char * phar_compress_filter(phar_entry_info * entry, int return_unknown);
 
+int phar_mount_entry(phar_archive_data *phar, char *filename, int filename_len, char *path, int path_len TSRMLS_DC);
 char *phar_find_in_include_path(char *file, char *entry, phar_archive_data *phar TSRMLS_DC);
 char *phar_fix_filepath(char *path, int *new_len, int use_cwd TSRMLS_DC);
 phar_entry_info * phar_open_jit(phar_archive_data *phar, phar_entry_info *entry, php_stream *fp,
index 3f91ab47cbd0d3eda3351c615a78458e6824d154..efb2f2f57f653db2e70543cda6619ae863c854e7 100755 (executable)
@@ -414,6 +414,38 @@ static void phar_postprocess_ru_web(char *fname, int fname_len, char **entry, in
 }
 /* }}} */
 
+/* {{{ proto void Phar::mount(string pharpath, string externalfile)
+ * mount an external file or path to a location within the phar.  This maps
+ * an external file or directory to a location within the phar archive, allowing
+ * reference to an external location as if it were within the phar archive.  This
+ * is useful for writable temp files like databases
+ */
+PHP_METHOD(Phar, mount)
+{
+       char *fname, *arch, *entry, *path, *actual;
+       int fname_len, arch_len, entry_len, path_len, actual_len;
+
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &path, &path_len, &actual, &actual_len) == FAILURE) {
+               return;
+       }
+
+       fname = zend_get_executed_filename(TSRMLS_C);
+       fname_len = strlen(fname);
+
+       if (SUCCESS == phar_split_fname(fname, fname_len, &arch, &arch_len, &entry, &entry_len TSRMLS_CC)) {
+               phar_archive_data **pphar;
+               if (SUCCESS != zend_hash_find(&(PHAR_GLOBALS->phar_fname_map), arch, arch_len, (void **)&pphar)) {
+                       /* TODO: throw exception */
+                       return;
+               }
+               if (SUCCESS != phar_mount_entry(*pphar, actual, actual_len, path, path_len TSRMLS_CC)) {
+                       /* TODO: throw exception */
+                       return;
+               }
+       }
+}
+/* }}} */
+
 /* {{{ proto void Phar::webPhar([string alias, [string index, [string f404, [array mimetypes, [callback rewrites]]]]])
  * mapPhar for web-based phars. Reads the currently executed file (a phar)
  * and registers its manifest. When executed in the CLI or CGI command-line sapi,
@@ -3423,6 +3455,12 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_phar_copy, 0, 0, 2)
        ZEND_ARG_INFO(0, oldfile)
 ZEND_END_ARG_INFO();
 
+static
+ZEND_BEGIN_ARG_INFO_EX(arginfo_phar_mount, 0, 0, 2)
+       ZEND_ARG_INFO(0, inphar)
+       ZEND_ARG_INFO(0, externalfile)
+ZEND_END_ARG_INFO();
+
 static
 ZEND_BEGIN_ARG_INFO_EX(arginfo_phar_conv, 0, 0, 0)
        ZEND_ARG_INFO(0, compression)
@@ -3480,6 +3518,7 @@ zend_function_entry php_archive_methods[] = {
        PHP_ME(Phar, loadPhar,              arginfo_phar_loadPhar,     ZEND_ACC_PUBLIC|ZEND_ACC_STATIC|ZEND_ACC_FINAL)
        PHP_ME(Phar, mapPhar,               arginfo_phar_mapPhar,      ZEND_ACC_PUBLIC|ZEND_ACC_STATIC|ZEND_ACC_FINAL)
        PHP_ME(Phar, webPhar,               arginfo_phar_webPhar,      ZEND_ACC_PUBLIC|ZEND_ACC_STATIC|ZEND_ACC_FINAL)
+       PHP_ME(Phar, mount,                 arginfo_phar_mount,        ZEND_ACC_PUBLIC|ZEND_ACC_STATIC|ZEND_ACC_FINAL)
        PHP_ME(Phar, mungServer,            arginfo_phar_mungServer,   ZEND_ACC_PUBLIC|ZEND_ACC_STATIC|ZEND_ACC_FINAL)
        PHP_ME(Phar, interceptFileFuncs,    NULL,                      ZEND_ACC_PUBLIC|ZEND_ACC_STATIC|ZEND_ACC_FINAL)
        PHP_ME(Phar, getExtractList,        NULL,                      ZEND_ACC_PUBLIC|ZEND_ACC_STATIC|ZEND_ACC_FINAL)
index 809835832ef3df3cf202858e9cdb06ed7775e2cb..f537601025e7ef82751624f386b2546e873bb42e 100644 (file)
@@ -75,10 +75,16 @@ int phar_seek_efp(phar_entry_info *entry, off_t offset, int whence, off_t positi
 }
 
 /* mount an absolute path or uri to a path internal to the phar archive */
-int phar_mount_entry(phar_archive_data *phar, char *filename, int filename_len, char *path, int path_len, int is_dir TSRMLS_DC)
+int phar_mount_entry(phar_archive_data *phar, char *filename, int filename_len, char *path, int path_len TSRMLS_DC)
 {
        phar_entry_info entry = {0};
        php_stream_statbuf ssb;
+       const char *err;
+       int is_dir;
+
+       if (phar_path_check(&path, &path_len, &err) > pcr_is_ok) {
+               return FAILURE;
+       }
 
 #if PHP_MAJOR_VERSION < 6
        if (PG(safe_mode) && (!php_checkuid(filename, NULL, CHECKUID_ALLOW_ONLY_FILE))) {
@@ -98,13 +104,13 @@ int phar_mount_entry(phar_archive_data *phar, char *filename, int filename_len,
        entry.is_mounted = 1;
        entry.is_crc_checked = 1;
        entry.fp_type = PHAR_TMP;
-       entry.is_dir = is_dir;
 
        if (SUCCESS != php_stream_stat_path(entry.link, &ssb)) {
                efree(entry.link);
                efree(entry.filename);
                return FAILURE;
        }
+       entry.is_dir = ssb.sb.st_mode & S_IFDIR ? 1 : 0;
        entry.uncompressed_filesize = entry.compressed_filesize = ssb.sb.st_size;
        entry.flags = ssb.sb.st_mode;
        if (SUCCESS == zend_hash_add(&phar->manifest, path, path_len, (void*)&entry, sizeof(phar_entry_info), NULL)) {