class Irc::Netmask
A Netmask
identifies each user by collecting its nick, username and hostname in the form nick!user@host
Netmasks can also contain glob patterns in any of their components; in this form they are used to refer to more than a user or to a user appearing under different forms.
Example:
-
*!*@*
refers to everybody -
*!someuser@somehost
refers to usersomeuser
on hostsomehost
regardless of the nick used.
Attributes
Public Class Methods
Create a new Netmask
from string str, which must be in the form nick!user@host
It is possible to specify a server or a casemap in the optional Hash: these are used to associate the Netmask
with the given server and to set its casemap: if a server is specified and a casemap is not, the server’s casemap is used. If both a server and a casemap are specified, the casemap must match the server’s casemap or an exception will be raised.
Empty nick
, user
or host
are converted to the generic glob pattern
# File lib/rbot/irc.rb, line 639 def initialize(str="", opts={}) # First of all, check for server/casemap option # init_server_or_casemap(opts) # Now we can see if the given string _str_ is an actual Netmask if str.respond_to?(:to_str) case str.to_str # We match a pretty generic string, to work around non-compliant # servers when /^(?:(\S+?)(?:(?:!(\S+?))?@(\S+))?)?$/ # We do assignment using our internal methods self.nick = $1 self.user = $2 self.host = $3 else raise ArgumentError, "#{str.to_str.inspect} does not represent a valid #{self.class}" end else raise TypeError, "#{str} cannot be converted to a #{self.class}" end end
Public Instance Methods
Sorting is done via the fullform
# File lib/rbot/irc.rb, line 853 def <=>(arg) case arg when Netmask self.fullform.irc_downcase(casemap) <=> arg.fullform.irc_downcase(casemap) else self.downcase <=> arg.downcase end end
Equality: two Netmasks are equal if they downcase to the same thing
TODO we may want it to try other.to_irc_netmask
# File lib/rbot/irc.rb, line 737 def ==(other) return false unless other.kind_of?(self.class) self.downcase == other.downcase end
Case equality. Checks if arg matches self
# File lib/rbot/irc.rb, line 847 def ===(arg) arg.to_irc_netmask(:casemap => casemap).matches?(self) end
This method returns a new Netmask
which is the fully downcased version of the receiver
# File lib/rbot/irc.rb, line 697 def downcased return self.full_downcase.to_irc_netmask(server_and_casemap) end
full_downcase
() will return the fullform downcased according to the User’s own casemap
# File lib/rbot/irc.rb, line 691 def full_downcase self.full_irc_downcase end
This method downcases the fullform of the netmask. While this may not be significantly different from the downcase()
method provided by the ServerOrCasemap
mixin, it’s significantly different for Netmask
subclasses such as User
whose simple downcasing uses the nick only.
# File lib/rbot/irc.rb, line 684 def full_irc_downcase(cmap=casemap) self.fullform.irc_downcase(cmap) end
# File lib/rbot/irc.rb, line 673 def fullform "#{nick}!#{user}@#{host}" end
# File lib/rbot/irc.rb, line 789 def generalize u = user.dup unless u.has_irc_glob? u.sub!(/^[in]=/, '=') or u.sub!(/^\W(\w+)/, '\1') u = '*' + u end h = host.dup unless h.has_irc_glob? if h.include? '/' h.sub!(/x-\w+$/, 'x-*') else h.match(/^[^\.]+\.[^\.]+$/) or h.sub!(/azzurra[=-][0-9a-f]+/i, '*') or # hello, azzurra, you suck! h.sub!(/^(\d+\.\d+\.\d+\.)\d+$/, '\1*') or h.sub!(/^[^\.]+\./, '*.') end end return Netmask.new("*!#{u}@#{h}", server_and_casemap) end
This method checks if a Netmask
is definite or not, by seeing if any of its components are defined by globs
# File lib/rbot/irc.rb, line 785 def has_irc_glob? return @nick.has_irc_glob? || @user.has_irc_glob? || @host.has_irc_glob? end
This method changes the hostname of the Netmask
, defaulting to the generic glob pattern if the result is the null string.
# File lib/rbot/irc.rb, line 762 def host=(newhost) @host = newhost.to_s @host = "*" if @host.empty? end
Inspection of a Netmask
reveals the server it’s bound to (if there is one), its casemap and the nick, user and host part
# File lib/rbot/irc.rb, line 725 def inspect str = self.__to_s__[0..-2] str << " @server=#{@server}" if defined?(@server) and @server str << " @nick=#{@nick.inspect} @user=#{@user.inspect}" str << " @host=#{@host.inspect} casemap=#{casemap.inspect}" str << ">" end
This method is used to match the current Netmask
against another one
The method returns true if each component of the receiver matches the corresponding component of the argument. By matching here we mean that any netmask described by the receiver is also described by the argument.
In this sense, matching is rather simple to define in the case when the receiver has no globs: it is just necessary to check if the argument describes the receiver, which can be done by matching it against the argument converted into an IRC Regexp
(see String#to_irc_regexp
).
The situation is also easy when the receiver has globs and the argument doesn’t, since in this case the result is false.
The more complex case in which both the receiver and the argument have globs is not handled yet.
# File lib/rbot/irc.rb, line 828 def matches?(arg) cmp = arg.to_irc_netmask(:casemap => casemap) debug "Matching #{self.fullform} against #{arg.inspect} (#{cmp.fullform})" [:nick, :user, :host].each { |component| us = self.send(component).irc_downcase(casemap) them = cmp.send(component).irc_downcase(casemap) if us.has_irc_glob? && them.has_irc_glob? next if us == them warn NotImplementedError return false end return false if us.has_irc_glob? && !them.has_irc_glob? return false unless us =~ them.to_irc_regexp } return true end
This method changes the nick of the Netmask
, defaulting to the generic glob pattern if the result is the null string.
# File lib/rbot/irc.rb, line 745 def nick=(newnick) @nick = newnick.to_s @nick = "*" if @nick.empty? end
We can replace everything at once with data from another Netmask
# File lib/rbot/irc.rb, line 769 def replace(other) case other when Netmask nick = other.nick user = other.user host = other.host @server = other.server @casemap = other.casemap unless @server else replace(other.to_irc_netmask(server_and_casemap)) end end
Converts the receiver into a Netmask
with the given (optional) server/casemap association. We return self unless a conversion is needed (different casemap/server)
Subclasses of Netmask
will return a new Netmask
, using full_downcase
# File lib/rbot/irc.rb, line 707 def to_irc_netmask(opts={}) if self.class == Netmask return self if fits_with_server_and_casemap?(opts) end return self.full_downcase.to_irc_netmask(server_and_casemap.merge(opts)) end
Converts the receiver into a User
with the given (optional) server/casemap association. We return self unless a conversion is needed (different casemap/server)
# File lib/rbot/irc.rb, line 718 def to_irc_user(opts={}) self.fullform.to_irc_user(server_and_casemap.merge(opts)) end
A Netmask
is easily converted to a String
for the usual representation. We skip the user or host parts if they are “*”, unless we’ve been asked for the full form
# File lib/rbot/irc.rb, line 666 def to_s ret = nick.dup ret << "!" << user unless user == "*" ret << "@" << host unless host == "*" return ret end