#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. */
logprintf (LOG_VERBOSE, _(", %s remaining"),
with_thousand_seps (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
user = u->user;
passwd = u->passwd;
search_netrc (u->host, (const char **)&user, (const char **)&passwd, 1);
- user = user ? user : opt.ftp_acc;
- passwd = passwd ? passwd : opt.ftp_pass;
- assert (user && passwd);
+ user = user ? user : (opt.ftp_user ? opt.ftp_user : opt.user);
+ if (!user) user = "anonymous";
+ passwd = passwd ? passwd : (opt.ftp_passwd ? opt.ftp_passwd : opt.passwd);
+ if (!passwd) passwd = "-wget@";
dtsock = -1;
local_sock = -1;
fd_close (csock);
con->csock = -1;
return err;
- break;
case FTPSRVERR:
logputs (LOG_VERBOSE, "\n");
logputs (LOG_NOTQUIET, _("Error in server greeting.\n"));
fd_close (csock);
con->csock = -1;
return err;
- break;
case WRITEFAILED:
logputs (LOG_VERBOSE, "\n");
logputs (LOG_NOTQUIET,
fd_close (csock);
con->csock = -1;
return err;
- break;
case FTPLOGREFUSED:
logputs (LOG_VERBOSE, "\n");
logputs (LOG_NOTQUIET, _("The server refuses login.\n"));
fd_close (csock);
con->csock = -1;
return FTPLOGREFUSED;
- break;
case FTPLOGINC:
logputs (LOG_VERBOSE, "\n");
logputs (LOG_NOTQUIET, _("Login incorrect.\n"));
fd_close (csock);
con->csock = -1;
return FTPLOGINC;
- break;
case FTPOK:
if (!opt.server_response)
logputs (LOG_VERBOSE, _("Logged in!\n"));
break;
default:
abort ();
- exit (1);
- break;
}
/* Third: Get the system type */
if (!opt.server_response)
fd_close (csock);
con->csock = -1;
return err;
- break;
case FTPSRVERR:
logputs (LOG_VERBOSE, "\n");
logputs (LOG_NOTQUIET,
break;
default:
abort ();
- break;
}
if (!opt.server_response && err != FTPSRVERR)
logputs (LOG_VERBOSE, _("done. "));
fd_close (csock);
con->csock = -1;
return err;
- break;
case FTPSRVERR :
/* PWD unsupported -- assume "/". */
xfree_null (con->id);
break;
default:
abort ();
- break;
}
/* VMS will report something like "PUB$DEVICE:[INITIAL.FOLDER]".
Convert it to "/INITIAL/FOLDER" */
fd_close (csock);
con->csock = -1;
return err;
- break;
case WRITEFAILED:
logputs (LOG_VERBOSE, "\n");
logputs (LOG_NOTQUIET,
fd_close (csock);
con->csock = -1;
return err;
- break;
case FTPUNKNOWNTYPE:
logputs (LOG_VERBOSE, "\n");
logprintf (LOG_NOTQUIET,
break;
default:
abort ();
- break;
}
if (!opt.server_response)
logputs (LOG_VERBOSE, _("done. "));
fd_close (csock);
con->csock = -1;
return err;
- break;
case WRITEFAILED:
logputs (LOG_VERBOSE, "\n");
logputs (LOG_NOTQUIET,
fd_close (csock);
con->csock = -1;
return err;
- break;
case FTPNSFOD:
logputs (LOG_VERBOSE, "\n");
logprintf (LOG_NOTQUIET, _("No such directory `%s'.\n\n"),
fd_close (csock);
con->csock = -1;
return err;
- break;
case FTPOK:
- /* fine and dandy */
break;
default:
abort ();
- break;
}
if (!opt.server_response)
logputs (LOG_VERBOSE, _("done.\n"));
fd_close (csock);
con->csock = -1;
return err;
- break;
case FTPOK:
/* Everything is OK. */
break;
default:
abort ();
- break;
}
if (!opt.server_response)
logputs (LOG_VERBOSE, _("done.\n"));
/* 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;
fd_close (csock);
con->csock = -1;
return err;
- break;
case WRITEFAILED:
logputs (LOG_VERBOSE, "\n");
logputs (LOG_NOTQUIET,
fd_close (csock);
con->csock = -1;
return err;
- break;
case FTPNOPASV:
logputs (LOG_VERBOSE, "\n");
logputs (LOG_NOTQUIET, _("Cannot initiate PASV transfer.\n"));
logputs (LOG_NOTQUIET, _("Cannot parse PASV response.\n"));
break;
case FTPOK:
- /* fine and dandy */
break;
default:
abort ();
- break;
} /* switch (err) */
if (err==FTPOK)
{
fd_close (dtsock);
fd_close (local_sock);
return err;
- break;
case WRITEFAILED:
logputs (LOG_VERBOSE, "\n");
logputs (LOG_NOTQUIET,
fd_close (dtsock);
fd_close (local_sock);
return err;
- break;
case CONSOCKERR:
logputs (LOG_VERBOSE, "\n");
logprintf (LOG_NOTQUIET, "socket: %s\n", strerror (errno));
fd_close (dtsock);
fd_close (local_sock);
return err;
- break;
case FTPSYSERR:
logputs (LOG_VERBOSE, "\n");
logprintf (LOG_NOTQUIET, _("Bind error (%s).\n"),
strerror (errno));
fd_close (dtsock);
return err;
- break;
case FTPPORTERR:
logputs (LOG_VERBOSE, "\n");
logputs (LOG_NOTQUIET, _("Invalid PORT.\n"));
fd_close (dtsock);
fd_close (local_sock);
return err;
- break;
case FTPOK:
- /* fine and dandy */
break;
default:
abort ();
- break;
} /* port switch */
if (!opt.server_response)
logputs (LOG_VERBOSE, _("done. "));
fd_close (dtsock);
fd_close (local_sock);
return err;
- break;
case WRITEFAILED:
logputs (LOG_VERBOSE, "\n");
logputs (LOG_NOTQUIET,
fd_close (dtsock);
fd_close (local_sock);
return err;
- break;
case FTPRESTFAIL:
logputs (LOG_VERBOSE, _("\nREST failed, starting from scratch.\n"));
rest_failed = 1;
break;
case FTPOK:
- /* fine and dandy */
break;
default:
abort ();
- break;
}
if (err != FTPRESTFAIL && !opt.server_response)
logputs (LOG_VERBOSE, _("done. "));
fd_close (dtsock);
fd_close (local_sock);
return err;
- break;
case WRITEFAILED:
logputs (LOG_VERBOSE, "\n");
logputs (LOG_NOTQUIET,
fd_close (dtsock);
fd_close (local_sock);
return err;
- break;
case FTPNSFOD:
logputs (LOG_VERBOSE, "\n");
logprintf (LOG_NOTQUIET, _("No such file `%s'.\n\n"),
fd_close (dtsock);
fd_close (local_sock);
return err;
- break;
case FTPOK:
- /* fine and dandy */
break;
default:
abort ();
- break;
}
if (!opt.server_response)
fd_close (dtsock);
fd_close (local_sock);
return err;
- break;
case WRITEFAILED:
logputs (LOG_VERBOSE, "\n");
logputs (LOG_NOTQUIET,
fd_close (dtsock);
fd_close (local_sock);
return err;
- break;
case FTPNSFOD:
logputs (LOG_VERBOSE, "\n");
logprintf (LOG_NOTQUIET, _("No such file or directory `%s'.\n\n"),
fd_close (dtsock);
fd_close (local_sock);
return err;
- break;
case FTPOK:
- /* fine and dandy */
break;
default:
abort ();
- break;
}
if (!opt.server_response)
logputs (LOG_VERBOSE, _("done.\n"));
fp = fopen (con->target, "wb");
else
{
- fp = fopen_excl (con->target, 0);
+ fp = fopen_excl (con->target, 1);
if (!fp && errno == EEXIST)
{
/* We cannot just invent a new name and use it (which is
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);
case FTPNSFOD: case FTPLOGINC: case FTPNOPASV: case CONTNOTSUPPORTED:
/* Fatal errors, give up. */
return err;
- break;
case CONSOCKERR: case CONERROR: case FTPSRVERR: case FTPRERR:
case WRITEFAILED: case FTPUNKNOWNTYPE: case FTPSYSERR:
case FTPPORTERR: case FTPLOGREFUSED: case FTPINVPASV:
locf = con->target;
}
continue;
- break;
case FTPRETRINT:
/* If the control connection was closed, the retrieval
will be considered OK if f->size == len. */
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
*dt = 0;
- memset (&con, 0, sizeof (con));
+ xzero (con);
con.csock = -1;
con.st = ON_YOUR_OWN;
}
else
{
- int wild = has_wildcards_p (u->file);
- if ((opt.ftp_glob && wild) || opt.recursive || opt.timestamping)
+ int ispattern = 0;
+ 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);