diff --git a/bin/xbps-install/main.c b/bin/xbps-install/main.c index d060723f..9ee4964b 100644 --- a/bin/xbps-install/main.c +++ b/bin/xbps-install/main.c @@ -243,9 +243,11 @@ main(int argc, char **argv) if (syncf && !update && (argc == optind)) exit(EXIT_SUCCESS); - if (!drun && (rv = xbps_pkgdb_lock(&xh)) != 0) { - fprintf(stderr, "Failed to lock the pkgdb: %s\n", strerror(rv)); - exit(rv); + if (!(xh.flags & XBPS_FLAG_DOWNLOAD_ONLY) && !drun) { + if ((rv = xbps_pkgdb_lock(&xh)) != 0) { + fprintf(stderr, "Failed to lock the pkgdb: %s\n", strerror(rv)); + exit(rv); + } } eexist = optind; diff --git a/bin/xbps-install/util.c b/bin/xbps-install/util.c index 84753edb..49c5beb5 100644 --- a/bin/xbps-install/util.c +++ b/bin/xbps-install/util.c @@ -138,6 +138,10 @@ print_trans_colmode(struct transaction *trans, int cols) pkgname = xbps_pkg_name(pkgver); assert(pkgname); + if (trans->xhp->flags & XBPS_FLAG_DOWNLOAD_ONLY) { + tract = "download"; + } + if (strcmp(tract, "install") == 0) { trans->inst_pkgcnt++; } else if (strcmp(tract, "update") == 0) { @@ -147,16 +151,14 @@ print_trans_colmode(struct transaction *trans, int cols) } else if (strcmp(tract, "configure") == 0) { trans->cf_pkgcnt++; } + ipkgd = xbps_pkgdb_get_pkg(trans->xhp, pkgname); + if (trans->xhp->flags & XBPS_FLAG_DOWNLOAD_ONLY) { - trans->inst_pkgcnt = 0; - trans->up_pkgcnt = 0; - trans->rm_pkgcnt = 0; - trans->cf_pkgcnt = 0; + ipkgd = NULL; } if (dload) { trans->dl_pkgcnt++; } - ipkgd = xbps_pkgdb_get_pkg(trans->xhp, pkgname); if (ipkgd) { xbps_dictionary_get_cstring_nocopy(ipkgd, "pkgver", &ipkgver); iver = xbps_pkg_version(ipkgver); diff --git a/lib/repo_pkgdeps.c b/lib/repo_pkgdeps.c index 0dbb0010..21b529b1 100644 --- a/lib/repo_pkgdeps.c +++ b/lib/repo_pkgdeps.c @@ -198,6 +198,16 @@ find_repo_deps(struct xbps_handle *xhp, foundvpkg = true; } } + if (xhp->flags & XBPS_FLAG_DOWNLOAD_ONLY) { + /* + * if XBPS_FLAG_DOWNLOAD_ONLY always assume + * all deps are not installed. This way one can download + * the whole set of binary packages to perform an + * off-line installation later on. + */ + curpkgd = NULL; + } + if (curpkgd == NULL) { if (errno && errno != ENOENT) { /* error */ diff --git a/lib/transaction_fetch.c b/lib/transaction_fetch.c index 67c8ecbf..e6749f68 100644 --- a/lib/transaction_fetch.c +++ b/lib/transaction_fetch.c @@ -24,7 +24,6 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include #include #include #include diff --git a/lib/transaction_ops.c b/lib/transaction_ops.c index 03725ee3..cbdc9721 100644 --- a/lib/transaction_ops.c +++ b/lib/transaction_ops.c @@ -81,6 +81,11 @@ trans_find_pkg(struct xbps_handle *xhp, const char *pkg, bool reinstall, } else { pkg_pkgdb = xbps_pkgdb_get_pkg(xhp, pkg); } + + if (xhp->flags & XBPS_FLAG_DOWNLOAD_ONLY) { + pkg_pkgdb = NULL; + } + /* * Find out if the pkg has been found in repository pool. */ @@ -254,6 +259,10 @@ xbps_autoupdate(struct xbps_handle *xhp) xbps_dbg_printf(xhp, "%s: trans_find_pkg xbps: %d\n", __func__, rv); if (rv == 0) { + if (xhp->flags & XBPS_FLAG_DOWNLOAD_ONLY) { + xhp->flags |= XBPS_FLAG_FORCE_REMOVE_REVDEPS; + return 1; + } /* a new xbps version is available, check its revdeps */ rdeps = xbps_pkgdb_get_pkg_revdeps(xhp, "xbps"); for (unsigned int i = 0; i < xbps_array_count(rdeps); i++) { diff --git a/lib/transaction_prepare.c b/lib/transaction_prepare.c index 5e3aa052..1ac27ef9 100644 --- a/lib/transaction_prepare.c +++ b/lib/transaction_prepare.c @@ -62,7 +62,6 @@ compute_transaction_stats(struct xbps_handle *xhp) struct statvfs svfs; uint64_t rootdir_free_size, tsize, dlsize, instsize, rmsize; uint32_t inst_pkgcnt, up_pkgcnt, cf_pkgcnt, rm_pkgcnt, dl_pkgcnt; - const char *tract, *pkgver, *repo; inst_pkgcnt = up_pkgcnt = cf_pkgcnt = rm_pkgcnt = dl_pkgcnt = 0; tsize = dlsize = instsize = rmsize = 0; @@ -72,6 +71,7 @@ compute_transaction_stats(struct xbps_handle *xhp) return EINVAL; while ((obj = xbps_object_iterator_next(iter)) != NULL) { + const char *pkgver = NULL, *repo = NULL, *tract = NULL; bool preserve = false; /* * Count number of pkgs to be removed, configured, @@ -82,6 +82,20 @@ compute_transaction_stats(struct xbps_handle *xhp) xbps_dictionary_get_cstring_nocopy(obj, "repository", &repo); xbps_dictionary_get_bool(obj, "preserve", &preserve); + if (xhp->flags & XBPS_FLAG_DOWNLOAD_ONLY) { + tract = "download"; + if (xbps_repository_is_remote(repo) && + !xbps_binpkg_exists(xhp, obj)) { + xbps_dictionary_get_uint64(obj, + "filename-size", &tsize); + tsize += 512; + dlsize += tsize; + dl_pkgcnt++; + xbps_dictionary_set_bool(obj, "download", true); + } + continue; + } + if (strcmp(tract, "configure") == 0) { cf_pkgcnt++; continue; @@ -347,6 +361,13 @@ xbps_transaction_prepare(struct xbps_handle *xhp) if (all_on_hold) goto out; + /* + * Do not perform any checks if XBPS_FLAG_DOWNLOAD_ONLY + * is set. We just need to download the archives (dependencies). + */ + if (xhp->flags & XBPS_FLAG_DOWNLOAD_ONLY) + goto out; + /* * Check for packages to be replaced. */