Back to index

php5  5.3.10
Defines | Functions
filestat.c File Reference
#include "php.h"
#include "safe_mode.h"
#include "fopen_wrappers.h"
#include "php_globals.h"
#include <stdlib.h>
#include <sys/stat.h>
#include <string.h>
#include <errno.h>
#include <ctype.h>
#include <time.h>
#include "basic_functions.h"
#include "php_filestat.h"

Go to the source code of this file.

Defines

#define S_ISDIR(mode)   (((mode)&S_IFMT) == S_IFDIR)
#define S_ISREG(mode)   (((mode)&S_IFMT) == S_IFREG)
#define S_ISLNK(mode)   (((mode)&S_IFMT) == S_IFLNK)
#define S_IXROOT   ( S_IXUSR | S_IXGRP | S_IXOTH )
#define IS_LINK_OPERATION(__t)   ((__t) == FS_TYPE || (__t) == FS_IS_LINK || (__t) == FS_LSTAT)
#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)
#define IS_ABLE_CHECK(__t)   ((__t) == FS_IS_R || (__t) == FS_IS_W || (__t) == FS_IS_X)
#define IS_ACCESS_CHECK(__t)   (IS_ABLE_CHECK(type) || (__t) == FS_EXISTS)
#define FileFunction(name, funcnum)

Functions

 PHP_RINIT_FUNCTION (filestat)
 PHP_RSHUTDOWN_FUNCTION (filestat)
static int php_disk_total_space (char *path, double *space TSRMLS_DC)
 PHP_FUNCTION (disk_total_space)
static int php_disk_free_space (char *path, double *space TSRMLS_DC)
 PHP_FUNCTION (disk_free_space)
static void php_do_chgrp (INTERNAL_FUNCTION_PARAMETERS, int do_lchgrp)
 PHP_FUNCTION (chgrp)
static void php_do_chown (INTERNAL_FUNCTION_PARAMETERS, int do_lchown)
 PHP_FUNCTION (chown)
 PHP_FUNCTION (chmod)
PHPAPI void php_clear_stat_cache (zend_bool clear_realpath_cache, const char *filename, int filename_len TSRMLS_DC)
 PHP_FUNCTION (clearstatcache)
PHPAPI void php_stat (const char *filename, php_stat_len filename_length, int type, zval *return_value TSRMLS_DC)
 FileFunction (PHP_FN(fileperms), FS_PERMS)
 PHP_FUNCTION (realpath_cache_get)

Define Documentation

#define FileFunction (   name,
  funcnum 
)
Value:
void name(INTERNAL_FUNCTION_PARAMETERS) { \
       char *filename; \
       int filename_len; \
	\
	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &filename, &filename_len) == FAILURE) { \
              return; \
       } \
	\
	php_stat(filename, (php_stat_len) filename_len, funcnum, return_value TSRMLS_CC); \
}

Definition at line 1032 of file filestat.c.

#define IS_ABLE_CHECK (   __t)    ((__t) == FS_IS_R || (__t) == FS_IS_W || (__t) == FS_IS_X)

Definition at line 777 of file filestat.c.

#define IS_ACCESS_CHECK (   __t)    (IS_ABLE_CHECK(type) || (__t) == FS_EXISTS)

Definition at line 778 of file filestat.c.

#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)

Definition at line 776 of file filestat.c.

#define IS_LINK_OPERATION (   __t)    ((__t) == FS_TYPE || (__t) == FS_IS_LINK || (__t) == FS_LSTAT)

Definition at line 775 of file filestat.c.

#define S_ISDIR (   mode)    (((mode)&S_IFMT) == S_IFDIR)

Definition at line 90 of file filestat.c.

#define S_ISLNK (   mode)    (((mode)&S_IFMT) == S_IFLNK)

Definition at line 96 of file filestat.c.

#define S_ISREG (   mode)    (((mode)&S_IFMT) == S_IFREG)

Definition at line 93 of file filestat.c.

#define S_IXROOT   ( S_IXUSR | S_IXGRP | S_IXOTH )

Definition at line 99 of file filestat.c.


Function Documentation

FileFunction ( PHP_FN(fileperms)  ,
FS_PERMS   
)

Definition at line 1047 of file filestat.c.

Here is the call graph for this function:

PHPAPI void php_clear_stat_cache ( zend_bool  clear_realpath_cache,
const char *  filename,
int filename_len  TSRMLS_DC 
)

Definition at line 735 of file filestat.c.

