aboutsummaryrefslogtreecommitdiffstats
path: root/pym/portage/checksum.py
diff options
context:
space:
mode:
Diffstat (limited to 'pym/portage/checksum.py')
-rw-r--r--pym/portage/checksum.py100
1 files changed, 82 insertions, 18 deletions
diff --git a/pym/portage/checksum.py b/pym/portage/checksum.py
index daf4a0cbf..f24a90ffc 100644
--- a/pym/portage/checksum.py
+++ b/pym/portage/checksum.py
@@ -1,15 +1,16 @@
# checksum.py -- core Portage functionality
-# Copyright 1998-2012 Gentoo Foundation
+# Copyright 1998-2014 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
import portage
-from portage.const import PRELINK_BINARY,HASHING_BLOCKSIZE
+from portage.const import PRELINK_BINARY, HASHING_BLOCKSIZE
from portage.localization import _
from portage import os
from portage import _encodings
from portage import _unicode_encode
import errno
import stat
+import subprocess
import tempfile
#dict of all available hash functions
@@ -48,16 +49,15 @@ class _generate_hash_function(object):
@type filename: String
@return: The hash and size of the data
"""
- f = _open_file(filename)
- blocksize = HASHING_BLOCKSIZE
- data = f.read(blocksize)
- size = 0
- checksum = self._hashobject()
- while data:
- checksum.update(data)
- size = size + len(data)
+ with _open_file(filename) as f:
+ blocksize = HASHING_BLOCKSIZE
+ size = 0
+ checksum = self._hashobject()
data = f.read(blocksize)
- f.close()
+ while data:
+ checksum.update(data)
+ size = size + len(data)
+ data = f.read(blocksize)
return (checksum.hexdigest(), size)
@@ -163,11 +163,16 @@ hashfunc_map["size"] = getsize
prelink_capable = False
if os.path.exists(PRELINK_BINARY):
- results = portage.subprocess_getstatusoutput(
- "%s --version > /dev/null 2>&1" % (PRELINK_BINARY,))
- if (results[0] >> 8) == 0:
- prelink_capable=1
- del results
+ cmd = [PRELINK_BINARY, "--version"]
+ cmd = [_unicode_encode(x, encoding=_encodings['fs'], errors='strict')
+ for x in cmd]
+ proc = subprocess.Popen(cmd, stdout=subprocess.PIPE,
+ stderr=subprocess.STDOUT)
+ proc.communicate()
+ status = proc.wait()
+ if os.WIFEXITED(status) and os.WEXITSTATUS(status) == os.EX_OK:
+ prelink_capable = 1
+ del cmd, proc, status
def is_prelinkable_elf(filename):
f = _open_file(filename)
@@ -217,6 +222,64 @@ def _filter_unaccelarated_hashes(digests):
return digests
+class _hash_filter(object):
+ """
+ Implements filtering for PORTAGE_CHECKSUM_FILTER.
+ """
+
+ __slots__ = ('transparent', '_tokens',)
+
+ def __init__(self, filter_str):
+ tokens = filter_str.upper().split()
+ if not tokens or tokens[-1] == "*":
+ del tokens[:]
+ self.transparent = not tokens
+ tokens.reverse()
+ self._tokens = tuple(tokens)
+
+ def __call__(self, hash_name):
+ if self.transparent:
+ return True
+ matches = ("*", hash_name)
+ for token in self._tokens:
+ if token in matches:
+ return True
+ elif token[:1] == "-":
+ if token[1:] in matches:
+ return False
+ return False
+
+def _apply_hash_filter(digests, hash_filter):
+ """
+ Return a new dict containing the filtered digests, or the same
+ dict if no changes are necessary. This will always preserve at
+ at least one digest, in order to ensure that they are not all
+ discarded.
+ @param digests: dictionary of digests
+ @type digests: dict
+ @param hash_filter: A callable that takes a single hash name
+ argument, and returns True if the hash is to be used or
+ False otherwise
+ @type hash_filter: callable
+ """
+
+ verifiable_hash_types = set(digests).intersection(hashfunc_map)
+ verifiable_hash_types.discard("size")
+ modified = False
+ if len(verifiable_hash_types) > 1:
+ for k in list(verifiable_hash_types):
+ if not hash_filter(k):
+ modified = True
+ verifiable_hash_types.remove(k)
+ if len(verifiable_hash_types) == 1:
+ break
+
+ if modified:
+ digests = dict((k, v) for (k, v) in digests.items()
+ if k == "size" or k in verifiable_hash_types)
+
+ return digests
+
def verify_all(filename, mydict, calc_prelink=0, strict=0):
"""
Verify all checksums against a file.
@@ -275,9 +338,10 @@ def verify_all(filename, mydict, calc_prelink=0, strict=0):
{"file" : filename, "type" : x})
else:
file_is_ok = False
- reason = (("Failed on %s verification" % x), myhash,mydict[x])
+ reason = (("Failed on %s verification" % x), myhash, mydict[x])
break
- return file_is_ok,reason
+
+ return file_is_ok, reason
def perform_checksum(filename, hashname="MD5", calc_prelink=0):
"""