Exemple #1
0
def start_dbus(dbus_launch):
    if not dbus_launch or dbus_launch.lower() in FALSE_OPTIONS:
        return 0, {}
    try:
        def preexec():
            assert POSIX
            os.setsid()
            close_fds()
        proc = subprocess.Popen(dbus_launch, stdin=subprocess.PIPE, stdout=subprocess.PIPE, shell=True, preexec_fn=preexec)
        out,_ = proc.communicate()
        assert proc.poll()==0, "exit code is %s" % proc.poll()
        #parse and add to global env:
        dbus_env = {}
        for l in bytestostr(out).splitlines():
            parts = l.split("=", 1)
            if len(parts)!=2:
                continue
            k,v = parts
            if v.startswith("'") and v.endswith("';"):
                v = v[1:-2]
            dbus_env[k] = v
        dbus_pid = int(dbus_env.get("DBUS_SESSION_BUS_PID", 0))
        return dbus_pid, dbus_env
    except Exception as e:
        get_util_logger().debug("start_dbus(%s)", dbus_launch, exc_info=True)
        error("dbus-launch failed to start using command '%s':\n" % dbus_launch)
        error(" %s\n" % e)
        return 0, {}
Exemple #2
0
def init():
    global bencode, bdecode, __version__
    from xpra.util import envbool
    cython_bencode_loaded = False
    if envbool("XPRA_USE_CYTHON_BENCODE", True):
        try:
            from xpra.net.bencode.cython_bencode import (
                bencode as cbencode,
                bdecode as cbdecode,
                __version__ as cversion,
            )
            bencode = cbencode
            bdecode = cbdecode
            __version__ = cversion
            cython_bencode_loaded = True
        except ImportError as e:
            from xpra.os_util import get_util_logger
            get_util_logger().warn(
                "Warning: cannot load cython bencode module: %s", e)
    if not cython_bencode_loaded:
        from xpra.net.bencode.bencode import (
            bencode as pbencode,
            bdecode as pbdecode,
            __version__ as pversion,
        )
        bencode = pbencode
        bdecode = pbdecode
        __version__ = pversion
Exemple #3
0
def has_uinput():
    try:
        import uinput
        assert uinput
    except NameError as e:
        log = get_util_logger()
        log("has_uinput()", exc_info=True)
        log.warn("Warning: the system python uinput module looks broken:")
        log.warn(" %s", e)
        return False
    except ImportError as e:
        log = get_util_logger()
        log("has_uinput()", exc_info=True)
        log.info("cannot access python uinput module:")
        log.info(" %s", e)
        return False
    try:
        uinput.fdopen()         #@UndefinedVariable
    except Exception as e:
        log = get_util_logger()
        log("has_uinput()", exc_info=True)
        log.info("cannot use uinput for virtual devices:")
        log.info(" %s", e)
        return False
    return True
Exemple #4
0
 def mksockdir(self, d, mode=0o700, uid=None, gid=None):
     if not d:
         return
     if not os.path.exists(d):
         if uid is None:
             uid = self.uid
         if gid is None:
             gid = self.gid
         parent = os.path.dirname(d)
         if parent and parent != "/" and not os.path.exists(parent):
             self.mksockdir(parent, mode, uid, gid)
         with umask_context(0):
             os.mkdir(d, mode)
         if uid != os.getuid() or gid != os.getgid():
             os.lchown(d, uid, gid)
     elif d != "/tmp":
         try:
             st_mode = os.stat(d).st_mode
             if st_mode & 0o777 != mode:
                 log = get_util_logger()
                 log.warn("Warning: socket directory '%s'", d)
                 log.warn(" expected permissions %s but found %s",
                          oct(mode), oct(st_mode & 0o777))
         except OSError:
             get_util_logger().log("mksockdir%s", (d, mode, uid, gid),
                                   exc_info=True)
