Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/python
- import socket
- import MySQLdb
- import signal
- from select import poll, POLLIN
- from time import time
- from os import getpid
- from sys import exit
- #### DEFINITIONS ####
- class state:
- ### CONFIG ###
- trigger = "!"
- db = {
- 'host': 'localhost',
- 'user': 'devcsw',
- 'pass': 'j00m',
- 'db' : 'devcsw',
- }
- pidfile = "snake.pid"
- identfile = "/home/bot/.oidentd.conf"
- ### MISC. ###
- uplink = {}
- def processIn(fh, sock, buf):
- bid = socks[fh][0]
- if buf.find("PING :") == 0:
- raw(sock, "PONG :"+buf[6:])
- elif buf.find("PRIVMSG") != -1:
- msgBegin = buf.find(':', 1)+1
- trigger = buf[msgBegin:msgBegin+1]
- if trigger == state.trigger:
- nuhMask = buf[1:buf.find(' ')]
- nick = nuhMask[0:nuhMask.find('!')]
- toChan = buf[buf.find(' ')+9:msgBegin-2]
- processMsg(fh, sock, buf, nick, nuhMask, toChan, buf[msgBegin+1:])
- def processMsg(fh, sock, buf, nick, nuhMask, toChan, msg):
- print "nick="+nick+";nuhMask="+nuhMask+";toChan="+toChan+";msg="+msg
- def writePid(fn):
- fh = open(fn, 'w')
- fh.write(str(getpid()))
- fh.close()
- def writeIdent(fn, ident):
- fh = open(fn, 'w')
- fh.write("global { reply \""+ident+"\" }")
- fh.close()
- def sigHdl(signum, frm):
- if signum == signal.SIGINT:
- print str(time())+"*GOT SIGINT - dying"
- for v in bots.values():
- myS = v[1]
- raw(myS, "QUIT :Going away")
- myS.close()
- exit()
- def raw(sock, buf):
- print str(time())+">"+buf
- sock.send(buf+"\r")
- def get(sock):
- data = sock.recv(1)
- if not data: return None
- while (data[-1] != "\n"):
- data += sock.recv(1)
- data = data.strip(" \r\t\n")
- print str(time())+"<"+data
- return data
- #### MAIN CODE ####
- writePid("snake.pid")
- signal.signal(signal.SIGHUP, signal.SIG_IGN)
- signal.signal(signal.SIGINT, sigHdl)
- dbh = MySQLdb.connect(host=state.db['host'],user=state.db['user'],passwd=state.db['pass'],db=state.db['db'])
- poller = poll()
- bots = {}
- socks = {}
- cursor = dbh.cursor()
- cursor.execute("SELECT id, nick, ident, gecos, irchost, ircport, ircpass FROM snk_bots")
- row = cursor.fetchone()
- while row is not None:
- writeIdent(state.identfile, row[2])
- s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
- s.connect((row[4], row[5]))
- if row[6] is not None: raw(s, "PASS :"+row[6])
- raw(s, "NICK "+row[1])
- raw(s, "USER "+row[2]+" * * :"+row[3])
- error = False
- buf = get(s)
- while buf:
- if buf is None:
- print str(time())+"*Skipping rest of registration for bot "+str(row[0])
- error = True
- break
- elif buf.find("ERROR :") == 0:
- print str(time())+"*Skipping rest of registration for bot "+str(row[0])
- error = True
- break
- elif buf.find("PING :") == 0:
- raw(s, "PONG :"+buf[6:])
- elif buf.find("433 * "+row[1]) != -1:
- raw(s, "NICK "+row[1]+"_")
- elif buf.find("001") != -1:
- state.uplink[row[0]] = buf[1:buf.find(" ")]
- print str(time())+"*Found 001 from "+state.uplink[row[0]]
- break;
- buf = get(s)
- if error:
- s.close()
- dbh.cursor().execute("UPDATE snk_bots SET online = 0 WHERE id = "+str(row[0]))
- row = cursor.fetchone()
- continue
- id = row[0]
- bots[id] = (s.fileno(), s)
- socks[s.fileno()] = (id, s)
- poller.register(s, POLLIN)
- dbh.cursor().execute("UPDATE snk_bots SET online = 1 WHERE id = "+str(row[0]))
- row = cursor.fetchone()
- cursor = dbh.cursor()
- cursor.execute("SELECT c.botid, c.chname FROM snk_chans AS c, snk_bots AS b WHERE b.id = c.botid AND b.online = 1")
- row = cursor.fetchone()
- while row is not None:
- id = row[0]
- chname = row[1]
- raw(bots[id][1], "JOIN "+chname)
- row = cursor.fetchone()
- while True:
- readSocks = poller.poll()
- for fheve in readSocks:
- fh = fheve[0]
- s = socks[fh][1]
- buf = get(s)
- if buf is None:
- print str(time())+"*LOST SOCKET "+str(socks[fh][0])
- poller.unregister(fh)
- else:
- processIn(fh, s, buf)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement