diff --git a/pisi/constants.py b/pisi/constants.py index 80f73e91..6a0aded4 100644 --- a/pisi/constants.py +++ b/pisi/constants.py @@ -57,6 +57,7 @@ class Constants: self.__c.xz_suffix = ".xz" self.__c.partial_suffix = ".part" + self.__c.temporary_suffix = ".tmp" # suffix for auto generated debug packages self.__c.debug_name_suffix = "-dbginfo" diff --git a/pisi/fetcher.py b/pisi/fetcher.py index 251e1063..49c549f7 100644 --- a/pisi/fetcher.py +++ b/pisi/fetcher.py @@ -105,19 +105,21 @@ class UIHandler: class Fetcher: """Fetcher can fetch a file from various sources using various protocols.""" - def __init__(self, url, destdir): + def __init__(self, url, destdir, destfile=None): if not isinstance(url, pisi.uri.URI): url = pisi.uri.URI(url) if ctx.config.get_option("authinfo"): url.set_auth_info(ctx.config.get_option("authinfo")) - self.url = url - self.destdir = destdir - self.archive_file = os.path.join(self.destdir, self.url.filename()) - self.partial_file = self.archive_file + ctx.const.partial_suffix + self.url = url + self.destdir = destdir + self.destfile = destfile self.progress = None + self.archive_file = os.path.join(destdir, destfile or url.filename()) + self.partial_file = os.path.join(self.destdir, self.url.filename()) + ctx.const.partial_suffix + util.ensure_dirs(self.destdir) def fetch (self): @@ -222,7 +224,7 @@ class Fetcher: # helper function -def fetch_url(url, destdir, progress=None): - fetch = Fetcher(url, destdir) +def fetch_url(url, destdir, progress=None, destfile=None): + fetch = Fetcher(url, destdir, destfile) fetch.progress = progress fetch.fetch() diff --git a/pisi/file.py b/pisi/file.py index 4dddbeca..c1a9a172 100644 --- a/pisi/file.py +++ b/pisi/file.py @@ -108,13 +108,17 @@ class File: pisi.util.ensure_dirs(transfer_dir) + # Check file integrity before saving? + check_integrity = sha1sum or sign + if sha1sum: sha1filename = File.download(pisi.uri.URI(uri.get_uri() + '.sha1sum'), transfer_dir) sha1f = file(sha1filename) newsha1 = sha1f.read().split("\n")[0] if uri.is_remote_file() or copylocal: - localfile = pisi.util.join_path(transfer_dir, uri.filename()) + tmpfile = check_integrity and uri.filename() + ctx.const.temporary_suffix + localfile = pisi.util.join_path(transfer_dir, tmpfile or uri.filename()) # TODO: code to use old .sha1sum file, is this a necessary optimization? #oldsha1fn = localfile + '.sha1sum' @@ -128,10 +132,9 @@ class File: if uri.is_remote_file(): ctx.ui.info(_("Fetching %s") % uri.get_uri(), verbose=True) - pisi.fetcher.fetch_url(uri, transfer_dir, ctx.ui.Progress) + pisi.fetcher.fetch_url(uri, transfer_dir, ctx.ui.Progress, tmpfile) else: - # copy to transfer dir, - localfile = pisi.util.join_path(transfer_dir, uri.filename()) + # copy to transfer dir ctx.ui.info(_("Copying %s to transfer dir") % uri.get_uri(), verbose=True) shutil.copy(uri.get_uri(), transfer_dir) else: @@ -143,10 +146,25 @@ class File: localfile = pisi.util.join_path(transfer_dir, os.path.basename(localfile)) shutil.copy(oldfn, localfile) + def clean_temporary(): + temp_files = [sha1filename] + if check_integrity: + temp_files.append(localfile) + for filename in temp_files: + try: + os.unlink(filename) + except OSError: + pass + if sha1sum: if (pisi.util.sha1_file(localfile) != newsha1): + clean_temporary() raise Error(_("File integrity of %s compromised.") % uri) + if check_integrity: + shutil.move(localfile, origfile) + localfile = origfile + localfile = File.decompress(localfile, compress) return localfile diff --git a/pisi/package.py b/pisi/package.py index 06f6edda..e49d7818 100644 --- a/pisi/package.py +++ b/pisi/package.py @@ -23,6 +23,7 @@ import pisi.context as ctx import pisi.archive as archive import pisi.uri import pisi.metadata +import pisi.file import pisi.files import pisi.util as util import fetcher @@ -95,7 +96,7 @@ class Package: if not os.path.exists(self.filepath): try: - fetcher.fetch_url(url, dest, ctx.ui.Progress) + pisi.file.File.download(url, dest) except pisi.fetcher.FetchError: # Bug 3465 if ctx.get_option('reinstall'):