123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126 |
- #!/usr/bin/python
- from __future__ import print_function
- import datetime
- import socket
- import random, string
- import daemon, getopt, sys
- import daemon.pidlockfile
- import traceback
- import os
- BUFFER_SIZE = 4096
- def myrandom(length):
- return ''.join(random.choice(string.lowercase) for i in range(length))
- def serve(port, bindTo, path_report_store=None):
- assert path_report_store != None
- s = socket.socket(socket.AF_INET6, socket.SOCK_STREAM)
- s.bind((bindTo, port))
- s.listen(1)
- print('DebugReport server listening on [{0}]:{1}'.format(bindTo, port))
- try:
- from cStringIO import StringIO # Python 2
- except ImportError:
- from io import StringIO # Python 3
- report_buffer = StringIO()
- while 1:
- conn, addr = s.accept()
- conn.settimeout(30.0)
- report_id = None
- try:
- while 1:
- data = conn.recv(BUFFER_SIZE)
- if not data: break
- report_buffer.write(data) # python will convert \n to os.linesep
- report_id = myrandom(10)
- except:
- # try to send a zero-length response back to the peer to indicate a problem
- try:
- conn.sendall("\r\n")
- finally:
- report_buffer.truncate(0)
- conn.close()
- continue
- # don't want to receive any more data from the client
- conn.shutdown(socket.SHUT_RD)
- filename = os.path.join(
- path_report_store,
- "%s_%s.log" % (datetime.date.today().strftime('%Y-%m-%d_'), report_id)
- )
- with open(filename, 'w') as f:
- try:
- f.write(report_buffer.getvalue())
- f.flush()
- except:
- try:
- conn.sendall("\r\n")
- finally:
- report_buffer.truncate(0)
- conn.close()
- continue
- # f will be closed automatically by leaving the 'with'-scope
- report_buffer.truncate(0)
- # send reply to reportee
- response = "%s\r\n" % report_id
- try:
- conn.sendall(response)
- finally:
- conn.close()
- command = 'echo "'+'new report \\\"{0}\\\" from [{2}]:{3} stored as \\\"{1}\\\""'.format(report_id, filename, addr[0], addr[1])
- command = command + ' | /usr/local/bin/ff_log_to_bot'
- os.system(command)
- print('new report "{0}" from [{2}]:{3} stored as "{1}"'.format(report_id, filename, addr[0], addr[1]))
- pass
- if __name__ == '__main__':
- try:
- opts, args = getopt.getopt(sys.argv[1:], "dp:b:s:", ["daemonize", "port=", "bind-to=", "report-store="])
- except:
- print ('Unrecognized option')
- sys.exit(2)
- daemonize = False
- port = 1337
- bindTo = None
- path_report_store = os.path.join(os.path.dirname(sys.argv[0]), "reports")
- for opt, arg in opts:
- if opt in ("-d", "--daemonize"):
- daemonize = True
- elif opt in ("-p", "--port"):
- port = int(arg)
- elif opt in ("-b", "--bind-to"):
- try:
- socket.inet_pton(socket.AF_INET6, arg)
- bindTo = str(arg)
- except:
- traceback.print_exc()
- sys.exit(1)
- elif opt in ("-s", "--report-store"):
- path_report_store = arg
- else:
- assert False
-
- if bindTo == None:
- print("Listening IP address is unset. Using default ::")
- bindTo = "::"
- if not os.path.exists(path_report_store):
- os.makedirs(path_report_store)
- if daemonize == True:
- daemonContext = daemon.DaemonContext(pidfile = daemon.pidlockfile.PIDLockFile("/var/run/ffpb-debugserver.pid"))
- with daemonContext:
- serve(port, bindTo, path_report_store=path_report_store)
- else:
- serve(port, bindTo, path_report_store=path_report_store)
|