2019-03-09 06:37:57 +00:00
'''
2019-06-12 20:12:56 +00:00
Onionr - Private P2P Communication
2019-03-09 06:37:57 +00:00
2019-09-12 19:50:06 +00:00
launch the api servers and communicator
2019-03-09 06:37:57 +00:00
'''
'''
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 < https : / / www . gnu . org / licenses / > .
'''
2019-04-20 22:55:54 +00:00
import os , time , sys , platform , sqlite3 , signal
2019-03-08 01:08:06 +00:00
from threading import Thread
2019-08-02 23:00:04 +00:00
import toomanyobjs
2019-07-31 05:10:28 +00:00
import config , apiservers , logger , communicator
2019-09-21 22:45:46 +00:00
from onionrplugins import onionrevents as events
2019-03-08 01:08:06 +00:00
from netcontroller import NetController
2019-06-23 17:41:07 +00:00
from onionrutils import localcommand
2019-07-19 04:59:44 +00:00
import filepaths
2019-07-17 22:41:33 +00:00
from coredb import daemonqueue
2019-07-31 05:10:28 +00:00
from etc import onionrvalues , cleanup
2019-07-20 00:01:16 +00:00
from onionrcrypto import getourkeypair
2019-07-30 05:19:22 +00:00
from utils import hastor , logoheader
2019-07-31 05:10:28 +00:00
from . import version
2019-08-05 04:08:56 +00:00
import serializeddata
2019-07-27 02:42:55 +00:00
2019-07-31 05:10:28 +00:00
def _proper_shutdown ( ) :
2019-07-19 04:59:44 +00:00
localcommand . local_command ( ' shutdown ' )
2019-06-15 01:31:01 +00:00
sys . exit ( 1 )
2019-07-31 05:10:28 +00:00
def daemon ( ) :
2019-03-08 01:08:06 +00:00
'''
Starts the Onionr communication daemon
'''
2019-07-27 02:42:55 +00:00
if not hastor . has_tor ( ) :
logger . error ( " Tor is not present in system path or Onionr directory " , terminal = True )
sys . exit ( 1 )
2019-03-08 01:08:06 +00:00
# remove runcheck if it exists
2019-07-19 04:59:44 +00:00
if os . path . isfile ( filepaths . run_check_file ) :
2019-03-08 01:08:06 +00:00
logger . debug ( ' Runcheck file found on daemon start, deleting in advance. ' )
2019-07-19 04:59:44 +00:00
os . remove ( filepaths . run_check_file )
2019-08-04 04:52:57 +00:00
# Create shared object
shared_state = toomanyobjs . TooMany ( )
2019-03-08 01:08:06 +00:00
2019-09-12 19:50:06 +00:00
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 ( )
2019-08-05 04:08:56 +00:00
shared_state . get ( serializeddata . SerializedData )
2019-08-04 04:52:57 +00:00
shared_state . share_object ( ) # share the parent object to the threads
2019-03-08 01:08:06 +00:00
apiHost = ' '
while apiHost == ' ' :
try :
2019-07-19 04:59:44 +00:00
with open ( filepaths . public_API_host_file , ' r ' ) as hostFile :
2019-03-08 01:08:06 +00:00
apiHost = hostFile . read ( )
except FileNotFoundError :
pass
time . sleep ( 0.5 )
2019-06-19 20:29:27 +00:00
logger . raw ( ' ' , terminal = True )
# print nice header thing :)
2019-07-31 05:10:28 +00:00
if config . get ( ' general.display_header ' , True ) :
2019-07-30 05:19:22 +00:00
logoheader . header ( )
2019-07-31 05:10:28 +00:00
version . version ( verbosity = 5 , function = logger . info )
2019-06-19 20:29:27 +00:00
logger . debug ( ' Python version %s ' % platform . python_version ( ) )
2019-07-31 05:10:28 +00:00
if onionrvalues . DEVELOPMENT_MODE :
2019-06-26 00:15:04 +00:00
logger . warn ( ' Development mode enabled ' , timestamp = False , terminal = True )
2019-08-04 04:52:57 +00:00
2019-07-31 05:10:28 +00:00
net = NetController ( config . get ( ' client.public.port ' , 59497 ) , apiServerIP = apiHost )
2019-08-04 04:52:57 +00:00
shared_state . add ( net )
2019-06-19 20:29:27 +00:00
logger . info ( ' Tor is starting... ' , terminal = True )
2019-03-08 01:08:06 +00:00
if not net . startTor ( ) :
2019-07-19 04:59:44 +00:00
localcommand . local_command ( ' shutdown ' )
2019-03-08 01:08:06 +00:00
sys . exit ( 1 )
2019-07-31 05:10:28 +00:00
if len ( net . myID ) > 0 and config . get ( ' general.security_level ' , 1 ) == 0 :
2019-03-08 01:08:06 +00:00
logger . debug ( ' Started .onion service: %s ' % ( logger . colors . underline + net . myID ) )
else :
logger . debug ( ' .onion service disabled ' )
2019-09-12 19:50:06 +00:00
logger . info ( ' Using public key: %s ' % ( logger . colors . underline + getourkeypair . get_keypair ( ) [ 0 ] [ : 52 ] ) )
2019-06-15 01:31:01 +00:00
try :
time . sleep ( 1 )
except KeyboardInterrupt :
2019-07-31 05:10:28 +00:00
_proper_shutdown ( )
2019-08-04 04:52:57 +00:00
events . event ( ' init ' , threaded = False )
2019-07-31 05:10:28 +00:00
events . event ( ' daemon_start ' )
2019-08-04 04:52:57 +00:00
communicator . startCommunicator ( shared_state )
2019-03-08 01:08:06 +00:00
2019-07-19 04:59:44 +00:00
localcommand . local_command ( ' shutdown ' )
2019-04-20 22:55:54 +00:00
2019-03-08 01:08:06 +00:00
net . killTor ( )
2019-08-08 06:25:48 +00:00
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
except KeyboardInterrupt :
pass
2019-07-31 05:10:28 +00:00
cleanup . delete_run_files ( )
2019-03-08 01:08:06 +00:00
2019-04-20 22:55:54 +00:00
def _ignore_sigint ( sig , frame ) :
2019-07-31 05:10:28 +00:00
''' This space intentionally left blank '''
2019-04-20 22:55:54 +00:00
return
2019-07-31 05:10:28 +00:00
def kill_daemon ( ) :
2019-03-08 01:08:06 +00:00
'''
2019-09-12 19:50:06 +00:00
Shutdown the Onionr daemon ( communicator )
2019-03-08 01:08:06 +00:00
'''
2019-06-19 20:29:27 +00:00
logger . warn ( ' Stopping the running daemon... ' , timestamp = False , terminal = True )
2019-03-08 01:08:06 +00:00
try :
2019-07-31 05:10:28 +00:00
events . event ( ' daemon_stop ' )
net = NetController ( config . get ( ' client.port ' , 59496 ) )
2019-03-08 01:08:06 +00:00
try :
2019-07-24 18:23:31 +00:00
daemonqueue . daemon_queue_add ( ' shutdown ' )
2019-03-08 01:08:06 +00:00
except sqlite3 . OperationalError :
pass
net . killTor ( )
except Exception as e :
2019-07-24 18:23:31 +00:00
logger . error ( ' Failed to shutdown daemon: ' + str ( e ) , error = e , timestamp = False , terminal = True )
2019-03-09 01:57:44 +00:00
return
2019-09-21 05:06:49 +00:00
kill_daemon . onionr_help = " Gracefully stops the Onionr API servers "
2019-09-12 19:50:06 +00:00
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 """
2019-03-09 01:57:44 +00:00
if os . path . exists ( ' .onionr-lock ' ) and not override :
2019-06-19 20:29:27 +00:00
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 )
2019-03-09 01:57:44 +00:00
else :
2019-07-31 05:10:28 +00:00
if not onionrvalues . DEVELOPMENT_MODE :
2019-03-09 01:57:44 +00:00
lockFile = open ( ' .onionr-lock ' , ' w ' )
lockFile . write ( ' ' )
lockFile . close ( )
2019-07-31 05:10:28 +00:00
daemon ( )
if not onionrvalues . DEVELOPMENT_MODE :
2019-03-09 01:57:44 +00:00
try :
os . remove ( ' .onionr-lock ' )
except FileNotFoundError :
2019-09-21 05:06:49 +00:00
pass
start . onionr_help = " Start Onionr node (public and clients API servers) "