mirror of https://github.com/9001/r0c.git
149 lines
3.2 KiB
Python
149 lines
3.2 KiB
Python
#!/usr/bin/env python2
|
|
# -*- coding: utf-8 -*-
|
|
from __future__ import print_function
|
|
|
|
|
|
"""r0c.py: retr0chat Telnet/Netcat Server"""
|
|
__version__ = "0.9"
|
|
__author__ = "ed <a@ocv.me>"
|
|
__credits__ = ["stackoverflow.com"]
|
|
__license__ = "MIT"
|
|
__copyright__ = 2018
|
|
|
|
|
|
import sys
|
|
import signal
|
|
if sys.version_info[0] == 2:
|
|
sys.dont_write_bytecode = True
|
|
|
|
from r0c.config import *
|
|
from r0c.util import *
|
|
from r0c.c_vt100 import *
|
|
from r0c.c_netcat import *
|
|
from r0c.c_telnet import *
|
|
from r0c.chat import *
|
|
|
|
|
|
if __name__ != '__main__':
|
|
print('this is not a library')
|
|
sys.exit(1)
|
|
|
|
|
|
class Core(object):
|
|
def __init__(self):
|
|
if len(sys.argv) != 3:
|
|
print()
|
|
print(' need argument 1: Telnet port (or 0 to disable)')
|
|
print(' need argument 2: NetCat port (or 0 to disable)')
|
|
print()
|
|
print(' example:')
|
|
print(' {0} 23 531'.format(sys.argv[0]))
|
|
print()
|
|
sys.exit(1)
|
|
|
|
self.telnet_port = int(sys.argv[1])
|
|
self.netcat_port = int(sys.argv[2])
|
|
|
|
print(' * Telnet server on port ' + str(self.telnet_port))
|
|
print(' * NetCat server on port ' + str(self.netcat_port))
|
|
|
|
self.stopping = False
|
|
self.pushthr_alive = False
|
|
self.asyncore_alive = False
|
|
|
|
print(' * Capturing ^C')
|
|
signal.signal(signal.SIGINT, self.signal_handler)
|
|
|
|
print(' * Creating world')
|
|
self.world = World(self)
|
|
|
|
print(' * Starting Telnet server')
|
|
self.telnet_server = TelnetServer('0.0.0.0', self.telnet_port, self.world)
|
|
|
|
print(' * Starting NetCat server')
|
|
self.netcat_server = NetcatServer('0.0.0.0', self.netcat_port, self.world)
|
|
|
|
print(' * Starting push driver')
|
|
self.push_thr = threading.Thread(target=self.push_worker, args=([self.telnet_server, self.netcat_server],))
|
|
#self.push_thr.daemon = True
|
|
self.push_thr.start()
|
|
|
|
print(' * Handover to asyncore')
|
|
self.asyncore_thr = threading.Thread(target=self.asyncore_worker)
|
|
self.asyncore_thr.start()
|
|
|
|
|
|
def run(self):
|
|
print(' * r0c is up')
|
|
|
|
while not self.stopping:
|
|
time.sleep(0.1)
|
|
|
|
print(' * asyncore terminating')
|
|
clean_shutdown = False
|
|
for n in range(0, 40): # 2sec
|
|
if not self.asyncore_alive:
|
|
print(' * asyncore stopped cleanly')
|
|
clean_shutdown = True
|
|
break
|
|
time.sleep(0.05)
|
|
|
|
if not clean_shutdown:
|
|
print(' -X- asyncore is stuck')
|
|
|
|
print(' * asyncore cleanup')
|
|
self.netcat_server.close()
|
|
self.telnet_server.close()
|
|
|
|
print(' * r0c is down')
|
|
|
|
|
|
def asyncore_worker(self):
|
|
self.asyncore_alive = True
|
|
|
|
timeout = 0.05
|
|
while not self.stopping:
|
|
asyncore.loop(timeout, count=0.5/timeout)
|
|
|
|
self.asyncore_alive = False
|
|
|
|
|
|
def push_worker(self, ifaces):
|
|
self.pushthr_alive = True
|
|
|
|
last_ts = None
|
|
while not self.stopping:
|
|
while True:
|
|
ts = time.time()
|
|
its = int(ts)
|
|
if its != last_ts:
|
|
last_ts = its
|
|
#print('=== {0}'.format(its))
|
|
break
|
|
if ts - its < 0.98:
|
|
#print(ts-its)
|
|
time.sleep((1-(ts-its))*0.9)
|
|
else:
|
|
time.sleep(0.01)
|
|
|
|
for iface in ifaces:
|
|
for client in iface.clients:
|
|
if not client.handshake_sz:
|
|
print('!!! push_worker without handshake_sz')
|
|
client.refresh(False)
|
|
|
|
self.pushthr_alive = False
|
|
|
|
|
|
def shutdown(self):
|
|
#monitor_threads()
|
|
self.stopping = True
|
|
|
|
|
|
def signal_handler(self, signal, frame):
|
|
self.shutdown()
|
|
|
|
|
|
core = Core()
|
|
core.run()
|