def run_stop(parser, opts, extra_args): magic_string = bencode(["hello", []]) + bencode(["shutdown-server"]) display_name = pick_display(parser, extra_args) sock, local = client_sock(parser, opts, display_name) sock.sendall(magic_string) while sock.recv(4096): pass if local: sockdir = DotXpra() for i in xrange(6): final_state = sockdir.server_state(display_name) if final_state is DotXpra.LIVE: time.sleep(0.5) else: break if final_state is DotXpra.DEAD: print "xpra at %s has exited." % display_name sys.exit(0) elif final_state is DotXpra.UNKNOWN: print ("How odd... I'm not sure what's going on with xpra at %s" % display_name) sys.exit(1) elif final_state is DotXpra.LIVE: print "Failed to shutdown xpra at %s" % display_name sys.exit(1) else: assert False else: print "Sent shutdown command"
def client_sock(parser, opts, display_name): if display_name.startswith("ssh:"): sshspec = display_name[len("ssh:"):] if ":" in sshspec: (host, display) = sshspec.split(":", 1) display_args = [":" + display] else: host = sshspec display_args = [] (a, b) = socket.socketpair() if opts.remote_xpra is not None: remote_xpra = opts.remote_xpra.split() else: remote_xpra = ["$HOME/.xpra/run-xpra"] p = subprocess.Popen(["ssh", host, "-e", "none"] + remote_xpra + ["_proxy"] + display_args, stdin=b.fileno(), stdout=b.fileno(), bufsize=0) return a, False elif display_name.startswith(":"): sockdir = DotXpra() sock = socket.socket(socket.AF_UNIX) sock.connect(sockdir.socket_path(display_name)) return sock, True elif display_name.startswith("tcp:"): host_spec = display_name[4:] (host, port) = host_spec.split(":", 1) if host == "": host = "127.0.0.1" sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.connect((host, int(port))) return sock, True else: parser.error("unknown format for display name")
def create_unix_domain_socket(display_name, upgrading): dotxpra = DotXpra() sockpath = dotxpra.server_socket_path(display_name, upgrading) listener = socket.socket(socket.AF_UNIX) listener.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) listener.bind(sockpath) return listener
def run_stop(parser, opts, extra_args): assert "gtk" not in sys.modules magic_string = bencode( ["hello", { "__prerelease_version": xpra.__version__ }]) + bencode(["shutdown-server"]) display_desc = pick_display(parser, opts, extra_args) conn = connect_or_fail(display_desc) while magic_string: magic_string = magic_string[conn.write(magic_string):] while conn.read(4096): pass if display_desc["local"]: sockdir = DotXpra() for _ in xrange(6): final_state = sockdir.server_state(display_desc["display"]) if final_state is DotXpra.LIVE: time.sleep(0.5) else: break if final_state is DotXpra.DEAD: print("xpra at %s has exited." % display_desc["display"]) sys.exit(0) elif final_state is DotXpra.UNKNOWN: print("How odd... I'm not sure what's going on with xpra at %s" % display_desc["display"]) sys.exit(1) elif final_state is DotXpra.LIVE: print("Failed to shutdown xpra at %s" % display_desc["display"]) sys.exit(1) else: assert False else: print("Sent shutdown command")
def __init__(self): dotxpra = DotXpra() display = os.environ.get("DISPLAY") from xpra.scripts.config import make_defaults_struct opts = make_defaults_struct() target = dotxpra.socket_path(display) log.info("attempting to connect to socket: %s", target) sock = socket.socket(socket.AF_UNIX) sock.connect(target) conn = SocketConnection(sock, sock.getsockname(), sock.getpeername(), target, "scroll-test") log.info("successfully created our socket connection: %s", conn) self.server = ServerMessenger(conn, opts) self.vscroll_events = maxdeque(1000) self.hscroll_events = maxdeque(1000) browser = WebBrowser() #hook some events: browser.content_tabs.connect("focus-view-title-changed", self.title_changed) vscroll_listeners.append(self.vscroll) hscroll_listeners.append(self.hscroll) #the things we tune: self.quality = -1 self.speed = -1 self.encoding = None self.strict = False
def run_proxy(parser, opts, script_file, args, start_server=False): from xpra.proxy import XpraProxy assert "gtk" not in sys.modules if start_server: assert len(args) == 1 display_name = args[0] #we must use a subprocess to avoid messing things up - yuk cmd = [script_file, "start"] + args if opts.start_child and len(opts.start_child) > 0: for x in opts.start_child: cmd.append("--start-child=%s" % x) if opts.exit_with_children: cmd.append("--exit-with-children") def setsid(): os.setsid() Popen(cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE, preexec_fn=setsid) dotxpra = DotXpra() start = time.time() while dotxpra.server_state(display_name, 1) != DotXpra.LIVE: if time.time() - start > 5: warn("server failed to start after %.1f seconds - sorry!" % (time.time() - start)) return time.sleep(0.10) server_conn = connect_or_fail(pick_display(parser, opts, args)) app = XpraProxy( TwoFileConnection(sys.stdout, sys.stdin, info="stdin/stdout"), server_conn) signal.signal(signal.SIGINT, app.quit) signal.signal(signal.SIGTERM, app.quit) app.run() return 0
def setup_local_socket(socket_dir, socket_dirs, display_name, clobber, mmap_group, socket_permissions): if sys.platform.startswith("win"): return None, None from xpra.log import Logger log = Logger("network") dotxpra = DotXpra(socket_dir or socket_dirs[0]) try: dotxpra.mksockdir() display_name = normalize_local_display_name(display_name) sockpath = dotxpra.socket_path(display_name) except Exception as e: raise InitException("socket path error: %s" % e) setup_server_socket_path(dotxpra, sockpath, display_name, clobber, wait_for_unknown=5) sock = create_unix_domain_socket(sockpath, mmap_group, socket_permissions) def cleanup_socket(): log.info("removing socket %s", sockpath) try: os.unlink(sockpath) except: pass _cleanups.append(cleanup_socket) return ("unix-domain", sock, sockpath), cleanup_socket
def run_stop(parser, opts, extra_args): assert "gtk" not in sys.modules magic_string = bencode(["hello", {"__prerelease_version": xpra.__version__}]) + bencode(["shutdown-server"]) display_desc = pick_display(parser, opts, extra_args) conn = connect_or_fail(display_desc) while magic_string: magic_string = magic_string[conn.write(magic_string):] while conn.read(4096): pass if display_desc["local"]: sockdir = DotXpra(opts.sockdir) for _ in xrange(6): final_state = sockdir.server_state(display_desc["display"]) if final_state is DotXpra.LIVE: break time.sleep(0.5) if final_state is DotXpra.DEAD: print("xpra at %s has exited." % display_desc["display"]) sys.exit(0) elif final_state is DotXpra.UNKNOWN: print("How odd... I'm not sure what's going on with xpra at %s" % display_desc["display"]) sys.exit(1) elif final_state is DotXpra.LIVE: print("Failed to shutdown xpra at %s" % display_desc["display"]) sys.exit(1) else: assert False, "invalid state: %s" % final_state else: print("Sent shutdown command")
def create_control_socket(self): assert self.socket_dir dotxpra = DotXpra(self.socket_dir) sockpath = dotxpra.socket_path(":proxy-%s" % os.getpid()) state = dotxpra.get_server_state(sockpath) if state in (DotXpra.LIVE, DotXpra.UNKNOWN): log.warn( "You already have a proxy server running at %s, the control socket will not be created!", sockpath) return False try: sock = create_unix_domain_socket(sockpath, None, 0o600) sock.listen(5) except Exception as e: log("create_unix_domain_socket failed for '%s'", sockpath, exc_info=True) log.error("Error: failed to setup control socket '%s':", sockpath) log.error(" %s", e) return False self.control_socket = sock self.control_socket_path = sockpath log.info("proxy instance now also available using unix domain socket:") log.info(" %s", self.control_socket_path) return True
def run_proxy(parser, opts, script_file, args, start_server=False): from xpra.proxy import XpraProxy assert "gtk" not in sys.modules if start_server: assert len(args)==1 display_name = args[0] #we must use a subprocess to avoid messing things up - yuk cmd = [script_file, "start"]+args if opts.start_child and len(opts.start_child)>0: for x in opts.start_child: cmd.append("--start-child=%s" % x) if opts.exit_with_children: cmd.append("--exit-with-children") def setsid(): os.setsid() Popen(cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE, preexec_fn=setsid) dotxpra = DotXpra() start = time.time() while dotxpra.server_state(display_name, 1)!=DotXpra.LIVE: if time.time()-start>5: warn("server failed to start after %.1f seconds - sorry!" % (time.time()-start)) return time.sleep(0.10) server_conn = connect_or_fail(pick_display(parser, opts, args)) app = XpraProxy(TwoFileConnection(sys.stdout, sys.stdin, info="stdin/stdout"), server_conn) signal.signal(signal.SIGINT, app.quit) signal.signal(signal.SIGTERM, app.quit) app.run() return 0
def __init__(self): dotxpra = DotXpra() display = os.environ.get("DISPLAY") from xpra.scripts.config import make_defaults_struct opts = make_defaults_struct() target = dotxpra.socket_path(display) log.info("attempting to connect to socket: %s", target) sock = socket.socket(socket.AF_UNIX) sock.connect(target) conn = SocketConnection(sock, sock.getsockname(), sock.getpeername(), target, "scroll-test") log.info("successfully created our socket connection: %s", conn) self.server = ServerMessenger(conn, opts) self.vscroll_events = deque(maxlen=1000) self.hscroll_events = deque(maxlen=1000) browser = WebBrowser() #hook some events: browser.content_tabs.connect("focus-view-title-changed", self.title_changed) vscroll_listeners.append(self.vscroll) hscroll_listeners.append(self.hscroll) #the things we tune: self.quality = -1 self.speed = -1 self.encoding = None self.strict = False
def guess_xpra_display(socket_dir, socket_dirs): dotxpra = DotXpra(socket_dir, socket_dirs) results = dotxpra.sockets() live = [display for state, display in results if state==DotXpra.LIVE] if len(live)==0: raise InitException("no existing xpra servers found") if len(live)>1: raise InitException("too many existing xpra servers found, cannot guess which one to use") return live[0]
def get_sessions(self): uid = self.get_uid() gid = self.get_gid() try: sockdir = DotXpra(socket_dir, actual_username=self.username) results = sockdir.sockets(check_uid=uid) displays = [display for state, display in results if state==DotXpra.LIVE] except Exception, e: log.error("cannot get socker directory for %s: %s", self.username, e) displays = []
def guess_xpra_display(socket_dir, socket_dirs): dotxpra = DotXpra(socket_dir, socket_dirs) results = dotxpra.sockets() live = [display for state, display in results if state == DotXpra.LIVE] if len(live) == 0: raise InitException("no existing xpra servers found") if len(live) > 1: raise InitException( "too many existing xpra servers found, cannot guess which one to use" ) return live[0]
def get_sessions(self): uid = self.get_uid() gid = self.get_gid() try: sockdir = DotXpra(socket_dir, socket_dirs, actual_username=self.username) results = sockdir.sockets(check_uid=uid) displays = [display for state, display in results if state==DotXpra.LIVE] except Exception as e: log.error("Error: cannot get socket directory for '%s':", self.username) log.error(" %s", e) displays = [] return uid, gid, displays, {}, {}
def get_sessions(self): uid = self.get_uid() gid = self.get_gid() try: sockdir = DotXpra(socket_dir, actual_username=self.username) results = sockdir.sockets(check_uid=uid) displays = [display for state, display in results if state==DotXpra.LIVE] except Exception as e: log.error("Error: cannot get socket directory for '%s':", self.username) log.error(" %s", e) displays = [] return uid, gid, displays, {}, {}
def create_control_socket(self): dotxpra = DotXpra(self.socket_dir) name = "proxy-%s" % os.getpid() sockpath = dotxpra.norm_make_path(name, dotxpra.sockdir()) state = dotxpra.get_server_state(sockpath) if state in (DotXpra.LIVE, DotXpra.UNKNOWN): log.warn("You already have a proxy server running at %s, the control socket will not be created!", sockpath) return False try: sock = create_unix_domain_socket(sockpath, None) sock.listen(5) except Exception, e: log.warn("failed to setup control socket %s: %s", sockpath, e) return False
def test_DoS(client_class_constructor, args): """ utility method for running DoS tests See: test_DoS_*_client.py """ assert len(args)==2, "usage: test_DoS_client :DISPLAY" import socket from xpra.dotxpra import DotXpra from xpra.bytestreams import SocketConnection import logging logging.root.setLevel(logging.DEBUG) logging.root.addHandler(logging.StreamHandler(sys.stderr)) opts = AdHocStruct() opts.password_file = "" opts.encoding = "rgb24" opts.jpegquality = 0 display = sys.argv[1] target = DotXpra().socket_path(display) print("will attempt to connect to socket: %s" % target) sock = socket.socket(socket.AF_UNIX) sock.connect(target) conn = SocketConnection(sock) print("socket connection=%s" % conn) app = client_class_constructor(conn, opts) try: app.run() finally: app.cleanup() print("ended") print("")
def create_control_socket(self): dotxpra = DotXpra(self.socket_dir) name = "proxy-%s" % os.getpid() sockpath = dotxpra.norm_make_path(name, dotxpra.sockdir()) state = dotxpra.get_server_state(sockpath) if state in (DotXpra.LIVE, DotXpra.UNKNOWN): log.warn( "You already have a proxy server running at %s, the control socket will not be created!", sockpath) return False try: sock = create_unix_domain_socket(sockpath, None) sock.listen(5) except Exception, e: log.warn("failed to setup control socket %s: %s", sockpath, e) return False
def pick_display(parser, opts, extra_args): if len(extra_args) == 0: # Pick a default server sockdir = DotXpra(opts.sockdir or get_default_socket_dir()) servers = sockdir.sockets() live_servers = [display for (state, display) in servers if state is DotXpra.LIVE] if len(live_servers) == 0: parser.error("cannot find a live server to connect to") elif len(live_servers) == 1: return parse_display_name(parser, opts, live_servers[0]) else: parser.error("there are multiple servers running, please specify") elif len(extra_args) == 1: return parse_display_name(parser, opts, extra_args[0]) else: parser.error("too many arguments")
def test_DoS(client_class_constructor, args): """ utility method for running DoS tests See: test_DoS_*_client.py """ assert len(args) == 2, "usage: test_DoS_client :DISPLAY" log.enable_debug() opts = make_defaults_struct() opts.password_file = "" opts.encoding = "rgb24" opts.jpegquality = 70 opts.quality = 70 opts.compression_level = 1 opts.encryption = "" display = sys.argv[1] target = DotXpra().socket_path(display) print("will attempt to connect to socket: %s" % target) sock = socket.socket(socket.AF_UNIX) sock.connect(target) conn = SocketConnection(sock, sock.getsockname(), sock.getpeername(), "test_DoS") print("socket connection=%s" % conn) app = client_class_constructor(conn, opts) try: app.run() finally: app.cleanup() print("ended") print("")
def show_final_state(display): sockdir = DotXpra(opts.sockdir) for _ in range(6): final_state = sockdir.server_state(display) if final_state is DotXpra.LIVE: time.sleep(0.5) if final_state is DotXpra.DEAD: print("xpra at %s has exited." % display) return 0 elif final_state is DotXpra.UNKNOWN: print("How odd... I'm not sure what's going on with xpra at %s" % display) return 1 elif final_state is DotXpra.LIVE: print("Failed to shutdown xpra at %s" % display) return 1 else: assert False, "invalid state: %s" % final_state return 1
def create_control_socket(self): dotxpra = DotXpra(self.socket_dir) name = "proxy-%s" % os.getpid() sockpath = dotxpra.norm_make_path(name, dotxpra.sockdir()) state = dotxpra.get_server_state(sockpath) if state in (DotXpra.LIVE, DotXpra.UNKNOWN): log.warn("You already have a proxy server running at %s, the control socket will not be created!", sockpath) return False try: sock = create_unix_domain_socket(sockpath, None, 0o600) sock.listen(5) except: log.warn("failed to setup control socket %s", sockpath, exc_info=True) return False self.control_socket = sock self.control_socket_path = sockpath log.info("proxy instance now also available using unix domain socket: %s", self.control_socket_path) return True
def pick_display(parser, opts, extra_args): if len(extra_args) == 0: # Pick a default server sockdir = DotXpra(opts.sockdir or get_default_socket_dir()) servers = sockdir.sockets() live_servers = [ display for (state, display) in servers if state is DotXpra.LIVE ] if len(live_servers) == 0: parser.error("cannot find a live server to connect to") elif len(live_servers) == 1: return parse_display_name(parser, opts, live_servers[0]) else: parser.error("there are multiple servers running, please specify") elif len(extra_args) == 1: return parse_display_name(parser, opts, extra_args[0]) else: parser.error("too many arguments")
def run_list(parser, opts, extra_args): if extra_args: parser.error("too many arguments for mode") sockdir = DotXpra() results = sockdir.sockets() if not results: sys.stdout.write("No xpra sessions found\n") else: sys.stdout.write("Found the following xpra sessions:\n") for state, display in results: sys.stdout.write("\t%s session at %s" % (state, display)) if state is DotXpra.DEAD: try: os.unlink(sockdir.socket_path(display)) except OSError: pass else: sys.stdout.write(" (cleaned up)") sys.stdout.write("\n")
def run_proxy(parser, opts, script_file, args, mode): from xpra.server.proxy import XpraProxy assert "gtk" not in sys.modules if mode in ("_proxy_start", "_shadow_start"): #we must use a subprocess to avoid messing things up - yuk cmd = [script_file] if mode=="_proxy_start": cmd.append("start") assert len(args)==1, "proxy/shadow-start: expected 1 argument but got %s" % len(args) display_name = args[0] else: assert mode=="_shadow_start" cmd.append("shadow") if len(args)==1: #display_name was provided: display_name = args[0] else: display_name = guess_X11_display() cmd += args if opts.start_child and len(opts.start_child)>0: for x in opts.start_child: cmd.append("--start-child=%s" % x) if opts.exit_with_children: cmd.append("--exit-with-children") if opts.exit_with_client or mode=="_shadow_start": cmd.append("--exit-with-client") def setsid(): os.setsid() Popen(cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE, preexec_fn=setsid) dotxpra = DotXpra() start = time.time() while dotxpra.server_state(display_name, 1)!=DotXpra.LIVE: if time.time()-start>5: warn("server failed to start after %.1f seconds - sorry!" % (time.time()-start)) return time.sleep(0.10) server_conn = connect_or_fail(pick_display(parser, opts, args)) app = XpraProxy(TwoFileConnection(sys.stdout, sys.stdin, info="stdin/stdout"), server_conn) signal.signal(signal.SIGINT, app.quit) signal.signal(signal.SIGTERM, app.quit) app.run() return 0
def pick_display(parser, opts, extra_args): if len(extra_args) == 0: if not XPRA_LOCAL_SERVERS_SUPPORTED: parser.error("need to specify a display") # Pick a default server sockdir = DotXpra() servers = sockdir.sockets() live_servers = [ display for (state, display) in servers if state is DotXpra.LIVE ] if len(live_servers) == 0: parser.error("cannot find a live server to connect to") elif len(live_servers) == 1: return parse_display_name(parser, opts, live_servers[0]) else: parser.error("there are multiple servers running, please specify") elif len(extra_args) == 1: return parse_display_name(parser, opts, extra_args[0]) else: parser.error("too many arguments")
def pick_display(parser, opts, extra_args): if len(extra_args) == 0: # Pick a default server sockdir = DotXpra(opts.socket_dir or get_default_socket_dir()) servers = sockdir.sockets() live_servers = [display for (state, display) in servers if state is DotXpra.LIVE] if len(live_servers) == 0: if not LOCAL_SERVERS_SUPPORTED: parser.error("this installation does not support local servers, you must specify a remote display") parser.error("cannot find a live server to connect to") elif len(live_servers) == 1: return parse_display_name(parser.error, opts, live_servers[0]) else: parser.error("there are multiple servers running, please specify") elif len(extra_args) == 1: return parse_display_name(parser.error, opts, extra_args[0]) else: parser.error("too many arguments")
def run_list(parser, opts, extra_args): assert "gtk" not in sys.modules if extra_args: parser.error("too many arguments for mode") sockdir = DotXpra() results = sockdir.sockets() if not results: sys.stdout.write("No xpra sessions found\n") else: sys.stdout.write("Found the following xpra sessions:\n") for state, display in results: sys.stdout.write("\t%s session at %s" % (state, display)) if state is DotXpra.DEAD: try: os.unlink(sockdir.socket_path(display)) except OSError: pass else: sys.stdout.write(" (cleaned up)") sys.stdout.write("\n")
def pick_display(parser, opts, extra_args): if len(extra_args) == 0: if not XPRA_LOCAL_SERVERS_SUPPORTED: parser.error("need to specify a display") # Pick a default server sockdir = DotXpra() servers = sockdir.sockets() live_servers = [display for (state, display) in servers if state is DotXpra.LIVE] if len(live_servers) == 0: parser.error("cannot find a live server to connect to") elif len(live_servers) == 1: return parse_display_name(parser, opts, live_servers[0]) else: parser.error("there are multiple servers running, please specify") elif len(extra_args) == 1: return parse_display_name(parser, opts, extra_args[0]) else: parser.error("too many arguments")
def create_control_socket(self): assert self.socket_dir dotxpra = DotXpra(self.socket_dir) sockpath = dotxpra.socket_path(":proxy-%s" % os.getpid()) state = dotxpra.get_server_state(sockpath) if state in (DotXpra.LIVE, DotXpra.UNKNOWN): log.warn("You already have a proxy server running at %s, the control socket will not be created!", sockpath) return False try: sock = create_unix_domain_socket(sockpath, None, 0o600) sock.listen(5) except Exception as e: log("create_unix_domain_socket failed for '%s'", sockpath, exc_info=True) log.error("Error: failed to setup control socket '%s':", sockpath) log.error(" %s", e) return False self.control_socket = sock self.control_socket_path = sockpath log.info("proxy instance now also available using unix domain socket:") log.info(" %s", self.control_socket_path) return True
def run_list(parser, opts, extra_args): assert "gtk" not in sys.modules if extra_args: parser.error("too many arguments for mode") sockdir = DotXpra(opts.socket_dir) results = sockdir.sockets() if not results: sys.stdout.write("No xpra sessions found\n") return 1 sys.stdout.write("Found the following xpra sessions:\n") for state, display in results: may_cleanup_socket(sockdir, state, display) #now, re-probe the "unknown" ones: unknown = [ display for state, display in results if state == DotXpra.UNKNOWN ] if len(unknown) > 0: sys.stdout.write("Re-probing unknown sessions: %s\n" % (", ".join(unknown))) counter = 0 while len(unknown) > 0 and counter < 5: time.sleep(1) counter += 1 probe_list = list(unknown) unknown = [] for display in probe_list: state = sockdir.server_state(display) if state is DotXpra.DEAD: may_cleanup_socket(sockdir, state, display) elif state is DotXpra.UNKNOWN: unknown.append(display) else: sys.stdout.write("\t%s session at %s\n" % (state, display)) #now cleanup those still unknown: clean_states = [DotXpra.DEAD, DotXpra.UNKNOWN] for display in unknown: state = sockdir.server_state(display) may_cleanup_socket(sockdir, state, display, clean_states=clean_states) return 0
def run_list(parser, opts, extra_args): assert "gtk" not in sys.modules if extra_args: parser.error("too many arguments for mode") sockdir = DotXpra(opts.socket_dir) results = sockdir.sockets() if not results: sys.stdout.write("No xpra sessions found\n") return 1 sys.stdout.write("Found the following xpra sessions:\n") for state, display in results: may_cleanup_socket(sockdir, state, display) #now, re-probe the "unknown" ones: unknown = [display for state, display in results if state==DotXpra.UNKNOWN] if len(unknown)>0: sys.stdout.write("Re-probing unknown sessions: %s\n" % (", ".join(unknown))) counter = 0 while len(unknown)>0 and counter<5: time.sleep(1) counter += 1 probe_list = list(unknown) unknown = [] for display in probe_list: state = sockdir.server_state(display) if state is DotXpra.DEAD: may_cleanup_socket(sockdir, state, display) elif state is DotXpra.UNKNOWN: unknown.append(display) else: sys.stdout.write("\t%s session at %s\n" % (state, display)) #now cleanup those still unknown: clean_states = [DotXpra.DEAD, DotXpra.UNKNOWN] for display in unknown: state = sockdir.server_state(display) may_cleanup_socket(sockdir, state, display, clean_states=clean_states) return 0
def create_control_socket(self): dotxpra = DotXpra(self.socket_dir) name = "proxy-%s" % os.getpid() sockpath = dotxpra.norm_make_path(name, dotxpra.sockdir()) state = dotxpra.get_server_state(sockpath) if state in (DotXpra.LIVE, DotXpra.UNKNOWN): log.warn( "You already have a proxy server running at %s, the control socket will not be created!", sockpath) return False try: sock = create_unix_domain_socket(sockpath, None, 0o600) sock.listen(5) except: log.warn("failed to setup control socket %s", sockpath, exc_info=True) return False self.control_socket = sock self.control_socket_path = sockpath log.info( "proxy instance now also available using unix domain socket: %s", self.control_socket_path) return True
def main(): print("main()") import gtk import signal from xpra.scripts.server import setup_local_socket, start_Xvfb, check_xvfb_process from xpra.scripts.main import parse_cmdline, configure_logging from xpra.dotxpra import DotXpra script_file = sys.argv[0] print("main() script_file=%s" % script_file) cmdline = sys.argv print("main() cmdline=%s" % cmdline) parser, opts, args, mode = parse_cmdline(cmdline) print("main() parser=%s" % parser) print("main() options=%s" % opts) print("main() mode=%s" % mode) display_name = args.pop(0) print("main() display=%s" % display_name) assert mode=="start", "only start mode is supported by this test server" configure_logging(opts, mode) dotxpra = DotXpra(opts.socket_dir) socket, cleanup_socket = setup_local_socket(dotxpra, display_name, False, opts.mmap_group) sockets = [socket] xvfb = start_Xvfb(opts.xvfb, display_name) assert check_xvfb_process(xvfb), "xvfb error" from xpra.x11.gtk_x11 import gdk_display_source assert gdk_display_source from xpra.x11.bindings.window_bindings import X11WindowBindings #@UnresolvedImport X11Window = X11WindowBindings() assert X11Window try: app = UnrespondingServer() app.init(opts) app.init_sockets(sockets) signal.signal(signal.SIGTERM, app.signal_quit) signal.signal(signal.SIGINT, app.signal_quit) return app.run() finally: for display in gtk.gdk.display_manager_get().list_displays(): display.close() xvfb.terminate() cleanup_socket()
def run_server(parser, opts, mode, xpra_file, extra_args): if opts.encoding and opts.encoding=="help": from xpra.codecs.loader import encodings_help from xpra.server.server_base import ServerBase print("xpra server supports the following encodings:\n * %s" % ("\n * ".join(encodings_help(ServerBase().encodings)))) return 0 assert mode in ("start", "upgrade", "shadow", "proxy") starting = mode == "start" upgrading = mode == "upgrade" shadowing = mode == "shadow" proxying = mode == "proxy" clobber = upgrading or opts.use_display #get the display name: if shadowing and len(extra_args)==0: from xpra.scripts.main import guess_X11_display display_name = guess_X11_display() else: if len(extra_args) != 1: parser.error("need exactly 1 extra argument") display_name = extra_args.pop(0) if not shadowing and not proxying: display_name_check(display_name) if not shadowing and not proxying and opts.exit_with_children and not opts.start_child: sys.stderr.write("--exit-with-children specified without any children to spawn; exiting immediately") return 1 atexit.register(run_cleanups) #the server class will usually override those: signal.signal(signal.SIGINT, deadly_signal) signal.signal(signal.SIGTERM, deadly_signal) dotxpra = DotXpra(opts.socket_dir) # Generate the script text now, because os.getcwd() will # change if/when we daemonize: script = xpra_runner_shell_script(xpra_file, os.getcwd(), opts.socket_dir) # Daemonize: if opts.daemon: logfd = open_log_file(dotxpra, opts.log_file, display_name) assert logfd > 2 daemonize(logfd) # Write out a shell-script so that we can start our proxy in a clean # environment: write_runner_shell_script(dotxpra, script) from xpra.log import Logger log = Logger() try: # Initialize the sockets before the display, # That way, errors won't make us kill the Xvfb # (which may not be ours to kill at that point) bind_tcp = parse_bind_tcp(opts.bind_tcp) sockets = [] mdns_info = {"display" : display_name, "username": getpass.getuser()} if opts.session_name: mdns_info["session"] = opts.session_name #tcp: for host, iport in bind_tcp: socket = setup_tcp_socket(host, iport) sockets.append(socket) #unix: socket, cleanup_socket = setup_local_socket(dotxpra, display_name, clobber, opts.mmap_group) if socket: #win32 returns None! sockets.append(socket) if opts.mdns: ssh_port = get_ssh_port() if ssh_port: mdns_publish(display_name, "ssh", [("", ssh_port)], mdns_info) if opts.mdns: mdns_publish(display_name, "tcp", bind_tcp, mdns_info) except Exception, e: log.error("cannot start server: failed to setup sockets: %s", e) return 1
def load_auth_file(): global auth_data, auth_data_time, password_file, socket_dir ptime = 0 if password_file: if not os.path.exists(password_file): log.error("password file is missing: %s", password_file) auth_data = None return auth_data try: ptime = os.stat(password_file).st_mtime except Exception as e: log.error("error accessing password file time: %s", e) if auth_data is None or ptime!=auth_data_time: auth_data = {} auth_data_time = ptime if password_file: f = None try: with open(password_file, mode='rb') as f: data = f.read() except Exception as e: log.error("error loading %s: %s", password_file, e) data = "" else: data = os.environ.get('XPRA_PASSWORD') i = 0 for line in data.splitlines(): i += 1 line = line.strip() if len(line)==0 or line.startswith("#"): continue log("line %s: %s", i, line) if line.find("|")<0: #assume old style file with just the password #get all the displays for the current user: sockdir = DotXpra(socket_dir) results = sockdir.sockets() displays = [display for state, display in results if state==DotXpra.LIVE] auth_data[""] = line, os.getuid(), os.getgid(), displays, {}, {} log("Warning: assuming this is a single password for all users") continue ldata = line.split("|") log("found %s fields at line %s", len(ldata), i) if len(ldata)<4: log.warn("skipped line %s of %s: not enough fields", i, password_file) continue #parse fields: username = ldata[0] password = ldata[1] def getsysid(s, default_value): if not s: return default_value try: return int(s) except: return default_value uid = getsysid(ldata[2], os.getuid()) gid = getsysid(ldata[3], os.getgid()) displays = ldata[4].split(",") env_options = {} session_options = {} if len(ldata)>=6: env_options = parseOptions(ldata[5]) if len(ldata)>=7: session_options = parseOptions(ldata[6]) auth_data[username] = password, uid, gid, displays, env_options, session_options log("loaded auth data from file %s: %s", password_file, auth_data) return auth_data
def run_server(parser, opts, mode, xpra_file, extra_args): if len(extra_args) != 1: parser.error("need exactly 1 extra argument") display_name = extra_args.pop(0) if opts.exit_with_children and not opts.children: print("--exit-with-children specified without any children to spawn; exiting immediately") return atexit.register(run_cleanups) signal.signal(signal.SIGINT, deadly_signal) signal.signal(signal.SIGTERM, deadly_signal) assert mode in ("start", "upgrade") upgrading = (mode == "upgrade") dotxpra = DotXpra(opts.sockdir) # This used to be given a display-specific name, but now we give it a # single fixed name and if multiple servers are started then the last one # will clobber the rest. This isn't great, but the tradeoff is that it # makes it possible to use bare 'ssh:hostname' display names and # autodiscover the proper numeric display name when only one xpra server # is running on the remote host. Might need to revisit this later if # people run into problems or autodiscovery turns out to be less useful # than expected. scriptpath = os.path.join(dotxpra.confdir(), "run-xpra") # Save the starting dir now, because we'll lose track of it when we # daemonize: starting_dir = os.getcwd() clobber = upgrading or opts.use_display try: sockpath = dotxpra.server_socket_path(display_name, clobber) except ServerSockInUse: parser.error("You already have an xpra server running at %s\n" " (did you want 'xpra upgrade'?)" % (display_name,)) # Daemonize: if opts.daemon: logpath = dotxpra.conf_path(display_name) + ".log" sys.stderr.write("Entering daemon mode; " + "any further errors will be reported to:\n" + (" %s\n" % logpath)) # Do some work up front, so any errors don't get lost. if os.path.exists(logpath): os.rename(logpath, logpath + ".old") logfd = os.open(logpath, os.O_WRONLY | os.O_CREAT | os.O_TRUNC, o0666) assert logfd > 2 os.chdir("/") if os.fork(): os._exit(0) os.setsid() if os.fork(): os._exit(0) close_all_fds(exceptions=[logfd]) fd0 = os.open("/dev/null", os.O_RDONLY) if fd0 != 0: os.dup2(fd0, 0) os.close(fd0) os.dup2(logfd, 1) os.dup2(logfd, 2) os.close(logfd) # Make these line-buffered: sys.stdout = os.fdopen(1, "w", 1) sys.stderr = os.fdopen(2, "w", 1) # Write out a shell-script so that we can start our proxy in a clean # environment: scriptfile = open(scriptpath, "w") # Unix is a little silly sometimes: umask = os.umask(0) os.umask(umask) if hasattr(os, "fchmod"): os.fchmod(scriptfile.fileno(), o0700 & ~umask) else: os.chmod(scriptpath, o0700 & ~umask) scriptfile.write(xpra_runner_shell_script(xpra_file, starting_dir)) scriptfile.close() # Do this after writing out the shell script: os.environ["DISPLAY"] = display_name if not clobber: # We need to set up a new server environment xauthority = os.environ.get("XAUTHORITY", os.path.expanduser("~/.Xauthority")) xvfb_cmd = opts.xvfb.replace("$XAUTHORITY", xauthority).split() xvfb_executable = xvfb_cmd[0] xvfb_cmd[0] = "%s-for-Xpra-%s" % (xvfb_executable, display_name) try: xvfb = subprocess.Popen(xvfb_cmd+[display_name], executable=xvfb_executable) except OSError, e: sys.stderr.write("Error starting Xvfb: %s\n" % (e,)) return raw_cookie = os.urandom(16) baked_cookie = raw_cookie.encode("hex") try: code = subprocess.call(["xauth", "add", display_name, "MIT-MAGIC-COOKIE-1", baked_cookie]) if code != 0: raise OSError("non-zero exit code: %s" % code) except OSError, e: sys.stderr.write("Error running xauth: %s\n" % e)
if f: f.close() except Exception, e: log.error("error loading %s: %s", password_file, e) data = "" i = 0 for line in data.splitlines(): i += 1 line = line.strip() if len(line)==0 or line.startswith("#"): continue debug("line %s: %s", i, line) if line.find("|")<0: #assume old style file with just the password #get all the displays for the current user: sockdir = DotXpra(socket_dir) results = sockdir.sockets() displays = [display for state, display in results if state==DotXpra.LIVE] auth_data[""] = line, os.getuid(), os.getgid(), displays, {}, {} debug("Warning: assuming this is a single password for all users") continue ldata = line.split("|") debug("found %s fields at line %s", len(ldata), i) if len(ldata)<4: log.warn("skipped line %s of %s: not enough fields", i, password_file) continue #parse fields: username = ldata[0] password = ldata[1] def getsysid(s, default_value): if not s:
child = Popen(cmd, stdin=PIPE, stdout=PIPE, preexec_fn=setsid) except OSError, e: sys.exit("Error running ssh program '%s': %s" % (cmd[0], e)) def abort_test(action): """ if ssh dies, we don't need to try to read/write from its sockets """ e = child.poll() if e is not None: error_message = "cannot %s using %s: the SSH process has terminated with exit code=%s" % (action, display_desc["full_ssh"], e) print(error_message) from wimpiggy.util import gtk_main_quit_really gtk_main_quit_really() raise IOError(error_message) return TwoFileConnection(child.stdin, child.stdout, abort_test, target=display_name) elif display_desc["type"] == "unix-domain": sockdir = DotXpra(display_desc["sockdir"]) sock = socket.socket(socket.AF_UNIX) sockfile = sockdir.socket_path(display_desc["display"]) return _socket_connect(sock, sockfile, display_name) elif display_desc["type"] == "tcp": sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) tcp_endpoint = (display_desc["host"], display_desc["port"]) return _socket_connect(sock, tcp_endpoint, display_name) else: assert False, "unsupported display type in connect" def run_client(parser, opts, extra_args, mode): if mode=="screenshot":
def run_server(parser, opts, mode, xpra_file, extra_args): if len(extra_args) != 1: parser.error("need exactly 1 extra argument") display_name = extra_args.pop(0) if display_name==":0": print("WARNING:") print("You are attempting to run the xpra server against the default X11 display '%s'." % display_name) print("This is generally not what you want.") print("You should probably use a higher display number just to avoid any confusion (and also this warning message).") if opts.exit_with_children and not opts.children: print("--exit-with-children specified without any children to spawn; exiting immediately") return 1 atexit.register(run_cleanups) signal.signal(signal.SIGINT, deadly_signal) signal.signal(signal.SIGTERM, deadly_signal) assert mode in ("start", "upgrade") upgrading = (mode == "upgrade") from xpra.scripts.main import get_default_socket_dir dotxpra = DotXpra(opts.sockdir or get_default_socket_dir()) # This used to be given a display-specific name, but now we give it a # single fixed name and if multiple servers are started then the last one # will clobber the rest. This isn't great, but the tradeoff is that it # makes it possible to use bare 'ssh:hostname' display names and # autodiscover the proper numeric display name when only one xpra server # is running on the remote host. Might need to revisit this later if # people run into problems or autodiscovery turns out to be less useful # than expected. scriptpath = os.path.join(dotxpra.confdir(), "run-xpra") # Save the starting dir now, because we'll lose track of it when we # daemonize: starting_dir = os.getcwd() # Daemonize: if opts.daemon: logpath = dotxpra.conf_path(display_name) + ".log" sys.stderr.write("Entering daemon mode; " + "any further errors will be reported to:\n" + (" %s\n" % logpath)) # Do some work up front, so any errors don't get lost. if os.path.exists(logpath): os.rename(logpath, logpath + ".old") logfd = os.open(logpath, os.O_WRONLY | os.O_CREAT | os.O_TRUNC, o0666) assert logfd > 2 os.chdir("/") if os.fork(): os._exit(0) os.setsid() if os.fork(): os._exit(0) close_all_fds(exceptions=[logfd]) fd0 = os.open("/dev/null", os.O_RDONLY) if fd0 != 0: os.dup2(fd0, 0) os.close(fd0) os.dup2(logfd, 1) os.dup2(logfd, 2) os.close(logfd) # Make these line-buffered: sys.stdout = os.fdopen(1, "w", 1) sys.stderr = os.fdopen(2, "w", 1) # Write out a shell-script so that we can start our proxy in a clean # environment: scriptfile = open(scriptpath, "w") # Unix is a little silly sometimes: umask = os.umask(0) os.umask(umask) if hasattr(os, "fchmod"): os.fchmod(scriptfile.fileno(), o0700 & ~umask) else: os.chmod(scriptpath, o0700 & ~umask) scriptfile.write(xpra_runner_shell_script(xpra_file, starting_dir, opts.sockdir)) scriptfile.close() # Initialize the sockets before the display, # That way, errors won't make us kill the Xvfb # (which may not be ours to kill at that point) sockets = [] if opts.bind_tcp: try: tcp_socket = create_tcp_socket(parser, opts.bind_tcp) sockets.append(tcp_socket) def cleanup_tcp_socket(): print("closing tcp socket %s" % opts.bind_tcp) try: tcp_socket.close() except: pass _cleanups.append(cleanup_tcp_socket) except Exception, e: print("cannot start - failed to create tcp socket at %s: %s" % (opts.bind_tcp, e)) return 1
def run_server(error_cb, opts, mode, xpra_file, extra_args): try: cwd = os.getcwd() except: cwd = os.path.expanduser("~") sys.stderr.write( "current working directory does not exist, using '%s'\n" % cwd) if opts.encoding and opts.encoding == "help": #avoid errors and warnings: opts.encoding = "" opts.clipboard = False opts.notifications = False print("xpra server supports the following encodings:") print("(please wait, encoder initialization may take a few seconds)") #disable info logging which would be confusing here from xpra.log import get_all_loggers, set_default_level import logging set_default_level(logging.WARN) logging.root.setLevel(logging.WARN) for x in get_all_loggers(): x.logger.setLevel(logging.WARN) from xpra.server.server_base import ServerBase sb = ServerBase() sb.init(opts) #ensures that the threaded video helper init has completed #(by running it again, which will block on the init lock) from xpra.codecs.video_helper import getVideoHelper getVideoHelper().init() sb.init_encodings() from xpra.codecs.loader import encoding_help for e in sb.encodings: print(" * %s" % encoding_help(e)) return 0 assert mode in ("start", "upgrade", "shadow", "proxy") starting = mode == "start" upgrading = mode == "upgrade" shadowing = mode == "shadow" proxying = mode == "proxy" clobber = upgrading or opts.use_display #get the display name: if shadowing and len(extra_args) == 0: if sys.platform.startswith("win") or sys.platform.startswith("darwin"): #just a virtual name for the only display available: display_name = ":0" else: from xpra.scripts.main import guess_X11_display display_name = guess_X11_display(opts.socket_dir) elif upgrading and len(extra_args) == 0: from xpra.scripts.main import guess_xpra_display display_name = guess_xpra_display(opts.socket_dir) else: if len(extra_args) > 1: error_cb( "too many extra arguments: only expected a display number") if len(extra_args) == 1: display_name = extra_args[0] if not shadowing and not proxying: display_name_check(display_name) else: if proxying: error_cb( "you must specify a free virtual display name to use with the proxy server" ) if not opts.displayfd: error_cb( "displayfd support is not enabled on this system, you must specify the display to use" ) if opts.use_display: #only use automatic guess for xpra displays and not X11 displays: from xpra.scripts.main import guess_xpra_display #@Reimport display_name = guess_xpra_display(opts.socket_dir) else: # We will try to find one automaticaly # Use the temporary magic value 'S' as marker: display_name = 'S' + str(os.getpid()) if not shadowing and not proxying and not upgrading and opts.exit_with_children and not opts.start_child: error_cb( "--exit-with-children specified without any children to spawn; exiting immediately" ) atexit.register(run_cleanups) #the server class will usually override those: signal.signal(signal.SIGINT, deadly_signal) signal.signal(signal.SIGTERM, deadly_signal) dotxpra = DotXpra(opts.socket_dir) # Generate the script text now, because os.getcwd() will # change if/when we daemonize: script = xpra_runner_shell_script(xpra_file, os.getcwd(), opts.socket_dir) stdout = sys.stdout stderr = sys.stderr # Daemonize: if opts.daemon: #daemonize will chdir to "/", so try to use an absolute path: if opts.password_file: opts.password_file = os.path.abspath(opts.password_file) # At this point we may not know the display name, # so log_filename0 may point to a temporary file which we will rename later log_filename0 = select_log_file(dotxpra, opts.log_file, display_name) logfd = open_log_file(log_filename0) assert logfd > 2 stdout, stderr = daemonize(logfd) try: stderr.write("Entering daemon mode; " + "any further errors will be reported to:\n" + (" %s\n" % log_filename0)) except: #this can happen if stderr is closed by the caller already pass # Write out a shell-script so that we can start our proxy in a clean # environment: write_runner_shell_script(dotxpra, script) from xpra.log import Logger log = Logger("server") mdns_recs = [] sockets = [] try: # Initialize the TCP sockets before the display, # That way, errors won't make us kill the Xvfb # (which may not be ours to kill at that point) bind_tcp = parse_bind_tcp(opts.bind_tcp) for host, iport in bind_tcp: socket = setup_tcp_socket(host, iport) sockets.append(socket) if opts.mdns: mdns_recs.append(("tcp", bind_tcp)) except Exception, e: log.error("cannot start server: failed to setup sockets: %s", e) return 1
e = child.poll() if e is not None: error_message = "cannot %s using %s: the SSH process has terminated with exit code=%s" % ( action, display_desc["full_ssh"], e) print(error_message) from wimpiggy.util import gtk_main_quit_really gtk_main_quit_really() raise IOError(error_message) return TwoFileConnection(child.stdin, child.stdout, abort_test, target=cmd) elif display_desc["type"] == "unix-domain": sockdir = DotXpra(display_desc["sockdir"]) sock = socket.socket(socket.AF_UNIX) sockfile = sockdir.socket_path(display_desc["display"]) return _socket_connect(sock, sockfile) elif display_desc["type"] == "tcp": sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) tcp_endpoint = (display_desc["host"], display_desc["port"]) return _socket_connect(sock, tcp_endpoint) else: assert False, "unsupported display type in connect" def run_client(parser, opts, extra_args, mode): if mode == "screenshot":
def abort_test(action): """ if ssh dies, we don't need to try to read/write from its sockets """ e = child.poll() if e is not None: error_message = "cannot %s using %s: the SSH process has terminated with exit code=%s" % ( action, display_desc["full_ssh"], e) print(error_message) from wimpiggy.util import gtk_main_quit_really gtk_main_quit_really() raise IOError(error_message) return TwoFileConnection(child.stdin, child.stdout, abort_test) elif XPRA_LOCAL_SERVERS_SUPPORTED and display_desc["type"] == "unix-domain": sockdir = DotXpra() sock = socket.socket(socket.AF_UNIX) return _socket_connect(sock, sockdir.socket_path(display_desc["display"])) elif display_desc["type"] == "tcp": sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) return _socket_connect(sock, (display_desc["host"], display_desc["port"])) else: assert False, "unsupported display type in connect" def run_client(parser, opts, extra_args, mode): if mode == "screenshot":
def load_auth_file(): global auth_data, auth_data_time, password_file, socket_dir, socket_dirs ptime = 0 if password_file: if not os.path.exists(password_file): log.error("password file is missing: %s", password_file) auth_data = None return auth_data try: ptime = os.stat(password_file).st_mtime except Exception as e: log.error("error accessing password file time: %s", e) if auth_data is None or ptime != auth_data_time: auth_data = {} auth_data_time = ptime if password_file: f = None try: with open(password_file, mode='rb') as f: data = f.read() except Exception as e: log.error("error loading %s: %s", password_file, e) data = "" log("loaded %s bytes from %s", len(data), password_file) else: data = os.environ.get('XPRA_PASSWORD', "") i = 0 for line in data.splitlines(): i += 1 line = line.strip() if len(line) == 0 or line.startswith("#"): continue log("line %s: %s", i, line) if line.find("|") < 0: #assume old style file with just the password #get all the displays for the current user: sockdir = DotXpra(socket_dir, socket_dirs) results = sockdir.sockets() displays = [ display for state, display in results if state == DotXpra.LIVE ] auth_data[""] = line, os.getuid(), os.getgid( ), displays, {}, {} log("Warning: assuming this is a single password for all users" ) continue ldata = line.split("|") log("found %s fields at line %s", len(ldata), i) if len(ldata) < 4: log.warn("skipped line %s of %s: not enough fields", i, password_file) continue #parse fields: username = ldata[0] password = ldata[1] def getsysid(s, default_value): if not s: return default_value try: return int(s) except: return default_value uid = getsysid(ldata[2], os.getuid()) gid = getsysid(ldata[3], os.getgid()) displays = ldata[4].split(",") env_options = {} session_options = {} if len(ldata) >= 6: env_options = parseOptions(ldata[5]) if len(ldata) >= 7: session_options = parseOptions(ldata[6]) auth_data[ username] = password, uid, gid, displays, env_options, session_options log("loaded auth data from file %s: %s", password_file, auth_data) return auth_data
def run_server(parser, opts, mode, xpra_file, extra_args): if len(extra_args) != 1: parser.error("need exactly 1 extra argument") display_name = extra_args.pop(0) if display_name == ":0": print("WARNING:") print( "You are attempting to run the xpra server against the default X11 display '%s'." % display_name) print("This is generally not what you want.") print( "You should probably use a higher display number just to avoid any confusion (and also this warning message)." ) if opts.exit_with_children and not opts.children: print( "--exit-with-children specified without any children to spawn; exiting immediately" ) return 1 atexit.register(run_cleanups) signal.signal(signal.SIGINT, deadly_signal) signal.signal(signal.SIGTERM, deadly_signal) assert mode in ("start", "upgrade") upgrading = (mode == "upgrade") from xpra.scripts.main import get_default_socket_dir dotxpra = DotXpra(opts.sockdir or get_default_socket_dir()) # This used to be given a display-specific name, but now we give it a # single fixed name and if multiple servers are started then the last one # will clobber the rest. This isn't great, but the tradeoff is that it # makes it possible to use bare 'ssh:hostname' display names and # autodiscover the proper numeric display name when only one xpra server # is running on the remote host. Might need to revisit this later if # people run into problems or autodiscovery turns out to be less useful # than expected. scriptpath = os.path.join(dotxpra.confdir(), "run-xpra") # Save the starting dir now, because we'll lose track of it when we # daemonize: starting_dir = os.getcwd() # Daemonize: if opts.daemon: logpath = dotxpra.conf_path(display_name) + ".log" sys.stderr.write("Entering daemon mode; " + "any further errors will be reported to:\n" + (" %s\n" % logpath)) # Do some work up front, so any errors don't get lost. if os.path.exists(logpath): os.rename(logpath, logpath + ".old") logfd = os.open(logpath, os.O_WRONLY | os.O_CREAT | os.O_TRUNC, o0666) assert logfd > 2 os.chdir("/") if os.fork(): os._exit(0) os.setsid() if os.fork(): os._exit(0) close_all_fds(exceptions=[logfd]) fd0 = os.open("/dev/null", os.O_RDONLY) if fd0 != 0: os.dup2(fd0, 0) os.close(fd0) os.dup2(logfd, 1) os.dup2(logfd, 2) os.close(logfd) # Make these line-buffered: sys.stdout = os.fdopen(1, "w", 1) sys.stderr = os.fdopen(2, "w", 1) # Write out a shell-script so that we can start our proxy in a clean # environment: scriptfile = open(scriptpath, "w") # Unix is a little silly sometimes: umask = os.umask(0) os.umask(umask) if hasattr(os, "fchmod"): os.fchmod(scriptfile.fileno(), o0700 & ~umask) else: os.chmod(scriptpath, o0700 & ~umask) scriptfile.write( xpra_runner_shell_script(xpra_file, starting_dir, opts.sockdir)) scriptfile.close() # Initialize the sockets before the display, # That way, errors won't make us kill the Xvfb # (which may not be ours to kill at that point) sockets = [] if opts.bind_tcp: try: tcp_socket = create_tcp_socket(parser, opts.bind_tcp) sockets.append(tcp_socket) def cleanup_tcp_socket(): print("closing tcp socket %s" % opts.bind_tcp) try: tcp_socket.close() except: pass _cleanups.append(cleanup_tcp_socket) except Exception, e: print("cannot start - failed to create tcp socket at %s: %s" % (opts.bind_tcp, e)) return 1
def run_server(parser, opts, mode, xpra_file, extra_args): if opts.encoding and opts.encoding == "help": #avoid errors and warnings: opts.encoding = "" opts.clipboard = False opts.notifications = False print("xpra server supports the following encodings:") print("(please wait, encoder initialization may take a few seconds)") #disable info logging which would be confusing here from xpra.log import get_all_loggers, set_default_level import logging set_default_level(logging.WARN) logging.root.setLevel(logging.WARN) for x in get_all_loggers(): x.logger.setLevel(logging.WARN) from xpra.server.server_base import ServerBase sb = ServerBase() sb.init(opts) #ensures that the threaded video helper init has completed #(by running it again, which will block on the init lock) from xpra.codecs.video_helper import getVideoHelper getVideoHelper().init() sb.init_encodings() from xpra.codecs.loader import encoding_help for e in sb.encodings: print(" * %s" % encoding_help(e)) return 0 assert mode in ("start", "upgrade", "shadow", "proxy") starting = mode == "start" upgrading = mode == "upgrade" shadowing = mode == "shadow" proxying = mode == "proxy" clobber = upgrading or opts.use_display #get the display name: if shadowing and len(extra_args) == 0: from xpra.scripts.main import guess_X11_display display_name = guess_X11_display() else: if len(extra_args) != 1: parser.error("need exactly 1 extra argument") display_name = extra_args.pop(0) if not shadowing and not proxying: display_name_check(display_name) if not shadowing and not proxying and not upgrading and opts.exit_with_children and not opts.start_child: sys.stderr.write( "--exit-with-children specified without any children to spawn; exiting immediately" ) return 1 atexit.register(run_cleanups) #the server class will usually override those: signal.signal(signal.SIGINT, deadly_signal) signal.signal(signal.SIGTERM, deadly_signal) dotxpra = DotXpra(opts.socket_dir) # Generate the script text now, because os.getcwd() will # change if/when we daemonize: script = xpra_runner_shell_script(xpra_file, os.getcwd(), opts.socket_dir) # Daemonize: if opts.daemon: #daemonize will chdir to "/", so try to use an absolute path: if opts.password_file: opts.password_file = os.path.abspath(opts.password_file) logfd = open_log_file(dotxpra, opts.log_file, display_name) assert logfd > 2 daemonize(logfd) # Write out a shell-script so that we can start our proxy in a clean # environment: write_runner_shell_script(dotxpra, script) from xpra.log import Logger log = Logger("server") try: # Initialize the sockets before the display, # That way, errors won't make us kill the Xvfb # (which may not be ours to kill at that point) bind_tcp = parse_bind_tcp(opts.bind_tcp) sockets = [] mdns_info = {"display": display_name, "username": getpass.getuser()} if opts.session_name: mdns_info["session"] = opts.session_name #tcp: for host, iport in bind_tcp: socket = setup_tcp_socket(host, iport) sockets.append(socket) #unix: socket, cleanup_socket = setup_local_socket(dotxpra, display_name, clobber, opts.mmap_group) if socket: #win32 returns None! sockets.append(socket) if opts.mdns: ssh_port = get_ssh_port() if ssh_port: mdns_publish(display_name, "ssh", [("", ssh_port)], mdns_info) if opts.mdns: mdns_publish(display_name, "tcp", bind_tcp, mdns_info) except Exception, e: log.error("cannot start server: failed to setup sockets: %s", e) return 1
def run_server(parser, opts, mode, xpra_file, extra_args): if len(extra_args) != 1: parser.error("need exactly 1 extra argument") display_name = extra_args.pop(0) if opts.exit_with_children and not opts.children: print( "--exit-with-children specified without any children to spawn; exiting immediately" ) return atexit.register(run_cleanups) signal.signal(signal.SIGINT, deadly_signal) signal.signal(signal.SIGTERM, deadly_signal) assert mode in ("start", "upgrade") upgrading = (mode == "upgrade") dotxpra = DotXpra(opts.sockdir) # This used to be given a display-specific name, but now we give it a # single fixed name and if multiple servers are started then the last one # will clobber the rest. This isn't great, but the tradeoff is that it # makes it possible to use bare 'ssh:hostname' display names and # autodiscover the proper numeric display name when only one xpra server # is running on the remote host. Might need to revisit this later if # people run into problems or autodiscovery turns out to be less useful # than expected. scriptpath = os.path.join(dotxpra.confdir(), "run-xpra") # Save the starting dir now, because we'll lose track of it when we # daemonize: starting_dir = os.getcwd() clobber = upgrading or opts.use_display try: sockpath = dotxpra.server_socket_path(display_name, clobber) except ServerSockInUse: parser.error("You already have an xpra server running at %s\n" " (did you want 'xpra upgrade'?)" % (display_name, )) # Daemonize: if opts.daemon: logpath = dotxpra.conf_path(display_name) + ".log" sys.stderr.write("Entering daemon mode; " + "any further errors will be reported to:\n" + (" %s\n" % logpath)) # Do some work up front, so any errors don't get lost. if os.path.exists(logpath): os.rename(logpath, logpath + ".old") logfd = os.open(logpath, os.O_WRONLY | os.O_CREAT | os.O_TRUNC, o0666) assert logfd > 2 os.chdir("/") if os.fork(): os._exit(0) os.setsid() if os.fork(): os._exit(0) close_all_fds(exceptions=[logfd]) fd0 = os.open("/dev/null", os.O_RDONLY) if fd0 != 0: os.dup2(fd0, 0) os.close(fd0) os.dup2(logfd, 1) os.dup2(logfd, 2) os.close(logfd) # Make these line-buffered: sys.stdout = os.fdopen(1, "w", 1) sys.stderr = os.fdopen(2, "w", 1) # Write out a shell-script so that we can start our proxy in a clean # environment: scriptfile = open(scriptpath, "w") # Unix is a little silly sometimes: umask = os.umask(0) os.umask(umask) if hasattr(os, "fchmod"): os.fchmod(scriptfile.fileno(), o0700 & ~umask) else: os.chmod(scriptpath, o0700 & ~umask) scriptfile.write(xpra_runner_shell_script(xpra_file, starting_dir)) scriptfile.close() # Do this after writing out the shell script: os.environ["DISPLAY"] = display_name if not clobber: # We need to set up a new server environment xauthority = os.environ.get("XAUTHORITY", os.path.expanduser("~/.Xauthority")) xvfb_cmd = opts.xvfb.replace("$XAUTHORITY", xauthority).split() xvfb_executable = xvfb_cmd[0] xvfb_cmd[0] = "%s-for-Xpra-%s" % (xvfb_executable, display_name) try: xvfb = subprocess.Popen(xvfb_cmd + [display_name], executable=xvfb_executable) except OSError, e: sys.stderr.write("Error starting Xvfb: %s\n" % (e, )) return raw_cookie = os.urandom(16) baked_cookie = raw_cookie.encode("hex") try: code = subprocess.call([ "xauth", "add", display_name, "MIT-MAGIC-COOKIE-1", baked_cookie ]) if code != 0: raise OSError("non-zero exit code: %s" % code) except OSError, e: sys.stderr.write("Error running xauth: %s\n" % e)