def init_client_mmap(token, mmap_group=None, socket_filename=None, size=128 * 1024 * 1024): """ Initializes an mmap area, writes the token in it and returns: (success flag, mmap_area, mmap_size, temp_file, mmap_filename) The caller must keep hold of temp_file to ensure it does not get deleted! This is used by the client. """ if not can_use_mmap(): log.error("cannot use mmap: python version is too old?") return False, None, 0, None, None log("init_mmap(%s, %s, %s)", token, mmap_group, socket_filename) try: import mmap import tempfile from stat import S_IRUSR, S_IWUSR, S_IRGRP, S_IWGRP mmap_dir = os.getenv("TMPDIR", "/tmp") if not os.path.exists(mmap_dir): raise Exception("TMPDIR %s does not exist!" % mmap_dir) #create the mmap file, the mkstemp that is called via NamedTemporaryFile ensures #that the file is readable and writable only by the creating user ID try: temp = tempfile.NamedTemporaryFile(prefix="xpra.", suffix=".mmap", dir=mmap_dir) except OSError as e: log.error("Error: cannot create mmap file:") log.error(" %s", e) return False, None, 0, None, None #keep a reference to it so it does not disappear! mmap_temp_file = temp mmap_filename = temp.name fd = temp.file.fileno() #set the group permissions and gid if the mmap-group option is specified if mmap_group and type(socket_filename) == str and os.path.exists( socket_filename): s = os.stat(socket_filename) os.fchown(fd, -1, s.st_gid) os.fchmod(fd, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP) assert size >= 1024 * 1024, "mmap size is too small: %s (minimum is 1MB)" % to_std_unit( size) assert size <= 1024 * 1024 * 1024, "mmap is too big: %s (maximum is 1GB)" % to_std_unit( size) unit = max(4096, mmap.PAGESIZE) #add 8 bytes for the mmap area control header zone: mmap_size = roundup(size + 8, unit) log("using mmap file %s, fd=%s, size=%s", mmap_filename, fd, mmap_size) os.lseek(fd, mmap_size - 1, os.SEEK_SET) assert os.write(fd, b'\x00') os.lseek(fd, 0, os.SEEK_SET) mmap_area = mmap.mmap(fd, length=mmap_size) write_mmap_token(mmap_area, token) return True, mmap_area, mmap_size, mmap_temp_file, mmap_filename except Exception as e: log.error("failed to setup mmap: %s", e, exc_info=True) clean_mmap(mmap_filename) return False, None, 0, None, None
def init_client_mmap(token, mmap_group=None, socket_filename=None, size=128*1024*1024): """ Initializes an mmap area, writes the token in it and returns: (success flag, mmap_area, mmap_size, temp_file, mmap_filename) The caller must keep hold of temp_file to ensure it does not get deleted! This is used by the client. """ if not can_use_mmap(): log.error("cannot use mmap: python version is too old?") return False, None, 0, None, None log("init_mmap(%s, %s, %s)", token, mmap_group, socket_filename) try: import mmap import tempfile from stat import S_IRUSR,S_IWUSR,S_IRGRP,S_IWGRP mmap_dir = os.getenv("TMPDIR", "/tmp") if not os.path.exists(mmap_dir): raise Exception("TMPDIR %s does not exist!" % mmap_dir) #create the mmap file, the mkstemp that is called via NamedTemporaryFile ensures #that the file is readable and writable only by the creating user ID try: temp = tempfile.NamedTemporaryFile(prefix="xpra.", suffix=".mmap", dir=mmap_dir) except OSError as e: log.error("Error: cannot create mmap file:") log.error(" %s", e) return False, None, 0, None, None #keep a reference to it so it does not disappear! mmap_temp_file = temp mmap_filename = temp.name fd = temp.file.fileno() #set the group permissions and gid if the mmap-group option is specified if mmap_group and type(socket_filename)==str and os.path.exists(socket_filename): s = os.stat(socket_filename) os.fchown(fd, -1, s.st_gid) os.fchmod(fd, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP) assert size>=1024*1024, "mmap size is too small: %s (minimum is 1MB)" % to_std_unit(size) assert size<=1024*1024*1024, "mmap is too big: %s (maximum is 1GB)" % to_std_unit(size) unit = max(4096, mmap.PAGESIZE) #add 8 bytes for the mmap area control header zone: mmap_size = roundup(size + 8, unit) log("using mmap file %s, fd=%s, size=%s", mmap_filename, fd, mmap_size) os.lseek(fd, mmap_size-1, os.SEEK_SET) assert os.write(fd, b'\x00') os.lseek(fd, 0, os.SEEK_SET) mmap_area = mmap.mmap(fd, length=mmap_size) write_mmap_token(mmap_area, token) return True, mmap_area, mmap_size, mmap_temp_file, mmap_filename except Exception as e: log.error("failed to setup mmap: %s", e, exc_info=True) clean_mmap(mmap_filename) return False, None, 0, None, None
def unit(scale): if scale==1: return "" else: unit, value = to_std_unit(scale) if value==1: return str(unit) return "x%s%s" % (int(value), unit)
def _process_print(self, _proto, packet): #ie: from the xpraforwarder we call this command: #command = ["xpra", "print", "socket:/path/tosocket", # filename, mimetype, source, title, printer, no_copies, print_options] assert self.file_transfer.printing #printlog("_process_print(%s, %s)", proto, packet) if len(packet) < 3: printlog.error("Error: invalid print packet, only %i arguments", len(packet)) printlog.error(" %s", [repr_ellipsized(x) for x in packet]) return def s(b): try: return b.decode("utf-8") except Exception: return bytestostr(b) filename = s(packet[1]) file_data = packet[2] mimetype, source_uuid, title, printer, no_copies, print_options = "", "*", "unnamed document", "", 1, "" if len(packet) >= 4: mimetype = bytestostr(packet[3]) if len(packet) >= 5: source_uuid = bytestostr(packet[4]) if len(packet) >= 6: title = s(packet[5]) if len(packet) >= 7: printer = bytestostr(packet[6]) if len(packet) >= 8: no_copies = int(packet[7]) if len(packet) >= 9: print_options = packet[8] #parse and validate: if len(mimetype) >= 128: printlog.error("Error: invalid mimetype in print packet:") printlog.error(" %s", repr_ellipsized(mimetype)) return if not isinstance(print_options, dict): s = bytestostr(print_options) print_options = {} for x in s.split(" "): parts = x.split("=", 1) if len(parts) == 2: print_options[parts[0]] = parts[1] printlog("process_print: %s", (filename, mimetype, "%s bytes" % len(file_data), source_uuid, title, printer, no_copies, print_options)) printlog("process_print: got %s bytes for file %s", len(file_data), filename) #parse the print options: u = hashlib.sha1() u.update(file_data) printlog("sha1 digest: %s", u.hexdigest()) options = { "printer": printer, "title": title, "copies": no_copies, "options": print_options, "sha1": u.hexdigest(), } printlog("parsed printer options: %s", options) if SAVE_PRINT_JOBS: self._save_print_job(filename, file_data) sent = 0 sources = tuple(self._server_sources.values()) printlog("will try to send to %i clients: %s", len(sources), sources) for ss in sources: if source_uuid not in ("*", ss.uuid): printlog("not sending to %s (uuid=%s, wanted uuid=%s)", ss, ss.uuid, source_uuid) continue if not ss.printing: if source_uuid != '*': printlog.warn("Warning: printing is not enabled for:") printlog.warn(" %s", ss) else: printlog("printing is not enabled for %s", ss) continue if not ss.printers: printlog.warn("Warning: client %s does not have any printers", ss.uuid) continue if printer not in ss.printers: printlog.warn( "Warning: client %s does not have a '%s' printer", ss.uuid, printer) continue printlog("'%s' sent to %s for printing on '%s'", bytestostr(title or filename), ss, printer) if ss.send_file(filename, mimetype, file_data, len(file_data), True, True, options): sent += 1 #warn if not sent: if sent == 0: l = printlog.warn else: l = printlog.info unit_str, v = to_std_unit(len(file_data), unit=1024) l("'%s' (%i%sB) sent to %i client%s for printing", title or filename, v, unit_str, sent, engs(sent))
def init_client_mmap(mmap_group=None, socket_filename=None, size=128*1024*1024, filename=None): """ Initializes an mmap area, writes the token in it and returns: (success flag, mmap_area, mmap_size, temp_file, mmap_filename) The caller must keep hold of temp_file to ensure it does not get deleted! This is used by the client. """ def rerr(): return False, False, None, 0, None, None log("init_mmap%s", (mmap_group, socket_filename, size, filename)) mmap_filename = filename mmap_temp_file = None delete = True try: import mmap unit = max(4096, mmap.PAGESIZE) #add 8 bytes for the mmap area control header zone: mmap_size = roundup(size + 8, unit) if WIN32: if not filename: from xpra.net.crypto import get_hex_uuid filename = "xpra-%s" % get_hex_uuid() mmap_filename = filename mmap_area = mmap.mmap(0, mmap_size, filename) #not a real file: delete = False mmap_temp_file = None else: assert POSIX if filename: if os.path.exists(filename): fd = os.open(filename, os.O_EXCL | os.O_RDWR) mmap_size = os.path.getsize(mmap_filename) #mmap_size = 4*1024*1024 #size restriction needed with ivshmem delete = False log.info("Using existing mmap file '%s': %sMB", mmap_filename, mmap_size//1024//1024) else: import errno flags = os.O_CREAT | os.O_EXCL | os.O_RDWR try: fd = os.open(filename, flags) mmap_temp_file = None #os.fdopen(fd, 'w') mmap_filename = filename except OSError as e: if e.errno == errno.EEXIST: log.error("Error: the mmap file '%s' already exists", filename) return rerr() raise else: import tempfile mmap_dir = os.getenv("TMPDIR", "/tmp") if not os.path.exists(mmap_dir): raise Exception("TMPDIR %s does not exist!" % mmap_dir) #create the mmap file, the mkstemp that is called via NamedTemporaryFile ensures #that the file is readable and writable only by the creating user ID try: temp = tempfile.NamedTemporaryFile(prefix="xpra.", suffix=".mmap", dir=mmap_dir) except OSError as e: log.error("Error: cannot create mmap file:") log.error(" %s", e) return rerr() #keep a reference to it so it does not disappear! mmap_temp_file = temp mmap_filename = temp.name fd = temp.file.fileno() #set the group permissions and gid if the mmap-group option is specified if mmap_group and type(socket_filename)==str and os.path.exists(socket_filename): from stat import S_IRUSR,S_IWUSR,S_IRGRP,S_IWGRP s = os.stat(socket_filename) os.fchown(fd, -1, s.st_gid) os.fchmod(fd, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP) assert mmap_size>=1024*1024, "mmap size is too small: %s (minimum is 1MB)" % to_std_unit(mmap_size) assert mmap_size<=1024*1024*1024, "mmap is too big: %s (maximum is 1GB)" % to_std_unit(mmap_size) log("using mmap file %s, fd=%s, size=%s", mmap_filename, fd, mmap_size) os.lseek(fd, mmap_size-1, os.SEEK_SET) assert os.write(fd, b'\x00') os.lseek(fd, 0, os.SEEK_SET) mmap_area = mmap.mmap(fd, length=mmap_size) return True, delete, mmap_area, mmap_size, mmap_temp_file, mmap_filename except Exception as e: log("failed to setup mmap: %s", e, exc_info=True) log.error("Error: mmap setup failed:") log.error(" %s", e) clean_mmap(mmap_filename) return rerr()