6 class SSHLoader < Source
7 attr_accessor :username, :password
9 def initialize uri, username=nil, password=nil, start_offset=nil, usual=true, archived=false, id=nil
10 raise ArgumentError, "not an mbox+ssh uri: #{uri.inspect}" unless uri =~ %r!^mbox\+ssh://!
12 super uri, start_offset, usual, archived, id
14 @parsed_uri = URI(uri)
18 @cur_offset = start_offset
21 opts[:username] = @username if @username
22 opts[:password] = @password if @password
24 @f = SSHFile.new host, filename, opts
25 @loader = Loader.new @f, start_offset, usual, archived, id
27 ## heuristic: use the filename as a label, unless the file
28 ## has a path that probably represents an inbox.
30 @labels << File.basename(filename).intern unless File.dirname(filename) =~ /\b(var|usr|spool)\b/
33 def connect; safely { @f.connect }; end
34 def host; @parsed_uri.host; end
35 def filename; @parsed_uri.path[1..-1] end
39 offset, labels = @loader.next
40 self.cur_offset = @loader.cur_offset # superclass keeps @cur_offset which is used by yaml
41 [offset, (labels + @labels).uniq] # add our labels
49 def cur_offset= o; @cur_offset = @loader.cur_offset = o; @dirty = true; end
50 def id; @loader.id; end
51 def id= o; @id = @loader.id = o; end
52 # def cur_offset; @loader.cur_offset; end # think we'll be ok without this
53 def to_s; @parsed_uri.to_s; end
58 rescue Net::SSH::Exception, SocketError, SSHFileError, SystemCallError, IOError => e
59 m = "error communicating with SSH server #{host} (#{e.class.name}): #{e.message}"
60 raise FatalSourceError, m
64 [:start_offset, :load_header, :load_message, :raw_header, :raw_full_message].each do |meth|
65 define_method(meth) { |*a| safely { @loader.send meth, *a } }
69 Redwood::register_yaml(SSHLoader, %w(uri username password cur_offset usual archived id))