Annotation of embedaddon/php/ext/standard/link_win32.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: Pierre A. Joye <pierre@php.net>                              |
        !            16:    +----------------------------------------------------------------------+
        !            17:  */
        !            18: 
        !            19: /* $Id: link_win32.c 321634 2012-01-01 13:15:04Z felipe $ */
        !            20: #ifdef PHP_WIN32
        !            21: 
        !            22: #include "php.h"
        !            23: #include "php_filestat.h"
        !            24: #include "php_globals.h"
        !            25: 
        !            26: #include <WinBase.h>
        !            27: 
        !            28: #include <stdlib.h>
        !            29: 
        !            30: #include <string.h>
        !            31: #if HAVE_PWD_H
        !            32: #include "win32/pwd.h"
        !            33: #endif
        !            34: 
        !            35: #if HAVE_GRP_H
        !            36: #include "win32/grp.h"
        !            37: #endif
        !            38: 
        !            39: #include <errno.h>
        !            40: #include <ctype.h>
        !            41: 
        !            42: #include "safe_mode.h"
        !            43: #include "php_link.h"
        !            44: #include "php_string.h"
        !            45: 
        !            46: /*
        !            47: TODO:
        !            48: - Create php_readlink (done), php_link and php_symlink in win32/link.c
        !            49: - Expose them (PHPAPI) so extensions developers can use them
        !            50: - define link/readlink/symlink to their php_ equivalent and use them in ext/standart/link.c
        !            51: - this file is then useless and we have a portable link API
        !            52: */
        !            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 target[MAXPATHLEN];
        !            61: 
        !            62:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &link, &link_len) == FAILURE) {
        !            63:                return;
        !            64:        }
        !            65: 
        !            66:        if (OPENBASEDIR_CHECKPATH(link)) {
        !            67:                RETURN_FALSE;
        !            68:        }
        !            69: 
        !            70:        if (php_sys_readlink(link, target, MAXPATHLEN) == -1) {
        !            71:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "readlink failed to read the symbolic link (%s), error %d)", link, GetLastError());
        !            72:                RETURN_FALSE;
        !            73:        }
        !            74:        RETURN_STRING(target, 1);
        !            75: }
        !            76: /* }}} */
        !            77: 
        !            78: /* {{{ proto int linkinfo(string filename)
        !            79:    Returns the st_dev field of the UNIX C stat structure describing the link */
        !            80: PHP_FUNCTION(linkinfo)
        !            81: {
        !            82:        char *link;
        !            83:        int link_len;
        !            84:        struct stat sb;
        !            85:        int ret;
        !            86: 
        !            87:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &link, &link_len) == FAILURE) {
        !            88:                return;
        !            89:        }
        !            90: 
        !            91:        ret = VCWD_STAT(link, &sb);
        !            92:        if (ret == -1) {
        !            93:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", strerror(errno));
        !            94:                RETURN_LONG(-1L);
        !            95:        }
        !            96: 
        !            97:        RETURN_LONG((long) sb.st_dev);
        !            98: }
        !            99: /* }}} */
        !           100: 
        !           101: /* {{{ proto int symlink(string target, string link)
        !           102:    Create a symbolic link */
        !           103: PHP_FUNCTION(symlink)
        !           104: {
        !           105:        char *topath, *frompath;
        !           106:        int topath_len, frompath_len;
        !           107:        BOOLEAN ret;
        !           108:        char source_p[MAXPATHLEN];
        !           109:        char dest_p[MAXPATHLEN];
        !           110:        char dirname[MAXPATHLEN];
        !           111:        size_t len;
        !           112:        DWORD attr;
        !           113:        HINSTANCE kernel32;
        !           114:        typedef BOOLEAN (WINAPI *csla_func)(LPCSTR, LPCSTR, DWORD);
        !           115:        csla_func pCreateSymbolicLinkA;
        !           116: 
        !           117:        kernel32 = LoadLibrary("kernel32.dll");
        !           118: 
        !           119:        if (kernel32) {
        !           120:                pCreateSymbolicLinkA = (csla_func)GetProcAddress(kernel32, "CreateSymbolicLinkA");
        !           121:                if (pCreateSymbolicLinkA == NULL) {
        !           122:                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Can't call CreateSymbolicLinkA");
        !           123:                        RETURN_FALSE;
        !           124:                }
        !           125:        } else {
        !           126:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Can't call get a handle on kernel32.dll");
        !           127:                RETURN_FALSE;
        !           128:        }
        !           129: 
        !           130:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &topath, &topath_len, &frompath, &frompath_len) == FAILURE) {
        !           131:                return;
        !           132:        }
        !           133:        
        !           134:        if (!expand_filepath(frompath, source_p TSRMLS_CC)) {
        !           135:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "No such file or directory");
        !           136:                RETURN_FALSE;
        !           137:        }
        !           138: 
        !           139:        memcpy(dirname, source_p, sizeof(source_p));
        !           140:        len = php_dirname(dirname, strlen(dirname));
        !           141: 
        !           142:        if (!expand_filepath_ex(topath, dest_p, dirname, len TSRMLS_CC)) {
        !           143:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "No such file or directory");
        !           144:                RETURN_FALSE;
        !           145:        }
        !           146: 
        !           147:        if (php_stream_locate_url_wrapper(source_p, NULL, STREAM_LOCATE_WRAPPERS_ONLY TSRMLS_CC) ||
        !           148:                php_stream_locate_url_wrapper(dest_p, NULL, STREAM_LOCATE_WRAPPERS_ONLY TSRMLS_CC) ) 
        !           149:        {
        !           150:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to symlink to a URL");
        !           151:                RETURN_FALSE;
        !           152:        }
        !           153: 
        !           154:        if (OPENBASEDIR_CHECKPATH(dest_p)) {
        !           155:                RETURN_FALSE;
        !           156:        }
        !           157: 
        !           158:        if (OPENBASEDIR_CHECKPATH(source_p)) {
        !           159:                RETURN_FALSE;
        !           160:        }
        !           161: 
        !           162:        if ((attr = GetFileAttributes(topath)) == INVALID_FILE_ATTRIBUTES) {
        !           163:                        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not fetch file information(error %d)", GetLastError());
        !           164:                        RETURN_FALSE;
        !           165:        }
        !           166: 
        !           167:        /* For the source, an expanded path must be used (in ZTS an other thread could have changed the CWD).
        !           168:         * For the target the exact string given by the user must be used, relative or not, existing or not.
        !           169:         * The target is relative to the link itself, not to the CWD. */
        !           170:        ret = pCreateSymbolicLinkA(source_p, topath, (attr & FILE_ATTRIBUTE_DIRECTORY ? 1 : 0));
        !           171: 
        !           172:        if (!ret) {
        !           173:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot create symlink, error code(%d)", GetLastError());
        !           174:                RETURN_FALSE;
        !           175:        }
        !           176: 
        !           177:        RETURN_TRUE;
        !           178: }
        !           179: /* }}} */
        !           180: 
        !           181: /* {{{ proto int link(string target, string link)
        !           182:    Create a hard link */
        !           183: PHP_FUNCTION(link)
        !           184: {
        !           185:        char *topath, *frompath;
        !           186:        int topath_len, frompath_len;
        !           187:        int ret;
        !           188:        char source_p[MAXPATHLEN];
        !           189:        char dest_p[MAXPATHLEN];
        !           190: 
        !           191:        /*First argument to link function is the target and hence should go to frompath
        !           192:          Second argument to link function is the link itself and hence should go to topath */
        !           193:        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &frompath, &frompath_len, &topath, &topath_len) == FAILURE) {
        !           194:                return;
        !           195:        }
        !           196: 
        !           197:        if (!expand_filepath(frompath, source_p TSRMLS_CC) || !expand_filepath(topath, dest_p TSRMLS_CC)) {
        !           198:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "No such file or directory");
        !           199:                RETURN_FALSE;
        !           200:        }
        !           201: 
        !           202:        if (php_stream_locate_url_wrapper(source_p, NULL, STREAM_LOCATE_WRAPPERS_ONLY TSRMLS_CC) ||
        !           203:                php_stream_locate_url_wrapper(dest_p, NULL, STREAM_LOCATE_WRAPPERS_ONLY TSRMLS_CC) ) 
        !           204:        {
        !           205:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to link to a URL");
        !           206:                RETURN_FALSE;
        !           207:        }
        !           208: 
        !           209:        if (OPENBASEDIR_CHECKPATH(source_p)) {
        !           210:                RETURN_FALSE;
        !           211:        }
        !           212: 
        !           213:        if (OPENBASEDIR_CHECKPATH(dest_p)) {
        !           214:                RETURN_FALSE;
        !           215:        }
        !           216: 
        !           217: #ifndef ZTS
        !           218:        ret = CreateHardLinkA(topath, frompath, NULL);
        !           219: #else 
        !           220:        ret = CreateHardLinkA(dest_p, source_p, NULL);  
        !           221: #endif 
        !           222: 
        !           223:        if (ret == 0) {
        !           224:                php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", strerror(errno));
        !           225:                RETURN_FALSE;
        !           226:        }
        !           227: 
        !           228:        RETURN_TRUE;
        !           229: }
        !           230: /* }}} */
        !           231: 
        !           232: #endif
        !           233: 
        !           234: /*
        !           235:  * Local variables:
        !           236:  * tab-width: 4
        !           237:  * c-basic-offset: 4
        !           238:  * End:
        !           239:  * vim600: noet sw=4 ts=4 fdm=marker
        !           240:  * vim<600: noet sw=4 ts=4
        !           241:  */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>