Remote IRC Viewer In Py

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)


Leave a comment