Annotation of embedaddon/php/ext/standard/link.c, revision 1.1
1.1 ! misho 1: /*
! 2: +----------------------------------------------------------------------+
! 3: | PHP Version 5 |
! 4: +----------------------------------------------------------------------+
! 5: | Copyright (c) 1997-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: | Author: |
! 16: +----------------------------------------------------------------------+
! 17: */
! 18:
! 19: /* $Id: link.c 321634 2012-01-01 13:15:04Z felipe $ */
! 20:
! 21: #include "php.h"
! 22: #include "php_filestat.h"
! 23: #include "php_globals.h"
! 24:
! 25: #ifdef HAVE_SYMLINK
! 26:
! 27: #include <stdlib.h>
! 28: #if HAVE_UNISTD_H
! 29: #include <unistd.h>
! 30: #endif
! 31: #include <sys/stat.h>
! 32: #include <string.h>
! 33: #if HAVE_PWD_H
! 34: #ifdef PHP_WIN32
! 35: #include "win32/pwd.h"
! 36: #else
! 37: #include <pwd.h>
! 38: #endif
! 39: #endif
! 40: #if HAVE_GRP_H
! 41: #ifdef PHP_WIN32
! 42: #include "win32/grp.h"
! 43: #else
! 44: #include <grp.h>
! 45: #endif
! 46: #endif
! 47: #include <errno.h>
! 48: #include <ctype.h>
! 49:
! 50: #include "safe_mode.h"
! 51: #include "php_link.h"
! 52: #include "php_string.h"
! 53:
! 54: /* {{{ proto string readlink(string filename)
! 55: Return the target of a symbolic link */
! 56: PHP_FUNCTION(readlink)
! 57: {
! 58: char *link;
! 59: int link_len;
! 60: char buff[MAXPATHLEN];
! 61: int ret;
! 62:
! 63: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &link, &link_len) == FAILURE) {
! 64: return;
! 65: }
! 66:
! 67: if (strlen(link) != link_len) {
! 68: RETURN_FALSE;
! 69: }
! 70:
! 71: if (PG(safe_mode) && !php_checkuid(link, NULL, CHECKUID_CHECK_FILE_AND_DIR)) {
! 72: RETURN_FALSE;
! 73: }
! 74:
! 75: if (php_check_open_basedir(link TSRMLS_CC)) {
! 76: RETURN_FALSE;
! 77: }
! 78:
! 79: ret = php_sys_readlink(link, buff, MAXPATHLEN-1);
! 80:
! 81: if (ret == -1) {
! 82: php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", strerror(errno));
! 83: RETURN_FALSE;
! 84: }
! 85: /* Append NULL to the end of the string */
! 86: buff[ret] = '\0';
! 87:
! 88: RETURN_STRING(buff, 1);
! 89: }
! 90: /* }}} */
! 91:
! 92: /* {{{ proto int linkinfo(string filename)
! 93: Returns the st_dev field of the UNIX C stat structure describing the link */
! 94: PHP_FUNCTION(linkinfo)
! 95: {
! 96: char *link;
! 97: int link_len;
! 98: struct stat sb;
! 99: int ret;
! 100:
! 101: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &link, &link_len) == FAILURE) {
! 102: return;
! 103: }
! 104:
! 105: ret = VCWD_LSTAT(link, &sb);
! 106: if (ret == -1) {
! 107: php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", strerror(errno));
! 108: RETURN_LONG(-1L);
! 109: }
! 110:
! 111: RETURN_LONG((long) sb.st_dev);
! 112: }
! 113: /* }}} */
! 114:
! 115: /* {{{ proto int symlink(string target, string link)
! 116: Create a symbolic link */
! 117: PHP_FUNCTION(symlink)
! 118: {
! 119: char *topath, *frompath;
! 120: int topath_len, frompath_len;
! 121: int ret;
! 122: char source_p[MAXPATHLEN];
! 123: char dest_p[MAXPATHLEN];
! 124: char dirname[MAXPATHLEN];
! 125: size_t len;
! 126:
! 127: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &topath, &topath_len, &frompath, &frompath_len) == FAILURE) {
! 128: return;
! 129: }
! 130:
! 131: if (strlen(topath) != topath_len) {
! 132: RETURN_FALSE;
! 133: }
! 134:
! 135: if (strlen(frompath) != frompath_len) {
! 136: RETURN_FALSE;
! 137: }
! 138:
! 139: if (!expand_filepath(frompath, source_p TSRMLS_CC)) {
! 140: php_error_docref(NULL TSRMLS_CC, E_WARNING, "No such file or directory");
! 141: RETURN_FALSE;
! 142: }
! 143:
! 144: memcpy(dirname, source_p, sizeof(source_p));
! 145: len = php_dirname(dirname, strlen(dirname));
! 146:
! 147: if (!expand_filepath_ex(topath, dest_p, dirname, len TSRMLS_CC)) {
! 148: php_error_docref(NULL TSRMLS_CC, E_WARNING, "No such file or directory");
! 149: RETURN_FALSE;
! 150: }
! 151:
! 152: if (php_stream_locate_url_wrapper(source_p, NULL, STREAM_LOCATE_WRAPPERS_ONLY TSRMLS_CC) ||
! 153: php_stream_locate_url_wrapper(dest_p, NULL, STREAM_LOCATE_WRAPPERS_ONLY TSRMLS_CC) )
! 154: {
! 155: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to symlink to a URL");
! 156: RETURN_FALSE;
! 157: }
! 158:
! 159: if (PG(safe_mode) && !php_checkuid(dest_p, NULL, CHECKUID_CHECK_FILE_AND_DIR)) {
! 160: RETURN_FALSE;
! 161: }
! 162:
! 163: if (PG(safe_mode) && !php_checkuid(source_p, NULL, CHECKUID_CHECK_FILE_AND_DIR)) {
! 164: RETURN_FALSE;
! 165: }
! 166:
! 167: if (php_check_open_basedir(dest_p TSRMLS_CC)) {
! 168: RETURN_FALSE;
! 169: }
! 170:
! 171: if (php_check_open_basedir(source_p TSRMLS_CC)) {
! 172: RETURN_FALSE;
! 173: }
! 174:
! 175: /* For the source, an expanded path must be used (in ZTS an other thread could have changed the CWD).
! 176: * For the target the exact string given by the user must be used, relative or not, existing or not.
! 177: * The target is relative to the link itself, not to the CWD. */
! 178: ret = symlink(topath, source_p);
! 179:
! 180: if (ret == -1) {
! 181: php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", strerror(errno));
! 182: RETURN_FALSE;
! 183: }
! 184:
! 185: RETURN_TRUE;
! 186: }
! 187: /* }}} */
! 188:
! 189: /* {{{ proto int link(string target, string link)
! 190: Create a hard link */
! 191: PHP_FUNCTION(link)
! 192: {
! 193: char *topath, *frompath;
! 194: int topath_len, frompath_len;
! 195: int ret;
! 196: char source_p[MAXPATHLEN];
! 197: char dest_p[MAXPATHLEN];
! 198:
! 199: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &topath, &topath_len, &frompath, &frompath_len) == FAILURE) {
! 200: return;
! 201: }
! 202:
! 203: if (strlen(topath) != topath_len) {
! 204: RETURN_FALSE;
! 205: }
! 206:
! 207: if (strlen(frompath) != frompath_len) {
! 208: RETURN_FALSE;
! 209: }
! 210:
! 211: if (!expand_filepath(frompath, source_p TSRMLS_CC) || !expand_filepath(topath, dest_p TSRMLS_CC)) {
! 212: php_error_docref(NULL TSRMLS_CC, E_WARNING, "No such file or directory");
! 213: RETURN_FALSE;
! 214: }
! 215:
! 216: if (php_stream_locate_url_wrapper(source_p, NULL, STREAM_LOCATE_WRAPPERS_ONLY TSRMLS_CC) ||
! 217: php_stream_locate_url_wrapper(dest_p, NULL, STREAM_LOCATE_WRAPPERS_ONLY TSRMLS_CC) )
! 218: {
! 219: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to link to a URL");
! 220: RETURN_FALSE;
! 221: }
! 222:
! 223: if (PG(safe_mode) && !php_checkuid(dest_p, NULL, CHECKUID_CHECK_FILE_AND_DIR)) {
! 224: RETURN_FALSE;
! 225: }
! 226:
! 227: if (PG(safe_mode) && !php_checkuid(source_p, NULL, CHECKUID_CHECK_FILE_AND_DIR)) {
! 228: RETURN_FALSE;
! 229: }
! 230:
! 231: if (php_check_open_basedir(dest_p TSRMLS_CC)) {
! 232: RETURN_FALSE;
! 233: }
! 234:
! 235: if (php_check_open_basedir(source_p TSRMLS_CC)) {
! 236: RETURN_FALSE;
! 237: }
! 238:
! 239: #ifndef ZTS
! 240: ret = link(topath, frompath);
! 241: #else
! 242: ret = link(dest_p, source_p);
! 243: #endif
! 244: if (ret == -1) {
! 245: php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", strerror(errno));
! 246: RETURN_FALSE;
! 247: }
! 248:
! 249: RETURN_TRUE;
! 250: }
! 251: /* }}} */
! 252:
! 253: #endif
! 254:
! 255: /*
! 256: * Local variables:
! 257: * tab-width: 4
! 258: * c-basic-offset: 4
! 259: * End:
! 260: * vim600: noet sw=4 ts=4 fdm=marker
! 261: * vim<600: noet sw=4 ts=4
! 262: */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>