--- vartree.py +++ vartree.py @@ -4574,6 +4574,43 @@ mode='w', encoding=_encodings['repo.content'], errors='backslashreplace') + + hashtype = self.settings.get("INTEGRITY_HASH").upper() + if hashtype is None: + hashtype = "SHA512" + elif hashtype != "SHA1" and hashtype != "SHA256": + hashtype = "SHA512" + + # open CONTENTS_DIGESTS file (possibly overwriting old one) for recording + # Use atomic_ofstream for automatic coercion of raw bytes to + # unicode, in order to prevent TypeError when writing raw bytes + # to TextIOWrapper with python2. + digfile = atomic_ofstream(_unicode_encode( + os.path.join(self.dbtmpdir, 'CONTENTS_DIGESTS_'+hashtype), + encoding=_encodings['fs'], errors='strict'), + mode='w', encoding=_encodings['repo.content'], + errors='backslashreplace') + + # open CONTENTS_DIGESTS file (possibly overwriting old one) for recording + # Use atomic_ofstream for automatic coercion of raw bytes to + # unicode, in order to prevent TypeError when writing raw bytes + # to TextIOWrapper with python2. + modfile = atomic_ofstream(_unicode_encode( + os.path.join(self.dbtmpdir, 'CONTENTS_MODES'), + encoding=_encodings['fs'], errors='strict'), + mode='w', encoding=_encodings['repo.content'], + errors='backslashreplace') + + # open CONTENTS_DIGESTS file (possibly overwriting old one) for recording + # Use atomic_ofstream for automatic coercion of raw bytes to + # unicode, in order to prevent TypeError when writing raw bytes + # to TextIOWrapper with python2. + paxfile = atomic_ofstream(_unicode_encode( + os.path.join(self.dbtmpdir, 'CONTENTS_ATTRS_PAX'), + encoding=_encodings['fs'], errors='strict'), + mode='w', encoding=_encodings['repo.content'], + errors='backslashreplace') + # Don't bump mtimes on merge since some application require # preservation of timestamps. This means that the unmerge phase must # check to see if file belongs to an installed instance in the same @@ -4586,7 +4623,7 @@ # we do a first merge; this will recurse through all files in our srcroot but also build up a # "second hand" of symlinks to merge later - if self.mergeme(srcroot, destroot, outfile, secondhand, + if self.mergeme(srcroot, destroot, outfile, digfile, modfile, paxfile, hashtype, secondhand, self.settings["EPREFIX"].lstrip(os.sep), cfgfiledict, mymtime): return 1 @@ -4598,7 +4635,7 @@ # couldn't get merged will be added to thirdhand. thirdhand = [] - if self.mergeme(srcroot, destroot, outfile, thirdhand, + if self.mergeme(srcroot, destroot, outfile, digfile, modfile, paxfile, hashtype, thirdhand, secondhand, cfgfiledict, mymtime): return 1 @@ -4612,7 +4649,7 @@ if len(secondhand): # force merge of remaining symlinks (broken or circular; oh well) - if self.mergeme(srcroot, destroot, outfile, None, + if self.mergeme(srcroot, destroot, outfile, digfile, modfile, paxfile, hashtype, None, secondhand, cfgfiledict, mymtime): return 1 @@ -4623,6 +4660,18 @@ outfile.flush() outfile.close() + #if we opened it, close it + digfile.flush() + digfile.close() + + #if we opened it, close it + modfile.flush() + modfile.close() + + #if we opened it, close it + paxfile.flush() + paxfile.close() + # write out our collection of md5sums if cfgfiledict != cfgfiledict_orig: cfgfiledict.pop("IGNORE", None) @@ -4634,7 +4683,7 @@ return os.EX_OK - def mergeme(self, srcroot, destroot, outfile, secondhand, stufftomerge, cfgfiledict, thismtime): + def mergeme(self, srcroot, destroot, outfile, digfile, modfile, paxfile, hashtype, secondhand, stufftomerge, cfgfiledict, thismtime): """ This function handles actual merging of the package contents to the livefs. @@ -4646,6 +4695,12 @@ @type destroot: String (Path) @param outfile: File to log operations to @type outfile: File Object + @param digfile: File to log digests info to + @type digfile: File Object + @param modfile: File to log mode info to + @type modfile: File Object + @param paxfile: File to log mode info to + @type paxfile: File Object @param secondhand: A set of items to merge in pass two (usually or symlinks that point to non-existing files that may get merged later) @type secondhand: List @@ -4784,6 +4839,39 @@ # confmem rejected this update zing = "---" + digest_length = 0 + if hashtype == "SHA1": + digest_length = 40 + elif hashtype == "SHA256": + digest_length = 64 + elif hashtype == "SHA512": + digest_length = 128 + + if stat.S_ISREG(mymode): + line_digest = portage.checksum.perform_checksum(mysrc, hashtype, 0)[0]+"\n" + line_mode = "mode:"+oct(mymode)[-4:]+"\n" + + attrlist = xattr.list(mysrc) + if len(attrlist)>0: + for i in attrlist: + if i == "user.pax.flags": + line_attr_pax = _unicode_decode(xattr.get(mysrc, "user.pax.flags")).zfill(5)+"\n" + else: + line_attr_pax = "00000\n" + + elif stat.S_ISDIR(mymode): + line_digest = '{num:0{width}}\n'.format(num=0, width=digest_length) + line_mode = "mode:"+oct(mymode)[-4:]+"\n" + line_attr_pax = "00000\n" + else: #LINK, FIFO, DEV + line_digest = '{num:0{width}}\n'.format(num=0, width=digest_length) + line_mode = "mode:"+oct(mymode)[-4:]+"\n" + line_attr_pax = "00000\n" + + digfile.write(line_digest) + modfile.write(line_mode) + paxfile.write(line_attr_pax) + if stat.S_ISLNK(mymode): # we are merging a symbolic link # Pass in the symlink target in order to bypass the