Hallo Ulrich,
I believe I understand what causes this problem now.
syncftp.rb uses Net for retrieving the file. If it does not find it, it
raises an exception. The script catches (rescues) the exception, and
proceeds normally if the file .syncftp does not exist on the remote
server.
Net has got many exceptions and it may raise different exceptions
depending upon your platform, operating system etc, a problem I
encountered once too.
On LinuxMint/Debian, it raises the following exception when a file is
not found:
#<Net::FTPPermError: 550 Requested action not taken.
storage/extSdCard/tmp/.syncftp : file does not exist
For you on Windows it raised an Net::FTPTempError “No such file or
directory”. I suppose the author did not test it on Windows?
Thus in order to fix this issue:
(a) edit the file syncftp.rb (D:/Gemeinsame
Dateien/Software/Internet/FTP/syncftp-master/lib/syncftp.rb) directly,
changing
rescue Net::FTPPermError => e
raise Net::FTPPermError, e.message, caller if
ftp.remote_file_exist?(remote+"/"+".syncftp")
end
to
rescue Net::FTPPermError, Net::FTPTempError => e
raise Net::FTPPermError, e.message, caller if
ftp.remote_file_exist?(remote+"/"+".syncftp")
end
(b) if editing the script file is not an option, monkey patch:
Net::FTPTempError = Net::FTPPermError
ftp.sync(:local => “test”, :remote => “tmp”)
This might introduce other issues if you start to use other
libraries/scripts relying on Net.Alternatively, redefine the entire
method after loading the library (this is the same as in the file
syncftp.rb, I only changed the one line with the rescue:
require ‘syncftp’
class SyncFTP
def sync( options = {} )
options = { :local => “.”, :remote => “.” , :passive =>
false}.merge( options )
local, remote , passive = options[:local], options[:remote],
options[:passive]
tmpname = tmpfilename
connect do |ftp|
ftp.passive = passive
# Read remote .syncftp
begin
ftp.gettextfile( remote+"/"+".syncftp", tmpname )
@remote_md5s = YAML.load( File.open( tmpname ).read )
rescue Net::FTPPermError, Net::FTPTempError => e
raise Net::FTPPermError, e.message, caller if
ftp.remote_file_exist?( remote+"/"+".syncftp" )
end
# Do the job Bob !
send_dir( ftp, local, remote )
# Write new .syncftp
File.open( tmpname, 'w' ) do |out|
YAML.dump( @local_md5s, out )
end
# Delete files
@delete_dirs = []
@delete_files = []
@remote_md5s.keys.clone.delete_if{ |f|
@local_md5s.keys.include?(f) }.each do |f|
if @remote_md5s[f] == “*”
@delete_dirs << f
else
@delete_files << f
end
end
@delete_files.each do |f|
@log.info “Delete ftp://#{@host}:#{@port}/#{f}”
begin
ftp.delete( f )
rescue => e
@log.info “ftp://#{@host}:#{@port}/#{f} does not exist”
end
end
@delete_dirs.each do |f|
@log.info “Delete ftp://#{@host}:#{@port}/#{f}”
begin
ftp.delete( f )
rescue => e
@log.info “ftp://#{@host}:#{@port}/#{f} does not exist”
end
end
ftp.puttextfile( tmpname, remote+"/"+".syncftp" )
end
File.delete( tmpname )
end
end
It interprets the file .syncftp as YAML, expecting an array. So in order
to create an “empty” file for testing, you need to create a file with an
empty array, eg. the following content:
— {}
Best regards, Dansei