Annotation of embedaddon/php/ext/standard/link_win32.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: 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>