PHP  
 PHP: Test and Code Coverage Analysis
downloads | QA | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | my php.net 
 

LCOV - code coverage report
Current view: top level - ext/standard - filestat.c (source / functions) Hit Total Coverage
Test: PHP Code Coverage Lines: 312 385 81.0 %
Date: 2015-06-27 Functions: 37 39 94.9 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10

Generated at Sat, 27 Jun 2015 09:41:20 +0000 (5 days ago)

Copyright © 2005-2015 The PHP Group
All rights reserved.