You should have received a copy of the GNU General Public License
along with Wget; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+In addition, as a special exception, the Free Software Foundation
+gives permission to link the code of its release of Wget with the
+OpenSSL project's "OpenSSL" library (or with modified versions of it
+that use the same license as the "OpenSSL" library), and distribute
+the linked executables. You must obey the GNU General Public License
+in all respects for all of the code used other than "OpenSSL". If you
+modify this file, you may extend this exception to your version of the
+file, but you are not obligated to do so. If you do not wish to do
+so, delete this exception statement from your version. */
#include <config.h>
#include "host.h"
#include "fnmatch.h"
#include "netrc.h"
+#include "convert.h" /* for downloaded_file */
#ifndef errno
extern int errno;
int st; /* connection status */
int cmd; /* command code */
struct rbuf rbuf; /* control connection buffer */
- long dltime; /* time of the download */
+ double dltime; /* time of the download in msecs */
enum stype rs; /* remote system reported by ftp server */
char *id; /* initial directory */
char *target; /* target file name */
address_list_release (al);
if (csock < 0)
- return errno == ECONNREFUSED ? CONREFUSED : CONERROR;
+ return CONNECT_ERROR (errno);
if (cmd & LEAVE_PENDING)
rbuf_initialize (&con->rbuf, csock);
A relative directory is one that does not begin with '/'
and, on non-Unix OS'es, one that doesn't begin with
- "<letter>:". */
+ "[a-z]:".
+
+ This is not done for OS400, which doesn't use
+ "/"-delimited directories, nor does it support directory
+ hierarchies. "CWD foo" followed by "CWD bar" leaves us
+ in "bar", not in "foo/bar", as would be customary
+ elsewhere. */
if (target[0] != '/'
&& !(con->rs != ST_UNIX
- && ISALPHA (target[0]) && target[1] == ':'))
+ && ISALPHA (target[0])
+ && target[1] == ':')
+ && con->rs != ST_OS400)
{
int idlen = strlen (con->id);
char *ntarget, *p;
logprintf (LOG_VERBOSE, _("couldn't connect to %s:%hu: %s\n"),
pretty_print_address (&passive_addr), passive_port,
strerror (save_errno));
- return save_errno == ECONNREFUSED ? CONREFUSED : CONERROR;
+ return CONNECT_ERROR (save_errno);
}
pasv_mode_open = 1; /* Flag to avoid accept port */
if (cmd & DO_RETR)
{
+ /* If we're in spider mode, don't really retrieve anything. The
+ fact that we got to this point should be proof enough that
+ the file exists, vaguely akin to HTTP's concept of a "HEAD"
+ request. */
+ if (opt.spider)
+ {
+ CLOSE (csock);
+ closeport (dtsock);
+ rbuf_uninitialize (&con->rbuf);
+ return RETRFINISHED;
+ }
+
if (opt.verbose)
{
if (!opt.server_response)
/* Rewind the output document if the download starts over and if
this is the first download. See gethttp() for a longer
explanation. */
- if (!restval && global_download_count == 0)
+ if (!restval && global_download_count == 0 && opt.dfp != stdout)
{
/* This will silently fail for streams that don't correspond
to regular files, but that's OK. */
struct stat st;
if (!con->target)
- con->target = url_filename (u);
+ con->target = url_file_name (u);
if (opt.noclobber && file_exists_p (con->target))
{
/* If we get out of the switch above without continue'ing, we've
successfully downloaded a file. Remember this fact. */
- downloaded_file(FILE_DOWNLOADED_NORMALLY, locf);
+ downloaded_file (FILE_DOWNLOADED_NORMALLY, locf);
if (con->st & ON_YOUR_OWN)
{
/* Find the listing file name. We do it by taking the file name of
the URL and replacing the last component with the listing file
name. */
- uf = url_filename (u);
+ uf = url_file_name (u);
lf = file_merge (uf, LIST_FILENAME);
xfree (uf);
DEBUGP ((_("Using `%s' as listing tmp file.\n"), lf));
ofile = xstrdup (u->file);
url_set_file (u, f->name);
- con->target = url_filename (u);
+ con->target = url_file_name (u);
err = RETROK;
dlthis = 1;
static uerr_t
ftp_retrieve_glob (struct url *u, ccon *con, int action)
{
- struct fileinfo *orig, *start;
+ struct fileinfo *f, *orig, *start;
uerr_t res;
con->cmd |= LEAVE_PENDING;
opt.accepts and opt.rejects. */
if (opt.accepts || opt.rejects)
{
- struct fileinfo *f = orig;
-
+ f = orig;
while (f)
{
if (f->type != FT_DIRECTORY && !acceptable (f->name))
f = f->next;
}
}
+ /* Remove all files with possible harmful names */
+ f = orig;
+ while (f)
+ {
+ if (has_insecure_name_p(f->name))
+ {
+ logprintf (LOG_VERBOSE, _("Rejecting `%s'.\n"), 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 && (action == GLOBALL || action == GETONE))
{
int matchres = 0;
- struct fileinfo *f = start;
+ f = start;
while (f)
{
matchres = fnmatch (u->file, f->name, 0);
char *filename = (opt.output_document
? xstrdup (opt.output_document)
: (con.target ? xstrdup (con.target)
- : url_filename (u)));
+ : url_file_name (u)));
res = ftp_index (filename, u, f);
if (res == FTPOK && opt.verbose)
{