#!/usr/bin/env python import socket import select from cStringIO import StringIO import os clients = [] # (socket, buffer) fqdn = socket.getfqdn() unix_user = os.environ["USER"] nick = unix_user # TODO: make overridable server = "irc.freenode.net" server_port = 6667 port_path = server # TODO remove neccessity for that. try: os.unlink(port_path) except: pass port_1 = socket.socket(socket.AF_UNIX) port_1.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) port_1.bind(port_path) port_1.listen(5) # TODO setting # use IRClib? probably overkill socket_1 = socket.socket() socket_1.connect((server, server_port)) foo = "Gate" socket_1.send("NICK %s\r\n" % nick) #line NOTICE AUTH :*** No identd (auth) response #line :sterling.freenode.net 433 * dannym :Nickname is already in use. #line ERROR :Closing Link: 127.0.0.1 (Connection Timed Out) # FIXME "bla" ? socket_1.send("USER %s %s bla :%s\r\n" % (unix_user, fqdn, foo)) #read_set, write_set, except_set = select.select(set([socket_1]), set(), set(), 120) # buffer: temp buffer (to write to) # socket_1: socket to read from def buffered_lined_read(buffer, socket_1): #if socket_1 in read_set: block = socket_1.recv(1024) if block == "": # EOF? return buffer.write(block) buffer.seek(0) while True: line = buffer.readline() if not line.endswith("\n"): break # here, is one complete line, with line terminator # remove line terminator line = line[:-1] # remove "\r" which "ought" to be here if len(line) > 0 and line[-1] == "\r": line = line[:-1] # here, is one complete line, without line terminators yield line buffer.seek(0) buffer.truncate() buffer.write(line) buffer = StringIO() while True: read_set, write_set, except_set = select.select(set(\ [socket_1, port_1] + [client_socket for client_socket, client_buffer in clients]), set(), set(), 120) if read_set == set() and except_set == set(): #print "zzZZZ" continue if port_1 in read_set: print "helloooo" if len(clients) < 100: # TODO configurable client, dummy = port_1.accept() clients.append((client, StringIO())) print "client", client else: pass # TODO reject dead_clients = set([]) for client_socket, client_buffer in clients: if client_socket in read_set: print "got stuff" for line in buffered_lined_read(client_buffer, client_socket): # send stuff to IRC server socket_1.send(line + "\r\n") if client_socket in except_set: client_socket.close() # shutdown(1) dead_clients.append(client_socket) # remove dead clients clients = [(client_socket, client_buffer) for client_socket, client_buffer in clients if client_socket not in dead_clients] if socket_1 in read_set: # read as many complete lines from IRC as possible, storing excess in buffer for line in buffered_lined_read(buffer, socket_1): print "line", line # traverse all clients in order for client_socket, client_buffer in clients: # send line(s) to that client client_socket.send(line + "\r\n") parts = line.split(" ", 1) # line PING :sterling.freenode.net if len(parts) > 1: command = parts[0] argument_string = parts[1] else: command = parts[0] argument_string = "" if command == "PING": #print "ping..." response = "PONG %s\r\n" % argument_string #print "response", response socket_1.send(response)