Annotation of embedaddon/php/ext/standard/link.c, revision 1.1.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>