return buf;
}
+CWD_API char *virtual_link(char *buf, size_t size TSRMLS_DC)
+{
+ size_t length;
+ char *p;
+ char tmp_path[MAXPATHLEN * 2];
+ char resolved_path[MAXPATHLEN];
+
+ if (IS_ABSOLUTE_PATH(buf, size)) {
+ memcpy(resolved_path, buf, size);
+ p[size] = '\0';
+ return resolved_path;
+ } else {
+ virtual_getcwd(tmp_path, MAXPATHLEN TSRMLS_CC);
+ p = tmp_path + strlen(tmp_path);
+ *p++ = '/';
+ memcpy(p, buf, size);
+ *(p + size) = '\0';
+
+ return tmp_path;
+ }
+}
+
/* Resolve path relatively to state and put the real path into state */
/* returns 0 for ok, 1 for error */
CWD_API int virtual_file_ex(cwd_state *state, const char *path, verify_path_func verify_path)
{
cwd_state new_state;
int retval;
+ char *p;
CWD_STATE_COPY(&new_state, &CWDG(cwd));
- virtual_file_ex(&new_state, path, NULL);
+ /* virtual_file_ex(&new_state, path, NULL); */
+ p = virtual_link(path, strlen(path) TSRMLS_CC);
- retval = lstat(new_state.cwd, buf);
+ retval = lstat(p, buf);
CWD_STATE_FREE(&new_state);
return retval;
#endif
#if !defined(TSRM_WIN32) && !defined(NETWARE)
CWD_API int virtual_lstat(const char *path, struct stat *buf TSRMLS_DC);
+CWD_API char *virtual_link(char *buf, size_t size TSRMLS_DC);
#endif
CWD_API int virtual_unlink(const char *path TSRMLS_DC);
CWD_API int virtual_mkdir(const char *pathname, mode_t mode TSRMLS_DC);
#define VCWD_RENAME(oldname, newname) virtual_rename(oldname, newname TSRMLS_CC)
#define VCWD_STAT(path, buff) virtual_stat(path, buff TSRMLS_CC)
#if !defined(TSRM_WIN32) && !defined(NETWARE)
-#define VCWD_LSTAT(path, buff) virtual_stat(path, buff TSRMLS_CC)
+#define VCWD_LSTAT(path, buff) virtual_lstat(path, buff TSRMLS_CC)
#else
#define VCWD_LSTAT(path, buff) virtual_lstat(path, buff TSRMLS_CC)
#endif
PHP_FUNCTION(readlink)
{
zval **filename;
- char buff[256];
+ char buff[MAXPATHLEN];
+ char *p;
int ret;
-
+
if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &filename) == FAILURE) {
WRONG_PARAM_COUNT;
}
convert_to_string_ex(filename);
- ret = readlink(Z_STRVAL_PP(filename), buff, 255);
+ p = virtual_link(Z_STRVAL_PP(filename), Z_STRLEN_PP(filename) TSRMLS_CC);
+
+ ret = readlink(p, buff, MAXPATHLEN-1);
if (ret == -1) {
php_error(E_WARNING, "readlink failed (%s)", strerror(errno));
RETURN_FALSE;
}
/* Append NULL to the end of the string */
buff[ret] = '\0';
+
RETURN_STRING(buff, 1);
}
/* }}} */
{
zval **topath, **frompath;
int ret;
+ char source_p[MAXPATHLEN];
+ char dest_p[MAXPATHLEN];
if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &topath, &frompath) == FAILURE) {
WRONG_PARAM_COUNT;
convert_to_string_ex(topath);
convert_to_string_ex(frompath);
- if (PG(safe_mode) && !php_checkuid(Z_STRVAL_PP(topath), NULL, CHECKUID_CHECK_FILE_AND_DIR)) {
- RETURN_FALSE;
+ expand_filepath(Z_STRVAL_PP(frompath), source_p TSRMLS_CC);
+ expand_filepath(Z_STRVAL_PP(topath), dest_p TSRMLS_CC);
+
+ if (php_stream_locate_url_wrapper(source_p, NULL, STREAM_LOCATE_WRAPPERS_ONLY TSRMLS_CC) ||
+ php_stream_locate_url_wrapper(dest_p, NULL, STREAM_LOCATE_WRAPPERS_ONLY TSRMLS_CC) )
+ {
+ php_error(E_WARNING, "Unable to symlink to a URL");
+ RETURN_FALSE;
}
- if (PG(safe_mode) && !php_checkuid(Z_STRVAL_PP(frompath), NULL, CHECKUID_CHECK_FILE_AND_DIR)) {
+ if (PG(safe_mode) && !php_checkuid(dest_p, NULL, CHECKUID_CHECK_FILE_AND_DIR)) {
RETURN_FALSE;
}
- if (php_check_open_basedir(Z_STRVAL_PP(topath) TSRMLS_CC)) {
+ if (PG(safe_mode) && !php_checkuid(source_p, NULL, CHECKUID_CHECK_FILE_AND_DIR)) {
RETURN_FALSE;
}
- if (php_check_open_basedir(Z_STRVAL_PP(frompath) TSRMLS_CC)) {
+ if (php_check_open_basedir(dest_p TSRMLS_CC)) {
RETURN_FALSE;
}
- if (!strncasecmp(Z_STRVAL_PP(topath), "http://", 7) || !strncasecmp(Z_STRVAL_PP(topath), "ftp://", 6)) {
- php_error(E_WARNING, "Unable to symlink to a URL");
+ if (php_check_open_basedir(source_p TSRMLS_CC)) {
RETURN_FALSE;
}
- ret = symlink(Z_STRVAL_PP(topath), Z_STRVAL_PP(frompath));
+ ret = symlink(dest_p, source_p);
if (ret == -1) {
php_error(E_WARNING, "Symlink failed (%s)", strerror(errno));
RETURN_FALSE;
{
zval **topath, **frompath;
int ret;
+ char source_p[MAXPATHLEN];
+ char dest_p[MAXPATHLEN];
if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &topath, &frompath) == FAILURE) {
WRONG_PARAM_COUNT;
convert_to_string_ex(topath);
convert_to_string_ex(frompath);
- if (PG(safe_mode) && !php_checkuid(Z_STRVAL_PP(topath), NULL, CHECKUID_CHECK_FILE_AND_DIR)) {
- RETURN_FALSE;
+ expand_filepath(Z_STRVAL_PP(frompath), source_p TSRMLS_CC);
+ expand_filepath(Z_STRVAL_PP(topath), dest_p TSRMLS_CC);
+
+ if (php_stream_locate_url_wrapper(source_p, NULL, STREAM_LOCATE_WRAPPERS_ONLY TSRMLS_CC) ||
+ php_stream_locate_url_wrapper(dest_p, NULL, STREAM_LOCATE_WRAPPERS_ONLY TSRMLS_CC) )
+ {
+ php_error(E_WARNING, "Unable to link to a URL");
+ RETURN_FALSE;
}
- if (PG(safe_mode) && !php_checkuid(Z_STRVAL_PP(frompath), NULL, CHECKUID_CHECK_FILE_AND_DIR)) {
+ if (PG(safe_mode) && !php_checkuid(dest_p, NULL, CHECKUID_CHECK_FILE_AND_DIR)) {
RETURN_FALSE;
}
- if (php_check_open_basedir(Z_STRVAL_PP(topath) TSRMLS_CC)) {
+ if (PG(safe_mode) && !php_checkuid(source_p, NULL, CHECKUID_CHECK_FILE_AND_DIR)) {
RETURN_FALSE;
}
- if (php_check_open_basedir(Z_STRVAL_PP(frompath) TSRMLS_CC)) {
+ if (php_check_open_basedir(dest_p TSRMLS_CC)) {
RETURN_FALSE;
}
- if (!strncasecmp(Z_STRVAL_PP(topath), "http://", 7) || !strncasecmp(Z_STRVAL_PP(topath), "ftp://", 6)) {
- php_error(E_WARNING, "Unable to link to a URL");
+ if (php_check_open_basedir(source_p TSRMLS_CC)) {
RETURN_FALSE;
}
- ret = link(Z_STRVAL_PP(topath), Z_STRVAL_PP(frompath));
+ ret = link(dest_p, source_p);
if (ret == -1) {
php_error(E_WARNING, "Link failed (%s)", strerror(errno));
RETURN_FALSE;