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>