{
       /* always clear CurrentStatFile and CurrentLStatFile even if filename is not NULL
        * as it may contain outdated data (e.g. "nlink" for a directory when deleting a file
        * in this directory, as shown by lstat_stat_variation9.phpt) */

       if (BG(CurrentStatFile)) {
              efree(BG(CurrentStatFile));
              BG(CurrentStatFile) = NULL;
       }
       if (BG(CurrentLStatFile)) {
              efree(BG(CurrentLStatFile));
              BG(CurrentLStatFile) = NULL;
       }
       if (clear_realpath_cache) {
              if (filename != NULL) {
                     realpath_cache_del(filename, filename_len TSRMLS_CC);
              } else {
                     realpath_cache_clean(TSRMLS_C);
              }
       }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int php_disk_free_space ( char *  path,
double *space  TSRMLS_DC 
) [static]

Definition at line 254 of file filestat.c.

{
       double bytesfree = 0;

       HINSTANCE kernel32;
       FARPROC gdfse;
       typedef BOOL (WINAPI *gdfse_func)(LPCTSTR, PULARGE_INTEGER, PULARGE_INTEGER, PULARGE_INTEGER);
       gdfse_func func;

       /* These are used by GetDiskFreeSpaceEx, if available. */
       ULARGE_INTEGER FreeBytesAvailableToCaller;
       ULARGE_INTEGER TotalNumberOfBytes;
       ULARGE_INTEGER TotalNumberOfFreeBytes;

       /* These are used by GetDiskFreeSpace otherwise. */
       DWORD SectorsPerCluster;
       DWORD BytesPerSector;
       DWORD NumberOfFreeClusters;
       DWORD TotalNumberOfClusters;

       /* GetDiskFreeSpaceEx is only available in NT and Win95 post-OSR2,
          so we have to jump through some hoops to see if the function
          exists. */
       kernel32 = LoadLibrary("kernel32.dll");
       if (kernel32) {
              gdfse = GetProcAddress(kernel32, "GetDiskFreeSpaceExA");
              /* It's available, so we can call it. */
              if (gdfse) {
                     func = (gdfse_func)gdfse;
                     if (func(path,
                                          &FreeBytesAvailableToCaller,
                                          &TotalNumberOfBytes,
                                          &TotalNumberOfFreeBytes) == 0) {
                            php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", php_win_err());
                            return FAILURE;
                     }

                     /* i know - this is ugly, but i works <thies@thieso.net> */
                     bytesfree  = FreeBytesAvailableToCaller.HighPart *
                            (double) (((unsigned long)1) << 31) * 2.0 +
                            FreeBytesAvailableToCaller.LowPart;
              } else { /* If it's not available, we just use GetDiskFreeSpace */
                     if (GetDiskFreeSpace(path,
                                          &SectorsPerCluster, &BytesPerSector,
                                          &NumberOfFreeClusters, &TotalNumberOfClusters) == 0) {
                            php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", php_win_err());
                            return FAILURE;
                     }
                     bytesfree = (double)NumberOfFreeClusters * (double)SectorsPerCluster * (double)BytesPerSector;
              }
       } else {
              php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to load kernel32.dll");
              return FAILURE;
       }

       *space = bytesfree;
       return SUCCESS;
}
/* }}} */
#elif defined(OS2) /* {{{ */
{
       double bytesfree = 0;
       FSALLOCATE fsinfo;
       char drive = path[0] & 95;

       if (DosQueryFSInfo( drive ? drive - 64 : 0, FSIL_ALLOC, &fsinfo, sizeof( fsinfo ) ) == 0) {
              bytesfree = (double)fsinfo.cbSector * fsinfo.cSectorUnit * fsinfo.cUnitAvail;
              *space = bytesfree;
              return SUCCESS;
       }
       return FAILURE;
}
/* }}} */
#else /* {{{ if !defined(OS2) && !defined(WINDOWS) */
{
       double bytesfree = 0;
#if defined(HAVE_SYS_STATVFS_H) && defined(HAVE_STATVFS)
       struct statvfs buf;
#elif (defined(HAVE_SYS_STATFS_H) || defined(HAVE_SYS_MOUNT_H)) && defined(HAVE_STATFS)
       struct statfs buf;
#endif

#if defined(HAVE_SYS_STATVFS_H) && defined(HAVE_STATVFS)
       if (statvfs(path, &buf)) {
              php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", strerror(errno));
              return FAILURE;
       }
       if (buf.f_frsize) {
              bytesfree = (((double)buf.f_bavail) * ((double)buf.f_frsize));
       } else {
              bytesfree = (((double)buf.f_bavail) * ((double)buf.f_bsize));
       }
#elif (defined(HAVE_SYS_STATFS_H) || defined(HAVE_SYS_MOUNT_H)) && defined(HAVE_STATFS)
       if (statfs(path, &buf)) {
              php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", strerror(errno));
              return FAILURE;
       }
#ifdef NETWARE
       bytesfree = (((double)buf.f_bsize) * ((double)buf.f_bfree));
#else
       bytesfree = (((double)buf.f_bsize) * ((double)buf.f_bavail));
#endif
#endif

       *space = bytesfree;
       return SUCCESS;
}

Here is the caller graph for this function:

static int php_disk_total_space ( char *  path,
double *space  TSRMLS_DC 
) [static]

Definition at line 123 of file filestat.c.

{
       double bytestotal = 0;
       HINSTANCE kernel32;
       FARPROC gdfse;
       typedef BOOL (WINAPI *gdfse_func)(LPCTSTR, PULARGE_INTEGER, PULARGE_INTEGER, PULARGE_INTEGER);
       gdfse_func func;

       /* These are used by GetDiskFreeSpaceEx, if available. */
       ULARGE_INTEGER FreeBytesAvailableToCaller;
       ULARGE_INTEGER TotalNumberOfBytes;
       ULARGE_INTEGER TotalNumberOfFreeBytes;

       /* These are used by GetDiskFreeSpace otherwise. */
       DWORD SectorsPerCluster;
       DWORD BytesPerSector;
       DWORD NumberOfFreeClusters;
       DWORD TotalNumberOfClusters;

       /* GetDiskFreeSpaceEx is only available in NT and Win95 post-OSR2,
          so we have to jump through some hoops to see if the function
          exists. */
       kernel32 = LoadLibrary("kernel32.dll");
       if (kernel32) {
              gdfse = GetProcAddress(kernel32, "GetDiskFreeSpaceExA");
              /* It's available, so we can call it. */
              if (gdfse) {
                     func = (gdfse_func)gdfse;
                     if (func(path,
                                          &FreeBytesAvailableToCaller,
                                          &TotalNumberOfBytes,
                                          &TotalNumberOfFreeBytes) == 0) {
                            php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", php_win_err());
                            return FAILURE;
                     }

                     /* i know - this is ugly, but i works <thies@thieso.net> */
                     bytestotal  = TotalNumberOfBytes.HighPart *
                            (double) (((unsigned long)1) << 31) * 2.0 +
                            TotalNumberOfBytes.LowPart;
              } else { /* If it's not available, we just use GetDiskFreeSpace */
                     if (GetDiskFreeSpace(path,
                                          &SectorsPerCluster, &BytesPerSector,
                                          &NumberOfFreeClusters, &TotalNumberOfClusters) == 0) {
                            php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", php_win_err());
                            return FAILURE;
                     }
                     bytestotal = (double)TotalNumberOfClusters * (double)SectorsPerCluster * (double)BytesPerSector;
              }
       } else {
              php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to load kernel32.dll");
              return FAILURE;
       }

       *space = bytestotal;
       return SUCCESS;
}
/* }}} */
#elif defined(OS2) /* {{{ */
{
       double bytestotal = 0;
       FSALLOCATE fsinfo;
       char drive = path[0] & 95;

       if (DosQueryFSInfo( drive ? drive - 64 : 0, FSIL_ALLOC, &fsinfo, sizeof( fsinfo ) ) == 0) {
              bytestotal = (double)fsinfo.cbSector * fsinfo.cSectorUnit * fsinfo.cUnit;
              *space = bytestotal;
              return SUCCESS;
       }
       return FAILURE;
}
/* }}} */
#else /* {{{ if !defined(OS2) && !defined(WINDOWS) */
{
       double bytestotal = 0;
#if defined(HAVE_SYS_STATVFS_H) && defined(HAVE_STATVFS)
       struct statvfs buf;
#elif (defined(HAVE_SYS_STATFS_H) || defined(HAVE_SYS_MOUNT_H)) && defined(HAVE_STATFS)
       struct statfs buf;
#endif

#if defined(HAVE_SYS_STATVFS_H) && defined(HAVE_STATVFS)
       if (statvfs(path, &buf)) {
              php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", strerror(errno));
              return FAILURE;
       }
       if (buf.f_frsize) {
              bytestotal = (((double)buf.f_blocks) * ((double)buf.f_frsize));
       } else {
              bytestotal = (((double)buf.f_blocks) * ((double)buf.f_bsize));
       }

#elif (defined(HAVE_SYS_STATFS_H) || defined(HAVE_SYS_MOUNT_H)) && defined(HAVE_STATFS)
       if (statfs(path, &buf)) {
              php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", strerror(errno));
              return FAILURE;
       }
       bytestotal = (((double)buf.f_bsize) * ((double)buf.f_blocks));
#endif

       *space = bytestotal;
       return SUCCESS;
}

Here is the caller graph for this function:

static void php_do_chgrp ( INTERNAL_FUNCTION_PARAMETERS  ,
int  do_lchgrp 
) [static]

Definition at line 394 of file filestat.c.

{
       char *filename;
       int filename_len;
       zval *group;
       gid_t gid;
       int ret;

       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz/", &filename, &filename_len, &group) == FAILURE) {
              RETURN_FALSE;
       }

       if (strlen(filename) != filename_len) {
              RETURN_FALSE;
       }

       if (Z_TYPE_P(group) == IS_LONG) {
              gid = (gid_t)Z_LVAL_P(group);
       } else if (Z_TYPE_P(group) == IS_STRING) {
#if defined(ZTS) && defined(HAVE_GETGRNAM_R) && defined(_SC_GETGR_R_SIZE_MAX)
              struct group gr;
              struct group *retgrptr;
              long grbuflen = sysconf(_SC_GETGR_R_SIZE_MAX);
              char *grbuf;

              if (grbuflen < 1) {
                     RETURN_FALSE;
              }

              grbuf = emalloc(grbuflen);
              if (getgrnam_r(Z_STRVAL_P(group), &gr, grbuf, grbuflen, &retgrptr) != 0 || retgrptr == NULL) {
                     php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find gid for %s", Z_STRVAL_P(group));
                     efree(grbuf);
                     RETURN_FALSE;
              }
              efree(grbuf);
              gid = gr.gr_gid;
#else
              struct group *gr = getgrnam(Z_STRVAL_P(group));

              if (!gr) {
                     php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find gid for %s", Z_STRVAL_P(group));
                     RETURN_FALSE;
              }
              gid = gr->gr_gid;
#endif
       } else {
              php_error_docref(NULL TSRMLS_CC, E_WARNING, "parameter 2 should be string or integer, %s given", zend_zval_type_name(group));
              RETURN_FALSE;
       }

       if (PG(safe_mode) &&(!php_checkuid(filename, NULL, CHECKUID_ALLOW_FILE_NOT_EXISTS))) {
              RETURN_FALSE;
       }

       /* Check the basedir */
       if (php_check_open_basedir(filename TSRMLS_CC)) {
              RETURN_FALSE;
       }

       if (do_lchgrp) {
#if HAVE_LCHOWN
              ret = VCWD_LCHOWN(filename, -1, gid);
#endif
       } else {
              ret = VCWD_CHOWN(filename, -1, gid);
       }
       if (ret == -1) {
              php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", strerror(errno));
              RETURN_FALSE;
       }
       RETURN_TRUE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void php_do_chown ( INTERNAL_FUNCTION_PARAMETERS  ,
int  do_lchown 
) [static]

Definition at line 499 of file filestat.c.

{
       char *filename;
       int filename_len;
       zval *user;
       uid_t uid;
       int ret;

       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz/", &filename, &filename_len, &user) == FAILURE) {
              return;
       }

       if (strlen(filename) != filename_len) {
              RETURN_FALSE;
       }

       if (Z_TYPE_P(user) == IS_LONG) {
              uid = (uid_t)Z_LVAL_P(user);
       } else if (Z_TYPE_P(user) == IS_STRING) {
#if defined(ZTS) && defined(_SC_GETPW_R_SIZE_MAX) && defined(HAVE_GETPWNAM_R)
              struct passwd pw;
              struct passwd *retpwptr = NULL;
              long pwbuflen = sysconf(_SC_GETPW_R_SIZE_MAX);
              char *pwbuf;

              if (pwbuflen < 1) {
                     RETURN_FALSE;
              }

              pwbuf = emalloc(pwbuflen);
              if (getpwnam_r(Z_STRVAL_P(user), &pw, pwbuf, pwbuflen, &retpwptr) != 0 || retpwptr == NULL) {
                     php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find uid for %s", Z_STRVAL_P(user));
                     efree(pwbuf);
                     RETURN_FALSE;
              }
              efree(pwbuf);
              uid = pw.pw_uid;
#else
              struct passwd *pw = getpwnam(Z_STRVAL_P(user));

              if (!pw) {
                     php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find uid for %s", Z_STRVAL_P(user));
                     RETURN_FALSE;
              }
              uid = pw->pw_uid;
#endif
       } else {
              php_error_docref(NULL TSRMLS_CC, E_WARNING, "parameter 2 should be string or integer, %s given", zend_zval_type_name(user));
              RETURN_FALSE;
       }

       if (PG(safe_mode) && (!php_checkuid(filename, NULL, CHECKUID_ALLOW_FILE_NOT_EXISTS))) {
              RETURN_FALSE;
       }

       /* Check the basedir */
       if (php_check_open_basedir(filename TSRMLS_CC)) {
              RETURN_FALSE;
       }

       if (do_lchown) {
#if HAVE_LCHOWN
              ret = VCWD_LCHOWN(filename, uid, -1);
#endif
       } else {
              ret = VCWD_CHOWN(filename, uid, -1);
       }
       if (ret == -1) {
              php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", strerror(errno));
              RETURN_FALSE;
       }
}