Exemple #5
0
def get_program_data_dir():
    #ie: "C:\ProgramData"
    try:
        return sh_get_folder_path(CSIDL_COMMON_APPDATA) or "C:\\ProgramData"
    except Exception:
        get_util_logger().debug("get_program_data_dir()", exc_info=True)
    return "C:\\ProgramData"
Exemple #6
0
def has_uinput():
    if not envbool("XPRA_UINPUT", True):
        return False
    try:
        import uinput
        assert uinput
    except NameError as e:
        log = get_util_logger()
        log("has_uinput()", exc_info=True)
        log.warn("Warning: the system python uinput module looks broken:")
        log.warn(" %s", e)
        return False
    except ImportError as e:
        log = get_util_logger()
        log("has_uinput()", exc_info=True)
        log.info("no uinput module")
        return False
    try:
        uinput.fdopen()         #@UndefinedVariable
    except Exception as e:
        log = get_util_logger()
        log("has_uinput()", exc_info=True)
        log.info("cannot use uinput for virtual devices,")
        log.info(" this is usually a permission issue:")
        log.info(" %s", e)
        return False
    return True
Exemple #7
0
def get_posix_sys_info():
    info = {}
    try:
        import resource
        for k, constant in {
                "server": "RUSAGE_SELF",
                "children": "RUSAGE_CHILDREN",
                "total": "RUSAGE_BOTH"
        }.items():
            try:
                v = getattr(resource, constant)
            except (NameError, AttributeError):
                continue
            stats = resource.getrusage(v)
            minfo = info.setdefault("memory", {}).setdefault(k, {})
            for var in ("utime", "stime", "maxrss", "ixrss", "idrss", "isrss",
                        "minflt", "majflt", "nswap", "inblock", "oublock",
                        "msgsnd", "msgrcv", "nsignals", "nvcsw", "nivcsw"):
                value = getattr(stats, "ru_%s" % var)
                if type(value) == float:
                    value = int(value)
                minfo[var] = value
    except:
        from xpra.os_util import get_util_logger
        get_util_logger().error("Error getting memory usage info",
                                exc_info=True)
    return info
Exemple #8
0
def save_dbus_env(env):
    #DBUS_SESSION_BUS_ADDRESS=unix:abstract=/tmp/dbus-B8CDeWmam9,guid=b77f682bd8b57a5cc02f870556cbe9e9
    #DBUS_SESSION_BUS_PID=11406
    #DBUS_SESSION_BUS_WINDOWID=50331649
    def u(s):
        try:
            return s.decode("latin1")
        except:
            return str(s)

    for n, conv, save in (("ADDRESS", u, _save_str), ("PID", int, _save_int),
                          ("WINDOW_ID", int, _save_int)):
        k = "DBUS_SESSION_BUS_%s" % n
        v = env.get(k)
        if v is None:
            continue
        try:
            tv = conv(v)
            save(k, tv)
        except Exception as e:
            get_util_logger().debug("save_dbus_env(%s)", env, exc_info=True)
            error(
                "failed to save dbus environment variable '%s' with value '%s':\n"
                % (k, v))
            error(" %s\n" % e)
Exemple #9
0
 def handle_signal(signum):
     try:
         sys.stderr.write("\n")
         sys.stderr.flush()
         get_util_logger().info("got signal %s",
                                SIGNAMES.get(signum, signum))
     except (IOError, OSError):
         pass
     callback(signum)
Exemple #10
0
def get_program_data_dir():
    #ie: "C:\ProgramData"
    try:
        buf = ctypes.create_unicode_buffer(ctypes.wintypes.MAX_PATH)
        SHGetFolderPath(0, CSIDL_COMMON_APPDATA, None, 0, buf)
        if buf.value:
            return buf.value
    except Exception:
        get_util_logger().debug("get_program_data_dir()", exc_info=True)
    return "C:\\ProgramData"
Exemple #11
0
 def write_signal():
     if commandtype is None:
         return
     try:
         sys.stderr.write("\n")
         sys.stderr.flush()
         cstr = ""
         if commandtype:
             cstr = commandtype + " "
         get_util_logger().info("%sgot signal %s", cstr, signame)
     except OSError:
         pass
