diff options
Diffstat (limited to 'src/database.c')
-rw-r--r-- | src/database.c | 38 |
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; } |