Login
[x]
Log in using an account from:
Fedora Account System
Red Hat Associate
Red Hat Customer
Or login using a Red Hat Bugzilla account
Forgot Password
Login:
Hide Forgot
Create an Account
Red Hat Bugzilla – Attachment 627449 Details for
Bug 227498
overwrites downloaded file with symlink
[?]
New
Simple Search
Advanced Search
My Links
Browse
Requests
Reports
Current State
Search
Tabular reports
Graphical reports
Duplicates
Other Reports
User Changes
Plotly Reports
Bug Status
Bug Severity
Non-Defaults
|
Product Dashboard
Help
Page Help!
Bug Writing Guidelines
What's new
Browser Support Policy
5.0.4.rh83 Release notes
FAQ
Guides index
User guide
Web Services
Contact
Legal
This site requires JavaScript to be enabled to function correctly, please enable it.
[patch]
Patch for wget-1.14 solving this issue
0001-Fixed-error-when-downloading-SYMLINK-from-FTP.patch (text/plain), 13.89 KB, created by
Tomáš Hozza
on 2012-10-15 13:56:39 UTC
(
hide
)
Description:
Patch for wget-1.14 solving this issue
Filename:
MIME Type:
Creator:
Tomáš Hozza
Created:
2012-10-15 13:56:39 UTC
Size:
13.89 KB
patch
obsolete
>From 151a60419bea65d6a2d0b5022f04384ce81c63b9 Mon Sep 17 00:00:00 2001 >From: Tomas Hozza <thozza@redhat.com> >Date: Mon, 15 Oct 2012 14:49:30 +0200 >Subject: [PATCH] Fixed error when downloading SYMLINK from FTP. > >Fixed problem with downloading single file from a FTP >server, when timestamping (-N) is used and the target >file is a SYMLINK. Now wget downloads the file to which >the SYMLINK points and sets timestamp correctly (to timestamp >of the target file to which the SYMLINK points). >--- > src/ftp.c | 302 +++++++++++++++++++++++++++++++++++++++++++------------------- > src/url.c | 4 +- > src/url.h | 2 + > 3 files changed, 211 insertions(+), 97 deletions(-) > >diff --git a/src/ftp.c b/src/ftp.c >index 669e663..4ac8a69 100644 >--- a/src/ftp.c >+++ b/src/ftp.c >@@ -1725,6 +1725,113 @@ static uerr_t ftp_retrieve_dirs (struct url *, struct fileinfo *, ccon *); > static uerr_t ftp_retrieve_glob (struct url *, ccon *, int); > static struct fileinfo *delelement (struct fileinfo *, struct fileinfo **); > static void freefileinfo (struct fileinfo *f); >+static bool has_insecure_name_p (const char *); >+ >+/* Do a safe check on given fileinfo list and remove entries that >+ 1. Do not conform with global rules given in opt.accepts or opt.rejects. >+ 2. Files with possible harmful names. >+ 3. Entries that do not match given globbing pattern if glob_action is >+ GLOB_GLOBALL or GLOB_GETONE. >+ >+ If argument "file" is null, entries are not matched against any globbing >+ pattern. */ >+static uerr_t >+fileinfo_cleanup (struct fileinfo **start, const char *file, int glob_action) >+{ >+ struct fileinfo *f; >+ >+ /* 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 */ >+ f = *start; >+ while (f) >+ { >+ if (has_insecure_name_p (f->name)) >+ { >+ logprintf (LOG_VERBOSE, _("Rejecting %s.\n"), >+ quote (f->name)); >+ f = delelement (f, start); >+ } >+ 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 (file) >+ { >+ if (glob_action == GLOB_GLOBALL) >+ { >+ int (*matcher) (const char *, const char *, int) >+ = opt.ignore_case ? fnmatch_nocase : fnmatch; >+ int matchres = 0; >+ >+ f = *start; >+ while (f) >+ { >+ matchres = matcher (file, f->name, 0); >+ if (matchres == -1) >+ { >+ logprintf (LOG_NOTQUIET, _("Error matching %s against %s: %s\n"), >+ file, quotearg_style (escape_quoting_style, f->name), >+ strerror (errno)); >+ break; >+ } >+ 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; >+ } >+ } >+ else if (glob_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) >+ { >+ if (0 != cmp(file, f->name)) >+ f = delelement (f, start); >+ else >+ f = f->next; >+ } >+ } >+ } >+ return RETROK; >+} > > /* Retrieve a list of files given in struct fileinfo linked list. If > a file is a symbolic link, do not retrieve it, but rather try to >@@ -1734,7 +1841,7 @@ static void freefileinfo (struct fileinfo *f); > If opt.recursive is set, after all files have been retrieved, > ftp_retrieve_dirs will be called to retrieve the directories. */ > static uerr_t >-ftp_retrieve_list (struct url *u, struct fileinfo *f, ccon *con) >+ftp_retrieve_list (struct url *u, struct fileinfo *f, ccon *con, int action) > { > static int depth = 0; > uerr_t err; >@@ -1841,11 +1948,102 @@ The sizes do not match (local %s) -- retrieving.\n\n"), > switch (f->type) > { > case FT_SYMLINK: >+ /* In case we are downloading just one file using timestamping >+ and this file is a SYMLINK, then we need to traverse this >+ SYMLINK to the destination file, get its fileinfo and match >+ the timestamp with existing file and finaly download it if >+ everything is OK! */ >+ if (action == GLOB_GETONE) >+ { >+ struct fileinfo *finfo_list; >+ struct url *tmp_url; >+ char *dir, *file, *tmp; >+ >+ tmp_url = xnew0 (struct url); >+ >+ split_path (f->linkto, &dir, &file); >+ if (!strcmp (dir, "")) >+ { >+ xfree (dir); >+ dir = xstrdup (u->dir); >+ } >+ tmp = concat_strings (u->host, ":", dir, "/", file, NULL); >+ >+ tmp_url->url = rewrite_shorthand_url (tmp); >+ tmp_url->scheme = u->scheme; >+ tmp_url->host = xstrdup (u->host); >+ tmp_url->port = u->port; >+ tmp_url->path = concat_strings (dir, "/", file, NULL); >+ if (u->params) >+ tmp_url->params = xstrdup (u->params); >+ if (u->query) >+ tmp_url->query = xstrdup (u->query); >+ if (u->fragment) >+ tmp_url->fragment = xstrdup (u->fragment); >+ tmp_url->dir = dir; >+ tmp_url->file = file; >+ if (u->user) >+ tmp_url->user = xstrdup (u->user); >+ if (u->passwd) >+ tmp_url->passwd = xstrdup (u->passwd); >+ >+ dir = NULL; >+ file = NULL; >+ xfree(tmp); >+ >+ err = ftp_get_listing (tmp_url, con, &finfo_list); >+ if (err != RETROK) >+ { >+ url_free (tmp_url); >+ return err; >+ } >+ >+ err = fileinfo_cleanup (&finfo_list, tmp_url->file, action); >+ if (err != RETROK) >+ { >+ url_free (tmp_url); >+ return err; >+ } >+ >+ url_free (tmp_url); >+ >+ /* Copy the real file fileinfo */ >+ f->type = finfo_list->type; >+ f->size = finfo_list->size; >+ f->tstamp = finfo_list->tstamp; >+ f->ptype = finfo_list->ptype; >+ f->perms = finfo_list->perms; >+ xfree (f->linkto); >+ if (finfo_list->linkto) >+ f->linkto = xstrdup (finfo_list->linkto); >+ else >+ f->linkto = NULL; >+ >+ freefileinfo (finfo_list); >+ >+ /* Reset FTP connection status and command >+ to the state like it was in the beginning */ >+ con->st &= ~ON_YOUR_OWN; >+ if (!(con->st & DONE_CWD)) >+ con->cmd |= DO_CWD; >+ else >+ con->cmd &= ~DO_CWD; >+ con->cmd |= (DO_RETR | LEAVE_PENDING); >+ >+ if (con->csock < 0) >+ con->cmd |= DO_LOGIN; >+ else >+ con->cmd &= ~DO_LOGIN; >+ >+ /* Now we have correct fileinfo and can check timestamp >+ of the real file. */ >+ continue; >+ } > /* If opt.retr_symlinks is defined, we treat symlinks as > if they were normal files. There is currently no way > to distinguish whether they might be directories, and > follow them. */ >- if (!opt.retr_symlinks) >+ else if (!opt.retr_symlinks) > { > #ifdef HAVE_SYMLINK > if (!f->linkto) >@@ -2060,8 +2258,9 @@ has_insecure_name_p (const char *s) > > /* A near-top-level function to retrieve the files in a directory. > The function calls ftp_get_listing, to get a linked list of files. >- Then it weeds out the file names that do not match the pattern. >- ftp_retrieve_list is called with this updated list as an argument. >+ Then it weeds out the file names that do not match the pattern >+ using fileinfo_cleanup function. ftp_retrieve_list is called with >+ this updated list as an argument. > > If the argument ACTION is GLOB_GETONE, just download the file (but > first get the listing, so that the time-stamp is heeded); if it's >@@ -2078,100 +2277,15 @@ ftp_retrieve_glob (struct url *u, ccon *con, int action) > res = ftp_get_listing (u, 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 */ >- f = start; >- while (f) >- { >- if (has_insecure_name_p (f->name)) >- { >- logprintf (LOG_VERBOSE, _("Rejecting %s.\n"), >- quote (f->name)); >- f = delelement (f, &start); >- } >- 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) >- { >- int (*matcher) (const char *, const char *, int) >- = opt.ignore_case ? fnmatch_nocase : fnmatch; >- int matchres = 0; >+ >+ res = fileinfo_cleanup (&start, u->file, action); >+ if (res != RETROK) >+ return res; > >- f = start; >- while (f) >- { >- 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; >- } >- 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; >- } >- } >- 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) >- { >- if (0 != cmp(u->file, f->name)) >- f = delelement (f, &start); >- else >- f = f->next; >- } >- } >- } > if (start) > { > /* Just get everything. */ >- res = ftp_retrieve_list (u, start, con); >+ res = ftp_retrieve_list (u, start, con, action); > } > else > { >diff --git a/src/url.c b/src/url.c >index e44dfcd..4ae7d33 100644 >--- a/src/url.c >+++ b/src/url.c >@@ -585,8 +585,6 @@ rewrite_shorthand_url (const char *url) > } > return ret; > } >- >-static void split_path (const char *, char **, char **); > > /* Like strpbrk, with the exception that it returns the pointer to the > terminating zero (end-of-string aka "eos") if no matching character >@@ -980,7 +978,7 @@ url_error (const char *url, int error_code) > > DIR and FILE are freshly allocated. */ > >-static void >+void > split_path (const char *path, char **dir, char **file) > { > char *last_slash = strrchr (path, '/'); >diff --git a/src/url.h b/src/url.h >index edb6b06..da13e2c 100644 >--- a/src/url.h >+++ b/src/url.h >@@ -111,4 +111,6 @@ bool schemes_are_similar_p (enum url_scheme a, enum url_scheme b); > > bool are_urls_equal (const char *u1, const char *u2); > >+void split_path (const char *path, char **dir, char **file); >+ > #endif /* URL_H */ >-- >1.7.11.7 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Flags:
thozza
: review?
Actions:
View
|
Diff
Attachments on
bug 227498
: 627449