diff --git a/src/onionrcommands/daemonlaunch.py b/src/onionrcommands/daemonlaunch.py index c320dfba..3c430bfa 100755 --- a/src/onionrcommands/daemonlaunch.py +++ b/src/onionrcommands/daemonlaunch.py @@ -25,37 +25,60 @@ from utils import hastor, logoheader from . import version import serializeddata import runtests +""" + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +""" + def _proper_shutdown(): localcommand.local_command('shutdown') sys.exit(1) + def daemon(): - ''' + """ Starts the Onionr communication daemon - ''' + """ + + offline_mode = config.get('general.offline_mode', False) + if not hastor.has_tor(): - logger.error("Tor is not present in system path or Onionr directory", terminal=True) - cleanup.delete_run_files() - sys.exit(1) + offline_mode = True + logger.error("Tor is not present in system path or Onionr directory", + terminal=True) # remove runcheck if it exists if os.path.isfile(filepaths.run_check_file): - logger.debug('Runcheck file found on daemon start, deleting in advance.') + logger.debug('Runcheck file found on daemon start, deleting.') os.remove(filepaths.run_check_file) - + # Create shared objects shared_state = toomanyobjs.TooMany() - Thread(target=shared_state.get(apiservers.ClientAPI).start, daemon=True, name='client HTTP API').start() - Thread(target=shared_state.get(apiservers.PublicAPI).start, daemon=True, name='public HTTP API').start() + Thread(target=shared_state.get(apiservers.ClientAPI).start, + daemon=True, name='client HTTP API').start() + if not offline_mode: + Thread(target=shared_state.get(apiservers.PublicAPI).start, + daemon=True, name='public HTTP API').start() - # Init run time tester (ensures Onionr is running right, for testing purposes) + # Init run time tester + # (ensures Onionr is running right, for testing purposes) shared_state.get(runtests.OnionrRunTestManager) shared_state.get(serializeddata.SerializedData) - shared_state.share_object() # share the parent object to the threads + shared_state.share_object() # share the parent object to the threads apiHost = '' while apiHost == '': @@ -70,59 +93,73 @@ def daemon(): # print nice header thing :) if config.get('general.display_header', True): logoheader.header() - version.version(verbosity = 5, function = logger.info) + version.version(verbosity=5, function=logger.info) logger.debug('Python version %s' % platform.python_version()) if onionrvalues.DEVELOPMENT_MODE: - logger.warn('Development mode enabled', timestamp = False, terminal=True) + logger.warn('Development mode enabled', timestamp=False, terminal=True) - net = NetController(config.get('client.public.port', 59497), apiServerIP=apiHost) + net = NetController(config.get('client.public.port', 59497), + apiServerIP=apiHost) shared_state.add(net) - logger.info('Tor is starting...', terminal=True) - if not net.startTor(): - localcommand.local_command('shutdown') - cleanup.delete_run_files() - sys.exit(1) - if len(net.myID) > 0 and config.get('general.security_level', 1) == 0: - logger.debug('Started .onion service: %s' % (logger.colors.underline + net.myID)) - else: - logger.debug('.onion service disabled') - logger.info('Using public key: %s' % (logger.colors.underline + getourkeypair.get_keypair()[0][:52])) + if not offline_mode: + logger.info('Tor is starting...', terminal=True) + if not net.startTor(): + localcommand.local_command('shutdown') + cleanup.delete_run_files() + sys.exit(1) + if len(net.myID) > 0 and config.get('general.security_level', 1) == 0: + logger.debug('Started .onion service: %s' % + (logger.colors.underline + net.myID)) + else: + logger.debug('.onion service disabled') + + logger.info('Using public key: %s' % + (logger.colors.underline + + getourkeypair.get_keypair()[0][:52])) try: time.sleep(1) except KeyboardInterrupt: pass - events.event('init', threaded = False) + events.event('init', threaded=False) events.event('daemon_start') communicator.startCommunicator(shared_state) localcommand.local_command('shutdown') - net.killTor() + if not offline_mode: + net.killTor() + try: - time.sleep(5) # Time to allow threads to finish, if not any "daemon" threads will be slaughtered http://docs.python.org/library/threading.html#threading.Thread.daemon + # Time to allow threads to finish, + # if not any "daemon" threads will be slaughtered + # http://docs.python.org/library/threading.html#threading.Thread.daemon + time.sleep(5) except KeyboardInterrupt: pass cleanup.delete_run_files() + def _ignore_sigint(sig, frame): - '''This space intentionally left blank''' + """This space intentionally left blank""" return + def kill_daemon(): - ''' + """ Shutdown the Onionr daemon (communicator) - ''' - logger.warn('Stopping the running daemon...', timestamp = False, terminal=True) + """ + logger.warn('Stopping the running daemon...', timestamp=False, + terminal=True) try: # On platforms where we can, fork out to prevent locking try: pid = os.fork() if pid != 0: return - except (AttributeError, OSError) as e: pass + except (AttributeError, OSError): pass events.event('daemon_stop') net = NetController(config.get('client.port', 59496)) @@ -133,15 +170,22 @@ def kill_daemon(): net.killTor() except Exception as e: - logger.error('Failed to shutdown daemon: ' + str(e), error = e, timestamp = False, terminal=True) + logger.error('Failed to shutdown daemon: ' + str(e), + error=e, timestamp=False, terminal=True) return + kill_daemon.onionr_help = "Gracefully stops the Onionr API servers" + def start(input: bool = False, override: bool = False): - """If no lock file, make one and start onionr, error if there is and its not overridden""" + """If no lock file, make one and start onionr, + error if there is and its not overridden""" if os.path.exists(filepaths.lock_file) and not override: - logger.fatal('Cannot start. Daemon is already running, or it did not exit cleanly.\n(if you are sure that there is not a daemon running, delete onionr.lock & try again).', terminal=True) + logger.fatal('Cannot start. Daemon is already running,' + + ' or it did not exit cleanly.\n' + + ' (if you are sure that there is not a daemon running,' + + ' delete onionr.lock & try again).', terminal=True) else: if not onionrvalues.DEVELOPMENT_MODE: lockFile = open(filepaths.lock_file, 'w') @@ -153,4 +197,5 @@ def start(input: bool = False, override: bool = False): except FileNotFoundError: pass + start.onionr_help = "Start Onionr node (public and clients API servers)"