Exemple #12
0
 def handle_signal(signum):
     try:
         sys.stderr.write("\n")
         sys.stderr.flush()
         cstr = ""
         if commandtype:
             cstr = commandtype + " "
         get_util_logger().info("%sgot signal %s", cstr,
                                SIGNAMES.get(signum, signum))
     except OSError:
         pass
     callback(signum)
     return True
Exemple #13
0
def do_get_download_dir():
    try:
        #values found here: https://stackoverflow.com/a/48706260
        import winreg   #@UnresolvedImport @Reimport
        sub_key = r'SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders'
        downloads_guid = '{374DE290-123F-4565-9164-39C4925E467B}'
        with winreg.OpenKey(winreg.HKEY_CURRENT_USER, sub_key) as key:
            DOWNLOAD_PATH = winreg.QueryValueEx(key, downloads_guid)[0]
    except Exception:
        get_util_logger()("do_get_download_dir()", exc_info=True)
        #fallback to what the documentation says is the default:
        DOWNLOAD_PATH = os.path.join(os.environ.get("USERPROFILE", "~"), "My Documents", "Downloads")
        if not os.path.exists(DOWNLOAD_PATH):
            DOWNLOAD_PATH = os.path.join(os.environ.get("USERPROFILE", "~"), "Downloads")
    return DOWNLOAD_PATH
Exemple #14
0
def create_uinput_devices(uinput_uuid, uid):
    log = get_util_logger()
    try:
        import uinput
        assert uinput
    except (ImportError, NameError) as e:
        log.error("Error: cannot access python uinput module:")
        log.error(" %s", e)
        return {}
    pointer = create_uinput_pointer_device(uinput_uuid, uid)
    touchpad = create_uinput_touchpad_device(uinput_uuid, uid)
    if not pointer and not touchpad:
        return {}
    def i(device):
        if not device:
            return {}
        name, uinput_pointer, dev_path = device
        return {
            "name"      : name,
            "uinput"    : uinput_pointer,
            "device"    : dev_path,
            }
    return {
        "pointer"   : i(pointer),
        "touchpad"  : i(touchpad),
        }
Exemple #15
0
def get_uinput_device_path(device):
    log = get_util_logger()
    try:
        log("get_uinput_device_path(%s)", device)
        fd = device._Device__uinput_fd
        log("fd(%s)=%s", device, fd)
        import fcntl        #@UnresolvedImport
        import ctypes
        l = 16
        buf = ctypes.create_string_buffer(l)
        _IOC_READ = 2
        #this magic value was calculated using the C macros:
        l = fcntl.ioctl(fd, 2148554028, buf)
        if l>0 and l<16:
            virt_dev_path = buf.raw[:l].rstrip("\0")
            log("UI_GET_SYSNAME(%s)=%s", fd, virt_dev_path)
            uevent_path = b"/sys/devices/virtual/input/%s" % virt_dev_path
            event_dirs = [x for x in os.listdir(uevent_path) if x.startswith("event")]
            log("event dirs(%s)=%s", uevent_path, event_dirs)
            for d in event_dirs:
                uevent_filename = os.path.join(uevent_path, d, "uevent")
                uevent_conf = open(uevent_filename, "rb").read()
                for line in uevent_conf.splitlines():
                    if line.find(b"=")>0:
                        k,v = line.split(b"=", 1)
                        log("%s=%s", k, v)
                        if k==b"DEVNAME":
                            dev_path = b"/dev/%s" % v
                            log("found device path: %s" % dev_path)
                            return dev_path
    except Exception as e:
        log.error("Error: cannot query uinput device path:")
        log.error(" %s", e)
    return None
