From c7d12d66f15f2cc1b2d1d3db7a6dec59ec5ac987 Mon Sep 17 00:00:00 2001 From: Darshit Shah Date: Tue, 13 Nov 2018 00:29:46 +0100 Subject: [PATCH] * src/ftp.c (ftp_retrieve_glob): Refactor to prevent looping over listing multiple times --- src/ftp.c | 130 +++++++++++++++++++++++++++--------------------------- 1 file changed, 64 insertions(+), 66 deletions(-) diff --git a/src/ftp.c b/src/ftp.c index daaae939..8af144ee 100644 --- a/src/ftp.c +++ b/src/ftp.c @@ -2578,96 +2578,94 @@ ftp_retrieve_glob (struct url *u, struct url *original_url, res = ftp_get_listing (u, original_url, con, &start); if (res != RETROK) return res; - /* First: weed out that do not conform the global rules given in - opt.accepts and opt.rejects. */ - if (opt.accepts || opt.rejects) - { - f = start; - while (f) - { - if (f->type != FT_DIRECTORY && !acceptable (f->name)) - { - logprintf (LOG_VERBOSE, _("Rejecting %s.\n"), - quote (f->name)); - f = delelement (f, &start); - } - else - f = f->next; - } - } - /* Remove all files with possible harmful names or invalid entries. */ + + // Set the function used for glob matching. + int (*matcher) (const char *, const char *, int) + = opt.ignore_case ? fnmatch_nocase : fnmatch; + + // Set the function used to compare strings +#ifdef __VMS + /* 2009-09-09 SMS. + * Odd-ball compiler ("HP C V7.3-009 on OpenVMS Alpha V7.3-2") + * bug causes spurious %CC-E-BADCONDIT complaint with this + * "?:" statement. (Different linkage attributes for strcmp() + * and strcasecmp().) Converting to "if" changes the + * complaint to %CC-W-PTRMISMATCH on "cmp = strcmp;". Adding + * the senseless type cast clears the complaint, and looks + * harmless. + */ + int (*cmp) (const char *, const char *) + = opt.ignore_case ? strcasecmp : (int (*)())strcmp; +#else /* def __VMS */ + int (*cmp) (const char *, const char *) + = opt.ignore_case ? strcasecmp : strcmp; +#endif /* def __VMS [else] */ + f = start; while (f) { - if (has_insecure_name_p (f->name) || is_invalid_entry (f)) + + // Weed out files that do not confirm to the global rules given in + // opt.accepts and opt.rejects + if ((opt.accepts || opt.rejects) && + f->type != FT_DIRECTORY && !acceptable (f->name)) { logprintf (LOG_VERBOSE, _("Rejecting %s.\n"), quote (f->name)); f = delelement (f, &start); + continue; } - else - f = f->next; - } - /* Now weed out the files that do not match our globbing pattern. - If we are dealing with a globbing pattern, that is. */ - if (*u->file) - { - if (action == GLOB_GLOBALL) + + + // Identify and eliminate possibly harmful names or invalid entries. + if (has_insecure_name_p (f->name) || is_invalid_entry (f)) { - int (*matcher) (const char *, const char *, int) - = opt.ignore_case ? fnmatch_nocase : fnmatch; - int matchres = 0; + logprintf (LOG_VERBOSE, _("Rejecting %s (Invalid Entry).\n"), + quote (f->name)); + f = delelement (f, &start); + continue; + } - f = start; - while (f) + + /* Now weed out the files that do not match our globbing pattern. + If we are dealing with a globbing pattern, that is. */ + if (*u->file) + { + if (action == GLOB_GLOBALL) { - matchres = matcher (u->file, f->name, 0); + int matchres = matcher (u->file, f->name, 0); if (matchres == -1) { logprintf (LOG_NOTQUIET, _("Error matching %s against %s: %s\n"), u->file, quotearg_style (escape_quoting_style, f->name), strerror (errno)); - break; + freefileinfo (start); + return RETRBADPATTERN; } if (matchres == FNM_NOMATCH) - f = delelement (f, &start); /* delete the element from the list */ - else - f = f->next; /* leave the element in the list */ - } - if (matchres == -1) - { - freefileinfo (start); - return RETRBADPATTERN; + { + f = delelement (f, &start); /* delete the element from the list */ + continue; + } } - } - else if (action == GLOB_GETONE) - { -#ifdef __VMS - /* 2009-09-09 SMS. - * Odd-ball compiler ("HP C V7.3-009 on OpenVMS Alpha V7.3-2") - * bug causes spurious %CC-E-BADCONDIT complaint with this - * "?:" statement. (Different linkage attributes for strcmp() - * and strcasecmp().) Converting to "if" changes the - * complaint to %CC-W-PTRMISMATCH on "cmp = strcmp;". Adding - * the senseless type cast clears the complaint, and looks - * harmless. - */ - int (*cmp) (const char *, const char *) - = opt.ignore_case ? strcasecmp : (int (*)())strcmp; -#else /* def __VMS */ - int (*cmp) (const char *, const char *) - = opt.ignore_case ? strcasecmp : strcmp; -#endif /* def __VMS [else] */ - f = start; - while (f) + else if (action == GLOB_GETONE) { if (0 != cmp(u->file, f->name)) - f = delelement (f, &start); - else - f = f->next; + { + f = delelement (f, &start); + continue; + } } } + + + f = f->next; } + + /* + * Now that preprocessing of the file listing is over, let's try to download + * all the remaining files in our listing. + */ if (start) { /* Just get everything. */ -- 2.19.1