All pastes #186995 Raw Edit

Something

public text v1 · immutable
#186995 ·published 2006-09-30 18:27 UTC
rendered paste body
#!/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, <line> 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, <line> 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)