summaryrefslogtreecommitdiffstats
path: root/lib/libfetch/ftp.c
diff options
context:
space:
mode:
authordes <des@FreeBSD.org>2000-01-07 10:59:12 +0000
committerdes <des@FreeBSD.org>2000-01-07 10:59:12 +0000
commit1e930b38f85120ad766f987dbbe256d25f9f5fc2 (patch)
treef796672a55f7c9e6ba03a7cb4902b9ebcb02e504 /lib/libfetch/ftp.c
parent5a9ffb7f5aae940fea91a0088b42469832041093 (diff)
downloadFreeBSD-src-1e930b38f85120ad766f987dbbe256d25f9f5fc2.zip
FreeBSD-src-1e930b38f85120ad766f987dbbe256d25f9f5fc2.tar.gz
Patches I've had lying around for several months:
* Add the 'h' ftp flag (allocate local port in high range) * Add the 'd' flag (use direct connection even if proxy is defined) * Make sure flags != NULL before calling strchr(). * Minor changes to some comments.
Diffstat (limited to 'lib/libfetch/ftp.c')
-rw-r--r--lib/libfetch/ftp.c57
1 files changed, 43 insertions, 14 deletions
diff --git a/lib/libfetch/ftp.c b/lib/libfetch/ftp.c
index a3279e1..7631155 100644
--- a/lib/libfetch/ftp.c
+++ b/lib/libfetch/ftp.c
@@ -151,16 +151,25 @@ _ftp_cmd(FILE *f, char *fmt, ...)
* Transfer file
*/
static FILE *
-_ftp_transfer(FILE *cf, char *oper, char *file, char *mode, int pasv)
+_ftp_transfer(FILE *cf, char *oper, char *file, char *mode, char *flags)
{
struct sockaddr_in sin;
- int e, sd = -1, l;
+ int pasv, high, verbose;
+ int e, sd = -1;
+ socklen_t l;
char *s;
FILE *df;
-
+
+ /* check flags */
+ pasv = (flags && strchr(flags, 'p'));
+ high = (flags && strchr(flags, 'h'));
+ verbose = (flags && strchr(flags, 'v'));
+
/* change directory */
if (((s = strrchr(file, '/')) != NULL) && (s != file)) {
*s = 0;
+ if (verbose)
+ _fetch_info("changing directory to %s", file);
if ((e = _ftp_cmd(cf, "CWD %s" ENDL, file)) != FTP_FILE_ACTION_OK) {
*s = '/';
_ftp_seterr(e);
@@ -168,6 +177,8 @@ _ftp_transfer(FILE *cf, char *oper, char *file, char *mode, int pasv)
}
*s++ = '/';
} else {
+ if (verbose)
+ _fetch_info("changing directory to /");
if ((e = _ftp_cmd(cf, "CWD /" ENDL)) != FTP_FILE_ACTION_OK) {
_ftp_seterr(e);
return NULL;
@@ -188,11 +199,15 @@ _ftp_transfer(FILE *cf, char *oper, char *file, char *mode, int pasv)
int i;
/* send PASV command */
+ if (verbose)
+ _fetch_info("setting passive mode");
if ((e = _ftp_cmd(cf, "PASV" ENDL)) != FTP_PASSIVE_MODE)
goto ouch;
- /* find address and port number. The reply to the PASV command
- is IMHO the one and only weak point in the FTP protocol. */
+ /*
+ * Find address and port number. The reply to the PASV command
+ * is IMHO the one and only weak point in the FTP protocol.
+ */
ln = _ftp_last_reply;
for (p = ln + 3; !isdigit(*p); p++)
/* nothing */ ;
@@ -209,10 +224,14 @@ _ftp_transfer(FILE *cf, char *oper, char *file, char *mode, int pasv)
bcopy(addr + 4, (char *)&sin.sin_port, 2);
/* connect to data port */
+ if (verbose)
+ _fetch_info("opening data connection");
if (connect(sd, (struct sockaddr *)&sin, sizeof(sin)) == -1)
goto sysouch;
/* make the server initiate the transfer */
+ if (verbose)
+ _fetch_info("initiating transfer");
e = _ftp_cmd(cf, "%s %s" ENDL, oper, s);
if (e != FTP_OPEN_DATA_CONNECTION)
goto ouch;
@@ -220,13 +239,19 @@ _ftp_transfer(FILE *cf, char *oper, char *file, char *mode, int pasv)
} else {
u_int32_t a;
u_short p;
- int d;
+ int arg, d;
/* find our own address, bind, and listen */
l = sizeof(sin);
if (getsockname(fileno(cf), (struct sockaddr *)&sin, &l) == -1)
goto sysouch;
sin.sin_port = 0;
+ arg = high ? IP_PORTRANGE_HIGH : IP_PORTRANGE_DEFAULT;
+ if (setsockopt(sd, IPPROTO_IP, IP_PORTRANGE,
+ (char *)&arg, sizeof(arg)) == -1)
+ goto sysouch;
+ if (verbose)
+ _fetch_info("binding data socket");
if (bind(sd, (struct sockaddr *)&sin, l) == -1)
goto sysouch;
if (listen(sd, 1) == -1)
@@ -245,6 +270,8 @@ _ftp_transfer(FILE *cf, char *oper, char *file, char *mode, int pasv)
goto ouch;
/* make the server initiate the transfer */
+ if (verbose)
+ _fetch_info("initiating transfer");
e = _ftp_cmd(cf, "%s %s" ENDL, oper, s);
if (e != FTP_OPEN_DATA_CONNECTION)
goto ouch;
@@ -275,14 +302,17 @@ ouch:
* Log on to FTP server
*/
static FILE *
-_ftp_connect(char *host, int port, char *user, char *pwd, int verbose)
+_ftp_connect(char *host, int port, char *user, char *pwd, char *flags)
{
- int sd, e, pp = FTP_DEFAULT_PORT;
+ int sd, e, pp = FTP_DEFAULT_PORT, direct, verbose;
char *p, *q;
FILE *f;
+ direct = (flags && strchr(flags, 'd'));
+ verbose = (flags && strchr(flags, 'v'));
+
/* check for proxy */
- if ((p = getenv("FTP_PROXY")) != NULL) {
+ if (!direct && (p = getenv("FTP_PROXY")) != NULL) {
if ((q = strchr(p, ':')) != NULL) {
/* XXX check that it's a valid number */
pp = atoi(q+1);
@@ -295,6 +325,7 @@ _ftp_connect(char *host, int port, char *user, char *pwd, int verbose)
} else {
/* no proxy, go straight to target */
sd = _fetch_connect(host, port, verbose);
+ p = NULL;
}
/* check connection */
@@ -396,8 +427,7 @@ _ftp_cached_connect(struct url *url, char *flags)
/* connect to server */
if (!cf) {
- cf = _ftp_connect(url->host, url->port, url->user, url->pwd,
- (strchr(flags, 'v') != NULL));
+ cf = _ftp_connect(url->host, url->port, url->user, url->pwd, flags);
if (!cf)
return NULL;
if (cached_socket)
@@ -422,8 +452,7 @@ fetchGetFTP(struct url *url, char *flags)
return NULL;
/* initiate the transfer */
- return _ftp_transfer(cf, "RETR", url->doc, "r",
- (flags && strchr(flags, 'p')));
+ return _ftp_transfer(cf, "RETR", url->doc, "r", flags);
}
/*
@@ -440,7 +469,7 @@ fetchPutFTP(struct url *url, char *flags)
/* initiate the transfer */
return _ftp_transfer(cf, (flags && strchr(flags, 'a')) ? "APPE" : "STOR",
- url->doc, "w", (flags && strchr(flags, 'p')));
+ url->doc, "w", flags);
}
/*
OpenPOWER on IntegriCloud