--- vartree.py +++ vartree.py @@ -77,6 +77,7 @@ from _emerge.SpawnProcess import SpawnProcess from ._ContentsCaseSensitivityManager import ContentsCaseSensitivityManager +from collections import OrderedDict import errno import fnmatch import gc @@ -89,6 +90,7 @@ import pwd import re import stat +import struct import sys import tempfile import textwrap @@ -1088,12 +1090,23 @@ else: relative_filename = filename[root_len:] contents_key = pkg._match_contents(relative_filename) - if contents_key: + index = -1 + try: + index = list(new_contents).index(filename)+1 + except ValueError: + print("List does not contain value") + if contents_key and index >= 0: # It's possible for two different paths to refer to the same # contents_key, due to directory symlinks. Therefore, pass a # default value to pop, in order to avoid a KeyError which # could otherwise be triggered (see bug #454400). new_contents.pop(contents_key, None) + self.removeFromContentsMeta(pkg.dbdir, index, "DIGESTS_SHA512") + self.removeFromContentsMeta(pkg.dbdir, index, "DIGESTS_SHA1") + self.removeFromContentsMeta(pkg.dbdir, index, "DIGESTS_SHA256") + self.removeFromContentsMeta(pkg.dbdir, index, "MODES") + self.removeFromContentsMeta(pkg.dbdir, index, "ATTRS_PAX") + self.removeFromContentsMeta(pkg.dbdir, index, "ATTRS_CAPS") removed += 1 if removed: @@ -1129,6 +1142,38 @@ self.writeContentsToContentsFile(pkg, new_contents, new_needed=new_needed) + def removeFromContentsMeta(self, vdbdir, index, type): + contents_file = "" + if (type in + {"DIGESTS_SHA512", + "DIGESTS_SHA256", + "DIGESTS_SHA1", + "MODES", + "ATTRS_PAX", + "ATTRS_CAPS"}): + contents_file = os.path.join(vdbdir, "CONTENTS_"+type) + else: + print("ERROR removeFromContentsMeta() got passed unexpected type "+type) + + if type == "DIGESTS_SHA512": linelen = 128+1 #including newline + elif type == "DIGESTS_SHA256": linelen = 64 + 1 + elif type == "DIGESTS_SHA1": linelen = 40+1 + elif type == "MODES": linelen = 4 + 1 + elif type == "ATTRS_PAX": linelen = 5 + 1 + elif type == "ATTRS_CAPS": linelen = 16 + 1 + else: + print("ERROR removeFromContentsMeta() got passed unexpected type "+type) + + if os.path.isfile(contents_file): + with open(contents_file,"r+") as f: + pre = f.read((index-1)*linelen) + f.read(129) + post = f.read() + f.seek(0, 0) + f.write(pre) + f.write(post) + f.truncate() + def writeContentsToContentsFile(self, pkg, new_contents, new_needed=None): """ @param pkg: package to write contents file for @@ -1784,7 +1829,7 @@ if self.contentscache is not None: return self.contentscache contents_file = os.path.join(self.dbdir, "CONTENTS") - pkgfiles = {} + pkgfiles = OrderedDict() try: with io.open(_unicode_encode(contents_file, encoding=_encodings['fs'], errors='strict'), @@ -3209,6 +3254,7 @@ preserve_paths.remove(f) continue new_contents[f_abs] = contents_entry + self.writeMetaData(f_abs) obj_type = contents_entry[0] showMessage(_(">>> needed %s %s\n") % (obj_type, f_abs), noiselevel=-1) @@ -3216,6 +3262,7 @@ parent_dir = os.path.dirname(f_abs) while len(parent_dir) > len(root): new_contents[parent_dir] = ["dir"] + self.writeMetaData(parent_dir) prev = parent_dir parent_dir = os.path.dirname(parent_dir) if prev == parent_dir: @@ -3225,6 +3272,67 @@ outfile.close() self._clear_contents_cache() + def writeMetaData(fname): + hashtype = "SHA512" + if hashtype is None: + hashtype = "SHA512" + elif hashtype != "SHA1" and hashtype != "SHA256": + hashtype = "SHA512" + + mystat = os.lstat(fname) + mymode = mystat[stat.ST_MODE] + + if stat.S_ISREG(mymode): + line_digest = portage.checksum.perform_checksum(fname, hashtype, 0)[0]+"\n" + line_mode = oct(mymode)[-4:]+"\n" + + attrlist = xattr.list(fname) + if len(attrlist)>0: + for i in attrlist: + if i == "user.pax.flags": + line_attr_pax = _unicode_decode(xattr.get(fname, "user.pax.flags")).zfill(5)+"\n" + if i == "security.capability": + caps = xattr.get(fname, "security.capability") # Take the actual value from xattr + caps_int = int(struct.unpack("0: + for i in attrlist: + if i == "user.pax.flags": + line_attr_pax = _unicode_decode(xattr.get(srcobj, "user.pax.flags")).zfill(5)+"\n" + if i == "security.capability": + caps = xattr.get(srcobj, "security.capability") # Take the actual value from xattr + caps_int = int(struct.unpack("