Here is a script (which probably contains bugs still) that allows one to host an “IRC like proxy” server in which multiple IRC clients can connect to one IRC server. Basically, the IRC session is simply relayed to all clients while the server maintains just one IRC connection. Anyway, the code is below in case you would like to play around with it.
import os import random import re import select import stat import socket import sys import time class loccom: def rand(self, numb): outp = "" for x in range(0, numb): outp += random.choice("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz") return outp def clrf(self): try: fobj = open(self.file, "w") fobj.write("") fobj.close() except: pass def tmpc(self): dlst = os.listdir(self.fold) for item in dlst: if (not re.match("^%s.*$" % (self.pref), item)): continue sobj = os.stat("%s/%s" % (self.fold, item)) psec = time.time() asec = sobj.st_atime msec = sobj.st_mtime stle = (60 * 60 * 1) if (((psec - asec) >= stle) or ((psec - msec) >= stle)): os.unlink("%s/%s" % (self.fold, item)) def __init__(self): toke = self.rand(16) self.fold = "/tmp" self.pref = "loccom" self.file = ("%s/%s.%s.txt" % (self.fold, self.pref, toke)) self.lock = 0 self.wait = 0.1 self.clrf() self.tmpc() def sloc(self): if (not os.path.isfile(self.file)): raise IOError("File does not exist.") while (self.lock != 0): time.sleep(self.wait) self.lock = 1 def rloc(self): self.lock = 0 def send(self, stri): self.sloc() try: fobj = open(self.file, "a") fobj.write(stri) fobj.close() except: pass self.rloc() def recv(self): self.sloc() try: fobj = open(self.file, "r") outp = fobj.read() fobj.close() except: outp = "" self.clrf() self.rloc() return outp def resi(srch, repl, inpt): while (1): regx = re.match("^.*(%s).*$" % srch, inpt, re.I | re.S) if (not regx): break inpt = re.sub(regx.group(1), repl, inpt) return inpt def ircpmake(): ircphost = "irc.freenode.net" ircpport = 6667 ircpobjc = socket.socket(socket.AF_INET, socket.SOCK_STREAM) ircpobjc.connect((ircphost, ircpport)) return ircpobjc statdata = "" def readline(inptstri=""): global statdata outpstri = "" if (inptstri != ""): statdata += inptstri;print("setting["+inptstri+"]") elif (statdata != ""): statlist = statdata.split("\n") if (len(statlist) > 1): outpstri = (statlist[0] + "\n") tempdata = "" for x in range(1, len(statlist)): if (statlist[x] == ""): continue if (tempdata != ""): tempdata += "\n" tempdata += statlist[x] if (tempdata != ""): if (statdata[-1] == '\n'): tempdata += "\n" statdata = tempdata return outpstri # irc client object ircpobjc = ircpmake() ipaddr = ircpobjc.getsockname() ipaddr = ipaddr[0] imptlist = [] chanlist = [] sendlist = [] recvlist = [] # parent server object hostname = "" portnumb = 6060 sockobjc = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sockobjc.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) sockobjc.bind((hostname, portnumb)) sockobjc.listen(1) while (1): sendremo = [] recvremo = [] (readlist, writelst, errolist) = select.select([sockobjc, ircpobjc], [], [], 0.1) if (sockobjc in readlist): (clieobjc, clieaddr) = sockobjc.accept() print("parent accepted [%s]" % (clieaddr[0])) servclie = loccom() clieserv = loccom() forkpidn = os.fork() if (forkpidn == 0): try: ircpobjc.close() sockobjc.close() sendlist = [] recvlist = [] except: pass break clieobjc.close() sendlist.append(servclie) recvlist.append(clieserv) for ircpitem in imptlist: servclie.send("FORK INIT\r\n%s\r\n" % (ircpitem)) for chanitem in chanlist: servclie.send("FORK INIT\r\n%s JOIN %s\r\n" % (chanitem[0], chanitem[1])) if (ircpobjc in readlist): try: ircpdata = ircpobjc.recv(1024) if (ircpdata): readline(inptstri=ircpdata) else: ircpobjc = ircpmake() except: ircpobjc = ircpmake() while (1): ircpdata = readline() if (not ircpdata): break ircpline = ircpdata.strip() regxobjc = re.match("^:[^ ]+ 001 .+$", ircpline, re.I) if (regxobjc): imptlist.append(ircpline) regxobjc = re.match("^(:[^ ]*%s[^ ]*) join ([^ ]+).*$" % (ipaddr), ircpline, re.I) if (regxobjc): chanlist.append([regxobjc.group(1), regxobjc.group(2)]) regxobjc = re.match("^(:[^ ]*%s[^ ]*) part ([^ ]+).*$" % (ipaddr), ircpline, re.I) if (regxobjc): remochan = [] for chanitem in chanlist: if (chanitem[1] == regxobjc.group(2)): remochan.append(chanitem) for remoitem in remochan: chanlist.remove(remoitem) print("ircp -> serv -> clie [%s]" % (ircpline)) for senditem in sendlist: try: senditem.send(ircpdata) except: sendremo.append(senditem) x = 0 for recvitem in recvlist: try: recvdata = recvitem.recv() if (recvdata): if (x > 0): recvdata = resi("\nNICK ", "\nTICK ", "\n" + recvdata) print("clie -> serv -> ircp [%s]" % (recvdata.strip())) try: ircpobjc.send(recvdata) except: ircpobjc = ircpmake() except: recvremo.append(recvitem) x += 1 for remoitem in sendremo: sendlist.remove(remoitem) for remoitem in recvremo: recvlist.remove(remoitem) if (forkpidn != 0): sys.exit(0) # child server object print("child accepted [%s]" % (clieaddr[0])) while (1): (readlist, writelst, errolist) = select.select([clieobjc], [], [], 0.1) if (clieobjc in readlist): cliedata = clieobjc.recv(1024) if (cliedata): cliedata = re.sub("^WHO ", "NAMES ", cliedata) print("user -> clie -> serv [%s]" % (cliedata.strip())) clieserv.send(cliedata) servdata = servclie.recv() if (servdata != ""): print("serv -> clie -> user [%s]" % (servdata.strip())) clieobjc.send(servdata)