diff --git a/bin/xbps-bin/defs.h b/bin/xbps-bin/defs.h index a7f8c30f..940f7318 100644 --- a/bin/xbps-bin/defs.h +++ b/bin/xbps-bin/defs.h @@ -85,14 +85,14 @@ bool yesno(const char *, ...); bool noyes(const char *, ...); /* from fetch_cb.c */ -void fetch_file_progress_cb(struct xbps_fetch_cb_data *); +void fetch_file_progress_cb(const struct xbps_fetch_cb_data *, void *); /* from state_cb.c */ -void state_cb(struct xbps_state_cb_data *); +void state_cb(const struct xbps_state_cb_data *, void *); /* from unpack_cb.c */ -void unpack_progress_cb_verbose(struct xbps_unpack_cb_data *); -void unpack_progress_cb(struct xbps_unpack_cb_data *); +void unpack_progress_cb_verbose(const struct xbps_unpack_cb_data *, void *); +void unpack_progress_cb(const struct xbps_unpack_cb_data *, void *); /* From util.c */ int show_pkg_files(prop_dictionary_t); diff --git a/bin/xbps-bin/fetch_cb.c b/bin/xbps-bin/fetch_cb.c index 740baa8c..77e6455f 100644 --- a/bin/xbps-bin/fetch_cb.c +++ b/bin/xbps-bin/fetch_cb.c @@ -47,14 +47,14 @@ * Compute and display ETA */ static const char * -stat_eta(struct xbps_fetch_cb_data *xfpd) +stat_eta(const struct xbps_fetch_cb_data *xfpd, void *cbdata) { - struct xferstat *xsp = xfpd->cookie; + struct xferstat *xfer = cbdata; static char str[16]; long elapsed, eta; off_t received, expected; - elapsed = xsp->last.tv_sec - xsp->start.tv_sec; + elapsed = xfer->last.tv_sec - xfer->start.tv_sec; received = xfpd->file_dloaded - xfpd->file_offset; expected = xfpd->file_size - xfpd->file_dloaded; eta = (long)(elapsed * expected / received); @@ -68,11 +68,6 @@ stat_eta(struct xbps_fetch_cb_data *xfpd) return str; } -/** High precision double comparison - * \param[in] a The first double to compare - * \param[in] b The second double to compare - * \return true on equal within precison, false if not equal within defined precision. - */ static inline bool compare_double(const double a, const double b) { @@ -88,15 +83,15 @@ compare_double(const double a, const double b) * Compute and display transfer rate */ static const char * -stat_bps(struct xbps_fetch_cb_data *xfpd) +stat_bps(const struct xbps_fetch_cb_data *xfpd, void *cbdata) { - struct xferstat *xsp = xfpd->cookie; + struct xferstat *xfer = cbdata; static char str[16]; char size[8]; double delta, bps; - delta = (xsp->last.tv_sec + (xsp->last.tv_usec / 1.e6)) - - (xsp->start.tv_sec + (xsp->start.tv_usec / 1.e6)); + delta = (xfer->last.tv_sec + (xfer->last.tv_usec / 1.e6)) + - (xfer->start.tv_sec + (xfer->start.tv_usec / 1.e6)); if (compare_double(delta, 0.0001)) { snprintf(str, sizeof str, "-- stalled --"); } else { @@ -112,73 +107,48 @@ stat_bps(struct xbps_fetch_cb_data *xfpd) * Update the stats display */ static void -stat_display(struct xbps_fetch_cb_data *xfpd) +stat_display(const struct xbps_fetch_cb_data *xfpd, void *cbdata) { - struct xferstat *xsp = xfpd->cookie; + struct xferstat *xfer = cbdata; struct timeval now; char totsize[8], recvsize[8]; gettimeofday(&now, NULL); - if (now.tv_sec <= xsp->last.tv_sec) + if (now.tv_sec <= xfer->last.tv_sec) return; - xsp->last = now; + xfer->last = now; (void)xbps_humanize_number(totsize, (int64_t)xfpd->file_size); (void)xbps_humanize_number(recvsize, (int64_t)xfpd->file_dloaded); fprintf(stderr,"\r%s: %s [%d%% of %s]", xfpd->file_name, recvsize, (int)((double)(100.0 * (double)xfpd->file_dloaded) / (double)xfpd->file_size), totsize); - fprintf(stderr," %s", stat_bps(xfpd)); + fprintf(stderr," %s", stat_bps(xfpd, xfer)); if (xfpd->file_size > 0 && xfpd->file_dloaded > 0 && - xsp->last.tv_sec >= xsp->start.tv_sec + 10) - fprintf(stderr," ETA: %s", stat_eta(xfpd)); + xfer->last.tv_sec >= xfer->start.tv_sec + 10) + fprintf(stderr," ETA: %s", stat_eta(xfpd, xfer)); fprintf(stderr,"\033[K"); } -/* - * Initialize the transfer statistics - */ -static void -stat_start(struct xferstat *xsp) -{ - gettimeofday(&xsp->start, NULL); - xsp->last.tv_sec = xsp->last.tv_usec = 0; -} - -/* - * Update the transfer statistics - */ -static void -stat_update(struct xbps_fetch_cb_data *xfpd) -{ - xfpd->file_dloaded += xfpd->file_offset; - stat_display(xfpd); -} - -/* - * Finalize the transfer statistics - */ -static void -stat_end(struct xbps_fetch_cb_data *xfpd) +void +fetch_file_progress_cb(const struct xbps_fetch_cb_data *xfpd, void *cbdata) { + struct xferstat *xfer = cbdata; char size[8]; - (void)xbps_humanize_number(size, (int64_t)xfpd->file_size); - fprintf(stderr,"\rDownloaded %s for %s [avg rate: %s]", - size, xfpd->file_name, stat_bps(xfpd)); - fprintf(stderr,"\033[K\n"); -} - -void -fetch_file_progress_cb(struct xbps_fetch_cb_data *xfpd) -{ - struct xferstat *xsp = xfpd->cookie; - - if (xfpd->cb_start) - stat_start(xsp); - else if (xfpd->cb_update) - stat_update(xfpd); - else if (xfpd->cb_end) - stat_end(xfpd); + if (xfpd->cb_start) { + /* start transfer stats */ + gettimeofday(&xfer->start, NULL); + xfer->last.tv_sec = xfer->last.tv_usec = 0; + } else if (xfpd->cb_update) { + /* update transfer stats */ + stat_display(xfpd, xfer); + } else if (xfpd->cb_end) { + /* end transfer stats */ + (void)xbps_humanize_number(size, (int64_t)xfpd->file_size); + fprintf(stderr,"\rDownloaded %s for %s [avg rate: %s]", + size, xfpd->file_name, stat_bps(xfpd, xfer)); + fprintf(stderr,"\033[K\n"); + } } diff --git a/bin/xbps-bin/main.c b/bin/xbps-bin/main.c index dc72d18d..380d6446 100644 --- a/bin/xbps-bin/main.c +++ b/bin/xbps-bin/main.c @@ -161,13 +161,13 @@ main(int argc, char **argv) exit(EXIT_FAILURE); } xhp->debug = debug; - xhp->xbps_state_cb = state_cb; - xhp->xbps_fetch_cb = fetch_file_progress_cb; - xhp->xfcd->cookie = &xfer; + xhp->state_cb = state_cb; + xhp->fetch_cb = fetch_file_progress_cb; + xhp->fetch_cb_data = &xfer; if (flags & XBPS_FLAG_VERBOSE) - xhp->xbps_unpack_cb = unpack_progress_cb_verbose; + xhp->unpack_cb = unpack_progress_cb_verbose; else - xhp->xbps_unpack_cb = unpack_progress_cb; + xhp->unpack_cb = unpack_progress_cb; if (rootdir) xhp->rootdir = prop_string_create_cstring(rootdir); diff --git a/bin/xbps-bin/remove.c b/bin/xbps-bin/remove.c index a82606ca..5e406b41 100644 --- a/bin/xbps-bin/remove.c +++ b/bin/xbps-bin/remove.c @@ -38,24 +38,12 @@ pkg_remove_and_purge(const char *pkgname, const char *version, bool purge) { int rv = 0; - printf("Removing package %s-%s ...\n", pkgname, version); - - if ((rv = xbps_remove_pkg(pkgname, version, false)) != 0) { - xbps_error_printf("xbps-bin: unable to remove %s-%s (%s).\n", - pkgname, version, strerror(errno)); + if ((rv = xbps_remove_pkg(pkgname, version, false)) != 0) return rv; - } - if (purge) { - printf(" Purging ... "); - (void)fflush(stdout); - if ((rv = xbps_purge_pkg(pkgname, false)) != 0) { - xbps_error_printf("xbps-bin: unable to purge %s-%s " - "(%s).\n", pkgname, version, - strerror(errno)); + + if (purge) + if ((rv = xbps_purge_pkg(pkgname, false)) != 0) return rv; - } - printf("done.\n"); - } return rv; } @@ -183,7 +171,7 @@ remove_installed_pkgs(int argc, char **argv, bool yes, bool purge, continue; } - xbps_printf("WARNING: %s IS REQUIRED BY %u PACKAGE%s:\n\n", + printf("WARNING: %s IS REQUIRED BY %u PACKAGE%s:\n\n", pkgver, prop_array_count(reqby), prop_array_count(reqby) > 1 ? "S" : ""); for (x = 0; x < prop_array_count(reqby); x++) { diff --git a/bin/xbps-bin/state_cb.c b/bin/xbps-bin/state_cb.c index 01491d93..6657988f 100644 --- a/bin/xbps-bin/state_cb.c +++ b/bin/xbps-bin/state_cb.c @@ -25,98 +25,73 @@ #include #include +#include #include #include "defs.h" void -state_cb(struct xbps_state_cb_data *xscd) +state_cb(const struct xbps_state_cb_data *xscd, void *cbdata) { + const struct xbps_handle *xhp = xbps_handle_get(); prop_dictionary_t pkgd; - const char *opkgver, *state_descr = NULL, *fetchstr; - char *pkgname; + const char *pkgver; - if (xscd->desc != NULL && xscd->pkgver == NULL && xscd->err == 0) { - printf("\n%s ...\n", xscd->desc); - return; - } + (void)cbdata; switch (xscd->state) { case XBPS_STATE_DOWNLOAD: - printf("Downloading `%s' (from %s) ...\n", - xscd->pkgver, xscd->repourl); - break; - case XBPS_STATE_DOWNLOAD_FAIL: - state_descr = "failed to download binary package"; - break; case XBPS_STATE_VERIFY: - printf("Checking `%s' integrity ...\n", xscd->binpkg_fname); - break; - case XBPS_STATE_VERIFY_FAIL: - state_descr = "failed to verify binary package SHA256"; - break; case XBPS_STATE_REMOVE: - printf("Removing `%s' ...\n", xscd->pkgver); - break; - case XBPS_STATE_REMOVE_FAIL: - state_descr = "failed to remove package"; - break; case XBPS_STATE_PURGE: - printf("Purging `%s' ...\n", xscd->pkgver); - break; - case XBPS_STATE_PURGE_FAIL: - state_descr = "failed to purge package"; - break; case XBPS_STATE_CONFIGURE: - printf("Configuring `%s' ...\n", xscd->pkgver); - break; - case XBPS_STATE_CONFIGURE_FAIL: - state_descr = "failed to configure package"; - break; - case XBPS_STATE_REGISTER_FAIL: - state_descr = "failed to register package"; - break; case XBPS_STATE_REGISTER: + case XBPS_STATE_UNREGISTER: case XBPS_STATE_INSTALL: + case XBPS_STATE_UNPACK: + case XBPS_STATE_REPOSYNC: + case XBPS_STATE_CONFIG_FILE: + printf("%s\n", xscd->desc); break; case XBPS_STATE_UPDATE: - pkgname = xbps_pkg_name(xscd->pkgver); - if (pkgname == NULL) { - xbps_error_printf("%s: failed to alloc pkgname!\n", - __func__); - exit(EXIT_FAILURE); - } - pkgd = xbps_find_pkg_dict_installed(pkgname, false); - prop_dictionary_get_cstring_nocopy(pkgd, "pkgver", &opkgver); + pkgd = xbps_find_pkg_dict_installed(xscd->pkgname, false); + prop_dictionary_get_cstring_nocopy(pkgd, "pkgver", &pkgver); prop_object_release(pkgd); - free(pkgname); - printf("Updating `%s' to `%s'...\n", opkgver, xscd->pkgver); + printf("Updating `%s' to `%s-%s'...\n", pkgver, + xscd->pkgname, xscd->version); break; - case XBPS_STATE_UPDATE_FAIL: - state_descr = "failed to update package"; - break; - case XBPS_STATE_UNPACK: - printf("Unpacking `%s' (from ../%s) ...\n", - xscd->pkgver, xscd->binpkg_fname); + case XBPS_STATE_REMOVE_FILE: + case XBPS_STATE_REMOVE_FILE_OBSOLETE: + if (xhp->flags & XBPS_FLAG_VERBOSE) + printf("%s\n", xscd->desc); + else { + printf("%s\n", xscd->desc); + printf("\033[1A\033[K"); + } break; case XBPS_STATE_UNPACK_FAIL: - state_descr = "failed to unpack binary package"; - break; - case XBPS_STATE_REPOSYNC: - printf("Synchronizing index for `%s' ...\n", - xscd->repourl); - break; + case XBPS_STATE_UPDATE_FAIL: + case XBPS_STATE_CONFIGURE_FAIL: + case XBPS_STATE_REGISTER_FAIL: + case XBPS_STATE_UNREGISTER_FAIL: + case XBPS_STATE_PURGE_FAIL: + case XBPS_STATE_REMOVE_FAIL: + case XBPS_STATE_VERIFY_FAIL: + case XBPS_STATE_DOWNLOAD_FAIL: case XBPS_STATE_REPOSYNC_FAIL: - fetchstr = xbps_fetch_error_string(); - xbps_error_printf("Failed to sync index: %s\n", - fetchstr ? fetchstr : strerror(xscd->err)); - return; + case XBPS_STATE_CONFIG_FILE_FAIL: + xbps_error_printf("%s\n", xscd->desc); + break; + case XBPS_STATE_REMOVE_FILE_FAIL: + case XBPS_STATE_REMOVE_FILE_HASH_FAIL: + case XBPS_STATE_REMOVE_FILE_OBSOLETE_FAIL: + /* Ignore errors due to not empty directories */ + if (xscd->err == ENOTEMPTY) + return; + + xbps_error_printf("%s\n", xscd->desc); + break; default: - xbps_dbg_printf("%s: unknown state %d %s\n", - xscd->pkgver, xscd->state, xscd->desc); + xbps_dbg_printf("unknown state %d\n", xscd->state); break; } - - if (state_descr != NULL && xscd->err != 0) - xbps_error_printf("%s: %s: %s\n", - xscd->pkgver, state_descr, strerror(xscd->err)); } diff --git a/bin/xbps-bin/unpack_cb.c b/bin/xbps-bin/unpack_cb.c index 3a85c62f..837de90a 100644 --- a/bin/xbps-bin/unpack_cb.c +++ b/bin/xbps-bin/unpack_cb.c @@ -30,8 +30,10 @@ #include "defs.h" void -unpack_progress_cb_verbose(struct xbps_unpack_cb_data *xpd) +unpack_progress_cb_verbose(const struct xbps_unpack_cb_data *xpd, void *cbdata) { + (void)cbdata; + if (xpd->entry == NULL || xpd->entry_is_metadata) return; else if (xpd->entry_size <= 0) @@ -43,8 +45,10 @@ unpack_progress_cb_verbose(struct xbps_unpack_cb_data *xpd) } void -unpack_progress_cb(struct xbps_unpack_cb_data *xpd) +unpack_progress_cb(const struct xbps_unpack_cb_data *xpd, void *cbdata) { + (void)cbdata; + if (xpd->entry == NULL || xpd->entry_is_metadata) return; else if (xpd->entry_size <= 0) diff --git a/bin/xbps-repo/main.c b/bin/xbps-repo/main.c index f4b8df0f..b958a82d 100644 --- a/bin/xbps-repo/main.c +++ b/bin/xbps-repo/main.c @@ -138,9 +138,9 @@ main(int argc, char **argv) exit(EXIT_FAILURE); } xhp->debug = debug; - xhp->xbps_state_cb = state_cb; - xhp->xbps_fetch_cb = fetch_file_progress_cb; - xhp->xfcd->cookie = &xfer; + xhp->state_cb = state_cb; + xhp->fetch_cb = fetch_file_progress_cb; + xhp->fetch_cb_data = &xfer; if (rootdir) xhp->rootdir = prop_string_create_cstring(rootdir); if (cachedir) @@ -190,7 +190,7 @@ main(int argc, char **argv) rv = show_pkg_info_from_repolist(argv[1], option); if (rv == ENOENT) { - xbps_printf("Unable to locate package " + printf("Unable to locate package " "`%s' in repository pool.\n", argv[1]); } else if (rv == ENOTSUP) { xbps_error_printf("xbps-repo: no repositories " @@ -207,7 +207,7 @@ main(int argc, char **argv) rv = show_pkg_deps_from_repolist(argv[1]); if (rv == ENOENT) { - xbps_printf("Unable to locate package " + printf("Unable to locate package " "`%s' in repository pool.\n", argv[1]); } else if (rv == ENOTSUP) { xbps_error_printf("xbps-repo: no repositories " @@ -229,7 +229,7 @@ main(int argc, char **argv) xbps_error_printf("xbps-repo: no repositories " "currently registered!\n"); } else if (errno == ENOENT) { - xbps_printf("Unable to locate package `%s' " + printf("Unable to locate package `%s' " "in repository pool.\n", argv[1]); } else { xbps_error_printf("xbps-repo: unexpected " diff --git a/bin/xbps-repo/show.c b/bin/xbps-repo/show.c index d50a68f1..40efa474 100644 --- a/bin/xbps-repo/show.c +++ b/bin/xbps-repo/show.c @@ -35,7 +35,10 @@ #include #include "../xbps-bin/defs.h" #include "defs.h" + +#ifdef HAVE_CONFIG_H #include "config.h" +#endif int show_pkg_info_from_repolist(const char *pkgname, const char *option) diff --git a/bin/xbps-uhelper/main.c b/bin/xbps-uhelper/main.c index ad4eaf54..b324f2aa 100644 --- a/bin/xbps-uhelper/main.c +++ b/bin/xbps-uhelper/main.c @@ -158,8 +158,8 @@ main(int argc, char **argv) exit(EXIT_FAILURE); } xhp->debug = debug; - xhp->xbps_fetch_cb = fetch_file_progress_cb; - xhp->xfcd->cookie = &xfer; + xhp->fetch_cb = fetch_file_progress_cb; + xhp->fetch_cb_data = &xfer; if (rootdir) xhp->rootdir = prop_string_create_cstring(rootdir); if (confdir) diff --git a/include/compat.h b/include/compat.h index 7d5f4f09..8b3186bf 100644 --- a/include/compat.h +++ b/include/compat.h @@ -2,6 +2,7 @@ #define COMPAT_H #include +#include #ifndef HAVE_STRLCAT size_t strlcat(char *, const char *, size_t); @@ -15,4 +16,8 @@ size_t strlcpy(char *, const char *, size_t); char *strcasestr(const char *, const char *); #endif +#if defined(HAVE_VASPRINTF) && !defined(_GNU_SOURCE) +int vasprintf(char **, const char *, va_list); +#endif + #endif /* COMPAT_H */ diff --git a/include/xbps_api.h b/include/xbps_api.h index 9e38765b..523d7775 100644 --- a/include/xbps_api.h +++ b/include/xbps_api.h @@ -55,7 +55,7 @@ */ #define XBPS_PKGINDEX_VERSION "1.3" -#define XBPS_API_VERSION "20111117" +#define XBPS_API_VERSION "20111124" #define XBPS_VERSION "0.11.0" /** @@ -146,7 +146,6 @@ __BEGIN_DECLS -void xbps_printf(const char *, ...); void xbps_dbg_printf(const char *, ...); void xbps_dbg_printf_append(const char *, ...); void xbps_error_printf(const char *, ...); @@ -160,53 +159,81 @@ void xbps_warn_printf(const char *, ...); * * Integer representing the xbps callback returned state. Possible values: * - * XBPS_STATE_UKKNOWN: unknown, state hasn't been - * prepared or some unknown error ocurred. - * - * XBPS_STATE_DOWNLOAD: a binary package is being downloaded. - * - * XBPS_STATE_VERIFY: a binary package is being verified. - * - * XBPS_STATE_REMOVE: a package is being removed. - * - * XBPS_STATE_PURGE: a package is being purged. - * - * XBPS_STATE_REPLACE: a package is being replaced. - * - * XBPS_STATE_INSTALL: a package is being installed. - * - * XBPS_STATE_UPDATE: a package is being updated. - * - * XBPS_STATE_UNPACK: a package is being unpacked. - * - * XBPS_STATE_CONFIGURE: a package is being configured. - * - * XBPS_STATE_REGISTER: a package is being registered. - * - * XBPS_STATE_REPOSYNC: a remote repository's - * pkg index is being synchronized. + * XBPS_STATE_UKKNOWN: unknown, state hasn't been prepared or unknown error. + * XBPS_STATE_TRANS_DOWNLOAD: transaction is downloading binary packages. + * XBPS_STATE_TRANS_VERIFY: transaction is verifying binary package integrity. + * XBPS_STATE_TRANS_RUN: transaction is performing operations: + * install, update, remove and replace. + * XBPS_STATE_TRANS_CONFIGURE: transaction is configuring all + * unpacked packages. + * XBPS_STATE_DOWNLOAD: a binary package is being downloaded. + * XBPS_STATE_VERIFY: a binary package is being verified. + * XBPS_STATE_REMOVE: a package is being removed. + * XBPS_STATE_REMOVE_FILE: a package file is being removed. + * XBPS_STATE_REMOVE_OBSOLETE: an obsolete package file is being removed. + * XBPS_STATE_PURGE: a package is being purged. + * XBPS_STATE_REPLACE: a package is being replaced. + * XBPS_STATE_INSTALL: a package is being installed. + * XBPS_STATE_UPDATE: a package is being updated. + * XBPS_STATE_UNPACK: a package is being unpacked. + * XBPS_STATE_CONFIGURE: a package is being configured. + * XBPS_STATE_CONFIG_FILE: a package configuration file is being processed. + * XBPS_STATE_REGISTER: a package is being registered. + * XBPS_STATE_UNREGISTER: a package is being unregistered. + * XBPS_STATE_REPOSYNC: a remote repository's package index is being + * synchronized. + * XBPS_STATE_VERIFY_FAIL: binary package integrity has failed. + * XBPS_STATE_DOWNLOAD_FAIL: binary package download has failed. + * XBPS_STATE_REMOVE_FAIL: a package removal has failed. + * XBPS_STATE_REMOVE_FILE_FAIL: a package file removal has failed. + * XBPS_STATE_REMOVE_FILE_HASH_FAIL: a package file removal due to + * its hash has failed. + * XBPS_STATE_REMOVE_FILE_OBSOLETE_FAIL: an obsolete package file + * removal has failed. + * XBPS_STATE_PURGE_FAIL: package purge has failed. + * XBPS_STATE_CONFIGURE_FAIL: package configure has failed. + * XBPS_STATE_CONFIG_FILE_FAIL: package configuration file operation + * has failed. + * XBPS_STATE_UPDATE_FAIL: package update has failed. + * XBPS_STATE_UNPACK_FAIL: package unpack has failed. + * XBPS_STATE_REGISTER_FAIL: package register has failed. + * XBPS_STATE_UNREGISTER_FAIL: package unregister has failed. + * XBPS_STATE_REPOSYNC_FAIL: syncing remote repositories has failed. */ typedef enum xbps_state { XBPS_STATE_UNKNOWN = 0, + XBPS_STATE_TRANS_DOWNLOAD, + XBPS_STATE_TRANS_VERIFY, + XBPS_STATE_TRANS_RUN, + XBPS_STATE_TRANS_CONFIGURE, XBPS_STATE_DOWNLOAD, XBPS_STATE_VERIFY, XBPS_STATE_REMOVE, + XBPS_STATE_REMOVE_FILE, + XBPS_STATE_REMOVE_FILE_OBSOLETE, XBPS_STATE_PURGE, XBPS_STATE_REPLACE, XBPS_STATE_INSTALL, XBPS_STATE_UPDATE, XBPS_STATE_UNPACK, XBPS_STATE_CONFIGURE, + XBPS_STATE_CONFIG_FILE, XBPS_STATE_REGISTER, + XBPS_STATE_UNREGISTER, XBPS_STATE_REPOSYNC, XBPS_STATE_VERIFY_FAIL, XBPS_STATE_DOWNLOAD_FAIL, XBPS_STATE_REMOVE_FAIL, + XBPS_STATE_REMOVE_FILE_FAIL, + XBPS_STATE_REMOVE_FILE_HASH_FAIL, + XBPS_STATE_REMOVE_FILE_OBSOLETE_FAIL, XBPS_STATE_PURGE_FAIL, XBPS_STATE_CONFIGURE_FAIL, + XBPS_STATE_CONFIG_FILE_FAIL, XBPS_STATE_UPDATE_FAIL, XBPS_STATE_UNPACK_FAIL, XBPS_STATE_REGISTER_FAIL, + XBPS_STATE_UNREGISTER_FAIL, XBPS_STATE_REPOSYNC_FAIL } xbps_state_t; @@ -229,36 +256,23 @@ struct xbps_state_cb_data { */ const char *desc; /** - * @var pkgver + * @var pkgname * - * XBPS state current pkgname/version string - * (set internally, read-only). + * Package name string (set internally, read-only). */ - const char *pkgver; + const char *pkgname; /** - * @var binpkg_fname + * @var version * - * Binary package's filename (set internally, read-only). + * Package version string (set internally, read-only). */ - const char *binpkg_fname; - /** - * @var repourl - * - * Repository URL (set internally, read-only). - */ - const char *repourl; + const char *version; /** * @var err * * XBPS state error value (set internally, read-only). */ int err; - /** - * @var cookie - * - * Pointer to user supplied data. - */ - void *cookie; }; /** @@ -275,57 +289,48 @@ struct xbps_fetch_cb_data { /** * @var file_size * - * Filename size for the file to be fetched (set internally, - * read-only). + * Filename size for the file to be fetched. */ off_t file_size; /** * @var file_offset * - * Current offset for the filename being fetched (set internally, - * read-only). + * Current offset for the filename being fetched. */ off_t file_offset; /** * @var file_dloaded * - * Bytes downloaded for the file being fetched - * (set internally, read-only). + * Bytes downloaded for the file being fetched. */ off_t file_dloaded; /** * @var file_name * - * File name being fetched (set internally, read-only). + * File name being fetched. */ const char *file_name; /** * @var cb_start * * If true the function callback should be prepared to start - * the transfer progress (set internally, read-only). + * the transfer progress. */ bool cb_start; /** * @var cb_update * * If true the function callback should be prepared to - * update the transfer progress (set internally, read-only). + * update the transfer progress. */ bool cb_update; /** * @var cb_end * * If true the function callback should be prepated to - * end the transfer progress (set internally, read-only). + * end the transfer progress. */ bool cb_end; - /** - * @var cookie - * - * Pointer to private user data. - */ - void *cookie; }; /** @@ -342,47 +347,39 @@ struct xbps_unpack_cb_data { /** * @var entry * - * Entry pathname string (set internally, read-only). + * Entry pathname string. */ const char *entry; /** * @var entry_size * - * Entry file size (set internally, read-only). + * Entry file size. */ int64_t entry_size; /** * @var entry_extract_count * - * Total number of extracted entries (set internally, read-only). + * Total number of extracted entries. */ ssize_t entry_extract_count; /** * @var entry_total_count * - * Total number of entries in package (set internally, read-only). + * Total number of entries in package. */ ssize_t entry_total_count; /** * @var entry_is_metadata * - * If true "entry" is a package metadata file (set internally, - * read-only). + * If true "entry" is a metadata file. */ bool entry_is_metadata; /** * @var entry_is_conf * - * If true "entry" is a configuration file (set internally, - * read-only). + * If true "entry" is a configuration file. */ bool entry_is_conf; - /** - * @var cookie - * - * Pointer to private user data. - */ - void *cookie; }; /** @@ -418,42 +415,42 @@ struct xbps_handle { * Pointer to the supplifed function callback to be used * in the XBPS possible states. */ - void (*xbps_state_cb)(struct xbps_state_cb_data *); + void (*state_cb)(const struct xbps_state_cb_data *, void *); /** - * @var xscd + * @var state_cb_data * - * Pointer to a xbps_state_cb_data structure. It's allocated by - * xbps_handle_alloc(), set internally. + * Pointer to user supplied data to be passed as argument to + * the \a xbps_state_cb function callback. */ - struct xbps_state_cb_data *xscd; + void *state_cb_data; /** * @var xbps_unpack_cb * * Pointer to the supplied function callback to be used in * xbps_unpack_binary_pkg(). */ - void (*xbps_unpack_cb)(struct xbps_unpack_cb_data *); + void (*unpack_cb)(const struct xbps_unpack_cb_data *, void *); /** - * @var xucd + * @var unpack_cb_data * - * Pointer to a xbps_unpack_cb_data structure to be passed - * as argument to the \a xbps_unpack_cb function callback. + * Pointer to user supplied data to be passed as argument to + * the \a xbps_unpack_cb function callback. */ - struct xbps_unpack_cb_data *xucd; + void *unpack_cb_data; /** * @var xbps_fetch_cb * * Pointer to the supplied function callback to be used in * xbps_fetch_file(). */ - void (*xbps_fetch_cb)(struct xbps_fetch_cb_data *); + void (*fetch_cb)(const struct xbps_fetch_cb_data *, void *); /** - * @var xfcd + * @var fetch_cb_data * - * Pointer to a xbps_fetch_cb_data structure to be passed - * as argument to the \a xbps_fetch_cb function callback. + * Pointer to user supplied data to be passed as argument to + * the \a xbps_fetch_cb function callback. */ - struct xbps_fetch_cb_data *xfcd; + void *fetch_cb_data; /** * @var rootdir * @@ -488,7 +485,6 @@ struct xbps_handle { * Flags to be set globally, possible values: * * - XBPS_FLAG_VERBOSE - * * - XBPS_FLAG_FORCE */ int flags; @@ -1087,10 +1083,11 @@ int xbps_register_pkg(prop_dictionary_t pkg_dict); * Unregister a package from the package database. * * @param[in] pkgname Package name. + * @param[in] version Package version. * * @return 0 on success, otherwise an errno value. */ -int xbps_unregister_pkg(const char *pkgname); +int xbps_unregister_pkg(const char *pkgname, const char *version); /*@}*/ @@ -1118,10 +1115,13 @@ int xbps_remove_pkg(const char *pkgname, const char *version, bool update); * The image in Detailed description shows off its structure. * @param[in] key Key of the array object to match, valid values are: * files, dirs, links and conf_files. + * @param[in] pkgver Package/version string matching package dictionary. * * @return 0 on success, otherwise an errno value. */ -int xbps_remove_pkg_files(prop_dictionary_t dict, const char *key); +int xbps_remove_pkg_files(prop_dictionary_t dict, + const char *key, + const char *pkgver); /*@}*/ diff --git a/include/xbps_api_impl.h b/include/xbps_api_impl.h index bc5acd47..5e57e445 100644 --- a/include/xbps_api_impl.h +++ b/include/xbps_api_impl.h @@ -31,9 +31,6 @@ # define NDEBUG #endif #include -#include -#include - #include #include "compat.h" #include "queue.h" @@ -127,7 +124,11 @@ prop_dictionary_t HIDDEN * @private * From lib/package_remove_obsoletes.c */ -int HIDDEN xbps_remove_obsoletes(prop_dictionary_t, prop_dictionary_t); +int HIDDEN xbps_remove_obsoletes(const char *, + const char *, + const char *, + prop_dictionary_t, + prop_dictionary_t); /** * @private @@ -203,6 +204,17 @@ prop_dictionary_t HIDDEN */ void HIDDEN xbps_init_virtual_pkgs(struct xbps_handle *); +/** + * @private + * From lib/cb_util.c + */ +void HIDDEN xbps_set_cb_fetch(off_t, off_t, off_t, const char *, + bool, bool, bool); +void HIDDEN xbps_set_cb_state(xbps_state_t, int, const char *, + const char *, const char *, ...); +void HIDDEN xbps_set_cb_unpack(const char *, int64_t, ssize_t, + ssize_t, bool, bool); + __END_DECLS #endif /* !_XBPS_API_IMPL_H_ */ diff --git a/lib/Makefile b/lib/Makefile index 89e2c498..776b7ae2 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -49,7 +49,7 @@ OBJS += transaction_dictionary.o transaction_sortdeps.o download.o OBJS += plist.o plist_archive_entry.o plist_find.o plist_match.o OBJS += plist_remove.o plist_fetch.o util.o util_hash.o OBJS += initend.o regpkgdb_dictionary.o init_virtualpkgs.o -OBJS += repository_findpkg.o repository_finddeps.o +OBJS += repository_findpkg.o repository_finddeps.o cb_util.o OBJS += repository_pool.o repository_pool_find.o repository_sync_index.o OBJS += $(EXTOBJS) $(COMPAT_SRCS) diff --git a/lib/cb_util.c b/lib/cb_util.c new file mode 100644 index 00000000..ebcb2cb4 --- /dev/null +++ b/lib/cb_util.c @@ -0,0 +1,140 @@ +/*- + * Copyright (c) 2011 Juan Romero Pardines. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifdef HAVE_VASPRINTF +# define _GNU_SOURCE /* for vasprintf(3) */ +#endif + +#include +#include +#include +#include +#include +#include + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "xbps_api_impl.h" + +void HIDDEN +xbps_set_cb_fetch(off_t file_size, + off_t file_offset, + off_t file_dloaded, + const char *file_name, + bool cb_start, + bool cb_update, + bool cb_end) +{ + const struct xbps_handle *xhp = xbps_handle_get(); + struct xbps_fetch_cb_data *xfcd; + + if (xhp->fetch_cb == NULL) + return; + + xfcd = malloc(sizeof(*xfcd)); + if (xfcd == NULL) + return; + + xfcd->file_size = file_size; + xfcd->file_offset = file_offset; + xfcd->file_dloaded = file_dloaded; + xfcd->file_name = file_name; + xfcd->cb_start = cb_start; + xfcd->cb_update = cb_update; + xfcd->cb_end = cb_end; + (*xhp->fetch_cb)(xfcd, xhp->fetch_cb_data); + free(xfcd); +} + +void HIDDEN +xbps_set_cb_state(xbps_state_t state, + int err, + const char *pkgname, + const char *version, + const char *fmt, + ...) +{ + struct xbps_state_cb_data *xscd; + const struct xbps_handle *xhp = xbps_handle_get(); + char *buf = NULL; + va_list va; + int retval; + + if (xhp->state_cb == NULL) + return; + + xscd = malloc(sizeof(*xscd)); + if (xscd == NULL) + return; + + xscd->state = state; + xscd->err = err; + xscd->pkgname = pkgname; + xscd->version = version; + if (fmt != NULL) { + va_start(va, fmt); + retval = vasprintf(&buf, fmt, va); + va_end(va); + if (retval == -1) + xscd->desc = NULL; + else + xscd->desc = buf; + } + (*xhp->state_cb)(xscd, xhp->fetch_cb_data); + if (buf != NULL) + free(buf); + + free(xscd); +} + +void HIDDEN +xbps_set_cb_unpack(const char *entry, + int64_t entry_size, + ssize_t entry_extract_count, + ssize_t entry_total_count, + bool entry_is_metadata, + bool entry_is_conf) +{ + const struct xbps_handle *xhp = xbps_handle_get(); + struct xbps_unpack_cb_data *xucd; + + if (xhp->unpack_cb == NULL) + return; + + xucd = malloc(sizeof(*xucd)); + if (xucd == NULL) + return; + + xucd->entry = entry; + xucd->entry_size = entry_size; + xucd->entry_extract_count = entry_extract_count; + xucd->entry_total_count = entry_total_count; + xucd->entry_is_metadata = entry_is_metadata; + xucd->entry_is_conf = entry_is_conf; + (*xhp->unpack_cb)(xucd, xhp->unpack_cb_data); + free(xucd); +} diff --git a/lib/compat/vasprintf.c b/lib/compat/vasprintf.c index 1bac36db..a9bf0df6 100644 --- a/lib/compat/vasprintf.c +++ b/lib/compat/vasprintf.c @@ -1,50 +1,81 @@ +/* $NetBSD: asprintf.c,v 1.2 2007/07/20 00:10:06 tnn Exp $ */ + /*- - * Copyright (c) 2008-2011 Juan Romero Pardines. + * Copyright (c) 2007 Joerg Sonnenberger . * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: + * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. */ -char * -xbps_xasprintf(const char *fmt, ...) +#include +#include +#include + +int +vasprintf(char **ret, const char *fmt, va_list ap) { - va_list ap, aq; + char *buf, *new_buf; size_t len; - int res; - char *buf; + int retval; - va_start(aq, fmt); - va_copy(ap, aq); - len = vsnprintf(NULL, 0, fmt, aq) + 1; - if ((buf = malloc(len)) == NULL) { - va_end(ap); - return NULL; + len = 128; + buf = malloc(len); + if (buf == NULL) { + *ret = NULL; + return -1; } - va_start(ap, fmt); - res = vsnprintf(buf, len, fmt, ap); - if (res < 0 || res >= (int)len) { + retval = vsnprintf(buf, len, fmt, ap); + if (retval < 0) { free(buf); - return NULL; + *ret = NULL; + return -1; } - return buf; + if (retval < len) { + new_buf = realloc(buf, retval + 1); + if (new_buf == NULL) + *ret = buf; + else + *ret = new_buf; + return retval; + } + + len = (size_t)retval + 1; + free(buf); + buf = malloc(len); + if (buf == NULL) { + *ret = NULL; + return -1; + } + retval = vsnprintf(buf, len, fmt, ap); + if (retval != len - 1) { + free(buf); + *ret = NULL; + return -1; + } + *ret = buf; + return retval; } diff --git a/lib/download.c b/lib/download.c index f34058c1..ab050160 100644 --- a/lib/download.c +++ b/lib/download.c @@ -231,7 +231,7 @@ xbps_fetch_file(const char *uri, goto out; } if (url_st.size == -1) { - xbps_error_printf("Remote file size is unknown!\n"); + xbps_dbg_printf("Remote file size is unknown!\n"); errno = EINVAL; rv = -1; goto out; @@ -240,7 +240,7 @@ xbps_fetch_file(const char *uri, * Remove local file if bigger than remote, and refetch the * whole shit again. */ - xbps_warn_printf("Local file %s is greater than remote, " + xbps_dbg_printf("Local file %s is greater than remote, " "removing local file and refetching...\n", filename); (void)remove(destfile); } else if (restart && url_st.mtime && url_st.size && @@ -260,29 +260,20 @@ xbps_fetch_file(const char *uri, rv = -1; goto out; } - /* * Initialize data for the fetch progress function callback * and let the user know that the transfer is going to start * immediately. */ - if (xhp != NULL && xhp->xbps_fetch_cb != NULL && xhp->xfcd != NULL) { - xhp->xfcd->file_name = filename; - xhp->xfcd->file_size = url_st.size; - xhp->xfcd->file_offset = url->offset; - xhp->xfcd->file_dloaded = -1; - xhp->xfcd->cb_start = true; - xhp->xfcd->cb_update = false; - xhp->xfcd->cb_end = false; - xhp->xbps_fetch_cb(xhp->xfcd); - } + xbps_set_cb_fetch(url_st.size, url->offset, -1, + filename, true, false, false); /* * Start fetching requested file. */ while ((bytes_read = fetchIO_read(fio, buf, sizeof(buf))) > 0) { bytes_written = write(fd, buf, (size_t)bytes_read); if (bytes_written != bytes_read) { - xbps_error_printf("Couldn't write to %s!\n", destfile); + xbps_dbg_printf("Couldn't write to %s!\n", destfile); rv = -1; goto out; } @@ -291,26 +282,11 @@ xbps_fetch_file(const char *uri, * Let the fetch progress callback know that * we are sucking more bytes from it. */ - if (xhp != NULL && xhp->xbps_fetch_cb != NULL && - xhp->xfcd != NULL) { - xhp->xfcd->file_dloaded = bytes_dload; - xhp->xfcd->cb_start = false; - xhp->xfcd->cb_update = true; - xhp->xbps_fetch_cb(xhp->xfcd); - } - - } - /* - * Let the fetch progress callback know that the file - * has been fetched. - */ - if (xhp != NULL && xhp->xbps_fetch_cb != NULL && xhp->xfcd != NULL) { - xhp->xfcd->cb_update = false; - xhp->xfcd->cb_end = true; - xhp->xbps_fetch_cb(xhp->xfcd); + xbps_set_cb_fetch(url_st.size, url->offset, bytes_dload, + filename, false, true, false); } if (bytes_read == -1) { - xbps_error_printf("IO error while fetching %s: %s\n", filename, + xbps_dbg_printf("IO error while fetching %s: %s\n", filename, fetchLastErrString); errno = EIO; rv = -1; @@ -320,6 +296,12 @@ xbps_fetch_file(const char *uri, rv = -1; goto out; } + /* + * Let the fetch progress callback know that the file + * has been fetched. + */ + xbps_set_cb_fetch(url_st.size, url->offset, bytes_dload, + filename, false, false, true); /* * Update mtime in local file to match remote file if transfer * was successful. @@ -331,7 +313,6 @@ xbps_fetch_file(const char *uri, rv = -1; goto out; } - /* File downloaded successfully */ rv = 1; diff --git a/lib/initend.c b/lib/initend.c index 310792fd..075ce283 100644 --- a/lib/initend.c +++ b/lib/initend.c @@ -203,12 +203,6 @@ xbps_end(struct xbps_handle *xh) prop_object_release(xh->cachedir); if (prop_object_type(xh->virtualpkgs_array) == PROP_TYPE_ARRAY) prop_object_release(xh->virtualpkgs_array); - if (xh->xfcd != NULL) - free(xh->xfcd); - if (xh->xucd != NULL) - free(xh->xucd); - if (xh->xscd != NULL) - free(xh->xscd); free(xh); xh = NULL; @@ -225,31 +219,7 @@ xbps_handle_get(void) struct xbps_handle * xbps_handle_alloc(void) { - struct xbps_handle *xh; - - xh = malloc(sizeof *xh); - if (xh == NULL) - return NULL; - xh->xscd = malloc(sizeof *xh->xscd); - if (xh->xscd == NULL) { - free(xh); - return NULL; - } - xh->xucd = malloc(sizeof *xh->xucd); - if (xh->xucd == NULL) { - free(xh->xscd); - free(xh); - return NULL; - } - xh->xfcd = malloc(sizeof *xh->xfcd); - if (xh->xfcd == NULL) { - free(xh->xucd); - free(xh->xscd); - free(xh); - return NULL; - } - - return xh; + return malloc(sizeof(struct xbps_handle)); } static void @@ -306,13 +276,3 @@ xbps_warn_printf(const char *fmt, ...) common_printf(stderr, "WARNING: ", fmt, ap); va_end(ap); } - -void -xbps_printf(const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - common_printf(stdout, NULL, fmt, ap); - va_end(ap); -} diff --git a/lib/package_config_files.c b/lib/package_config_files.c index 6476f44e..94c73cf5 100644 --- a/lib/package_config_files.c +++ b/lib/package_config_files.c @@ -179,7 +179,6 @@ xbps_entry_install_conf_file(prop_dictionary_t filesd, break; } } - /* * Orig = X, Curr = X, New = X * @@ -200,38 +199,39 @@ xbps_entry_install_conf_file(prop_dictionary_t filesd, } else if ((strcmp(sha256_orig, sha256_cur) == 0) && (strcmp(sha256_orig, sha256_new)) && (strcmp(sha256_cur, sha256_new))) { - xbps_printf("Updating configuration file `%s' " - "with new version.\n", cffile); + xbps_set_cb_state(XBPS_STATE_CONFIG_FILE, + 0, pkgname, version, + "Updating configuration file `%s' provided " + "by version `%s'.", cffile, version); rv = 1; break; /* * Orig = X, Curr = Y, New = X - * * Keep current file as is. */ } else if ((strcmp(sha256_orig, sha256_new) == 0) && (strcmp(sha256_cur, sha256_new)) && (strcmp(sha256_orig, sha256_cur))) { - xbps_printf("Keeping modified configuration file " - "`%s'.\n", cffile); + xbps_set_cb_state(XBPS_STATE_CONFIG_FILE, + 0, pkgname, version, + "Keeping modified configuration file `%s'.", + cffile); rv = 0; break; /* * Orig = X, Curr = Y, New = Y - * - * Install new file. + * Keep current file as is. */ } else if ((strcmp(sha256_cur, sha256_new) == 0) && (strcmp(sha256_orig, sha256_new)) && (strcmp(sha256_orig, sha256_cur))) { xbps_dbg_printf("%s: conf_file %s orig = X," "cur = Y, new = Y\n", pkgname, entry_pname); - rv = 1; + rv = 0; break; /* * Orig = X, Curr = Y, New = Z - * - * Install new file as file.new- + * Install new file as .new- */ } else if ((strcmp(sha256_orig, sha256_cur)) && (strcmp(sha256_cur, sha256_new)) && @@ -242,10 +242,10 @@ xbps_entry_install_conf_file(prop_dictionary_t filesd, rv = -1; break; } - xbps_printf("Keeping modified configuration file " - "`%s'.\n", cffile); - xbps_printf("Installing new configuration file as " - "`%s.new-%s'\n", cffile, version); + xbps_set_cb_state(XBPS_STATE_CONFIG_FILE, + 0, pkgname, version, + "Installing new configuration file to " + "`%s.new-%s'.", cffile, version); archive_entry_set_pathname(entry, buf); free(buf); rv = 1; diff --git a/lib/package_configure.c b/lib/package_configure.c index 0d4fcaac..662c8161 100644 --- a/lib/package_configure.c +++ b/lib/package_configure.c @@ -120,15 +120,8 @@ xbps_configure_pkg(const char *pkgname, if (pkgver == NULL) return ENOMEM; - if (xhp->xbps_state_cb) { - xhp->xscd->desc = NULL; - xhp->xscd->binpkg_fname = NULL; - xhp->xscd->repourl = NULL; - xhp->xscd->err = 0; - xhp->xscd->state = XBPS_STATE_CONFIGURE; - xhp->xscd->pkgver = pkgver; - xhp->xbps_state_cb(xhp->xscd); - } + xbps_set_cb_state(XBPS_STATE_CONFIGURE, 0, pkgname, lver, + "Configuring package `%s' ...", pkgver); buf = xbps_xasprintf(".%s/metadata/%s/INSTALL", XBPS_META_PATH, pkgname); @@ -138,8 +131,10 @@ xbps_configure_pkg(const char *pkgname, } if (chdir(prop_string_cstring_nocopy(xhp->rootdir)) == -1) { - xbps_dbg_printf("%s: [configure] chdir to '%s' returned %s\n", - pkgname, prop_string_cstring_nocopy(xhp->rootdir), + xbps_set_cb_state(XBPS_STATE_CONFIGURE_FAIL, errno, + pkgname, lver, + "%s: [configure] failed to chdir to rootdir `%s': %s", + pkgver, prop_string_cstring_nocopy(xhp->rootdir), strerror(errno)); free(buf); free(pkgver); @@ -149,10 +144,12 @@ xbps_configure_pkg(const char *pkgname, if (access(buf, X_OK) == 0) { if (xbps_file_exec(buf, "post", pkgname, lver, update ? "yes" : "no", NULL) != 0) { + xbps_set_cb_state(XBPS_STATE_CONFIGURE_FAIL, errno, + pkgname, lver, + "%s: [configure] INSTALL script failed to execute " + "the post ACTION: %s", pkgver, strerror(errno)); free(buf); free(pkgver); - xbps_error_printf("%s: post install script error: %s\n", - pkgname, strerror(errno)); return errno; } } else { @@ -165,14 +162,13 @@ xbps_configure_pkg(const char *pkgname, free(buf); rv = xbps_set_pkg_state_installed(pkgname, lver, pkgver, XBPS_PKG_STATE_INSTALLED); - free(pkgver); - - if (rv != 0 && xhp->xbps_state_cb) { - xhp->xscd->pkgver = pkgver; - xhp->xscd->err = rv; - xhp->xscd->state = XBPS_STATE_CONFIGURE_FAIL; - xhp->xbps_state_cb(xhp->xscd); + if (rv != 0) { + xbps_set_cb_state(XBPS_STATE_CONFIGURE_FAIL, rv, + pkgname, lver, + "%s: [configure] failed to set state to installed: %s", + pkgver, strerror(rv)); } + free(pkgver); return rv; } diff --git a/lib/package_purge.c b/lib/package_purge.c index bf2d458f..7c67b170 100644 --- a/lib/package_purge.c +++ b/lib/package_purge.c @@ -47,7 +47,10 @@ */ static int -remove_pkg_metadata(const char *pkgname, const char *rootdir) +remove_pkg_metadata(const char *pkgname, + const char *version, + const char *pkgver, + const char *rootdir) { struct dirent *dp; DIR *dirp; @@ -80,10 +83,12 @@ remove_pkg_metadata(const char *pkgname, const char *rootdir) return ENOMEM; } - if (unlink(path) == -1) - xbps_warn_printf("can't remove metadata file: " - "`%s': %s\n", dp->d_name, strerror(errno)); - + if (unlink(path) == -1) { + xbps_set_cb_state(XBPS_STATE_PURGE_FAIL, + errno, pkgname, version, + "%s: [purge] failed to remove metafile `%s': %s", + pkgver, path, strerror(errno)); + } free(path); } (void)closedir(dirp); @@ -121,13 +126,14 @@ xbps_purge_pkg(const char *pkgname, bool check_state) { struct xbps_handle *xhp; prop_dictionary_t dict, pkgd; - const char *version; + const char *version, *pkgver; char *buf; int rv = 0; pkg_state_t state; assert(pkgname != NULL); xhp = xbps_handle_get(); + /* * Firstly let's get the pkg dictionary from regpkgdb. */ @@ -138,6 +144,10 @@ xbps_purge_pkg(const char *pkgname, bool check_state) pkgname, strerror(errno)); return errno; } + prop_dictionary_get_cstring_nocopy(pkgd, "pkgver", &pkgver); + prop_dictionary_get_cstring_nocopy(pkgd, "version", &version); + xbps_set_cb_state(XBPS_STATE_PURGE, 0, pkgname, version, + "Purging package `%s'...", pkgver); if (check_state) { /* @@ -156,16 +166,24 @@ xbps_purge_pkg(const char *pkgname, bool check_state) */ dict = xbps_dictionary_from_metadata_plist(pkgname, XBPS_PKGFILES); if (dict == NULL) { - xbps_dbg_printf("[purge] %s: failed to read files.plist (%s)\n", - pkgname, strerror(errno)); + xbps_set_cb_state(XBPS_STATE_PURGE_FAIL, + errno, pkgname, version, + "%s: [purge] failed to read metafile `%s': %s", + pkgver, XBPS_PKGFILES, strerror(errno)); if (errno != ENOENT) return errno; } else { if (prop_dictionary_get(dict, "conf_files")) { - rv = xbps_remove_pkg_files(dict, "conf_files"); + rv = xbps_remove_pkg_files(dict, "conf_files", pkgver); prop_object_release(dict); - if (rv != 0) + if (rv != 0) { + xbps_set_cb_state(XBPS_STATE_PURGE_FAIL, + rv, pkgname, version, + "%s: [purge] failed to remove " + "configuration files: %s", + pkgver, strerror(rv)); return rv; + } } } /* @@ -173,8 +191,11 @@ xbps_purge_pkg(const char *pkgname, bool check_state) */ if (chdir(prop_string_cstring_nocopy(xhp->rootdir)) == -1) { rv = errno; - xbps_error_printf("[purge] %s: cannot change to rootdir " - "(%s)\n", pkgname, strerror(rv)); + xbps_set_cb_state(XBPS_STATE_PURGE_FAIL, + rv, pkgname, version, + "%s: [purge] failed to chdir to rootdir `%s': %s", + pkgver, prop_string_cstring_nocopy(xhp->rootdir), + strerror(rv)); return rv; } buf = xbps_xasprintf(".%s/metadata/%s/REMOVE", XBPS_META_PATH, pkgname); @@ -183,16 +204,15 @@ xbps_purge_pkg(const char *pkgname, bool check_state) return rv; } if (access(buf, X_OK) == 0) { - prop_dictionary_get_cstring_nocopy(pkgd, "version", &version); - - if (xbps_file_exec(buf, "purge", - pkgname, version, "no", NULL) != 0) { + rv = xbps_file_exec(buf, "purge", pkgname, version, "no", NULL); + if (rv != 0) { free(buf); if (errno && errno != ENOENT) { - rv = errno; - xbps_error_printf("%s: purge action error in " - "REMOVE script: %s\n", pkgname, - strerror(errno)); + xbps_set_cb_state(XBPS_STATE_PURGE_FAIL, + errno, pkgname, version, + "%s: [purge] REMOVE script failed to " + "execute purge ACTION: %s", + pkgver, strerror(errno)); return rv; } } @@ -201,20 +221,17 @@ xbps_purge_pkg(const char *pkgname, bool check_state) /* * Remove metadata dir and unregister package. */ - if ((rv = remove_pkg_metadata(pkgname, + if ((rv = remove_pkg_metadata(pkgname, version, pkgver, prop_string_cstring_nocopy(xhp->rootdir))) != 0) { - xbps_dbg_printf("[purge] %s: failed to remove metadata " - "files (%s)\n", pkgname, strerror(rv)); + xbps_set_cb_state(XBPS_STATE_PURGE_FAIL, + rv, pkgname, version, + "%s: [purge] failed to remove metadata files: %s", + pkgver, strerror(rv)); if (rv != ENOENT) return rv; } - if ((rv = xbps_unregister_pkg(pkgname)) != 0) { - xbps_error_printf("%s: couldn't unregister package: %s\n", - pkgname, strerror(rv)); + if ((rv = xbps_unregister_pkg(pkgname, version)) != 0) return rv; - } - if (xhp->flags & XBPS_FLAG_VERBOSE) - xbps_printf("Package %s purged successfully.\n", pkgname); return rv; } diff --git a/lib/package_register.c b/lib/package_register.c index c8c0463d..b81aa2c7 100644 --- a/lib/package_register.c +++ b/lib/package_register.c @@ -67,6 +67,9 @@ xbps_register_pkg(prop_dictionary_t pkgrd) provides = prop_dictionary_get(pkgrd, "provides"); reqby = prop_dictionary_get(pkgrd, "requiredby"); + xbps_set_cb_state(XBPS_STATE_REGISTER, 0, pkgname, version, + "Registering package `%s'...", pkgver); + assert(pkgname != NULL); assert(version != NULL); assert(desc != NULL); @@ -108,9 +111,6 @@ xbps_register_pkg(prop_dictionary_t pkgrd) else if (xhp->install_reason_manual) autoinst = false; - xbps_dbg_printf("%s: autoinst %d reason_auto %d reason_manual %d\n", - pkgver, autoinst, xhp->install_reason_auto, xhp->install_reason_manual); - if (!prop_dictionary_set_bool(pkgd, "automatic-install", autoinst)) { prop_object_release(pkgd); @@ -149,6 +149,12 @@ xbps_register_pkg(prop_dictionary_t pkgrd) return ENOENT; } out: + if (rv != 0) { + xbps_set_cb_state(XBPS_STATE_REGISTER_FAIL, + rv, pkgname, version, + "%s: failed to register package: %s", + pkgver, strerror(rv)); + } prop_object_release(dict); free(plist); @@ -156,7 +162,7 @@ out: } int -xbps_unregister_pkg(const char *pkgname) +xbps_unregister_pkg(const char *pkgname, const char *version) { struct xbps_handle *xhp; char *plist; @@ -164,17 +170,28 @@ xbps_unregister_pkg(const char *pkgname) assert(pkgname != NULL); + xbps_set_cb_state(XBPS_STATE_UNREGISTER, 0, pkgname, version, + "Unregistering package `%s'...", pkgname); + xhp = xbps_handle_get(); plist = xbps_xasprintf("%s/%s/%s", prop_string_cstring_nocopy(xhp->rootdir), XBPS_META_PATH, XBPS_REGPKGDB); - if (plist == NULL) - return ENOMEM; - - if (!xbps_remove_pkg_dict_from_plist_by_name(pkgname, plist)) + if (plist == NULL) { + rv = ENOMEM; + goto out; + } + if (!xbps_remove_pkg_dict_from_plist_by_name(pkgname, plist)) { rv = errno; - + goto out; + } +out: + if (rv != 0) { + xbps_set_cb_state(XBPS_STATE_UNREGISTER_FAIL, + rv, pkgname, version, + "%s: failed to unregister package: %s", + pkgname, strerror(rv)); + } free(plist); - return rv; } diff --git a/lib/package_remove.c b/lib/package_remove.c index e89713b9..d222fdb7 100644 --- a/lib/package_remove.c +++ b/lib/package_remove.c @@ -71,14 +71,16 @@ */ int -xbps_remove_pkg_files(prop_dictionary_t dict, const char *key) +xbps_remove_pkg_files(prop_dictionary_t dict, + const char *key, + const char *pkgver) { struct xbps_handle *xhp; prop_array_t array; prop_object_iterator_t iter; prop_object_t obj; - const char *file, *sha256, *curobj = NULL; - char *path = NULL; + const char *file, *sha256, *version, *curobj = NULL; + char *path = NULL, *pkgname = NULL; int rv = 0; assert(prop_object_type(dict) == PROP_TYPE_DICTIONARY); @@ -104,6 +106,9 @@ xbps_remove_pkg_files(prop_dictionary_t dict, const char *key) else if (strcmp(key, "dirs") == 0) curobj = "directory"; + pkgname = xbps_pkg_name(pkgver); + version = xbps_pkg_version(pkgver); + while ((obj = prop_object_iterator_next(iter))) { prop_dictionary_get_cstring_nocopy(obj, "file", &file); path = xbps_xasprintf("%s/%s", @@ -123,28 +128,41 @@ xbps_remove_pkg_files(prop_dictionary_t dict, const char *key) "sha256", &sha256); rv = xbps_file_hash_check(path, sha256); if (rv == ENOENT) { - xbps_warn_printf("'%s' doesn't exist!\n", file); + /* missing file, ignore it */ + xbps_set_cb_state( + XBPS_STATE_REMOVE_FILE_HASH_FAIL, + rv, pkgname, version, + "%s: failed to check hash for %s `%s': %s", + pkgver, curobj, file, strerror(rv)); free(path); rv = 0; continue; } else if (rv == ERANGE) { rv = 0; - if (xhp->flags & XBPS_FLAG_FORCE) { - xbps_warn_printf("'%s': SHA256 " - "mismatch, forcing removal...\n", - file); - } else { - xbps_warn_printf("'%s': SHA256 " - "mismatch, preserving file...\n", - file); - } if ((xhp->flags & XBPS_FLAG_FORCE) == 0) { + xbps_set_cb_state( + XBPS_STATE_REMOVE_FILE_HASH_FAIL, + 0, pkgname, version, + "%s: %s `%s' SHA256 mismatch, " + "preserving file", pkgver, + curobj, file); free(path); continue; + } else { + xbps_set_cb_state( + XBPS_STATE_REMOVE_FILE_HASH_FAIL, + 0, pkgname, version, + "%s: %s `%s' SHA256 mismatch, " + "forcing removal", pkgver, + curobj, file); } } else if (rv != 0 && rv != ERANGE) { - xbps_error_printf("failed to check hash for " - "`%s': %s\n", file, strerror(rv)); + xbps_set_cb_state( + XBPS_STATE_REMOVE_FILE_HASH_FAIL, + rv, pkgname, version, + "%s: [remove] failed to check hash for " + "%s `%s': %s", pkgver, curobj, file, + strerror(rv)); free(path); break; } @@ -153,19 +171,21 @@ xbps_remove_pkg_files(prop_dictionary_t dict, const char *key) * Remove the object if possible. */ if (remove(path) == -1) { - if (errno != EEXIST && - errno != ENOTEMPTY && - errno != EBUSY) - xbps_warn_printf("can't remove %s `%s': %s\n", - curobj, file, strerror(errno)); + xbps_set_cb_state(XBPS_STATE_REMOVE_FILE_FAIL, + errno, pkgname, version, + "%s: failed to remove %s `%s': %s", pkgver, + curobj, file, strerror(errno)); } else { - /* Success */ - if (xhp->flags & XBPS_FLAG_VERBOSE) - xbps_printf("Removed %s: `%s'\n", curobj, file); + /* success */ + xbps_set_cb_state(XBPS_STATE_REMOVE_FILE, + 0, pkgname, version, + "Removed %s `%s'", curobj, file); } free(path); } prop_object_iterator_release(iter); + if (pkgname) + free(pkgname); return rv; } @@ -175,8 +195,7 @@ xbps_remove_pkg(const char *pkgname, const char *version, bool update) { struct xbps_handle *xhp; prop_dictionary_t dict; - const char *pkgver; - char *buf; + char *buf, *pkgver; int rv = 0; bool rmfile_exists = false; @@ -190,14 +209,31 @@ xbps_remove_pkg(const char *pkgname, const char *version, bool update) if (!xbps_check_is_installed_pkg_by_name(pkgname)) return ENOENT; - buf = xbps_xasprintf(".%s/metadata/%s/REMOVE", - XBPS_META_PATH, pkgname); - if (buf == NULL) + pkgver = xbps_xasprintf("%s-%s", pkgname, version); + if (pkgver == NULL) return ENOMEM; + xbps_set_cb_state(XBPS_STATE_REMOVE, 0, pkgname, version, + "Removing package `%s'...", pkgver); + + buf = xbps_xasprintf(".%s/metadata/%s/REMOVE", + XBPS_META_PATH, pkgname); + if (buf == NULL) { + rv = ENOMEM; + free(pkgver); + return rv; + } + if (chdir(prop_string_cstring_nocopy(xhp->rootdir)) == -1) { + rv = errno; + xbps_set_cb_state(XBPS_STATE_REMOVE_FAIL, + rv, pkgname, version, + "%s: [remove] failed to chdir to rootdir `%s': %s", + pkgver, prop_string_cstring_nocopy(xhp->rootdir), + strerror(rv)); free(buf); - return EINVAL; + free(pkgver); + return rv; } /* @@ -207,13 +243,18 @@ xbps_remove_pkg(const char *pkgname, const char *version, bool update) rmfile_exists = true; if (xbps_file_exec(buf, "pre", pkgname, version, update ? "yes" : "no", NULL) != 0) { - xbps_error_printf("%s: pre remove script error: %s\n", - pkgname, strerror(errno)); + xbps_set_cb_state(XBPS_STATE_REMOVE_FAIL, + errno, pkgname, version, + "%s: [remove] REMOVE script failed to " + "execute pre ACTION: %s", + pkgver, strerror(errno)); + free(pkgver); free(buf); return errno; } } else { if (errno != ENOENT) { + free(pkgver); free(buf); return errno; } @@ -225,6 +266,7 @@ xbps_remove_pkg(const char *pkgname, const char *version, bool update) * continue. Its files will be overwritten later in unpack phase. */ if (update) { + free(pkgver); free(buf); return xbps_requiredby_pkg_remove(pkgname); } @@ -234,27 +276,30 @@ xbps_remove_pkg(const char *pkgname, const char *version, bool update) */ dict = xbps_dictionary_from_metadata_plist(pkgname, XBPS_PKGFILES); if (dict == NULL) { + free(pkgver); free(buf); return errno; } - prop_dictionary_get_cstring_nocopy(dict, "pkgver", &pkgver); /* Remove links */ - if ((rv = xbps_remove_pkg_files(dict, "links")) != 0) { + if ((rv = xbps_remove_pkg_files(dict, "links", pkgver)) != 0) { prop_object_release(dict); free(buf); + free(pkgver); return rv; } /* Remove regular files */ - if ((rv = xbps_remove_pkg_files(dict, "files")) != 0) { + if ((rv = xbps_remove_pkg_files(dict, "files", pkgver)) != 0) { prop_object_release(dict); free(buf); + free(pkgver); return rv; } /* Remove dirs */ - if ((rv = xbps_remove_pkg_files(dict, "dirs")) != 0) { + if ((rv = xbps_remove_pkg_files(dict, "dirs", pkgver)) != 0) { prop_object_release(dict); free(buf); + free(pkgver); return rv; } prop_object_release(dict); @@ -265,9 +310,12 @@ xbps_remove_pkg(const char *pkgname, const char *version, bool update) */ if (rmfile_exists && (xbps_file_exec(buf, "post", pkgname, version, "no", NULL) != 0)) { - xbps_error_printf("%s: post remove script error: %s\n", - pkgname, strerror(errno)); + xbps_set_cb_state(XBPS_STATE_REMOVE_FAIL, + errno, pkgname, version, + "%s: [remove] REMOVE script failed to execute " + "post ACTION: %s", pkgver, strerror(errno)); free(buf); + free(pkgver); return errno; } free(buf); @@ -275,15 +323,27 @@ xbps_remove_pkg(const char *pkgname, const char *version, bool update) /* * Update the requiredby array of all required dependencies. */ - if ((rv = xbps_requiredby_pkg_remove(pkgname)) != 0) + if ((rv = xbps_requiredby_pkg_remove(pkgname)) != 0) { + xbps_set_cb_state(XBPS_STATE_REMOVE_FAIL, + rv, pkgname, version, + "%s: [remove] failed to remove requiredby entries: %s", + pkgver, strerror(rv)); + free(pkgver); return rv; + } /* * Set package state to "config-files". */ rv = xbps_set_pkg_state_installed(pkgname, version, pkgver, XBPS_PKG_STATE_CONFIG_FILES); - + if (rv != 0) { + xbps_set_cb_state(XBPS_STATE_REMOVE_FAIL, + rv, pkgname, version, + "%s: [remove] failed to set state to config-files: %s", + pkgver, strerror(rv)); + } + free(pkgver); return rv; } diff --git a/lib/package_remove_obsoletes.c b/lib/package_remove_obsoletes.c index 410200e2..d73b62ce 100644 --- a/lib/package_remove_obsoletes.c +++ b/lib/package_remove_obsoletes.c @@ -36,7 +36,11 @@ #include "xbps_api_impl.h" int HIDDEN -xbps_remove_obsoletes(prop_dictionary_t oldd, prop_dictionary_t newd) +xbps_remove_obsoletes(const char *pkgname, + const char *version, + const char *pkgver, + prop_dictionary_t oldd, + prop_dictionary_t newd) { prop_object_iterator_t iter, iter2; prop_object_t obj, obj2; @@ -127,19 +131,16 @@ again: * Obsolete obj found, remove it. */ if (remove(file) == -1) { - if (errno != EEXIST && - errno != ENOTEMPTY && - errno != EBUSY) { - xbps_warn_printf("couldn't remove obsole entry " - "`%s': %s\n", - prop_string_cstring_nocopy(oldstr), - strerror(errno)); - } + xbps_set_cb_state(XBPS_STATE_REMOVE_FILE_OBSOLETE_FAIL, + errno, pkgname, version, + "%s: failed to remove obsolete entry `%s': %s", + pkgver, file, strerror(errno)); free(file); continue; } - xbps_printf("Removed obsolete entry: %s\n", - prop_string_cstring_nocopy(oldstr)); + xbps_set_cb_state(XBPS_STATE_REMOVE_FILE_OBSOLETE, + 0, pkgname, version, + "Removed obsolete entry: %s", file); free(file); } if (!dolinks) { diff --git a/lib/package_unpack.c b/lib/package_unpack.c index c198a0e7..d0785698 100644 --- a/lib/package_unpack.c +++ b/lib/package_unpack.c @@ -83,18 +83,25 @@ static int extract_metafile(struct archive *ar, struct archive_entry *entry, const char *file, - const char *pkgname, - const char *version, + const char *pkgver, bool exec, int flags) { - char *buf; + const char *version; + char *buf, *pkgname; int rv; + pkgname = xbps_pkg_name(pkgver); + if (pkgname == NULL) + return ENOMEM; + version = xbps_pkg_version(pkgver); + buf = xbps_xasprintf(".%s/metadata/%s/%s", XBPS_META_PATH, pkgname, file); - if (buf == NULL) + if (buf == NULL) { + free(pkgname); return ENOMEM; + } archive_entry_set_pathname(entry, buf); free(buf); @@ -102,86 +109,99 @@ extract_metafile(struct archive *ar, archive_entry_set_perm(entry, 0750); if (archive_read_extract(ar, entry, flags) != 0) { - if ((rv = archive_errno(ar)) != EEXIST) { - xbps_error_printf("failed to extract metadata file `%s'" - "for `%s-%s': %s\n", file, pkgname, version, - strerror(rv)); - } + rv = archive_errno(ar); + xbps_set_cb_state(XBPS_STATE_UNPACK_FAIL, + rv, pkgname, version, + "%s: [unpack] failed to extract metafile `%s': %s", + pkgver, file, strerror(rv)); + free(pkgname); + return rv; } + free(pkgname); return 0; } static int -remove_metafile(const char *file, const char *pkgname, const char *version) +remove_metafile(const char *file, const char *pkgver) { - char *buf; + const char *version; + char *buf, *pkgname; + + pkgname = xbps_pkg_name(pkgver); + if (pkgname == NULL) + return ENOMEM; + version = xbps_pkg_version(pkgver); buf = xbps_xasprintf(".%s/metadata/%s/%s", XBPS_META_PATH, pkgname, file); - if (buf == NULL) + if (buf == NULL) { + free(pkgname); return ENOMEM; - + } if (unlink(buf) == -1) { if (errno && errno != ENOENT) { - xbps_error_printf("failed to remove metadata file " - "`%s' while unpacking `%s-%s': %s\n", file, - pkgname, version, strerror(errno)); + xbps_set_cb_state(XBPS_STATE_UNPACK_FAIL, + errno, pkgname, version, + "%s: [unpack] failed to remove metafile `%s': %s", + pkgver, file, strerror(errno)); + free(pkgname); free(buf); return errno; } } free(buf); + free(pkgname); return 0; } -/* - * Execute the unpack progress function callback if set and its - * private data is also set. It's so sad that - * archive_read_set_progress_callback() from libarchive(3) cannot be used - * here because sometimes it misses some entries by unknown reasons. - */ -#define RUN_PROGRESS_CB() \ -do { \ - if (xhp->xbps_unpack_cb != NULL) \ - (*xhp->xbps_unpack_cb)(xhp->xucd); \ -} while (0) - static int -unpack_archive(prop_dictionary_t pkg_repod, - struct archive *ar, - const char *pkgname, - const char *version, - struct xbps_handle *xhp) +unpack_archive(prop_dictionary_t pkg_repod, struct archive *ar) { prop_dictionary_t propsd = NULL, filesd = NULL, old_filesd = NULL; prop_array_t array; + const struct xbps_handle *xhp = xbps_handle_get(); const struct stat *entry_statp; + struct xbps_unpack_cb_data *xucd = NULL; struct archive_entry *entry; size_t nmetadata = 0, entry_idx = 0; - const char *entry_pname, *transact; + const char *entry_pname, *transact, *pkgname, *version, *pkgver, *fname; char *buf = NULL, *pkgfilesd = NULL; int rv, flags; bool preserve, update, replace; assert(prop_object_type(pkg_repod) == PROP_TYPE_DICTIONARY); assert(ar != NULL); - assert(pkgname != NULL); - assert(version != NULL); preserve = update = false; - - if (chdir(prop_string_cstring_nocopy(xhp->rootdir)) == -1) { - xbps_error_printf("cannot chdir to rootdir for " - "`%s-%s': %s\n", pkgname, version, strerror(errno)); - return errno; - } - prop_dictionary_get_bool(pkg_repod, "preserve", &preserve); prop_dictionary_get_cstring_nocopy(pkg_repod, "transaction", &transact); - assert(transact != NULL); + prop_dictionary_get_cstring_nocopy(pkg_repod, "pkgname", &pkgname); + prop_dictionary_get_cstring_nocopy(pkg_repod, "version", &version); + prop_dictionary_get_cstring_nocopy(pkg_repod, "pkgver", &pkgver); + prop_dictionary_get_cstring_nocopy(pkg_repod, "filename", &fname); + + if (xhp->unpack_cb != NULL) { + /* initialize data for unpack cb */ + xucd = malloc(sizeof(*xucd)); + if (xucd == NULL) + return ENOMEM; + + xucd->entry_extract_count = 0; + xucd->entry_total_count = 0; + } + + if (chdir(prop_string_cstring_nocopy(xhp->rootdir)) == -1) { + xbps_set_cb_state(XBPS_STATE_UNPACK_FAIL, + errno, pkgname, version, + "%s: [unpack] failed to chdir to rootdir `%s': %s", + pkgver, prop_string_cstring_nocopy(xhp->rootdir), + strerror(errno)); + rv = errno; + goto out; + } if (strcmp(transact, "update") == 0) update = true; @@ -192,10 +212,10 @@ unpack_archive(prop_dictionary_t pkg_repod, * anymore. */ if (update) { - if ((rv = remove_metafile("INSTALL", pkgname, version)) != 0) - return rv; - if ((rv = remove_metafile("REMOVE", pkgname, version)) != 0) - return rv; + if ((rv = remove_metafile("INSTALL", pkgver)) != 0) + goto out; + if ((rv = remove_metafile("REMOVE", pkgver)) != 0) + goto out; } /* * Process the archive files. @@ -214,11 +234,11 @@ unpack_archive(prop_dictionary_t pkg_repod, /* * Prepare unpack callback ops. */ - if (xhp->xbps_unpack_cb != NULL) { - xhp->xucd->entry = entry_pname; - xhp->xucd->entry_size = archive_entry_size(entry); - xhp->xucd->entry_is_metadata = false; - xhp->xucd->entry_is_conf = false; + if (xucd != NULL) { + xucd->entry = entry_pname; + xucd->entry_size = archive_entry_size(entry); + xucd->entry_is_metadata = false; + xucd->entry_is_conf = false; } if (strcmp("./INSTALL", entry_pname) == 0) { /* @@ -232,7 +252,7 @@ unpack_archive(prop_dictionary_t pkg_repod, goto out; } rv = extract_metafile(ar, entry, "INSTALL", - pkgname, version, true, flags); + pkgver, true, flags); if (rv != 0) { free(buf); goto out; @@ -241,27 +261,33 @@ unpack_archive(prop_dictionary_t pkg_repod, pkgname, version, update ? "yes" : "no", NULL); free(buf); if (rv != 0) { - xbps_error_printf("%s-%s: pre-install script " - "error: %s\n", pkgname, version, - strerror(rv)); + xbps_set_cb_state(XBPS_STATE_UNPACK_FAIL, + rv, pkgname, version, + "%s: [unpack] INSTALL script failed " + "to execute pre ACTION: %s", + pkgver, strerror(rv)); goto out; } nmetadata++; - xhp->xucd->entry_is_metadata = true; - xhp->xucd->entry_extract_count++; - RUN_PROGRESS_CB(); + if (xucd != NULL) { + xucd->entry_is_metadata = true; + xucd->entry_extract_count++; + (*xhp->unpack_cb)(xucd, xhp->unpack_cb_data); + } continue; } else if (strcmp("./REMOVE", entry_pname) == 0) { rv = extract_metafile(ar, entry, "REMOVE", - pkgname, version, true, flags); + pkgver, true, flags); if (rv != 0) goto out; nmetadata++; - xhp->xucd->entry_is_metadata = true; - xhp->xucd->entry_extract_count++; - RUN_PROGRESS_CB(); + if (xucd != NULL) { + xucd->entry_is_metadata = true; + xucd->entry_extract_count++; + (*xhp->unpack_cb)(xucd, xhp->unpack_cb_data); + } continue; } else if (strcmp("./files.plist", entry_pname) == 0) { @@ -276,14 +302,16 @@ unpack_archive(prop_dictionary_t pkg_repod, goto out; } nmetadata++; - xhp->xucd->entry_is_metadata = true; - xhp->xucd->entry_extract_count++; - RUN_PROGRESS_CB(); + if (xucd != NULL) { + xucd->entry_is_metadata = true; + xucd->entry_extract_count++; + (*xhp->unpack_cb)(xucd, xhp->unpack_cb_data); + } continue; } else if (strcmp("./props.plist", entry_pname) == 0) { rv = extract_metafile(ar, entry, XBPS_PKGPROPS, - pkgname, version, false, flags); + pkgver, false, flags); if (rv != 0) goto out; @@ -294,9 +322,11 @@ unpack_archive(prop_dictionary_t pkg_repod, goto out; } nmetadata++; - xhp->xucd->entry_is_metadata = true; - xhp->xucd->entry_extract_count++; - RUN_PROGRESS_CB(); + if (xucd != NULL) { + xucd->entry_is_metadata = true; + xucd->entry_extract_count++; + (*xhp->unpack_cb)(xucd, xhp->unpack_cb_data); + } continue; } /* @@ -311,9 +341,12 @@ unpack_archive(prop_dictionary_t pkg_repod, * This is not an XBPS binary package. */ if (entry_idx >= 3) { - xbps_error_printf("invalid binary pkg archive" - "for `%s-%s'\n", pkgname, version); - return ENODEV; + xbps_set_cb_state(XBPS_STATE_UNPACK_FAIL, + ENODEV, pkgname, version, + "%s: [unpack] invalid binary package `%s'.", + pkgver, fname); + rv = ENODEV; + goto out; } entry_idx++; @@ -323,17 +356,18 @@ unpack_archive(prop_dictionary_t pkg_repod, * Compute total entries in progress data, if set. * total_entries = metadata + files + conf_files + links. */ - xhp->xucd->entry_total_count = nmetadata; - array = prop_dictionary_get(filesd, "files"); - xhp->xucd->entry_total_count += - (ssize_t)prop_array_count(array); - array = prop_dictionary_get(filesd, "conf_files"); - xhp->xucd->entry_total_count += - (ssize_t)prop_array_count(array); - array = prop_dictionary_get(filesd, "links"); - xhp->xucd->entry_total_count += - (ssize_t)prop_array_count(array); - + if (xucd != NULL) { + xucd->entry_total_count = nmetadata; + array = prop_dictionary_get(filesd, "files"); + xucd->entry_total_count += + (ssize_t)prop_array_count(array); + array = prop_dictionary_get(filesd, "conf_files"); + xucd->entry_total_count += + (ssize_t)prop_array_count(array); + array = prop_dictionary_get(filesd, "links"); + xucd->entry_total_count += + (ssize_t)prop_array_count(array); + } replace = false; if (prop_dictionary_get_bool(pkg_repod, "replacing-package", &replace) && replace) { @@ -364,8 +398,8 @@ unpack_archive(prop_dictionary_t pkg_repod, goto out; } else if (rv == 1) { /* configuration file */ - if (xhp->xucd != NULL) - xhp->xucd->entry_is_conf = true; + if (xucd != NULL) + xucd->entry_is_conf = true; rv = xbps_entry_install_conf_file(filesd, entry, entry_pname, pkgname, version); @@ -411,25 +445,24 @@ unpack_archive(prop_dictionary_t pkg_repod, */ if (archive_read_extract(ar, entry, flags) != 0) { rv = archive_errno(ar); - if (rv != EEXIST) { - xbps_error_printf("failed to extract `%s' " - "from `%s-%s': %s\n", entry_pname, - pkgname, version, strerror(rv)); - goto out; - } else { - xbps_warn_printf("ignoring existing " - "entry: %s\n", entry_pname); - } + xbps_set_cb_state(XBPS_STATE_UNPACK_FAIL, + rv, pkgname, version, + "%s: [unpack] failed to extract file `%s': %s", + pkgver, entry_pname, strerror(rv)); + } + if (xucd != NULL) { + xucd->entry_extract_count++; + (*xhp->unpack_cb)(xucd, xhp->unpack_cb_data); } - xhp->xucd->entry_extract_count++; - RUN_PROGRESS_CB(); } /* * If there was any error extracting files from archive, error out. */ if ((rv = archive_errno(ar)) != 0) { - xbps_dbg_printf("%s-%s: error extracting pkg files: %s\n", - pkgname, version, archive_errno(ar)); + xbps_set_cb_state(XBPS_STATE_UNPACK_FAIL, + rv, pkgname, version, + "%s: [unpack] error while extracting files from `%s': %s", + pkgver, fname, strerror(rv)); goto out; } /* @@ -449,7 +482,9 @@ unpack_archive(prop_dictionary_t pkg_repod, */ old_filesd = prop_dictionary_internalize_from_zfile(pkgfilesd); if (prop_object_type(old_filesd) == PROP_TYPE_DICTIONARY) { - if ((rv = xbps_remove_obsoletes(old_filesd, filesd)) != 0) { + rv = xbps_remove_obsoletes(pkgname, version, + pkgver, old_filesd, filesd); + if (rv != 0) { prop_object_release(old_filesd); rv = errno; goto out; @@ -469,8 +504,10 @@ out1: goto out; } if (xbps_mkpath(buf, 0755) == -1) { - xbps_dbg_printf("%s-%s: failed to create pkg metadir: %s\n", - pkgname, version, strerror(errno)); + xbps_set_cb_state(XBPS_STATE_UNPACK_FAIL, + errno, pkgname, version, + "%s: [unpack] failed to create pkg metadir `%s': %s", + buf, pkgver, strerror(errno)); rv = errno; goto out; } @@ -479,12 +516,15 @@ out1: */ if (!prop_dictionary_externalize_to_zfile(filesd, pkgfilesd)) { rv = errno; - xbps_error_printf("failed to extract metadata %s file" - "for `%s-%s': %s\n", XBPS_PKGFILES, pkgname, - version, strerror(rv)); + xbps_set_cb_state(XBPS_STATE_UNPACK_FAIL, + errno, pkgname, version, + "%s: [unpack] failed to extract metadata file `%s': %s", + pkgver, XBPS_PKGFILES, strerror(errno)); goto out; } out: + if (xucd != NULL) + free(xucd); if (pkgfilesd != NULL) free(pkgfilesd); if (buf != NULL) @@ -496,12 +536,10 @@ out: return rv; } -#undef RUN_PROGRESS_CB int xbps_unpack_binary_pkg(prop_dictionary_t pkg_repod) { - struct xbps_handle *xhp; struct archive *ar; const char *pkgname, *version, *repoloc, *pkgver, *fname; char *bpkg; @@ -515,10 +553,16 @@ xbps_unpack_binary_pkg(prop_dictionary_t pkg_repod) prop_dictionary_get_cstring_nocopy(pkg_repod, "repository", &repoloc); prop_dictionary_get_cstring_nocopy(pkg_repod, "filename", &fname); + xbps_set_cb_state(XBPS_STATE_UNPACK, + 0, pkgname, version, + "Unpacking package `%s'...", pkgver); + bpkg = xbps_path_from_repository_uri(pkg_repod, repoloc); if (bpkg == NULL) { - xbps_error_printf("cannot determine binary pkg file " - "for `%s-%s': %s\n", pkgname, version, strerror(errno)); + xbps_set_cb_state(XBPS_STATE_UNPACK_FAIL, + errno, pkgname, version, + "%s: [unpack] cannot determine binary package " + "file for `%s': %s", pkgver, fname, strerror(errno)); return errno; } @@ -534,40 +578,43 @@ xbps_unpack_binary_pkg(prop_dictionary_t pkg_repod) if (archive_read_open_filename(ar, bpkg, ARCHIVE_READ_BLOCKSIZE) != 0) { rv = archive_errno(ar); - xbps_error_printf("failed to open `%s' binpkg: %s\n", - fname, strerror(rv)); + xbps_set_cb_state(XBPS_STATE_UNPACK_FAIL, + rv, pkgname, version, + "%s: [unpack] failed to open binary package `%s': %s", + pkgver, fname, strerror(rv)); goto out; } - /* - * Set extract progress callback if specified. - */ - xhp = xbps_handle_get(); - if (xhp->xbps_unpack_cb != NULL) { - xhp->xucd->entry_extract_count = 0; - xhp->xucd->entry_total_count = 0; - } /* * Set package state to half-unpacked. */ if ((rv = xbps_set_pkg_state_installed(pkgname, version, pkgver, XBPS_PKG_STATE_HALF_UNPACKED)) != 0) { - xbps_error_printf("failed to set `%s' to half-unpacked " - "state: %s\n", pkgver, strerror(rv)); + xbps_set_cb_state(XBPS_STATE_UNPACK_FAIL, + rv, pkgname, version, + "%s: [unpack] failed to set state to half-unpacked: %s", + pkgver, strerror(rv)); goto out; } /* * Extract archive files. */ - if ((rv = unpack_archive(pkg_repod, ar, pkgname, version, xhp)) != 0) + rv = unpack_archive(pkg_repod, ar); + if (rv != 0) { + xbps_set_cb_state(XBPS_STATE_UNPACK_FAIL, + rv, pkgname, version, + "%s: [unpack] failed to unpack files on archive: %s", + pkgver, strerror(rv)); goto out; - + } /* * Set package state to unpacked. */ if ((rv = xbps_set_pkg_state_installed(pkgname, version, pkgver, XBPS_PKG_STATE_UNPACKED)) != 0) { - xbps_error_printf("failed to set `%s' to unpacked " - "state: %s\n", pkgver, strerror(rv)); + xbps_set_cb_state(XBPS_STATE_UNPACK_FAIL, + rv, pkgname, version, + "%s: [unpack] failed to set state to unpacked: %s", + pkgver, strerror(rv)); } out: if (bpkg) diff --git a/lib/repository_finddeps.c b/lib/repository_finddeps.c index 1fb88b05..2d430fa2 100644 --- a/lib/repository_finddeps.c +++ b/lib/repository_finddeps.c @@ -225,7 +225,7 @@ find_repo_deps(prop_dictionary_t transd, /* transaction dictionary */ pkgname = xbps_pkgpattern_name(reqpkg); if (pkgname == NULL) { rv = EINVAL; - xbps_error_printf("failed to get " + xbps_dbg_printf("failed to get " "pkgname from `%s'!", reqpkg); break; } @@ -237,7 +237,7 @@ find_repo_deps(prop_dictionary_t transd, /* transaction dictionary */ if (errno && errno != ENOENT) { /* error */ rv = errno; - xbps_error_printf("failed to find " + xbps_dbg_printf("failed to find " "installed pkg for `%s': %s\n", reqpkg, strerror(errno)); break; @@ -253,7 +253,7 @@ find_repo_deps(prop_dictionary_t transd, /* transaction dictionary */ if (errno && errno != ENOENT) { /* error */ rv = errno; - xbps_error_printf("failed to find " + xbps_dbg_printf("failed to find " "installed virtual pkg for `%s': %s\n", reqpkg, strerror(errno)); break; @@ -325,7 +325,7 @@ find_repo_deps(prop_dictionary_t transd, /* transaction dictionary */ } else { /* error matching pkgpattern */ prop_object_release(tmpd); - xbps_error_printf("failed to match " + xbps_dbg_printf("failed to match " "pattern %s with %s\n", reqpkg, pkgver_q); break; } @@ -368,7 +368,7 @@ find_repo_deps(prop_dictionary_t transd, /* transaction dictionary */ if (curpkgd == NULL) { /* pkg not found, there was some error */ if (errno && errno != ENOENT) { - xbps_error_printf("failed to find pkg " + xbps_dbg_printf("failed to find pkg " "for `%s' in rpool: %s\n", reqpkg, strerror(errno)); rv = errno; diff --git a/lib/repository_sync_index.c b/lib/repository_sync_index.c index efae2c33..6f6314d6 100644 --- a/lib/repository_sync_index.c +++ b/lib/repository_sync_index.c @@ -92,7 +92,7 @@ xbps_repository_sync_pkg_index(const char *uri) struct xbps_handle *xhp; struct url *url = NULL; struct stat st; - const char *fetch_outputdir; + const char *fetch_outputdir, *fetchstr = NULL; char *rpidx, *lrepodir, *uri_fixedp; char *metadir, *tmp_metafile, *lrepofile; int rv = 0; @@ -124,8 +124,10 @@ xbps_repository_sync_pkg_index(const char *uri) goto out; } if ((rv = xbps_mkpath(metadir, 0755)) == -1) { - xbps_dbg_printf("[rsyncidx] failed to create metadir `%s': " - "%s\n", metadir, strerror(errno)); + xbps_set_cb_state(XBPS_STATE_REPOSYNC_FAIL, + errno, NULL, NULL, + "[reposync] failed to create metadir `%s': %s", + metadir, strerror(errno)); goto out; } /* @@ -166,25 +168,19 @@ xbps_repository_sync_pkg_index(const char *uri) fetch_outputdir = metadir; /* reposync start cb */ - if (xhp->xbps_state_cb) { - xhp->xscd->state = XBPS_STATE_REPOSYNC; - xhp->xscd->repourl = uri; - xhp->xbps_state_cb(xhp->xscd); - } + xbps_set_cb_state(XBPS_STATE_REPOSYNC, 0, NULL, NULL, + "Synchronizing index for `%s'...", uri); /* * Download index.plist file from repository. */ if (xbps_fetch_file(rpidx, fetch_outputdir, true, NULL) == -1) { /* reposync error cb */ - if (xhp->xbps_state_cb) { - xhp->xscd->state = XBPS_STATE_REPOSYNC_FAIL; - xhp->xscd->repourl = uri; - if (fetchLastErrCode != 0) - xhp->xscd->err = fetchLastErrCode; - else - xhp->xscd->err = errno; - xhp->xbps_state_cb(xhp->xscd); - } + fetchstr = xbps_fetch_error_string(); + xbps_set_cb_state(XBPS_STATE_REPOSYNC_FAIL, + fetchLastErrCode != 0 ? fetchLastErrCode : errno, + NULL, NULL, + "[reposync] failed to fetch file `%s': %s", + rpidx, fetchstr ? fetchstr : strerror(errno)); rv = -1; goto out; } @@ -197,8 +193,8 @@ xbps_repository_sync_pkg_index(const char *uri) */ tmpd = prop_dictionary_internalize_from_zfile(tmp_metafile); if (tmpd == NULL) { - xbps_dbg_printf("[rsyncidx] downloaded index.plist " - "file cannot be read! removing...\n"); + xbps_set_cb_state(XBPS_STATE_REPOSYNC_FAIL, 0, NULL, NULL, + "[reposync] downloaded file `%s' is not valid.", rpidx); (void)unlink(tmp_metafile); rv = -1; goto out; @@ -214,19 +210,22 @@ xbps_repository_sync_pkg_index(const char *uri) * Create local repodir to store index.plist file. */ if ((rv = xbps_mkpath(lrepodir, 0755)) == -1) { - xbps_dbg_printf("[rsyncidx] failed to create repodir " - "`%s': %s\n", lrepodir, strerror(errno)); + xbps_set_cb_state(XBPS_STATE_REPOSYNC_FAIL, errno, NULL, NULL, + "[reposync] failed to create repodir for `%s': %s", + lrepodir, strerror(rv)); goto out; } /* * Rename to destination file now it has been fetched successfully. */ - if ((rv = rename(tmp_metafile, lrepofile)) == -1) - xbps_dbg_printf("[rsyncidx] failed to rename `%s' to " - "`%s': %s\n", tmp_metafile, lrepofile, strerror(errno)); - else + if ((rv = rename(tmp_metafile, lrepofile)) == -1) { + xbps_set_cb_state(XBPS_STATE_REPOSYNC_FAIL, errno, NULL, NULL, + "[reposync] failed to rename index file `%s' to `%s': %s", + tmp_metafile, lrepofile, strerror(errno)); + } else { rv = 1; /* success */ + } out: if (rpidx) diff --git a/lib/transaction_commit.c b/lib/transaction_commit.c index 159f6c05..19b5d222 100644 --- a/lib/transaction_commit.c +++ b/lib/transaction_commit.c @@ -35,33 +35,12 @@ #include "xbps_api_impl.h" -#define RUN_STATE_CB(s, d, p, bf, burl) \ -do { \ - if (xhp->xbps_state_cb != NULL) { \ - xhp->xscd->state = s; \ - xhp->xscd->desc = d; \ - xhp->xscd->pkgver = p; \ - xhp->xscd->binpkg_fname = bf; \ - xhp->xscd->repourl = burl; \ - (*xhp->xbps_state_cb)(xhp->xscd); \ - } \ -} while (0) - -#define RUN_STATE_ERR_CB(s, p, r) \ -do { \ - if (xhp->xbps_state_cb != NULL) { \ - xhp->xscd->state = s; \ - xhp->xscd->pkgver = p; \ - xhp->xscd->err = r; \ - (*xhp->xbps_state_cb)(xhp->xscd); \ - } \ -} while (0) - static int -check_binpkgs_hash(struct xbps_handle *xhp, prop_object_iterator_t iter) +check_binpkgs_hash(prop_object_iterator_t iter) { prop_object_t obj; const char *pkgver, *repoloc, *filen, *sha256, *trans; + const char *pkgname, *version; char *binfile; int rv = 0; @@ -71,6 +50,8 @@ check_binpkgs_hash(struct xbps_handle *xhp, prop_object_iterator_t iter) (strcmp(trans, "configure") == 0)) continue; + prop_dictionary_get_cstring_nocopy(obj, "pkgname", &pkgname); + prop_dictionary_get_cstring_nocopy(obj, "version", &version); prop_dictionary_get_cstring_nocopy(obj, "repository", &repoloc); assert(repoloc != NULL); prop_dictionary_get_cstring_nocopy(obj, "pkgver", &pkgver); @@ -86,11 +67,15 @@ check_binpkgs_hash(struct xbps_handle *xhp, prop_object_iterator_t iter) rv = EINVAL; break; } - RUN_STATE_CB(XBPS_STATE_VERIFY, NULL, pkgver, filen, repoloc); + xbps_set_cb_state(XBPS_STATE_VERIFY, 0, pkgname, version, + "Verifying `%s' package integrity...", filen, repoloc); rv = xbps_file_hash_check(binfile, sha256); if (rv != 0) { free(binfile); - RUN_STATE_ERR_CB(XBPS_STATE_VERIFY_FAIL, pkgver, rv); + xbps_set_cb_state(XBPS_STATE_VERIFY_FAIL, + rv, pkgname, version, + "Failed to verify `%s' package integrity: %s", + filen, strerror(rv)); break; } free(binfile); @@ -105,6 +90,7 @@ download_binpkgs(struct xbps_handle *xhp, prop_object_iterator_t iter) { prop_object_t obj; const char *pkgver, *repoloc, *filen, *trans; + const char *pkgname, *version; char *binfile; int rv = 0; @@ -114,6 +100,8 @@ download_binpkgs(struct xbps_handle *xhp, prop_object_iterator_t iter) (strcmp(trans, "configure") == 0)) continue; + prop_dictionary_get_cstring_nocopy(obj, "pkgname", &pkgname); + prop_dictionary_get_cstring_nocopy(obj, "version", &version); prop_dictionary_get_cstring_nocopy(obj, "repository", &repoloc); assert(repoloc != NULL); prop_dictionary_get_cstring_nocopy(obj, "pkgver", &pkgver); @@ -138,23 +126,30 @@ download_binpkgs(struct xbps_handle *xhp, prop_object_iterator_t iter) */ if (xbps_mkpath(prop_string_cstring_nocopy(xhp->cachedir), 0755) == -1) { - xbps_error_printf("xbps-bin: cannot mkdir cachedir " - "`%s': %s.\n", - prop_string_cstring_nocopy(xhp->cachedir), + xbps_set_cb_state(XBPS_STATE_DOWNLOAD_FAIL, + errno, pkgname, version, + "%s: [trans] cannot create cachedir `%s': %s", + pkgver, prop_string_cstring_nocopy(xhp->cachedir), strerror(errno)); free(binfile); rv = errno; break; } - RUN_STATE_CB(XBPS_STATE_DOWNLOAD, NULL, pkgver, filen, repoloc); + xbps_set_cb_state(XBPS_STATE_DOWNLOAD, + 0, pkgname, version, + "Downloading binary package `%s' (from `%s')...", + filen, repoloc); /* * Fetch binary package. */ rv = xbps_fetch_file(binfile, prop_string_cstring_nocopy(xhp->cachedir), false, NULL); if (rv == -1) { - RUN_STATE_ERR_CB(XBPS_STATE_DOWNLOAD_FAIL, - pkgver, errno); + xbps_set_cb_state(XBPS_STATE_DOWNLOAD_FAIL, + errno, pkgname, version, + "%s: [trans] failed to download binary package " + "`%s' from `%s': %s", pkgver, filen, repoloc, + strerror(errno)); free(binfile); break; } @@ -185,23 +180,23 @@ xbps_transaction_commit(prop_dictionary_t transd) /* * Download binary packages (if they come from a remote repository). */ - RUN_STATE_CB(XBPS_STATE_DOWNLOAD, - "[*] Downloading binary packages", NULL, NULL, NULL); + xbps_set_cb_state(XBPS_STATE_TRANS_DOWNLOAD, 0, NULL, NULL, + "[*] Downloading binary packages"); if ((rv = download_binpkgs(xhp, iter)) != 0) goto out; /* * Check SHA256 hashes for binary packages in transaction. */ - RUN_STATE_CB(XBPS_STATE_VERIFY, - "[*] Verifying binary package integrity", NULL, NULL, NULL); - if ((rv = check_binpkgs_hash(xhp, iter)) != 0) + xbps_set_cb_state(XBPS_STATE_TRANS_VERIFY, 0, NULL, NULL, + "[*] Verifying binary package integrity"); + if ((rv = check_binpkgs_hash(iter)) != 0) goto out; /* * Install, update, configure or remove packages as specified * in the transaction dictionary. */ - RUN_STATE_CB(XBPS_STATE_INSTALL, - "[*] Running transaction tasks", NULL, NULL, NULL); + xbps_set_cb_state(XBPS_STATE_TRANS_RUN, 0, NULL, NULL, + "[*] Running transaction tasks"); while ((obj = prop_object_iterator_next(iter)) != NULL) { update = false; @@ -217,34 +212,21 @@ xbps_transaction_commit(prop_dictionary_t transd) */ prop_dictionary_get_bool(obj, "remove-and-update", &update); - RUN_STATE_CB(XBPS_STATE_REMOVE, - NULL, pkgver, NULL, NULL); rv = xbps_remove_pkg(pkgname, version, update); - if (rv != 0) { - RUN_STATE_ERR_CB(XBPS_STATE_REMOVE_FAIL, - pkgver, rv); + if (rv != 0) goto out; - } if (update) continue; - RUN_STATE_CB(XBPS_STATE_PURGE, - NULL, pkgver, NULL, NULL); - if ((rv = xbps_purge_pkg(pkgname, false)) != 0) { - RUN_STATE_ERR_CB(XBPS_STATE_PURGE_FAIL, - pkgver, rv); + if ((rv = xbps_purge_pkg(pkgname, false)) != 0) goto out; - } } else if (strcmp(tract, "configure") == 0) { /* * Reconfigure pending package. */ rv = xbps_configure_pkg(pkgname, version, false, false); - if (rv != 0) { - RUN_STATE_ERR_CB(XBPS_STATE_CONFIGURE_FAIL, - pkgver, rv); + if (rv != 0) goto out; - } } else { /* * Install or update a package. @@ -257,43 +239,41 @@ xbps_transaction_commit(prop_dictionary_t transd) * Update a package: execute pre-remove * action if found before unpacking. */ - RUN_STATE_CB(XBPS_STATE_UPDATE, - NULL, pkgver, filen, NULL); + xbps_set_cb_state(XBPS_STATE_UPDATE, + 0, pkgname, version, NULL); rv = xbps_remove_pkg(pkgname, version, true); if (rv != 0) { - RUN_STATE_ERR_CB(XBPS_STATE_UPDATE_FAIL, - pkgver, rv); + xbps_set_cb_state( + XBPS_STATE_UPDATE_FAIL, + rv, pkgname, version, + "%s: [trans] failed to update " + "package to `%s': %s", pkgver, + version, strerror(rv)); goto out; } + } else { + /* Install a package */ + xbps_set_cb_state(XBPS_STATE_INSTALL, + 0, pkgname, version, NULL); } /* * Unpack binary package. */ - RUN_STATE_CB(XBPS_STATE_UNPACK, NULL, - pkgver, filen, NULL); - if ((rv = xbps_unpack_binary_pkg(obj)) != 0) { - RUN_STATE_ERR_CB(XBPS_STATE_UNPACK_FAIL, - pkgver, rv); + if ((rv = xbps_unpack_binary_pkg(obj)) != 0) goto out; - } /* * Register package. */ - RUN_STATE_CB(XBPS_STATE_REGISTER, - NULL, pkgver, filen, NULL); - if ((rv = xbps_register_pkg(obj)) != 0) { - RUN_STATE_ERR_CB(XBPS_STATE_REGISTER_FAIL, - pkgver, rv); + if ((rv = xbps_register_pkg(obj)) != 0) goto out; - } } } prop_object_iterator_reset(iter); /* * Configure all unpacked packages. */ - RUN_STATE_CB(XBPS_STATE_CONFIGURE, - "[*] Configuring unpacked packages", NULL, NULL, NULL); + xbps_set_cb_state(XBPS_STATE_TRANS_CONFIGURE, 0, NULL, NULL, + "[*] Configuring unpacked packages"); while ((obj = prop_object_iterator_next(iter)) != NULL) { prop_dictionary_get_cstring_nocopy(obj, "transaction", &tract); @@ -306,11 +286,9 @@ xbps_transaction_commit(prop_dictionary_t transd) if (strcmp(tract, "update") == 0) update = true; - if ((rv = xbps_configure_pkg(pkgname, version, - false, update)) != 0) { - RUN_STATE_ERR_CB(XBPS_STATE_CONFIGURE_FAIL, pkgver, rv); + rv = xbps_configure_pkg(pkgname, version, false, update); + if (rv != 0) goto out; - } } out: diff --git a/lib/transaction_sortdeps.c b/lib/transaction_sortdeps.c index f9482d54..ab386651 100644 --- a/lib/transaction_sortdeps.c +++ b/lib/transaction_sortdeps.c @@ -341,7 +341,7 @@ xbps_sort_pkg_deps(void) */ ndeps = prop_array_count(unsorted); if (!prop_array_ensure_capacity(sorted, ndeps)) { - xbps_error_printf("failed to set capacity to the sorted " + xbps_dbg_printf("failed to set capacity to the sorted " "pkgdeps array\n"); return ENOMEM; } diff --git a/lib/util.c b/lib/util.c index 70b78e36..b89930e0 100644 --- a/lib/util.c +++ b/lib/util.c @@ -35,7 +35,9 @@ #include #include +#ifdef HAVE_CONFIG_H #include "config.h" +#endif #include "xbps_api_impl.h" /** @@ -281,7 +283,6 @@ xbps_pkg_has_rundeps(prop_dictionary_t pkgd) return false; } -#ifdef HAVE_VASPRINTF char * xbps_xasprintf(const char *fmt, ...) { @@ -297,4 +298,3 @@ xbps_xasprintf(const char *fmt, ...) return buf; } -#endif /* HAVE_VASPRINTF */