=begin Copyright (c) 2020 Marek Küthe This program is free software. It comes without any warranty, to the extent permitted by applicable law. You can redistribute it and/or modify it under the terms of the Do What The Fuck You Want To Public License, Version 2, as published by Sam Hocevar. See http://www.wtfpl.net/ for more details. =end module I2PLookuper require "socket" module SAMHelper def self.samcmd fircmd, seccmd = nil, args = {} cmd = "#{fircmd}#{seccmd ? " #{seccmd}" : ""}" args.each_pair { |arg, value| cmd << " #{arg}=\"#{value.to_s}\"" } return cmd end def self.parsesamcmd ans ans.chomp! ans += " " f = ans.index " " s = ans.index " ", f + 1 w = ans[f+1...s] args = Hash.new loop do g1 = ans.index "=", s+1 break if g1 == nil g2 = nil if ans[g1+1] == "\"" g2 = ans.index "\"", g1+2 args[ans[s+1..g1-1]] = ans[g1+2..g2-1] else g2 = ans.index " ", g1+1 args[ans[s+1..g1-1]] = ans[g1+1..g2-1] end s = g2 end return [ans[0...f], w, args] end end class BOBLookuper attr_reader :version, :status # @status: # :connected # :connectedand[bob initialize status, eg. "ok" or "error"] # :disconnected def initialize host = "127.0.0.1", port = 2827 @sock = TCPSocket.new host, port @status = :connected ver = @sock.gets.chomp status = @sock.gets.chomp @status = "connectedand#{status.downcase}".to_sym @version = ver.split[1] at_exit { self.close } end def close if @status != :disconnected @sock.puts "quit" @sock.close @status = :disconnected end end def lookup name oldstatus = @status @status = :lookup @sock.puts "lookup #{name}" res = @sock.gets.chomp space = res.index " " @status = oldstatus return res[0...space].downcase.to_sym, res[space+1..-1] end end class SAMLookuper attr_reader :status, :version def initialize host = "127.0.0.1", port = 7656, samhelper = SAMHelper @samhelper = SAMHelper @sock = TCPSocket.new host, port @status = :connected @sock.puts @samhelper.samcmd "HELLO", "VERSION", { "MIN" => "1.0" } res = @samhelper.parsesamcmd @sock.gets.chomp @status = "connectedand#{res[2]["RESULT"].downcase}".to_sym @version = res[2]["VERSION"] at_exit { self.close } end def close if @status != :disconnected @sock.puts @samhelper.samcmd "QUIT" @sock.close @status = :disconnected end end def lookup name oldstatus = @status @status = :lookup @sock.puts @samhelper.samcmd "NAMING", "LOOKUP", { "NAME" => name } res = @samhelper.parsesamcmd @sock.gets @status = oldstatus return res[2]["RESULT"].downcase.to_sym, res[2].has_key?("VALUE") ? res[2]["VALUE"] : res[2]["RESULT"].tr("_", " ") end end end