You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

158 lines
3.4 KiB

28 years ago
17 years ago
28 years ago
28 years ago
28 years ago
28 years ago
28 years ago
17 years ago
28 years ago
28 years ago
28 years ago
28 years ago
28 years ago
28 years ago
28 years ago
28 years ago
28 years ago
28 years ago
28 years ago
28 years ago
28 years ago
28 years ago
28 years ago
28 years ago
28 years ago
28 years ago
28 years ago
28 years ago
  1. #include <malloc.h>
  2. #include <string.h>
  3. #include <errno.h>
  4. #include "php.h"
  5. #include "readdir.h"
  6. #include "TSRM.h"
  7. /**********************************************************************
  8. * Implement dirent-style opendir/readdir/rewinddir/closedir on Win32
  9. *
  10. * Functions defined are opendir(), readdir(), rewinddir() and
  11. * closedir() with the same prototypes as the normal dirent.h
  12. * implementation.
  13. *
  14. * Does not implement telldir(), seekdir(), or scandir(). The dirent
  15. * struct is compatible with Unix, except that d_ino is always 1 and
  16. * d_off is made up as we go along.
  17. *
  18. * The DIR typedef is not compatible with Unix.
  19. **********************************************************************/
  20. DIR *opendir(const char *dir)
  21. {
  22. DIR *dp;
  23. char *filespec;
  24. HANDLE handle;
  25. int index;
  26. char resolved_path_buff[MAXPATHLEN];
  27. TSRMLS_FETCH();
  28. if (!VCWD_REALPATH(dir, resolved_path_buff)) {
  29. return NULL;
  30. }
  31. filespec = (char *)malloc(strlen(resolved_path_buff) + 2 + 1);
  32. strcpy(filespec, resolved_path_buff);
  33. index = strlen(filespec) - 1;
  34. if (index >= 0 && (filespec[index] == '/' ||
  35. (filespec[index] == '\\' && (index == 0 || !IsDBCSLeadByte(filespec[index-1])))))
  36. filespec[index] = '\0';
  37. strcat(filespec, "\\*");
  38. dp = (DIR *) malloc(sizeof(DIR));
  39. dp->offset = 0;
  40. dp->finished = 0;
  41. if ((handle = FindFirstFile(filespec, &(dp->fileinfo))) == INVALID_HANDLE_VALUE) {
  42. DWORD err = GetLastError();
  43. if (err == ERROR_NO_MORE_FILES || err == ERROR_FILE_NOT_FOUND) {
  44. dp->finished = 1;
  45. } else {
  46. free(dp);
  47. free(filespec);
  48. return NULL;
  49. }
  50. }
  51. dp->dir = strdup(resolved_path_buff);
  52. dp->handle = handle;
  53. free(filespec);
  54. return dp;
  55. }
  56. struct dirent *readdir(DIR *dp)
  57. {
  58. if (!dp || dp->finished)
  59. return NULL;
  60. if (dp->offset != 0) {
  61. if (FindNextFile(dp->handle, &(dp->fileinfo)) == 0) {
  62. dp->finished = 1;
  63. return NULL;
  64. }
  65. }
  66. dp->offset++;
  67. strlcpy(dp->dent.d_name, dp->fileinfo.cFileName, _MAX_FNAME+1);
  68. dp->dent.d_ino = 1;
  69. dp->dent.d_reclen = strlen(dp->dent.d_name);
  70. dp->dent.d_off = dp->offset;
  71. return &(dp->dent);
  72. }
  73. int readdir_r(DIR *dp, struct dirent *entry, struct dirent **result)
  74. {
  75. if (!dp || dp->finished) {
  76. *result = NULL;
  77. return 0;
  78. }
  79. if (dp->offset != 0) {
  80. if (FindNextFile(dp->handle, &(dp->fileinfo)) == 0) {
  81. dp->finished = 1;
  82. *result = NULL;
  83. return 0;
  84. }
  85. }
  86. dp->offset++;
  87. strlcpy(dp->dent.d_name, dp->fileinfo.cFileName, _MAX_FNAME+1);
  88. dp->dent.d_ino = 1;
  89. dp->dent.d_reclen = strlen(dp->dent.d_name);
  90. dp->dent.d_off = dp->offset;
  91. memcpy(entry, &dp->dent, sizeof(*entry));
  92. *result = &dp->dent;
  93. return 0;
  94. }
  95. int closedir(DIR *dp)
  96. {
  97. if (!dp)
  98. return 0;
  99. /* It is valid to scan an empty directory but we have an invalid
  100. handle in this case (no first file found). */
  101. if (dp->handle != INVALID_HANDLE_VALUE) {
  102. FindClose(dp->handle);
  103. }
  104. if (dp->dir)
  105. free(dp->dir);
  106. if (dp)
  107. free(dp);
  108. return 0;
  109. }
  110. int rewinddir(DIR *dp)
  111. {
  112. /* Re-set to the beginning */
  113. char *filespec;
  114. HANDLE handle;
  115. int index;
  116. FindClose(dp->handle);
  117. dp->offset = 0;
  118. dp->finished = 0;
  119. filespec = (char *)malloc(strlen(dp->dir) + 2 + 1);
  120. strcpy(filespec, dp->dir);
  121. index = strlen(filespec) - 1;
  122. if (index >= 0 && (filespec[index] == '/' ||
  123. (filespec[index] == '\\' && (index == 0 || !IsDBCSLeadByte(filespec[index-1])))))
  124. filespec[index] = '\0';
  125. strcat(filespec, "/*");
  126. if ((handle = FindFirstFile(filespec, &(dp->fileinfo))) == INVALID_HANDLE_VALUE) {
  127. dp->finished = 1;
  128. }
  129. dp->handle = handle;
  130. free(filespec);
  131. return 0;
  132. }