1 : /*
2 : +----------------------------------------------------------------------+
3 : | PHP Version 5 |
4 : +----------------------------------------------------------------------+
5 : | Copyright (c) 1997-2009 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: Jim Winstead <jimw@php.net> |
16 : +----------------------------------------------------------------------+
17 : */
18 :
19 : /* $Id: filestat.c 290190 2009-11-03 21:21:34Z guenter $ */
20 :
21 : #include "php.h"
22 : #include "safe_mode.h"
23 : #include "fopen_wrappers.h"
24 : #include "php_globals.h"
25 :
26 : #include <stdlib.h>
27 : #include <sys/stat.h>
28 : #include <string.h>
29 : #include <errno.h>
30 : #include <ctype.h>
31 : #include <time.h>
32 :
33 : #if HAVE_UNISTD_H
34 : # include <unistd.h>
35 : #endif
36 :
37 : #if HAVE_SYS_PARAM_H
38 : # include <sys/param.h>
39 : #endif
40 :
41 : #if HAVE_SYS_VFS_H
42 : # include <sys/vfs.h>
43 : #endif
44 :
45 : #ifdef OS2
46 : # define INCL_DOS
47 : # include <os2.h>
48 : #endif
49 :
50 : #if defined(HAVE_SYS_STATVFS_H) && defined(HAVE_STATVFS)
51 : # include <sys/statvfs.h>
52 : #elif defined(HAVE_SYS_STATFS_H) && defined(HAVE_STATFS)
53 : # include <sys/statfs.h>
54 : #elif defined(HAVE_SYS_MOUNT_H) && defined(HAVE_STATFS)
55 : # include <sys/mount.h>
56 : #endif
57 :
58 : #if HAVE_PWD_H
59 : # ifdef PHP_WIN32
60 : # include "win32/pwd.h"
61 : # else
62 : # include <pwd.h>
63 : # endif
64 : #endif
65 :
66 : #if HAVE_GRP_H
67 : # ifdef PHP_WIN32
68 : # include "win32/grp.h"
69 : # else
70 : # include <grp.h>
71 : # endif
72 : #endif
73 :
74 : #if HAVE_UTIME
75 : # ifdef PHP_WIN32
76 : # include <sys/utime.h>
77 : # else
78 : # include <utime.h>
79 : # endif
80 : #endif
81 :
82 : #ifdef PHP_WIN32
83 : #include "win32/winutil.h"
84 : #endif
85 :
86 : #include "basic_functions.h"
87 : #include "php_filestat.h"
88 :
89 : #ifndef S_ISDIR
90 : #define S_ISDIR(mode) (((mode)&S_IFMT) == S_IFDIR)
91 : #endif
92 : #ifndef S_ISREG
93 : #define S_ISREG(mode) (((mode)&S_IFMT) == S_IFREG)
94 : #endif
95 : #ifndef S_ISLNK
96 : #define S_ISLNK(mode) (((mode)&S_IFMT) == S_IFLNK)
97 : #endif
98 :
99 : #define S_IXROOT ( S_IXUSR | S_IXGRP | S_IXOTH )
100 :
101 : PHP_RINIT_FUNCTION(filestat) /* {{{ */
102 17619 : {
103 17619 : BG(CurrentStatFile)=NULL;
104 17619 : BG(CurrentLStatFile)=NULL;
105 17619 : return SUCCESS;
106 : }
107 : /* }}} */
108 :
109 : PHP_RSHUTDOWN_FUNCTION(filestat) /* {{{ */
110 17651 : {
111 17651 : if (BG(CurrentStatFile)) {
112 369 : efree (BG(CurrentStatFile));
113 369 : BG(CurrentStatFile) = NULL;
114 : }
115 17651 : if (BG(CurrentLStatFile)) {
116 29 : efree (BG(CurrentLStatFile));
117 29 : BG(CurrentLStatFile) = NULL;
118 : }
119 17651 : return SUCCESS;
120 : }
121 : /* }}} */
122 :
123 : static int php_disk_total_space(char *path, double *space TSRMLS_DC) /* {{{ */
124 : #if defined(WINDOWS) /* {{{ */
125 : {
126 : double bytestotal = 0;
127 : HINSTANCE kernel32;
128 : FARPROC gdfse;
129 : typedef BOOL (WINAPI *gdfse_func)(LPCTSTR, PULARGE_INTEGER, PULARGE_INTEGER, PULARGE_INTEGER);
130 : gdfse_func func;
131 :
132 : /* These are used by GetDiskFreeSpaceEx, if available. */
133 : ULARGE_INTEGER FreeBytesAvailableToCaller;
134 : ULARGE_INTEGER TotalNumberOfBytes;
135 : ULARGE_INTEGER TotalNumberOfFreeBytes;
136 :
137 : /* These are used by GetDiskFreeSpace otherwise. */
138 : DWORD SectorsPerCluster;
139 : DWORD BytesPerSector;
140 : DWORD NumberOfFreeClusters;
141 : DWORD TotalNumberOfClusters;
142 :
143 : /* GetDiskFreeSpaceEx is only available in NT and Win95 post-OSR2,
144 : so we have to jump through some hoops to see if the function
145 : exists. */
146 : kernel32 = LoadLibrary("kernel32.dll");
147 : if (kernel32) {
148 : gdfse = GetProcAddress(kernel32, "GetDiskFreeSpaceExA");
149 : /* It's available, so we can call it. */
150 : if (gdfse) {
151 : func = (gdfse_func)gdfse;
152 : if (func(path,
153 : &FreeBytesAvailableToCaller,
154 : &TotalNumberOfBytes,
155 : &TotalNumberOfFreeBytes) == 0) {
156 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", php_win_err());
157 : return FAILURE;
158 : }
159 :
160 : /* i know - this is ugly, but i works <thies@thieso.net> */
161 : bytestotal = TotalNumberOfBytes.HighPart *
162 : (double) (((unsigned long)1) << 31) * 2.0 +
163 : TotalNumberOfBytes.LowPart;
164 : } else { /* If it's not available, we just use GetDiskFreeSpace */
165 : if (GetDiskFreeSpace(path,
166 : &SectorsPerCluster, &BytesPerSector,
167 : &NumberOfFreeClusters, &TotalNumberOfClusters) == 0) {
168 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", php_win_err());
169 : return FAILURE;
170 : }
171 : bytestotal = (double)TotalNumberOfClusters * (double)SectorsPerCluster * (double)BytesPerSector;
172 : }
173 : } else {
174 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to load kernel32.dll");
175 : return FAILURE;
176 : }
177 :
178 : *space = bytestotal;
179 : return SUCCESS;
180 : }
181 : /* }}} */
182 : #elif defined(OS2) /* {{{ */
183 : {
184 : double bytestotal = 0;
185 : FSALLOCATE fsinfo;
186 : char drive = path[0] & 95;
187 :
188 : if (DosQueryFSInfo( drive ? drive - 64 : 0, FSIL_ALLOC, &fsinfo, sizeof( fsinfo ) ) == 0) {
189 : bytestotal = (double)fsinfo.cbSector * fsinfo.cSectorUnit * fsinfo.cUnit;
190 : *space = bytestotal;
191 : return SUCCESS;
192 : }
193 : return FAILURE;
194 : }
195 : /* }}} */
196 : #else /* {{{ if !defined(OS2) && !defined(WINDOWS) */
197 23 : {
198 23 : double bytestotal = 0;
199 : #if defined(HAVE_SYS_STATVFS_H) && defined(HAVE_STATVFS)
200 : struct statvfs buf;
201 : #elif (defined(HAVE_SYS_STATFS_H) || defined(HAVE_SYS_MOUNT_H)) && defined(HAVE_STATFS)
202 : struct statfs buf;
203 : #endif
204 :
205 : #if defined(HAVE_SYS_STATVFS_H) && defined(HAVE_STATVFS)
206 23 : if (statvfs(path, &buf)) {
207 3 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", strerror(errno));
208 3 : return FAILURE;
209 : }
210 20 : if (buf.f_frsize) {
211 20 : bytestotal = (((double)buf.f_blocks) * ((double)buf.f_frsize));
212 : } else {
213 0 : bytestotal = (((double)buf.f_blocks) * ((double)buf.f_bsize));
214 : }
215 :
216 : #elif (defined(HAVE_SYS_STATFS_H) || defined(HAVE_SYS_MOUNT_H)) && defined(HAVE_STATFS)
217 : if (statfs(path, &buf)) {
218 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", strerror(errno));
219 : return FAILURE;
220 : }
221 : bytestotal = (((double)buf.f_bsize) * ((double)buf.f_blocks));
222 : #endif
223 :
224 20 : *space = bytestotal;
225 20 : return SUCCESS;
226 : }
227 : #endif
228 : /* }}} */
229 : /* }}} */
230 :
231 : /* {{{ proto float disk_total_space(string path)
232 : Get total disk space for filesystem that path is on */
233 : PHP_FUNCTION(disk_total_space)
234 26 : {
235 : double bytestotal;
236 : char *path;
237 : int path_len;
238 :
239 26 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &path, &path_len) == FAILURE) {
240 3 : return;
241 : }
242 :
243 23 : if (php_check_open_basedir(path TSRMLS_CC)) {
244 0 : RETURN_FALSE;
245 : }
246 :
247 23 : if (php_disk_total_space(path, &bytestotal TSRMLS_CC) == SUCCESS) {
248 20 : RETURN_DOUBLE(bytestotal);
249 : }
250 3 : RETURN_FALSE;
251 : }
252 : /* }}} */
253 :
254 : static int php_disk_free_space(char *path, double *space TSRMLS_DC) /* {{{ */
255 : #if defined(WINDOWS) /* {{{ */
256 : {
257 : double bytesfree = 0;
258 :
259 : HINSTANCE kernel32;
260 : FARPROC gdfse;
261 : typedef BOOL (WINAPI *gdfse_func)(LPCTSTR, PULARGE_INTEGER, PULARGE_INTEGER, PULARGE_INTEGER);
262 : gdfse_func func;
263 :
264 : /* These are used by GetDiskFreeSpaceEx, if available. */
265 : ULARGE_INTEGER FreeBytesAvailableToCaller;
266 : ULARGE_INTEGER TotalNumberOfBytes;
267 : ULARGE_INTEGER TotalNumberOfFreeBytes;
268 :
269 : /* These are used by GetDiskFreeSpace otherwise. */
270 : DWORD SectorsPerCluster;
271 : DWORD BytesPerSector;
272 : DWORD NumberOfFreeClusters;
273 : DWORD TotalNumberOfClusters;
274 :
275 : /* GetDiskFreeSpaceEx is only available in NT and Win95 post-OSR2,
276 : so we have to jump through some hoops to see if the function
277 : exists. */
278 : kernel32 = LoadLibrary("kernel32.dll");
279 : if (kernel32) {
280 : gdfse = GetProcAddress(kernel32, "GetDiskFreeSpaceExA");
281 : /* It's available, so we can call it. */
282 : if (gdfse) {
283 : func = (gdfse_func)gdfse;
284 : if (func(path,
285 : &FreeBytesAvailableToCaller,
286 : &TotalNumberOfBytes,
287 : &TotalNumberOfFreeBytes) == 0) {
288 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", php_win_err());
289 : return FAILURE;
290 : }
291 :
292 : /* i know - this is ugly, but i works <thies@thieso.net> */
293 : bytesfree = FreeBytesAvailableToCaller.HighPart *
294 : (double) (((unsigned long)1) << 31) * 2.0 +
295 : FreeBytesAvailableToCaller.LowPart;
296 : } else { /* If it's not available, we just use GetDiskFreeSpace */
297 : if (GetDiskFreeSpace(path,
298 : &SectorsPerCluster, &BytesPerSector,
299 : &NumberOfFreeClusters, &TotalNumberOfClusters) == 0) {
300 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", php_win_err());
301 : return FAILURE;
302 : }
303 : bytesfree = (double)NumberOfFreeClusters * (double)SectorsPerCluster * (double)BytesPerSector;
304 : }
305 : } else {
306 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to load kernel32.dll");
307 : return FAILURE;
308 : }
309 :
310 : *space = bytesfree;
311 : return SUCCESS;
312 : }
313 : /* }}} */
314 : #elif defined(OS2) /* {{{ */
315 : {
316 : double bytesfree = 0;
317 : FSALLOCATE fsinfo;
318 : char drive = path[0] & 95;
319 :
320 : if (DosQueryFSInfo( drive ? drive - 64 : 0, FSIL_ALLOC, &fsinfo, sizeof( fsinfo ) ) == 0) {
321 : bytesfree = (double)fsinfo.cbSector * fsinfo.cSectorUnit * fsinfo.cUnitAvail;
322 : *space = bytesfree;
323 : return SUCCESS;
324 : }
325 : return FAILURE;
326 : }
327 : /* }}} */
328 : #else /* {{{ if !defined(OS2) && !defined(WINDOWS) */
329 40 : {
330 40 : double bytesfree = 0;
331 : #if defined(HAVE_SYS_STATVFS_H) && defined(HAVE_STATVFS)
332 : struct statvfs buf;
333 : #elif (defined(HAVE_SYS_STATFS_H) || defined(HAVE_SYS_MOUNT_H)) && defined(HAVE_STATFS)
334 : struct statfs buf;
335 : #endif
336 :
337 : #if defined(HAVE_SYS_STATVFS_H) && defined(HAVE_STATVFS)
338 40 : if (statvfs(path, &buf)) {
339 4 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", strerror(errno));
340 4 : return FAILURE;
341 : }
342 36 : if (buf.f_frsize) {
343 36 : bytesfree = (((double)buf.f_bavail) * ((double)buf.f_frsize));
344 : } else {
345 0 : bytesfree = (((double)buf.f_bavail) * ((double)buf.f_bsize));
346 : }
347 : #elif (defined(HAVE_SYS_STATFS_H) || defined(HAVE_SYS_MOUNT_H)) && defined(HAVE_STATFS)
348 : if (statfs(path, &buf)) {
349 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", strerror(errno));
350 : return FAILURE;
351 : }
352 : #ifdef NETWARE
353 : bytesfree = (((double)buf.f_bsize) * ((double)buf.f_bfree));
354 : #else
355 : bytesfree = (((double)buf.f_bsize) * ((double)buf.f_bavail));
356 : #endif
357 : #endif
358 :
359 36 : *space = bytesfree;
360 36 : return SUCCESS;
361 : }
362 : #endif
363 : /* }}} */
364 : /* }}} */
365 :
366 : /* {{{ proto float disk_free_space(string path)
367 : Get free disk space for filesystem that path is on */
368 : PHP_FUNCTION(disk_free_space)
369 53 : {
370 : double bytesfree;
371 : char *path;
372 : int path_len;
373 :
374 53 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &path, &path_len) == FAILURE) {
375 5 : return;
376 : }
377 :
378 48 : if (php_check_open_basedir(path TSRMLS_CC)) {
379 8 : RETURN_FALSE;
380 : }
381 :
382 40 : if (php_disk_free_space(path, &bytesfree TSRMLS_CC) == SUCCESS) {
383 36 : RETURN_DOUBLE(bytesfree);
384 : }
385 4 : RETURN_FALSE;
386 : }
387 : /* }}} */
388 :
389 : #if !defined(WINDOWS) && !defined(NETWARE)
390 : static void php_do_chgrp(INTERNAL_FUNCTION_PARAMETERS, int do_lchgrp) /* {{{ */
391 2 : {
392 : char *filename;
393 : int filename_len;
394 : zval *group;
395 : gid_t gid;
396 : int ret;
397 :
398 2 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz/", &filename, &filename_len, &group) == FAILURE) {
399 0 : RETURN_FALSE;
400 : }
401 :
402 2 : if (Z_TYPE_P(group) == IS_LONG) {
403 1 : gid = (gid_t)Z_LVAL_P(group);
404 1 : } else if (Z_TYPE_P(group) == IS_STRING) {
405 : #if defined(ZTS) && defined(HAVE_GETGRNAM_R) && defined(_SC_GETGR_R_SIZE_MAX)
406 : struct group gr;
407 : struct group *retgrptr;
408 : long grbuflen = sysconf(_SC_GETGR_R_SIZE_MAX);
409 : char *grbuf;
410 :
411 : if (grbuflen < 1) {
412 : RETURN_FALSE;
413 : }
414 :
415 : grbuf = emalloc(grbuflen);
416 : if (getgrnam_r(Z_STRVAL_P(group), &gr, grbuf, grbuflen, &retgrptr) != 0 || retgrptr == NULL) {
417 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find gid for %s", Z_STRVAL_P(group));
418 : efree(grbuf);
419 : RETURN_FALSE;
420 : }
421 : efree(grbuf);
422 : gid = gr.gr_gid;
423 : #else
424 0 : struct group *gr = getgrnam(Z_STRVAL_P(group));
425 :
426 0 : if (!gr) {
427 0 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find gid for %s", Z_STRVAL_P(group));
428 0 : RETURN_FALSE;
429 : }
430 0 : gid = gr->gr_gid;
431 : #endif
432 : } else {
433 1 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "parameter 2 should be string or integer, %s given", zend_zval_type_name(group));
434 1 : RETURN_FALSE;
435 : }
436 :
437 1 : if (PG(safe_mode) &&(!php_checkuid(filename, NULL, CHECKUID_ALLOW_FILE_NOT_EXISTS))) {
438 0 : RETURN_FALSE;
439 : }
440 :
441 : /* Check the basedir */
442 1 : if (php_check_open_basedir(filename TSRMLS_CC)) {
443 0 : RETURN_FALSE;
444 : }
445 :
446 1 : if (do_lchgrp) {
447 : #if HAVE_LCHOWN
448 1 : ret = VCWD_LCHOWN(filename, -1, gid);
449 : #endif
450 : } else {
451 0 : ret = VCWD_CHOWN(filename, -1, gid);
452 : }
453 1 : if (ret == -1) {
454 0 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", strerror(errno));
455 0 : RETURN_FALSE;
456 : }
457 1 : RETURN_TRUE;
458 : }
459 : /* }}} */
460 : #endif
461 :
462 : #ifndef NETWARE
463 : /* {{{ proto bool chgrp(string filename, mixed group)
464 : Change file group */
465 : PHP_FUNCTION(chgrp)
466 1 : {
467 : #if !defined(WINDOWS)
468 1 : php_do_chgrp(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
469 : #else
470 : RETURN_FALSE;
471 : #endif
472 1 : }
473 : /* }}} */
474 :
475 : /* {{{ proto bool lchgrp(string filename, mixed group)
476 : Change symlink group */
477 : #if HAVE_LCHOWN
478 : PHP_FUNCTION(lchgrp)
479 1 : {
480 : # if !defined(WINDOWS)
481 1 : php_do_chgrp(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
482 : # else
483 : RETURN_FALSE;
484 : # endif
485 1 : }
486 : #endif
487 : /* }}} */
488 : #endif /* !NETWARE */
489 :
490 : #if !defined(WINDOWS) && !defined(NETWARE)
491 : static void php_do_chown(INTERNAL_FUNCTION_PARAMETERS, int do_lchown) /* {{{ */
492 8 : {
493 : char *filename;
494 : int filename_len;
495 : zval *user;
496 : uid_t uid;
497 : int ret;
498 :
499 8 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz/", &filename, &filename_len, &user) == FAILURE) {
500 4 : return;
501 : }
502 :
503 4 : if (Z_TYPE_P(user) == IS_LONG) {
504 3 : uid = (uid_t)Z_LVAL_P(user);
505 1 : } else if (Z_TYPE_P(user) == IS_STRING) {
506 : #if defined(ZTS) && defined(_SC_GETPW_R_SIZE_MAX) && defined(HAVE_GETPWNAM_R)
507 : struct passwd pw;
508 : struct passwd *retpwptr = NULL;
509 : long pwbuflen = sysconf(_SC_GETPW_R_SIZE_MAX);
510 : char *pwbuf;
511 :
512 : if (pwbuflen < 1) {
513 : RETURN_FALSE;
514 : }
515 :
516 : pwbuf = emalloc(pwbuflen);
517 : if (getpwnam_r(Z_STRVAL_P(user), &pw, pwbuf, pwbuflen, &retpwptr) != 0 || retpwptr == NULL) {
518 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find uid for %s", Z_STRVAL_P(user));
519 : efree(pwbuf);
520 : RETURN_FALSE;
521 : }
522 : efree(pwbuf);
523 : uid = pw.pw_uid;
524 : #else
525 0 : struct passwd *pw = getpwnam(Z_STRVAL_P(user));
526 :
527 0 : if (!pw) {
528 0 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find uid for %s", Z_STRVAL_P(user));
529 0 : RETURN_FALSE;
530 : }
531 0 : uid = pw->pw_uid;
532 : #endif
533 : } else {
534 1 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "parameter 2 should be string or integer, %s given", zend_zval_type_name(user));
535 1 : RETURN_FALSE;
536 : }
537 :
538 3 : if (PG(safe_mode) && (!php_checkuid(filename, NULL, CHECKUID_ALLOW_FILE_NOT_EXISTS))) {
539 0 : RETURN_FALSE;
540 : }
541 :
542 : /* Check the basedir */
543 3 : if (php_check_open_basedir(filename TSRMLS_CC)) {
544 0 : RETURN_FALSE;
545 : }
546 :
547 3 : if (do_lchown) {
548 : #if HAVE_LCHOWN
549 3 : ret = VCWD_LCHOWN(filename, uid, -1);
550 : #endif
551 : } else {
552 0 : ret = VCWD_CHOWN(filename, uid, -1);
553 : }
554 3 : if (ret == -1) {
555 2 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", strerror(errno));
556 2 : RETURN_FALSE;
557 : }
558 : }
559 : /* }}} */
560 : #endif
561 :
562 : #ifndef NETWARE
563 : /* {{{ proto bool chown (string filename, mixed user)
564 : Change file owner */
565 : PHP_FUNCTION(chown)
566 1 : {
567 : #if !defined(WINDOWS)
568 1 : RETVAL_TRUE;
569 1 : php_do_chown(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
570 : #else
571 : RETURN_FALSE;
572 : #endif
573 1 : }
574 : /* }}} */
575 :
576 : /* {{{ proto bool chown (string filename, mixed user)
577 : Change file owner */
578 : #if HAVE_LCHOWN
579 : PHP_FUNCTION(lchown)
580 7 : {
581 : # if !defined(WINDOWS)
582 7 : RETVAL_TRUE;
583 7 : php_do_chown(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
584 : # else
585 : RETURN_FALSE;
586 : # endif
587 7 : }
588 : #endif
589 : /* }}} */
590 : #endif /* !NETWARE */
591 :
592 : /* {{{ proto bool chmod(string filename, int mode)
593 : Change file mode */
594 : PHP_FUNCTION(chmod)
595 10334 : {
596 : char *filename;
597 : int filename_len;
598 : long mode;
599 : int ret;
600 : mode_t imode;
601 :
602 10334 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sl", &filename, &filename_len, &mode) == FAILURE) {
603 31 : return;
604 : }
605 :
606 10303 : if (PG(safe_mode) &&(!php_checkuid(filename, NULL, CHECKUID_ALLOW_FILE_NOT_EXISTS))) {
607 0 : RETURN_FALSE;
608 : }
609 :
610 : /* Check the basedir */
611 10303 : if (php_check_open_basedir(filename TSRMLS_CC)) {
612 8 : RETURN_FALSE;
613 : }
614 :
615 10295 : imode = (mode_t) mode;
616 : /* In safe mode, do not allow to setuid files.
617 : * Setuiding files could allow users to gain privileges
618 : * that safe mode doesn't give them. */
619 :
620 10295 : if (PG(safe_mode)) {
621 : php_stream_statbuf ssb;
622 5 : if (php_stream_stat_path_ex(filename, 0, &ssb, NULL)) {
623 0 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "stat failed for %s", filename);
624 0 : RETURN_FALSE;
625 : }
626 5 : if ((imode & 04000) != 0 && (ssb.sb.st_mode & 04000) == 0) {
627 0 : imode ^= 04000;
628 : }
629 5 : if ((imode & 02000) != 0 && (ssb.sb.st_mode & 02000) == 0) {
630 0 : imode ^= 02000;
631 : }
632 5 : if ((imode & 01000) != 0 && (ssb.sb.st_mode & 01000) == 0) {
633 0 : imode ^= 01000;
634 : }
635 : }
636 :
637 10295 : ret = VCWD_CHMOD(filename, imode);
638 10295 : if (ret == -1) {
639 25 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", strerror(errno));
640 25 : RETURN_FALSE;
641 : }
642 10270 : RETURN_TRUE;
643 : }
644 : /* }}} */
645 :
646 : #if HAVE_UTIME
647 : /* {{{ proto bool touch(string filename [, int time [, int atime]])
648 : Set modification time of file */
649 : PHP_FUNCTION(touch)
650 252 : {
651 : char *filename;
652 : int filename_len;
653 252 : long filetime = 0, fileatime = 0;
654 252 : int ret, argc = ZEND_NUM_ARGS();
655 : FILE *file;
656 : struct utimbuf newtimebuf;
657 252 : struct utimbuf *newtime = &newtimebuf;
658 :
659 252 : if (zend_parse_parameters(argc TSRMLS_CC, "s|ll", &filename, &filename_len, &filetime, &fileatime) == FAILURE) {
660 31 : return;
661 : }
662 :
663 221 : switch (argc) {
664 : case 1:
665 : #ifdef HAVE_UTIME_NULL
666 167 : newtime = NULL;
667 : #else
668 : newtime->modtime = newtime->actime = time(NULL);
669 : #endif
670 167 : break;
671 : case 2:
672 8 : newtime->modtime = newtime->actime = filetime;
673 8 : break;
674 : case 3:
675 46 : newtime->modtime = filetime;
676 46 : newtime->actime = fileatime;
677 46 : break;
678 : default:
679 : /* Never reached */
680 0 : WRONG_PARAM_COUNT;
681 : }
682 :
683 : /* Safe-mode */
684 221 : if (PG(safe_mode) && (!php_checkuid(filename, NULL, CHECKUID_CHECK_FILE_AND_DIR))) {
685 0 : RETURN_FALSE;
686 : }
687 :
688 : /* Check the basedir */
689 221 : if (php_check_open_basedir(filename TSRMLS_CC)) {
690 8 : RETURN_FALSE;
691 : }
692 :
693 : /* create the file if it doesn't exist already */
694 213 : if (VCWD_ACCESS(filename, F_OK) != 0) {
695 128 : file = VCWD_FOPEN(filename, "w");
696 128 : if (file == NULL) {
697 11 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to create file %s because %s", filename, strerror(errno));
698 11 : RETURN_FALSE;
699 : }
700 117 : fclose(file);
701 : }
702 :
703 202 : ret = VCWD_UTIME(filename, newtime);
704 202 : if (ret == -1) {
705 0 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "Utime failed: %s", strerror(errno));
706 0 : RETURN_FALSE;
707 : }
708 202 : RETURN_TRUE;
709 : }
710 : /* }}} */
711 : #endif
712 :
713 : /* {{{ php_clear_stat_cache()
714 : */
715 : PHPAPI void php_clear_stat_cache(zend_bool clear_realpath_cache, const char *filename, int filename_len TSRMLS_DC)
716 33548 : {
717 : /* always clear CurrentStatFile and CurrentLStatFile even if filename is not NULL
718 : * as it may contains outdated data (e.g. "nlink" for a directory when deleting a file
719 : * in this directory, as shown by lstat_stat_variation9.phpt) */
720 33548 : if (BG(CurrentStatFile)) {
721 18946 : efree(BG(CurrentStatFile));
722 18946 : BG(CurrentStatFile) = NULL;
723 : }
724 33548 : if (BG(CurrentLStatFile)) {
725 46 : efree(BG(CurrentLStatFile));
726 46 : BG(CurrentLStatFile) = NULL;
727 : }
728 33548 : if (clear_realpath_cache) {
729 25269 : if (filename != NULL) {
730 3 : realpath_cache_del(filename, filename_len TSRMLS_CC);
731 : } else {
732 25266 : realpath_cache_clean(TSRMLS_C);
733 : }
734 : }
735 33548 : }
736 : /* }}} */
737 :
738 : /* {{{ proto void clearstatcache([bool clear_realpath_cache[, string filename]])
739 : Clear file stat cache */
740 : PHP_FUNCTION(clearstatcache)
741 8284 : {
742 8284 : zend_bool clear_realpath_cache = 0;
743 8284 : char *filename = NULL;
744 8284 : int filename_len = 0;
745 :
746 8284 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|bs", &clear_realpath_cache, &filename, &filename_len) == FAILURE) {
747 1 : return;
748 : }
749 :
750 8283 : php_clear_stat_cache(clear_realpath_cache, filename, filename_len TSRMLS_CC);
751 : }
752 : /* }}} */
753 :
754 : #define IS_LINK_OPERATION(__t) ((__t) == FS_TYPE || (__t) == FS_IS_LINK || (__t) == FS_LSTAT)
755 : #define IS_EXISTS_CHECK(__t) ((__t) == FS_EXISTS || (__t) == FS_IS_W || (__t) == FS_IS_R || (__t) == FS_IS_X || (__t) == FS_IS_FILE || (__t) == FS_IS_DIR || (__t) == FS_IS_LINK)
756 : #define IS_ABLE_CHECK(__t) ((__t) == FS_IS_R || (__t) == FS_IS_W || (__t) == FS_IS_X)
757 : #define IS_ACCESS_CHECK(__t) (IS_ABLE_CHECK(type) || (__t) == FS_EXISTS)
758 :
759 : /* {{{ php_stat
760 : */
761 : PHPAPI void php_stat(const char *filename, php_stat_len filename_length, int type, zval *return_value TSRMLS_DC)
762 91414 : {
763 : zval *stat_dev, *stat_ino, *stat_mode, *stat_nlink, *stat_uid, *stat_gid, *stat_rdev,
764 : *stat_size, *stat_atime, *stat_mtime, *stat_ctime, *stat_blksize, *stat_blocks;
765 : struct stat *stat_sb;
766 : php_stream_statbuf ssb;
767 91414 : int flags = 0, rmask=S_IROTH, wmask=S_IWOTH, xmask=S_IXOTH; /* access rights defaults to other */
768 : char *stat_sb_names[13] = {
769 : "dev", "ino", "mode", "nlink", "uid", "gid", "rdev",
770 : "size", "atime", "mtime", "ctime", "blksize", "blocks"
771 91414 : };
772 : char *local;
773 : php_stream_wrapper *wrapper;
774 : char safe_mode_buf[MAXPATHLEN];
775 :
776 91414 : if (!filename_length) {
777 66 : RETURN_FALSE;
778 : }
779 :
780 91348 : if ((wrapper = php_stream_locate_url_wrapper(filename, &local, 0 TSRMLS_CC)) == &php_plain_files_wrapper) {
781 90915 : if (php_check_open_basedir(local TSRMLS_CC)) {
782 161 : RETURN_FALSE;
783 90754 : } else if (PG(safe_mode)) {
784 0 : if (type == FS_IS_X) {
785 0 : if (strstr(local, "..")) {
786 0 : RETURN_FALSE;
787 : } else {
788 0 : char *b = strrchr(local, PHP_DIR_SEPARATOR);
789 0 : snprintf(safe_mode_buf, MAXPATHLEN, "%s%s%s", PG(safe_mode_exec_dir), (b ? "" : "/"), (b ? b : local));
790 0 : local = (char *)&safe_mode_buf;
791 : }
792 0 : } else if (!php_checkuid_ex(local, NULL, CHECKUID_ALLOW_FILE_NOT_EXISTS, CHECKUID_NO_ERRORS)) {
793 0 : RETURN_FALSE;
794 : }
795 : }
796 : }
797 :
798 91187 : if (IS_ACCESS_CHECK(type)) {
799 5635 : if (wrapper == &php_plain_files_wrapper) {
800 :
801 5551 : switch (type) {
802 : #ifdef F_OK
803 : case FS_EXISTS:
804 3182 : RETURN_BOOL(VCWD_ACCESS(local, F_OK) == 0);
805 : break;
806 : #endif
807 : #ifdef W_OK
808 : case FS_IS_W:
809 1094 : RETURN_BOOL(VCWD_ACCESS(local, W_OK) == 0);
810 : break;
811 : #endif
812 : #ifdef R_OK
813 : case FS_IS_R:
814 677 : RETURN_BOOL(VCWD_ACCESS(local, R_OK) == 0);
815 : break;
816 : #endif
817 : #ifdef X_OK
818 : case FS_IS_X:
819 598 : RETURN_BOOL(VCWD_ACCESS(local, X_OK) == 0);
820 : break;
821 : #endif
822 : }
823 : }
824 : }
825 :
826 85636 : if (IS_LINK_OPERATION(type)) {
827 3194 : flags |= PHP_STREAM_URL_STAT_LINK;
828 : }
829 85636 : if (IS_EXISTS_CHECK(type)) {
830 66353 : flags |= PHP_STREAM_URL_STAT_QUIET;
831 : }
832 :
833 85636 : if (php_stream_stat_path_ex((char *)filename, flags, &ssb, NULL)) {
834 : /* Error Occured */
835 220 : if (!IS_EXISTS_CHECK(type)) {
836 81 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "%sstat failed for %s", IS_LINK_OPERATION(type) ? "L" : "", filename);
837 : }
838 220 : RETURN_FALSE;
839 : }
840 :
841 85416 : stat_sb = &ssb.sb;
842 :
843 :
844 : #ifndef NETWARE
845 85416 : if (type >= FS_IS_W && type <= FS_IS_X) {
846 43 : if(ssb.sb.st_uid==getuid()) {
847 0 : rmask=S_IRUSR;
848 0 : wmask=S_IWUSR;
849 0 : xmask=S_IXUSR;
850 43 : } else if(ssb.sb.st_gid==getgid()) {
851 0 : rmask=S_IRGRP;
852 0 : wmask=S_IWGRP;
853 0 : xmask=S_IXGRP;
854 : } else {
855 : int groups, n, i;
856 : gid_t *gids;
857 :
858 43 : groups = getgroups(0, NULL);
859 43 : if(groups > 0) {
860 43 : gids=(gid_t *)safe_emalloc(groups, sizeof(gid_t), 0);
861 43 : n=getgroups(groups, gids);
862 129 : for(i=0;i<n;i++){
863 86 : if(ssb.sb.st_gid==gids[i]) {
864 0 : rmask=S_IRGRP;
865 0 : wmask=S_IWGRP;
866 0 : xmask=S_IXGRP;
867 0 : break;
868 : }
869 : }
870 43 : efree(gids);
871 : }
872 : }
873 : }
874 : #endif
875 :
876 : #ifndef NETWARE
877 85416 : if (IS_ABLE_CHECK(type) && getuid() == 0) {
878 : /* root has special perms on plain_wrapper
879 : But we don't know about root under Netware */
880 0 : if (wrapper == &php_plain_files_wrapper) {
881 0 : if (type == FS_IS_X) {
882 0 : xmask = S_IXROOT;
883 : } else {
884 0 : RETURN_TRUE;
885 : }
886 : }
887 : }
888 : #endif
889 :
890 85416 : switch (type) {
891 : case FS_PERMS:
892 6760 : RETURN_LONG((long)ssb.sb.st_mode);
893 : case FS_INODE:
894 45 : RETURN_LONG((long)ssb.sb.st_ino);
895 : case FS_SIZE:
896 12056 : RETURN_LONG((long)ssb.sb.st_size);
897 : case FS_OWNER:
898 55 : RETURN_LONG((long)ssb.sb.st_uid);
899 : case FS_GROUP:
900 26 : RETURN_LONG((long)ssb.sb.st_gid);
901 : case FS_ATIME:
902 37 : RETURN_LONG((long)ssb.sb.st_atime);
903 : case FS_MTIME:
904 39 : RETURN_LONG((long)ssb.sb.st_mtime);
905 : case FS_CTIME:
906 33 : RETURN_LONG((long)ssb.sb.st_ctime);
907 : case FS_TYPE:
908 26 : if (S_ISLNK(ssb.sb.st_mode)) {
909 2 : RETURN_STRING("link", 1);
910 : }
911 24 : switch(ssb.sb.st_mode & S_IFMT) {
912 1 : case S_IFIFO: RETURN_STRING("fifo", 1);
913 1 : case S_IFCHR: RETURN_STRING("char", 1);
914 9 : case S_IFDIR: RETURN_STRING("dir", 1);
915 1 : case S_IFBLK: RETURN_STRING("block", 1);
916 12 : case S_IFREG: RETURN_STRING("file", 1);
917 : #if defined(S_IFSOCK) && !defined(ZEND_WIN32)&&!defined(__BEOS__)
918 0 : case S_IFSOCK: RETURN_STRING("socket", 1);
919 : #endif
920 : }
921 0 : php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Unknown file type (%d)", ssb.sb.st_mode&S_IFMT);
922 0 : RETURN_STRING("unknown", 1);
923 : case FS_IS_W:
924 9 : RETURN_BOOL((ssb.sb.st_mode & wmask) != 0);
925 : case FS_IS_R:
926 18 : RETURN_BOOL((ssb.sb.st_mode&rmask)!=0);
927 : case FS_IS_X:
928 16 : RETURN_BOOL((ssb.sb.st_mode&xmask)!=0 && !S_ISDIR(ssb.sb.st_mode));
929 : case FS_IS_FILE:
930 930 : RETURN_BOOL(S_ISREG(ssb.sb.st_mode));
931 : case FS_IS_DIR:
932 62105 : RETURN_BOOL(S_ISDIR(ssb.sb.st_mode));
933 : case FS_IS_LINK:
934 3117 : RETURN_BOOL(S_ISLNK(ssb.sb.st_mode));
935 : case FS_EXISTS:
936 19 : RETURN_TRUE; /* the false case was done earlier */
937 : case FS_LSTAT:
938 : /* FALLTHROUGH */
939 : case FS_STAT:
940 125 : array_init(return_value);
941 :
942 125 : MAKE_LONG_ZVAL_INCREF(stat_dev, stat_sb->st_dev);
943 125 : MAKE_LONG_ZVAL_INCREF(stat_ino, stat_sb->st_ino);
944 125 : MAKE_LONG_ZVAL_INCREF(stat_mode, stat_sb->st_mode);
945 125 : MAKE_LONG_ZVAL_INCREF(stat_nlink, stat_sb->st_nlink);
946 125 : MAKE_LONG_ZVAL_INCREF(stat_uid, stat_sb->st_uid);
947 125 : MAKE_LONG_ZVAL_INCREF(stat_gid, stat_sb->st_gid);
948 : #ifdef HAVE_ST_RDEV
949 125 : MAKE_LONG_ZVAL_INCREF(stat_rdev, stat_sb->st_rdev);
950 : #else
951 : MAKE_LONG_ZVAL_INCREF(stat_rdev, -1);
952 : #endif
953 125 : MAKE_LONG_ZVAL_INCREF(stat_size, stat_sb->st_size);
954 125 : MAKE_LONG_ZVAL_INCREF(stat_atime, stat_sb->st_atime);
955 125 : MAKE_LONG_ZVAL_INCREF(stat_mtime, stat_sb->st_mtime);
956 125 : MAKE_LONG_ZVAL_INCREF(stat_ctime, stat_sb->st_ctime);
957 : #ifdef HAVE_ST_BLKSIZE
958 125 : MAKE_LONG_ZVAL_INCREF(stat_blksize, stat_sb->st_blksize);
959 : #else
960 : MAKE_LONG_ZVAL_INCREF(stat_blksize,-1);
961 : #endif
962 : #ifdef HAVE_ST_BLOCKS
963 125 : MAKE_LONG_ZVAL_INCREF(stat_blocks, stat_sb->st_blocks);
964 : #else
965 : MAKE_LONG_ZVAL_INCREF(stat_blocks,-1);
966 : #endif
967 : /* Store numeric indexes in propper order */
968 125 : zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_dev, sizeof(zval *), NULL);
969 125 : zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_ino, sizeof(zval *), NULL);
970 125 : zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_mode, sizeof(zval *), NULL);
971 125 : zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_nlink, sizeof(zval *), NULL);
972 125 : zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_uid, sizeof(zval *), NULL);
973 125 : zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_gid, sizeof(zval *), NULL);
974 :
975 125 : zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_rdev, sizeof(zval *), NULL);
976 125 : zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_size, sizeof(zval *), NULL);
977 125 : zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_atime, sizeof(zval *), NULL);
978 125 : zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_mtime, sizeof(zval *), NULL);
979 125 : zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_ctime, sizeof(zval *), NULL);
980 125 : zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_blksize, sizeof(zval *), NULL);
981 125 : zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_blocks, sizeof(zval *), NULL);
982 :
983 : /* Store string indexes referencing the same zval*/
984 125 : zend_hash_update(HASH_OF(return_value), stat_sb_names[0], strlen(stat_sb_names[0])+1, (void *) &stat_dev, sizeof(zval *), NULL);
985 125 : zend_hash_update(HASH_OF(return_value), stat_sb_names[1], strlen(stat_sb_names[1])+1, (void *) &stat_ino, sizeof(zval *), NULL);
986 125 : zend_hash_update(HASH_OF(return_value), stat_sb_names[2], strlen(stat_sb_names[2])+1, (void *) &stat_mode, sizeof(zval *), NULL);
987 125 : zend_hash_update(HASH_OF(return_value), stat_sb_names[3], strlen(stat_sb_names[3])+1, (void *) &stat_nlink, sizeof(zval *), NULL);
988 125 : zend_hash_update(HASH_OF(return_value), stat_sb_names[4], strlen(stat_sb_names[4])+1, (void *) &stat_uid, sizeof(zval *), NULL);
989 125 : zend_hash_update(HASH_OF(return_value), stat_sb_names[5], strlen(stat_sb_names[5])+1, (void *) &stat_gid, sizeof(zval *), NULL);
990 125 : zend_hash_update(HASH_OF(return_value), stat_sb_names[6], strlen(stat_sb_names[6])+1, (void *) &stat_rdev, sizeof(zval *), NULL);
991 125 : zend_hash_update(HASH_OF(return_value), stat_sb_names[7], strlen(stat_sb_names[7])+1, (void *) &stat_size, sizeof(zval *), NULL);
992 125 : zend_hash_update(HASH_OF(return_value), stat_sb_names[8], strlen(stat_sb_names[8])+1, (void *) &stat_atime, sizeof(zval *), NULL);
993 125 : zend_hash_update(HASH_OF(return_value), stat_sb_names[9], strlen(stat_sb_names[9])+1, (void *) &stat_mtime, sizeof(zval *), NULL);
994 125 : zend_hash_update(HASH_OF(return_value), stat_sb_names[10], strlen(stat_sb_names[10])+1, (void *) &stat_ctime, sizeof(zval *), NULL);
995 125 : zend_hash_update(HASH_OF(return_value), stat_sb_names[11], strlen(stat_sb_names[11])+1, (void *) &stat_blksize, sizeof(zval *), NULL);
996 125 : zend_hash_update(HASH_OF(return_value), stat_sb_names[12], strlen(stat_sb_names[12])+1, (void *) &stat_blocks, sizeof(zval *), NULL);
997 :
998 125 : return;
999 : }
1000 0 : php_error_docref(NULL TSRMLS_CC, E_WARNING, "Didn't understand stat call");
1001 0 : RETURN_FALSE;
1002 : }
1003 : /* }}} */
1004 :
1005 : /* another quickie macro to make defining similar functions easier */
1006 : /* {{{ FileFunction(name, funcnum) */
1007 : #define FileFunction(name, funcnum) \
1008 : void name(INTERNAL_FUNCTION_PARAMETERS) { \
1009 : char *filename; \
1010 : int filename_len; \
1011 : \
1012 : if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &filename, &filename_len) == FAILURE) { \
1013 : return; \
1014 : } \
1015 : \
1016 : php_stat(filename, (php_stat_len) filename_len, funcnum, return_value TSRMLS_CC); \
1017 : }
1018 : /* }}} */
1019 :
1020 : /* {{{ proto int fileperms(string filename)
1021 : Get file permissions */
1022 6784 : FileFunction(PHP_FN(fileperms), FS_PERMS)
1023 : /* }}} */
1024 :
1025 : /* {{{ proto int fileinode(string filename)
1026 : Get file inode */
1027 70 : FileFunction(PHP_FN(fileinode), FS_INODE)
1028 : /* }}} */
1029 :
1030 : /* {{{ proto int filesize(string filename)
1031 : Get file size */
1032 12071 : FileFunction(PHP_FN(filesize), FS_SIZE)
1033 : /* }}} */
1034 :
1035 : /* {{{ proto int fileowner(string filename)
1036 : Get file owner */
1037 80 : FileFunction(PHP_FN(fileowner), FS_OWNER)
1038 : /* }}} */
1039 :
1040 : /* {{{ proto int filegroup(string filename)
1041 : Get file group */
1042 51 : FileFunction(PHP_FN(filegroup), FS_GROUP)
1043 : /* }}} */
1044 :
1045 : /* {{{ proto int fileatime(string filename)
1046 : Get last access time of file */
1047 52 : FileFunction(PHP_FN(fileatime), FS_ATIME)
1048 : /* }}} */
1049 :
1050 : /* {{{ proto int filemtime(string filename)
1051 : Get last modification time of file */
1052 52 : FileFunction(PHP_FN(filemtime), FS_MTIME)
1053 : /* }}} */
1054 :
1055 : /* {{{ proto int filectime(string filename)
1056 : Get inode modification time of file */
1057 47 : FileFunction(PHP_FN(filectime), FS_CTIME)
1058 : /* }}} */
1059 :
1060 : /* {{{ proto string filetype(string filename)
1061 : Get file type */
1062 38 : FileFunction(PHP_FN(filetype), FS_TYPE)
1063 : /* }}} */
1064 :
1065 : /* {{{ proto bool is_writable(string filename)
1066 : Returns true if file can be written */
1067 1116 : FileFunction(PHP_FN(is_writable), FS_IS_W)
1068 : /* }}} */
1069 :
1070 : /* {{{ proto bool is_readable(string filename)
1071 : Returns true if file can be read */
1072 694 : FileFunction(PHP_FN(is_readable), FS_IS_R)
1073 : /* }}} */
1074 :
1075 : /* {{{ proto bool is_executable(string filename)
1076 : Returns true if file is executable */
1077 613 : FileFunction(PHP_FN(is_executable), FS_IS_X)
1078 : /* }}} */
1079 :
1080 : /* {{{ proto bool is_file(string filename)
1081 : Returns true if file is a regular file */
1082 967 : FileFunction(PHP_FN(is_file), FS_IS_FILE)
1083 : /* }}} */
1084 :
1085 : /* {{{ proto bool is_dir(string filename)
1086 : Returns true if file is directory */
1087 59003 : FileFunction(PHP_FN(is_dir), FS_IS_DIR)
1088 : /* }}} */
1089 :
1090 : /* {{{ proto bool is_link(string filename)
1091 : Returns true if file is symbolic link */
1092 67 : FileFunction(PHP_FN(is_link), FS_IS_LINK)
1093 : /* }}} */
1094 :
1095 : /* {{{ proto bool file_exists(string filename)
1096 : Returns true if filename exists */
1097 3246 : FileFunction(PHP_FN(file_exists), FS_EXISTS)
1098 : /* }}} */
1099 :
1100 : /* {{{ proto array lstat(string filename)
1101 : Give information about a file or symbolic link */
1102 46 : FileFunction(php_if_lstat, FS_LSTAT)
1103 : /* }}} */
1104 :
1105 : /* {{{ proto array stat(string filename)
1106 : Give information about a file */
1107 124 : FileFunction(php_if_stat, FS_STAT)
1108 : /* }}} */
1109 :
1110 : /*
1111 : * Local variables:
1112 : * tab-width: 4
1113 : * c-basic-offset: 4
1114 : * End:
1115 : * vim600: sw=4 ts=4 fdm=marker
1116 : * vim<600: sw=4 ts=4
1117 : */
|