Exemple #16
0
def print_DE_warnings(desktop_display, pulseaudio, notifications, dbus_launch):
    de = os.environ.get("XDG_SESSION_DESKTOP") or os.environ.get(
        "SESSION_DESKTOP")
    if not de:
        return
    warnings = []
    log = get_util_logger()
    if pulseaudio is not False:
        try:
            xprop = subprocess.Popen(
                ["xprop", "-root", "-display", desktop_display],
                stdout=subprocess.PIPE)
            out, _ = xprop.communicate()
            for x in out.splitlines():
                if x.startswith("PULSE_SERVER"):
                    #found an existing pulseaudio server
                    warnings.append("pulseaudio")
                    break
        except:
            pass  #don't care, this is just to decide if we show an informative warning or not
    if notifications and not dbus_launch:
        warnings.append("notifications")
    if warnings:
        log.warn("Warning: xpra start from an existing '%s' desktop session",
                 de)
        log.warn(" %s forwarding may not work", " and ".join(warnings))
        log.warn(" try using a clean environment, a dedicated user,")
        log.warn(" or disable xpra's %s option",
                 " and ".join(['"%s"' % x for x in warnings]))
Exemple #17
0
def get_listener_class():
    from xpra.os_util import get_util_logger
    log = get_util_logger()
    log("mdns.get_listener_class() AVAHI=%s, ZEROCONF=%s", AVAHI, ZEROCONF)
    if AVAHI:
        try:
            from xpra.net.mdns.avahi_listener import AvahiListener
            log("AvahiListener=%s", AvahiListener)
            return AvahiListener
        except ImportError:
            log("failed to import AvahiListener", exc_info=True)
    if ZEROCONF:
        #workaround for MacOS Big Sur which broke ctypes,
        #ctypes is used in the ifaddr module which is imported by zeroconf:
        if sys.platform.startswith("darwin"):
            import xpra.platform    #pylint: disable=import-outside-toplevel
            #on MacOS, an import side-effect is to patch the ctypes loader
            assert xpra.platform
        try:
            from xpra.net.mdns.zeroconf_listener import ZeroconfListener
            log("ZeroconfListener=%s", ZeroconfListener)
            return ZeroconfListener
        except (ImportError, OSError):
            log("failed to import ZeroconfListener", exc_info=True)
    return None
Exemple #18
0
def create_uinput_device(uuid, uid, events, name):
    log = get_util_logger()
    import uinput
    BUS_USB = 0x03
    #BUS_VIRTUAL = 0x06
    VENDOR = 0xffff
    PRODUCT = 0x1000
    #our xpra_udev_product_version script will use the version attribute to set
    #the udev OWNER value
    VERSION = uid
    try:
        device = uinput.Device(events, name=name, bustype=BUS_USB, vendor=VENDOR, product=PRODUCT, version=VERSION)
    except OSError as e:
        log("uinput.Device creation failed", exc_info=True)
        if os.getuid()==0:
            #running as root, this should work!
            log.error("Error: cannot open uinput,")
            log.error(" make sure that the kernel module is loaded")
            log.error(" and that the /dev/uinput device exists:")
            log.error(" %s", e)
        else:
            log.info("cannot access uinput: %s", e)
        return None
    dev_path = get_uinput_device_path(device)
    if not dev_path:
        device.destroy()
        return None
    return name, device, dev_path
Exemple #19
0
def source_env(source=()) -> dict:
    log = get_util_logger()
    env = {}
    for f in source:
        e = env_from_sourcing(f)
        log("source_env %s=%s", f, e)
        env.update(e)
    return env
Exemple #20
0
def kill_xvfb(xvfb_pid):
    if xvfb_pid:
        log = get_util_logger()
        log.info("killing xvfb with pid %s", xvfb_pid)
        try:
            os.kill(xvfb_pid, signal.SIGTERM)
        except OSError as e:
            log.info("failed to kill xvfb process with pid %s:", xvfb_pid)
            log.info(" %s", e)
