ssb->sb.st_mtime = data->timestamp;
ssb->sb.st_atime = data->timestamp;
ssb->sb.st_ctime = data->timestamp;
+#endif
+ } else if (!is_dir && data->is_dir && (data->is_tar || data->is_zip)) {
+ ssb->sb.st_size = 0;
+ ssb->sb.st_mode = data->flags & PHAR_ENT_PERM_MASK;
+ ssb->sb.st_mode |= S_IFDIR; /* regular directory */
+ /* timestamp is just the timestamp when this was added to the phar */
+#ifdef NETWARE
+ ssb->sb.st_mtime.tv_sec = data->timestamp;
+ ssb->sb.st_atime.tv_sec = data->timestamp;
+ ssb->sb.st_ctime.tv_sec = data->timestamp;
+#else
+ ssb->sb.st_mtime = data->timestamp;
+ ssb->sb.st_atime = data->timestamp;
+ ssb->sb.st_ctime = data->timestamp;
#endif
} else {
ssb->sb.st_size = 0;
char *fname = NULL;
int fname_len, failed;
zend_op_array *(*save)(zend_file_handle *file_handle, int type TSRMLS_DC);
+ phar_archive_data *phar;
save = zend_compile_file; /* restore current handler or we cause trouble */
zend_compile_file = phar_orig_compile_file;
fname = zend_get_executed_filename(TSRMLS_C);
fname_len = strlen(fname);
- if (fname_len == sizeof("[no active file]")-1 && !strncmp(fname, "[no active file]", fname_len)) {
- if (strstr(file_handle->filename, ".phar.zip") && !strstr(file_handle->filename, ":\\")) {
- /* zip-based phar */
- spprintf(&name, 4096, "phar://%s/%s", file_handle->filename, ".phar/stub.php");
- file_handle->type = ZEND_HANDLE_FILENAME;
- file_handle->free_filename = 1;
- file_handle->filename = name;
- if (file_handle->opened_path) {
- efree(file_handle->opened_path);
- }
- goto skip_phar;
- }
- if (strstr(file_handle->filename, ".phar.tar") && !strstr(file_handle->filename, ":\\")) {
- /* tar-based phar */
- spprintf(&name, 4096, "phar://%s/%s", file_handle->filename, ".phar/stub.php");
- file_handle->type = ZEND_HANDLE_FILENAME;
- file_handle->free_filename = 1;
- file_handle->filename = name;
- if (file_handle->opened_path) {
- efree(file_handle->opened_path);
+ if (strstr(file_handle->filename, ".phar") && !strstr(file_handle->filename, ":\\")) {
+ if (SUCCESS == phar_open_filename(file_handle->filename, strlen(file_handle->filename), NULL, 0, 0, &phar, NULL TSRMLS_CC)) {
+ if (phar->is_zip || phar->is_tar) {
+ /* zip-based phar */
+ spprintf(&name, 4096, "phar://%s/%s", file_handle->filename, ".phar/stub.php");
+ file_handle->type = ZEND_HANDLE_FILENAME;
+ file_handle->free_filename = 1;
+ file_handle->filename = name;
+ if (file_handle->opened_path) {
+ efree(file_handle->opened_path);
+ }
+ goto skip_phar;
}
- goto skip_phar;
}
}
if (zend_hash_num_elements(&(PHAR_GLOBALS->phar_fname_map))) {
if (strstr(fname, "://")) {
char *arch, *entry;
int arch_len, entry_len;
- phar_archive_data *phar;
+ phar_archive_data *mphar;
/* running within a zip-based phar, acquire the actual name */
if (SUCCESS != phar_split_fname(fname, fname_len, &arch, &arch_len, &entry, &entry_len TSRMLS_CC)) {
entry = fname;
fname = arch;
fname_len = arch_len;
- if (SUCCESS == phar_open_loaded(fname, fname_len, alias, alias_len, 0, &phar, 0 TSRMLS_CC) && phar && (phar->is_zip || phar->is_tar)) {
+ if (SUCCESS == phar_open_loaded(fname, fname_len, alias, alias_len, 0, &mphar, 0 TSRMLS_CC) && mphar && (phar->is_zip || phar->is_tar)) {
efree(arch);
- fname = phar->fname;
- fname_len = phar->fname_len;
+ fname = mphar->fname;
+ fname_len = mphar->fname_len;
} else {
efree(arch);
fname = entry;
/* check for "rewrite" urls */
if (SUCCESS == zend_hash_find(Z_ARRVAL_P(rewrites), entry, entry_len+1, (void **) &fd_ptr)) {
if (IS_STRING != Z_TYPE_PP(fd_ptr)) {
- phar_entry_delref(phar TSRMLS_CC);
#ifdef PHP_WIN32
efree(fname);
#endif
}
/* }}} */
+/* {{{ proto bool Phar::isTar()
+ * Returns true if the phar archive is based on the tar file format
+ */
+PHP_METHOD(Phar, isTar)
+{
+ PHAR_ARCHIVE_OBJECT();
+
+ RETURN_BOOL(phar_obj->arc.archive->is_tar);
+}
+/* }}} */
+
+/* {{{ proto bool Phar::isZip()
+ * Returns true if the phar archive is based on the Zip file format
+ */
+PHP_METHOD(Phar, isZip)
+{
+ PHAR_ARCHIVE_OBJECT();
+
+ RETURN_BOOL(phar_obj->arc.archive->is_zip);
+}
+/* }}} */
+
+/* {{{ proto bool Phar::isPhar()
+ * Returns true if the phar archive is based on the phar file format
+ */
+PHP_METHOD(Phar, isPhar)
+{
+ PHAR_ARCHIVE_OBJECT();
+
+ RETURN_BOOL(!phar_obj->arc.archive->is_tar && !phar_obj->arc.archive->is_zip);
+}
+/* }}} */
+
/* {{{ proto bool Phar::delete(string file)
* Delete a file from within the Phar
*/
{
PHAR_ENTRY_OBJECT();
- if (entry_obj->ent.entry->is_dir) {
- if (!entry_obj->ent.entry->is_zip && !entry_obj->ent.entry->is_tar && entry_obj->ent.entry->filename) {
+ if (entry_obj->ent.entry->is_dir&& !entry_obj->ent.entry->is_zip && !entry_obj->ent.entry->is_tar) {
+ if (entry_obj->ent.entry->filename) {
efree(entry_obj->ent.entry->filename);
entry_obj->ent.entry->filename = NULL;
}
long perms;
PHAR_ENTRY_OBJECT();
- if (entry_obj->ent.entry->is_dir) {
+ if (entry_obj->ent.entry->is_dir && (!entry_obj->ent.entry->is_tar && !entry_obj->ent.entry->is_zip)) {
zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, \
"Phar entry is a directory, cannot chmod"); \
}
PHP_ME(Phar, offsetUnset, arginfo_phar_offsetExists, ZEND_ACC_PUBLIC)
PHP_ME(Phar, uncompressAllFiles, NULL, ZEND_ACC_PUBLIC)
PHP_ME(Phar, buildFromIterator, arginfo_phar_build, ZEND_ACC_PUBLIC)
+ PHP_ME(Phar, isTar, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Phar, isZip, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(Phar, isPhar, NULL, ZEND_ACC_PUBLIC)
#endif
/* static member functions */
PHP_ME(Phar, apiVersion, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC|ZEND_ACC_FINAL)
int phar_open_or_create_tar(char *fname, int fname_len, char *alias, int alias_len, int options, phar_archive_data** pphar, char **error TSRMLS_DC) /* {{{ */
{
phar_archive_data *phar;
- int ret = phar_create_or_parse_filename(fname, fname_len, alias, alias_len, options, pphar, error TSRMLS_CC);
+ int ret = phar_create_or_parse_filename(fname, fname_len, alias, alias_len, options, &phar, error TSRMLS_CC);
+ if (pphar) {
+ *pphar = phar;
+ }
if (FAILURE == ret) {
return FAILURE;
}
- if ((*pphar)->is_tar) {
+ if (phar->is_tar) {
return ret;
}
-
- phar = *pphar;
if (phar->is_brandnew) {
phar->is_tar = 1;
+ phar->internal_file_start = 0;
return SUCCESS;
}
if (old && entry.tar_type == TAR_FILE && S_ISDIR(entry.flags)) {
entry.tar_type = TAR_DIR;
}
+ if (entry.tar_type == TAR_DIR) {
+ entry.is_dir = 1;
+ }
entry.link = NULL;
if (entry.tar_type == TAR_LINK) {
if (entry->fp) {
/* new file */
file = entry->fp;
- php_stream_seek(file, 0, SEEK_SET);
+ if (file == entry->phar->fp) {
+ php_stream_seek(file, entry->offset_within_phar, SEEK_SET);
+ } else {
+ php_stream_seek(file, 0, SEEK_SET);
+ }
} else {
file = fp->old;
php_stream_seek(file, entry->offset_within_phar, SEEK_SET);
memset(padding, 0, 512);
php_stream_write(fp->new, padding, ((entry->uncompressed_filesize +511)&~511) - entry->uncompressed_filesize);
- if (entry->fp) {
- php_stream_close(entry->fp);
- entry->fp = NULL;
+ entry->is_modified = 0;
+ if (entry->fp && entry->fp_refcount == 0) {
+ if (entry->fp != entry->phar->fp) {
+ php_stream_close(entry->fp);
+ entry->fp = NULL;
+ }
}
/* note new location within tar */
entry.is_modified = 1;
entry.is_tar = 1;
entry.tar_type = '0';
+ entry.phar = archive;
/* set alias */
if (archive->is_explicit_alias) {
entry.filename = estrndup(".phar/alias.txt", sizeof(".phar/alias.txt")-1);