--- /tmp/bintree.py 2013-11-05 04:12:41.138995391 -0500 +++ /usr/lib/portage/pym/portage/dbapi/bintree.py 2013-11-11 19:09:06.084788754 -0500 @@ -939,10 +939,41 @@ if not fcmd: raise EnvironmentError("FETCHCOMMAND is unset") - fd, tmp_filename = tempfile.mkstemp() - tmp_dirname, tmp_basename = os.path.split(tmp_filename) - os.close(fd) + # old method completely breaks timestamp caching + # make a secure archive copy of our file (preserves timestamps) + # cd to tempdir so wget analyses the unqualified basename + # fetch file + # cd back + + tmp_dirname = tempfile.mkdtemp() + fetch_cwd = os.getcwd() + os.chdir(tmp_dirname) + tmp_basename = os.path.basename(pkgindex_file) + # no race condition since the target is atomically unlinked if exists + fd_tmpfile,tmp_filename = tempfile.mkstemp(dir=tmp_dirname) + os.rename(tmp_filename, tmp_basename) + tmp_stat_original = None + + if os.path.exists(pkgindex_file): + f_tmpfile = os.fdopen(fd_tmpfile, 'wb') + + # copy original file + f_pkgindex_file = open(pkgindex_file, 'rb') + f_tmpfile.write(f_pkgindex_file.read()) + f_tmpfile.close() + f_pkgindex_file.close() + + # preserve timestamps + os.utime(tmp_basename, (int(local_timestamp), int(local_timestamp))) + tmp_stat_original = os.stat(tmp_basename) + + else: + _f = os.path.exists('Packages') + os.close(fd_tmpfile) + + fcmd = fcmd.replace('-O "${DISTDIR}/${FILE}"', '-N') + fcmd_vars = { "DISTDIR": tmp_dirname, "FILE": tmp_basename, @@ -957,9 +988,21 @@ success = portage.getbinpkg.file_get( fcmd=fcmd, fcmd_vars=fcmd_vars) + + if tmp_stat_original and tmp_stat_original.st_ctime == os.stat(os.path.join(tmp_dirname, tmp_basename)).st_ctime: + # set to the tmpdir so both are deleted + tmp_filename = tmp_dirname + os.chdir(fetch_cwd) + raise UseCachedCopyOfRemoteIndex() + if not success: + os.chdir(fetch_cwd) raise EnvironmentError("%s failed" % (setting,)) - f = open(tmp_filename, 'rb') + + f = open(tmp_basename, 'rb') + # set to the tmpdir so both are deleted + tmp_filename = tmp_dirname + os.chdir(fetch_cwd) f_dec = codecs.iterdecode(f, _encodings['repo.content'], errors='replace')