summaryrefslogtreecommitdiff
path: root/src/database.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/database.c')
-rw-r--r--src/database.c38
1 files changed, 20 insertions, 18 deletions
diff --git a/src/database.c b/src/database.c
index ef9f73c..3962a8e 100644
--- a/src/database.c
+++ b/src/database.c
@@ -605,6 +605,7 @@ int apk_cache_download(struct apk_database *db, struct apk_repository *repo,
struct apk_package *pkg, int verify,
apk_progress_cb cb, void *cb_ctx)
{
+ struct stat st;
struct apk_istream *is;
struct apk_bstream *bs;
struct apk_sign_ctx sctx;
@@ -618,40 +619,42 @@ int apk_cache_download(struct apk_database *db, struct apk_repository *repo,
r = apk_pkg_format_cache_pkg(b, pkg);
else
r = apk_repo_format_cache_index(b, repo);
- if (r < 0)
- return r;
+ if (r < 0) return r;
r = apk_repo_format_real_url(db, repo, pkg, url, sizeof(url));
- if (r < 0)
- return r;
+ if (r < 0) return r;
- apk_message("fetch %s", url);
+ if (fstatat(db->cache_fd, cacheitem, &st, 0) != 0) st.st_mtime = 0;
- if (apk_flags & APK_SIMULATE)
- return 0;
+ apk_message("fetch %s", url);
- if (cb)
- cb(cb_ctx, 0);
+ if (apk_flags & APK_SIMULATE) return 0;
+ if (cb) cb(cb_ctx, 0);
if (verify != APK_SIGN_NONE) {
apk_sign_ctx_init(&sctx, APK_SIGN_VERIFY, NULL, db->keys_fd);
- bs = apk_bstream_from_url(url);
+ bs = apk_bstream_from_url_if_modified(url, st.st_mtime);
bs = apk_bstream_tee(bs, db->cache_fd, tmpcacheitem, cb, cb_ctx);
is = apk_bstream_gunzip_mpart(bs, apk_sign_ctx_mpart_cb, &sctx);
- if (is) r = apk_tar_parse(is, apk_sign_ctx_verify_tar, &sctx, FALSE, &db->id_cache);
- else r = -errno;
+ if (!IS_ERR_OR_NULL(is))
+ r = apk_tar_parse(is, apk_sign_ctx_verify_tar, &sctx, FALSE, &db->id_cache);
+ else
+ r = PTR_ERR(is) ?: -EIO;
apk_sign_ctx_free(&sctx);
} else {
- is = apk_istream_from_url(url);
- fd = openat(db->cache_fd, tmpcacheitem, O_RDWR | O_CREAT | O_TRUNC | O_CLOEXEC, 0644);
+ is = apk_istream_from_url_if_modified(url, st.st_mtime);
+ if (!IS_ERR_OR_NULL(is)) {
+ fd = openat(db->cache_fd, tmpcacheitem, O_RDWR | O_CREAT | O_TRUNC | O_CLOEXEC, 0644);
+ if (fd < 0) r = -errno;
+ } else fd = -1, r = PTR_ERR(is) ?: -EIO;
+
if (fd >= 0) {
r = apk_istream_splice(is, fd, APK_SPLICE_ALL, cb, cb_ctx);
close(fd);
- } else {
- r = -errno;
}
}
- if (is) is->close(is);
+ if (!IS_ERR_OR_NULL(is)) is->close(is);
+ if (r == -EALREADY) return 0;
if (r < 0) {
unlinkat(db->cache_fd, tmpcacheitem, 0);
return r;
@@ -659,7 +662,6 @@ int apk_cache_download(struct apk_database *db, struct apk_repository *repo,
if (renameat(db->cache_fd, tmpcacheitem, db->cache_fd, cacheitem) < 0)
return -errno;
-
return 0;
}