> This is done for background jobs to delay the connection usage to avoid
> excessive ABOR's. E.g. if you do two commands quickly, then background
> job can start its own data transfer between them and it will be
> aborted immediately:
>    get file &
>    ls; cd ..
>
> With this code background session delays for 1 second before actually
> using the connection.

Okay, I understand this better now.  A suggestion: instead of delaying
the job for a second, make it wait until the session has been idle for a
second.  That way, "get file &" starts immediately (since nothing has been
happening on the session.)  This doesn't help the case where there's
other priority levels in use (would be useful to have an intelligent
antiidle job on idle priority -1), but nothing does that yet.

idle_time could use being changed to a Time; currently, rounding error
can make the delay up to 2 seconds.  (I'd suggest a lower number, too;
maybe 500ms.)

(ftpclass.cc, ftpclass.h)

Nothing actually reads takeover_time now.

On Tue, Dec 11, 2001 at 02:01:35PM -0500, Glenn Maynard wrote:
> GetFileInfo should probably fail here:
> 
> lftp :~> cls -ld ~
> ~/
> lftp :~> cls -ld /
> //
> 
> (we're not actually connected)
> 
> Another symptom:
> lftp :~> find
> ./
> find: Not connected

Fixed this by moving the ~ and / special case check after the initial
chdir.  If the session isn't OK, the chdir will fail first.  I don't
quite understand the ~ test:

       if(showdir && verify_fn[0]=='~' &&
         !strcmp(verify_fn,session->GetCwd()))

verify_fn is the basename of session->GetCwd(), so this is only true if
!strcmp(session->GetCwd(), basename_ptr(session->GetCwd())) is true.
When is this true other than just "~"?  (Duplicated the test via origdir.)
Okay, I was able to get rid of it anyway.  (cls -d still wasn't working
with all ~ cases; ie. "cls -ld .." when home isn't /.)

Moved the code to grab verify_fn after the chdir, since we're far more
likely to have the home directory path by then.  (I have a feeling it's
still not guaranteed; what if the Chdir was out of cache?  Could we have
lost the home directory information?)

07:00pm [EMAIL PROTECTED]/2 [~/lftp/src] ./lftp 0
lftp 0:~> u glenn
Password:
lftp glenn@0:~> de 5
lftp glenn@0:~> cls -ld ..
---- Connecting to 0 (0.0.0.0) port 21
<--- 220-
<--- 220 Server ready.
---> AUTH TLS
<--- 234 AUTH TLS successful
---> PBSZ 0
<--- 200 PBSZ 0 successful
---> USER glenn
<--- 331 Password required for glenn.
---> PASS XXXX
<--- 230 User glenn logged in.
---> PWD
<--- 257 "/home/glenn" is current directory.
---> CWD /home/glenn/../..
<--- 250 CWD command successful.
---> CWD /
<--- 250 CWD command successful.
---> PORT 127,0,0,1,16,213
<--- 200 PORT command successful.
---> LIST
<--- 150 Opening ASCII mode data connection for file list.
<--- 226-Transfer complete.
<--- 226 Quotas off
drwxrwsr-x   12 root     root          122 Nov 22 20:29 ../

The directory that's going to be CWD'd do should have ..s squashed out
after the PWD is found.

GetFileInfo.cc: move ~ and / special case to make sure Chdir is done.

Another (slightly obscure) shortcoming here: if the data is cached, we
won't do the real Chdir at all.  So,

06:18pm [EMAIL PROTECTED]/2 [~/lftp/src] ./lftp 0
lftp 0:~> cls -ld
---- Connecting to 0 (0.0.0.0) port 21
./
lftp 0:/> clo
lftp 0:/> cd ~ &
lftp 0:~> cls -ld
---- Connecting to 0 (0.0.0.0) port 21
cls: File cannot be accessed

I don't know if this has any less contrived manifestations.

> <--- 530 Login incorrect.
> (^Z)
> [0] find &
>         .: Delaying before reconnect: 55 [Delaying before reconnect: 55]

GetFileInfo.cc: add missing MOVED.

> (Oops, also getting a dupe status somewhere.  Less important, though.)

FindJob.cc: Remove extraneous session status.  Fix memleak.
NetAccess.cc: cosmetic.

-- 
Glenn Maynard
Index: ChmodJob.cc
===================================================================
RCS file: /home/lav/cvsroot/lftp/src/ChmodJob.cc,v
retrieving revision 1.4
diff -u -r1.4 ChmodJob.cc
--- ChmodJob.cc 2001/12/11 15:10:35     1.4
+++ ChmodJob.cc 2001/12/12 03:46:15
@@ -79,7 +79,6 @@
    else
       fmt = _("Mode of `%s' changed to %04o (%s).\n");
 
-
    int mode=GetMode(fi);
    if(mode==-1)
    {
Index: FindJob.cc
===================================================================
RCS file: /home/lav/cvsroot/lftp/src/FindJob.cc,v
retrieving revision 1.21
diff -u -r1.21 FindJob.cc
--- FindJob.cc  2001/12/11 16:24:18     1.21
+++ FindJob.cc  2001/12/12 03:46:16
@@ -234,7 +234,7 @@
 
    const char *new_path="";
    if(old_path) // the first path will be empty
-      new_path=xstrdup(dir_file(old_path,dir));
+      new_path=alloca_strdup(dir_file(old_path,dir));
 
    /* matching exclusions don't include the path, so they operate
     * on the filename portion only */
@@ -374,8 +374,7 @@
    case INFO:
       if(stack_ptr>=0)
         path=top.path;
-      printf("\t%s: %s [%s]\n",dir_file(path,dir),li->Status(),
-                          session->CurrentStatus());
+      printf("\t%s: %s\n",dir_file(path,dir),li->Status());
       break;
    case WAIT:
       break;
Index: GetFileInfo.cc
===================================================================
RCS file: /home/lav/cvsroot/lftp/src/GetFileInfo.cc,v
retrieving revision 1.9
diff -u -r1.9 GetFileInfo.cc
--- GetFileInfo.cc      2001/12/11 16:07:00     1.9
+++ GetFileInfo.cc      2001/12/12 03:46:17
@@ -118,36 +118,12 @@
       {
         tried_file=true;
 
-        /* CD into the full path (without validation), and grab the
-         * path's basename. */
+        /* Chdir to the parent directory of the path: */
         session->Chdir(dir, false);
-        verify_fn = xstrdup(basename_ptr(session->GetCwd()));
-
-        /* Special case: looking up home dir. We won't find ~ in the listing
-         * anyway, so make a phony entry. */
-        if(showdir && verify_fn[0]=='~' && !strcmp(verify_fn,session->GetCwd()))
-           goto phony_dir;
-
-        /* Now go to the parent directory to list the directory we now
-         * have a name for: */
         cd_path = "..";
 
         xfree(path_to_prefix);
         path_to_prefix=dirname_alloc(dir);
-
-        /* Special case: looking up "/". Make a phony "/" entry. */
-        if(showdir && !strcmp(verify_fn, "/"))
-        {
-        phony_dir:
-           FileInfo *fi = new FileInfo(verify_fn);
-           fi->SetType(fi->DIRECTORY);
-
-           result = new FileSet;
-           result->Add(fi);
-           state=DONE;
-           return MOVED;
-        }
-
         was_directory=false;
       }
 
@@ -174,6 +150,34 @@
         return MOVED;
       }
 
+      if(!was_directory)
+      {
+        /* We now (hopefully) have the home directory path.  Find out
+         * the real name of the path (we may have something like "..".) */
+
+        char *pwd = alloca_strdup(session->GetCwd());
+
+        session->SetCwd(origdir);
+        session->Chdir(dir, false);
+
+        verify_fn = xstrdup(basename_ptr(session->GetCwd()));
+
+        /* go back */
+        session->SetCwd(pwd);
+      }
+
+      /* Special case: looking up "/". Make a phony entry. */
+      if(showdir && !strcmp(verify_fn, "/"))
+      {
+        FileInfo *fi = new FileInfo(verify_fn);
+        fi->SetType(fi->DIRECTORY);
+
+        result = new FileSet;
+        result->Add(fi);
+        state=DONE;
+        return MOVED;
+      }
+
       /* Get a listing: */
       li=session->MakeListInfo();
       if(follow_symlinks) li->FollowSymlinks();
@@ -257,6 +261,7 @@
            result->PrependPath(path_to_prefix);
         done=true;
         session->Chdir(origdir, false);
+        m=MOVED;
       }
       return m;
    }
