Annotation of embedaddon/php/ext/standard/link_win32.c, revision 1.1.1.3
1.1 misho 1: /*
2: +----------------------------------------------------------------------+
3: | PHP Version 5 |
4: +----------------------------------------------------------------------+
1.1.1.3 ! misho 5: | Copyright (c) 1997-2013 The PHP Group |
1.1 misho 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>