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