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
53PHPAPI 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
60PHPAPI 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
120fail:
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