2 # This is a Solaris specific patch. It was offered to
3 # upstream, but upstream opted for fix, which sets the
4 # GLOB_LIMIT at compile time. All details can be found
6 # http://bugs.proftpd.org/show_bug.cgi?id=4082
8 --- a/include/glibc-glob.h
9 +++ b/include/glibc-glob.h
10 @@ -85,6 +85,7 @@ extern "C" {
11 #define GLOB_ABORTED 2 /* Read error. */
12 #define GLOB_NOMATCH 3 /* No matches found. */
13 #define GLOB_NOSYS 4 /* Not implemented. */
14 +#define GLOB_LIMIT 5 /* MAX_RESULTS limit reached */
16 /* Previous versions of this file defined GLOB_ABEND instead of
17 GLOB_ABORTED. Provide a compatibility definition here. */
18 --- a/lib/glibc-glob.c
19 +++ b/lib/glibc-glob.c
20 @@ -40,6 +40,15 @@ char *alloca ();
21 #define MAX_RECURSION PR_TUNABLE_GLOBBING_MAX_RECURSION
22 #define MAX_RESULTS PR_TUNABLE_GLOBBING_MAX_MATCHES
24 +unsigned long GlobMaxResults = 0;
26 +static unsigned long get_globmaxresults(void)
28 + if (GlobMaxResults > 0)
29 + return GlobMaxResults;
33 /* Enable GNU extensions in glob.h. */
35 # define _GNU_SOURCE 1
36 @@ -239,8 +248,6 @@ extern void bcopy ();
37 # define mempcpy(Dest, Src, Len) __mempcpy (Dest, Src, Len)
40 -static unsigned long nbresults;
42 #ifndef __GNU_LIBRARY__
45 @@ -1157,7 +1164,6 @@ int
46 glob (const char *pattern, int flags, int (*errfunc) __P((const char *, int)),
50 return glob_limited(0U, pattern, flags, errfunc, pglob);
53 @@ -1318,6 +1324,7 @@ glob_in_dir (const char *pattern, const char *directory, int flags,
57 + int ret_glob_limit = 0;
59 meta = __glob_pattern_p (pattern, !(flags & GLOB_NOESCAPE));
60 if (meta == 0 && (flags & (GLOB_NOCHECK|GLOB_NOMAGIC)))
61 @@ -1428,10 +1435,6 @@ glob_in_dir (const char *pattern, const char *directory, int flags,
65 - if (nbresults > MAX_RESULTS) {
69 if (! REAL_DIR_ENTRY (d))
72 @@ -1463,6 +1466,14 @@ glob_in_dir (const char *pattern, const char *directory, int flags,
77 + if (nfound > get_globmaxresults()) {
78 + for (; names != NULL; names = names->next)
87 @@ -1516,6 +1527,9 @@ glob_in_dir (const char *pattern, const char *directory, int flags,
94 return nfound == 0 ? GLOB_NOMATCH : 0;
97 --- a/modules/mod_core.c
98 +++ b/modules/mod_core.c
99 @@ -1048,6 +1048,26 @@ MODRET set_maxconnrate(cmd_rec *cmd) {
100 return PR_HANDLED(cmd);
103 +extern unsigned long GlobMaxResults;
105 +MODRET set_globmaxresults(cmd_rec *cmd) {
110 + CHECK_CONF(cmd,CONF_ROOT);
112 + max = strtoul(cmd->argv[1], &endp, 10);
114 + if ((endp && *endp) || max == 0)
115 + CONF_ERROR(cmd, "argument must be greater than 0");
117 + pr_log_debug(DEBUG1, "setting GlobMaxResults to %lu", max);
119 + GlobMaxResults = max;
120 + return PR_HANDLED(cmd);
123 MODRET set_timeoutidle(cmd_rec *cmd) {
125 config_rec *c = NULL;
126 @@ -6941,6 +6961,8 @@ static conftable core_conftab[] = {
127 { "From", add_from, NULL },
128 { "FSCachePolicy", set_fscachepolicy, NULL },
129 { "FSOptions", set_fsoptions, NULL },
130 + { "GlobMaxResults", set_globmaxresults, NULL },
131 + { "Group", set_group, NULL },
132 { "Group", set_group, NULL },
133 { "GroupOwner", add_groupowner, NULL },
134 { "HideFiles", set_hidefiles, NULL },
135 --- a/modules/mod_ls.c
136 +++ b/modules/mod_ls.c
137 @@ -2181,6 +2181,8 @@ static int dolist(cmd_rec *cmd, const char *opt, const char *resp_code,
138 pr_response_add(R_226, _("Read error during globbing of %s"),
139 pr_fs_encode_path(cmd->tmp_pool, arg));
141 + } else if (a == GLOB_LIMIT) {
142 + pr_response_add(R_226, _("Too many files"));
143 } else if (a != GLOB_NOMATCH) {
144 pr_response_add(R_226, _("Unknown error during globbing of %s"),
145 pr_fs_encode_path(cmd->tmp_pool, arg));
146 @@ -3146,7 +3148,10 @@ MODRET ls_nlst(cmd_rec *cmd) {
147 return PR_HANDLED(cmd);
150 - pr_response_add_err(R_450, _("No files found"));
151 + if (res == GLOB_LIMIT)
152 + pr_response_add_err(R_451, _("Too many files"));
154 + pr_response_add_err(R_450, _("No files found"));
156 pr_cmd_set_errno(cmd, ENOENT);