Annotation of embedaddon/php/ext/standard/filestat.c, revision 1.1

1.1     ! misho       1: /*
        !             2:    +----------------------------------------------------------------------+
        !             3:    | PHP Version 5                                                        |
        !             4:    +----------------------------------------------------------------------+
        !             5:    | Copyright (c) 1997-2012 The PHP Group                                |
        !             6:    +----------------------------------------------------------------------+
        !             7:    | This source file is subject to version 3.01 of the PHP license,      |
        !             8:    | that is bundled with this package in the file LICENSE, and is        |
        !             9:    | available through the world-wide-web at the following url:           |
        !            10:    | http://www.php.net/license/3_01.txt                                  |
        !            11:    | If you did not receive a copy of the PHP license and are unable to   |
        !            12:    | obtain it through the world-wide-web, please send a note to          |
        !            13:    | license@php.net so we can mail you a copy immediately.               |
        !            14:    +----------------------------------------------------------------------+
        !            15:    | Author:  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:  */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>