Subject: bin/7073: Tweaked ftp URL support in ftp(1)
To: None <gnats-bugs@gnats.netbsd.org>
From: William O Ferry <woferry@warp.wofme.com>
List: netbsd-bugs
Date: 03/02/1999 00:44:20
>Number:         7073
>Category:       bin
>Synopsis:       Tweaked ftp URL support in ftp(1)
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    bin-bug-people (Utility Bug People)
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Tue Mar  2 00:50:01 1999
>Last-Modified:
>Originator:     William O Ferry
>Organization:
>Release:        <NetBSD-current source date> Sup'ed 2/21/99 23:31 PST
>Environment:
	
System: NetBSD warp.wofme.com 1.3H NetBSD 1.3H (kernel) #1: Sun Oct 18 15:32:03 PDT 1998 root@Ludicrous.Gemini.NU:/.u1/work/kernel i386


>Description:
	
	The ftp(1) manpage lists a usage as
ftp [-f] [-o output] ftp://[user:password@]host[:port]/file[/]

	The source code implies that the :password portion is optional, but
when I try ftp://user@host/ I end up logged into the host as anonymous.

	Also, our ftp(1) behaves somewhat inconsistantly with URLs such as
ftp://user@host//dir/

	Specifically, "//dir/" sets the CWD to /dir/, "//" leaves you in user's
home directory.

	Reading RFC1738 however, it seems that "//dir/" should not work as it
does.  It seems that the result I am looking for should be accomplished by
"ftp ftp://user:password@host/%2Fdir/", and I guess either "/%2F" or maybe
"/%2F/" to end up in /.  None of these 3 URLs seem to work with our ftp(1) (I
get an error such as "550 %2Fetc: No such file or directory."), and I am not
sure what would be the best way to implement this.  The second chunk of my
patch makes "//" behave as I had expected given how "//etc/" behaves, but is
only adding to something that as far as I can tell is not RFC compliant.

	FWIW my understanding of the RFC seems to imply that an empty username
or an empty password (ftp://:@host/ ???) is legal, and should be treated
differently than no username or password.  Currently our ftp(1) considers these
to be Invalid URLs.  In general I think there are several additional tweaks
our ftp(1) would require in order to be compliant with this RFC, I'd be
willing to help whoever wants to look into this try to figure out where we do
not comply and make the necessary changes.
>How-To-Repeat:
	Try "ftp ftp://user@host/", and find that you are either logged in as
anonymous, or the login is refused if the host does not allow anonymous logins.
Also, try "ftp ftp://user:password@host//etc/" and find that you are left in
/etc, then try "ftp ftp://user:password@host//" and find that you are left in
user's homedirectory, not /.
	
>Fix:
--- /usr/src/usr.bin/ftp/fetch.c.orig   Tue Jan 26 04:19:28 1999
+++ /usr/src/usr.bin/ftp/fetch.c        Mon Mar  1 23:26:43 1999
@@ -276,6 +276,7 @@
 
        cp = strchr(thost, '@');
        if (cp != NULL) {
+               anonftp = 0;
                *user = thost;
                *cp = '\0';
                *host = xstrdup(cp + 1);
@@ -1008,7 +1009,9 @@
                if (*dir == '/')
                        dir++;          /* skip leading / */
                cp = strrchr(dir, '/');
-               if (cp != NULL) {
+               if ((*dir == '/') && (*(dir+1) == '\0')) {
+                       file = NULL;
+               } else if (cp != NULL) {
                        *cp++ = '\0';
                        file = cp;
                } else {

And to adjust the manpage:

--- /usr/src/usr.bin/ftp/ftp.1.orig     Sun Jan 24 04:25:58 1999
+++ /usr/src/usr.bin/ftp/ftp.1  Mon Mar  1 23:31:09 1999
@@ -66,7 +66,7 @@
 .Nm ftp
 .Op Fl f
 .Op Fl o Ar output
-ftp://[\fIuser\fR:\fIpassword\fR@]\fIhost\fR[:\fIport\fR]/\fIfile\fR[/]
+ftp://[\fIuser[\fR:\fIpassword]\fR@]\fIhost\fR[:\fIport\fR]/\fIfile\fR[/]
 .Nm ftp
 .Op Fl f
 .Op Fl o Ar output

	
>Audit-Trail:
>Unformatted: