Annotation of embedaddon/php/ext/standard/filestat.c, revision 1.1.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>