acarsdec

an ACARS decoder
git clone git://r-36.net/acarsdec
Log | Files | Refs | README

stdinsrv.py (2433B)


      1 #!/usr/bin/env python
      2 # coding=utf-8
      3 #
      4 # Copy me if you can.
      5 # by Christoph Lohmann <20h@r-36.net> 
      6 #
      7 
      8 import sys
      9 from socket import socket, AF_INET, SOCK_STREAM, SO_REUSEADDR, SOL_SOCKET
     10 from select import poll, POLLIN, POLLPRI, POLLERR, POLLHUP
     11 from fcntl import fcntl, F_GETFL, F_SETFL
     12 from os import O_NONBLOCK
     13 import errno
     14 import time
     15 from getopt import getopt, GetoptError
     16 
     17 def dbg(msg):
     18 	sys.stderr.write("%s\n" % (msg))
     19 
     20 def usage(app):
     21 	sys.stderr.write("usage: %s [-d] [-p port] [-h bind host]\n" % (app))
     22 	sys.exit(1)
     23 
     24 def main(args):
     25 	try:
     26 		opts, args = getopt(args[1:], "dp:h:")
     27 	except GetoptError, err:
     28 		sys.stderr.write("%s\n" % (str(err)))
     29 		usage(args[0])
     30 
     31 	debug = False
     32 	host = ""
     33 	port = 6789
     34 	for o, a in opts:
     35 		if o == "-p":
     36 			port = int(a)
     37 		elif o == "-d":
     38 			debug = True
     39 		elif o == "-h":
     40 			host = a
     41 		else:
     42 			assert False, "unhandled option"
     43 
     44 	sock = socket(AF_INET, SOCK_STREAM)
     45 	sock.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
     46 	sock.bind((host, port))
     47 	sock.listen(5)
     48 
     49 	fl = fcntl(sys.stdin, F_GETFL)
     50 	fcntl(sys.stdin, F_SETFL, fl | O_NONBLOCK)
     51 
     52 	clients = []
     53 	def getcli(fd):
     54 		for i in clients:
     55 			if i.fileno() == fd:
     56 				return i
     57 
     58 	def broadcastcli(data):
     59 		if debug == True:
     60 			dbg("Broadcast")
     61 		for i in clients:
     62 			try:
     63 				i.send(data)
     64 				i.flush(data)
     65 			except:
     66 				next
     67 
     68 	def closecli(fd):
     69 		if debug == True:
     70 			dbg("Close: %d" % (fd))
     71 		cli = getcli(i[0])
     72 		clients.remove(cli)
     73 		po.unregister(cli)
     74 		cli.close()
     75 
     76 	po = poll()
     77 	po.register(sys.stdin, POLLIN|POLLPRI|POLLERR|POLLHUP)
     78 	po.register(sock, POLLIN|POLLPRI)
     79 	while 1:
     80 		events = po.poll(30)
     81 		for i in events:
     82 			if i[0] == sock.fileno():
     83 				cli = sock.accept()[0]
     84 				cli.setblocking(0)
     85 				clients.append(cli)
     86 				po.register(cli, POLLIN|POLLPRI)
     87 				if debug == True:
     88 					dbg("Accept: %d" % (cli.fileno()))
     89 			elif i[1] in (POLLERR, POLLHUP):
     90 				if debug == True:
     91 					dbg("err or hup: %d" % (i[0]))
     92 				if i[0] == sys.stdin.fileno():
     93 					return 1
     94 				cli = getcli(i[0])
     95 				clients.remove(cli)
     96 				po.unregister(cli)
     97 				cli.close()
     98 			elif i[1] in (POLLIN, POLLPRI):
     99 				if i[0] == sys.stdin.fileno():
    100 					if debug == True:
    101 						dbg("Input on stdin.")
    102 					broadcastcli(sys.stdin.read(4096))
    103 				else:
    104 					if debug == True:
    105 						dbg("Input from client: %d" % (i[0]))
    106 					cli = getcli(i[0])
    107 					a = cli.recv(4096)
    108 					if len(a) == 0:
    109 						closecli(i[0])
    110 
    111 if __name__ == "__main__":
    112 	sys.exit(main(sys.argv))
    113