def set_http(self): # import circle_http str = circle_http.status() if self.config.get("http") == 0: if self.http_running: str = circle_http.stop() return str elif self.config.get("http") == 2: if not self.http_running: str = circle_http.start("local", self) return str elif self.config.get("http") == 1: if not self.http_running: str = circle_http.start("remote", self) return str
def run(self, initial_command=None, proxy_mode="none"): """ This is the daemon mainloop. """ self.thread_list = utility.thread_list if proxy_mode == "always" or (proxy_mode == "auto" and node.need_proxy()): print _("Circle needs to run a proxy (see documentation).") print print _("SSH to where ([email protected])? "), proxy_host = sys.stdin.readline().strip() proxy_obj = proxy.Proxy(proxy_host) else: proxy_obj = None if sys.platform == "win32" or initial_command == "no-fork\n": fork = 0 initial_command = "gtk\n" else: fork = 1 if fork: branch = os.fork() else: branch = 0 if not branch: # Note: 'print' statements are not allowed within this branch of the fork # os.setsid() sys.stdin.close() dev_null = open("/dev/null", "wt") sys.stdout.close() sys.stderr.close() sys.stdout = dev_null sys.stderr = dev_null if fork: com_sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) com_sock_file = os.path.join(utility.config_dir, "daemon_socket") try: os.unlink(com_sock_file) except OSError: pass com_sock.bind(com_sock_file) com_sock.listen(5) self.start() self.node = node.Node() self.node.start(proxy_obj) self.file_server = file_server.File_server(self.node) self.cache = cache.Cache(self.node) self.interface = None self.config = utility.get_config("daemon", {}) for pair in [ ("public_dir", ""), ("private_dir", ""), ("download_dir", ""), ("stay_alive", 1), ("http", 0), ("publish_apt", 0), ("keep_sharing", 0), ]: if not self.config.has_key(pair[0]): self.config[pair[0]] = pair[1] self.file_server.set_roots(self.config) self.file_server.start() self.cache.start() # if fork: # def signal_handler(signal, frame): # raise error.Error('signal') # else: # def signal_handler(signal, frame): # print _("Received signal %d.") % signal # for s in exit_signals: # signal.signal(s, signal_handler) self.accept_gtk = 1 self.stopping = 0 self.http_running = 0 self.set_http() self.interface_running = 0 if not fork: from ui_gtk import circle_gtk self.gtk_interface_requested = 1 utility.Task(circle_gtk.gui_task, self, fork).start() output = sys.stdout else: self.gtk_interface_requested = 0 gui_task_launched = 0 while not self.stopping: # at this point it cannot be 'text' if initial_command: command = initial_command initial_command = None # if command == 'text\n': input = sys.stdin output = sys.stdout connection = None else: try: while not select.select([com_sock], [], [], 0.1)[0]: if self.stopping: break try: utility._daemon_action_timeout() except: apply(utility.report_bug, sys.exc_info()) # if stopping we need to exit the 2nd loop too: if self.stopping: break connection = com_sock.accept()[0] input = connection.makefile("rt") output = connection.makefile("wt") command = input.readline() except: apply(utility.report_bug, sys.exc_info()) continue if command == "quit\n": if self.interface_running: output.write("Shutting down interface...\n") self.interface.shutdown() self.stopping = 1 break if command == "shutdown\n": if self.interface_running: output.write("Shutting down interface...") self.interface.shutdown() else: output.write("No interface running.") elif command == "sync config\n": self.config = utility.get_config("daemon", {}) self.file_server.set_roots(self.config) output.write(_("Active circle daemon has updated its settings.")) elif command == "status\n": str = self.status() output.write(str) elif command == "activate\n": self.node.activate_hashtable() output.write("Hashtable activated") elif command == "gtk\n": if not self.accept_gtk: output.write("cannot run gtk interface: problem with gtk threads") else: if not gui_task_launched: from ui_gtk import circle_gtk utility.Task(circle_gtk.gui_task, self, fork).start() gui_task_launched = 1 if not self.interface_running: self.gtk_interface_requested = 1 else: output.write("Circle interface already running") elif command == "text\n": def text_task(self, input, output): from ui_text import circle_text import settings settings.terminal_encoding = sys.getdefaultencoding() self.interface = circle_text.Circle_text(self, input, output) self.interface.run_main() self.interface_running = 0 # try: input.close() if connection: connection.close() output.close() # except: # pass if not self.interface_running: self.interface_running = 1 output.write("Starting text interface\n") utility.Task(text_task, self, input, output).start() else: output.write("Circle interface already running") input.close() if connection: connection.close() output.close() elif command == "debug\n": for item in threading.enumerate(): output.write(repr(item) + "\n\n") elif command[0:6] == "search": utility.Task(search_task, self, command[7:-1], input, output, connection).start() elif command[0:4] == "find": utility.Task(find_task, self, command[5:-1], input, output, connection).start() elif command[0:4] == "get ": utility.Task(get_file_task, self, command[4:38], input, output, connection).start() elif command == "http local\n": self.config["http"] = 2 output.write(self.set_http()) elif command == "http remote\n": self.config["http"] = 1 output.write(self.set_http()) elif command == "http stop\n": self.config["http"] = 0 output.write(self.set_http()) elif command[0:7] == "connect": try: address = utility.parse_address(self.node.address, command[8:-1]) self.node.probe(address) except: output.write(sys.exc_info()[1]) else: output.write(_("Huh?")) if command.split()[0] not in ["search", "find", "get", "text"]: try: input.close() connection.close() output.close() except: pass if self.accept_gtk and self.gtk_interface_requested: # print "waiting for interface..." while self.gtk_interface_requested: utility._daemon_action_timeout() time.sleep(0.01) # print "interface is down" # utility.threadnice_mainloop_stop() # except error.Error: # signal, eg ^C, SIGTERM # pass for s in exit_signals: signal.signal(s, signal.SIG_IGN) self.cache.stop() self.file_server.stop() if self.node.hashtable_running: initial_links = len(self.node.links) self.node.deactivate_hashtable() while self.node.hashtable_offloaders or self.node.links: utility._daemon_action_timeout() time.sleep(0.01) output.write( "offloading : %.1f%% \r" % ((initial_links - len(self.node.links)) * 100.0 / initial_links) ) output.flush() # todo: ensure that this terminates # node.stop() needs to be called, interrupt is bad if self.interface: if self.interface.name_server.disconnect_threads: print "disconnecting identity..." while self.interface.name_server.disconnect_threads: time.sleep(0.01) utility._daemon_action_timeout() print "stopping node" self.node.stop() if fork: com_sock.close() os.unlink(com_sock_file) if self.http_running: circle_http.stop() if self.stopping: self.running = 0 try: if fork: output.write(_("Circle daemon stopped.")) input.close() output.flush() output.close() connection.close() except: pass self.stop() else: print _("Circle daemon started.")