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: 313 386 81.1 %
Date: 2014-04-16 Functions: 37 39 94.9 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10

Generated at Wed, 16 Apr 2014 12:47:58 +0000 (7 days ago)

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