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