++s;
if (!*s)
return 0;
- if (tolower (*s) != 'b')
+ if (TOLOWER (*s) != 'b')
continue;
if (strncasecmp (s, "byte", 4))
continue;
}
/* Third: Set type to Image (binary). */
if (!opt.server_response)
- logprintf (LOG_VERBOSE, "==> TYPE %c ... ", toupper (u->ftp_type));
- err = ftp_type (&con->rbuf, toupper (u->ftp_type));
+ logprintf (LOG_VERBOSE, "==> TYPE %c ... ", TOUPPER (u->ftp_type));
+ err = ftp_type (&con->rbuf, TOUPPER (u->ftp_type));
/* FTPRERR, WRITEFAILED, FTPUNKNOWNTYPE */
switch (err)
{
logputs (LOG_VERBOSE, "\n");
logprintf (LOG_NOTQUIET,
_("Unknown type `%c', closing control connection.\n"),
- toupper (u->ftp_type));
+ TOUPPER (u->ftp_type));
CLOSE (csock);
rbuf_uninitialize (&con->rbuf);
return err;
/* If anything is to be retrieved, PORT (or PASV) must be sent. */
if (cmd & (DO_LIST | DO_RETR))
{
- if (opt.ftp_pasv)
+ if (opt.ftp_pasv > 0)
{
char thost[256];
unsigned short tport;
expected_bytes = ftp_expected_bytes (ftp_last_respline);
} /* cmd & DO_LIST */
+ /* Some FTP servers return the total length of file after REST
+ command, others just return the remaining size. */
+ if (*len && restval && expected_bytes
+ && (expected_bytes == *len - restval))
+ {
+ DEBUGP (("Lying FTP server found, adjusting.\n"));
+ expected_bytes = *len;
+ }
+
/* If no transmission was required, then everything is OK. */
if (!(cmd & (DO_LIST | DO_RETR)))
return RETRFINISHED;
}
}
else
- fp = opt.dfp;
+ {
+ fp = opt.dfp;
+ if (!restval)
+ {
+ /* This will silently fail for streams that don't correspond
+ to regular files, but that's OK. */
+ rewind (fp);
+ clearerr (fp);
+ }
+ }
if (*len)
{
/* Close data connection socket. */
closeport (dtsock);
/* Close the local file. */
- if (!opt.dfp || con->cmd & DO_LIST)
- fclose (fp);
- else
- fflush (fp);
+ {
+ /* Close or flush the file. We have to be careful to check for
+ error here. Checking the result of fwrite() is not enough --
+ errors could go unnoticed! */
+ int flush_res;
+ if (!opt.dfp || con->cmd & DO_LIST)
+ flush_res = fclose (fp);
+ else
+ flush_res = fflush (fp);
+ if (flush_res == EOF)
+ res = -2;
+ }
/* If get_contents couldn't write to fp, bail out. */
if (res == -2)
{
/* If we get out of the switch above without continue'ing, we've
successfully downloaded a file. Remember this fact. */
- downloaded_file(ADD_FILE, locf);
+ downloaded_file(FILE_DOWNLOADED_NORMALLY, locf);
if (con->st & ON_YOUR_OWN)
{
tms, tmrate, locf, len);
logprintf (LOG_NONVERBOSE, "%s URL: %s [%ld] -> \"%s\" [%d]\n",
tms, u->url, len, locf, count);
- /* Do not count listings among the downloaded stuff, since they
- will get deleted anyway. */
- if (!(con->cmd & DO_LIST))
+
+ if ((con->cmd & DO_LIST))
+ /* This is a directory listing file. */
{
- ++opt.numurls;
- opt.downloaded += len;
+ if (!opt.remove_listing)
+ /* --dont-remove-listing was specified, so do count this towards the
+ number of bytes and files downloaded. */
+ {
+ downloaded_increase (len);
+ opt.numurls++;
+ }
+
+ /* Deletion of listing files is not controlled by --delete-after, but
+ by the more specific option --dont-remove-listing, and the code
+ to do this deletion is in another function. */
}
+ else
+ /* This is not a directory listing file. */
+ {
+ /* Unlike directory listing files, don't pretend normal files weren't
+ downloaded if they're going to be deleted. People seeding proxies,
+ for instance, may want to know how many bytes and files they've
+ downloaded through it. */
+ downloaded_increase (len);
+ opt.numurls++;
+
+ if (opt.delete_after)
+ {
+ 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));
+ }
+ }
+
/* Restore the original leave-pendingness. */
if (orig_lp)
con->cmd |= LEAVE_PENDING;
/* Increase the depth. */
++depth;
- if (opt.reclevel && depth > opt.reclevel)
+ if (opt.reclevel != INFINITE_RECURSION && depth > opt.reclevel)
{
DEBUGP ((_("Recursion depth %d exceeded max. depth %d.\n"),
depth, opt.reclevel));
while (f)
{
- if (opt.quota && opt.downloaded > opt.quota)
+ if (downloaded_exceeds_quota ())
{
--depth;
return QUOTEXC;
else if (f->tstamp == -1)
logprintf (LOG_NOTQUIET, _("%s: corrupt time-stamp.\n"), u->local);
- if (f->perms && dlthis)
+ if (f->perms && f->type == FT_PLAINFILE && dlthis)
chmod (u->local, f->perms);
else
DEBUGP (("Unrecognized permissions for %s.\n", u->local));
f = f->next;
} /* while */
/* We do not want to call ftp_retrieve_dirs here */
- if (opt.recursive && !(opt.reclevel && depth >= opt.reclevel))
+ if (opt.recursive &&
+ !(opt.reclevel != INFINITE_RECURSION && depth >= opt.reclevel))
err = ftp_retrieve_dirs (u, orig, con);
else if (opt.recursive)
DEBUGP ((_("Will not retrieve dirs since depth is %d (max %d).\n"),
{
int len;
- if (opt.quota && opt.downloaded > opt.quota)
+ if (downloaded_exceeds_quota ())
break;
if (f->type != FT_DIRECTORY)
continue;
}
}
freefileinfo (start);
- if (opt.quota && opt.downloaded > opt.quota)
+ if (downloaded_exceeds_quota ())
return QUOTEXC;
else
/* #### Should we return `res' here? */