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

LTP GCOV extension - code coverage report
Current view: directory - standard - dir.c
Test: PHP Code Coverage
Date: 2009-11-21 Instrumented lines: 180
Code covered: 86.1 % Executed lines: 155
Legend: not executed executed

       1                 : /*
       2                 :    +----------------------------------------------------------------------+
       3                 :    | PHP Version 5                                                        |
       4                 :    +----------------------------------------------------------------------+
       5                 :    | Copyright (c) 1997-2009 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: Thies C. Arntzen <thies@thieso.net>                          |
      16                 :    +----------------------------------------------------------------------+
      17                 :  */
      18                 : 
      19                 : /* $Id: dir.c 286555 2009-07-30 12:06:40Z felipe $ */
      20                 : 
      21                 : /* {{{ includes/startup/misc */
      22                 : 
      23                 : #include "php.h"
      24                 : #include "fopen_wrappers.h"
      25                 : #include "file.h"
      26                 : #include "php_dir.h"
      27                 : #include "php_string.h"
      28                 : #include "php_scandir.h"
      29                 : #include "basic_functions.h"
      30                 : 
      31                 : #ifdef HAVE_DIRENT_H
      32                 : #include <dirent.h>
      33                 : #endif
      34                 : 
      35                 : #if HAVE_UNISTD_H
      36                 : #include <unistd.h>
      37                 : #endif
      38                 : 
      39                 : #include <errno.h>
      40                 : 
      41                 : #ifdef PHP_WIN32
      42                 : #include "win32/readdir.h"
      43                 : #endif
      44                 : 
      45                 : 
      46                 : #ifdef HAVE_GLOB
      47                 : #ifndef PHP_WIN32
      48                 : #include <glob.h>
      49                 : #else
      50                 : #include "win32/glob.h"
      51                 : #endif
      52                 : #endif
      53                 : 
      54                 : typedef struct {
      55                 :         int default_dir;
      56                 : } php_dir_globals;
      57                 : 
      58                 : #ifdef ZTS
      59                 : #define DIRG(v) TSRMG(dir_globals_id, php_dir_globals *, v)
      60                 : int dir_globals_id;
      61                 : #else
      62                 : #define DIRG(v) (dir_globals.v)
      63                 : php_dir_globals dir_globals;
      64                 : #endif
      65                 : 
      66                 : #if 0
      67                 : typedef struct {
      68                 :         int id;
      69                 :         DIR *dir;
      70                 : } php_dir;
      71                 : 
      72                 : static int le_dirp;
      73                 : #endif
      74                 : 
      75                 : static zend_class_entry *dir_class_entry_ptr;
      76                 : 
      77                 : #define FETCH_DIRP() \
      78                 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &id) == FAILURE) { \
      79                 :                 return; \
      80                 :         } \
      81                 :         if (ZEND_NUM_ARGS() == 0) { \
      82                 :                 myself = getThis(); \
      83                 :                 if (myself) { \
      84                 :                         if (zend_hash_find(Z_OBJPROP_P(myself), "handle", sizeof("handle"), (void **)&tmp) == FAILURE) { \
      85                 :                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to find my handle property"); \
      86                 :                                 RETURN_FALSE; \
      87                 :                         } \
      88                 :                         ZEND_FETCH_RESOURCE(dirp, php_stream *, tmp, -1, "Directory", php_file_le_stream()); \
      89                 :                 } else { \
      90                 :                         ZEND_FETCH_RESOURCE(dirp, php_stream *, 0, DIRG(default_dir), "Directory", php_file_le_stream()); \
      91                 :                 } \
      92                 :         } else { \
      93                 :                 dirp = (php_stream *) zend_fetch_resource(&id TSRMLS_CC, -1, "Directory", NULL, 1, php_file_le_stream()); \
      94                 :                 if (!dirp) \
      95                 :                         RETURN_FALSE; \
      96                 :         } 
      97                 : 
      98                 : static const zend_function_entry php_dir_class_functions[] = {
      99                 :         PHP_FALIAS(close,       closedir,       NULL)
     100                 :         PHP_FALIAS(rewind,      rewinddir,      NULL)
     101                 :         PHP_NAMED_FE(read,  php_if_readdir, NULL)
     102                 :         {NULL, NULL, NULL}
     103                 : };
     104                 : 
     105                 : 
     106                 : static void php_set_default_dir(int id TSRMLS_DC)
     107            5086 : {
     108            5086 :         if (DIRG(default_dir)!=-1) {
     109            3026 :                 zend_list_delete(DIRG(default_dir));
     110                 :         }
     111                 : 
     112            5086 :         if (id != -1) {
     113            3044 :                 zend_list_addref(id);
     114                 :         }
     115                 :         
     116            5086 :         DIRG(default_dir) = id;
     117            5086 : }
     118                 : 
     119                 : PHP_RINIT_FUNCTION(dir)
     120           17619 : {
     121           17619 :         DIRG(default_dir) = -1;
     122           17619 :         return SUCCESS;
     123                 : }
     124                 : 
     125                 : PHP_MINIT_FUNCTION(dir)
     126           17633 : {
     127                 :         static char dirsep_str[2], pathsep_str[2];
     128                 :         zend_class_entry dir_class_entry;
     129                 : 
     130           17633 :         INIT_CLASS_ENTRY(dir_class_entry, "Directory", php_dir_class_functions);
     131           17633 :         dir_class_entry_ptr = zend_register_internal_class(&dir_class_entry TSRMLS_CC);
     132                 : 
     133                 : #ifdef ZTS
     134                 :         ts_allocate_id(&dir_globals_id, sizeof(php_dir_globals), NULL, NULL);
     135                 : #endif
     136                 : 
     137           17633 :         dirsep_str[0] = DEFAULT_SLASH;
     138           17633 :         dirsep_str[1] = '\0';
     139           17633 :         REGISTER_STRING_CONSTANT("DIRECTORY_SEPARATOR", dirsep_str, CONST_CS|CONST_PERSISTENT);
     140                 : 
     141           17633 :         pathsep_str[0] = ZEND_PATHS_SEPARATOR;
     142           17633 :         pathsep_str[1] = '\0';
     143           17633 :         REGISTER_STRING_CONSTANT("PATH_SEPARATOR", pathsep_str, CONST_CS|CONST_PERSISTENT);
     144                 : 
     145                 : #ifdef HAVE_GLOB
     146                 : 
     147                 : #ifdef GLOB_BRACE
     148           17633 :         REGISTER_LONG_CONSTANT("GLOB_BRACE", GLOB_BRACE, CONST_CS | CONST_PERSISTENT);
     149                 : #else
     150                 : # define GLOB_BRACE 0
     151                 : #endif
     152                 : 
     153                 : #ifdef GLOB_MARK
     154           17633 :         REGISTER_LONG_CONSTANT("GLOB_MARK", GLOB_MARK, CONST_CS | CONST_PERSISTENT);
     155                 : #else
     156                 : # define GLOB_MARK 0
     157                 : #endif
     158                 : 
     159                 : #ifdef GLOB_NOSORT
     160           17633 :         REGISTER_LONG_CONSTANT("GLOB_NOSORT", GLOB_NOSORT, CONST_CS | CONST_PERSISTENT);
     161                 : #else 
     162                 : # define GLOB_NOSORT 0
     163                 : #endif
     164                 : 
     165                 : #ifdef GLOB_NOCHECK
     166           17633 :         REGISTER_LONG_CONSTANT("GLOB_NOCHECK", GLOB_NOCHECK, CONST_CS | CONST_PERSISTENT);
     167                 : #else 
     168                 : # define GLOB_NOCHECK 0
     169                 : #endif
     170                 : 
     171                 : #ifdef GLOB_NOESCAPE
     172           17633 :         REGISTER_LONG_CONSTANT("GLOB_NOESCAPE", GLOB_NOESCAPE, CONST_CS | CONST_PERSISTENT);
     173                 : #else 
     174                 : # define GLOB_NOESCAPE 0
     175                 : #endif
     176                 : 
     177                 : #ifdef GLOB_ERR
     178           17633 :         REGISTER_LONG_CONSTANT("GLOB_ERR", GLOB_ERR, CONST_CS | CONST_PERSISTENT);
     179                 : #else 
     180                 : # define GLOB_ERR 0
     181                 : #endif
     182                 : 
     183                 : #ifndef GLOB_ONLYDIR
     184                 : # define GLOB_ONLYDIR (1<<30)
     185                 : # define GLOB_EMULATE_ONLYDIR
     186                 : # define GLOB_FLAGMASK (~GLOB_ONLYDIR)
     187                 : #else
     188                 : # define GLOB_FLAGMASK (~0)
     189                 : #endif
     190                 : 
     191                 : /* This is used for checking validity of passed flags (passing invalid flags causes segfault in glob()!! */
     192                 : #define GLOB_AVAILABLE_FLAGS (0 | GLOB_BRACE | GLOB_MARK | GLOB_NOSORT | GLOB_NOCHECK | GLOB_NOESCAPE | GLOB_ERR | GLOB_ONLYDIR)
     193                 : 
     194           17633 :         REGISTER_LONG_CONSTANT("GLOB_ONLYDIR", GLOB_ONLYDIR, CONST_CS | CONST_PERSISTENT);
     195           17633 :         REGISTER_LONG_CONSTANT("GLOB_AVAILABLE_FLAGS", GLOB_AVAILABLE_FLAGS, CONST_CS | CONST_PERSISTENT);
     196                 : 
     197                 : #endif /* HAVE_GLOB */
     198                 : 
     199           17633 :         return SUCCESS;
     200                 : }
     201                 : /* }}} */
     202                 : 
     203                 : /* {{{ internal functions */
     204                 : static void _php_do_opendir(INTERNAL_FUNCTION_PARAMETERS, int createobject)
     205            3186 : {
     206                 :         char *dirname;
     207                 :         int dir_len;
     208            3186 :         zval *zcontext = NULL;
     209            3186 :         php_stream_context *context = NULL;
     210                 :         php_stream *dirp;
     211                 : 
     212            3186 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|r", &dirname, &dir_len, &zcontext) == FAILURE) {
     213              66 :                 RETURN_NULL();
     214                 :         }
     215                 : 
     216            3120 :         context = php_stream_context_from_zval(zcontext, 0);
     217                 :         
     218            3120 :         dirp = php_stream_opendir(dirname, ENFORCE_SAFE_MODE|REPORT_ERRORS, context);
     219                 : 
     220            3120 :         if (dirp == NULL) {
     221              76 :                 RETURN_FALSE;
     222                 :         }
     223                 : 
     224            3044 :         dirp->flags |= PHP_STREAM_FLAG_NO_FCLOSE;
     225                 :                 
     226            3044 :         php_set_default_dir(dirp->rsrc_id TSRMLS_CC);
     227                 : 
     228            3044 :         if (createobject) {
     229              22 :                 object_init_ex(return_value, dir_class_entry_ptr);
     230              22 :                 add_property_stringl(return_value, "path", dirname, dir_len, 1);
     231              22 :                 add_property_resource(return_value, "handle", dirp->rsrc_id);
     232                 :                 php_stream_auto_cleanup(dirp); /* so we don't get warnings under debug */
     233                 :         } else {
     234            3022 :                 php_stream_to_zval(dirp, return_value);
     235                 :         }
     236                 : }
     237                 : /* }}} */
     238                 : 
     239                 : /* {{{ proto mixed opendir(string path[, resource context])
     240                 :    Open a directory and return a dir_handle */
     241                 : PHP_FUNCTION(opendir)
     242            3095 : {
     243            3095 :         _php_do_opendir(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
     244            3095 : }
     245                 : /* }}} */
     246                 : 
     247                 : /* {{{ proto object dir(string directory[, resource context])
     248                 :    Directory class with properties, handle and class and methods read, rewind and close */
     249                 : PHP_FUNCTION(getdir)
     250              91 : {
     251              91 :         _php_do_opendir(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
     252              91 : }
     253                 : /* }}} */
     254                 : 
     255                 : /* {{{ proto void closedir([resource dir_handle])
     256                 :    Close directory connection identified by the dir_handle */
     257                 : PHP_FUNCTION(closedir)
     258            3038 : {
     259            3038 :         zval *id = NULL, **tmp, *myself;
     260                 :         php_stream *dirp;
     261                 :         int rsrc_id;
     262                 : 
     263            3038 :         FETCH_DIRP();
     264                 : 
     265            3009 :         if (!(dirp->flags & PHP_STREAM_FLAG_IS_DIR)) {
     266               1 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "%d is not a valid Directory resource", dirp->rsrc_id);
     267               1 :                 RETURN_FALSE;
     268                 :         }
     269                 : 
     270            3008 :         rsrc_id = dirp->rsrc_id;
     271            3008 :         zend_list_delete(dirp->rsrc_id);
     272                 : 
     273            3008 :         if (rsrc_id == DIRG(default_dir)) {
     274            2042 :                 php_set_default_dir(-1 TSRMLS_CC);
     275                 :         }
     276                 : }
     277                 : /* }}} */
     278                 : 
     279                 : #if defined(HAVE_CHROOT) && !defined(ZTS) && ENABLE_CHROOT_FUNC
     280                 : /* {{{ proto bool chroot(string directory)
     281                 :    Change root directory */
     282                 : PHP_FUNCTION(chroot)
     283               0 : {
     284                 :         char *str;
     285                 :         int ret, str_len;
     286                 :         
     287               0 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &str, &str_len) == FAILURE) {
     288               0 :                 RETURN_FALSE;
     289                 :         }
     290                 :         
     291               0 :         ret = chroot(str);
     292               0 :         if (ret != 0) {
     293               0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s (errno %d)", strerror(errno), errno);
     294               0 :                 RETURN_FALSE;
     295                 :         }
     296                 : 
     297               0 :         php_clear_stat_cache(1, NULL, 0 TSRMLS_CC);
     298                 :         
     299               0 :         ret = chdir("/");
     300                 :         
     301               0 :         if (ret != 0) {
     302               0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s (errno %d)", strerror(errno), errno);
     303               0 :                 RETURN_FALSE;
     304                 :         }
     305                 : 
     306               0 :         RETURN_TRUE;
     307                 : }
     308                 : /* }}} */
     309                 : #endif
     310                 : 
     311                 : /* {{{ proto bool chdir(string directory)
     312                 :    Change the current directory */
     313                 : PHP_FUNCTION(chdir)
     314             291 : {
     315                 :         char *str;
     316                 :         int ret, str_len;
     317                 :         
     318             291 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &str, &str_len) == FAILURE) {
     319               4 :                 RETURN_FALSE;
     320                 :         }
     321                 : 
     322             287 :         if ((PG(safe_mode) && !php_checkuid(str, NULL, CHECKUID_CHECK_FILE_AND_DIR)) || php_check_open_basedir(str TSRMLS_CC)) {
     323               6 :                 RETURN_FALSE;
     324                 :         }
     325             281 :         ret = VCWD_CHDIR(str);
     326                 :         
     327             281 :         if (ret != 0) {
     328              21 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s (errno %d)", strerror(errno), errno);
     329              21 :                 RETURN_FALSE;
     330                 :         }
     331                 : 
     332             260 :         if (BG(CurrentStatFile) && !IS_ABSOLUTE_PATH(BG(CurrentStatFile), strlen(BG(CurrentStatFile)))) {
     333               1 :                 efree(BG(CurrentStatFile));
     334               1 :                 BG(CurrentStatFile) = NULL;
     335                 :         }
     336             260 :         if (BG(CurrentLStatFile) && !IS_ABSOLUTE_PATH(BG(CurrentLStatFile), strlen(BG(CurrentLStatFile)))) {
     337               0 :                 efree(BG(CurrentLStatFile));
     338               0 :                 BG(CurrentLStatFile) = NULL;
     339                 :         }
     340                 : 
     341             260 :         RETURN_TRUE;
     342                 : }
     343                 : /* }}} */
     344                 : 
     345                 : /* {{{ proto mixed getcwd(void)
     346                 :    Gets the current directory */
     347                 : PHP_FUNCTION(getcwd)
     348             244 : {
     349                 :         char path[MAXPATHLEN];
     350             244 :         char *ret=NULL;
     351                 :         
     352             244 :         if (zend_parse_parameters_none() == FAILURE) {
     353               1 :                 return;
     354                 :         }
     355                 : 
     356                 : #if HAVE_GETCWD
     357             243 :         ret = VCWD_GETCWD(path, MAXPATHLEN);
     358                 : #elif HAVE_GETWD
     359                 :         ret = VCWD_GETWD(path);
     360                 : #endif
     361                 : 
     362             243 :         if (ret) {
     363             243 :                 RETURN_STRING(path, 1);
     364                 :         } else {
     365               0 :                 RETURN_FALSE;
     366                 :         }
     367                 : }
     368                 : /* }}} */
     369                 : 
     370                 : /* {{{ proto void rewinddir([resource dir_handle])
     371                 :    Rewind dir_handle back to the start */
     372                 : PHP_FUNCTION(rewinddir)
     373              33 : {
     374              33 :         zval *id = NULL, **tmp, *myself;
     375                 :         php_stream *dirp;
     376                 :         
     377              33 :         FETCH_DIRP();
     378                 : 
     379               4 :         if (!(dirp->flags & PHP_STREAM_FLAG_IS_DIR)) {
     380               1 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "%d is not a valid Directory resource", dirp->rsrc_id);
     381               1 :                 RETURN_FALSE;
     382                 :         }
     383                 : 
     384               3 :         php_stream_rewinddir(dirp);
     385                 : }
     386                 : /* }}} */
     387                 : 
     388                 : /* {{{ proto string readdir([resource dir_handle])
     389                 :    Read directory entry from dir_handle */
     390                 : PHP_NAMED_FUNCTION(php_if_readdir)
     391           59017 : {
     392           59017 :         zval *id = NULL, **tmp, *myself;
     393                 :         php_stream *dirp;
     394                 :         php_stream_dirent entry;
     395                 : 
     396           59017 :         FETCH_DIRP();
     397                 : 
     398           58987 :         if (!(dirp->flags & PHP_STREAM_FLAG_IS_DIR)) {
     399               1 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "%d is not a valid Directory resource", dirp->rsrc_id);
     400               1 :                 RETURN_FALSE;
     401                 :         }
     402                 : 
     403           58986 :         if (php_stream_readdir(dirp, &entry)) {
     404           56062 :                 RETURN_STRINGL(entry.d_name, strlen(entry.d_name), 1);
     405                 :         }
     406            2924 :         RETURN_FALSE;
     407                 : }
     408                 : /* }}} */
     409                 : 
     410                 : #ifdef HAVE_GLOB
     411                 : /* {{{ proto array glob(string pattern [, int flags])
     412                 :    Find pathnames matching a pattern */
     413                 : PHP_FUNCTION(glob)
     414             120 : {
     415             120 :         int cwd_skip = 0;
     416                 : #ifdef ZTS
     417                 :         char cwd[MAXPATHLEN];
     418                 :         char work_pattern[MAXPATHLEN];
     419                 :         char *result;
     420                 : #endif
     421             120 :         char *pattern = NULL;
     422                 :         int pattern_len;
     423             120 :         long flags = 0;
     424                 :         glob_t globbuf;
     425                 :         int n;
     426                 :         int ret;
     427             120 :         zend_bool basedir_limit = 0;
     428                 : 
     429             120 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &pattern, &pattern_len, &flags) == FAILURE) {
     430               4 :                 return;
     431                 :         }
     432                 : 
     433             116 :         if (pattern_len >= MAXPATHLEN) {
     434               0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Pattern exceeds the maximum allowed length of %d characters", MAXPATHLEN);
     435               0 :                 RETURN_FALSE;
     436                 :         }
     437                 : 
     438             116 :         if ((GLOB_AVAILABLE_FLAGS & flags) != flags) {
     439               0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "At least one of the passed flags is invalid or not supported on this platform");
     440               0 :                 RETURN_FALSE;
     441                 :         }
     442                 : 
     443                 : #ifdef ZTS 
     444                 :         if (!IS_ABSOLUTE_PATH(pattern, pattern_len)) {
     445                 :                 result = VCWD_GETCWD(cwd, MAXPATHLEN);  
     446                 :                 if (!result) {
     447                 :                         cwd[0] = '\0';
     448                 :                 }
     449                 : #ifdef PHP_WIN32
     450                 :                 if (IS_SLASH(*pattern)) {
     451                 :                         cwd[2] = '\0';
     452                 :                 }
     453                 : #endif
     454                 :                 cwd_skip = strlen(cwd)+1;
     455                 : 
     456                 :                 snprintf(work_pattern, MAXPATHLEN, "%s%c%s", cwd, DEFAULT_SLASH, pattern);
     457                 :                 pattern = work_pattern;
     458                 :         } 
     459                 : #endif
     460                 : 
     461                 :         
     462             116 :         memset(&globbuf, 0, sizeof(glob_t));
     463             116 :         globbuf.gl_offs = 0;
     464             116 :         if (0 != (ret = glob(pattern, flags & GLOB_FLAGMASK, NULL, &globbuf))) {
     465                 : #ifdef GLOB_NOMATCH
     466              49 :                 if (GLOB_NOMATCH == ret) {
     467                 :                         /* Some glob implementation simply return no data if no matches
     468                 :                            were found, others return the GLOB_NOMATCH error code.
     469                 :                            We don't want to treat GLOB_NOMATCH as an error condition
     470                 :                            so that PHP glob() behaves the same on both types of 
     471                 :                            implementations and so that 'foreach (glob() as ...'
     472                 :                            can be used for simple glob() calls without further error
     473                 :                            checking.
     474                 :                         */
     475              49 :                         goto no_results;
     476                 :                 }
     477                 : #endif
     478               0 :                 RETURN_FALSE;
     479                 :         }
     480                 : 
     481                 :         /* now catch the FreeBSD style of "no matches" */
     482              67 :         if (!globbuf.gl_pathc || !globbuf.gl_pathv) {
     483              49 : no_results:
     484              49 :                 if (PG(safe_mode) || (PG(open_basedir) && *PG(open_basedir))) {
     485                 :                         struct stat s;
     486                 : 
     487               1 :                         if (0 != VCWD_STAT(pattern, &s) || S_IFDIR != (s.st_mode & S_IFMT)) {
     488               1 :                                 RETURN_FALSE;
     489                 :                         }
     490                 :                 }
     491              48 :                 array_init(return_value);
     492              48 :                 return;
     493                 :         }
     494                 : 
     495              67 :         array_init(return_value);
     496             199 :         for (n = 0; n < globbuf.gl_pathc; n++) {
     497             132 :                 if (PG(safe_mode) || (PG(open_basedir) && *PG(open_basedir))) {
     498              17 :                         if (PG(safe_mode) && (!php_checkuid_ex(globbuf.gl_pathv[n], NULL, CHECKUID_CHECK_FILE_AND_DIR, CHECKUID_NO_ERRORS))) {
     499               0 :                                 basedir_limit = 1;
     500               0 :                                 continue;
     501              17 :                         } else if (php_check_open_basedir_ex(globbuf.gl_pathv[n], 0 TSRMLS_CC)) {
     502              10 :                                 basedir_limit = 1;
     503              10 :                                 continue;
     504                 :                         }
     505                 :                 }
     506                 :                 /* we need to do this everytime since GLOB_ONLYDIR does not guarantee that
     507                 :                  * all directories will be filtered. GNU libc documentation states the
     508                 :                  * following: 
     509                 :                  * If the information about the type of the file is easily available 
     510                 :                  * non-directories will be rejected but no extra work will be done to 
     511                 :                  * determine the information for each file. I.e., the caller must still be 
     512                 :                  * able to filter directories out. 
     513                 :                  */
     514             122 :                 if (flags & GLOB_ONLYDIR) {
     515                 :                         struct stat s;
     516                 : 
     517              20 :                         if (0 != VCWD_STAT(globbuf.gl_pathv[n], &s)) {
     518               0 :                                 continue;
     519                 :                         }
     520                 : 
     521              20 :                         if (S_IFDIR != (s.st_mode & S_IFMT)) {
     522               0 :                                 continue;
     523                 :                         }
     524                 :                 }
     525             122 :                 add_next_index_string(return_value, globbuf.gl_pathv[n]+cwd_skip, 1);
     526                 :         }
     527                 : 
     528              67 :         globfree(&globbuf);
     529                 : 
     530              67 :         if (basedir_limit && !zend_hash_num_elements(Z_ARRVAL_P(return_value))) {
     531               9 :                 zval_dtor(return_value);
     532               9 :                 RETURN_FALSE;
     533                 :         }
     534                 : }
     535                 : /* }}} */
     536                 : #endif 
     537                 : 
     538                 : /* {{{ proto array scandir(string dir [, int sorting_order [, resource context]])
     539                 :    List files & directories inside the specified path */
     540                 : PHP_FUNCTION(scandir)
     541             121 : {
     542                 :         char *dirn;
     543                 :         int dirn_len;
     544             121 :         long flags = 0;
     545                 :         char **namelist;
     546                 :         int n, i;
     547             121 :         zval *zcontext = NULL;
     548             121 :         php_stream_context *context = NULL;
     549                 : 
     550             121 :         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|lr", &dirn, &dirn_len, &flags, &zcontext) == FAILURE) {
     551              36 :                 return;
     552                 :         }
     553                 : 
     554              85 :         if (dirn_len < 1) {
     555               9 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Directory name cannot be empty");
     556               9 :                 RETURN_FALSE;
     557                 :         }
     558                 : 
     559              76 :         if (zcontext) {
     560               2 :                 context = php_stream_context_from_zval(zcontext, 0);
     561                 :         }
     562                 : 
     563              76 :         if (!flags) {
     564              65 :                 n = php_stream_scandir(dirn, &namelist, context, (void *) php_stream_dirent_alphasort);
     565                 :         } else {
     566              11 :                 n = php_stream_scandir(dirn, &namelist, context, (void *) php_stream_dirent_alphasortr);
     567                 :         }
     568              76 :         if (n < 0) {
     569              31 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "(errno %d): %s", errno, strerror(errno));
     570              31 :                 RETURN_FALSE;
     571                 :         }
     572                 :         
     573              45 :         array_init(return_value);
     574                 : 
     575             184 :         for (i = 0; i < n; i++) {
     576             139 :                 add_next_index_string(return_value, namelist[i], 0);
     577                 :         }
     578                 : 
     579              45 :         if (n) {
     580              45 :                 efree(namelist);
     581                 :         }
     582                 : }
     583                 : /* }}} */
     584                 : 
     585                 : /*
     586                 :  * Local variables:
     587                 :  * tab-width: 4
     588                 :  * c-basic-offset: 4
     589                 :  * End:
     590                 :  * vim600: sw=4 ts=4 fdm=marker
     591                 :  * vim<600: sw=4 ts=4
     592                 :  */

Generated by: LTP GCOV extension version 1.5

Generated at Sat, 21 Nov 2009 12:27:11 +0000 (3 days ago)

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