diff --git a/classes.py b/classes.py index 1a3ddc5..0defbec 100644 --- a/classes.py +++ b/classes.py @@ -463,9 +463,9 @@ class Irc(): cmd_args = cmd_args[1:] if cmd not in world.commands: self.msg(self.called_by or source, 'Error: Unknown command %r.' % cmd) - log.info('(%s) Received unknown command %r from %s', self.name, cmd, utils.getHostmask(self, source)) + log.info('(%s) Received unknown command %r from %s', self.name, cmd, self.getHostmask(source)) return - log.info('(%s) Calling command %r for %s', self.name, cmd, utils.getHostmask(self, source)) + log.info('(%s) Calling command %r for %s', self.name, cmd, self.getHostmask(source)) for func in world.commands[cmd]: try: func(self, source, cmd_args) @@ -809,6 +809,45 @@ class Irc(): if numeric in self.servers[server].users: return server + def isManipulatableClient(self, uid): + """ + Returns whether the given user is marked as an internal, manipulatable + client. Usually, automatically spawned services clients should have this + set True to prevent interactions with opers (like mode changes) from + causing desyncs. + """ + return self.isInternalClient(uid) and self.users[uid].manipulatable + + def getHostmask(self, user, realhost=False, ip=False): + """ + Returns the hostmask of the given user, if present. If the realhost option + is given, return the real host of the user instead of the displayed host. + If the ip option is given, return the IP address of the user (this overrides + realhost).""" + userobj = self.users.get(user) + + try: + nick = userobj.nick + except AttributeError: + nick = '' + + try: + ident = userobj.ident + except AttributeError: + ident = '' + + try: + if ip: + host = userobj.ip + elif realhost: + host = userobj.realhost + else: + host = userobj.host + except AttributeError: + host = '' + + return '%s!%s@%s' % (nick, ident, host) + class IrcUser(): """PyLink IRC user class.""" def __init__(self, nick, ts, uid, ident='null', host='null', diff --git a/coreplugin.py b/coreplugin.py index 4eeac7a..24ebc34 100644 --- a/coreplugin.py +++ b/coreplugin.py @@ -157,14 +157,14 @@ def handle_mode(irc, source, command, args): # If the sender is not a PyLink client, and the target IS a protected # client, revert any forced deoper attempts. if irc.isInternalClient(target) and not irc.isInternalClient(source): - if ('-o', None) in modes and (target == irc.pseudoclient.uid or not utils.isManipulatableClient(irc, target)): + if ('-o', None) in modes and (target == irc.pseudoclient.uid or not irc.isManipulatableClient(target)): irc.proto.mode(irc.sid, target, {('+o', None)}) utils.add_hook(handle_mode, 'MODE') def handle_operup(irc, source, command, args): """Logs successful oper-ups on networks.""" otype = args.get('text', 'IRC Operator') - log.debug("(%s) Successful oper-up (opertype %r) from %s", irc.name, otype, utils.getHostmask(irc, source)) + log.debug("(%s) Successful oper-up (opertype %r) from %s", irc.name, otype, irc.getHostmask(source)) irc.users[source].opertype = otype utils.add_hook(handle_operup, 'CLIENT_OPERED') @@ -209,12 +209,12 @@ def identify(irc, source, args): irc.users[source].identified = realuser irc.msg(source, 'Successfully logged in as %s.' % realuser) log.info("(%s) Successful login to %r by %s", - irc.name, username, utils.getHostmask(irc, source)) + irc.name, username, irc.getHostmask(source)) else: irc.msg(source, 'Error: Incorrect credentials.') u = irc.users[source] log.warning("(%s) Failed login to %r from %s", - irc.name, username, utils.getHostmask(irc, source)) + irc.name, username, irc.getHostmask(source)) @utils.add_cmd def shutdown(irc, source, args): @@ -242,7 +242,7 @@ def load(irc, source, args): if name in world.plugins: irc.reply("Error: %r is already loaded." % name) return - log.info('(%s) Loading plugin %r for %s', irc.name, name, utils.getHostmask(irc, source)) + log.info('(%s) Loading plugin %r for %s', irc.name, name, irc.getHostmask(source)) try: world.plugins[name] = pl = utils.loadModuleFromFolder(name, world.plugins_folder) except ImportError as e: @@ -269,7 +269,7 @@ def unload(irc, source, args): irc.reply("Error: Not enough arguments. Needs 1: plugin name.") return if name in world.plugins: - log.info('(%s) Unloading plugin %r for %s', irc.name, name, utils.getHostmask(irc, source)) + log.info('(%s) Unloading plugin %r for %s', irc.name, name, irc.getHostmask(source)) pl = world.plugins[name] log.debug('sys.getrefcount of plugin %s is %s', pl, sys.getrefcount(pl)) # Remove any command functions set by the plugin. diff --git a/plugins/bots.py b/plugins/bots.py index b3738ef..88f94f6 100644 --- a/plugins/bots.py +++ b/plugins/bots.py @@ -44,7 +44,7 @@ def quit(irc, source, args): quitmsg = ' '.join(args[1:]) or 'Client Quit' - if not utils.isManipulatableClient(irc, u): + if not irc.isManipulatableClient(u): irc.reply("Error: Cannot force quit a protected PyLink services client.") return @@ -79,7 +79,7 @@ def joinclient(irc, source, args): irc.reply("Error: No valid channels given.") return - if not utils.isManipulatableClient(irc, u): + if not irc.isManipulatableClient(u): irc.reply("Error: Cannot force join a protected PyLink services client.") return @@ -121,7 +121,7 @@ def nick(irc, source, args): irc.reply('Error: Invalid nickname %r.' % newnick) return - elif not utils.isManipulatableClient(irc, u): + elif not irc.isManipulatableClient(u): irc.reply("Error: Cannot force nick changes for a protected PyLink services client.") return @@ -163,7 +163,7 @@ def part(irc, source, args): irc.reply("Error: No valid channels given.") return - if not utils.isManipulatableClient(irc, u): + if not irc.isManipulatableClient(u): irc.reply("Error: Cannot force part a protected PyLink services client.") return diff --git a/plugins/exec.py b/plugins/exec.py index 1bd7237..9cbd780 100644 --- a/plugins/exec.py +++ b/plugins/exec.py @@ -30,7 +30,7 @@ def _exec(irc, source, args): return log.info('(%s) Executing %r for %s', irc.name, args, - utils.getHostmask(irc, source)) + irc.getHostmask(source)) exec(args, globals(), locals()) utils.add_cmd(_exec, 'exec') @@ -48,7 +48,7 @@ def _eval(irc, source, args): return log.info('(%s) Evaluating %r for %s', irc.name, args, - utils.getHostmask(irc, source)) + irc.getHostmask(source)) irc.reply(eval(args)) utils.add_cmd(_eval, 'eval') @@ -66,7 +66,7 @@ def raw(irc, source, args): return log.info('(%s) Sending raw text %r to IRC for %s', irc.name, args, - utils.getHostmask(irc, source)) + irc.getHostmask(source)) irc.send(args) irc.reply("Done.") @@ -85,5 +85,5 @@ def inject(irc, source, args): return log.info('(%s) Injecting raw text %r into protocol module for %s', irc.name, - args, utils.getHostmask(irc, source)) + args, irc.getHostmask(source)) irc.reply(irc.runline(args)) diff --git a/plugins/opercmds.py b/plugins/opercmds.py index cedaeb7..07f7c76 100644 --- a/plugins/opercmds.py +++ b/plugins/opercmds.py @@ -50,7 +50,7 @@ def checkban(irc, source, args): results = 0 for uid, userobj in irc.users.copy().items(): - targetmask = utils.getHostmask(irc, uid) + targetmask = irc.getHostmask(uid) if ircmatch.match(casemapping, banmask, targetmask): if results < 50: # XXX rather arbitrary limit serverobj = irc.servers[irc.getServer(uid)] @@ -70,7 +70,7 @@ def checkban(irc, source, args): # Target can be both a nick (of an online user) or a hostmask. uid = irc.nickToUid(targetmask) if uid: - targetmask = utils.getHostmask(irc, uid) + targetmask = irc.getHostmask(uid) elif not utils.isHostmask(targetmask): irc.reply("Error: Invalid nick or hostmask '%s'." % targetmask) return @@ -92,7 +92,7 @@ def jupe(irc, source, args): try: servername = args[0] reason = ' '.join(args[1:]) or "No reason given" - desc = "Juped by %s: [%s]" % (utils.getHostmask(irc, source), reason) + desc = "Juped by %s: [%s]" % (irc.getHostmask(source), reason) except IndexError: irc.reply('Error: Not enough arguments. Needs 1-2: servername, reason (optional).') return diff --git a/plugins/relay.py b/plugins/relay.py index 15351fc..aa83139 100644 --- a/plugins/relay.py +++ b/plugins/relay.py @@ -1244,7 +1244,7 @@ def create(irc, source, args): irc.reply('Error: Channel %r is already part of a relay.' % channel) return - creator = utils.getHostmask(irc, source) + creator = irc.getHostmask(source) # Create the relay database entry with the (network name, channel name) # pair - this is just a dict with various keys. db[(irc.name, channel)] = {'claim': [irc.name], 'links': set(), @@ -1291,7 +1291,7 @@ def destroy(irc, source, args): del db[entry] log.info('(%s) relay: Channel %s destroyed by %s.', irc.name, - channel, utils.getHostmask(irc, source)) + channel, irc.getHostmask(source)) irc.reply('Done.') else: irc.reply('Error: No such relay %r exists.' % channel) @@ -1344,7 +1344,7 @@ def link(irc, source, args): return entry['links'].add((irc.name, localchan)) log.info('(%s) relay: Channel %s linked to %s%s by %s.', irc.name, - localchan, remotenet, channel, utils.getHostmask(irc, source)) + localchan, remotenet, channel, irc.getHostmask(source)) initializeChannel(irc, localchan) irc.reply('Done.') @@ -1386,7 +1386,7 @@ def delink(irc, source, args): db[entry]['links'].remove((irc.name, channel)) irc.reply('Done.') log.info('(%s) relay: Channel %s delinked from %s%s by %s.', irc.name, - channel, entry[0], entry[1], utils.getHostmask(irc, source)) + channel, entry[0], entry[1], irc.getHostmask(source)) else: irc.reply('Error: No such relay %r.' % channel) diff --git a/protocols/inspircd.py b/protocols/inspircd.py index 9fa4a0a..c788559 100644 --- a/protocols/inspircd.py +++ b/protocols/inspircd.py @@ -697,7 +697,7 @@ class InspIRCdProtocol(TS6BaseProtocol): if self.irc.isInternalServer(target): # The target has to be one of our servers in order to work... uplink = self.irc.servers[target].uplink - reason = 'Requested by %s' % utils.getHostmask(self.irc, numeric) + reason = 'Requested by %s' % self.irc.getHostmask(numeric) self._send(uplink, 'SQUIT %s :%s' % (target, reason)) return self.handle_squit(numeric, 'SQUIT', [target, reason]) else: diff --git a/protocols/nefarious.py b/protocols/nefarious.py index be83ecf..c62a1ca 100644 --- a/protocols/nefarious.py +++ b/protocols/nefarious.py @@ -591,7 +591,7 @@ class P10Protocol(Protocol): if not self.irc.isInternalClient(numeric): raise LookupError('No such PyLink client exists.') - sendername = utils.getHostmask(self.irc, numeric) + sendername = self.irc.getHostmask(numeric) creationts = self.irc.channels[target].ts diff --git a/protocols/unreal.py b/protocols/unreal.py index 303f6bf..f561ebf 100644 --- a/protocols/unreal.py +++ b/protocols/unreal.py @@ -294,7 +294,7 @@ class UnrealProtocol(TS6BaseProtocol): # <- :unreal.midnight.vpn NOTICE @#test :[Knock] by GL|!gl@hidden-1C620195 (test) assert utils.isChannel(target), "Can only knock on channels!" sender = self.irc.getServer(numeric) - s = '[Knock] by %s (%s)' % (utils.getHostmask(self.irc, numeric), text) + s = '[Knock] by %s (%s)' % (self.irc.getHostmask(numeric), text) self._send(sender, 'NOTICE @%s :%s' % (target, s)) ### HANDLERS diff --git a/utils.py b/utils.py index 7074c13..c87890a 100644 --- a/utils.py +++ b/utils.py @@ -159,45 +159,6 @@ def checkAuthenticated(irc, uid, allowAuthed=True, allowOper=True): raise NotAuthenticatedError("You are not authenticated!") return True -def isManipulatableClient(irc, uid): - """ - Returns whether the given user is marked as an internal, manipulatable - client. Usually, automatically spawned services clients should have this - set True to prevent interactions with opers (like mode changes) from - causing desyncs. - """ - return irc.isInternalClient(uid) and irc.users[uid].manipulatable - -def getHostmask(irc, user, realhost=False, ip=False): - """ - Returns the hostmask of the given user, if present. If the realhost option - is given, return the real host of the user instead of the displayed host. - If the ip option is given, return the IP address of the user (this overrides - realhost).""" - userobj = irc.users.get(user) - - try: - nick = userobj.nick - except AttributeError: - nick = '' - - try: - ident = userobj.ident - except AttributeError: - ident = '' - - try: - if ip: - host = userobj.ip - elif realhost: - host = userobj.realhost - else: - host = userobj.host - except AttributeError: - host = '' - - return '%s!%s@%s' % (nick, ident, host) - def loadModuleFromFolder(name, folder): """ Imports and returns a module, if existing, from a specific folder.