Bug 4670

Summary: /usr/bin/fetch fails to ftp a file ncftp can
Product: Base System Reporter: David O'Brien <obrien>
Component: binAssignee: freebsd-bugs (Nobody) <bugs>
Status: Closed FIXED    
Severity: Affects Only Me    
Priority: Normal    
Version: 2.2-STABLE   
Hardware: Any   
OS: Any   

Description David O'Brien 1997-10-01 12:30:01 UTC
    fetch ftp://ftp.fu-berlin.de/pub/unix/mail/mutt/mutt-pgp/mutt-0.84e-0.84.dif
    fails, where as
    ncftp ftp://ftp.fu-berlin.de/pub/unix/mail/mutt/mutt-pgp/mutt-0.84e-0.84.dif
    works

    bash$ fetch -v ftp://ftp.fu-berlin.de/pub/unix/mail/mutt/mutt-pgp/mutt-0.84e
    Sending: USER anonymous
    FTP.FU-Berlin.DE ready, please login as user "ftp".
    Anonymous login ok, send your e-mail address as password.
    Sending: PASS obrien@dragon.nuxi.com
   
    Welcome at Freie Universitaet Berlin, Germany.
   
    Anonymous login ok, for special commands see the README.
    Sending: TYPE I
    Type set to I.
    Sending SIZE pub/unix/mail/mutt/mutt-pgp/mutt-0.84e-0.84.diff.gz
    pub/unix/mail/mutt/mutt-pgp/mutt-0.84e-0.84.diff.gz: not a plain file.
    Sending MDTM pub/unix/mail/mutt/mutt-pgp/mutt-0.84e-0.84.diff.gz
    pub/unix/mail/mutt/mutt-pgp/mutt-0.84e-0.84.diff.gz: No such file or directo
    fetch: pub/unix/mail/mutt/mutt-pgp/mutt-0.84e-0.84.diff.gz: cannot get remot
    Sending: PORT 169,237,60,72,4,246
    PORT command successful.
    Sending: RETR pub/unix/mail/mutt/mutt-pgp/mutt-0.84e-0.84.diff.gz
    pub/unix/mail/mutt/mutt-pgp/mutt-0.84e-0.84.diff.gz: No such file OR directo
    fetch: ftp://ftp.fu-berlin.de/pub/unix/mail/mutt/mutt-pgp/mutt-0.84e-0.84.di
    fetch: File unavailable (e.g., file not found, no access)
    Sending: QUIT 
    Goodbye.
    bash$
    bash$
    bash$ ncftp ftp://ftp.fu-berlin.de/pub/unix/mail/mutt/mutt-pgp/mutt-0.84e-0.
    FTP.FU-Berlin.DE ready, please login as user "ftp".
    Receiving file: mutt-0.84e-0.84.diff.gz
    mutt-0.84e-0.84.diff.gz: 13751 bytes received in 11.27 seconds, 1.19 K/s.
    exit

Fix: 

???
How-To-Repeat:     
    fetch ftp://ftp.fu-berlin.de/pub/unix/mail/mutt/mutt-pgp/mutt-0.84e-0.84.dif
    ncftp ftp://ftp.fu-berlin.de/pub/unix/mail/mutt/mutt-pgp/mutt-0.84e-0.84.dif
Comment 1 gurney_j 1997-10-01 18:46:51 UTC
David O'Brien scribbled this message on Oct 1:
>     Sending SIZE pub/unix/mail/mutt/mutt-pgp/mutt-0.84e-0.84.diff.gz
>     pub/unix/mail/mutt/mutt-pgp/mutt-0.84e-0.84.diff.gz: not a plain file.
>     Sending MDTM pub/unix/mail/mutt/mutt-pgp/mutt-0.84e-0.84.diff.gz
>     pub/unix/mail/mutt/mutt-pgp/mutt-0.84e-0.84.diff.gz: No such file or directo
>     fetch: pub/unix/mail/mutt/mutt-pgp/mutt-0.84e-0.84.diff.gz: cannot get remot
>     Sending: PORT 169,237,60,72,4,246
>     PORT command successful.
>     Sending: RETR pub/unix/mail/mutt/mutt-pgp/mutt-0.84e-0.84.diff.gz
>     pub/unix/mail/mutt/mutt-pgp/mutt-0.84e-0.84.diff.gz: No such file OR directo
>     fetch: ftp://ftp.fu-berlin.de/pub/unix/mail/mutt/mutt-pgp/mutt-0.84e-0.84.di
>     fetch: File unavailable (e.g., file not found, no access)
>     Sending: QUIT 
>     Goodbye.
>     bash$
>     bash$
>     bash$ ncftp ftp://ftp.fu-berlin.de/pub/unix/mail/mutt/mutt-pgp/mutt-0.84e-0.
>     FTP.FU-Berlin.DE ready, please login as user "ftp".
>     Receiving file: mutt-0.84e-0.84.diff.gz
>     mutt-0.84e-0.84.diff.gz: 13751 bytes received in 11.27 seconds, 1.19 K/s.
>     exit

well.. basicly the output tells you all you need.. when you login,
the file pub/unix/mail/.../mutt isn't avail.. it turns out that the
ftp server decides to dump you in the /pub directory instead of the
root directory...  so you end up duplicating the pub...

now the question is, should we simply add a / to the front of the path
in fetch?  it would fix it...  I don't have my RFC database close at hand
but does it tell you whwer you are suppose to get dumped when you login?

