Return to filestat.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / php / ext / standard |
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: ! 19: /* $Id: filestat.c 321634 2012-01-01 13:15:04Z felipe $ */ ! 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: { ! 103: BG(CurrentStatFile)=NULL; ! 104: BG(CurrentLStatFile)=NULL; ! 105: return SUCCESS; ! 106: } ! 107: /* }}} */ ! 108: ! 109: PHP_RSHUTDOWN_FUNCTION(filestat) /* {{{ */ ! 110: { ! 111: if (BG(CurrentStatFile)) { ! 112: efree (BG(CurrentStatFile)); ! 113: BG(CurrentStatFile) = NULL; ! 114: } ! 115: if (BG(CurrentLStatFile)) { ! 116: efree (BG(CurrentLStatFile)); ! 117: BG(CurrentLStatFile) = NULL; ! 118: } ! 119: 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: { ! 198: 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: if (statvfs(path, &buf)) { ! 207: php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", strerror(errno)); ! 208: return FAILURE; ! 209: } ! 210: if (buf.f_frsize) { ! 211: bytestotal = (((double)buf.f_blocks) * ((double)buf.f_frsize)); ! 212: } else { ! 213: 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: *space = bytestotal; ! 225: 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: { ! 235: double bytestotal; ! 236: char *path; ! 237: int path_len; ! 238: ! 239: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &path, &path_len) == FAILURE) { ! 240: return; ! 241: } ! 242: ! 243: if (php_check_open_basedir(path TSRMLS_CC)) { ! 244: RETURN_FALSE; ! 245: } ! 246: ! 247: if (php_disk_total_space(path, &bytestotal TSRMLS_CC) == SUCCESS) { ! 248: RETURN_DOUBLE(bytestotal); ! 249: } ! 250: 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: { ! 330: 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: if (statvfs(path, &buf)) { ! 339: php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", strerror(errno)); ! 340: return FAILURE; ! 341: } ! 342: if (buf.f_frsize) { ! 343: bytesfree = (((double)buf.f_bavail) * ((double)buf.f_frsize)); ! 344: } else { ! 345: 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: *space = bytesfree; ! 360: 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: { ! 370: double bytesfree; ! 371: char *path; ! 372: int path_len; ! 373: ! 374: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &path, &path_len) == FAILURE) { ! 375: return; ! 376: } ! 377: ! 378: if (php_check_open_basedir(path TSRMLS_CC)) { ! 379: RETURN_FALSE; ! 380: } ! 381: ! 382: if (strlen(path) != path_len) { ! 383: RETURN_FALSE; ! 384: } ! 385: ! 386: if (php_disk_free_space(path, &bytesfree TSRMLS_CC) == SUCCESS) { ! 387: RETURN_DOUBLE(bytesfree); ! 388: } ! 389: RETURN_FALSE; ! 390: } ! 391: /* }}} */ ! 392: ! 393: #if !defined(WINDOWS) && !defined(NETWARE) ! 394: static void php_do_chgrp(INTERNAL_FUNCTION_PARAMETERS, int do_lchgrp) /* {{{ */ ! 395: { ! 396: char *filename; ! 397: int filename_len; ! 398: zval *group; ! 399: gid_t gid; ! 400: int ret; ! 401: ! 402: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz/", &filename, &filename_len, &group) == FAILURE) { ! 403: RETURN_FALSE; ! 404: } ! 405: ! 406: if (strlen(filename) != filename_len) { ! 407: RETURN_FALSE; ! 408: } ! 409: ! 410: if (Z_TYPE_P(group) == IS_LONG) { ! 411: gid = (gid_t)Z_LVAL_P(group); ! 412: } else if (Z_TYPE_P(group) == IS_STRING) { ! 413: #if defined(ZTS) && defined(HAVE_GETGRNAM_R) && defined(_SC_GETGR_R_SIZE_MAX) ! 414: struct group gr; ! 415: struct group *retgrptr; ! 416: long grbuflen = sysconf(_SC_GETGR_R_SIZE_MAX); ! 417: char *grbuf; ! 418: ! 419: if (grbuflen < 1) { ! 420: RETURN_FALSE; ! 421: } ! 422: ! 423: grbuf = emalloc(grbuflen); ! 424: if (getgrnam_r(Z_STRVAL_P(group), &gr, grbuf, grbuflen, &retgrptr) != 0 || retgrptr == NULL) { ! 425: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find gid for %s", Z_STRVAL_P(group)); ! 426: efree(grbuf); ! 427: RETURN_FALSE; ! 428: } ! 429: efree(grbuf); ! 430: gid = gr.gr_gid; ! 431: #else ! 432: struct group *gr = getgrnam(Z_STRVAL_P(group)); ! 433: ! 434: if (!gr) { ! 435: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find gid for %s", Z_STRVAL_P(group)); ! 436: RETURN_FALSE; ! 437: } ! 438: gid = gr->gr_gid; ! 439: #endif ! 440: } else { ! 441: php_error_docref(NULL TSRMLS_CC, E_WARNING, "parameter 2 should be string or integer, %s given", zend_zval_type_name(group)); ! 442: RETURN_FALSE; ! 443: } ! 444: ! 445: if (PG(safe_mode) &&(!php_checkuid(filename, NULL, CHECKUID_ALLOW_FILE_NOT_EXISTS))) { ! 446: RETURN_FALSE; ! 447: } ! 448: ! 449: /* Check the basedir */ ! 450: if (php_check_open_basedir(filename TSRMLS_CC)) { ! 451: RETURN_FALSE; ! 452: } ! 453: ! 454: if (do_lchgrp) { ! 455: #if HAVE_LCHOWN ! 456: ret = VCWD_LCHOWN(filename, -1, gid); ! 457: #endif ! 458: } else { ! 459: ret = VCWD_CHOWN(filename, -1, gid); ! 460: } ! 461: if (ret == -1) { ! 462: php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", strerror(errno)); ! 463: RETURN_FALSE; ! 464: } ! 465: RETURN_TRUE; ! 466: } ! 467: /* }}} */ ! 468: #endif ! 469: ! 470: #ifndef NETWARE ! 471: /* {{{ proto bool chgrp(string filename, mixed group) ! 472: Change file group */ ! 473: PHP_FUNCTION(chgrp) ! 474: { ! 475: #if !defined(WINDOWS) ! 476: php_do_chgrp(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0); ! 477: #else ! 478: RETURN_FALSE; ! 479: #endif ! 480: } ! 481: /* }}} */ ! 482: ! 483: /* {{{ proto bool lchgrp(string filename, mixed group) ! 484: Change symlink group */ ! 485: #if HAVE_LCHOWN ! 486: PHP_FUNCTION(lchgrp) ! 487: { ! 488: # if !defined(WINDOWS) ! 489: php_do_chgrp(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1); ! 490: # else ! 491: RETURN_FALSE; ! 492: # endif ! 493: } ! 494: #endif ! 495: /* }}} */ ! 496: #endif /* !NETWARE */ ! 497: ! 498: #if !defined(WINDOWS) && !defined(NETWARE) ! 499: static void php_do_chown(INTERNAL_FUNCTION_PARAMETERS, int do_lchown) /* {{{ */ ! 500: { ! 501: char *filename; ! 502: int filename_len; ! 503: zval *user; ! 504: uid_t uid; ! 505: int ret; ! 506: ! 507: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz/", &filename, &filename_len, &user) == FAILURE) { ! 508: return; ! 509: } ! 510: ! 511: if (strlen(filename) != filename_len) { ! 512: RETURN_FALSE; ! 513: } ! 514: ! 515: if (Z_TYPE_P(user) == IS_LONG) { ! 516: uid = (uid_t)Z_LVAL_P(user); ! 517: } else if (Z_TYPE_P(user) == IS_STRING) { ! 518: #if defined(ZTS) && defined(_SC_GETPW_R_SIZE_MAX) && defined(HAVE_GETPWNAM_R) ! 519: struct passwd pw; ! 520: struct passwd *retpwptr = NULL; ! 521: long pwbuflen = sysconf(_SC_GETPW_R_SIZE_MAX); ! 522: char *pwbuf; ! 523: ! 524: if (pwbuflen < 1) { ! 525: RETURN_FALSE; ! 526: } ! 527: ! 528: pwbuf = emalloc(pwbuflen); ! 529: if (getpwnam_r(Z_STRVAL_P(user), &pw, pwbuf, pwbuflen, &retpwptr) != 0 || retpwptr == NULL) { ! 530: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find uid for %s", Z_STRVAL_P(user)); ! 531: efree(pwbuf); ! 532: RETURN_FALSE; ! 533: } ! 534: efree(pwbuf); ! 535: uid = pw.pw_uid; ! 536: #else ! 537: struct passwd *pw = getpwnam(Z_STRVAL_P(user)); ! 538: ! 539: if (!pw) { ! 540: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find uid for %s", Z_STRVAL_P(user)); ! 541: RETURN_FALSE; ! 542: } ! 543: uid = pw->pw_uid; ! 544: #endif ! 545: } else { ! 546: php_error_docref(NULL TSRMLS_CC, E_WARNING, "parameter 2 should be string or integer, %s given", zend_zval_type_name(user)); ! 547: RETURN_FALSE; ! 548: } ! 549: ! 550: if (PG(safe_mode) && (!php_checkuid(filename, NULL, CHECKUID_ALLOW_FILE_NOT_EXISTS))) { ! 551: RETURN_FALSE; ! 552: } ! 553: ! 554: /* Check the basedir */ ! 555: if (php_check_open_basedir(filename TSRMLS_CC)) { ! 556: RETURN_FALSE; ! 557: } ! 558: ! 559: if (do_lchown) { ! 560: #if HAVE_LCHOWN ! 561: ret = VCWD_LCHOWN(filename, uid, -1); ! 562: #endif ! 563: } else { ! 564: ret = VCWD_CHOWN(filename, uid, -1); ! 565: } ! 566: if (ret == -1) { ! 567: php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", strerror(errno)); ! 568: RETURN_FALSE; ! 569: } ! 570: } ! 571: /* }}} */ ! 572: #endif ! 573: ! 574: #ifndef NETWARE ! 575: /* {{{ proto bool chown (string filename, mixed user) ! 576: Change file owner */ ! 577: PHP_FUNCTION(chown) ! 578: { ! 579: #if !defined(WINDOWS) ! 580: RETVAL_TRUE; ! 581: php_do_chown(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0); ! 582: #else ! 583: RETURN_FALSE; ! 584: #endif ! 585: } ! 586: /* }}} */ ! 587: ! 588: /* {{{ proto bool chown (string filename, mixed user) ! 589: Change file owner */ ! 590: #if HAVE_LCHOWN ! 591: PHP_FUNCTION(lchown) ! 592: { ! 593: # if !defined(WINDOWS) ! 594: RETVAL_TRUE; ! 595: php_do_chown(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1); ! 596: # else ! 597: RETURN_FALSE; ! 598: # endif ! 599: } ! 600: #endif ! 601: /* }}} */ ! 602: #endif /* !NETWARE */ ! 603: ! 604: /* {{{ proto bool chmod(string filename, int mode) ! 605: Change file mode */ ! 606: PHP_FUNCTION(chmod) ! 607: { ! 608: char *filename; ! 609: int filename_len; ! 610: long mode; ! 611: int ret; ! 612: mode_t imode; ! 613: ! 614: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sl", &filename, &filename_len, &mode) == FAILURE) { ! 615: return; ! 616: } ! 617: ! 618: if (PG(safe_mode) &&(!php_checkuid(filename, NULL, CHECKUID_ALLOW_FILE_NOT_EXISTS))) { ! 619: RETURN_FALSE; ! 620: } ! 621: ! 622: if (strlen(filename) != filename_len) { ! 623: RETURN_FALSE; ! 624: } ! 625: ! 626: /* Check the basedir */ ! 627: if (php_check_open_basedir(filename TSRMLS_CC)) { ! 628: RETURN_FALSE; ! 629: } ! 630: ! 631: imode = (mode_t) mode; ! 632: /* In safe mode, do not allow to setuid files. ! 633: * Setuiding files could allow users to gain privileges ! 634: * that safe mode doesn't give them. */ ! 635: ! 636: if (PG(safe_mode)) { ! 637: php_stream_statbuf ssb; ! 638: if (php_stream_stat_path_ex(filename, 0, &ssb, NULL)) { ! 639: php_error_docref(NULL TSRMLS_CC, E_WARNING, "stat failed for %s", filename); ! 640: RETURN_FALSE; ! 641: } ! 642: if ((imode & 04000) != 0 && (ssb.sb.st_mode & 04000) == 0) { ! 643: imode ^= 04000; ! 644: } ! 645: if ((imode & 02000) != 0 && (ssb.sb.st_mode & 02000) == 0) { ! 646: imode ^= 02000; ! 647: } ! 648: if ((imode & 01000) != 0 && (ssb.sb.st_mode & 01000) == 0) { ! 649: imode ^= 01000; ! 650: } ! 651: } ! 652: ! 653: ret = VCWD_CHMOD(filename, imode); ! 654: if (ret == -1) { ! 655: php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", strerror(errno)); ! 656: RETURN_FALSE; ! 657: } ! 658: RETURN_TRUE; ! 659: } ! 660: /* }}} */ ! 661: ! 662: #if HAVE_UTIME ! 663: /* {{{ proto bool touch(string filename [, int time [, int atime]]) ! 664: Set modification time of file */ ! 665: PHP_FUNCTION(touch) ! 666: { ! 667: char *filename; ! 668: int filename_len; ! 669: long filetime = 0, fileatime = 0; ! 670: int ret, argc = ZEND_NUM_ARGS(); ! 671: FILE *file; ! 672: struct utimbuf newtimebuf; ! 673: struct utimbuf *newtime = &newtimebuf; ! 674: ! 675: if (zend_parse_parameters(argc TSRMLS_CC, "s|ll", &filename, &filename_len, &filetime, &fileatime) == FAILURE) { ! 676: return; ! 677: } ! 678: ! 679: if (strlen(filename) != filename_len) { ! 680: RETURN_FALSE; ! 681: } ! 682: ! 683: switch (argc) { ! 684: case 1: ! 685: #ifdef HAVE_UTIME_NULL ! 686: newtime = NULL; ! 687: #else ! 688: newtime->modtime = newtime->actime = time(NULL); ! 689: #endif ! 690: break; ! 691: case 2: ! 692: newtime->modtime = newtime->actime = filetime; ! 693: break; ! 694: case 3: ! 695: newtime->modtime = filetime; ! 696: newtime->actime = fileatime; ! 697: break; ! 698: default: ! 699: /* Never reached */ ! 700: WRONG_PARAM_COUNT; ! 701: } ! 702: ! 703: /* Safe-mode */ ! 704: if (PG(safe_mode) && (!php_checkuid(filename, NULL, CHECKUID_CHECK_FILE_AND_DIR))) { ! 705: RETURN_FALSE; ! 706: } ! 707: ! 708: /* Check the basedir */ ! 709: if (php_check_open_basedir(filename TSRMLS_CC)) { ! 710: RETURN_FALSE; ! 711: } ! 712: ! 713: /* create the file if it doesn't exist already */ ! 714: if (VCWD_ACCESS(filename, F_OK) != 0) { ! 715: file = VCWD_FOPEN(filename, "w"); ! 716: if (file == NULL) { ! 717: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to create file %s because %s", filename, strerror(errno)); ! 718: RETURN_FALSE; ! 719: } ! 720: fclose(file); ! 721: } ! 722: ! 723: ret = VCWD_UTIME(filename, newtime); ! 724: if (ret == -1) { ! 725: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Utime failed: %s", strerror(errno)); ! 726: RETURN_FALSE; ! 727: } ! 728: RETURN_TRUE; ! 729: } ! 730: /* }}} */ ! 731: #endif ! 732: ! 733: /* {{{ php_clear_stat_cache() ! 734: */ ! 735: PHPAPI void php_clear_stat_cache(zend_bool clear_realpath_cache, const char *filename, int filename_len TSRMLS_DC) ! 736: { ! 737: /* always clear CurrentStatFile and CurrentLStatFile even if filename is not NULL ! 738: * as it may contain outdated data (e.g. "nlink" for a directory when deleting a file ! 739: * in this directory, as shown by lstat_stat_variation9.phpt) */ ! 740: ! 741: if (BG(CurrentStatFile)) { ! 742: efree(BG(CurrentStatFile)); ! 743: BG(CurrentStatFile) = NULL; ! 744: } ! 745: if (BG(CurrentLStatFile)) { ! 746: efree(BG(CurrentLStatFile)); ! 747: BG(CurrentLStatFile) = NULL; ! 748: } ! 749: if (clear_realpath_cache) { ! 750: if (filename != NULL) { ! 751: realpath_cache_del(filename, filename_len TSRMLS_CC); ! 752: } else { ! 753: realpath_cache_clean(TSRMLS_C); ! 754: } ! 755: } ! 756: } ! 757: /* }}} */ ! 758: ! 759: /* {{{ proto void clearstatcache([bool clear_realpath_cache[, string filename]]) ! 760: Clear file stat cache */ ! 761: PHP_FUNCTION(clearstatcache) ! 762: { ! 763: zend_bool clear_realpath_cache = 0; ! 764: char *filename = NULL; ! 765: int filename_len = 0; ! 766: ! 767: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|bs", &clear_realpath_cache, &filename, &filename_len) == FAILURE) { ! 768: return; ! 769: } ! 770: ! 771: php_clear_stat_cache(clear_realpath_cache, filename, filename_len TSRMLS_CC); ! 772: } ! 773: /* }}} */ ! 774: ! 775: #define IS_LINK_OPERATION(__t) ((__t) == FS_TYPE || (__t) == FS_IS_LINK || (__t) == FS_LSTAT) ! 776: #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) ! 777: #define IS_ABLE_CHECK(__t) ((__t) == FS_IS_R || (__t) == FS_IS_W || (__t) == FS_IS_X) ! 778: #define IS_ACCESS_CHECK(__t) (IS_ABLE_CHECK(type) || (__t) == FS_EXISTS) ! 779: ! 780: /* {{{ php_stat ! 781: */ ! 782: PHPAPI void php_stat(const char *filename, php_stat_len filename_length, int type, zval *return_value TSRMLS_DC) ! 783: { ! 784: zval *stat_dev, *stat_ino, *stat_mode, *stat_nlink, *stat_uid, *stat_gid, *stat_rdev, ! 785: *stat_size, *stat_atime, *stat_mtime, *stat_ctime, *stat_blksize, *stat_blocks; ! 786: struct stat *stat_sb; ! 787: php_stream_statbuf ssb; ! 788: int flags = 0, rmask=S_IROTH, wmask=S_IWOTH, xmask=S_IXOTH; /* access rights defaults to other */ ! 789: char *stat_sb_names[13] = { ! 790: "dev", "ino", "mode", "nlink", "uid", "gid", "rdev", ! 791: "size", "atime", "mtime", "ctime", "blksize", "blocks" ! 792: }; ! 793: char *local; ! 794: php_stream_wrapper *wrapper; ! 795: char safe_mode_buf[MAXPATHLEN]; ! 796: ! 797: if (!filename_length) { ! 798: RETURN_FALSE; ! 799: } ! 800: ! 801: if (strlen(filename) != filename_length) { ! 802: RETURN_FALSE; ! 803: } ! 804: ! 805: if ((wrapper = php_stream_locate_url_wrapper(filename, &local, 0 TSRMLS_CC)) == &php_plain_files_wrapper) { ! 806: if (php_check_open_basedir(local TSRMLS_CC)) { ! 807: RETURN_FALSE; ! 808: } else if (PG(safe_mode)) { ! 809: if (type == FS_IS_X) { ! 810: if (strstr(local, "..")) { ! 811: RETURN_FALSE; ! 812: } else { ! 813: char *b = strrchr(local, PHP_DIR_SEPARATOR); ! 814: snprintf(safe_mode_buf, MAXPATHLEN, "%s%s%s", PG(safe_mode_exec_dir), (b ? "" : "/"), (b ? b : local)); ! 815: local = (char *)&safe_mode_buf; ! 816: } ! 817: } else if (!php_checkuid_ex(local, NULL, CHECKUID_ALLOW_FILE_NOT_EXISTS, CHECKUID_NO_ERRORS)) { ! 818: RETURN_FALSE; ! 819: } ! 820: } ! 821: } ! 822: ! 823: if (IS_ACCESS_CHECK(type)) { ! 824: if (wrapper == &php_plain_files_wrapper) { ! 825: ! 826: switch (type) { ! 827: #ifdef F_OK ! 828: case FS_EXISTS: ! 829: RETURN_BOOL(VCWD_ACCESS(local, F_OK) == 0); ! 830: break; ! 831: #endif ! 832: #ifdef W_OK ! 833: case FS_IS_W: ! 834: RETURN_BOOL(VCWD_ACCESS(local, W_OK) == 0); ! 835: break; ! 836: #endif ! 837: #ifdef R_OK ! 838: case FS_IS_R: ! 839: RETURN_BOOL(VCWD_ACCESS(local, R_OK) == 0); ! 840: break; ! 841: #endif ! 842: #ifdef X_OK ! 843: case FS_IS_X: ! 844: RETURN_BOOL(VCWD_ACCESS(local, X_OK) == 0); ! 845: break; ! 846: #endif ! 847: } ! 848: } ! 849: } ! 850: ! 851: if (IS_LINK_OPERATION(type)) { ! 852: flags |= PHP_STREAM_URL_STAT_LINK; ! 853: } ! 854: if (IS_EXISTS_CHECK(type)) { ! 855: flags |= PHP_STREAM_URL_STAT_QUIET; ! 856: } ! 857: ! 858: if (php_stream_stat_path_ex((char *)filename, flags, &ssb, NULL)) { ! 859: /* Error Occured */ ! 860: if (!IS_EXISTS_CHECK(type)) { ! 861: php_error_docref(NULL TSRMLS_CC, E_WARNING, "%sstat failed for %s", IS_LINK_OPERATION(type) ? "L" : "", filename); ! 862: } ! 863: RETURN_FALSE; ! 864: } ! 865: ! 866: stat_sb = &ssb.sb; ! 867: ! 868: ! 869: #ifndef NETWARE ! 870: if (type >= FS_IS_W && type <= FS_IS_X) { ! 871: if(ssb.sb.st_uid==getuid()) { ! 872: rmask=S_IRUSR; ! 873: wmask=S_IWUSR; ! 874: xmask=S_IXUSR; ! 875: } else if(ssb.sb.st_gid==getgid()) { ! 876: rmask=S_IRGRP; ! 877: wmask=S_IWGRP; ! 878: xmask=S_IXGRP; ! 879: } else { ! 880: int groups, n, i; ! 881: gid_t *gids; ! 882: ! 883: groups = getgroups(0, NULL); ! 884: if(groups > 0) { ! 885: gids=(gid_t *)safe_emalloc(groups, sizeof(gid_t), 0); ! 886: n=getgroups(groups, gids); ! 887: for(i=0;i<n;i++){ ! 888: if(ssb.sb.st_gid==gids[i]) { ! 889: rmask=S_IRGRP; ! 890: wmask=S_IWGRP; ! 891: xmask=S_IXGRP; ! 892: break; ! 893: } ! 894: } ! 895: efree(gids); ! 896: } ! 897: } ! 898: } ! 899: #endif ! 900: ! 901: #ifndef NETWARE ! 902: if (IS_ABLE_CHECK(type) && getuid() == 0) { ! 903: /* root has special perms on plain_wrapper ! 904: But we don't know about root under Netware */ ! 905: if (wrapper == &php_plain_files_wrapper) { ! 906: if (type == FS_IS_X) { ! 907: xmask = S_IXROOT; ! 908: } else { ! 909: RETURN_TRUE; ! 910: } ! 911: } ! 912: } ! 913: #endif ! 914: ! 915: switch (type) { ! 916: case FS_PERMS: ! 917: RETURN_LONG((long)ssb.sb.st_mode); ! 918: case FS_INODE: ! 919: RETURN_LONG((long)ssb.sb.st_ino); ! 920: case FS_SIZE: ! 921: RETURN_LONG((long)ssb.sb.st_size); ! 922: case FS_OWNER: ! 923: RETURN_LONG((long)ssb.sb.st_uid); ! 924: case FS_GROUP: ! 925: RETURN_LONG((long)ssb.sb.st_gid); ! 926: case FS_ATIME: ! 927: RETURN_LONG((long)ssb.sb.st_atime); ! 928: case FS_MTIME: ! 929: RETURN_LONG((long)ssb.sb.st_mtime); ! 930: case FS_CTIME: ! 931: RETURN_LONG((long)ssb.sb.st_ctime); ! 932: case FS_TYPE: ! 933: if (S_ISLNK(ssb.sb.st_mode)) { ! 934: RETURN_STRING("link", 1); ! 935: } ! 936: switch(ssb.sb.st_mode & S_IFMT) { ! 937: case S_IFIFO: RETURN_STRING("fifo", 1); ! 938: case S_IFCHR: RETURN_STRING("char", 1); ! 939: case S_IFDIR: RETURN_STRING("dir", 1); ! 940: case S_IFBLK: RETURN_STRING("block", 1); ! 941: case S_IFREG: RETURN_STRING("file", 1); ! 942: #if defined(S_IFSOCK) && !defined(ZEND_WIN32)&&!defined(__BEOS__) ! 943: case S_IFSOCK: RETURN_STRING("socket", 1); ! 944: #endif ! 945: } ! 946: php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Unknown file type (%d)", ssb.sb.st_mode&S_IFMT); ! 947: RETURN_STRING("unknown", 1); ! 948: case FS_IS_W: ! 949: RETURN_BOOL((ssb.sb.st_mode & wmask) != 0); ! 950: case FS_IS_R: ! 951: RETURN_BOOL((ssb.sb.st_mode&rmask)!=0); ! 952: case FS_IS_X: ! 953: RETURN_BOOL((ssb.sb.st_mode&xmask)!=0 && !S_ISDIR(ssb.sb.st_mode)); ! 954: case FS_IS_FILE: ! 955: RETURN_BOOL(S_ISREG(ssb.sb.st_mode)); ! 956: case FS_IS_DIR: ! 957: RETURN_BOOL(S_ISDIR(ssb.sb.st_mode)); ! 958: case FS_IS_LINK: ! 959: RETURN_BOOL(S_ISLNK(ssb.sb.st_mode)); ! 960: case FS_EXISTS: ! 961: RETURN_TRUE; /* the false case was done earlier */ ! 962: case FS_LSTAT: ! 963: /* FALLTHROUGH */ ! 964: case FS_STAT: ! 965: array_init(return_value); ! 966: ! 967: MAKE_LONG_ZVAL_INCREF(stat_dev, stat_sb->st_dev); ! 968: MAKE_LONG_ZVAL_INCREF(stat_ino, stat_sb->st_ino); ! 969: MAKE_LONG_ZVAL_INCREF(stat_mode, stat_sb->st_mode); ! 970: MAKE_LONG_ZVAL_INCREF(stat_nlink, stat_sb->st_nlink); ! 971: MAKE_LONG_ZVAL_INCREF(stat_uid, stat_sb->st_uid); ! 972: MAKE_LONG_ZVAL_INCREF(stat_gid, stat_sb->st_gid); ! 973: #ifdef HAVE_ST_RDEV ! 974: MAKE_LONG_ZVAL_INCREF(stat_rdev, stat_sb->st_rdev); ! 975: #else ! 976: MAKE_LONG_ZVAL_INCREF(stat_rdev, -1); ! 977: #endif ! 978: MAKE_LONG_ZVAL_INCREF(stat_size, stat_sb->st_size); ! 979: MAKE_LONG_ZVAL_INCREF(stat_atime, stat_sb->st_atime); ! 980: MAKE_LONG_ZVAL_INCREF(stat_mtime, stat_sb->st_mtime); ! 981: MAKE_LONG_ZVAL_INCREF(stat_ctime, stat_sb->st_ctime); ! 982: #ifdef HAVE_ST_BLKSIZE ! 983: MAKE_LONG_ZVAL_INCREF(stat_blksize, stat_sb->st_blksize); ! 984: #else ! 985: MAKE_LONG_ZVAL_INCREF(stat_blksize,-1); ! 986: #endif ! 987: #ifdef HAVE_ST_BLOCKS ! 988: MAKE_LONG_ZVAL_INCREF(stat_blocks, stat_sb->st_blocks); ! 989: #else ! 990: MAKE_LONG_ZVAL_INCREF(stat_blocks,-1); ! 991: #endif ! 992: /* Store numeric indexes in propper order */ ! 993: zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_dev, sizeof(zval *), NULL); ! 994: zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_ino, sizeof(zval *), NULL); ! 995: zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_mode, sizeof(zval *), NULL); ! 996: zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_nlink, sizeof(zval *), NULL); ! 997: zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_uid, sizeof(zval *), NULL); ! 998: zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_gid, sizeof(zval *), NULL); ! 999: ! 1000: zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_rdev, sizeof(zval *), NULL); ! 1001: zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_size, sizeof(zval *), NULL); ! 1002: zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_atime, sizeof(zval *), NULL); ! 1003: zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_mtime, sizeof(zval *), NULL); ! 1004: zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_ctime, sizeof(zval *), NULL); ! 1005: zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_blksize, sizeof(zval *), NULL); ! 1006: zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_blocks, sizeof(zval *), NULL); ! 1007: ! 1008: /* Store string indexes referencing the same zval*/ ! 1009: zend_hash_update(HASH_OF(return_value), stat_sb_names[0], strlen(stat_sb_names[0])+1, (void *) &stat_dev, sizeof(zval *), NULL); ! 1010: zend_hash_update(HASH_OF(return_value), stat_sb_names[1], strlen(stat_sb_names[1])+1, (void *) &stat_ino, sizeof(zval *), NULL); ! 1011: zend_hash_update(HASH_OF(return_value), stat_sb_names[2], strlen(stat_sb_names[2])+1, (void *) &stat_mode, sizeof(zval *), NULL); ! 1012: zend_hash_update(HASH_OF(return_value), stat_sb_names[3], strlen(stat_sb_names[3])+1, (void *) &stat_nlink, sizeof(zval *), NULL); ! 1013: zend_hash_update(HASH_OF(return_value), stat_sb_names[4], strlen(stat_sb_names[4])+1, (void *) &stat_uid, sizeof(zval *), NULL); ! 1014: zend_hash_update(HASH_OF(return_value), stat_sb_names[5], strlen(stat_sb_names[5])+1, (void *) &stat_gid, sizeof(zval *), NULL); ! 1015: zend_hash_update(HASH_OF(return_value), stat_sb_names[6], strlen(stat_sb_names[6])+1, (void *) &stat_rdev, sizeof(zval *), NULL); ! 1016: zend_hash_update(HASH_OF(return_value), stat_sb_names[7], strlen(stat_sb_names[7])+1, (void *) &stat_size, sizeof(zval *), NULL); ! 1017: zend_hash_update(HASH_OF(return_value), stat_sb_names[8], strlen(stat_sb_names[8])+1, (void *) &stat_atime, sizeof(zval *), NULL); ! 1018: zend_hash_update(HASH_OF(return_value), stat_sb_names[9], strlen(stat_sb_names[9])+1, (void *) &stat_mtime, sizeof(zval *), NULL); ! 1019: zend_hash_update(HASH_OF(return_value), stat_sb_names[10], strlen(stat_sb_names[10])+1, (void *) &stat_ctime, sizeof(zval *), NULL); ! 1020: zend_hash_update(HASH_OF(return_value), stat_sb_names[11], strlen(stat_sb_names[11])+1, (void *) &stat_blksize, sizeof(zval *), NULL); ! 1021: zend_hash_update(HASH_OF(return_value), stat_sb_names[12], strlen(stat_sb_names[12])+1, (void *) &stat_blocks, sizeof(zval *), NULL); ! 1022: ! 1023: return; ! 1024: } ! 1025: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Didn't understand stat call"); ! 1026: RETURN_FALSE; ! 1027: } ! 1028: /* }}} */ ! 1029: ! 1030: /* another quickie macro to make defining similar functions easier */ ! 1031: /* {{{ FileFunction(name, funcnum) */ ! 1032: #define FileFunction(name, funcnum) \ ! 1033: void name(INTERNAL_FUNCTION_PARAMETERS) { \ ! 1034: char *filename; \ ! 1035: int filename_len; \ ! 1036: \ ! 1037: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &filename, &filename_len) == FAILURE) { \ ! 1038: return; \ ! 1039: } \ ! 1040: \ ! 1041: php_stat(filename, (php_stat_len) filename_len, funcnum, return_value TSRMLS_CC); \ ! 1042: } ! 1043: /* }}} */ ! 1044: ! 1045: /* {{{ proto int fileperms(string filename) ! 1046: Get file permissions */ ! 1047: FileFunction(PHP_FN(fileperms), FS_PERMS) ! 1048: /* }}} */ ! 1049: ! 1050: /* {{{ proto int fileinode(string filename) ! 1051: Get file inode */ ! 1052: FileFunction(PHP_FN(fileinode), FS_INODE) ! 1053: /* }}} */ ! 1054: ! 1055: /* {{{ proto int filesize(string filename) ! 1056: Get file size */ ! 1057: FileFunction(PHP_FN(filesize), FS_SIZE) ! 1058: /* }}} */ ! 1059: ! 1060: /* {{{ proto int fileowner(string filename) ! 1061: Get file owner */ ! 1062: FileFunction(PHP_FN(fileowner), FS_OWNER) ! 1063: /* }}} */ ! 1064: ! 1065: /* {{{ proto int filegroup(string filename) ! 1066: Get file group */ ! 1067: FileFunction(PHP_FN(filegroup), FS_GROUP) ! 1068: /* }}} */ ! 1069: ! 1070: /* {{{ proto int fileatime(string filename) ! 1071: Get last access time of file */ ! 1072: FileFunction(PHP_FN(fileatime), FS_ATIME) ! 1073: /* }}} */ ! 1074: ! 1075: /* {{{ proto int filemtime(string filename) ! 1076: Get last modification time of file */ ! 1077: FileFunction(PHP_FN(filemtime), FS_MTIME) ! 1078: /* }}} */ ! 1079: ! 1080: /* {{{ proto int filectime(string filename) ! 1081: Get inode modification time of file */ ! 1082: FileFunction(PHP_FN(filectime), FS_CTIME) ! 1083: /* }}} */ ! 1084: ! 1085: /* {{{ proto string filetype(string filename) ! 1086: Get file type */ ! 1087: FileFunction(PHP_FN(filetype), FS_TYPE) ! 1088: /* }}} */ ! 1089: ! 1090: /* {{{ proto bool is_writable(string filename) ! 1091: Returns true if file can be written */ ! 1092: FileFunction(PHP_FN(is_writable), FS_IS_W) ! 1093: /* }}} */ ! 1094: ! 1095: /* {{{ proto bool is_readable(string filename) ! 1096: Returns true if file can be read */ ! 1097: FileFunction(PHP_FN(is_readable), FS_IS_R) ! 1098: /* }}} */ ! 1099: ! 1100: /* {{{ proto bool is_executable(string filename) ! 1101: Returns true if file is executable */ ! 1102: FileFunction(PHP_FN(is_executable), FS_IS_X) ! 1103: /* }}} */ ! 1104: ! 1105: /* {{{ proto bool is_file(string filename) ! 1106: Returns true if file is a regular file */ ! 1107: FileFunction(PHP_FN(is_file), FS_IS_FILE) ! 1108: /* }}} */ ! 1109: ! 1110: /* {{{ proto bool is_dir(string filename) ! 1111: Returns true if file is directory */ ! 1112: FileFunction(PHP_FN(is_dir), FS_IS_DIR) ! 1113: /* }}} */ ! 1114: ! 1115: /* {{{ proto bool is_link(string filename) ! 1116: Returns true if file is symbolic link */ ! 1117: FileFunction(PHP_FN(is_link), FS_IS_LINK) ! 1118: /* }}} */ ! 1119: ! 1120: /* {{{ proto bool file_exists(string filename) ! 1121: Returns true if filename exists */ ! 1122: FileFunction(PHP_FN(file_exists), FS_EXISTS) ! 1123: /* }}} */ ! 1124: ! 1125: /* {{{ proto array lstat(string filename) ! 1126: Give information about a file or symbolic link */ ! 1127: FileFunction(php_if_lstat, FS_LSTAT) ! 1128: /* }}} */ ! 1129: ! 1130: /* {{{ proto array stat(string filename) ! 1131: Give information about a file */ ! 1132: FileFunction(php_if_stat, FS_STAT) ! 1133: /* }}} */ ! 1134: ! 1135: /* {{{ proto bool realpath_cache_size() ! 1136: Get current size of realpath cache */ ! 1137: PHP_FUNCTION(realpath_cache_size) ! 1138: { ! 1139: if (zend_parse_parameters_none() == FAILURE) { ! 1140: return; ! 1141: } ! 1142: RETURN_LONG(realpath_cache_size(TSRMLS_C)); ! 1143: } ! 1144: ! 1145: /* {{{ proto bool realpath_cache_get() ! 1146: Get current size of realpath cache */ ! 1147: PHP_FUNCTION(realpath_cache_get) ! 1148: { ! 1149: realpath_cache_bucket **buckets = realpath_cache_get_buckets(TSRMLS_C), **end = buckets + realpath_cache_max_buckets(TSRMLS_C); ! 1150: ! 1151: if (zend_parse_parameters_none() == FAILURE) { ! 1152: return; ! 1153: } ! 1154: ! 1155: array_init(return_value); ! 1156: while(buckets < end) { ! 1157: realpath_cache_bucket *bucket = *buckets; ! 1158: while(bucket) { ! 1159: zval *entry; ! 1160: MAKE_STD_ZVAL(entry); ! 1161: array_init(entry); ! 1162: ! 1163: add_assoc_long(entry, "key", bucket->key); ! 1164: add_assoc_bool(entry, "is_dir", bucket->is_dir); ! 1165: add_assoc_stringl(entry, "realpath", bucket->realpath, bucket->realpath_len, 1); ! 1166: add_assoc_long(entry, "expires", bucket->expires); ! 1167: #ifdef PHP_WIN32 ! 1168: add_assoc_bool(entry, "is_rvalid", bucket->is_rvalid); ! 1169: add_assoc_bool(entry, "is_wvalid", bucket->is_wvalid); ! 1170: add_assoc_bool(entry, "is_readable", bucket->is_readable); ! 1171: add_assoc_bool(entry, "is_writable", bucket->is_writable); ! 1172: #endif ! 1173: zend_hash_update(Z_ARRVAL_P(return_value), bucket->path, bucket->path_len+1, &entry, sizeof(zval *), NULL); ! 1174: bucket = bucket->next; ! 1175: } ! 1176: buckets++; ! 1177: } ! 1178: } ! 1179: ! 1180: /* ! 1181: * Local variables: ! 1182: * tab-width: 4 ! 1183: * c-basic-offset: 4 ! 1184: * End: ! 1185: * vim600: sw=4 ts=4 fdm=marker ! 1186: * vim<600: sw=4 ts=4 ! 1187: */