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: 297 362 82.0 %
Date: 2014-04-08 Functions: 37 37 100.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10

Generated at Tue, 08 Apr 2014 11:59:45 +0000 (9 days ago)

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