static void show_package_list(xbps_object_iterator_t iter, const char *match, int cols) { xbps_object_t obj; const char *pkgver, *tract; while ((obj = xbps_object_iterator_next(iter)) != NULL) { xbps_dictionary_get_cstring_nocopy(obj, "pkgver", &pkgver); xbps_dictionary_get_cstring_nocopy(obj, "transaction", &tract); if (strcmp(match, tract)) continue; print_package_line(pkgver, cols, false); } xbps_object_iterator_reset(iter); print_package_line(NULL, cols, true); }
static void show_package_list(struct transaction *trans, const char *match, int cols) { xbps_object_t obj; while ((obj = xbps_object_iterator_next(trans->iter)) != NULL) { const char *pkgver, *tract; char *buf = NULL; bool dload = false; xbps_dictionary_get_cstring_nocopy(obj, "pkgver", &pkgver); xbps_dictionary_get_cstring_nocopy(obj, "transaction", &tract); xbps_dictionary_get_bool(obj, "download", &dload); if (match && strcmp(tract, "update") == 0) { xbps_dictionary_t ipkgd; const char *ipkgver, *iversion, *version; char *pkgname; /* get installed pkgver */ pkgname = xbps_pkg_name(pkgver); assert(pkgname); ipkgd = xbps_pkgdb_get_pkg(trans->xhp, pkgname); assert(ipkgd); xbps_dictionary_get_cstring_nocopy(ipkgd, "pkgver", &ipkgver); version = xbps_pkg_version(pkgver); iversion = xbps_pkg_version(ipkgver); buf = xbps_xasprintf("%s (%s -> %s)", pkgname, iversion, version); free(pkgname); } if ((match && (strcmp(match, tract) == 0)) || (!match && dload)) { if (buf) { print_package_line(buf, cols, false); free(buf); } else { print_package_line(pkgver, cols, false); } } } xbps_object_iterator_reset(trans->iter); print_package_line(NULL, cols, true); }
static int remove_pkg_files(struct xbps_handle *xhp, xbps_dictionary_t dict, const char *key, const char *pkgver) { xbps_array_t array; xbps_object_iterator_t iter; xbps_object_t obj; const char *curobj = NULL; /* These are symlinks in Void and must not be removed */ const char *basesymlinks[] = { "/bin", "/sbin", "/usr/sbin", "/lib", "/lib32", "/lib64", "/usr/lib32", "/usr/lib64", "/var/run", }; int rv = 0; assert(xbps_object_type(dict) == XBPS_TYPE_DICTIONARY); assert(key != NULL); array = xbps_dictionary_get(dict, key); if (xbps_array_count(array) == 0) return 0; iter = xbps_array_iter_from_dict(dict, key); if (iter == NULL) return ENOMEM; if (strcmp(key, "files") == 0) curobj = "file"; else if (strcmp(key, "conf_files") == 0) curobj = "configuration file"; else if (strcmp(key, "links") == 0) curobj = "link"; else if (strcmp(key, "dirs") == 0) curobj = "directory"; xbps_object_iterator_reset(iter); while ((obj = xbps_object_iterator_next(iter))) { const char *file, *sha256; char path[PATH_MAX]; bool found; xbps_dictionary_get_cstring_nocopy(obj, "file", &file); snprintf(path, sizeof(path), "%s/%s", xhp->rootdir, file); if ((strcmp(key, "files") == 0) || (strcmp(key, "conf_files") == 0)) { /* * Check SHA256 hash in regular files and * configuration files. */ xbps_dictionary_get_cstring_nocopy(obj, "sha256", &sha256); rv = xbps_file_hash_check(path, sha256); if (rv == ENOENT) { /* missing file, ignore it */ xbps_set_cb_state(xhp, XBPS_STATE_REMOVE_FILE_HASH_FAIL, rv, pkgver, "%s: failed to check hash for %s `%s': %s", pkgver, curobj, file, strerror(rv)); rv = 0; continue; } else if (rv == ERANGE) { rv = 0; if ((xhp->flags & XBPS_FLAG_FORCE_REMOVE_FILES) == 0) { xbps_set_cb_state(xhp, XBPS_STATE_REMOVE_FILE_HASH_FAIL, 0, pkgver, "%s: %s `%s' SHA256 mismatch, " "preserving file", pkgver, curobj, file); continue; } else { xbps_set_cb_state(xhp, XBPS_STATE_REMOVE_FILE_HASH_FAIL, 0, pkgver, "%s: %s `%s' SHA256 mismatch, " "forcing removal", pkgver, curobj, file); } } else if (rv != 0 && rv != ERANGE) { xbps_set_cb_state(xhp, XBPS_STATE_REMOVE_FILE_HASH_FAIL, rv, pkgver, "%s: [remove] failed to check hash for " "%s `%s': %s", pkgver, curobj, file, strerror(rv)); break; } } /* * Make sure to not remove any symlink of root directory. */ found = false; for (uint8_t i = 0; i < __arraycount(basesymlinks); i++) { if (strcmp(file, basesymlinks[i]) == 0) { found = true; xbps_dbg_printf(xhp, "[remove] %s ignoring " "%s removal\n", pkgver, file); break; } } if (found) { continue; } if (strcmp(key, "links") == 0) { const char *target = NULL; char *lnk; xbps_dictionary_get_cstring_nocopy(obj, "target", &target); assert(target); lnk = xbps_symlink_target(xhp, path, target); if (lnk == NULL) { xbps_dbg_printf(xhp, "[remove] %s " "symlink_target: %s\n", path, strerror(errno)); continue; } if (strcmp(lnk, target)) { xbps_dbg_printf(xhp, "[remove] %s symlink " "modified (stored %s current %s)\n", path, target, lnk); if ((xhp->flags & XBPS_FLAG_FORCE_REMOVE_FILES) == 0) { free(lnk); continue; } } free(lnk); } /* * Remove the object if possible. */ if (remove(path) == -1) { xbps_set_cb_state(xhp, XBPS_STATE_REMOVE_FILE_FAIL, errno, pkgver, "%s: failed to remove %s `%s': %s", pkgver, curobj, file, strerror(errno)); } else { /* success */ xbps_set_cb_state(xhp, XBPS_STATE_REMOVE_FILE, 0, pkgver, "Removed %s `%s'", curobj, file); } } xbps_object_iterator_release(iter); return rv; }