1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
|
#!/usr/bin/env python
# This file is part of Xpra.
# Copyright (C) 2017-2020 Antoine Martin <antoine@xpra.org>
# Xpra is released under the terms of the GNU GPL v2, or, at your option, any
# later version. See the file COPYING for details.
import os
import sys
if os.environ.get("XPRA_XDG_OPEN"):
sys.stderr.write("xdg-open: aborting to avoid forwarding loop\n")
sys.exit(1)
socket_path = os.environ.get("XPRA_SERVER_SOCKET")
display = os.environ.get("DISPLAY", "unknown")
if socket_path and os.path.exists(socket_path):
if len(sys.argv)!=2:
sys.stderr.write("xdg-open: invalid number of arguments\n")
sys.stderr.write("Try `xdg-open --help' for more information.\n")
arg = sys.argv[1]
if arg in ("--help", "--manual"):
sys.stderr.write("xdg-open { file | URL }\n")
sys.stderr.flush()
sys.exit(0)
if arg=="--version":
from xpra import __version__
sys.stdout.write("xpra xdg-open %s\n" % __version__)
sys.exit(0)
def send_control_command(*control_command_args):
from subprocess import Popen, PIPE
try:
command = ["xpra", "control", "socket://%s" % socket_path] + list(control_command_args)
proc = Popen(command, stdout=PIPE, stderr=PIPE)
#sys.stderr.write("Popen(%s)=%s\n" % (command, proc))
out, err = proc.communicate(None)
if proc.returncode==0:
sys.exit(0)
else:
if out:
try:
sys.stdout.buffer.write(out)
except AttributeError:
sys.stdout.write(out)
sys.stdout.flush()
if err:
try:
sys.stderr.buffer.write(err)
except AttributeError:
sys.stderr.write(err)
sys.stderr.flush()
except Exception as e:
sys.stderr.write("xdg-open: failed to forward to xpra server using socket '%s': %s\n" % (socket_path, e))
sys.stderr.flush()
sys.exit(1)
#try to forward URI or file:
#sys.stderr.write("xdg-open: forwarding request to xpra server at '%s'\n" % (socket_path,))
filename = os.path.abspath(arg)
#sys.stderr.write("arg: '%s'\n" % x)
if arg.find("://")>0:
proto, filename = arg.split("://", 1)
if proto=="file":
#this is a URL and may be escaped:
from urllib.parse import unquote
send_control_command("send-file", unquote(filename), "open", "*")
else:
send_control_command("open-url", arg, "*")
elif os.path.exists(arg) and os.path.isfile(arg):
send_control_command("send-file", filename, "open", "*")
elif os.path.exists(arg) and not os.path.isfile(arg):
#fall-through to regular xdg-open:
pass
else:
sys.stderr.write("xdg-open: unrecognized argument form '%s'\n" % arg)
sys.exit(1)
#fallback to the "real" xdg-open:
this_file = os.path.abspath(__file__)
xdg_open_override_dir = os.path.dirname(this_file)
env = os.environ.copy()
PATH = env.get("PATH", "").split(os.pathsep)
if xdg_open_override_dir not in ("/usr/bin", "/bin"):
#remove our path from PATH:
PATH = [x for x in PATH if os.path.abspath(x)!=xdg_open_override_dir]
env["PATH"] = os.pathsep.join(PATH)
env["XPRA_XDG_OPEN"] = "1"
#find the real xdg-open:
real_xdg_open = None
for x in PATH:
real_xdg_open = os.path.join(x, "xdg-open")
if os.path.exists(real_xdg_open) and os.path.isfile(real_xdg_open):
break
if not real_xdg_open:
sys.stderr.write("xdg-open: real executable not found in $PATH\n")
sys.exit(1)
if real_xdg_open==this_file:
sys.stderr.write("xdg-open: loop detected\n")
sys.exit(1)
os.execve(real_xdg_open, ["xdg-open"]+sys.argv[1:], env)
|