From f5f109a0688a24ded03803cd3b19d62ad574f13e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dag-Erling=20Sm=C3=B8rgrav?= Date: Fri, 7 Jan 2000 10:59:12 +0000 Subject: [PATCH] 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. --- lib/libfetch/fetch.3 | 30 ++++++++++++++++++++++- lib/libfetch/file.c | 2 +- lib/libfetch/ftp.c | 57 +++++++++++++++++++++++++++++++++----------- lib/libfetch/http.c | 9 +++---- 4 files changed, 78 insertions(+), 20 deletions(-) diff --git a/lib/libfetch/fetch.3 b/lib/libfetch/fetch.3 index dd0849aea9fb..f925d25c0fac 100644 --- a/lib/libfetch/fetch.3 +++ b/lib/libfetch/fetch.3 @@ -223,6 +223,20 @@ If the (passive) flag is specified, a passive (rather than active) connection will be attempted. .Pp +If the +.Fa h +(high) flag is specified, data sockets will be allocated in the high +port range (see +.Xr ip 4 ). +.Pp +If the +.Fa d +(direct) flag is specified, +.Fn fetchGetFTP +and +.Fn fetchPutFTP +will use a direct connection even if a proxy server is defined. +.Pp If no user name or password is given, the .Nm fetch library will attempt an anonymous login, with user name "ftp" and @@ -235,6 +249,14 @@ and functions implement the HTTP/1.1 protocol. With a little luck, there's even a chance that they comply with RFC2068. .Pp +If the +.Fa d +(direct) flag is specified, +.Fn fetchGetHTTP +and +.Fn fetchPutHTTP +will use a direct connection even if a proxy server is defined. +.Pp Since there seems to be no good way of implementing the HTTP PUT method in a manner consistent with the rest of the .Nm fetch @@ -314,7 +336,8 @@ to use for transferring files. .Sh SEE ALSO .Xr com_err 3 , .Xr fetch 1 , -.Xr ftpio 3 +.Xr ftpio 3 , +.Xr ip 4 . .Rs .%A T. Berners-Lee, L. Masinter & M. McCahill .%D December 1994 @@ -401,6 +424,11 @@ system errors. For instance, error code 202 means "Command not implemented, superfluous at this site" in an FTP context and "Accepted" in an HTTP context. .Pp +.Fn fetchStatFTP +does not check that the result of an MDTM command is a valid date. +.Pp +The HTTP code needs a complete rewrite, or at least a serious cleanup. +.Pp The man page is poorly written and produces badly formatted text. .Pp Tons of other stuff. diff --git a/lib/libfetch/file.c b/lib/libfetch/file.c index 5b594c49e0a1..d00f2d654959 100644 --- a/lib/libfetch/file.c +++ b/lib/libfetch/file.c @@ -55,7 +55,7 @@ fetchPutFile(struct url *u, char *flags) { FILE *f; - if (strchr(flags, 'a')) + if (flags && strchr(flags, 'a')) f = fopen(u->doc, "a"); else f = fopen(u->doc, "w"); diff --git a/lib/libfetch/ftp.c b/lib/libfetch/ftp.c index a3279e153d44..76311551ea0c 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 @@ _ftp_transfer(FILE *cf, char *oper, char *file, char *mode, int pasv) * 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); } /* diff --git a/lib/libfetch/http.c b/lib/libfetch/http.c index 716d6c2a139f..9b32bc214f4a 100644 --- a/lib/libfetch/http.c +++ b/lib/libfetch/http.c @@ -293,13 +293,14 @@ _http_auth(char *usr, char *pwd) FILE * fetchGetHTTP(struct url *URL, char *flags) { - int sd = -1, e, i, enc = ENC_NONE, verbose; + int sd = -1, e, i, enc = ENC_NONE, direct, verbose; struct cookie *c; char *ln, *p, *px, *q; FILE *f, *cf; size_t len; - verbose = (strchr(flags, 'v') != NULL); + direct = (flags && strchr(flags, 'd')); + verbose = (flags && strchr(flags, 'v')); /* allocate cookie */ if ((c = calloc(1, sizeof(struct cookie))) == NULL) @@ -310,14 +311,14 @@ fetchGetHTTP(struct url *URL, char *flags) URL->port = 80; /* default HTTP port */ /* attempt to connect to proxy server */ - if ((px = getenv("HTTP_PROXY")) != NULL) { + if (!direct && (px = getenv("HTTP_PROXY")) != NULL) { char host[MAXHOSTNAMELEN]; int port = 3128; /* XXX I think 3128 is default... check? */ /* measure length */ len = strcspn(px, ":"); - /* get port (atoi is a little too tolerant perhaps?) */ + /* get port (XXX atoi is a little too tolerant perhaps?) */ if (px[len] == ':') port = atoi(px+len+1);