2 +----------------------------------------------------------------------+
4 +----------------------------------------------------------------------+
5 | Copyright (c) 1997-2013 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 | Authors: Andi Gutmans <andi@zend.com> |
16 | Sascha Schumann <sascha@schumann.cx> |
17 | Pierre Joye <pierre@php.net> |
18 +----------------------------------------------------------------------+
27 #include "tsrm_config_common.h"
29 #include <sys/types.h>
51 #if defined(__osf__) || defined(_AIX)
57 #include <sys/utime.h>
58 /* mode_t isn't defined on Windows */
59 typedef unsigned short mode_t
;
61 #define DEFAULT_SLASH '\\'
62 #define DEFAULT_DIR_SEPARATOR ';'
63 #define IS_SLASH(c) ((c) == '/' || (c) == '\\')
64 #define IS_SLASH_P(c) (*(c) == '/' || \
65 (*(c) == '\\' && !IsDBCSLeadByte(*(c-1))))
67 /* COPY_WHEN_ABSOLUTE is 2 under Win32 because by chance both regular absolute paths
68 in the file system and UNC paths need copying of two characters */
69 #define COPY_WHEN_ABSOLUTE(path) 2
70 #define IS_UNC_PATH(path, len) \
71 (len >= 2 && IS_SLASH(path[0]) && IS_SLASH(path[1]))
72 #define IS_ABSOLUTE_PATH(path, len) \
73 (len >= 2 && ((isalpha(path[0]) && path[1] == ':') || IS_UNC_PATH(path, len)))
75 #elif defined(NETWARE)
80 #define DEFAULT_SLASH '/'
81 #define DEFAULT_DIR_SEPARATOR ';'
82 #define IS_SLASH(c) ((c) == '/' || (c) == '\\')
83 #define IS_SLASH_P(c) IS_SLASH(*(c))
84 /* Colon indicates volume name, either first character should be forward slash or backward slash */
85 #define IS_ABSOLUTE_PATH(path, len) \
86 ((strchr(path, ':') != NULL) || ((len >= 1) && ((path[0] == '/') || (path[0] == '\\'))))
93 #define DEFAULT_SLASH '/'
96 #define DEFAULT_DIR_SEPARATOR ';'
98 #define DEFAULT_DIR_SEPARATOR ':'
101 #define IS_SLASH(c) ((c) == '/')
102 #define IS_SLASH_P(c) (*(c) == '/')
107 #ifndef COPY_WHEN_ABSOLUTE
108 #define COPY_WHEN_ABSOLUTE(path) 0
111 #ifndef IS_ABSOLUTE_PATH
112 #define IS_ABSOLUTE_PATH(path, len) \
122 # define CWD_API __declspec(dllexport)
124 # define CWD_API __declspec(dllimport)
126 #elif defined(__GNUC__) && __GNUC__ >= 4
127 # define CWD_API __attribute__ ((visibility("default")))
133 CWD_API
int php_sys_stat_ex(const char *path
, struct stat
*buf
, int lstat
);
134 # define php_sys_stat(path, buf) php_sys_stat_ex(path, buf, 0)
135 # define php_sys_lstat(path, buf) php_sys_stat_ex(path, buf, 1)
136 CWD_API
int php_sys_readlink(const char *link
, char *target
, size_t target_len
);
138 # define php_sys_stat stat
139 # define php_sys_lstat lstat
141 # define php_sys_readlink(link, target, target_len) readlink(link, target, target_len)
145 typedef struct _cwd_state
{
150 typedef int (*verify_path_func
)(const cwd_state
*);
152 CWD_API
void virtual_cwd_startup(void);
153 CWD_API
void virtual_cwd_shutdown(void);
154 CWD_API
char *virtual_getcwd_ex(size_t *length TSRMLS_DC
);
155 CWD_API
char *virtual_getcwd(char *buf
, size_t size TSRMLS_DC
);
156 CWD_API
int virtual_chdir(const char *path TSRMLS_DC
);
157 CWD_API
int virtual_chdir_file(const char *path
, int (*p_chdir
)(const char *path TSRMLS_DC
) TSRMLS_DC
);
158 CWD_API
int virtual_filepath(const char *path
, char **filepath TSRMLS_DC
);
159 CWD_API
int virtual_filepath_ex(const char *path
, char **filepath
, verify_path_func verify_path TSRMLS_DC
);
160 CWD_API
char *virtual_realpath(const char *path
, char *real_path TSRMLS_DC
);
161 CWD_API
FILE *virtual_fopen(const char *path
, const char *mode TSRMLS_DC
);
162 CWD_API
int virtual_open(const char *path TSRMLS_DC
, int flags
, ...);
163 CWD_API
int virtual_creat(const char *path
, mode_t mode TSRMLS_DC
);
164 CWD_API
int virtual_rename(char *oldname
, char *newname TSRMLS_DC
);
165 CWD_API
int virtual_stat(const char *path
, struct stat
*buf TSRMLS_DC
);
166 CWD_API
int virtual_lstat(const char *path
, struct stat
*buf TSRMLS_DC
);
167 CWD_API
int virtual_unlink(const char *path TSRMLS_DC
);
168 CWD_API
int virtual_mkdir(const char *pathname
, mode_t mode TSRMLS_DC
);
169 CWD_API
int virtual_rmdir(const char *pathname TSRMLS_DC
);
170 CWD_API
DIR *virtual_opendir(const char *pathname TSRMLS_DC
);
171 CWD_API
FILE *virtual_popen(const char *command
, const char *type TSRMLS_DC
);
172 CWD_API
int virtual_access(const char *pathname
, int mode TSRMLS_DC
);
173 #if defined(TSRM_WIN32)
174 /* these are not defined in win32 headers */
190 CWD_API
int virtual_utime(const char *filename
, struct utimbuf
*buf TSRMLS_DC
);
192 CWD_API
int virtual_chmod(const char *filename
, mode_t mode TSRMLS_DC
);
193 #if !defined(TSRM_WIN32) && !defined(NETWARE)
194 CWD_API
int virtual_chown(const char *filename
, uid_t owner
, gid_t group
, int link TSRMLS_DC
);
197 /* One of the following constants must be used as the last argument
198 in virtual_file_ex() call. */
200 #define CWD_EXPAND 0 /* expand "." and ".." but dont resolve symlinks */
201 #define CWD_FILEPATH 1 /* resolve symlinks if file is exist otherwise expand */
202 #define CWD_REALPATH 2 /* call realpath(), resolve symlinks. File must exist */
204 CWD_API
int virtual_file_ex(cwd_state
*state
, const char *path
, verify_path_func verify_path
, int use_realpath TSRMLS_DC
);
206 CWD_API
char *tsrm_realpath(const char *path
, char *real_path TSRMLS_DC
);
208 #define REALPATH_CACHE_TTL (2*60) /* 2 minutes */
209 #define REALPATH_CACHE_SIZE 0 /* disabled while php.ini isn't loaded */
211 typedef struct _realpath_cache_bucket
{
220 unsigned char is_rvalid
;
221 unsigned char is_readable
;
222 unsigned char is_wvalid
;
223 unsigned char is_writable
;
225 struct _realpath_cache_bucket
*next
;
226 } realpath_cache_bucket
;
228 typedef struct _virtual_cwd_globals
{
230 long realpath_cache_size
;
231 long realpath_cache_size_limit
;
232 long realpath_cache_ttl
;
233 realpath_cache_bucket
*realpath_cache
[1024];
234 } virtual_cwd_globals
;
237 extern ts_rsrc_id cwd_globals_id
;
238 # define CWDG(v) TSRMG(cwd_globals_id, virtual_cwd_globals *, v)
240 extern virtual_cwd_globals cwd_globals
;
241 # define CWDG(v) (cwd_globals.v)
244 CWD_API
void realpath_cache_clean(TSRMLS_D
);
245 CWD_API
void realpath_cache_del(const char *path
, int path_len TSRMLS_DC
);
246 CWD_API realpath_cache_bucket
* realpath_cache_lookup(const char *path
, int path_len
, time_t t TSRMLS_DC
);
247 CWD_API
int realpath_cache_size(TSRMLS_D
);
248 CWD_API
int realpath_cache_max_buckets(TSRMLS_D
);
249 CWD_API realpath_cache_bucket
** realpath_cache_get_buckets(TSRMLS_D
);
251 /* The actual macros to be used in programs using TSRM
252 * If the program defines VIRTUAL_DIR it will use the
253 * virtual_* functions
258 #define VCWD_GETCWD(buff, size) virtual_getcwd(buff, size TSRMLS_CC)
259 #define VCWD_FOPEN(path, mode) virtual_fopen(path, mode TSRMLS_CC)
260 /* Because open() has two modes, we have to macros to replace it */
261 #define VCWD_OPEN(path, flags) virtual_open(path TSRMLS_CC, flags)
262 #define VCWD_OPEN_MODE(path, flags, mode) virtual_open(path TSRMLS_CC, flags, mode)
263 #define VCWD_CREAT(path, mode) virtual_creat(path, mode TSRMLS_CC)
264 #define VCWD_CHDIR(path) virtual_chdir(path TSRMLS_CC)
265 #define VCWD_CHDIR_FILE(path) virtual_chdir_file(path, virtual_chdir TSRMLS_CC)
266 #define VCWD_GETWD(buf)
267 #define VCWD_REALPATH(path, real_path) virtual_realpath(path, real_path TSRMLS_CC)
268 #define VCWD_RENAME(oldname, newname) virtual_rename(oldname, newname TSRMLS_CC)
269 #define VCWD_STAT(path, buff) virtual_stat(path, buff TSRMLS_CC)
270 # define VCWD_LSTAT(path, buff) virtual_lstat(path, buff TSRMLS_CC)
271 #define VCWD_UNLINK(path) virtual_unlink(path TSRMLS_CC)
272 #define VCWD_MKDIR(pathname, mode) virtual_mkdir(pathname, mode TSRMLS_CC)
273 #define VCWD_RMDIR(pathname) virtual_rmdir(pathname TSRMLS_CC)
274 #define VCWD_OPENDIR(pathname) virtual_opendir(pathname TSRMLS_CC)
275 #define VCWD_POPEN(command, type) virtual_popen(command, type TSRMLS_CC)
276 #define VCWD_ACCESS(pathname, mode) virtual_access(pathname, mode TSRMLS_CC)
278 #define VCWD_UTIME(path, time) virtual_utime(path, time TSRMLS_CC)
280 #define VCWD_CHMOD(path, mode) virtual_chmod(path, mode TSRMLS_CC)
281 #if !defined(TSRM_WIN32) && !defined(NETWARE)
282 #define VCWD_CHOWN(path, owner, group) virtual_chown(path, owner, group, 0 TSRMLS_CC)
284 #define VCWD_LCHOWN(path, owner, group) virtual_chown(path, owner, group, 1 TSRMLS_CC)
290 #define VCWD_GETCWD(buff, size) getcwd(buff, size)
291 #define VCWD_FOPEN(path, mode) fopen(path, mode)
292 #define VCWD_OPEN(path, flags) open(path, flags)
293 #define VCWD_OPEN_MODE(path, flags, mode) open(path, flags, mode)
294 #define VCWD_CREAT(path, mode) creat(path, mode)
295 /* rename on windows will fail if newname already exists.
296 MoveFileEx has to be used */
297 #if defined(TSRM_WIN32)
298 # define VCWD_RENAME(oldname, newname) (MoveFileEx(oldname, newname, MOVEFILE_REPLACE_EXISTING|MOVEFILE_COPY_ALLOWED) == 0 ? -1 : 0)
300 # define VCWD_RENAME(oldname, newname) rename(oldname, newname)
302 #define VCWD_CHDIR(path) chdir(path)
303 #define VCWD_CHDIR_FILE(path) virtual_chdir_file(path, chdir)
304 #define VCWD_GETWD(buf) getwd(buf)
305 #define VCWD_STAT(path, buff) php_sys_stat(path, buff)
306 #define VCWD_LSTAT(path, buff) lstat(path, buff)
307 #define VCWD_UNLINK(path) unlink(path)
308 #define VCWD_MKDIR(pathname, mode) mkdir(pathname, mode)
309 #define VCWD_RMDIR(pathname) rmdir(pathname)
310 #define VCWD_OPENDIR(pathname) opendir(pathname)
311 #define VCWD_POPEN(command, type) popen(command, type)
312 #if defined(TSRM_WIN32)
313 #define VCWD_ACCESS(pathname, mode) tsrm_win32_access(pathname, mode TSRMLS_CC)
315 #define VCWD_ACCESS(pathname, mode) access(pathname, mode)
318 #define VCWD_REALPATH(path, real_path) tsrm_realpath(path, real_path TSRMLS_CC)
322 # define VCWD_UTIME(path, time) win32_utime(path, time)
324 # define VCWD_UTIME(path, time) utime(path, time)
328 #define VCWD_CHMOD(path, mode) chmod(path, mode)
329 #if !defined(TSRM_WIN32) && !defined(NETWARE)
330 #define VCWD_CHOWN(path, owner, group) chown(path, owner, group)
332 #define VCWD_LCHOWN(path, owner, group) lchown(path, owner, group)
338 #endif /* VIRTUAL_CWD_H */