HTFTP: Don't fail if server doesn't understand REIN [patch]

On Wed, Feb 12, 2003 at 06:34:29PM +0100, Richard Atterer wrote:
> Further problem with FTP: "REIN"
> 
>   libwww doesn't behave correctly with my test FTP server (running
>   OpenBSD's ftpd): When libwww wants to reuse an existing control
>   connection, it first issues REIN, which the server doesn't understand
>   ("502 REIN command not implemented."). Next, it thinks it has to send
>   "USER anonymous" again, which doesn't work either ("530 Can't change user
>   from guest login.") At this point libwww gives up, when it could actually
>   just proceed with the RETR. Grr... patch forthcoming.

...and here is the patch. To apply it, pipe this mail into
patch -d somepath/w3c-libwww-5.4.0/Library/src

I have taken care not to change the behaviour: libwww still tries REIN, but 
if that fails *and* a subsequent USER also fails, it just assumes that 
everything is OK, and does the RETR.

This way, if a server doesn't understand REIN, but it does need the
subsequent USER, everything will still work. (Do some FTP servers really
behave this way?)

This patch does not fix the problem if a server doesn't like REIN *and* it
also doesn't support "RETR /path/to/file", because during the first
retrieval, libwww will CWD to the correct subdirectory to do just "RETR
file" - but later, it will have forgotten that the current dir is still 
/path/to.

All the best,

  Richard

-- 
  __   _
  |_) /|  Richard Atterer     |  CS student at the Technische  |  GnuPG key:
  | \/¯|  http://atterer.net  |  Universität München, Germany  |  0x888354F7
  ¯ '` ¯

--- HTFTP.c.orig	2003-01-13 18:12:44.000000000 +0100
+++ HTFTP.c	2003-02-12 17:17:47.000000000 +0100
@@ -542,6 +542,7 @@
 	NEED_GREETING,
 	NEED_REIN,
 	NEED_UID,
+	NEED_UID_NO_REIN,
 	NEED_PASSWD,
 	NEED_ACCOUNT,
 	PROMPT_USER
@@ -596,7 +597,7 @@
 		    */
 		    if ((ctrl->repcode/100 == 2) || (ctrl->repcode == 502)) {
 			ctrl->substate = (ctrl->uid && *ctrl->uid) ?
-			    NEED_UID : PROMPT_USER;
+			    NEED_UID_NO_REIN : PROMPT_USER;/*_NO_REIN?*/
 		    } else {
 			ctrl->substate = SUB_SUCCESS;	    /* hope the best */
 		    }
@@ -609,6 +610,11 @@
 
 	  case NEED_UID:
 	    HTTRACE(PROT_TRACE, "FTP Login... now in state NEED_UID\n");
+	  case NEED_UID_NO_REIN:
+	    if (ctrl->substate == NEED_UID_NO_REIN) {
+		HTTRACE(PROT_TRACE, "FTP Login... now in state "
+			"NEED_UID_NO_REIN\n");
+	    }
 	    if (!ctrl->sent) {
 		status = SendCommand(request, ctrl, "USER", ctrl->uid);
 		if (status == HT_WOULD_BLOCK)
@@ -632,6 +638,10 @@
 		    /* } else if (ctrl->repcode == 530) */
 			/* ctrl->substate = PROMPT_USER;*/        /* User unknown */
 		    } else if (ctrl->repcode == 530) {
+			/* If REIN failed and a subsequent USER also failed,
+			   just assume that we're still logged in. */
+			if (ctrl->substate == NEED_UID_NO_REIN)
+			    ctrl->alreadyLoggedIn = YES;
 			if (ctrl->alreadyLoggedIn == YES) {
 			    ctrl->substate = SUB_SUCCESS;
 			    HTTRACE(PROT_TRACE, "FTP Login... Already logged in\n");

Received on Thursday, 13 February 2003 14:45:41 UTC