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)