Here is the call graph for this function:

Here is the caller graph for this function:

PHP_FUNCTION ( disk_total_space  )

Definition at line 233 of file filestat.c.

{
       double bytestotal;
       char *path;
       int path_len;

       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &path, &path_len) == FAILURE) {
              return;
       }

       if (php_check_open_basedir(path TSRMLS_CC)) {
              RETURN_FALSE;
       }

       if (php_disk_total_space(path, &bytestotal TSRMLS_CC) == SUCCESS) {
              RETURN_DOUBLE(bytestotal);
       }
       RETURN_FALSE;
}

Here is the call graph for this function:

PHP_FUNCTION ( disk_free_space  )

Definition at line 368 of file filestat.c.

{
       double bytesfree;
       char *path;
       int path_len;

       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &path, &path_len) == FAILURE) {
              return;
       }

       if (php_check_open_basedir(path TSRMLS_CC)) {
              RETURN_FALSE;
       }

       if (strlen(path) != path_len) {
              RETURN_FALSE;
       }

       if (php_disk_free_space(path, &bytesfree TSRMLS_CC) == SUCCESS) {
              RETURN_DOUBLE(bytesfree);
       }
       RETURN_FALSE;
}

Here is the call graph for this function:

PHP_FUNCTION ( chgrp  )

