summaryrefslogtreecommitdiff
path: root/bouncer.py
diff options
context:
space:
mode:
authorBrian Sherson <caretaker82@euclid.shersonb.net>2014-01-10 20:38:51 -0800
committerBrian Sherson <caretaker82@euclid.shersonb.net>2014-01-10 20:38:51 -0800
commit2bc7e36fa2e33f8ddbb1aaeebbf4e2e788a9602b (patch)
tree388771cff941e1305f0dddc3c5e064b8e3fbd5a8 /bouncer.py
parentf85a25ca2d46544de3ca5613eebdef903e9340ee (diff)
New Release
Diffstat (limited to 'bouncer.py')
-rw-r--r--bouncer.py783
1 files changed, 445 insertions, 338 deletions
diff --git a/bouncer.py b/bouncer.py
index 3c321fa..0e351ac 100644
--- a/bouncer.py
+++ b/bouncer.py
@@ -9,16 +9,29 @@ import string
import hashlib
import traceback
import irc
+import getpass
from threading import Thread, Lock
import Queue
+def BouncerReload(BNC):
+ if BNC.isAlive():
+ BNC.stop()
+ newBNC = Bouncer(addr=BNC.addr, port=BNC.port, ssl=BNC.ssl, ipv6=BNC.ipv6,
+ certfile=BNC.certfile, keyfile=BNC.keyfile, timeout=BNC.timeout, autoaway=BNC.autoaway)
+ for label, (IRC, passwd, hashtype) in BNC.servers.items():
+ IRC.rmAddon(BNC)
+ IRC.addAddon(newBNC, label=label, passwd=passwd, hashtype=hashtype)
+ return newBNC
+
+
class Bouncer (Thread):
- def __init__(self, addr="", port=16667, ssl=False, ipv6=False, certfile=None, keyfile=None, ignore=None, debug=False, log=sys.stderr, timeout=300, BNC=None, autoaway=None):
+
+ def __init__(self, addr="", port=16667, ssl=False, ipv6=False, certfile=None, keyfile=None, ignore=None, debug=False, timeout=300, autoaway=None):
self.__name__ = "Bouncer for pyIRC"
- self.__version__ = "1.1"
+ self.__version__ = "1.2"
self.__author__ = "Brian Sherson"
- self.__date__ = "December 1, 2013"
+ self.__date__ = "December 26, 2013"
self.addr = addr
self.port = port
@@ -37,9 +50,10 @@ class Bouncer (Thread):
self.debug = debug
self.timeout = timeout
self.autoaway = autoaway
+ self._stopexpected = False
- ### Keep track of what extensions/connections are requesting WHO, WHOIS, and LIST, because we don't want to spam every bouncer connection with the server's replies.
- ### In the future, MAY implement this idea in the irc module.
+ # Keep track of what extensions/connections are requesting WHO, WHOIS, and LIST, because we don't want to spam every bouncer connection with the server's replies.
+ # In the future, MAY implement this idea in the irc module.
self.whoexpected = {}
self.whoisexpected = {}
self.listexpected = {}
@@ -59,13 +73,19 @@ class Bouncer (Thread):
try:
(connection, addr) = self.socket.accept()
if self.ssl:
- connection = ssl.wrap_socket(connection, server_side=True, certfile=self.certfile, keyfile=self.keyfile, ssl_version=ssl.PROTOCOL_SSLv23)
+ connection = ssl.wrap_socket(
+ connection, server_side=True, certfile=self.certfile, keyfile=self.keyfile, ssl_version=ssl.PROTOCOL_SSLv23)
#print ((self,"New client connecting from %s:%s"%addr))
except socket.error:
- #print "Shutting down Listener"
+ # print "Shutting down Listener"
self.socket.close()
- #raise
+ if not self._stopexpected:
+ raise
sys.exit()
+ except:
+ tb = traceback.format_exc()
+ print >>sys.stderr, tb
+ continue
connection.settimeout(self.timeout)
bouncer = BouncerConnection(
self, connection, addr, debug=self.debug)
@@ -75,15 +95,23 @@ class Bouncer (Thread):
except:
pass
- def onAddonAdd(self, IRC, label, passwd, hashtype="md5"):
- if IRC in [connection for (connection, passwd, hashtype) in self.servers.values()]:
+ def onAddonAdd(self, IRC, label, passwd=None, hashtype="sha512"):
+ if passwd == None:
+ while True:
+ passwd = getpass.getpass("Enter new password: ")
+ if passwd == getpass.getpass("Confirm new password: "):
+ break
+ print "Passwords do not match!"
+ passwd = hashlib.new(hashtype, passwd).hexdigest()
+ if IRC in [connection for (connection, p, h) in self.servers.values()]:
return # Silently do nothing
if label in self.servers.keys():
return
self.servers[label] = (IRC, passwd, hashtype)
self.whoexpected[IRC] = []
if self.debug:
- IRC.logwrite("dbg [Bouncer.onAddonAdd] Clearing WHO expected list." % vars())
+ IRC.logwrite(
+ "dbg [Bouncer.onAddonAdd] Clearing WHO expected list." % vars())
self.whoisexpected[IRC] = []
self.listexpected[IRC] = []
@@ -96,6 +124,7 @@ class Bouncer (Thread):
del self.servers[label]
def stop(self):
+ self._stopexpected = True
self.socket.shutdown(0)
def disconnectall(self, quitmsg="Disconnecting all sessions"):
@@ -104,248 +133,259 @@ class Bouncer (Thread):
def onDisconnect(self, IRC, expected=False):
self.whoexpected[IRC] = []
- if self.debug:
- IRC.logwrite("dbg [Bouncer.onDisconnect] Clearing WHO expected list.")
self.whoisexpected[IRC] = []
self.listexpected[IRC] = []
for bouncerconnection in self.connections:
if bouncerconnection.IRC == IRC:
- bouncerconnection.quit(quitmsg="IRC connection lost")
+ #bouncerconnection.quit(quitmsg="IRC connection lost")
+ for channel in IRC.identity.channels:
+ bouncerconnection.send(":%s!%s@%s PART %s :Bouncer Connection Lost\n" % (
+ IRC.identity.nick, IRC.identity.username, IRC.identity.host, channel.name))
+ bouncerconnection.send(
+ ":%s!%s@%s QUIT :Bouncer Connection Lost\n" %
+ (IRC.identity.nick, IRC.identity.username, IRC.identity.host))
+ bouncerconnection.send(
+ ":*Bouncer* NOTICE %s :Connection to %s:%s has been lost.\n" %
+ (bouncerconnection.nick, IRC.server, IRC.port))
+
+ def onQuit(self, IRC, user, quitmsg):
+ # For some odd reason, certain networks (*cough*Freenode*cough*) will send a quit message for the user, causing IRC.identity.channels to be cleared
+ # before onDisconnect can be executed. This is the remedy.
+ for bouncerconnection in self.connections:
+ if bouncerconnection.IRC == IRC:
+ if quitmsg:
+ bouncerconnection.send(":%s!%s@%s QUIT :%s\n" % (
+ user.nick, user.username, user.host, quitmsg))
+ else:
+ bouncerconnection.send(
+ ":%s!%s@%s QUIT\n" % (user.nick, user.username, user.host))
+ if user == IRC.identity:
+ for channel in IRC.identity.channels:
+ bouncerconnection.send(":%s!%s@%s PART %s :Bouncer Connection Lost\n" % (
+ IRC.identity.nick, IRC.identity.username, IRC.identity.host, channel.name))
+
+ def onConnectAttempt(self, IRC):
+ for bouncerconnection in self.connections:
+ if bouncerconnection.IRC == IRC:
+ bouncerconnection.send(
+ ":*Bouncer* NOTICE %s :Attempting connection to %s:%s.\n" %
+ (bouncerconnection.nick, IRC.server, IRC.port))
+
+ def onConnect(self, IRC):
+ for bouncerconnection in self.connections:
+ if bouncerconnection.IRC == IRC:
+ bouncerconnection.send(
+ ":*Bouncer* NOTICE %s :Connection to %s:%s established.\n" %
+ (bouncerconnection.nick, IRC.server, IRC.port))
+
+ def onMeNickChange(self, IRC, newnick):
+ for bouncerconnection in self.connections:
+ if bouncerconnection.IRC == IRC:
+ bouncerconnection.send(":%s!%s@%s NICK %s\n" %
+ (IRC.identity.nick, IRC.identity.username, IRC.identity.host, newnick))
+ bouncerconnection.nick = newnick
+
+ def onRegistered(self, IRC):
+ for bouncerconnection in self.connections:
+ if bouncerconnection.IRC == IRC:
+ if bouncerconnection.nick != IRC.identity.nick:
+ bouncerconnection.send(":%s!%s@%s NICK %s\n" % (
+ bouncerconnection.nick, bouncerconnection.username, bouncerconnection.host, IRC.identity.nick))
+ bouncerconnection.nick = IRC.identity.nick
+
+ def onConnectFail(self, IRC, exc, excmsg, tb):
+ for bouncerconnection in self.connections:
+ if bouncerconnection.IRC == IRC:
+ bouncerconnection.send(
+ ":*Bouncer* NOTICE %s :Connection to %s:%s failed: %s.\n" %
+ (bouncerconnection.nick, IRC.server, IRC.port, excmsg))
def onSendChanMsg(self, IRC, origin, channel, targetprefix, msg):
- ### Called when bot sends a PRIVMSG to channel.
- ### The variable origin refers to a class instance voluntarily identifying itself as that which requested data be sent.
+ # Called when bot sends a PRIVMSG to channel.
+ # The variable origin refers to a class instance voluntarily
+ # identifying itself as that which requested data be sent.
for bouncerconnection in self.connections:
if IRC == bouncerconnection.IRC and origin != bouncerconnection:
- bouncerconnection.send(":%s!%s@%s PRIVMSG %s%s :%s\n"%(IRC.identity.nick, IRC.identity.username, IRC.identity.host, targetprefix, channel.name, msg))
+ bouncerconnection.send(":%s!%s@%s PRIVMSG %s%s :%s\n" %
+ (IRC.identity.nick, IRC.identity.username, IRC.identity.host, targetprefix, channel.name, msg))
def onSendChanAction(self, IRC, origin, channel, targetprefix, action):
- self.onSendChanMsg(IRC, origin, channel, targetprefix,
- "\x01ACTION %s\x01"%action)
+ self.onSendChanMsg(
+ IRC, origin, channel, targetprefix, "\x01ACTION %s\x01" % action)
def onSendChanNotice(self, IRC, origin, channel, targetprefix, msg):
- ### Called when bot sends a NOTICE to channel.
- ### The variable origin refers to a class instance voluntarily identifying itself as that which requested data be sent.
+ # Called when bot sends a NOTICE to channel.
+ # The variable origin refers to a class instance voluntarily
+ # identifying itself as that which requested data be sent.
for bouncerconnection in self.connections:
if IRC == bouncerconnection.IRC and origin != bouncerconnection:
- bouncerconnection.send(":%s!%s@%s NOTICE %s%s :%s\n"%(IRC.identity.nick, IRC.identity.username, IRC.identity.host, targetprefix, channel.name, msg))
+ bouncerconnection.send(":%s!%s@%s NOTICE %s%s :%s\n" % (
+ IRC.identity.nick, IRC.identity.username, IRC.identity.host, targetprefix, channel.name, msg))
def onSend(self, IRC, origin, line, cmd, target, params, extinfo):
if cmd.upper() == "WHO":
self.whoexpected[IRC].append(origin)
if self.debug:
- with IRC.loglock:
- timestamp = irc.timestamp()
- if issubclass(type(origin), Thread):
- name = origin.name
- print >>IRC.log, "%(timestamp)s dbg [Bouncer.onSend] Adding %(origin)s (%(name)s) to WHO expected list." % vars()
- else:
- print >>IRC.log, "%(timestamp)s dbg [Bouncer.onSend] Adding %(origin)s to WHO expected list." % vars()
- for obj in self.whoexpected[IRC]:
- if issubclass(type(obj), Thread):
- name = obj.name
- print >>IRC.log, "%(timestamp)s dbg [Bouncer.onSend] WHO expected: %(obj)s (%(name)s)" % vars()
- else:
- print >>IRC.log, "%(timestamp)s dbg [Bouncer.onSend] WHO expected: %(obj)s" % vars()
- IRC.log.flush()
+ if issubclass(type(origin), Thread):
+ name = origin.name
+ IRC.logwrite(
+ "dbg [Bouncer.onSend] Adding %(origin)s (%(name)s) to WHO expected list." % vars())
+ else:
+ IRC.logwrite(
+ "dbg [Bouncer.onSend] Adding %(origin)s to WHO expected list." % vars())
+ IRC.logwrite(
+ "dbg [Bouncer.onSend] WHO expected list size: %d" %
+ len(self.whoexpected[IRC]))
elif cmd.upper() == "WHOIS":
self.whoisexpected[IRC].append(origin)
elif cmd.upper() == "LIST":
self.listexpected[IRC].append(origin)
def onWhoEntry(self, IRC, origin, channel, user, channame, username, host, serv, nick, flags, hops, realname):
- ### Called when a WHO list is received.
+ # Called when a WHO list is received.
if len(self.whoexpected[IRC]) and self.whoexpected[IRC][0] in self.connections:
bncconnection = self.whoexpected[IRC][0]
- try:
- bncconnection.send(":%s 352 %s %s %s %s %s %s %s :%s %s\n"%(origin, IRC.identity.nick, channame, username, host, serv, nick, flags, hops, realname))
- except socket.error:
- pass
+ bncconnection.send(":%s 352 %s %s %s %s %s %s %s :%s %s\n" %
+ (origin, IRC.identity.nick, channame, username, host, serv, nick, flags, hops, realname))
def onWhoEnd(self, IRC, origin, param, endmsg):
- ### Called when a WHO list is received.
+ # Called when a WHO list is received.
if len(self.whoexpected[IRC]) and self.whoexpected[IRC][0] in self.connections:
bncconnection = self.whoexpected[IRC][0]
- try:
- bncconnection.send(":%s 315 %s %s :%s\n"%(
- origin, IRC.identity.nick, param, endmsg))
- except socket.error:
- pass
- finally:
- del self.whoexpected[IRC][0]
-
- def onWho(self, IRC, params, wholist, endmsg):
- ### Called when a WHO list is received.
- if len(self.whoexpected[IRC]):
- try:
- if self.whoexpected[IRC][0] in self.connections:
- bncconnection = self.whoexpected[IRC][0]
- lines = [":%s 352 %s %s %s %s %s %s %s :%s %s\n"%(IRC.serv, IRC.identity.nick, channame, username, host, serv, nick, flags, hops, realname) for (channel, user, channame, username, host, serv, nick, flags, hops, realname) in wholist]+[":%s 315 %s %s :%s\n"%(IRC.serv, IRC.identity.nick, params, endmsg)]
- bncconnection.send("".join(lines))
- finally:
- del self.whoexpected[IRC][0]
+ bncconnection.send(":%s 315 %s %s :%s\n" %
+ (origin, IRC.identity.nick, param, endmsg))
+ if self.debug:
+ if issubclass(type(self.whoexpected[IRC][0]), Thread):
+ name = self.whoexpected[IRC][0].name
+ IRC.logwrite(
+ "dbg [Bouncer.onWhoEnd] Removing %s (%s) from WHO expected list." %
+ (self.whoexpected[IRC][0], name))
+ else:
+ IRC.logwrite(
+ "dbg [Bouncer.onWhoEnd] Removing %s from WHO expected list." % self.whoexpected[IRC][0])
+ del self.whoexpected[IRC][0]
+ if self.debug:
+ IRC.logwrite("dbg [Bouncer.onWhoEnd] WHO expected list size: %d" %
+ len(self.whoexpected[IRC]))
def onListStart(self, IRC, origin, params, extinfo):
- ### Called when a WHO list is received.
+ # Called when a WHO list is received.
if len(self.listexpected[IRC]) and self.listexpected[IRC][0] in self.connections:
bncconnection = self.listexpected[IRC][0]
- try:
- bncconnection.send(":%s 321 %s %s :%s\n"%(origin,
- IRC.identity.nick, params, extinfo))
- except socket.error:
- pass
+ bncconnection.send(":%s 321 %s %s :%s\n" %
+ (origin, IRC.identity.nick, params, extinfo))
def onListEntry(self, IRC, origin, channel, population, extinfo):
- ### Called when a WHO list is received.
+ # Called when a WHO list is received.
if len(self.listexpected[IRC]) and self.listexpected[IRC][0] in self.connections:
bncconnection = self.listexpected[IRC][0]
- try:
- bncconnection.send(":%s 322 %s %s %d :%s\n"%(origin, IRC.identity.nick, channel.name, population, extinfo))
- except socket.error:
- pass
+ bncconnection.send(":%s 322 %s %s %d :%s\n" %
+ (origin, IRC.identity.nick, channel.name, population, extinfo))
def onListEnd(self, IRC, origin, endmsg):
- ### Called when a WHO list is received.
+ # Called when a WHO list is received.
if len(self.listexpected[IRC]) and self.listexpected[IRC][0] in self.connections:
bncconnection = self.listexpected[IRC][0]
- try:
- bncconnection.send(":%s 323 %s :%s\n"%(
- origin, IRC.identity.nick, endmsg))
- except socket.error:
- pass
- finally:
- del self.listexpected[IRC][0]
+ bncconnection.send(":%s 323 %s :%s\n" %
+ (origin, IRC.identity.nick, endmsg))
+ del self.listexpected[IRC][0]
def onWhoisStart(self, IRC, origin, user, nickname, username, host, realname):
- ### Called when a WHOIS reply is received.
+ # Called when a WHOIS reply is received.
if len(self.whoisexpected[IRC]):
if self.whoisexpected[IRC][0] in self.connections:
bncconnection = self.whoisexpected[IRC][0]
- try:
- bncconnection.send(":%s 311 %s %s %s %s * :%s\n" % (origin, IRC.identity.nick, nickname, username, host, realname))
- except socket.error:
- pass
+ bncconnection.send(":%s 311 %s %s %s %s * :%s\n" %
+ (origin, IRC.identity.nick, nickname, username, host, realname))
def onWhoisRegisteredNick(self, IRC, origin, user, nickname, msg):
- ### Called when a WHOIS reply is received.
+ # Called when a WHOIS reply is received.
if len(self.whoisexpected[IRC]) and self.whoisexpected[IRC][0] in self.connections:
bncconnection = self.whoisexpected[IRC][0]
- try:
- bncconnection.send(":%s 307 %s %s :%s\n" % (
- origin, IRC.identity.nick, nickname, msg))
- except socket.error:
- pass
+ bncconnection.send(":%s 307 %s %s :%s\n" %
+ (origin, IRC.identity.nick, nickname, msg))
def onWhoisConnectingFrom(self, IRC, origin, user, nickname, msg):
- ### Called when a WHOIS reply is received.
+ # Called when a WHOIS reply is received.
if len(self.whoisexpected[IRC]) and self.whoisexpected[IRC][0] in self.connections:
bncconnection = self.whoisexpected[IRC][0]
- try:
- bncconnection.send(":%s 378 %s %s :%s\n" % (
- origin, IRC.identity.nick, nickname, msg))
- except socket.error:
- pass
+ bncconnection.send(":%s 378 %s %s :%s\n" %
+ (origin, IRC.identity.nick, nickname, msg))
def onWhoisChannels(self, IRC, origin, user, nickname, chanlist):
- ### Called when a WHOIS reply is received.
+ # Called when a WHOIS reply is received.
if len(self.whoisexpected[IRC]) and self.whoisexpected[IRC][0] in self.connections:
bncconnection = self.whoisexpected[IRC][0]
- try:
- bncconnection.send(":%s 319 %s %s :%s\n" % (origin, IRC.identity.nick, nickname, " ".join(chanlist)))
- except socket.error:
- pass
+ bncconnection.send(":%s 319 %s %s :%s\n" %
+ (origin, IRC.identity.nick, nickname, " ".join(chanlist)))
def onWhoisAvailability(self, IRC, origin, user, nickname, msg):
- ### Called when a WHOIS reply is received.
+ # Called when a WHOIS reply is received.
if len(self.whoisexpected[IRC]) and self.whoisexpected[IRC][0] in self.connections:
bncconnection = self.whoisexpected[IRC][0]
- try:
- bncconnection.send(":%s 310 %s %s :%s\n" % (
- origin, IRC.identity.nick, nickname, msg))
- except socket.error:
- pass
+ bncconnection.send(":%s 310 %s %s :%s\n" %
+ (origin, IRC.identity.nick, nickname, msg))
def onWhoisServer(self, IRC, origin, user, nickname, server, servername):
- ### Called when a WHOIS reply is received.
+ # Called when a WHOIS reply is received.
if len(self.whoisexpected[IRC]) and self.whoisexpected[IRC][0] in self.connections:
bncconnection = self.whoisexpected[IRC][0]
- try:
- bncconnection.send(":%s 312 %s %s %s :%s\n" % (origin, IRC.identity.nick, nickname, server, servername))
- except socket.error:
- pass
+ bncconnection.send(":%s 312 %s %s %s :%s\n" %
+ (origin, IRC.identity.nick, nickname, server, servername))
def onWhoisOp(self, IRC, origin, user, nickname, msg):
if len(self.whoisexpected[IRC]) and self.whoisexpected[IRC][0] in self.connections:
bncconnection = self.whoisexpected[IRC][0]
- try:
- bncconnection.send(":%s 313 %s %s :%s\n" % (
- origin, IRC.identity.nick, nickname, msg))
- except socket.error:
- pass
+ bncconnection.send(":%s 313 %s %s :%s\n" %
+ (origin, IRC.identity.nick, nickname, msg))
def onWhoisAway(self, IRC, origin, user, nickname, awaymsg):
if len(self.whoisexpected[IRC]) and self.whoisexpected[IRC][0] in self.connections:
bncconnection = self.whoisexpected[IRC][0]
- try:
- bncconnection.send(":%s 301 %s %s :%s\n" % (origin,
- IRC.identity.nick, nickname, awaymsg))
- except socket.error:
- pass
+ bncconnection.send(":%s 301 %s %s :%s\n" %
+ (origin, IRC.identity.nick, nickname, awaymsg))
def onWhoisTimes(self, IRC, origin, user, nickname, idletime, signontime, msg):
if len(self.whoisexpected[IRC]) and self.whoisexpected[IRC][0] in self.connections:
bncconnection = self.whoisexpected[IRC][0]
- try:
- bncconnection.send(":%s 317 %s %s %d %d :%s\n" % (origin, IRC.identity.nick, nickname, idletime, signontime, msg))
- except socket.error:
- pass
+ bncconnection.send(":%s 317 %s %s %d %d :%s\n" %
+ (origin, IRC.identity.nick, nickname, idletime, signontime, msg))
def onWhoisSSL(self, IRC, origin, user, nickname, msg):
if len(self.whoisexpected[IRC]) and self.whoisexpected[IRC][0] in self.connections:
bncconnection = self.whoisexpected[IRC][0]
- try:
- bncconnection.send(":%s 671 %s %s :%s\n" % (
- origin, IRC.identity.nick, nickname, msg))
- except socket.error:
- pass
+ bncconnection.send(":%s 671 %s %s :%s\n" %
+ (origin, IRC.identity.nick, nickname, msg))
def onWhoisModes(self, IRC, origin, user, nickname, msg):
if len(self.whoisexpected[IRC]) and self.whoisexpected[IRC][0] in self.connections:
bncconnection = self.whoisexpected[IRC][0]
- try:
- bncconnection.send(":%s 339 %s %s :%s\n" % (
- origin, IRC.identity.nick, nickname, msg))
- except socket.error:
- pass
+ bncconnection.send(":%s 339 %s %s :%s\n" %
+ (origin, IRC.identity.nick, nickname, msg))
def onWhoisLoggedInAs(self, IRC, origin, user, nickname, loggedinas, msg):
if len(self.whoisexpected[IRC]) and self.whoisexpected[IRC][0] in self.connections:
bncconnection = self.whoisexpected[IRC][0]
- try:
- bncconnection.send(":%s 330 %s %s %s :%s\n" % (origin, IRC.identity.nick, nickname, loggedinas, msg))
- except socket.error:
- pass
+ bncconnection.send(":%s 330 %s %s %s :%s\n" %
+ (origin, IRC.identity.nick, nickname, loggedinas, msg))
def onWhoisEnd(self, IRC, origin, user, nickname, msg):
if len(self.whoisexpected[IRC]) and self.whoisexpected[IRC][0] in self.connections:
bncconnection = self.whoisexpected[IRC][0]
- try:
- bncconnection.send(":%s 318 %s %s :%s\n" % (
- origin, IRC.identity.nick, nickname, msg))
- except socket.error:
- pass
- finally:
- del self.whoisexpected[IRC][0]
+ bncconnection.send(":%s 318 %s %s :%s\n" %
+ (origin, IRC.identity.nick, nickname, msg))
+ del self.whoisexpected[IRC][0]
def onUnhandled(self, IRC, line, origin, cmd, target, params, extinfo):
for bouncerconnection in self.connections:
if bouncerconnection.IRC == IRC:
- bouncerconnection.send("%s\n"%line)
+ bouncerconnection.send("%s\n" % line)
class BouncerConnection (Thread):
+
def __init__(self, bouncer, connection, addr, debug=False):
- #print "Initializing ListenThread..."
+ # print "Initializing ListenThread..."
self.bouncer = bouncer
self.connection = connection
self.host, self.port = self.addr = addr[:2]
@@ -371,7 +411,8 @@ class BouncerConnection (Thread):
self.connection.send(data)
except socket.error:
exc, excmsg, tb = sys.exc_info()
- print >>self.IRC.logwrite(*["!!! [BouncerConnection.send] Exception in thread %(self)s" % vars()]+["!!! [BouncerConnection.send] %(tbline)s" % vars() for tbline in traceback.format_exc().split("\n")])
+ print >>self.IRC.logwrite(*["!!! [BouncerConnection.send] Exception in thread %(self)s" % vars()] + [
+ "!!! [BouncerConnection.send] %(tbline)s" % vars() for tbline in traceback.format_exc().split("\n")])
self.quit(quitmsg=excmsg.message)
def __repr__(self):
@@ -401,18 +442,19 @@ class BouncerConnection (Thread):
self.quitmsg = quitmsg
with self.lock:
try:
- self.connection.send("ERROR :Closing link: (%s@%s) [%s]\n" % (self.IRC.identity.nick if self.IRC else "*", self.host, quitmsg))
+ self.connection.send("ERROR :Closing link: (%s@%s) [%s]\n" % (
+ self.IRC.identity.nick if self.IRC else "*", self.host, quitmsg))
except:
pass
try:
- self.connection.shutdown(1)
+ self.connection.shutdown(socket.SHUT_WR)
self.connection.close()
except:
pass
self.quitting = True
def run(self):
- ### Name loopup should happen here instead
+ # Name loopup should happen here instead
ipv4match = re.findall(
r"^::ffff:((\d+)\.(\d+)\.(\d+)\.(\d+))$", self.host)
if self.bouncer.ipv6 and ipv4match:
@@ -428,7 +470,7 @@ class BouncerConnection (Thread):
except:
pass
- ### Add connection to connection list.
+ # Add connection to connection list.
listnumerics = dict(b=(367, 368, "channel ban list"),
e=(348, 349, "Channel Exception List"),
@@ -447,7 +489,8 @@ class BouncerConnection (Thread):
try:
while True:
- ### Read data (appending) into readbuf, then break lines and append lines to linebuf
+ # Read data (appending) into readbuf, then break lines and
+ # append lines to linebuf
while len(linebuf) == 0:
timestamp = irc.timestamp()
read = self.connection.recv(512)
@@ -460,10 +503,11 @@ class BouncerConnection (Thread):
if lastlf >= 0:
linebuf.extend(string.split(readbuf[0:lastlf], "\n"))
- readbuf = readbuf[lastlf+1:]
+ readbuf = readbuf[lastlf + 1:]
line = string.rstrip(linebuf.pop(0))
- match = re.findall("^(.+?)(?:\\s+(.+?)(?:\\s+(.+?))??)??(?:\\s+:(.*))?$", line, re.I)
+ match = re.findall(
+ "^(.+?)(?:\\s+(.+?)(?:\\s+(.+?))??)??(?:\\s+:(.*))?$", line, re.I)
if len(match) == 0:
continue
@@ -474,146 +518,165 @@ class BouncerConnection (Thread):
passwd = target if target else extinfo
else:
self.quit("Access Denied")
+ print "*** [BouncerConnection] Incoming connection from %s failed: Expected PASS." % (self.host)
break
- elif not nick: # Bouncer expects a NICK command
+ elif not self.nick: # Bouncer expects a NICK command
if cmd.upper() == "NICK":
- nick = target if target else extinfo
+ self.nick = target if target else extinfo
else:
self.quit("Access Denied")
+ print "*** [BouncerConnection] Incoming connection from %s failed: Expected NICK." % (self.host)
break
elif not self.username: # Bouncer expects a USER command to finish registration
if cmd.upper() == "USER":
self.username = target
- #print self.username
+ # print self.username
if self.username in self.bouncer.servers.keys():
- self.IRC, passwdhash, hashtype = self.bouncer.servers[self.username]
- passmatch = hashlib.new(hashtype, passwd).hexdigest() == passwdhash
+ self.IRC, passwdhash, hashtype = self.bouncer.servers[
+ self.username]
+ passmatch = hashlib.new(
+ hashtype, passwd).hexdigest() == passwdhash
with self.IRC.lock:
- self.IRC.logwrite("*** [BouncerConnection] Incoming connection from %s to %s." % (self.host, self.IRC))
+ if not passmatch:
+ self.quit("Access Denied")
+ self.IRC.logwrite(
+ "*** [BouncerConnection] Incoming connection from %s to %s denied: Invalid password." % (self.host, self.IRC))
+ for bouncerconnection in self.bouncer.connections:
+ if bouncerconnection.IRC != self.IRC:
+ continue
+ if not bouncerconnection.quitting:
+ bouncerconnection.send(":*Bouncer* NOTICE %s :Incoming connection from %s to %s dened: Invalid password.\n" % (
+ bouncerconnection.IRC.identity.nick, self.host, self.IRC))
+ break
+
+ self.IRC.logwrite(
+ "*** [BouncerConnection] Incoming connection from %s to %s." % (self.host, self.IRC))
with self.bouncer.lock:
- ### Announce connection to all other bouncer connections.
- if self.debug:
- self.IRC.logwrite("dbg [BouncerConnection] Attempting to broadcast incoming connection %(self)s." % vars())
+ # Announce connection to all other bouncer
+ # connections.
for bouncerconnection in self.bouncer.connections:
if bouncerconnection.IRC != self.IRC:
continue
- if self.debug:
- self.IRC.logwrite("dbg [BouncerConnection] Broadcasting to %(bouncerconnection)s." % vars())
if not bouncerconnection.quitting:
- bouncerconnection.send(":*Bouncer* NOTICE %s :Incoming connection from %s to %s\n" % (bouncerconnection.IRC.identity.nick, self.host, self.IRC))
- if self.debug:
- self.IRC.logwrite("dbg [BouncerConnection] Success: %(bouncerconnection)s." % vars())
- if len([bncconnection for bncconnection in self.bouncer.connections if bncconnection.IRC == self.IRC]) == 0 and self.IRC.identity.away:
- ### Bouncer connection should automatically return from away status.
+ bouncerconnection.send(":*Bouncer* NOTICE %s :Incoming connection from %s to %s\n" % (
+ bouncerconnection.IRC.identity.nick, self.host, self.IRC))
+ if len([bncconnection for bncconnection in self.bouncer.connections if bncconnection.IRC == self.IRC]) == 0 and self.IRC.registered and type(self.IRC.identity) == irc.User and self.IRC.identity.away:
+ # Bouncer connection should
+ # automatically return from away
+ # status.
self.IRC.raw("AWAY")
self.bouncer.connections.append(self)
- if not (self.IRC.connected and self.IRC.registered and type(self.IRC.supports) == dict and "CHANMODES" in self.IRC.supports.keys() and passmatch):
- self.quit("Access Denied")
- break
-
- ### If we have made it to this point, then access has been granted.
- labels = [bouncerconnection.label for bouncerconnection in self.bouncer.connections if bouncerconnection.IRC == self.IRC and bouncerconnection.label]
- n = 1
- while "*%s_%d"%(self.username, n) in labels:
- n += 1
- self.label = "*%s_%d"%(self.username, n)
-
- ### Request Version info.
- #self.connection.send(":$bouncer PRIVMSG %s :\x01VERSION\x01\n" % (self.IRC.identity.nick))
-
- ### Log incoming connection
-
- ### Send Greeting.
- with self.lock:
- self.connection.send(":%s 001 %s :%s\n" % (self.IRC.serv, self.IRC.identity.nick, self.IRC.welcome))
- self.connection.send(":%s 002 %s :%s\n" % (self.IRC.serv, self.IRC.identity.nick, self.IRC.hostinfo))
- self.connection.send(":%s 003 %s :%s\n" % (self.IRC.serv, self.IRC.identity.nick, self.IRC.servcreated))
- self.connection.send(":%s 004 %s %s\n" % (self.IRC.serv, self.IRC.identity.nick, self.IRC.servinfo))
-
- ### Send 005 response.
- supports = ["CHANMODES=%s"%(",".join(value)) if name == "CHANMODES" else "PREFIX=(%s)%s"%value if name == "PREFIX" else "%s=%s"%(name, value) if value else name for name, value in self.IRC.supports.items()]
- supports.sort()
- supportsreply = []
- supportsstr = " ".join(supports)
- index = 0
- while True:
- if len(supportsstr)-index > 196:
- nextindex = supportsstr.rfind(" ", index, index+196)
- supportsreply.append(supportsstr[index:nextindex])
- index = nextindex+1
+ if self.IRC.registered:
+ # Send Greeting.
+ with self.lock:
+ if self.IRC.welcome:
+ self.connection.send(":%s 001 %s :%s\n" % (
+ self.IRC.serv, self.IRC.identity.nick, self.IRC.welcome))
+ if self.IRC.hostinfo:
+ self.connection.send(":%s 002 %s :%s\n" % (
+ self.IRC.serv, self.IRC.identity.nick, self.IRC.hostinfo))
+ if self.IRC.servcreated:
+ self.connection.send(":%s 003 %s :%s\n" % (
+ self.IRC.serv, self.IRC.identity.nick, self.IRC.servcreated))
+ if self.IRC.servinfo:
+ self.connection.send(":%s 004 %s %s\n" % (
+ self.IRC.serv, self.IRC.identity.nick, self.IRC.servinfo))
+
+ # Send 005 response.
+ if self.IRC.supports:
+ supports = ["CHANMODES=%s" % (",".join(value)) if name == "CHANMODES" else "PREFIX=(%s)%s" % value if name == "PREFIX" else "%s=%s" % (
+ name, value) if value else name for name, value in self.IRC.supports.items()]
+ supports.sort()
+ supportsreply = []
+ supportsstr = " ".join(supports)
+ index = 0
+ while True:
+ if len(supportsstr) - index > 196:
+ nextindex = supportsstr.rfind(
+ " ", index, index + 196)
+ supportsreply.append(
+ supportsstr[index:nextindex])
+ index = nextindex + 1
+ else:
+ supportsreply.append(
+ supportsstr[index:])
+ break
+ for support in supportsreply:
+ self.connection.send(":%s 005 %s %s :are supported by this server\n" % (
+ self.IRC.serv, self.IRC.identity.nick, support))
+
+ # Send MOTD
+ if self.IRC.motdgreet and self.IRC.motd and self.IRC.motdend:
+ self.connection.send(":%s 375 %s :%s\n" % (
+ self.IRC.serv, self.IRC.identity.nick, self.IRC.motdgreet))
+ for motdline in self.IRC.motd:
+ self.connection.send(":%s 372 %s :%s\n" % (
+ self.IRC.serv, self.IRC.identity.nick, motdline))
+ try:
+ self.connection.send(":%s 376 %s :%s\n" % (
+ self.IRC.serv, self.IRC.identity.nick, self.IRC.motdend))
+ except AttributeError:
+ self.connection.send(
+ ":%s 376 %s\n" % (self.IRC.serv, self.IRC.identity.nick))
else:
- supportsreply.append(supportsstr[index:])
- break
- for support in supportsreply:
- self.connection.send(":%s 005 %s %s :are supported by this server\n" % (self.IRC.serv, self.IRC.identity.nick, support))
-
- ### Send MOTD
- if self.IRC.motdgreet and self.IRC.motd and self.IRC.motdend:
- self.connection.send(":%s 375 %s :%s\n" % (self.IRC.serv, self.IRC.identity.nick, self.IRC.motdgreet))
- for motdline in self.IRC.motd:
- self.connection.send(":%s 372 %s :%s\n" % (self.IRC.serv, self.IRC.identity.nick, motdline))
- try:
- self.connection.send(":%s 376 %s :%s\n" % (self.IRC.serv, self.IRC.identity.nick, self.IRC.motdend))
- except AttributeError:
- self.connection.send(":%s 376 %s\n" % (self.IRC.serv, self.IRC.identity.nick))
- else:
- self.connection.send(":%s 422 %s :MOTD File is missing\n" % (self.IRC.serv, self.IRC.identity.nick))
-
- ### Send user modes and snomasks.
- self.connection.send(":%s 221 %s +%s\n" % (self.IRC.serv, self.IRC.identity.nick, self.IRC.identity.modes))
- if "s" in self.IRC.identity.modes and self.IRC.identity.snomask:
- self.connection.send(":%s 008 %s +%s :Server notice mask\n" % (self.IRC.server, self.IRC.identity.nick, self.IRC.identity.snomask))
-
- # ### Join user to internal bouncer channel.
- # self.connection.send(":%s!%s@%s JOIN :$bouncer\n" % (self.IRC.identity.nick, self.IRC.identity.username, self.IRC.identity.host))
-
- # ### Set internal bouncer topic.
- # self.connection.send(":$bouncer 332 %s $bouncer :Bouncer internal channel. Enter bouncer commands here.\n" % (self.IRC.identity.nick))
- # self.connection.send(":$bouncer 333 %s $bouncer $bouncer %s\n" % (self.IRC.identity.nick, self.bouncer.starttime))
-
- # ### Send NAMES for internal bouncer channel.
- # self.connection.send(":$bouncer 353 %s @ $bouncer :%s\n" % (
- # self.IRC.identity.nick,
- # string.join(["@*Bouncer*"]+["@%s"%bouncerconnection.label for bouncerconnection in self.bouncer.connections]))
- # )
- # self.connection.send(":$bouncer 366 %s $bouncer :End of /NAMES list.\n" % (self.IRC.identity.nick))
-
- # ### Give operator mode to user.
- # self.connection.send(":*Bouncer* MODE $bouncer +o %s\n" % (self.IRC.identity.nick))
-
- ### Join user to channels.
- for channel in self.IRC.identity.channels:
- ### JOIN command
- self.connection.send(":%s!%s@%s JOIN :%s\n" % (self.IRC.identity.nick, self.IRC.identity.username, self.IRC.identity.host, channel.name))
-
- ### Topic
- self.connection.send(":%s 332 %s %s :%s\n" % (self.IRC.serv, self.IRC.identity.nick, channel.name, channel.topic))
- self.connection.send(":%s 333 %s %s %s %s\n" % (self.IRC.serv, self.IRC.identity.nick, channel.name, channel.topicsetby, channel.topictime))
-
- ### Determine if +s or +p modes are set in channel
- secret = "s" in channel.modes.keys() and channel.modes["s"]
- private = "p" in channel.modes.keys() and channel.modes["p"]
-
- ### Construct NAMES for channel.
- namesusers = []
- modes, symbols = self.IRC.supports["PREFIX"]
- self.connection.send(":%s 353 %s %s %s :%s\n" % (
- self.IRC.serv,
- self.IRC.identity.nick,
- "@" if secret else ("*" if private else "="),
- channel.name,
- string.join([string.join([symbols[k] if modes[k] in channel.modes.keys() and user in channel.modes[modes[k]] else "" for k in xrange(len(modes))], "")+user.nick for user in channel.users]))
- )
- self.connection.send(":%s 366 %s %s :End of /NAMES list.\n" % (self.IRC.serv, self.IRC.identity.nick, channel.name))
-
+ self.connection.send(
+ ":%s 422 %s :MOTD File is missing\n" % (self.IRC.serv, self.IRC.identity.nick))
+
+ # Send user modes and snomasks.
+ self.connection.send(":%s 221 %s +%s\n" % (
+ self.IRC.serv, self.IRC.identity.nick, self.IRC.identity.modes))
+
+ if "s" in self.IRC.identity.modes and self.IRC.identity.snomask:
+ self.connection.send(":%s 008 %s +%s :Server notice mask\n" % (
+ self.IRC.serv, self.IRC.identity.nick, self.IRC.identity.snomask))
+
+ # Join user to channels.
+ for channel in self.IRC.identity.channels:
+ # JOIN command
+ self.connection.send(":%s!%s@%s JOIN :%s\n" % (
+ self.IRC.identity.nick, self.IRC.identity.username, self.IRC.identity.host, channel.name))
+
+ # Topic
+ self.connection.send(":%s 332 %s %s :%s\n" % (
+ self.IRC.serv, self.IRC.identity.nick, channel.name, channel.topic))
+ self.connection.send(":%s 333 %s %s %s %s\n" % (self.IRC.serv, self.IRC.identity.nick, channel.name, channel.topicsetby.nick if type(
+ channel.topicsetby) == irc.User else channel.topicsetby, channel.topictime))
+
+ # Determine if +s or +p modes are
+ # set in channel
+ secret = "s" in channel.modes.keys() and channel.modes[
+ "s"]
+ private = "p" in channel.modes.keys(
+ ) and channel.modes["p"]
+
+ # Construct NAMES for channel.
+ namesusers = []
+ modes, symbols = self.IRC.supports[
+ "PREFIX"]
+ self.connection.send(":%s 353 %s %s %s :%s\n" % (
+ self.IRC.serv,
+ self.IRC.identity.nick,
+ "@" if secret else (
+ "*" if private else "="),
+ channel.name,
+ string.join([string.join([symbols[k] if modes[k] in channel.modes.keys() and user in channel.modes[modes[k]] else "" for k in xrange(len(modes))], "") + user.nick for user in channel.users]))
+ )
+ self.connection.send(":%s 366 %s %s :End of /NAMES list.\n" % (
+ self.IRC.serv, self.IRC.identity.nick, channel.name))
+ else:
+ self.send(
+ ":*Bouncer* NOTICE %s :Not connected to server. Type /bncconnect to attempt connection.\n" % self.nick)
+ self.send(":%s 001 %s :Welcome to the Bouncer IRC Network %s!%s@%s\n" % (
+ "*Bouncer*", self.nick, self.nick, self.username, self.host))
else: # User not found
self.quit("Access Denied")
break
else: # Client did not send USER command when expected
self.quit("Access Denied")
+ print "*** [BouncerConnection] Incoming connection from %s failed: Expected USER." % (self.host)
break
elif cmd.upper() == "QUIT":
@@ -621,60 +684,98 @@ class BouncerConnection (Thread):
break
elif cmd.upper() == "PING":
- self.send(":%s PONG %s :%s\n" % (self.IRC.serv, self.IRC.serv, self.IRC.identity.nick))
-
- elif cmd.upper() in ("PRIVMSG", "NOTICE"):
- ### Check if CTCP
- ctcp = re.findall("^\x01(.*?)(?:\\s+(.*?)\\s*)?\x01$",
- extinfo)
-
- if ctcp: # If CTCP, only want to
- (ctcptype, ext) = ctcp[0] # Unpack CTCP info
-
- if ctcptype == "LAGCHECK": # Client is doing a lag check. No need to send to IRC network, just reply back.
- self.send(":%s!%s@%s %s\n" % (self.IRC.identity.nick, self.IRC.identity.username, self.IRC.identity.host, line))
+ self.send(":%s PONG %s :%s\n" %
+ (self.IRC.serv, self.IRC.serv, self.IRC.identity.nick if type(self.IRC.identity) == irc.User else "***"))
+
+ elif cmd.upper() == "BNCCONNECT":
+ with self.IRC.lock:
+ if self.IRC.isAlive() and self.IRC.connected:
+ self.send(
+ ":*Bouncer* NOTICE %s :Bouncer is already connected.\n" % self.nick)
else:
- self.IRC.raw(line, origin=self)
- else:
- self.IRC.raw(line, origin=self)
-
- elif cmd.upper() == "MODE": # Will want to determine is requesting modes, or attempting to modify modes.
- if target and "CHANTYPES" in self.IRC.supports.keys() and target[0] in self.IRC.supports["CHANTYPES"]:
- if params == "":
- channel = self.IRC.channel(target)
- modes = channel.modes.keys()
- modestr = "".join([mode for mode in modes if mode not in self.IRC.supports["CHANMODES"][0]+self.IRC.supports["PREFIX"][0] and channel.modes[mode]])
- params = " ".join([channel.modes[mode] for mode in modes if mode in self.IRC.supports["CHANMODES"][1]+self.IRC.supports["CHANMODES"][2] and channel.modes[mode]])
- with self.lock:
- if len(modestr):
- self.connection.send(":%s 324 %s %s +%s %s\n" % (self.IRC.serv, self.IRC.identity.nick, channel.name, modestr, params))
- if channel.created:
- self.connection.send(":%s 329 %s %s %s\n" % (self.IRC.serv, self.IRC.identity.nick, channel.name, channel.created))
- elif re.match("^\\+?[%s]+$"%self.IRC.supports["CHANMODES"][0], params) and extinfo == "":
- #print "ddd Mode List Request", params
- channel = self.IRC.channel(target)
- redundant = []
- for mode in params.lstrip("+"):
- if mode in redundant or mode not in listnumerics.keys():
- continue
- i, e, l = listnumerics[mode]
+ self.IRC.start()
+
+ elif cmd.upper() == "BNCQUIT":
+ with self.IRC.lock:
+ if self.IRC.isAlive() and self.IRC.connected and self.IRC.registered:
+ quitmsg = " ".join(
+ [word for word in [target, params, extinfo] if word])
+ self.IRC.quit(quitmsg)
+ else:
+ self.send(
+ ":*Bouncer* NOTICE %s :Bouncer is already disconnected.\n" % self.nick)
+
+ else:
+ with self.IRC.lock:
+ if not self.IRC.connected:
+ self.send(
+ ":*Bouncer* NOTICE %s :Not connected to server. Type /bncconnect to attempt connection.\n" % self.nick)
+ break
+ elif not self.IRC.registered:
+ self.send(
+ ":*Bouncer* NOTICE %s :Not registered.\n" % self.nick)
+ break
+ elif cmd.upper() in ("PRIVMSG", "NOTICE"):
+ # Check if CTCP
+ ctcp = re.findall(
+ "^\x01(.*?)(?:\\s+(.*?)\\s*)?\x01$", extinfo)
+
+ if ctcp: # If CTCP, only want to
+ (ctcptype, ext) = ctcp[0] # Unpack CTCP info
+
+ if ctcptype == "LAGCHECK": # Client is doing a lag check. No need to send to IRC network, just reply back.
+ self.send(":%s!%s@%s %s\n" % (
+ self.IRC.identity.nick, self.IRC.identity.username, self.IRC.identity.host, line))
+ else:
+ self.IRC.raw(line, origin=self)
+ else:
+ self.IRC.raw(line, origin=self)
+
+ elif cmd.upper() == "MODE": # Will want to determine is requesting modes, or attempting to modify modes.
+ if target and "CHANTYPES" in self.IRC.supports.keys() and target[0] in self.IRC.supports["CHANTYPES"]:
+ if params == "":
+ channel = self.IRC.channel(target)
+ modes = channel.modes.keys()
+ modestr = "".join([mode for mode in modes if mode not in self.IRC.supports[
+ "CHANMODES"][0] + self.IRC.supports["PREFIX"][0] and channel.modes[mode]])
+ params = " ".join([channel.modes[mode] for mode in modes if mode in self.IRC.supports[
+ "CHANMODES"][1] + self.IRC.supports["CHANMODES"][2] and channel.modes[mode]])
+ with self.lock:
+ if len(modestr):
+ self.connection.send(":%s 324 %s %s +%s %s\n" % (
+ self.IRC.serv, self.IRC.identity.nick, channel.name, modestr, params))
+ if channel.created:
+ self.connection.send(":%s 329 %s %s %s\n" % (
+ self.IRC.serv, self.IRC.identity.nick, channel.name, channel.created))
+ elif re.match("^\\+?[%s]+$" % self.IRC.supports["CHANMODES"][0], params) and extinfo == "":
+ # print "ddd Mode List Request", params
+ channel = self.IRC.channel(target)
+ redundant = []
+ for mode in params.lstrip("+"):
+ if mode in redundant or mode not in listnumerics.keys():
+ continue
+ i, e, l = listnumerics[mode]
+ with self.lock:
+ if mode in channel.modes.keys():
+ for (mask, setby, settime) in channel.modes[mode]:
+ self.connection.send(":%s %d %s %s %s %s %s\n" % (
+ self.IRC.serv, i, channel.context.identity.nick, channel.name, mask, setby, settime))
+ self.connection.send(":%s %d %s %s :End of %s\n" % (
+ self.IRC.serv, e, channel.context.identity.nick, channel.name, l))
+ redundant.append(mode)
+ else:
+ self.IRC.raw(line, origin=self)
+ elif params == "" and target.lower() == self.IRC.identity.nick.lower():
with self.lock:
- if mode in channel.modes.keys():
- for (mask, setby, settime) in channel.modes[mode]:
- self.connection.send(":%s %d %s %s %s %s %s\n" % (self.IRC.serv, i, channel.context.identity.nick, channel.name, mask, setby, settime))
- self.connection.send(":%s %d %s %s :End of %s\n" % (self.IRC.serv, e, channel.context.identity.nick, channel.name, l))
- redundant.append(mode)
+ self.connection.send(":%s 221 %s +%s\n" % (
+ self.IRC.serv, self.IRC.identity.nick, self.IRC.identity.modes))
+ if "s" in self.IRC.identity.modes and self.IRC.identity.snomask:
+ self.connection.send(":%s 008 %s +%s :Server notice mask\n" % (
+ self.IRC.serv, self.IRC.identity.nick, self.IRC.identity.snomask))
+ else:
+ self.IRC.raw(line, origin=self)
else:
self.IRC.raw(line, origin=self)
- elif params == "" and target.lower() == self.IRC.identity.nick.lower():
- with self.lock:
- self.connection.send(":%s 221 %s +%s\n" % (self.IRC.serv, self.IRC.identity.nick, self.IRC.identity.modes))
- if "s" in self.IRC.identity.modes and self.IRC.identity.snomask:
- self.connection.send(":%s 008 %s +%s :Server notice mask\n" % (self.IRC.serv, self.IRC.identity.nick, self.IRC.identity.snomask))
- else:
- self.IRC.raw(line, origin=self)
- else:
- self.IRC.raw(line, origin=self)
except SystemExit:
pass # No need to pass error message if break resulted from sys.exit()
@@ -683,9 +784,10 @@ class BouncerConnection (Thread):
self.quitmsg = str(excmsg)
if self.IRC:
exc, excmsg, tb = sys.exc_info()
- self.IRC.logwrite(*["!!! [BouncerConnection] Exception in thread %(self)s" % vars()]+["!!! [BouncerConnection] %(tbline)s" % vars() for tbline in traceback.format_exc().split("\n")])
+ self.IRC.logwrite(*["!!! [BouncerConnection] Exception in thread %(self)s" % vars()] + [
+ "!!! [BouncerConnection] %(tbline)s" % vars() for tbline in traceback.format_exc().split("\n")])
finally:
- ### Juuuuuuust in case.
+ # Juuuuuuust in case.
with self.lock:
try:
self.connection.shutdown(1)
@@ -694,28 +796,33 @@ class BouncerConnection (Thread):
pass
if self.IRC:
- self.IRC.logwrite("*** [BouncerConnection] Connection from %s terminated (%s)." % (self.host, self.quitmsg))
+ self.IRC.logwrite(
+ "*** [BouncerConnection] Connection from %s terminated (%s)." % (self.host, self.quitmsg))
if self in self.bouncer.connections:
with self.bouncer.lock:
self.bouncer.connections.remove(self)
- if self.IRC.connected and self.IRC.identity and len([bncconnection for bncconnection in self.bouncer.connections if bncconnection.IRC == self.IRC]) == 0 and not self.IRC.identity.away and self.bouncer.autoaway:
- ### Bouncer automatically sets away status.
- self.IRC.raw("AWAY :%s"%self.bouncer.autoaway)
+ if self.IRC.connected and self.IRC.identity and len([bncconnection for bncconnection in self.bouncer.connections if bncconnection.IRC == self.IRC]) == 0 and self.IRC.registered and type(self.IRC.identity) == irc.User and not self.IRC.identity.away and self.bouncer.autoaway:
+ # Bouncer automatically sets away status.
+ self.IRC.raw("AWAY :%s" % self.bouncer.autoaway)
if self.debug:
- self.IRC.logwrite("dbg [BouncerConnection] Attempting to broadcast terminated connection %(self)s." % vars())
+ self.IRC.logwrite(
+ "dbg [BouncerConnection] Attempting to broadcast terminated connection %(self)s." % vars())
for bouncerconnection in self.bouncer.connections:
if bouncerconnection.IRC == self.IRC:
if self.debug:
- self.IRC.logwrite("dbg [BouncerConnection] Broadcasting to %(bouncerconnection)s." % vars())
+ self.IRC.logwrite(
+ "dbg [BouncerConnection] Broadcasting to %(bouncerconnection)s." % vars())
if not bouncerconnection.quitting:
- bouncerconnection.connection.send(":*Bouncer* NOTICE %s :Connection from %s to %s terminated (%s)\n" % (bouncerconnection.IRC.identity.nick, self.host, self.IRC, self.quitmsg))
+ bouncerconnection.connection.send(":*Bouncer* NOTICE %s :Connection from %s to %s terminated (%s)\n" % (
+ bouncerconnection.IRC.identity.nick, self.host, self.IRC, self.quitmsg))
if self.debug:
- self.IRC.logwrite("dbg [BouncerConnection] Success: %(bouncerconnection)s." % vars())
-
-# ### Announce QUIT to other bouncer connections.
-# for bouncerconnection in self.bouncer.connections:
-# try:
-# bouncerconnection.connection.send(":%s!%s@%s QUIT :%s\n" % (self.label, self.username, self.host, self.quitmsg))
-# except:
-# pass
+ self.IRC.logwrite(
+ "dbg [BouncerConnection] Success: %(bouncerconnection)s." % vars())
+
+# Announce QUIT to other bouncer connections.
+# for bouncerconnection in self.bouncer.connections:
+# try:
+# bouncerconnection.connection.send(":%s!%s@%s QUIT :%s\n" % (self.label, self.username, self.host, self.quitmsg))
+# except:
+# pass