-- 
  John-Mark Gurney                          Modem/FAX: +1 541 683 6954
  Cu Networking

  Live in Peace, destroy Micro$oft, support free software, run FreeBSD
Comment 2 fenner 1997-10-01 20:41:51 UTC
However, if fetch followed the RFC1738 definition of ftp: URL's, then it
would be able to fetch this particular URL.

Sending: USER anonymous
FTP.FU-Berlin.DE ready, please login as user "ftp".
Anonymous login ok, send your e-mail address as password.
Sending: PASS fenner@ampere.freebsd.org

Welcome at Freie Universitaet Berlin, Germany.

Anonymous login ok, for special commands see the README.
Sending: TYPE I
Type set to I.
Sending: CWD pub
CWD command successful.
Sending: CWD unix
CWD command successful.
Sending: CWD mail
CWD command successful.
Sending: CWD mutt
CWD command successful.
Sending: CWD mutt-pgp
This is the Mutt version with PGP support.  I always try to upload the
latest version here.  This is either the illegally exported version from
  ftp://ftp.teuto.de/pub/user/lmb
or my adaption of the PGP parts to a newer Mutt version.  This is an
inofficial Mutt version.
                                leitner@math.fu-berlin.de

CWD command successful.
Sending SIZE mutt-0.84e-0.84.diff.gz
13751
Sending MDTM mutt-0.84e-0.84.diff.gz
19970917125011
Sending: PORT 204,216,27,20,4,19
PORT command successful.
Sending: RETR mutt-0.84e-0.84.diff.gz
Opening BINARY mode data connection for mutt-0.84e-0.84.diff.gz (13751 bytes).
Receiving mutt-0.84e-0.84.diff.gz (13751 bytes)Sending: QUIT
Transfer complete.


The following diff causes fetch to interpret FTP URL's as RFC1738
defines.

  Bill

Index: ftp.c
===================================================================
RCS file: /home/ncvs/src/usr.bin/fetch/ftp.c,v
retrieving revision 1.7
diff -u -r1.7 ftp.c
--- ftp.c	1997/05/31 14:45:41	1.7
+++ ftp.c	1997/10/01 19:33:41
@@ -293,6 +293,7 @@
 	off_t seekloc, wehave;
 	time_t modtime;
 	size_t readresult, writeresult;
+	char *p, *q, *path;
 
 	ftp = ftpLogin(ftps->ftp_hostname, 
 		       (char *)(ftps->ftp_user ? ftps->ftp_user : "anonymous"),
@@ -306,8 +307,19 @@
 	}
 	ftpBinary(ftp);
 	ftpPassive(ftp, fs->fs_passive_mode);
-	size = ftpGetSize(ftp, ftps->ftp_remote_file);
-	modtime = ftpGetModtime(ftp, ftps->ftp_remote_file);
+	p = path = safe_strdup(ftps->ftp_remote_file);
+	while ((q = strchr(p, '/')) != 0) {
+		*q++ = '\0';
+		if ((status = ftpChdir(ftp, p)) != 0) {
+			warnx("%s: %s: %s", ftps->ftp_hostname,
+				p, ftpErrString(status));
+			free(path);
+			return EX_IOERR;
+		}
+		p = q;
+	}
+	size = ftpGetSize(ftp, p);
+	modtime = ftpGetModtime(ftp, p);
 	if (modtime <= 0) {	/* xxx */
 		warnx("%s: cannot get remote modification time", 
 		      ftps->ftp_remote_file);
@@ -334,6 +346,7 @@
 		if (fs->fs_mirror && stab.st_size == size
 		    && modtime <= stab.st_mtime) {
 			fclose(ftp);
+			free(path);
 			return 0;
 		}
 		if (fs->fs_restart) {
@@ -342,7 +355,8 @@
 		}
 	}
 
-	remote = ftpGet(ftp, ftps->ftp_remote_file, &seekloc);
+	remote = ftpGet(ftp, p, &seekloc);
+	free(path);
 	if (remote == 0) {
 		if (ftpErrno(ftp)) {
 			warnx("ftp://%s/%s: FTP error:",
Comment 3 fenner 1997-10-01 21:07:36 UTC
Oops; that patch doesn't handle encoded slashes right.  Looks like
ftp_parse() has to break up the elements of the path and call
percent_decode() on each element individually, and save the list
in ftps for ftp_retrieve() to use.

  Bill
Comment 4 David O'Brien 1997-10-05 22:13:55 UTC
> well.. basicly the output tells you all you need.. when you login,
> the file pub/unix/mail/.../mutt isn't avail.. it turns out that the
> ftp server decides to dump you in the /pub directory instead of the
> root directory...  so you end up duplicating the pub...
> 
> now the question is, should we simply add a / to the front of the path
> in fetch?  it would fix it...  

I'd say yes.  It is the implimentation of least surprize.  If I wanted a
relative path, I'd have specified it as:

    ftp://ftp.foo.com/./some/dir/path/filewanted.tar.gz


-- 
-- David	(obrien@NUXI.com  -or-  obrien@FreeBSD.org)
Comment 5 Bill Fenner freebsd_committer freebsd_triage 1997-10-06 02:10:32 UTC
State Changed
From-To: open->closed

Fixed in rev 1.8 of ftp.c; fetch now uses the proper RFC1738 
interpretation of ftp URL's which allows this URL to be fetched.