def main(reactor): # change the port to 9151 for Tor Browser Bundle tor_ep = TCP4ClientEndpoint(reactor, "localhost", 9051) connection = yield txtorcon.build_tor_connection(tor_ep, build_state=False) version = yield connection.get_info('version', 'events/names') print("Connected to Tor {version}".format(**version)) print("Events:", version['events/names']) print("Building state.") state = yield txtorcon.TorState.from_protocol(connection) print("listening for circuit events") state.add_circuit_listener(MyCircuitListener()) print("Issuing NEWNYM.") yield connection.signal('NEWNYM') print("OK.") print("Existing circuits:") for c in state.circuits.values(): print(' ', c) print("listening for INFO events") def print_info(i): print("INFO:", i) connection.add_event_listener('INFO', print_info) done = Deferred() yield done # never callback()s so infinite loop
def _connect(self, reactor, update_status): maker = self._tor_control_endpoint_maker with add_context(update_status, "making Tor control endpoint"): tor_control_endpoint = yield maker(reactor, update_status) assert IStreamClientEndpoint.providedBy(tor_control_endpoint) with add_context(update_status, "connecting to Tor"): tproto = yield txtorcon.build_tor_connection(tor_control_endpoint, build_state=False) with add_context(update_status, "waiting for Tor bootstrap"): config = yield txtorcon.TorConfig.from_protocol(tproto) ports = list(config.SocksPort) # I've seen "9050", and "unix:/var/run/tor/socks WorldWritable" for port in ports: pieces = port.split() p = pieces[0] if p == txtorcon.DEFAULT_VALUE: p = "9050" try: portnum = int(p) socks_desc = "tcp:127.0.0.1:%d" % portnum self._socks_desc = socks_desc # stash for tests socks_endpoint = clientFromString(reactor, socks_desc) returnValue(socks_endpoint) except ValueError: pass raise ValueError("could not use config.SocksPort: %r" % (ports,))
def _try_to_connect(reactor, endpoint_desc, stdout, txtorcon): # yields a TorState, or None ep = clientFromString(reactor, endpoint_desc) d = txtorcon.build_tor_connection(ep) def _failed(f): # depending upon what's listening at that endpoint, we might get # various errors. If this list is too short, we might expose an # exception to the user (causing "tahoe create-node" to fail messily) # when we're supposed to just try the next potential port instead. # But I don't want to catch everything, because that may hide actual # coding errrors. f.trap(ConnectionRefusedError, # nothing listening on TCP ConnectError, # missing unix socket, or permission denied #ValueError, # connecting to e.g. an HTTP server causes an # UnhandledException (around a ValueError) when the handshake # fails to parse, but that's not something we can catch. The # attempt hangs, so don't do that. RuntimeError, # authentication failure ) if stdout: stdout.write("Unable to reach Tor at '%s': %s\n" % (endpoint_desc, f.value)) return None d.addErrback(_failed) return d
def main(reactor): ep = TCP4ClientEndpoint(reactor, "localhost", 9251) tor_protocol = yield txtorcon.build_tor_connection(ep, build_state=False) print "Connected to Tor" hs_public_port = 80 hs_port = yield txtorcon.util.available_tcp_port(reactor) hs_string = '%s 127.0.0.1:%d' % (hs_public_port, hs_port) print "Adding ephemeral service", hs_string print "(this can take some time; please be patient)" hs = txtorcon.EphemeralHiddenService([hs_string]) yield hs.add_to_tor(tor_protocol) print "Added ephemeral HS to Tor:", hs.hostname print "Starting site" site = server.Site(Simple()) hs_endpoint = TCP4ServerEndpoint(reactor, hs_port, interface='127.0.0.1') yield hs_endpoint.listen(site) # in 5 seconds, remove the hidden service -- obviously this is # where you'd do your "real work" or whatever. d = defer.Deferred() @defer.inlineCallbacks def remove(): print "Removing the hiddenservice. Private key was" print hs.private_key yield hs.remove_from_tor(tor_protocol) d.callback(None) if False: reactor.callLater(5, remove) print "waiting 5 seconds" else: print "waiting forever" yield d
def _try_to_connect(reactor, endpoint_desc, stdout, txtorcon): # yields a TorState, or None ep = clientFromString(reactor, endpoint_desc) d = txtorcon.build_tor_connection(ep) def _failed(f): # depending upon what's listening at that endpoint, we might get # various errors. If this list is too short, we might expose an # exception to the user (causing "tahoe create-node" to fail messily) # when we're supposed to just try the next potential port instead. # But I don't want to catch everything, because that may hide actual # coding errrors. f.trap( ConnectionRefusedError, # nothing listening on TCP ConnectError, # missing unix socket, or permission denied #ValueError, # connecting to e.g. an HTTP server causes an # UnhandledException (around a ValueError) when the handshake # fails to parse, but that's not something we can catch. The # attempt hangs, so don't do that. RuntimeError, # authentication failure ) if stdout: stdout.write("Unable to reach Tor at '%s': %s\n" % (endpoint_desc, f.value)) return None d.addErrback(_failed) return d
def main(launch_tor=False): log.startLogging(sys.stdout) control_port = 9051 if launch_tor: control_port = 9151 config = txtorcon.TorConfig() config.ControlPort = control_port config.SocksPort = 0 d = txtorcon.launch_tor(config, reactor, progress_updates=progress) ## launch_tor returns a TorProcessProtocol ## ...so we grab out the TorControlProtocol instance in order ## to simply use the same callback on "d" below d.addCallback(lambda pp: pp.tor_protocol) else: ## if build_state=True, then we get a TorState() object back d = txtorcon.build_tor_connection((reactor, '127.0.0.1', control_port), build_state=False) d.addCallback(setup_complete).addErrback(an_error) try: reactor.run() except KeyboardInterrupt: pass # ctrl+c
def start(self): # Connect to an existing Tor, or create a new one. If we need to # launch an onion service, then we need a working control port (and # authentication cookie). If we're only acting as a client, we don't # need the control port. if self._tor_socks_port is not None: self._can_run_service = False returnValue(True) _start_find = self._timing.add_event("find tor") # try port 9051, then try /var/run/tor/control . Throws on failure. state = None _start_tcp = self._timing.add_event("tor localhost") try: connection = (self._reactor, "127.0.0.1", self._tor_control_port) state = yield txtorcon.build_tor_connection(connection) self._tor_protocol = state.protocol except ConnectError: print("unable to reach Tor on %d" % self._tor_control_port) pass self._timing.finish_event(_start_tcp) if not state: _start_unix = self._timing.add_event("tor unix") try: connection = (self._reactor, "/var/run/tor/control") # add build_state=False to get back a Protocol object instead # of a State object state = yield txtorcon.build_tor_connection(connection) self._tor_protocol = state.protocol except (ValueError, ConnectError): print("unable to reach Tor on /var/run/tor/control") pass self._timing.finish_event(_start_unix) if state: print("connected to pre-existing Tor process") print("state:", state) else: print("launching my own Tor process") yield self._create_my_own_tor() # that sets self._tor_socks_port and self._tor_protocol self._timing.finish_event(_start_find) self._can_run_service = True returnValue(True)
def test_build_with_answers_no_pid(self): p = FakeEndpointAnswers( ["", "", "", "", ""] # ns/all # circuit-status # stream-status # address-mappings/all # entry-guards ) d = build_tor_connection(p, build_state=True) d.addCallback(self.confirm_state) d.addCallback(self.confirm_no_pid) p.proto.post_bootstrap.callback(p.proto) return d
def start(self): connection = TCP4ClientEndpoint(self.reactor, "localhost", self.options.control_port) d = txtorcon.build_tor_connection(connection) d.addCallback(self.setup_success) d.addErrback(self.setup_failed) try: self.reactor.run() except KeyboardInterrupt: pass
def main(): try: opts, args = getopt.gnu_getopt(sys.argv[1:], "c:hp:t", [ "control_port=", "help", "port", "launch_tor" ]) except getopt.GetoptError as err: print str(err) usage() sys.exit(2) for o, a in opts: if o in ("-h", "--help"): usage() sys.exit() elif o in ("-c", "--control_port"): options.control_port = int(a) elif o in ("-t", "--launch_tor"): options.launch_tor = True elif o in ("-p", "--port"): options.port = int(a) else: assert False, "unhandled option" log.startLogging(sys.stdout) if options.launch_tor: config = txtorcon.TorConfig() config.ControlPort = options.control_port config.SocksPort = 0 d = txtorcon.launch_tor(config, reactor, progress_updates=progress) # launch_tor returns a TorProcessProtocol # ...so we grab out the TorControlProtocol instance in order # to simply use the same callback on "d" below d.addCallback(lambda pp: pp.tor_protocol) else: # if build_state=True, then we get a TorState() object back d = txtorcon.build_tor_connection((reactor, '127.0.0.1', options.control_port), build_state=False) d.addCallback(setup_complete).addErrback(an_error) try: reactor.run() except KeyboardInterrupt: pass # ctrl+c
def test_build_with_answers_no_pid(self): p = FakeEndpointAnswers(['', # ns/all '', # circuit-status '', # stream-status '', # address-mappings/all '' # entry-guards ]) d = build_tor_connection(p, build_state=True) d.addCallback(self.confirm_state) d.addCallback(self.confirm_no_pid) p.proto.post_bootstrap.callback(p.proto) return d
def test_build_with_answers_guards_unfound_entry(self): p = FakeEndpointAnswers(['', # ns/all '', # circuit-status '', # stream-status '', # address-mappings/all '\n\nkerblam up\nOK\n' # entry-guards ]) d = build_tor_connection(p, build_state=True) d.addCallback(self.confirm_state) d.addCallback(self.confirm_no_pid) p.proto.post_bootstrap.callback(p.proto) return d
def test_build_with_answers(self): p = FakeEndpointAnswers(['', # ns/all '', # circuit-status '', # stream-status '', # address-mappings/all '', # entry-guards '1234' # PID ]) d = build_tor_connection(p, build_state=True) d.addCallback(self.confirm_state).addErrback(self.fail) d.addCallback(self.confirm_pid).addErrback(self.fail) p.proto.post_bootstrap.callback(p.proto) return d
def main(reactor): # change the port to 9151 for Tor Browser Bundle connection = TCP4ClientEndpoint(reactor, "localhost", 9051) state = yield txtorcon.build_tor_connection(connection) print("Connected to tor {state.protocol.version}".format(state=state)) print("Current circuits:") for circ in state.circuits.values(): path = '->'.join([r.name for r in circ.path]) print(" {circ.id}: {circ.state}, {path}".format(circ=circ, path=path)) # can also do "low level" things with the protocol proto = state.protocol answer = yield proto.queue_command("GETINFO version") print("GETINFO version: {answer}".format(answer=answer))
def _connect(self, reactor, update_status): maker = self._tor_control_endpoint_maker with add_context(update_status, "making Tor control endpoint"): tor_control_endpoint = yield maker(reactor, update_status) assert IStreamClientEndpoint.providedBy(tor_control_endpoint) with add_context(update_status, "connecting to Tor"): tproto = yield txtorcon.build_tor_connection(tor_control_endpoint, build_state=False) with add_context(update_status, "waiting for Tor bootstrap"): config = yield txtorcon.TorConfig.from_protocol(tproto) ports = list(config.SocksPort) # I've seen "9050", and "unix:/var/run/tor/socks WorldWritable" # and recently [["9050", "unix:.."]] which is weird try: (socks_endpoint, socks_desc) = next(find_port(reactor, ports)) self._socks_desc = socks_desc # stash for tests returnValue(socks_endpoint) except StopIteration: raise ValueError("could not use config.SocksPort: %r" % (ports, ))
def _try_control_port(self, control_port): NOPE = (None, None, None) ep = clientFromString(self._reactor, control_port) try: tproto = yield build_tor_connection(ep, build_state=False) # now wait for bootstrap tconfig = yield TorConfig.from_protocol(tproto) except (ValueError, ConnectError): returnValue(NOPE) socks_ports = list(tconfig.SocksPort) socks_port = socks_ports[0] # TODO: when might there be multiple? # I've seen "9050", and "unix:/var/run/tor/socks WorldWritable" pieces = socks_port.split() p = pieces[0] if p == DEFAULT_VALUE: socks_desc = "tcp:127.0.0.1:9050" elif re.search('^\d+$', p): socks_desc = "tcp:127.0.0.1:%s" % p else: socks_desc = p returnValue((tproto, tconfig, socks_desc))
def main(tor_control, tor_data): log.startLogging( sys.stdout ) def start_tor(): config = txtorcon.TorConfig() config.DataDirectory = tor_data def get_random_tor_ports(): d2 = txtorcon.util.available_tcp_port(reactor) d2.addCallback(lambda port: config.__setattr__('SocksPort', port)) d2.addCallback(lambda _: txtorcon.util.available_tcp_port(reactor)) d2.addCallback(lambda port: config.__setattr__('ControlPort', port)) return d2 def launch_and_get_protocol(ignore): d2 = txtorcon.launch_tor(config, reactor, stdout=sys.stdout) d2.addCallback(lambda tpp: txtorcon.TorState(tpp.tor_protocol).post_bootstrap) d2.addCallback(lambda state: state.protocol) return d2 d = get_random_tor_ports().addCallback(launch_and_get_protocol) def change_torrc(result): config.UseEntryGuards=0 d2 = config.save() d2.addCallback(lambda ign: result) return d2 d.addCallback(change_torrc) d.addCallback(lambda protocol: TorState.from_protocol(protocol)) return d if tor_control is None: print "launching tor..." d = start_tor() else: print "using tor control port..." endpoint = clientFromString(reactor, tor_control.encode('utf-8')) d = txtorcon.build_tor_connection(endpoint, build_state=False) d.addCallback( ProbeAll2HopCircuits, reactor, './logs', stopped=reactor.stop ) reactor.run()
print "Issuing NEWNYM." yield connection.signal('NEWNYM') print "OK." print "Building state." state = txtorcon.TorState(connection) yield state.post_bootstrap print "State initialized." print "Existing circuits:" for c in state.circuits.values(): print ' ', c print "listening for circuit events" state.add_circuit_listener(MyCircuitListener()) print "listening for INFO events" def print_info(i): print "INFO:", i connection.add_event_listener('INFO', print_info) ## since we don't call reactor.stop(), we keep running d = txtorcon.build_tor_connection(connection, build_state=False) d.addCallback(main).addErrback(error) ## this will only return after reactor.stop() is called reactor.run()
def connect_to_control_port(): connection = TCP4ClientEndpoint(reactor, '127.0.0.1', config.tor.control_port) config.tor_state = yield build_tor_connection(connection)
print "Connected to Tor.", version['version'] print version['events/names'] print "Issuing NEWNYM." yield connection.signal('NEWNYM') print "OK." print "Building state." state = txtorcon.TorState(connection) yield state.post_bootstrap print "State initialized." print "Existing circuits:" for c in state.circuits.values(): print ' ', c print "listening for circuit events" state.add_circuit_listener(MyCircuitListener()) print "listening for INFO events" def print_info(i): print "INFO:", i connection.add_event_listener('INFO', print_info) ## since we don't call reactor.stop(), we keep running d = txtorcon.build_tor_connection(connection, build_state=False) d.addCallback(main).addErrback(error) ## this will only return after reactor.stop() is called reactor.run()
def dispatch(args=None): """ this is the main program; see __main__.py """ if args is None: args = sys.argv global _log_observer options = Options() try: options.parseOptions(args[1:]) except (usage.UsageError, RuntimeError) as e: print(options.getUsage()) print(util.colors.red('Error: ') + str(e), file=sys.stderr) sys.exit(128) except Exception as e: print('Unknown error:', e) sys.exit(200) if options['color'] == 'never' or options['no-color'] or \ (options['color'] == 'auto' and not sys.stdin.isatty()): util.turn_off_color() if options.subCommand is None: print(options) return sub = options.commands[options.subCommand] try: sub.validate(options.subOptions, options) except Exception as e: print(options.getUsage()) print(util.colors.red('Error: ') + str(e), file=sys.stderr) if options['debug']: raise e return build_state = sub.build_state show_general_info = options['info'] endpoint = options['connect'] try: endpoint = endpoints.clientFromString(reactor, options['connect']) except ValueError: try: endpoint = endpoints.clientFromString(reactor, 'tcp:' + options['connect']) except TypeError: endpoint = endpoints.clientFromString(reactor, 'tcp:localhost:' + options['connect']) if options['timestamps']: _log_observer.timestamp = True if sub.controller_connection: d = txtorcon.build_tor_connection(endpoint, build_state=build_state) elif sub.build_state: raise RuntimeError("Internal error: subcommand can't set build_state=True with controller_connection=False") else: d = defer.succeed(None) show_general_info = False if show_general_info: d.addCallback(general_information, True) d.addCallback(lambda arg: ICarmlCommand(sub).run(options.subOptions, options, arg)) d.addErrback(setup_failed, options['debug']) if options['debug']: def dump_heap(): from guppy import hpy print(hpy().heap()) d.addCallback(lambda _: dump_heap()) # task.react needs a function that returns a Deferred task.react(lambda _: d)
state.protocol.add_event_listener('STATUS_CLIENT', log.msg) log.msg('Existing state when we connected:') for s in state.streams.values(): logStream(s, state) log.msg('Existing circuits:') for c in state.circuits.values(): logCircuit(c) def setup_failed(arg): print "SETUP FAILED",arg log.err(arg) reactor.stop() log.startLogging(sys.stdout) d = None try: if os.stat('/var/run/tor/control').st_mode & (stat.S_IRGRP | stat.S_IRUSR | stat.S_IROTH): print "using control socket" d = txtorcon.build_tor_connection(UNIXClientEndpoint(reactor, "/var/run/tor/control")) except OSError: pass if d is None: d = txtorcon.build_tor_connection(TCP4ClientEndpoint(reactor, "localhost", 9051)) d.addCallback(setup).addErrback(setup_failed) reactor.run()
attacher = MyAttacher(state) state.set_attacher(attacher, reactor) state.add_circuit_listener(attacher) state.add_stream_listener(MyStreamListener()) print "Existing state when we connected:" print "Streams:" for s in state.streams.values(): print ' ',s print print "General-purpose circuits:" for c in filter(lambda x: x.purpose == 'GENERAL', state.circuits.values()): print ' ',c.id,'->'.join(map(lambda x: x.location.countrycode, c.path)) def setup_failed(arg): print "SETUP FAILED",arg reactor.stop() if os.stat('/var/run/tor/control').st_mode & (stat.S_IRGRP | stat.S_IRUSR | stat.S_IROTH): print "using control socket" point = UNIXClientEndpoint(reactor, "/var/run/tor/control") else: point = TCP4ClientEndpoint(reactor, "localhost", 9051) d = txtorcon.build_tor_connection(point) d.addCallback(do_setup).addErrback(setup_failed) reactor.run()
def getTorState(self): connection = TCP4ClientEndpoint(reactor, '127.0.0.1', config.tor.control_port) config.tor_state = yield build_tor_connection(connection)
#!/usr/bin/env python from twisted.internet import reactor from twisted.internet.endpoints import TCP4ClientEndpoint import txtorcon def example(state): """ This callback gets called after we've connected and loaded all the current Tor state. """ print "Fully bootstrapped state:", state print " with bootstrapped protocol:", state.protocol reactor.stop() ## change the port to 9151 for Tor Browser Bundle connection = TCP4ClientEndpoint(reactor, "localhost", 9051) d = txtorcon.build_tor_connection(connection) d.addCallback(example) ## this will only return after reactor.stop() is called reactor.run()
def test_build_tcp(self): d = build_tor_connection((FakeReactor(self), '127.0.0.1', 1234)) d.addCallback(self.fail) d.addErrback(lambda x: None) return d
def main(tor_control, tor_data, log_dir, status_log, relay_list, consensus, secret, partitions, this_partition, build_duration, circuit_timeout, log_chunk_size, max_concurrency): assert status_log is not None status_log_fh = open(status_log, 'w') globalLogPublisher.addObserver(textFileLogObserver(status_log_fh)) def start_tor(): config = txtorcon.TorConfig() config.DataDirectory = tor_data def get_random_tor_ports(): d2 = txtorcon.util.available_tcp_port(reactor) d2.addCallback(lambda port: config.__setattr__('SocksPort', port)) d2.addCallback(lambda _: txtorcon.util.available_tcp_port(reactor)) d2.addCallback( lambda port: config.__setattr__('ControlPort', port)) return d2 def launch_and_get_protocol(ignore): d2 = txtorcon.launch_tor(config, reactor, stdout=sys.stdout) d2.addCallback( lambda tpp: txtorcon.TorState(tpp.tor_protocol).post_bootstrap) d2.addCallback(lambda state: state.protocol) return d2 d3 = get_random_tor_ports().addCallback(launch_and_get_protocol) def change_torrc(result): config.UseEntryGuards = 0 d2 = config.save() d2.addCallback(lambda ign: result) return d2 d3.addCallback(change_torrc) d3.addCallback(lambda protocol: TorState.from_protocol(protocol)) return d3 def gather_relays(tor_state): if consensus is not None: routers = get_router_list_from_consensus(tor_state, consensus) elif relay_list is not None: routers = get_router_list_from_file(tor_state, relay_list) else: print "wtf" sys.exit(1) return (tor_state, routers) if tor_control is None: print "launching tor..." d = start_tor() else: print "using tor control port..." endpoint = clientFromString(reactor, tor_control.encode('utf-8')) d = txtorcon.build_tor_connection(endpoint, build_state=True) d.addCallback(gather_relays) def start_probe(args): tor_state, routers = args consensus = "" for relay in [str(relay.id_hex) for relay in routers]: consensus += relay + "," consensus_hash = hashlib.sha256(consensus).digest() shared_secret_hash = hashlib.sha256(secret).digest() prng_seed = hashlib.pbkdf2_hmac('sha256', consensus_hash, shared_secret_hash, iterations=1) circuit_generator = lazy2HopCircuitGenerator(routers, this_partition, partitions, prng_seed) probe = ProbeAll2HopCircuits(tor_state, reactor, log_dir, reactor.stop, partitions, this_partition, build_duration, circuit_timeout, circuit_generator, log_chunk_size, max_concurrency) print "starting scan" probe.start() def signal_handler(signal, frame): print "signal caught, stopping probe" probe.stop() signal.signal(signal.SIGINT, signal_handler) signal.signal(signal.SIGTERM, signal_handler) d.addCallback(start_probe) reactor.run()
import os import stat from twisted.internet import reactor from twisted.internet.endpoints import UNIXClientEndpoint from twisted.internet.endpoints import TCP4ClientEndpoint import txtorcon def log(msg): print msg def setup(proto): print "Connected to a Tor version",proto.version for event in ['INFO', 'NOTICE', 'WARN', 'ERR']: proto.add_event_listener(event, log) def setup_failed(arg): print "SETUP FAILED",arg reactor.stop() if os.stat('/var/run/tor/control').st_mode & (stat.S_IRGRP | stat.S_IRUSR | stat.S_IROTH): print "using control socket" point = UNIXClientEndpoint(reactor, "/var/run/tor/control") else: point = TCP4ClientEndpoint(reactor, "localhost", 9051) d = txtorcon.build_tor_connection(point, build_state=False) d.addCallback(setup).addErrback(setup_failed) reactor.run()
def test_build(self): p = FakeEndpoint() d = build_tor_connection(p, build_state=False) d.addCallback(self.confirm_proto) p.proto.post_bootstrap.callback(p.proto) return d
print '\nTo carry on where you left off, run:' print ' %s --failed %d --built %d' % (sys.argv[0], listener.failed_circuits, listener.built_circuits), for name in listener.per_guard_built.keys(): print '--guard %s,%d,%d' % (name, listener.per_guard_built[name], listener.per_guard_failed[name]), print reactor.addSystemEventTrigger('before', 'shutdown', on_shutdown) if options['connect']: host, port = options['connect'].split(':') port = int(port) print "Connecting to %s:%d..." % (host, port) endpoint = endpoints.clientFromString(reactor, 'tcp:host=%s:port=%d' % (host, port)) else: endpoint = None try: ## FIXME more Pythonic to not check, and accept more exceptions? if os.stat('/var/run/tor/control').st_mode & (stat.S_IRGRP | stat.S_IRUSR | stat.S_IROTH): print "using control socket" endpoint = endpoints.UNIXClientEndpoint(reactor, "/var/run/tor/control") except OSError: pass if endpoint is None: endpoint = endpoints.TCP4ClientEndpoint(reactor, "localhost", 9051) print "Connecting via", endpoint d = txtorcon.build_tor_connection(endpoint, build_state=True) d.addCallback(setup).addErrback(setup_failed) reactor.run()
def test_build_unix(self): tf = tempfile.NamedTemporaryFile() d = build_tor_connection((FakeReactor(self), tf.name)) d.addCallback(self.fail) d.addErrback(lambda x: None) return d
def dispatch(args=None): """ this is the main program; see __main__.py """ if args is None: args = sys.argv global _log_observer options = Options() try: options.parseOptions(args[1:]) except (usage.UsageError, RuntimeError) as e: print(options.getUsage()) print(util.colors.red('Error: ') + str(e), file=sys.stderr) sys.exit(128) except Exception as e: print('Unknown error:', e) sys.exit(200) if options['color'] == 'never' or options['no-color'] or \ (options['color'] == 'auto' and not sys.stdin.isatty()): util.turn_off_color() if options.subCommand is None: print(options) return sub = options.commands[options.subCommand] try: sub.validate(options.subOptions, options) except Exception as e: print(options.getUsage()) print(util.colors.red('Error: ') + str(e), file=sys.stderr) if options['debug']: raise e return build_state = sub.build_state show_general_info = options['info'] endpoint = options['connect'] try: endpoint = endpoints.clientFromString(reactor, options['connect']) except ValueError: try: endpoint = endpoints.clientFromString(reactor, 'tcp:' + options['connect']) except TypeError: endpoint = endpoints.clientFromString( reactor, 'tcp:localhost:' + options['connect']) if options['timestamps']: _log_observer.timestamp = True if sub.controller_connection: d = txtorcon.build_tor_connection(endpoint, build_state=build_state) elif sub.build_state: raise RuntimeError( "Internal error: subcommand can't set build_state=True with controller_connection=False" ) else: d = defer.succeed(None) show_general_info = False if show_general_info: d.addCallback(general_information, True) d.addCallback( lambda arg: ICarmlCommand(sub).run(options.subOptions, options, arg)) d.addErrback(setup_failed, options['debug']) if options['debug']: def dump_heap(): from guppy import hpy print(hpy().heap()) d.addCallback(lambda _: dump_heap()) # task.react needs a function that returns a Deferred task.react(lambda _: d)