class SCPIrcFile
Introduction¶ ↑
SCPIrcFile
provides access to data housed in the mrSCPI RC file found at $HOME/.mrSCPIrc
or at $MRSCPIRC
.
RC File Content¶ ↑
The file has (for now) two kinds of lines: Nickname at SCPIrcFile
& Network at SCPIrcFile
.
Nickname¶ ↑
Nickname lines look like this:
<space_separated_list_of_nicknames> => <space_separated_list_of_network_annotated_urls>
The components are as follows:
nickname
-
Is a sequence of non-whitespace characters. It may not contain
@
,:
, or/
.
network_annotated_url
-
Is of the form:
[network_name]@[net_protocol://]ip_address[:net_port]
net_protocol
-
Is one of
raw
,soip
,lxi
, ort3k
.
net_port
-
Is an integer.
ip_address
-
May be an IP address or host DNS name.
Network¶ ↑
Network lines look like this:
<network_name> <space_separated_list_of_networks>
The components are as follows:
network_name
-
Is a sequence of non-whitespace characters. It may not contain
@
,:
, or/
.
Use¶ ↑
In general SCPIrcFile
provides three services:
urlParser
-
Parse URLs, expanding nicknames as required.
lookupURLnickname
-
Lookup nickname in the RC file
lookupNetwork
-
Lookup networks in the RC file (given an IP address or automatically querying the current host’s IP)
When nickname strings provided as arguments have no explicitly given network, then the network lines in the RC file are used to try and find one. The host IP addresses are tested for inclusion in each domain listed in the RC file – in the order they are found in the file. If the host has an IP address that is included in one of the networks, then that network name is used for the nickname lookup. If nothing is found, then the network name is left as the empty string – so it will match a network_annotated_url
with an empty network.
Public Class Methods
# File src/mrSCPI.rb, line 1234 def initialize () @rcNetworks = nil @rcURLnicknames = nil if ENV['HOME'] || ENV['MRSCPIRC'] then configFileName = ENV['MRSCPIRC'] || (ENV['HOME'] + '/.mrSCPIrc') if FileTest.exist?(configFileName) then begin configFileFD = open(configFileName, "r") rescue PrintyPrintyBangBang.instance.logPrinter(1, "ERROR: Failed to open RC file!", self, 83) end if(configFileFD) then @rcNetworks = Array.new @rcURLnicknames = Hash.new configFileFD.each_line do |line| line = line.chomp.gsub(/#.*/, '').downcase.strip.gsub(/ +/, ' ') configLineMatchData = line.match(/^([a-zA-Z]+) (.+)$/) if configLineMatchData then if configLineMatchData[1] == 'nickname' then if configLineMatchData[2].match?('=>') then (aliases, urls) = configLineMatchData[2].split('=>').map { |x| x.strip.split(/ +/) } aliases.each do |a| @rcURLnicknames[a] = (urls.map {|e| ( e.match?('@') ? e : "@#{e}" ).split('@') }).to_h end else PrintyPrintyBangBang.instance.logPrinter(2, "WARNING: RC file: Syntax error in nickname: #{line.inspect}", self) end elsif configLineMatchData[1] == 'network' then netSpecs = configLineMatchData[2].split(/ +/) netName = netSpecs.shift netSpecs = netSpecs.map { |x| IPAddr.new(x) } @rcNetworks.push([netName, netSpecs]) else PrintyPrintyBangBang.instance.logPrinter(2, "WARNING: RC file: Unrecognized configuration statement: #{line.inspect}", self) end else if line != '' then PrintyPrintyBangBang.instance.logPrinter(2, "WARNING: RC file: Syntax error: #{line.inspect}", self) end end end configFileFD.close else PrintyPrintyBangBang.instance.logPrinter(2, "WARNING: RC file: Unable to open file: #{configFileName.inspect}", self) end else PrintyPrintyBangBang.instance.logPrinter(2, "WARNING: RC file missing.", self) end else PrintyPrintyBangBang.instance.logPrinter(2, "WARNING: Can't load RC file (no HOME or MRSCPIRC variable).", self) end end
Public Instance Methods
Find a network in the RC file that contains the given ip_address
. If ip_address
is nil
, then the IP addresses of the current host are used. If nothing is found, then an empty string is returned.
# File src/mrSCPI.rb, line 1328 def lookupNetwork (ip_address=nil) if !(@rcNetworks.empty?) then if ip_address.nil? then ip_address = Socket.ip_address_list.select(&:ipv4?).map { |x| IPAddr.new(x.ip_address) } end dMatch = @rcNetworks.find { |network, nets| nets.any? { |n| ip_address.any? { |a| n.include?(a) } } } if dMatch then return dMatch.first end end return '' end
Helper function to lookup instrument nicknames to URLs. The nicknameString
can take one of three forms:
-
network@nickname
-
@nickname
-
nickname
SCPIsession
only uses the first two forms. Returns an nil
if the lookup failed. Otherwise returns the match as a string.
# File src/mrSCPI.rb, line 1294 def lookupURLnickname (nicknameString) if @rcURLnicknames then nicknameMatch = nicknameString.match(SCPIregexLibrary.instance.a(:mrs_nickname)) if nicknameMatch then inNetwork = (nicknameMatch[1].nil? ? '' : nicknameMatch[1].downcase) inName = nicknameMatch[2].downcase # Now figure out what network we should use if inNetwork == '' then inNetwork = lookupNetwork() || inNetwork end # Now we look for our nickname if @rcURLnicknames.empty? then PrintyPrintyBangBang.instance.logPrinter(1, "ERROR: No nicknams loaded.", self, 78) return nil elsif @rcURLnicknames.member?(inName) && @rcURLnicknames[inName].member?(inNetwork) then return @rcURLnicknames[inName][inNetwork] else PrintyPrintyBangBang.instance.logPrinter(1, "ERROR: Nickname was not found in the RC file", self, 79) return nil end else PrintyPrintyBangBang.instance.logPrinter(1, "ERROR: Invalid nickname string", self, 80) return nil end else PrintyPrintyBangBang.instance.logPrinter(1, "ERROR: RC config file errors", self, 81) return nil end end
Parse URLs. Lookup nicknames if requried. Return nil if urlString is invalid and a hash otherwise
# File src/mrSCPI.rb, line 1343 def urlParser (urlString) if urlString.match?('@') then urlString = SCPIrcFile.instance.lookupURLnickname(urlString) if urlString.nil? then return nil end end urlMatch = urlString.match(SCPIregexLibrary.instance.a(:mrs_url)) if urlMatch then return { :url => urlString, :net_protocol => (urlMatch[1] && urlMatch[1].to_sym), :ip_address => urlMatch[2], :net_port => (urlMatch[3] && urlMatch[3].to_i) } else PrintyPrintyBangBang.instance.logPrinter(1, "ERROR: :url was malformed: #{urlString.inspect}", self, 70) return nil end end