Return to link.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / php / ext / standard |
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: */