Definition at line 473 of file filestat.c.

{
#if !defined(WINDOWS)
       php_do_chgrp(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
#else
       RETURN_FALSE;
#endif
}

Here is the call graph for this function:

PHP_FUNCTION ( chown  )

Definition at line 577 of file filestat.c.

{
#if !defined(WINDOWS)
       RETVAL_TRUE;
       php_do_chown(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
#else
       RETURN_FALSE;
#endif
}

Here is the call graph for this function:

PHP_FUNCTION ( chmod  )

Definition at line 606 of file filestat.c.

{
       char *filename;
       int filename_len;
       long mode;
       int ret;
       mode_t imode;

       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sl", &filename, &filename_len, &mode) == FAILURE) {
              return;
       }

       if (PG(safe_mode) &&(!php_checkuid(filename, NULL, CHECKUID_ALLOW_FILE_NOT_EXISTS))) {
              RETURN_FALSE;
       }

       if (strlen(filename) != filename_len) {
              RETURN_FALSE;
       }

       /* Check the basedir */
       if (php_check_open_basedir(filename TSRMLS_CC)) {
              RETURN_FALSE;
       }

       imode = (mode_t) mode;
       /* In safe mode, do not allow to setuid files.
        * Setuiding files could allow users to gain privileges
        * that safe mode doesn't give them. */

       if (PG(safe_mode)) {
              php_stream_statbuf ssb;
              if (php_stream_stat_path_ex(filename, 0, &ssb, NULL)) {
                     php_error_docref(NULL TSRMLS_CC, E_WARNING, "stat failed for %s", filename);
                     RETURN_FALSE;
              }
              if ((imode & 04000) != 0 && (ssb.sb.st_mode & 04000) == 0) {
                     imode ^= 04000;
              }
              if ((imode & 02000) != 0 && (ssb.sb.st_mode & 02000) == 0) {
                     imode ^= 02000;
              }
              if ((imode & 01000) != 0 && (ssb.sb.st_mode & 01000) == 0) {
                     imode ^= 01000;
              }
       }

       ret = VCWD_CHMOD(filename, imode);
       if (ret == -1) {
              php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", strerror(errno));
              RETURN_FALSE;
       }
       RETURN_TRUE;
}

Here is the call graph for this function:

PHP_FUNCTION ( clearstatcache  )

Definition at line 761 of file filestat.c.

{
       zend_bool  clear_realpath_cache = 0;
       char      *filename             = NULL;
       int        filename_len         = 0;

       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|bs", &clear_realpath_cache, &filename, &filename_len) == FAILURE) {
              return;
       }

       php_clear_stat_cache(clear_realpath_cache, filename, filename_len TSRMLS_CC);
}

