Annotation of embedaddon/php/ext/standard/link_win32.c, revision 1.1.1.2

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

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