diff -Naurp lftp-4.4.8.orig/src/FileAccess.h lftp-4.4.8/src/FileAccess.h --- lftp-4.4.8.orig/src/FileAccess.h 2013-05-27 14:05:24.000000000 +0200 +++ lftp-4.4.8/src/FileAccess.h 2015-05-13 15:02:31.556462128 +0200 @@ -26,6 +26,7 @@ #include "SMTask.h" #include "trio.h" #include "xstring.h" +#include "misc.h" #include "ResMgr.h" #include "FileSet.h" #include "ArgV.h" @@ -86,6 +87,7 @@ public: void Set(const char *new_path,bool new_is_file=false,const char *new_url=0,int device_prefix_len=0); void SetURL(const char *u) { url.set(u); } void Change(const char *new_path,bool new_is_file=false,const char *new_path_enc=0,int device_prefix_len=0); + const xstring& GetDirectory() const { return is_file?dirname(path):path; } void ExpandTilde(const Path &home); static void Optimize(xstring& p,int dev_prefix=0); void Optimize() { Optimize(path,device_prefix_len); } diff -Naurp lftp-4.4.8.orig/src/MirrorJob.cc lftp-4.4.8/src/MirrorJob.cc --- lftp-4.4.8.orig/src/MirrorJob.cc 2013-03-19 13:57:12.000000000 +0100 +++ lftp-4.4.8/src/MirrorJob.cc 2015-05-13 15:10:58.419627179 +0200 @@ -561,22 +561,25 @@ void MirrorJob::HandleChdir(FileAccessRe // cd to another url. const char *loc_c=session->GetNewLocation(); int max_redirections=ResMgr::Query("xfer:max-redirections",0); - if(loc_c && max_redirections>0 && last_char(loc_c)=='/') + if(loc_c && max_redirections>0) { if(++redirections>max_redirections) goto cd_err_normal; eprintf(_("%s: received redirection to `%s'\n"),"mirror",loc_c); char *loc=alloca_strdup(loc_c); - session->Close(); // loc_c is no longer valid. - ParsedURL u(loc,true); if(!u.proto) { - session->Chdir(url::decode(loc)); + bool is_file=(last_char(loc)!='/'); + FileAccess::Path new_cwd(session->GetNewCwd()); + new_cwd.Change(0,is_file,loc); + session->PathVerify(new_cwd); + session->Roll(); return; } + session->Close(); // loc_c is no longer valid. session=FA::New(&u); session->Chdir(u.path); return; @@ -680,7 +683,7 @@ int MirrorJob::Do() if(source_session->IsOpen()) return m; - source_dir.set(source_session->GetCwd()); + source_dir.set(source_session->GetCwd().GetDirectory()); pre_MAKE_TARGET_DIR: { @@ -763,7 +766,7 @@ int MirrorJob::Do() return m; create_target_dir=false; - target_dir.set(target_session->GetCwd()); + target_dir.set(target_session->GetCwd().GetDirectory()); pre_GETTING_LIST_INFO: set_state(GETTING_LIST_INFO);