Annotation of embedaddon/php/ext/standard/link.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: |
16: +----------------------------------------------------------------------+
17: */
18:
19: /* $Id: link.c 321634 2012-01-01 13:15:04Z felipe $ */
20:
21: #include "php.h"
22: #include "php_filestat.h"
23: #include "php_globals.h"
24:
25: #ifdef HAVE_SYMLINK
26:
27: #include <stdlib.h>
28: #if HAVE_UNISTD_H
29: #include <unistd.h>
30: #endif
31: #include <sys/stat.h>
32: #include <string.h>
33: #if HAVE_PWD_H
34: #ifdef PHP_WIN32
35: #include "win32/pwd.h"
36: #else
37: #include <pwd.h>
38: #endif
39: #endif
40: #if HAVE_GRP_H
41: #ifdef PHP_WIN32
42: #include "win32/grp.h"
43: #else
44: #include <grp.h>
45: #endif
46: #endif
47: #include <errno.h>
48: #include <ctype.h>
49:
50: #include "safe_mode.h"
51: #include "php_link.h"
52: #include "php_string.h"
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 buff[MAXPATHLEN];
61: int ret;
62:
63: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &link, &link_len) == FAILURE) {
64: return;
65: }
66:
67: if (strlen(link) != link_len) {
68: RETURN_FALSE;
69: }
70:
71: if (PG(safe_mode) && !php_checkuid(link, NULL, CHECKUID_CHECK_FILE_AND_DIR)) {
72: RETURN_FALSE;
73: }
74:
75: if (php_check_open_basedir(link TSRMLS_CC)) {
76: RETURN_FALSE;
77: }
78:
79: ret = php_sys_readlink(link, buff, MAXPATHLEN-1);
80:
81: if (ret == -1) {
82: php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", strerror(errno));
83: RETURN_FALSE;
84: }
85: /* Append NULL to the end of the string */
86: buff[ret] = '\0';
87:
88: RETURN_STRING(buff, 1);
89: }
90: /* }}} */
91:
92: /* {{{ proto int linkinfo(string filename)
93: Returns the st_dev field of the UNIX C stat structure describing the link */
94: PHP_FUNCTION(linkinfo)
95: {
96: char *link;
97: int link_len;
98: struct stat sb;
99: int ret;
100:
101: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &link, &link_len) == FAILURE) {
102: return;
103: }
104:
105: ret = VCWD_LSTAT(link, &sb);
106: if (ret == -1) {
107: php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", strerror(errno));
108: RETURN_LONG(-1L);
109: }
110:
111: RETURN_LONG((long) sb.st_dev);
112: }
113: /* }}} */
114:
115: /* {{{ proto int symlink(string target, string link)
116: Create a symbolic link */
117: PHP_FUNCTION(symlink)
118: {
119: char *topath, *frompath;
120: int topath_len, frompath_len;
121: int ret;
122: char source_p[MAXPATHLEN];
123: char dest_p[MAXPATHLEN];
124: char dirname[MAXPATHLEN];
125: size_t len;
126:
127: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &topath, &topath_len, &frompath, &frompath_len) == FAILURE) {
128: return;
129: }
130:
131: if (strlen(topath) != topath_len) {
132: RETURN_FALSE;
133: }
134:
135: if (strlen(frompath) != frompath_len) {
136: RETURN_FALSE;
137: }
138:
139: if (!expand_filepath(frompath, source_p TSRMLS_CC)) {
140: php_error_docref(NULL TSRMLS_CC, E_WARNING, "No such file or directory");
141: RETURN_FALSE;
142: }
143:
144: memcpy(dirname, source_p, sizeof(source_p));
145: len = php_dirname(dirname, strlen(dirname));
146:
147: if (!expand_filepath_ex(topath, dest_p, dirname, len TSRMLS_CC)) {
148: php_error_docref(NULL TSRMLS_CC, E_WARNING, "No such file or directory");
149: RETURN_FALSE;
150: }
151:
152: if (php_stream_locate_url_wrapper(source_p, NULL, STREAM_LOCATE_WRAPPERS_ONLY TSRMLS_CC) ||
153: php_stream_locate_url_wrapper(dest_p, NULL, STREAM_LOCATE_WRAPPERS_ONLY TSRMLS_CC) )
154: {
155: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to symlink to a URL");
156: RETURN_FALSE;
157: }
158:
159: if (PG(safe_mode) && !php_checkuid(dest_p, NULL, CHECKUID_CHECK_FILE_AND_DIR)) {
160: RETURN_FALSE;
161: }
162:
163: if (PG(safe_mode) && !php_checkuid(source_p, NULL, CHECKUID_CHECK_FILE_AND_DIR)) {
164: RETURN_FALSE;
165: }
166:
167: if (php_check_open_basedir(dest_p TSRMLS_CC)) {
168: RETURN_FALSE;
169: }
170:
171: if (php_check_open_basedir(source_p TSRMLS_CC)) {
172: RETURN_FALSE;
173: }
174:
175: /* For the source, an expanded path must be used (in ZTS an other thread could have changed the CWD).
176: * For the target the exact string given by the user must be used, relative or not, existing or not.
177: * The target is relative to the link itself, not to the CWD. */
178: ret = symlink(topath, source_p);
179:
180: if (ret == -1) {
181: php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", strerror(errno));
182: RETURN_FALSE;
183: }
184:
185: RETURN_TRUE;
186: }
187: /* }}} */
188:
189: /* {{{ proto int link(string target, string link)
190: Create a hard link */
191: PHP_FUNCTION(link)
192: {
193: char *topath, *frompath;
194: int topath_len, frompath_len;
195: int ret;
196: char source_p[MAXPATHLEN];
197: char dest_p[MAXPATHLEN];
198:
199: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &topath, &topath_len, &frompath, &frompath_len) == FAILURE) {
200: return;
201: }
202:
203: if (strlen(topath) != topath_len) {
204: RETURN_FALSE;
205: }
206:
207: if (strlen(frompath) != frompath_len) {
208: RETURN_FALSE;
209: }
210:
211: if (!expand_filepath(frompath, source_p TSRMLS_CC) || !expand_filepath(topath, dest_p TSRMLS_CC)) {
212: php_error_docref(NULL TSRMLS_CC, E_WARNING, "No such file or directory");
213: RETURN_FALSE;
214: }
215:
216: if (php_stream_locate_url_wrapper(source_p, NULL, STREAM_LOCATE_WRAPPERS_ONLY TSRMLS_CC) ||
217: php_stream_locate_url_wrapper(dest_p, NULL, STREAM_LOCATE_WRAPPERS_ONLY TSRMLS_CC) )
218: {
219: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to link to a URL");
220: RETURN_FALSE;
221: }
222:
223: if (PG(safe_mode) && !php_checkuid(dest_p, NULL, CHECKUID_CHECK_FILE_AND_DIR)) {
224: RETURN_FALSE;
225: }
226:
227: if (PG(safe_mode) && !php_checkuid(source_p, NULL, CHECKUID_CHECK_FILE_AND_DIR)) {
228: RETURN_FALSE;
229: }
230:
231: if (php_check_open_basedir(dest_p TSRMLS_CC)) {
232: RETURN_FALSE;
233: }
234:
235: if (php_check_open_basedir(source_p TSRMLS_CC)) {
236: RETURN_FALSE;
237: }
238:
239: #ifndef ZTS
240: ret = link(topath, frompath);
241: #else
242: ret = link(dest_p, source_p);
243: #endif
244: if (ret == -1) {
245: php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", strerror(errno));
246: RETURN_FALSE;
247: }
248:
249: RETURN_TRUE;
250: }
251: /* }}} */
252:
253: #endif
254:
255: /*
256: * Local variables:
257: * tab-width: 4
258: * c-basic-offset: 4
259: * End:
260: * vim600: noet sw=4 ts=4 fdm=marker
261: * vim<600: noet sw=4 ts=4
262: */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>