Here is the call graph for this function:

PHP_FUNCTION ( realpath_cache_get  )

Definition at line 1147 of file filestat.c.

{
       realpath_cache_bucket **buckets = realpath_cache_get_buckets(TSRMLS_C), **end = buckets + realpath_cache_max_buckets(TSRMLS_C);

       if (zend_parse_parameters_none() == FAILURE) {
              return;
       }

       array_init(return_value);
       while(buckets < end) {
              realpath_cache_bucket *bucket = *buckets;
              while(bucket) {
                     zval *entry;
                     MAKE_STD_ZVAL(entry);
                     array_init(entry);

                     add_assoc_long(entry, "key", bucket->key);
                     add_assoc_bool(entry, "is_dir", bucket->is_dir);
                     add_assoc_stringl(entry, "realpath", bucket->realpath, bucket->realpath_len, 1);
                     add_assoc_long(entry, "expires", bucket->expires);
#ifdef PHP_WIN32
                     add_assoc_bool(entry, "is_rvalid", bucket->is_rvalid);
                     add_assoc_bool(entry, "is_wvalid", bucket->is_wvalid);
                     add_assoc_bool(entry, "is_readable", bucket->is_readable);
                     add_assoc_bool(entry, "is_writable", bucket->is_writable);
#endif
                     zend_hash_update(Z_ARRVAL_P(return_value), bucket->path, bucket->path_len+1, &entry, sizeof(zval *), NULL);
                     bucket = bucket->next;
              }
              buckets++;
       }
}

