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

Generated by: LTP GCOV extension version 1.5

Generated at Thu, 19 Nov 2009 08:20:22 +0000 (5 days ago)

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