diff options
Diffstat (limited to 'pym/portage_checksum.py')
-rw-r--r-- | pym/portage_checksum.py | 134 |
1 files changed, 134 insertions, 0 deletions
diff --git a/pym/portage_checksum.py b/pym/portage_checksum.py new file mode 100644 index 000000000..cefcda6db --- /dev/null +++ b/pym/portage_checksum.py @@ -0,0 +1,134 @@ +# portage_checksum.py -- core Portage functionality +# Copyright 1998-2004 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 +# $Header: /var/cvsroot/gentoo-src/portage/pym/portage_checksum.py,v 1.10.2.2 2005/08/10 05:42:03 ferringb Exp $ +cvs_id_string="$Id: portage_checksum.py,v 1.10.2.2 2005/08/10 05:42:03 ferringb Exp $"[5:-2] + +from portage_const import PRIVATE_PATH,PRELINK_BINARY +import os +import shutil +import stat +import portage_exec +import portage_util +import portage_locks +import commands +import sha + +prelink_capable = False +if os.path.exists(PRELINK_BINARY): + results = commands.getstatusoutput(PRELINK_BINARY+" --version > /dev/null 2>&1") + if (results[0] >> 8) == 0: + prelink_capable=1 + del results + +def perform_md5(x, calc_prelink=0): + return perform_checksum(x, md5hash, calc_prelink)[0] + +def perform_sha1(x, calc_prelink=0): + return perform_checksum(x, sha1hash, calc_prelink)[0] + +def perform_all(x, calc_prelink=0): + mydict = {} + mydict["SHA1"] = perform_sha1(x, calc_prelink) + mydict["MD5"] = perform_md5(x, calc_prelink) + return mydict + +def get_valid_checksum_keys(): + return ["SHA1", "MD5"] + +def verify_all(filename, mydict, calc_prelink=0, strict=0): + # Dict relates to single file only. + # returns: (passed,reason) + file_is_ok = True + reason = "Reason unknown" + try: + if mydict["size"] != os.stat(filename)[stat.ST_SIZE]: + return False,"Filesize does not match recorded size" + except OSError, e: + return False, str(e) + for x in mydict.keys(): + if x == "size": + continue + elif x == "SHA1": + if mydict[x] != perform_sha1(filename, calc_prelink=calc_prelink): + if strict: + raise portage_exception.DigestException, "Failed to verify '$(file)s' on checksum type '%(type)s'" % {"file":filename, "type":x} + else: + file_is_ok = False + reason = "Failed on %s verification" % (x,) + break + elif x == "MD5": + if mydict[x] != perform_md5(filename, calc_prelink=calc_prelink): + if strict: + raise portage_exception.DigestException, "Failed to verify '$(file)s' on checksum type '%(type)s'" % {"file":filename, "type":x} + else: + file_is_ok = False + reason = "Failed on %s verification" % (x,) + break + return file_is_ok,reason + +# We _try_ to load this module. If it fails we do the slow fallback. +try: + import fchksum + + def md5hash(filename): + return fchksum.fmd5t(filename) + +except ImportError: + import md5 + def md5hash(filename): + f = open(filename, 'rb') + blocksize=32768 + data = f.read(blocksize) + size = 0L + sum = md5.new() + while data: + sum.update(data) + size = size + len(data) + data = f.read(blocksize) + f.close() + + return (sum.hexdigest(),size) + +def sha1hash(filename): + f = open(filename, 'rb') + blocksize=32768 + data = f.read(blocksize) + size = 0L + sum = sha.new() + while data: + sum.update(data) + size = size + len(data) + data = f.read(blocksize) + f.close() + + return (sum.hexdigest(),size) + +def perform_checksum(filename, hash_function=md5hash, calc_prelink=0): + myfilename = filename[:] + prelink_tmpfile = PRIVATE_PATH+"/prelink-checksum.tmp."+str(os.getpid()) + mylock = None + + if calc_prelink and prelink_capable: + mylock = portage_locks.lockfile(prelink_tmpfile, wantnewlockfile=1) + # Create non-prelinked temporary file to md5sum. + # Raw data is returned on stdout, errors on stderr. + # Non-prelinks are just returned. + try: + shutil.copy2(filename,prelink_tmpfile) + except SystemExit, e: + raise + except Exception,e: + portage_util.writemsg("!!! Unable to copy file '"+str(filename)+"'.\n") + portage_util.writemsg("!!! "+str(e)+"\n") + raise + portage_exec.spawn(PRELINK_BINARY+" --undo "+prelink_tmpfile,fd_pipes={}) + myfilename=prelink_tmpfile + + myhash, mysize = hash_function(myfilename) + + if calc_prelink and prelink_capable: + os.unlink(prelink_tmpfile) + portage_locks.unlockfile(mylock) + + return (myhash,mysize) |