php_scandir.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  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: Shane Caraveo <shane@caraveo.com> |
  16. | Ilia Alshanetsky <ilia@prohost.org> |
  17. +----------------------------------------------------------------------+
  18. */
  19. /* $Id$ */
  20. #include "php.h"
  21. #include "php_scandir.h"
  22. #ifdef HAVE_SYS_TYPES_H
  23. #include <sys/types.h>
  24. #endif
  25. #ifdef HAVE_DIRENT_H
  26. #include <dirent.h>
  27. #endif
  28. #ifndef HAVE_SCANDIR
  29. #ifdef PHP_WIN32
  30. #include "win32/param.h"
  31. #include "win32/readdir.h"
  32. #endif
  33. #include <stdlib.h>
  34. #ifndef NETWARE
  35. #include <search.h>
  36. #endif
  37. #endif /* HAVE_SCANDIR */
  38. #ifndef HAVE_ALPHASORT
  39. #ifdef HAVE_STRING_H
  40. #include <string.h>
  41. #endif
  42. PHPAPI int php_alphasort(const struct dirent **a, const struct dirent **b)
  43. {
  44. return strcoll((*a)->d_name,(*b)->d_name);
  45. }
  46. #endif /* HAVE_ALPHASORT */
  47. #ifndef HAVE_SCANDIR
  48. PHPAPI int php_scandir(const char *dirname, struct dirent **namelist[], int (*selector) (const struct dirent *entry), int (*compare) (const struct dirent **a, const struct dirent **b))
  49. {
  50. DIR *dirp = NULL;
  51. struct dirent **vector = NULL;
  52. int vector_size = 0;
  53. int nfiles = 0;
  54. char entry[sizeof(struct dirent)+MAXPATHLEN];
  55. struct dirent *dp = (struct dirent *)&entry;
  56. if (namelist == NULL) {
  57. return -1;
  58. }
  59. if (!(dirp = opendir(dirname))) {
  60. return -1;
  61. }
  62. while (!php_readdir_r(dirp, (struct dirent *)entry, &dp) && dp) {
  63. int dsize = 0;
  64. struct dirent *newdp = NULL;
  65. if (selector && (*selector)(dp) == 0) {
  66. continue;
  67. }
  68. if (nfiles == vector_size) {
  69. struct dirent **newv;
  70. if (vector_size == 0) {
  71. vector_size = 10;
  72. } else {
  73. vector_size *= 2;
  74. }
  75. newv = (struct dirent **) realloc (vector, vector_size * sizeof (struct dirent *));
  76. if (!newv) {
  77. return -1;
  78. }
  79. vector = newv;
  80. }
  81. dsize = sizeof (struct dirent) + ((strlen(dp->d_name) + 1) * sizeof(char));
  82. newdp = (struct dirent *) malloc(dsize);
  83. if (newdp == NULL) {
  84. goto fail;
  85. }
  86. vector[nfiles++] = (struct dirent *) memcpy(newdp, dp, dsize);
  87. }
  88. closedir(dirp);
  89. *namelist = vector;
  90. if (compare) {
  91. qsort (*namelist, nfiles, sizeof(struct dirent *), compare);
  92. }
  93. return nfiles;
  94. fail:
  95. while (nfiles-- > 0) {
  96. free(vector[nfiles]);
  97. }
  98. free(vector);
  99. return -1;
  100. }
  101. #endif
  102. /*
  103. * Local variables:
  104. * tab-width: 4
  105. * c-basic-offset: 4
  106. * End:
  107. * vim600: sw=4 ts=4 fdm=marker
  108. * vim<600: sw=4 ts=4
  109. */