def write_file(file_path, text): """ Write some text into a temporary file, creating its directory as needed, and then atomically move to target location. :param str file_path: the path to the file. :param str text: the file content. :raises: lib.errors.SCIONIOError: IO error occurred """ # ":" is an illegal filename char on both windows and OSX, so disallow it globally to prevent # incompatibility. assert ":" not in file_path, file_path dir_ = os.path.dirname(file_path) try: os.makedirs(dir_, exist_ok=True) except OSError as e: raise SCIONIOError("Error creating '%s' dir: %s" % (dir_, e.strerror)) from None tmp_file = file_path + ".new" try: with open(tmp_file, 'w') as f: f.write(text) except OSError as e: raise SCIONIOError("Error creating/writing to temp file '%s': %s" % (file_path, e.strerror)) from None try: os.rename(tmp_file, file_path) except OSError as e: raise SCIONIOError("Error moving '%s' to '%s': %s" % (tmp_file, file_path, e.strerror)) from None
def copy_file(src, dst): dst_dir = os.path.dirname(dst) try: os.makedirs(dst_dir, exist_ok=True) except OSError as e: raise SCIONIOError("Error creating dir '%s': %s" % (dst_dir, e.strerror)) from None try: shutil.copyfile(src, dst) except OSError as e: raise SCIONIOError("Error copying '%s' to '%s': %s" % (src, dst, e.strerror)) from None
def recv(self, block=True): """ Read data from socket. :returns: bytestring containing received data. """ flags = 0 if not block: flags = MSG_DONTWAIT buf = recv_all(self.sock, self.COOKIE_LEN + 5, flags) if not buf: return None, None cookie, addr_type, packet_len = struct.unpack("!8sBI", buf) if cookie != self.COOKIE: raise SCIONIOError("Dispatcher socket out of sync") port_len = 0 if addr_type != AddrType.NONE: port_len = 2 addr_len = haddr_get_type(addr_type).LEN # We know there is data coming, block here to avoid sync problems. buf = recv_all(self.sock, addr_len + port_len + packet_len, 0) if addr_len > 0: addr = buf[:addr_len] port = struct.unpack("!H", buf[addr_len:addr_len + port_len]) sender = (str(ipaddress.ip_address(addr)), port) else: addr = "" port = 0 sender = (None, None) packet = buf[addr_len + port_len:] return packet, sender
def read_file(file_path): """ Read and return contents of a file. :param str file_path: the path to the file. :returns: the file's contents. :rtype: str :raises: lib.errors.SCIONIOError: error opening/reading from file. """ try: with open(file_path) as file_handler: return file_handler.read() except OSError as e: raise SCIONIOError("Unable to open '%s': %s" % (file_path, e.strerror)) from None
def load_yaml_file(file_path): """ Read and parse a YAML config file. :param str file_path: the path to the file. :returns: YAML data :rtype: dict :raises: lib.errors.SCIONIOError: error opening/reading from file. lib.errors.SCIONYAMLError: error parsing file. """ try: with open(file_path) as f: return yaml.load(f) except OSError as e: raise SCIONIOError("Error opening '%s': %s" % (file_path, e.strerror)) from None except (yaml.scanner.ScannerError) as e: raise SCIONYAMLError("Error parsing '%s': %s" % (file_path, e)) from None
def load_json_file(file_path): """ Read and parse a JSON config file. :param str file_path: the path to the file. :returns: JSON data :rtype: dict :raises: lib.errors.SCIONIOError: error opening/reading from file. lib.errors.SCIONJSONError: error parsing file. """ try: with open(file_path) as f: return json.load(f) except OSError as e: raise SCIONIOError("Error opening '%s': %s" % (file_path, e.strerror)) from None except (ValueError, KeyError, TypeError) as e: raise SCIONJSONError("Error parsing '%s': %s" % (file_path, e)) from None