On Thu, Apr 16, 2009 at 05:04:31PM +0800, 戴明仁 (mingjen_tai) wrote:
> I’m trying to log onto a sftp server using lftp, and make multi-levels of 
> path by mkdir –p. But lftp reports error. Here is the debug message.

Please try this patch.

--
   Alexander.
Index: FileAccess.cc
===================================================================
RCS file: /home/lav/cvsroot/lftp/src/FileAccess.cc,v
retrieving revision 1.159
diff -u -p -r1.159 FileAccess.cc
--- FileAccess.cc       27 Nov 2008 05:56:11 -0000      1.159
+++ FileAccess.cc       16 Apr 2009 14:06:41 -0000
@@ -275,6 +275,23 @@ void FileAccess::Mkdir(const char *fn,bo
    mkdir_p=allp;
 }
 
+StringSet *FileAccess::MkdirMakeSet()
+{
+   StringSet *set=new StringSet;
+   const char *sl=strchr(file,'/');
+   while(sl)
+   {
+      if(sl>file)
+      {
+        xstring& tmp=xstring::get_tmp(file,sl-file);
+        if(tmp.ne(".") && tmp.ne(".."))
+           set->Append(tmp);
+      }
+      sl=strchr(sl+1,'/');
+   }
+   return set;
+}
+
 bool FileAccess::SameLocationAs(const FileAccess *fa) const
 {
    return SameSiteAs(fa);
Index: FileAccess.h
===================================================================
RCS file: /home/lav/cvsroot/lftp/src/FileAccess.h,v
retrieving revision 1.110
diff -u -p -r1.110 FileAccess.h
--- FileAccess.h        27 Nov 2008 05:56:11 -0000      1.110
+++ FileAccess.h        16 Apr 2009 13:49:55 -0000
@@ -192,6 +192,8 @@ protected:
    FileAccess *FirstSameSite() { return NextSameSite(0); }
    FileAccess *NextSameSite(FileAccess *);
 
+   StringSet *MkdirMakeSet(); // splits the path for mkdir -p
+
    int device_prefix_len(const char *path);
 
 public:
Index: SFtp.cc
===================================================================
RCS file: /home/lav/cvsroot/lftp/src/SFtp.cc,v
retrieving revision 1.82
diff -u -p -r1.82 SFtp.cc
--- SFtp.cc     27 Nov 2008 05:56:27 -0000      1.82
+++ SFtp.cc     16 Apr 2009 13:58:19 -0000
@@ -622,6 +622,12 @@ void SFtp::SendRequest()
       break;
    }
    case MAKE_DIR:
+      if(mkdir_p)
+      {
+        Ref<StringSet> dirs(MkdirMakeSet());
+        for(int i=0; i<dirs->Count(); i++)
+           SendRequest(new 
Request_MKDIR(WirePath(dirs->String(i)),protocol_version),Expect::IGNORE);
+      }
       SendRequest(new 
Request_MKDIR(WirePath(file),protocol_version),Expect::DEFAULT);
       state=WAITING;
       break;
Index: ftpclass.cc
===================================================================
RCS file: /home/lav/cvsroot/lftp/src/ftpclass.cc,v
retrieving revision 1.456
diff -u -p -r1.456 ftpclass.cc
--- ftpclass.cc 17 Mar 2009 10:59:59 -0000      1.456
+++ ftpclass.cc 16 Apr 2009 13:52:41 -0000
@@ -1884,19 +1884,11 @@ int   Ftp::Do()
       {
         if(mode==MAKE_DIR && mkdir_p)
         {
-           const char *sl=strchr(file,'/');
-           while(sl)
+           Ref<StringSet> dirs(MkdirMakeSet());
+           for(int i=0; i<dirs->Count(); i++)
            {
-              if(sl>file)
-              {
-                 xstring& tmp=xstring::get_tmp(file,sl-file);
-                 if(tmp.ne(".") && tmp.ne(".."))
-                 {
-                    conn->SendCmd2("MKD",tmp);
-                    expect->Push(Expect::IGNORE);
-                 }
-              }
-              sl=strchr(sl+1,'/');
+              conn->SendCmd2("MKD",dirs->String(i));
+              expect->Push(Expect::IGNORE);
            }
         }
 

Reply via email to