#include <stdio.h>
#include <stdlib.h>
-#ifdef HAVE_STRING_H
-# include <string.h>
-#else
-# include <strings.h>
-#endif
+#include <string.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
-#include <sys/types.h>
#include <assert.h>
#include <errno.h>
#include "convert.h" /* for downloaded_file */
#include "recur.h" /* for INFINITE_RECURSION */
-#ifndef errno
-extern int errno;
-#endif
-
-extern LARGE_INT total_downloaded_bytes;
-
/* File where the "ls -al" listing will be saved. */
#define LIST_FILENAME ".listing"
extern char ftp_last_respline[];
extern FILE *output_stream;
-extern int output_stream_regular;
+extern bool output_stream_regular;
typedef struct
{
#endif
static void
-print_length (wgint size, wgint start, int authoritative)
+print_length (wgint size, wgint start, bool authoritative)
{
- logprintf (LOG_VERBOSE, _("Length: %s"), with_thousand_seps (size));
+ logprintf (LOG_VERBOSE, _("Length: %s"), number_to_static_string (size));
if (size >= 1024)
logprintf (LOG_VERBOSE, " (%s)", human_readable (size));
if (start > 0)
{
if (start >= 1024)
logprintf (LOG_VERBOSE, _(", %s (%s) remaining"),
- with_thousand_seps (size - start),
+ number_to_static_string (size - start),
human_readable (size - start));
else
logprintf (LOG_VERBOSE, _(", %s remaining"),
- with_thousand_seps (size - start));
+ number_to_static_string (size - start));
}
- if (!authoritative)
- logputs (LOG_VERBOSE, _(" (unauthoritative)\n"));
+ logputs (LOG_VERBOSE, !authoritative ? _(" (unauthoritative)\n") : "\n");
}
/* Retrieves a file with denoted parameters through opening an FTP
uerr_t err = RETROK; /* appease the compiler */
FILE *fp;
char *user, *passwd, *respline;
- char *tms, *tmrate;
+ char *tms;
+ const char *tmrate;
int cmd = con->cmd;
- int pasv_mode_open = 0;
+ bool pasv_mode_open = false;
wgint expected_bytes = 0;
- int rest_failed = 0;
+ bool rest_failed = false;
int flags;
wgint rd_size;
else /* do not CWD */
logputs (LOG_VERBOSE, _("==> CWD not required.\n"));
- if ((cmd & DO_RETR) && restval && *len == 0)
+ if ((cmd & DO_RETR) && *len == 0)
{
if (opt.verbose)
{
switch (err)
{
case FTPRERR:
- case FTPSRVERR :
+ case FTPSRVERR:
logputs (LOG_VERBOSE, "\n");
logputs (LOG_NOTQUIET, _("\
Error in server response, closing control connection.\n"));
abort ();
}
if (!opt.server_response)
- logputs (LOG_VERBOSE, _("done.\n"));
+ logprintf (LOG_VERBOSE, *len ? "%s\n" : _("done.\n"),
+ number_to_static_string (*len));
}
/* If anything is to be retrieved, PORT (or PASV) must be sent. */
if (cmd & (DO_LIST | DO_RETR))
{
- if (opt.ftp_pasv > 0)
+ if (opt.ftp_pasv)
{
ip_address passive_addr;
int passive_port;
? CONERROR : CONIMPOSSIBLE);
}
- pasv_mode_open = 1; /* Flag to avoid accept port */
+ pasv_mode_open = true; /* Flag to avoid accept port */
if (!opt.server_response)
logputs (LOG_VERBOSE, _("done. "));
} /* err==FTP_OK */
return err;
case FTPRESTFAIL:
logputs (LOG_VERBOSE, _("\nREST failed, starting from scratch.\n"));
- rest_failed = 1;
+ rest_failed = true;
break;
case FTPOK:
break;
fp = fopen (con->target, "wb");
else
{
- fp = fopen_excl (con->target, 1);
+ fp = fopen_excl (con->target, true);
if (!fp && errno == EEXIST)
{
/* We cannot just invent a new name and use it (which is
if (*len)
{
- print_length (*len, restval, 1);
+ print_length (*len, restval, true);
expected_bytes = *len; /* for get_contents/show_progress */
}
else if (expected_bytes)
- print_length (expected_bytes, restval, 0);
+ print_length (expected_bytes, restval, false);
/* Get the contents of the document. */
flags = 0;
restval, &rd_size, len, &con->dltime, flags);
tms = time_str (NULL);
- tmrate = retr_rate (rd_size, con->dltime, 0);
+ tmrate = retr_rate (rd_size, con->dltime);
+ total_download_time += con->dltime;
+
/* Close data connection socket. */
fd_close (dtsock);
fd_close (local_sock);
int count, orig_lp;
wgint restval, len = 0;
char *tms, *locf;
- char *tmrate = NULL;
+ const char *tmrate = NULL;
uerr_t err;
struct_stat st;
if (opt.noclobber && file_exists_p (con->target))
{
logprintf (LOG_VERBOSE,
- _("File `%s' already there, not retrieving.\n"), con->target);
+ _("File `%s' already there; not retrieving.\n"), con->target);
/* If the file is there, we suppose it's retrieved OK. */
return RETROK;
}
}
/* Decide whether or not to restart. */
- restval = 0;
- if (count > 1)
- restval = len; /* start where the previous run left off */
- else if (opt.always_rest
- && stat (locf, &st) == 0
- && S_ISREG (st.st_mode))
+ if (opt.always_rest
+ && stat (locf, &st) == 0
+ && S_ISREG (st.st_mode))
+ /* When -c is used, continue from on-disk size. (Can't use
+ hstat.len even if count>1 because we don't want a failed
+ first attempt to clobber existing data.) */
restval = st.st_size;
+ else if (count > 1)
+ restval = len; /* start where the previous run left off */
+ else
+ restval = 0;
/* Get the current time string. */
tms = time_str (NULL);
/* Print fetch message, if opt.verbose. */
if (opt.verbose)
{
- char *hurl = url_string (u, 1);
+ char *hurl = url_string (u, true);
char tmp[256];
strcpy (tmp, " ");
if (count > 1)
}
tms = time_str (NULL);
if (!opt.spider)
- tmrate = retr_rate (len - restval, con->dltime, 0);
+ tmrate = retr_rate (len - restval, con->dltime);
/* If we get out of the switch above without continue'ing, we've
successfully downloaded a file. Remember this fact. */
/* Need to hide the password from the URL. The `if' is here
so that we don't do the needless allocation every
time. */
- char *hurl = url_string (u, 1);
+ char *hurl = url_string (u, true);
logprintf (LOG_NONVERBOSE, "%s URL: %s [%s] -> \"%s\" [%d]\n",
tms, hurl, number_to_static_string (len), locf, count);
xfree (hurl);
if (opt.delete_after)
{
- DEBUGP (("Removing file due to --delete-after in"
- " ftp_loop_internal():\n"));
+ DEBUGP (("\
+Removing file due to --delete-after in ftp_loop_internal():\n"));
logprintf (LOG_VERBOSE, _("Removing %s.\n"), locf);
if (unlink (locf))
logprintf (LOG_NOTQUIET, "unlink: %s\n", strerror (errno));
return err;
}
-static uerr_t ftp_retrieve_dirs PARAMS ((struct url *, struct fileinfo *,
- ccon *));
-static uerr_t ftp_retrieve_glob PARAMS ((struct url *, ccon *, int));
-static struct fileinfo *delelement PARAMS ((struct fileinfo *,
- struct fileinfo **));
-static void freefileinfo PARAMS ((struct fileinfo *f));
+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);
/* 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
struct fileinfo *orig;
wgint local_size;
time_t tml;
- int dlthis;
+ bool dlthis;
/* Increase the depth. */
++depth;
con->target = url_file_name (u);
err = RETROK;
- dlthis = 1;
+ dlthis = true;
if (opt.timestamping && f->type == FT_PLAINFILE)
{
struct_stat st;
.orig suffix. */
if (!stat (con->target, &st))
{
- int eq_size;
- int cor_val;
+ bool eq_size;
+ bool cor_val;
/* Else, get it from the file. */
local_size = st.st_size;
tml = st.st_mtime;
values. Assumme sizes being equal for servers that lie
about file size. */
cor_val = (con->rs == ST_UNIX || con->rs == ST_WINNT);
- eq_size = cor_val ? (local_size == f->size) : 1 ;
+ eq_size = cor_val ? (local_size == f->size) : true;
if (f->tstamp <= tml && eq_size)
{
/* Remote file is older, file sizes can be compared and
are both equal. */
logprintf (LOG_VERBOSE, _("\
Remote file no newer than local file `%s' -- not retrieving.\n"), con->target);
- dlthis = 0;
+ dlthis = false;
}
else if (eq_size)
{
logprintf (LOG_VERBOSE, _("\
Already have correct symlink %s -> %s\n\n"),
con->target, escnonprint (f->linkto));
- dlthis = 0;
+ dlthis = false;
break;
}
}
return RETROK;
}
-/* Return non-zero if S has a leading '/' or contains '../' */
-static int
+/* Return true if S has a leading '/' or contains '../' */
+static bool
has_insecure_name_p (const char *s)
{
if (*s == '/')
- return 1;
+ return true;
if (strstr (s, "../") != 0)
- return 1;
+ return true;
- return 0;
+ return false;
}
/* A near-top-level function to retrieve the files in a directory.
}
else
{
- int wild = has_wildcards_p (u->file);
- if ((opt.ftp_glob && wild) || opt.recursive || opt.timestamping)
+ bool ispattern = false;
+ if (opt.ftp_glob)
+ {
+ /* Treat the URL as a pattern if the file name part of the
+ URL path contains wildcards. (Don't check for u->file
+ because it is unescaped and therefore doesn't leave users
+ the option to escape literal '*' as %2A.) */
+ char *file_part = strrchr (u->path, '/');
+ if (!file_part)
+ file_part = u->path;
+ ispattern = has_wildcards_p (file_part);
+ }
+ if (ispattern || opt.recursive || opt.timestamping)
{
/* ftp_retrieve_glob is a catch-all function that gets called
if we need globbing, time-stamping or recursion. Its
third argument is just what we really need. */
res = ftp_retrieve_glob (u, &con,
- (opt.ftp_glob && wild)
- ? GLOB_GLOBALL : GLOB_GETONE);
+ ispattern ? GLOB_GLOBALL : GLOB_GETONE);
}
else
res = ftp_loop_internal (u, NULL, &con);