stdinsrv.py - acarsdec - an ACARS decoder
 (HTM) git clone git://r-36.net/acarsdec
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) 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