Index: NetAccess.cc
===================================================================
RCS file: /home/lav/cvsroot/lftp/src/NetAccess.cc,v
retrieving revision 1.49
diff -u -r1.49 NetAccess.cc
--- NetAccess.cc        2001/12/05 18:35:01     1.49
+++ NetAccess.cc        2001/12/12 03:46:17
@@ -491,7 +491,7 @@
 {
    static char buf[80];
    if(connection_limit>0 && connection_limit<=CountConnections())
-      return _("Connections limit reached");
+      return _("Connection limit reached");
    long remains=ReconnectInterval()-(time_t(now)-try_time);
    if(remains<=0)
       return "";
Index: ftpclass.cc
===================================================================
RCS file: /home/lav/cvsroot/lftp/src/ftpclass.cc,v
retrieving revision 1.223
diff -u -r1.223 ftpclass.cc
--- ftpclass.cc 2001/12/10 10:13:46     1.223
+++ ftpclass.cc 2001/12/12 03:46:22
@@ -994,10 +994,15 @@
    return 0;
 }
 
-void  Ftp::GetBetterConnection(int level,int count)
+/* Return true if we *could* take over a connection, but didn't because
+ * it hasn't been idle long enough.  (if idle_time becomes a Time, make
+ * this return an integer in milliseconds or -1 for no, so we can Timeout
+ * accurately.) */
+bool Ftp::GetBetterConnection(int level,int count)
 {
+   bool could = false;
    if(level==0 && cwd==0)
-      return;
+      return could;
 
    for(FA *fo=FirstSameSite(); fo!=0; fo=NextSameSite(fo))
    {
@@ -1023,7 +1028,7 @@
            o->DataAbort();
            o->DataClose();
            if(o->control_sock==-1)
-              return; // oops...
+              return could; // oops...
         }
         else
         {
@@ -1033,7 +1038,11 @@
       }
       else
       {
-        takeover_time=now;
+        if(now < o->idle_start+1)
+        {
+           could = true;
+           continue; /* try again soon */
+        }
       }
 
       if(level==0 && xstrcmp(real_cwd,o->real_cwd))
@@ -1041,8 +1050,11 @@
 
       // so borrow the connection
       MoveConnectionHere(o);
-      return;
+
+      /* not could; did */
+      return false;
    }