Here is the call graph for this function:

PHP_RINIT_FUNCTION ( filestat  )

Definition at line 101 of file filestat.c.

{
       BG(CurrentStatFile)=NULL;
       BG(CurrentLStatFile)=NULL;
       return SUCCESS;
}
PHP_RSHUTDOWN_FUNCTION ( filestat  )

Definition at line 109 of file filestat.c.

{
       if (BG(CurrentStatFile)) {
              efree (BG(CurrentStatFile));
              BG(CurrentStatFile) = NULL;
       }
       if (BG(CurrentLStatFile)) {
              efree (BG(CurrentLStatFile));
              BG(CurrentLStatFile) = NULL;
       }
       return SUCCESS;
}
PHPAPI void php_stat ( const char *  filename,
php_stat_len  filename_length,
int  type,
zval *return_value  TSRMLS_DC 
)

Definition at line 782 of file filestat.c.

{
       zval *stat_dev, *stat_ino, *stat_mode, *stat_nlink, *stat_uid, *stat_gid, *stat_rdev,
               *stat_size, *stat_atime, *stat_mtime, *stat_ctime, *stat_blksize, *stat_blocks;
       struct stat *stat_sb;
       php_stream_statbuf ssb;
       int flags = 0, rmask=S_IROTH, wmask=S_IWOTH, xmask=S_IXOTH; /* access rights defaults to other */
       char *stat_sb_names[13] = {
              "dev", "ino", "mode", "nlink", "uid", "gid", "rdev",
              "size", "atime", "mtime", "ctime", "blksize", "blocks"
       };
       char *local;
       php_stream_wrapper *wrapper;
       char safe_mode_buf[MAXPATHLEN];

       if (!filename_length) {
              RETURN_FALSE;
       }

       if (strlen(filename) != filename_length) {
              RETURN_FALSE;
       }

       if ((wrapper = php_stream_locate_url_wrapper(filename, &local, 0 TSRMLS_CC)) == &php_plain_files_wrapper) {
              if (php_check_open_basedir(local TSRMLS_CC)) {
                     RETURN_FALSE;
              } else if (PG(safe_mode)) {
                     if (type == FS_IS_X) {
                            if (strstr(local, "..")) {
                                   RETURN_FALSE;
                            } else {
                                   char *b = strrchr(local, PHP_DIR_SEPARATOR);
                                   snprintf(safe_mode_buf, MAXPATHLEN, "%s%s%s", PG(safe_mode_exec_dir), (b ? "" : "/"), (b ? b : local));
                                   local = (char *)&safe_mode_buf;
                            }
                     } else if (!php_checkuid_ex(local, NULL, CHECKUID_ALLOW_FILE_NOT_EXISTS, CHECKUID_NO_ERRORS)) {
                            RETURN_FALSE;
                     }
              }
       }

       if (IS_ACCESS_CHECK(type)) {
              if (wrapper == &php_plain_files_wrapper) {

                     switch (type) {
#ifdef F_OK
                            case FS_EXISTS:
                                   RETURN_BOOL(VCWD_ACCESS(local, F_OK) == 0);
                                   break;
#endif
#ifdef W_OK
                            case FS_IS_W:
                                   RETURN_BOOL(VCWD_ACCESS(local, W_OK) == 0);
                                   break;
#endif
#ifdef R_OK
                            case FS_IS_R:
                                   RETURN_BOOL(VCWD_ACCESS(local, R_OK) == 0);
                                   break;
#endif
#ifdef X_OK
                            case FS_IS_X:
                                   RETURN_BOOL(VCWD_ACCESS(local, X_OK) == 0);
                                   break;
#endif
                     }
              }
       }

       if (IS_LINK_OPERATION(type)) {
              flags |= PHP_STREAM_URL_STAT_LINK;
       }
       if (IS_EXISTS_CHECK(type)) {
              flags |= PHP_STREAM_URL_STAT_QUIET;
       }

       if (php_stream_stat_path_ex((char *)filename, flags, &ssb, NULL)) {
              /* Error Occured */
              if (!IS_EXISTS_CHECK(type)) {
                     php_error_docref(NULL TSRMLS_CC, E_WARNING, "%sstat failed for %s", IS_LINK_OPERATION(type) ? "L" : "", filename);
              }
              RETURN_FALSE;
       }

       stat_sb = &ssb.sb;


#ifndef NETWARE
       if (type >= FS_IS_W && type <= FS_IS_X) {
              if(ssb.sb.st_uid==getuid()) {
                     rmask=S_IRUSR;
                     wmask=S_IWUSR;
                     xmask=S_IXUSR;
              } else if(ssb.sb.st_gid==getgid()) {
                     rmask=S_IRGRP;
                     wmask=S_IWGRP;
                     xmask=S_IXGRP;
              } else {
                     int   groups, n, i;
                     gid_t *gids;

                     groups = getgroups(0, NULL);
                     if(groups > 0) {
                            gids=(gid_t *)safe_emalloc(groups, sizeof(gid_t), 0);
                            n=getgroups(groups, gids);
                            for(i=0;i<n;i++){
                                   if(ssb.sb.st_gid==gids[i]) {
                                          rmask=S_IRGRP;
                                          wmask=S_IWGRP;
                                          xmask=S_IXGRP;
                                          break;
                                   }
                            }
                            efree(gids);
                     }
              }
       }
#endif

#ifndef NETWARE
       if (IS_ABLE_CHECK(type) && getuid() == 0) {
              /* root has special perms on plain_wrapper
                 But we don't know about root under Netware */
              if (wrapper == &php_plain_files_wrapper) {
                     if (type == FS_IS_X) {
                            xmask = S_IXROOT;
                     } else {
                            RETURN_TRUE;
                     }
              }
       }
#endif

       switch (type) {
       case FS_PERMS:
              RETURN_LONG((long)ssb.sb.st_mode);
       case FS_INODE:
              RETURN_LONG((long)ssb.sb.st_ino);
       case FS_SIZE:
              RETURN_LONG((long)ssb.sb.st_size);
       case FS_OWNER:
              RETURN_LONG((long)ssb.sb.st_uid);
       case FS_GROUP:
              RETURN_LONG((long)ssb.sb.st_gid);
       case FS_ATIME:
              RETURN_LONG((long)ssb.sb.st_atime);
       case FS_MTIME:
              RETURN_LONG((long)ssb.sb.st_mtime);
       case FS_CTIME:
              RETURN_LONG((long)ssb.sb.st_ctime);
       case FS_TYPE:
              if (S_ISLNK(ssb.sb.st_mode)) {
                     RETURN_STRING("link", 1);
              }
              switch(ssb.sb.st_mode & S_IFMT) {
              case S_IFIFO: RETURN_STRING("fifo", 1);
              case S_IFCHR: RETURN_STRING("char", 1);
              case S_IFDIR: RETURN_STRING("dir", 1);
              case S_IFBLK: RETURN_STRING("block", 1);
              case S_IFREG: RETURN_STRING("file", 1);
#if defined(S_IFSOCK) && !defined(ZEND_WIN32)&&!defined(__BEOS__)
              case S_IFSOCK: RETURN_STRING("socket", 1);
#endif
              }
              php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Unknown file type (%d)", ssb.sb.st_mode&S_IFMT);
              RETURN_STRING("unknown", 1);
       case FS_IS_W:
              RETURN_BOOL((ssb.sb.st_mode & wmask) != 0);
       case FS_IS_R:
              RETURN_BOOL((ssb.sb.st_mode&rmask)!=0);
       case FS_IS_X:
              RETURN_BOOL((ssb.sb.st_mode&xmask)!=0 && !S_ISDIR(ssb.sb.st_mode));
       case FS_IS_FILE:
              RETURN_BOOL(S_ISREG(ssb.sb.st_mode));
       case FS_IS_DIR:
              RETURN_BOOL(S_ISDIR(ssb.sb.st_mode));
       case FS_IS_LINK:
              RETURN_BOOL(S_ISLNK(ssb.sb.st_mode));
       case FS_EXISTS:
              RETURN_TRUE; /* the false case was done earlier */
       case FS_LSTAT:
              /* FALLTHROUGH */
       case FS_STAT:
              array_init(return_value);

              MAKE_LONG_ZVAL_INCREF(stat_dev, stat_sb->st_dev);
              MAKE_LONG_ZVAL_INCREF(stat_ino, stat_sb->st_ino);
              MAKE_LONG_ZVAL_INCREF(stat_mode, stat_sb->st_mode);
              MAKE_LONG_ZVAL_INCREF(stat_nlink, stat_sb->st_nlink);
              MAKE_LONG_ZVAL_INCREF(stat_uid, stat_sb->st_uid);
              MAKE_LONG_ZVAL_INCREF(stat_gid, stat_sb->st_gid);
#ifdef HAVE_ST_RDEV
              MAKE_LONG_ZVAL_INCREF(stat_rdev, stat_sb->st_rdev);
#else
              MAKE_LONG_ZVAL_INCREF(stat_rdev, -1);
#endif
              MAKE_LONG_ZVAL_INCREF(stat_size, stat_sb->st_size);
              MAKE_LONG_ZVAL_INCREF(stat_atime, stat_sb->st_atime);
              MAKE_LONG_ZVAL_INCREF(stat_mtime, stat_sb->st_mtime);
              MAKE_LONG_ZVAL_INCREF(stat_ctime, stat_sb->st_ctime);
#ifdef HAVE_ST_BLKSIZE
              MAKE_LONG_ZVAL_INCREF(stat_blksize, stat_sb->st_blksize);
#else
              MAKE_LONG_ZVAL_INCREF(stat_blksize,-1);
#endif
#ifdef HAVE_ST_BLOCKS
              MAKE_LONG_ZVAL_INCREF(stat_blocks, stat_sb->st_blocks);
#else
              MAKE_LONG_ZVAL_INCREF(stat_blocks,-1);
#endif
              /* Store numeric indexes in propper order */
              zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_dev, sizeof(zval *), NULL);
              zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_ino, sizeof(zval *), NULL);
              zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_mode, sizeof(zval *), NULL);
              zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_nlink, sizeof(zval *), NULL);
              zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_uid, sizeof(zval *), NULL);
              zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_gid, sizeof(zval *), NULL);

              zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_rdev, sizeof(zval *), NULL);
              zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_size, sizeof(zval *), NULL);
              zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_atime, sizeof(zval *), NULL);
              zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_mtime, sizeof(zval *), NULL);
              zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_ctime, sizeof(zval *), NULL);
              zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_blksize, sizeof(zval *), NULL);
              zend_hash_next_index_insert(HASH_OF(return_value), (void *)&stat_blocks, sizeof(zval *), NULL);

              /* Store string indexes referencing the same zval*/
              zend_hash_update(HASH_OF(return_value), stat_sb_names[0], strlen(stat_sb_names[0])+1, (void *) &stat_dev, sizeof(zval *), NULL);
              zend_hash_update(HASH_OF(return_value), stat_sb_names[1], strlen(stat_sb_names[1])+1, (void *) &stat_ino, sizeof(zval *), NULL);
              zend_hash_update(HASH_OF(return_value), stat_sb_names[2], strlen(stat_sb_names[2])+1, (void *) &stat_mode, sizeof(zval *), NULL);
              zend_hash_update(HASH_OF(return_value), stat_sb_names[3], strlen(stat_sb_names[3])+1, (void *) &stat_nlink, sizeof(zval *), NULL);
              zend_hash_update(HASH_OF(return_value), stat_sb_names[4], strlen(stat_sb_names[4])+1, (void *) &stat_uid, sizeof(zval *), NULL);
              zend_hash_update(HASH_OF(return_value), stat_sb_names[5], strlen(stat_sb_names[5])+1, (void *) &stat_gid, sizeof(zval *), NULL);
              zend_hash_update(HASH_OF(return_value), stat_sb_names[6], strlen(stat_sb_names[6])+1, (void *) &stat_rdev, sizeof(zval *), NULL);
              zend_hash_update(HASH_OF(return_value), stat_sb_names[7], strlen(stat_sb_names[7])+1, (void *) &stat_size, sizeof(zval *), NULL);
              zend_hash_update(HASH_OF(return_value), stat_sb_names[8], strlen(stat_sb_names[8])+1, (void *) &stat_atime, sizeof(zval *), NULL);
              zend_hash_update(HASH_OF(return_value), stat_sb_names[9], strlen(stat_sb_names[9])+1, (void *) &stat_mtime, sizeof(zval *), NULL);
              zend_hash_update(HASH_OF(return_value), stat_sb_names[10], strlen(stat_sb_names[10])+1, (void *) &stat_ctime, sizeof(zval *), NULL);
              zend_hash_update(HASH_OF(return_value), stat_sb_names[11], strlen(stat_sb_names[11])+1, (void *) &stat_blksize, sizeof(zval *), NULL);
              zend_hash_update(HASH_OF(return_value), stat_sb_names[12], strlen(stat_sb_names[12])+1, (void *) &stat_blocks, sizeof(zval *), NULL);

              return;
       }
       php_error_docref(NULL TSRMLS_CC, E_WARNING, "Didn't understand stat call");
       RETURN_FALSE;
}

Here is the call graph for this function:

Here is the caller graph for this function: