def _isPathValid(self, tok=None, path=None, cmd=None): '''Check the validity of an absolute path name.''' if tok: path = modtok.parse_token(tok, df.yes)[0] path = "/".join(path) if not path: return False if path[0] != '/': return False b = False for d in rootdirs: if path.startswith(d): b = True break if not b: return False if path[1] == "_" and "internal" not in cmd: return False if path.find('//') != -1: return False return True
def removeItem(self, tok): path, _ = parse_token(tok, bVal=defs.auto) if len(path) == 1: if not (self.isWritable() and self[path[0]].isWritable()): raise IKException(ErrorCode.permissionDenied, tok, "Item is read-only") del self[path[0]] return self sec = self.getItem(path[:-1]) return sec.removeItem(path[-1])
def handleBinToken(self, dest, tok, optmap): if dest: tok = os.path.join( dest, tok ) path, nam, val = modtok.parse_token( tok, bNam=True, bVal=True) sec = self.fs.getItem( path ) exefile = sec.getItem( nam ) log.debug( "Calling: " + exefile.val + " " + val ) if tok.startswith(stor.BINPATH + "/sh/"): subprocess.call( exefile.val + " " + val, shell=True ) else: subprocess.call( [exefile.val, val], shell=False )
def addItem(self, tok: str = None, path: list = None, val=None, binaryVal=None, attrs=None, addMode=defs.noOverwrite): '''Add a token or section to stor''' if tok: if not binaryVal: path, val = parse_token(tok, bVal=defs.auto) else: path, _ = parse_token(tok, bVal=defs.no) val = binaryVal else: if val and binaryVal: raise IKException(ErrorCode.unsupportedParameterValue, val, "Both value and binary value are specified") if binaryVal: val = binaryVal if not path: raise IKException(ErrorCode.unknownDataFormat, val, "Token name is not specified") if val: # Storage contains items of two types: SVal and Stor: if not isinstance(val, SVal) and not isinstance(val, dict): nam = path[-1] val = SVal(rootStor=self.rootStor, name=nam, attrs=attrs, val=val) return self._addItem(path=path, val=val, attrs=attrs, addMode=addMode)
def getItem(self, path): '''Return a token or section with the given path.''' if type(path) is str: lpath, _ = parse_token(path, bVal=defs.auto) return self.getItem(lpath) else: if path: if path[0] not in self.keys(): raise IKException(ErrorCode.objectNotExists, path[0], "Item doesn't exist") if len(path) > 1: return self[path[0]].getItem(path[1:]) else: return self[path[0]] raise IKException(ErrorCode.nameError, "getItem: path is empty") return self
def serialize(self, fhd, read=True, fpath=None): '''Serialization (writing) for storage values''' logsr.debug("SVal.ser() is called...") fh = self.getSerializationFile(fhd, read, fpath) if read: '''Returns: 0 - EOF 1 - OK 2 - Non-token line ''' tok = b"" val = b"" attrs = None continued = "" binaryVal = None while True: origPos = fh.tell() l = fh.readline().rstrip(b'\n') if l: if l[-1] == '\\': continued += l[:-1] continue if continued: l = continued continued = "" if l and (l[0] == ord(' ') or l[0] == ord('\t')): if not tok: raise IKException(ErrorCode.unknownDataFormat, l, "Cannot parse token.") tok += b" " + l[1:] elif tok: if val: tok += val val = b"" mtok = reTok.match(tok.decode(errors="surrogateescape")) if not mtok or mtok.lastindex != 2: raise IKException(ErrorCode.unknownDataFormat, l, "Cannot parse token") tok = tok.replace(b'\n\t', b'\n') enc = "utf-8" compr = False binaryVal = None if attrs: enc = attrs.get("encoding", enc) compr = bool(attrs.get("compression", str(compr))) if enc != "binary": tok = tok.decode(enc, errors="surrogateescape") else: binaryVal = tok tok = "" fh.seek(origPos, SEEK_SET) break elif l.startswith(b"//attributes "): if attrs: raise IKException(ErrorCode.unrecognizedParameter, tok, "Unknown data file format") _, _, s = l.decode().partition(" ") lattrs = s.split(" ") attrs = {} for x in lattrs: k, _, v = x.partition("=") if not (k and v): raise IKException( ErrorCode.unrecognizedSyntax, x, "Unrecognized syntax for an attribute") attrs[k] = v if k == SItem.persPathAttrName: if not os.path.isabs(v): v = os.path.normpath( os.path.join(os.path.dirname(fh.name), v)) with open(v, "rb") as f: val = f.read() logsr.debug("SVal.ser() reads attributes: {0}".format(s)) tok = b"" elif l.startswith(b'//'): fh.seek(origPos, SEEK_SET) logsr.debug("SVal.ser() returns 2") return 2 elif l: tok = l else: # EOF logsr.debug("SVal.ser() returns 0") return 0 if not binaryVal: path, val = parse_token(tok, bVal=defs.yes) else: path, _ = parse_token(tok, bVal=defs.no) val = binaryVal self.name = path[-1] self.attrs = attrs if attrs else {} self.val = val logsr.debug("SVal.ser() reads token: {0}={1}".format( path[-1], val)) return 1 else: # if SVal has separate storage, fh points to it and fhcur to stor's storage; # otherwise, fh and fhcur are the same fhcur = fhd.get("cur", fh) def writeAttrs(fh, attrs): '''Writes token attributs to data file at the current file position.''' if attrs: fhcur.write(b"//attributes") s = "" for k, v in attrs.items(): s += " {0}={1}".format(k, v) fhcur.write(s.encode()) fhcur.write(b'\n') logsr.debug( "SVal.ser() writes to fhcur ({0}): attributes {1}". format(fhcur.name, s)) writeAttrs(fhcur, self.attrs) if self.attrs: enc = self.attrs.get("enc", "utf-8") else: enc = "utf-8" if type(self.val) is bytes or type(self.val) is bytearray: pass elif type(self.val) is str: v = self.val.encode(enc) else: v = repr(self.val).encode() v = v.replace(b'\n', b'\n\t') logsr.debug( "SVal.ser() writes to fhcur({0}) token name: {1}".format( fhcur.name, self.name)) fhcur.write("{0}=".format(self.name).encode(enc)) logsr.debug( "SVal.ser() writes to fhcur({0}) token value: {1}".format( fhcur.name, v)) fh.write(v) fhcur.write(b'\n') self.changed = False