root/ext/standard/dir.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. php_set_default_dir
  2. PHP_RINIT_FUNCTION
  3. PHP_MINIT_FUNCTION
  4. _php_do_opendir
  5. PHP_FUNCTION
  6. PHP_FUNCTION
  7. PHP_FUNCTION
  8. PHP_FUNCTION
  9. PHP_FUNCTION
  10. PHP_FUNCTION
  11. PHP_FUNCTION
  12. PHP_NAMED_FUNCTION
  13. PHP_FUNCTION
  14. PHP_FUNCTION

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

/* [<][>][^][v][top][bottom][index][help] */