Exemple #21
0
def has_uinput():
    try:
        import uinput
        assert uinput
    except (ImportError, NameError) as e:
        log = get_util_logger()
        log("has_uinput()", exc_info=True)
        log.info("cannot access python uinput module:")
        log.info(" %s", e)
        return False
    try:
        uinput.fdopen()
    except Exception as e:
        log = get_util_logger()
        log("has_uinput()", exc_info=True)
        log.info("cannot use uinput for virtual devices:")
        log.info(" %s", e)
        return False
    return True
Exemple #22
0
def print_DE_warnings():
    de = os.environ.get("XDG_SESSION_DESKTOP") or os.environ.get("SESSION_DESKTOP")
    if not de:
        return
    log = get_util_logger()
    log.warn("Warning: xpra start from an existing '%s' desktop session", de)
    log.warn(" without using dbus-launch,")
    log.warn(" notifications forwarding may not work")
    log.warn(" try using a clean environment, a dedicated user,")
    log.warn(" or disable xpra's notifications option")
Exemple #23
0
def get_icc_info():
    ENV_ICC_DATA = os.environ.get("XPRA_ICC_DATA")
    if ENV_ICC_DATA:
        import binascii
        return {
            "source": "environment-override",
            "data": binascii.unhexlify(ENV_ICC_DATA),
        }
    from xpra.os_util import get_util_logger, bytestostr
    log = get_util_logger()
    info = {}
    try:
        from PIL import ImageCms
        from PIL.ImageCms import get_display_profile, getDefaultIntent
        INTENT_STR = {}
        for x in ("PERCEPTUAL", "RELATIVE_COLORIMETRIC", "SATURATION",
                  "ABSOLUTE_COLORIMETRIC"):
            v = getattr(ImageCms, "INTENT_%s" % x, None)
            if v:
                INTENT_STR[v] = x.lower().replace("_", "-")
        log("get_icc_info() intents=%s", INTENT_STR)

        def getDefaultIntentStr(_p):
            return INTENT_STR.get(getDefaultIntent(_p), "unknown")

        def getData(_p):
            return _p.tobytes()

        p = get_display_profile()
        log("get_icc_info() display_profile=%s", p)
        if p:
            for (k, fn) in {
                    "name": "getProfileName",
                    "info": "getProfileInfo",
                    "copyright": "getProfileCopyright",
                    "manufacturer": "getProfileManufacturer",
                    "model": "getProfileModel",
                    "description": "getProfileDescription",
                    "default-intent": "getDefaultIntentStr",
                    "data": "getData",
            }.items():
                m = getattr(ImageCms, fn, None)
                if not m:
                    log("%s lacks %s", ImageCms, fn)
                    continue
                try:
                    v = m(p)
                    info[k] = bytestostr(v).rstrip("\n\r")
                except Exception as e:
                    log("ICC profile error on %s using %s: %s", k, fn, e)
    except Exception as e:
        log("get_icc_info()", exc_info=True)
        log.warn("Warning: cannot query ICC profiles:")
        log.warn(" %s", e)
    return info
Exemple #24
0
 def impcheck(*modules):
     for mod in modules:
         try:
             __import__("xpra.%s" % mod, {}, {}, [])
         except ImportError:
             if mod not in impwarned:
                 impwarned.append(mod)
                 log = get_util_logger()
                 log.warn("Warning: missing %s module", mod)
             return False
     return True
Exemple #25
0
def do_get_desktop_background_paths():
    try:
        import winreg   #@UnresolvedImport @Reimport
        key_path = "Control Panel\\Desktop"
        key = winreg.OpenKey(winreg.HKEY_CURRENT_USER, key_path, 0, winreg.KEY_READ)    #@UndefinedVariable
        wallpaper = winreg.QueryValueEx(key, 'WallPaper')[0]    #@UndefinedVariable
        return [wallpaper,]
    except Exception:
        log = get_util_logger()
        log("do_get_desktop_background_paths()", exc_info=True)
    return []