+   return could;
 }
 
 void  Ftp::HandleTimeout()
@@ -1109,9 +1121,15 @@
       {
         if(i>=2 && (connection_limit==0 || connection_limit>count))
            break;
-        GetBetterConnection(i,count);
+        bool could = GetBetterConnection(i,count);
         if(state!=INITIAL_STATE)
            return MOVED;
+        if(could)
+        {
+           /* try again in 250ms */
+           Timeout(250);
+           return m;
+        }
       }
 
       if(!ReconnectAllowed())
@@ -1339,14 +1357,6 @@
         SetError(NO_FILE,_("SITE CHMOD is disabled by ftp:use-site-chmod"));
         return MOVED;
       }
-
-      if(takeover_time!=NO_DATE && takeover_time+1-priority>now
-      && connection_limit>0 && connection_limit<=CountConnections()+1)
-      {
-        TimeoutS(takeover_time+1-priority-now);
-        goto notimeout_return;
-      }
-      takeover_time=NO_DATE;
 
       if(home==0 && !RespQueueIsEmpty())
         goto usual_return;
Index: ftpclass.h
===================================================================
RCS file: /home/lav/cvsroot/lftp/src/ftpclass.h,v
retrieving revision 1.84
diff -u -r1.84 ftpclass.h
--- ftpclass.h  2001/12/05 16:37:13     1.84
+++ ftpclass.h  2001/12/12 03:46:22
@@ -264,7 +264,7 @@
    bool         rest_list;
    char  *list_options;
 
-   void         GetBetterConnection(int level,int count);
+   bool         GetBetterConnection(int level,int count);
    bool  SameConnection(const Ftp *o);
 
    int  nop_interval;

Reply via email to