/* Look for regexp "( *[0-9]+ *byte" (literal parenthesis) anywhere in
- the string S, and return the number converted to long, if found, 0
+ the string S, and return the number converted to wgint, if found, 0
otherwise. */
-static long
+static wgint
ftp_expected_bytes (const char *s)
{
- long res;
+ wgint res;
while (1)
{
++s;
if (!*s)
return 0;
- for (++s; *s && ISSPACE (*s); s++);
- if (!*s)
- return 0;
- if (!ISDIGIT (*s))
- continue;
- res = 0;
- do
- {
- res = (*s - '0') + 10 * res;
- ++s;
- }
- while (*s && ISDIGIT (*s));
+ ++s; /* skip the '(' */
+ res = str_to_wgint (s, (char **) &s, 10);
if (!*s)
return 0;
while (*s && ISSPACE (*s))
connection to the server. It always closes the data connection,
and closes the control connection in case of error. */
static uerr_t
-getftp (struct url *u, long *len, long restval, ccon *con)
+getftp (struct url *u, wgint *len, wgint restval, ccon *con)
{
int csock, dtsock, local_sock, res;
- uerr_t err;
+ uerr_t err = RETROK; /* appease the compiler */
FILE *fp;
char *user, *passwd, *respline;
char *tms, *tmrate;
int cmd = con->cmd;
int pasv_mode_open = 0;
- long expected_bytes = 0L;
+ wgint expected_bytes = 0L;
int rest_failed = 0;
int flags;
- long rd_size;
+ wgint rd_size;
assert (con != NULL);
assert (con->target != NULL);
con->csock = -1;
/* Second: Login with proper USER/PASS sequence. */
- logprintf (LOG_VERBOSE, _("Logging in as %s ... "), user);
+ logprintf (LOG_VERBOSE, _("Logging in as %s ... "), escnonprint (user));
if (opt.server_response)
logputs (LOG_ALWAYS, "\n");
err = ftp_login (csock, logname, passwd);
}
if (!opt.server_response)
- logprintf (LOG_VERBOSE, "==> CWD %s ... ", target);
+ logprintf (LOG_VERBOSE, "==> CWD %s ... ", escnonprint (target));
err = ftp_cwd (csock, target);
/* FTPRERR, WRITEFAILED, FTPNSFOD */
switch (err)
case FTPNSFOD:
logputs (LOG_VERBOSE, "\n");
logprintf (LOG_NOTQUIET, _("No such directory `%s'.\n\n"),
- u->dir);
+ escnonprint (u->dir));
fd_close (csock);
con->csock = -1;
return err;
if (opt.verbose)
{
if (!opt.server_response)
- logprintf (LOG_VERBOSE, "==> SIZE %s ... ", u->file);
+ logprintf (LOG_VERBOSE, "==> SIZE %s ... ", escnonprint (u->file));
}
err = ftp_size (csock, u->file, len);
if (restval && (cmd & DO_RETR))
{
if (!opt.server_response)
- logprintf (LOG_VERBOSE, "==> REST %ld ... ", restval);
+ logprintf (LOG_VERBOSE, "==> REST %s ... ",
+ number_to_static_string (restval));
err = ftp_rest (csock, restval);
/* FTPRERR, WRITEFAILED, FTPRESTFAIL */
{
if (restval)
logputs (LOG_VERBOSE, "\n");
- logprintf (LOG_VERBOSE, "==> RETR %s ... ", u->file);
+ logprintf (LOG_VERBOSE, "==> RETR %s ... ", escnonprint (u->file));
}
}
break;
case FTPNSFOD:
logputs (LOG_VERBOSE, "\n");
- logprintf (LOG_NOTQUIET, _("No such file `%s'.\n\n"), u->file);
+ logprintf (LOG_NOTQUIET, _("No such file `%s'.\n\n"),
+ escnonprint (u->file));
fd_close (dtsock);
fd_close (local_sock);
return err;
mkalldirs (con->target);
if (opt.backups)
rotate_backups (con->target);
- /* #### Is this correct? */
- chmod (con->target, 0600);
- fp = fopen (con->target, restval ? "ab" : "wb");
+ if (restval)
+ fp = fopen (con->target, "ab");
+ else if (opt.noclobber || opt.always_rest || opt.timestamping || opt.dirstruct
+ || opt.output_document)
+ fp = fopen (con->target, "wb");
+ else
+ {
+ fp = fopen_excl (con->target, 0);
+ if (!fp && errno == EEXIST)
+ {
+ /* We cannot just invent a new name and use it (which is
+ what functions like unique_create typically do)
+ because we told the user we'd use this name.
+ Instead, return and retry the download. */
+ logprintf (LOG_NOTQUIET, _("%s has sprung into existence.\n"),
+ con->target);
+ fd_close (csock);
+ con->csock = -1;
+ fd_close (dtsock);
+ fd_close (local_sock);
+ return FOPEN_EXCL_ERR;
+ }
+ }
if (!fp)
{
logprintf (LOG_NOTQUIET, "%s: %s\n", con->target, strerror (errno));
char *line;
/* The lines are being read with read_whole_line because of
no-buffering on opt.lfile. */
- while ((line = read_whole_line (fp)))
+ while ((line = read_whole_line (fp)) != NULL)
{
- logprintf (LOG_ALWAYS, "%s\n", line);
+ logprintf (LOG_ALWAYS, "%s\n", escnonprint (line));
xfree (line);
}
fclose (fp);
ftp_loop_internal (struct url *u, struct fileinfo *f, ccon *con)
{
int count, orig_lp;
- long restval, len = 0;
+ wgint restval, len = 0;
char *tms, *locf;
char *tmrate = NULL;
uerr_t err;
- struct stat st;
+ struct_stat st;
if (!con->target)
con->target = url_file_name (u);
case CONSOCKERR: case CONERROR: case FTPSRVERR: case FTPRERR:
case WRITEFAILED: case FTPUNKNOWNTYPE: case FTPSYSERR:
case FTPPORTERR: case FTPLOGREFUSED: case FTPINVPASV:
+ case FOPEN_EXCL_ERR:
printwhat (count, opt.ntry);
/* non-fatal errors */
+ if (err == FOPEN_EXCL_ERR)
+ {
+ /* Re-determine the file name. */
+ xfree_null (con->target);
+ con->target = url_file_name (u);
+ locf = con->target;
+ }
continue;
break;
case FTPRETRINT:
con->csock = -1;
}
if (!opt.spider)
- logprintf (LOG_VERBOSE, _("%s (%s) - `%s' saved [%ld]\n\n"),
- tms, tmrate, locf, len);
+ logprintf (LOG_VERBOSE, _("%s (%s) - `%s' saved [%s]\n\n"),
+ tms, tmrate, locf, number_to_static_string (len));
if (!opt.verbose && !opt.quiet)
{
/* 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);
- logprintf (LOG_NONVERBOSE, "%s URL: %s [%ld] -> \"%s\" [%d]\n",
- tms, hurl, len, locf, count);
+ logprintf (LOG_NONVERBOSE, "%s URL: %s [%s] -> \"%s\" [%d]\n",
+ tms, hurl, number_to_static_string (len), locf, count);
xfree (hurl);
}
static int depth = 0;
uerr_t err;
struct fileinfo *orig;
- long local_size;
+ wgint local_size;
time_t tml;
int dlthis;
dlthis = 1;
if (opt.timestamping && f->type == FT_PLAINFILE)
{
- struct stat st;
+ struct_stat st;
/* If conversion of HTML files retrieved via FTP is ever implemented,
we'll need to stat() <file>.orig here when -K has been specified.
I'm not implementing it now since files on an FTP server are much
{
/* Sizes do not match */
logprintf (LOG_VERBOSE, _("\
-The sizes do not match (local %ld) -- retrieving.\n\n"), local_size);
+The sizes do not match (local %s) -- retrieving.\n\n"),
+ number_to_static_string (local_size));
}
}
} /* opt.timestamping && f->type == FT_PLAINFILE */
_("Invalid name of the symlink, skipping.\n"));
else
{
- struct stat st;
+ struct_stat st;
/* Check whether we already have the correct
symbolic link. */
int rc = lstat (con->target, &st);
{
logprintf (LOG_VERBOSE, _("\
Already have correct symlink %s -> %s\n\n"),
- con->target, f->linkto);
+ con->target, escnonprint (f->linkto));
dlthis = 0;
break;
}
}
}
logprintf (LOG_VERBOSE, _("Creating symlink %s -> %s\n"),
- con->target, f->linkto);
+ con->target, escnonprint (f->linkto));
/* Unlink before creating symlink! */
unlink (con->target);
if (symlink (f->linkto, con->target) == -1)
- logprintf (LOG_NOTQUIET, "symlink: %s\n",
- strerror (errno));
+ logprintf (LOG_NOTQUIET, "symlink: %s\n", strerror (errno));
logputs (LOG_VERBOSE, "\n");
} /* have f->linkto */
#else /* not HAVE_SYMLINK */
case FT_DIRECTORY:
if (!opt.recursive)
logprintf (LOG_NOTQUIET, _("Skipping directory `%s'.\n"),
- f->name);
+ escnonprint (f->name));
break;
case FT_PLAINFILE:
/* Call the retrieve loop. */
break;
case FT_UNKNOWN:
logprintf (LOG_NOTQUIET, _("%s: unknown/unsupported file type.\n"),
- f->name);
+ escnonprint (f->name));
break;
} /* switch */
if (!accdir (newdir, ALLABS))
{
logprintf (LOG_VERBOSE, _("\
-Not descending to `%s' as it is excluded/not-included.\n"), newdir);
+Not descending to `%s' as it is excluded/not-included.\n"),
+ escnonprint (newdir));
continue;
}
{
if (f->type != FT_DIRECTORY && !acceptable (f->name))
{
- logprintf (LOG_VERBOSE, _("Rejecting `%s'.\n"), f->name);
+ logprintf (LOG_VERBOSE, _("Rejecting `%s'.\n"),
+ escnonprint (f->name));
f = delelement (f, &start);
}
else
{
if (has_insecure_name_p (f->name))
{
- logprintf (LOG_VERBOSE, _("Rejecting `%s'.\n"), f->name);
+ logprintf (LOG_VERBOSE, _("Rejecting `%s'.\n"),
+ escnonprint (f->name));
f = delelement (f, &start);
}
else
return RETRBADPATTERN;
}
}
- res = RETROK;
if (start)
{
/* Just get everything. */
/* No luck. */
/* #### This message SUCKS. We should see what was the
reason that nothing was retrieved. */
- logprintf (LOG_VERBOSE, _("No matches on pattern `%s'.\n"), u->file);
+ logprintf (LOG_VERBOSE, _("No matches on pattern `%s'.\n"),
+ escnonprint (u->file));
}
else /* GETONE or GETALL */
{
con.rs = ST_UNIX;
con.id = NULL;
con.proxy = proxy;
- res = RETROK; /* in case it's not used */
/* If the file name is empty, the user probably wants a directory
index. We'll provide one, properly HTML-ized. Unless
{
if (!opt.output_document)
{
- struct stat st;
- long sz;
+ struct_stat st;
+ wgint sz;
if (stat (filename, &st) == 0)
sz = st.st_size;
else
sz = -1;
logprintf (LOG_NOTQUIET,
- _("Wrote HTML-ized index to `%s' [%ld].\n"),
- filename, sz);
+ _("Wrote HTML-ized index to `%s' [%s].\n"),
+ filename, number_to_static_string (sz));
}
else
logprintf (LOG_NOTQUIET,