Exemple #26
0
def create_uinput_pointer_device(uuid, uid):
    log = get_util_logger()
    try:
        import uinput
    except (ImportError, NameError) as e:
        log.error("Error: cannot access python uinput module:")
        log.error(" %s", e)
        return None
    events = (
        uinput.REL_X,
        uinput.REL_Y,
        uinput.REL_WHEEL,
        #REL_HIRES_WHEEL = 0x10
        #uinput.REL_HWHEEL,
        uinput.BTN_LEFT,
        uinput.BTN_RIGHT,
        uinput.BTN_MIDDLE,
        uinput.BTN_SIDE,
        uinput.BTN_EXTRA,
        uinput.BTN_FORWARD,
        uinput.BTN_BACK,
    )
    BUS_USB = 0x03
    #BUS_VIRTUAL = 0x06
    VENDOR = 0xffff
    PRODUCT = 0x1000
    #our xpra_udev_product_version script will use the version attribute to set
    #the udev OWNER value
    VERSION = uid
    name = "Xpra Virtual Pointer %s" % uuid
    try:
        uinput_pointer = uinput.Device(events,
                                       name=name,
                                       bustype=BUS_USB,
                                       vendor=VENDOR,
                                       product=PRODUCT,
                                       version=VERSION)
    except OSError as e:
        log("uinput.Device creation failed", exc_info=True)
        if os.getuid() == 0:
            #running as root, this should work!
            log.error("Error: cannot open uinput,")
            log.error(" make sure that the kernel module is loaded")
            log.error(" and that the /dev/uinput device exists:")
            log.error(" %s", e)
        else:
            log.info("cannot access uinput: %s", e)
        return None
    dev_path = get_uinput_device_path(uinput_pointer)
    if not dev_path:
        uinput_pointer.destroy()
        return None
    return name, uinput_pointer, dev_path
Exemple #27
0
def kill_xvfb(xvfb_pid):
    log = get_util_logger()
    log.info("killing xvfb with pid %s", xvfb_pid)
    try:
        os.kill(xvfb_pid, signal.SIGTERM)
    except OSError as e:
        log.info("failed to kill xvfb process with pid %s:", xvfb_pid)
        log.info(" %s", e)
    from xpra.x11.vfb_util import PRIVATE_XAUTH
    xauthority = os.environ.get("XAUTHORITY")
    if PRIVATE_XAUTH and xauthority and os.path.exists(xauthority):
        os.unlink(xauthority)
Exemple #28
0
def source_env(source=()) -> dict:
    log = get_util_logger()
    log("source_env(%s)", source)
    env = {}
    for f in source:
        if not f:
            continue
        e = env_from_sourcing(f)
        log("source_env %s=%s", f, e)
        env.update(e)
    log("source_env(%s)=%s", source, env)
    return env
Exemple #29
0
 def get_all_namedpipes(self):
     log = get_util_logger()
     xpra_pipes = {}
     for pipe_name in os.listdir(PIPE_PATH):
         if not pipe_name.startswith(PIPE_PREFIX):
             log("found non-xpra pipe: %s", pipe_name)
             continue
         name = pipe_name[len(PIPE_PREFIX):]
         #found an xpra pipe
         #FIXME: filter using matching_display?
         xpra_pipes[name] = pipe_name
     log("get_all_namedpipes()=%s", xpra_pipes)
     return xpra_pipes
Exemple #30
0
def ival(key, default, minv=0, maxv=None) -> int:
    try:
        v = os.environ.get("XPRA_BATCH_%s" % key)
        if v is None:
            return default
        iv = int(v)
        assert minv is None or minv<=iv, "value for %s is too small: %s (minimum is %s)" % (key, iv, minv)
        assert maxv is None or maxv>=iv, "value for %s is too high: %s (maximum is %s)" % (key, iv, maxv)
        return iv
    except Exception as e:
        from xpra.os_util import get_util_logger
        log = get_util_logger()
        log.warn("failed to parse value '%s' for %s: %s", v, key, e)
        return default