* Retrieve a copy of the file information on a single file within a phar, or null.
* This also transfers the open file pointer, if any, to the entry.
*/
-static int phar_get_entry_data(phar_entry_data **ret, char *fname, int fname_len, char *path, int path_len, char *mode TSRMLS_DC) /* {{{ */
+static int phar_get_entry_data(phar_entry_data **ret, char *fname, int fname_len, char *path, int path_len, char *mode, char **error TSRMLS_DC) /* {{{ */
{
phar_archive_data *phar;
phar_entry_info *entry;
return FAILURE;
}
*ret = NULL;
+ *error = (char *) emalloc(200 + fname_len);
+ **error = '\0';
if (for_write && PHAR_G(readonly)) {
- php_error_docref(NULL TSRMLS_CC, E_RECOVERABLE_ERROR, "phar error: file \"%s\" cannot opened for writing, disabled by ini setting", fname);
+ if (error) {
+ sprintf(*error, "phar error: file \"%s\" cannot opened for writing, disabled by ini setting", fname);
+ }
return FAILURE;
}
if ((phar = phar_get_archive(fname, fname_len, NULL, 0 TSRMLS_CC)) != NULL) {
if ((entry = phar_get_entry_info(phar, path, path_len TSRMLS_CC)) != NULL) {
if (entry->is_modified && !for_write) {
- php_error_docref(NULL TSRMLS_CC, E_RECOVERABLE_ERROR, "phar error: file \"%s\" cannot opened for reading, writable file pointers are open", fname);
+ if (error) {
+ sprintf(*error, "phar error: file \"%s\" cannot opened for reading, writable file pointers are open", fname);
+ }
return FAILURE;
}
if (entry->fp_refcount && for_write) {
- php_error_docref(NULL TSRMLS_CC, E_RECOVERABLE_ERROR, "phar error: file \"%s\" cannot opened for writing, readable file pointers are open", fname);
+ if (error) {
+ sprintf(*error, "phar error: file \"%s\" cannot opened for writing, readable file pointers are open", fname);
+ }
return FAILURE;
}
if (entry->is_deleted) {
/**
* Create a new dummy file slot within a writeable phar for a newly created file
*/
-phar_entry_data *phar_get_or_create_entry_data(char *fname, int fname_len, char *path, int path_len, char *mode TSRMLS_DC) /* {{{ */
+phar_entry_data *phar_get_or_create_entry_data(char *fname, int fname_len, char *path, int path_len, char *mode, char **error TSRMLS_DC) /* {{{ */
{
phar_archive_data *phar;
phar_entry_info *entry, etemp;
return NULL;
}
- if (FAILURE == phar_get_entry_data(&ret, fname, fname_len, path, path_len, mode TSRMLS_CC)) {
+ if (FAILURE == phar_get_entry_data(&ret, fname, fname_len, path, path_len, mode, error TSRMLS_CC)) {
return NULL;
}
if (ret) {
phar_entry_data *idata;
char *internal_file;
char *buffer;
+ char *error;
char *filter_name;
char tmpbuf[8];
php_url *resource = NULL;
/* strip leading "/" */
internal_file = estrdup(resource->path + 1);
if (mode[0] == 'w' || (mode[0] == 'r' && mode[1] == '+')) {
- if (NULL == (idata = phar_get_or_create_entry_data(resource->host, strlen(resource->host), internal_file, strlen(internal_file), mode TSRMLS_CC))) {
+ if (NULL == (idata = phar_get_or_create_entry_data(resource->host, strlen(resource->host), internal_file, strlen(internal_file), mode, &error TSRMLS_CC))) {
+ if (error[0]) {
+ php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, error);
+ }
+ efree(error);
php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "phar error: file \"%s\" could not be created in phar \"%s\"", internal_file, resource->host);
efree(internal_file);
php_url_free(resource);
return NULL;
}
+ efree(error);
fpf = php_stream_alloc(&phar_ops, idata, NULL, mode);
php_url_free(resource);
efree(internal_file);
}
return fpf;
} else {
- if ((FAILURE == phar_get_entry_data(&idata, resource->host, strlen(resource->host), internal_file, strlen(internal_file), "r" TSRMLS_CC)) || !idata) {
+ if ((FAILURE == phar_get_entry_data(&idata, resource->host, strlen(resource->host), internal_file, strlen(internal_file), "r", &error TSRMLS_CC)) || !idata) {
+ if (error[0]) {
+ php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, error);
+ }
+ efree(error);
php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "phar error: \"%s\" is not a file in phar \"%s\"", internal_file, resource->host);
efree(internal_file);
php_url_free(resource);
return NULL;
}
+ /* alloced in get_entry_data */
+ efree(error);
}
php_url_free(resource);
{
php_url *resource;
char *internal_file;
+ char *error;
phar_entry_data *idata;
resource = php_url_parse(url);
/* need to copy to strip leading "/", will get touched again */
internal_file = estrdup(resource->path + 1);
- if (FAILURE == phar_get_entry_data(&idata, resource->host, strlen(resource->host), internal_file, strlen(internal_file), "r" TSRMLS_CC)) {
+ if (FAILURE == phar_get_entry_data(&idata, resource->host, strlen(resource->host), internal_file, strlen(internal_file), "r", &error TSRMLS_CC)) {
/* constraints of fp refcount were not met */
+ if (error[0]) {
+ php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, error);
+ }
+ efree(error);
efree(internal_file);
php_url_free(resource);
return FAILURE;
}
+ efree(error);
if (!idata) {
php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "phar error: \"%s\" is not a file in phar \"%s\", cannot unlink", internal_file, resource->host);
efree(internal_file);
phar_entry_delref(idata TSRMLS_CC);
return FAILURE;
}
+ php_url_free(resource);
efree(internal_file);
phar_entry_remove(idata TSRMLS_CC);
return SUCCESS;
PHP_METHOD(Phar, offsetSet)
{
char *fname;
+ char *error;
int fname_len;
zval *contents;
long contents_len = PHP_STREAM_COPY_ALL;
if (Z_TYPE_P(contents) != IS_STRING && Z_TYPE_P(contents) != IS_RESOURCE) {
zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "Entry %s could not be written to", fname);
}
- if (!(data = phar_get_or_create_entry_data(phar_obj->arc.archive->fname, phar_obj->arc.archive->fname_len, fname, fname_len, "w+b" TSRMLS_CC))) {
- zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "Entry %s does not exist and cannot be created", fname);
+ if (!(data = phar_get_or_create_entry_data(phar_obj->arc.archive->fname, phar_obj->arc.archive->fname_len, fname, fname_len, "w+b", &error TSRMLS_CC))) {
+ zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "Entry %s does not exist and cannot be created: %s", fname, error);
+ efree(error);
} else {
+ efree(error);
if (Z_TYPE_P(contents) == IS_STRING) {
contents_len = php_stream_write(data->fp, Z_STRVAL_P(contents), Z_STRLEN_P(contents));
if (contents_len != Z_STRLEN_P(contents)) {