Always overwrite files while unpacking, this makes the "essential" obj obsolete.

This helps to catch upgrade problems and simplifies some parts of the code.
Bumped XBPS_RELVER because xbps_remove_pkg() has been changed.

--HG--
extra : convert_revision : xtraeme%40gmail.com-20100128150850-gcs93su38t6moydn
This commit is contained in:
Juan RP 2010-01-28 16:08:50 +01:00
parent 375330a956
commit 61dde1ac02
8 changed files with 75 additions and 108 deletions

77
NEWS
View File

@ -1,48 +1,53 @@
xbps-0.4 (2010-02-01): xbps-0.4 (2010-02-01):
* xbps-bin(8): enable -f option for the 'purge' and 'remove' targets. * libxbps, xbps-bin(8), xbps-repo(8): redirect all warning and error
If set, files will be removed even if its hash doesn't match for the messages to stderr.
'remove' target, and configuration files for the 'purge' target.
* xbps-uhelper: the 'fetch' target now accepts an arbitrary number of * libxbps: changes xbps_yesno() and xbps_noyes() to only accept "yes" or "no"
arguments, and sets default libfetch cache connection limits. (case insensitive) answers rather than 'y' or 'n', to avoid mistaken answers.
* xbps-bin(8): when downloading binary packages, it now sets default * xbps-repo(8): added support to the 'search' target to find exact matches,
libfetch cache connection limits, thus reusing connections to the same host. i.e 'xbps-repo search bash'.
* libxbps: synced libfetch code with NetBSD's pkgsrc, updated to 2.30.
* Added doxygen documentation for the API, enabled with BUILD_API_DOCS.
* libxbps: be more strict finding required metadata plist files in binary
packages. Now the code checks for the two required plist files to be at
index <= 4 and doesn't write any entry to storage until they aren't found.
* libxbps: many exported functions to the API are now internal and not
exported, because they were only used internally. The API is still not
finished and may be changed without notice.
* Makefiles reworked to support parallel builds.
* libxbps: fixed some memleaks found by cppcheck and valgrind.
* libxbps: fixed some bugs while upgrading essential packages when new package
didn't have an INSTALL or REMOVE script and old package had them.
* xbps-bin(8): added support to the 'install' and 'update' targets to
accept package patterns, i.e "xbps-bin install 'foo<=3.0'.
See https://blueprints.launchpad.net/xbps/+spec/install-pkg-by-pkgmatch
* xbps-bin(8) added support to the 'install', 'remove' and 'update' * xbps-bin(8) added support to the 'install', 'remove' and 'update'
targets to accept any arbitrary number of package names, i.e targets to accept any arbitrary number of package names, i.e
"xbps-bin install foo blah baz". "xbps-bin install foo blah baz".
See https://blueprints.launchpad.net/xbps/+spec/arbitrary-pkgname-args See https://blueprints.launchpad.net/xbps/+spec/arbitrary-pkgname-args
* xbps-repo(8): added support to the 'search' target to find exact matches, * xbps-bin(8): added support to the 'install' and 'update' targets to
i.e 'xbps-repo search bash'. accept package patterns, i.e "xbps-bin install 'foo<=3.0'.
See https://blueprints.launchpad.net/xbps/+spec/install-pkg-by-pkgmatch
* libxbps: changes xbps_yesno() and xbps_noyes() to only accept "yes" or "no" * libxbps: fixed some bugs while upgrading essential packages when new package
(case insensitive) answers rather than 'y' or 'n', to avoid mistaken answers. didn't have an INSTALL or REMOVE script and old package had them.
* libxbps, xbps-bin(8), xbps-repo(8): redirect all warning and error * libxbps: fixed some memleaks found by cppcheck and valgrind.
messages to stderr.
* Makefiles reworked to support parallel builds.
* libxbps: many exported functions to the API are now internal and not
exported, because they were only used internally. The API is still not
finished and may be changed without notice.
* libxbps: be more strict finding required metadata plist files in binary
packages. Now the code checks for the two required plist files to be at
index <= 4 and doesn't write any entry to storage until they aren't found.
* Added doxygen documentation for the API, enabled with BUILD_API_DOCS.
* libxbps: synced libfetch code with NetBSD's pkgsrc, updated to 2.30.
* xbps-bin(8): when downloading binary packages, it now sets default
libfetch cache connection limits, thus reusing connections to the same host.
* xbps-uhelper: the 'fetch' target now accepts an arbitrary number of
arguments, and sets default libfetch cache connection limits.
* xbps-bin(8): enable -f option for the 'purge' and 'remove' targets.
If set, files will be removed even if its hash doesn't match for the
'remove' target, and configuration files for the 'purge' target.
* libxbps: always overwrite files while unpacking, and compare old and
new files to remove obsoletes if necessary. This makes the "essential"
object in package dictionary unnecessary, because all packages are
treated as they were essential.

View File

@ -474,7 +474,7 @@ replace_packages(prop_object_iterator_t iter, const char *pkgver)
prop_object_release(instd); prop_object_release(instd);
version = xbps_get_pkg_version(pkgver); version = xbps_get_pkg_version(pkgver);
rv = xbps_remove_pkg(reppkgn, version, false, false); rv = xbps_remove_pkg(reppkgn, version, false);
if (rv != 0) { if (rv != 0) {
fprintf(stderr, "xbps-bin: couldn't remove %s (%s)\n", fprintf(stderr, "xbps-bin: couldn't remove %s (%s)\n",
reppkgn, strerror(rv)); reppkgn, strerror(rv));
@ -499,14 +499,14 @@ exec_transaction(struct transaction *trans)
prop_object_iterator_t replaces_iter; prop_object_iterator_t replaces_iter;
const char *pkgname, *version, *pkgver, *instver, *filename, *tract; const char *pkgname, *version, *pkgver, *instver, *filename, *tract;
int rv = 0; int rv = 0;
bool update, essential, preserve, autoinst; bool update, preserve, autoinst;
pkg_state_t state = 0; pkg_state_t state = 0;
assert(trans != NULL); assert(trans != NULL);
assert(trans->dict != NULL); assert(trans->dict != NULL);
assert(trans->iter != NULL); assert(trans->iter != NULL);
update = essential = autoinst = preserve = false; update = autoinst = preserve = false;
/* /*
* Show download/installed size for the transaction. * Show download/installed size for the transaction.
*/ */
@ -546,7 +546,6 @@ exec_transaction(struct transaction *trans)
"pkgver", &pkgver)) "pkgver", &pkgver))
return errno; return errno;
prop_dictionary_get_bool(obj, "automatic-install", &autoinst); prop_dictionary_get_bool(obj, "automatic-install", &autoinst);
prop_dictionary_get_bool(obj, "essential", &essential);
prop_dictionary_get_bool(obj, "preserve", &preserve); prop_dictionary_get_bool(obj, "preserve", &preserve);
if (!prop_dictionary_get_cstring_nocopy(obj, if (!prop_dictionary_get_cstring_nocopy(obj,
"filename", &filename)) "filename", &filename))
@ -595,28 +594,17 @@ exec_transaction(struct transaction *trans)
} }
prop_object_release(instpkgd); prop_object_release(instpkgd);
/* if (preserve)
* If package is marked as 'essential' remove old
* requiredby entries and overwrite pkg files; otherwise
* remove old package and install new one. This
* is all handled internally in xbps_remove_pkg()
* and xbps_unpack_binary_pkg().
*/
if (essential && !preserve)
printf("Replacing %s-%s with %s-%s ...\n",
pkgname, instver, pkgname, version);
else if (essential && preserve)
printf("Conserving %s-%s files, installing new " printf("Conserving %s-%s files, installing new "
"version ...\n", pkgname, instver); "version ...\n", pkgname, instver);
else else
printf("Removing %s-%s before installing new " printf("Replacing %s files (%s -> %s) ...\n",
"version ...\n", pkgname, instver); pkgname, instver, version);
rv = xbps_remove_pkg(pkgname, version, true, essential); rv = xbps_remove_pkg(pkgname, version, true);
if (rv != 0) { if (rv != 0) {
fprintf(stderr, "xbps-bin: error " fprintf(stderr, "xbps-bin: error "
"%s %s-%s (%s)\n", essential ? "replacing %s-%s (%s)\n", pkgname,
"replacing" : "removing", pkgname,
instver, strerror(rv)); instver, strerror(rv));
return rv; return rv;
} }

View File

@ -104,7 +104,7 @@ xbps_autoremove_pkgs(bool force)
goto out; goto out;
} }
printf("Removing package %s-%s ...\n", pkgname, version); printf("Removing package %s-%s ...\n", pkgname, version);
if ((rv = xbps_remove_pkg(pkgname, version, false, false)) != 0) if ((rv = xbps_remove_pkg(pkgname, version, false)) != 0)
goto out; goto out;
} }
@ -186,8 +186,7 @@ xbps_remove_installed_pkgs(int argc, char **argv, bool force)
continue; continue;
prop_dictionary_get_cstring_nocopy(dict, "version", &version); prop_dictionary_get_cstring_nocopy(dict, "version", &version);
printf("Removing package %s-%s ...\n", argv[i], version); printf("Removing package %s-%s ...\n", argv[i], version);
rv = xbps_remove_pkg(argv[i], version, false, false); if ((rv = xbps_remove_pkg(argv[i], version, false)) != 0) {
if (rv != 0) {
fprintf(stderr, "E: unable to remove %s-%s (%s).\n", fprintf(stderr, "E: unable to remove %s-%s (%s).\n",
argv[i], version, strerror(errno)); argv[i], version, strerror(errno));
return rv; return rv;

View File

@ -107,9 +107,10 @@ show_pkg_info(prop_dictionary_t dict)
if (obj && prop_object_type(obj) == PROP_TYPE_STRING) if (obj && prop_object_type(obj) == PROP_TYPE_STRING)
printf("Version: %s\n", prop_string_cstring_nocopy(obj)); printf("Version: %s\n", prop_string_cstring_nocopy(obj));
obj = prop_dictionary_get(dict, "essential"); obj = prop_dictionary_get(dict, "preserve");
if (obj && prop_object_type(obj) == PROP_TYPE_BOOL) if (obj && prop_object_type(obj) == PROP_TYPE_BOOL)
printf("Essential: %s\n", prop_bool_true(obj) ? "yes" : "no"); printf("Preserve files: %s\n",
prop_bool_true(obj) ? "yes" : "no");
obj = prop_dictionary_get(dict, "replaces"); obj = prop_dictionary_get(dict, "replaces");
if (obj && prop_object_type(obj) == PROP_TYPE_ARRAY) { if (obj && prop_object_type(obj) == PROP_TYPE_ARRAY) {

View File

@ -8,7 +8,6 @@ digraph pkg_props_dictionary {
main -> pkgname [label="string"]; main -> pkgname [label="string"];
main -> version [label="string"]; main -> version [label="string"];
main -> pkgver [label="string"]; main -> pkgver [label="string"];
main -> essential [label="bool"];
main -> preserve [label="bool"]; main -> preserve [label="bool"];
main -> run_depends [label="array"]; main -> run_depends [label="array"];
run_depends [style=filled]; run_depends [style=filled];

View File

@ -58,7 +58,7 @@ __BEGIN_DECLS
* @def XBPS_RELVER * @def XBPS_RELVER
* Current library release date. * Current library release date.
*/ */
#define XBPS_RELVER "20100121" #define XBPS_RELVER "20100128"
/** /**
* @def XBPS_META_PATH * @def XBPS_META_PATH
@ -128,9 +128,7 @@ __BEGIN_DECLS
#define ARCHIVE_READ_BLOCKSIZE 10240 #define ARCHIVE_READ_BLOCKSIZE 10240
#define EXTRACT_FLAGS ARCHIVE_EXTRACT_SECURE_NODOTDOT | \ #define EXTRACT_FLAGS ARCHIVE_EXTRACT_SECURE_NODOTDOT | \
ARCHIVE_EXTRACT_SECURE_SYMLINKS | \ ARCHIVE_EXTRACT_SECURE_SYMLINKS
ARCHIVE_EXTRACT_NO_OVERWRITE | \
ARCHIVE_EXTRACT_NO_OVERWRITE_NEWER
#define FEXTRACT_FLAGS ARCHIVE_EXTRACT_OWNER | ARCHIVE_EXTRACT_PERM | \ #define FEXTRACT_FLAGS ARCHIVE_EXTRACT_OWNER | ARCHIVE_EXTRACT_PERM | \
ARCHIVE_EXTRACT_TIME | EXTRACT_FLAGS ARCHIVE_EXTRACT_TIME | EXTRACT_FLAGS
@ -637,15 +635,12 @@ void xbps_regpkgs_dictionary_release(void);
* *
* @param[in] pkgname Package name to match. * @param[in] pkgname Package name to match.
* @param[in] version Package version associated. * @param[in] version Package version associated.
* @param[in] update If true, and depending if \a pkgname is an * @param[in] update If true, some steps will be skipped. See in the
* <em>essential</em> package, some steps will be skipped. See in the * detailed description above for more information.
* detailed description section for more information.
* @param[in] essential Set it to true if \a pkgname is essential.
* *
* @return 0 on success, or an errno value otherwise. * @return 0 on success, or an errno value otherwise.
*/ */
int xbps_remove_pkg(const char *pkgname, const char *version, int xbps_remove_pkg(const char *pkgname, const char *version, bool update);
bool update, bool essential);
/** /**
* Remove files defined in a proplib array as specified by \a key * Remove files defined in a proplib array as specified by \a key

View File

@ -51,10 +51,8 @@
* -# Its state will be changed to XBPS_PKG_STATE_CONFIG_FILES. * -# Its state will be changed to XBPS_PKG_STATE_CONFIG_FILES.
* *
* @note * @note
* -# If a package is going to be updated and it's an essential package, * -# If a package is going to be updated, only steps <b>1</b> and <b>4</b>
* only steps <b>1</b> and <b>4</b> will be executed. * will be executed.
* -# If a package is going to be updated and it's <b>NOT</b> an essential
* package, only steps <b>1</b>, <b>2</b> and <b>4</b> will be executed.
* -# If a package is going to be removed, all steps will be executed. * -# If a package is going to be removed, all steps will be executed.
* *
* The following image shows the structure of an internalized package's * The following image shows the structure of an internalized package's
@ -186,8 +184,7 @@ xbps_remove_pkg_files(prop_dictionary_t dict, const char *key)
} }
int int
xbps_remove_pkg(const char *pkgname, const char *version, xbps_remove_pkg(const char *pkgname, const char *version, bool update)
bool update, bool essential)
{ {
prop_dictionary_t dict; prop_dictionary_t dict;
const char *rootdir = xbps_get_rootdir(); const char *rootdir = xbps_get_rootdir();
@ -235,12 +232,11 @@ xbps_remove_pkg(const char *pkgname, const char *version,
} }
/* /*
* If updating an essential package, we just need to execute * If updating a package, we just need to execute the current
* the current pre-remove action target, unregister its requiredby * pre-remove action target, unregister its requiredby entries and
* entries and continue. Its files will be overwritten later in * continue. Its files will be overwritten later in unpack phase.
* the unpack phase.
*/ */
if (essential && update) { if (update) {
free(buf); free(buf);
return xbps_requiredby_pkg_remove(pkgname); return xbps_requiredby_pkg_remove(pkgname);
} }

View File

@ -44,8 +44,8 @@
* - All other kind of files on archive are extracted. * - All other kind of files on archive are extracted.
* - Handles configuration files by taking care of updating them with * - Handles configuration files by taking care of updating them with
* new versions if necessary and to not overwrite modified ones. * new versions if necessary and to not overwrite modified ones.
* - If it's an <b>essential</b> package, files from installed package are * - Files from installed package are compared with new package and
* compared with new package and obsolete files are removed. * obsolete files are removed.
* - Finally its state is set to XBPS_PKG_STATE_UNPACKED. * - Finally its state is set to XBPS_PKG_STATE_UNPACKED.
* *
* The following image shown below represents a transaction dictionary * The following image shown below represents a transaction dictionary
@ -87,13 +87,13 @@ unpack_archive_fini(struct archive *ar, prop_dictionary_t pkg)
const char *pkgname, *version, *rootdir, *entry_str, *transact; const char *pkgname, *version, *rootdir, *entry_str, *transact;
char *buf; char *buf;
int rv = 0, flags, lflags; int rv = 0, flags, lflags;
bool essential, preserve, actgt, skip_entry, update; bool preserve, actgt, skip_entry, update;
bool props_plist_found, files_plist_found; bool props_plist_found, files_plist_found;
assert(ar != NULL); assert(ar != NULL);
assert(pkg != NULL); assert(pkg != NULL);
essential = preserve = actgt = skip_entry = update = false; preserve = actgt = skip_entry = update = false;
props_plist_found = files_plist_found = false; props_plist_found = files_plist_found = false;
rootdir = xbps_get_rootdir(); rootdir = xbps_get_rootdir();
flags = xbps_get_flags(); flags = xbps_get_flags();
@ -108,10 +108,7 @@ unpack_archive_fini(struct archive *ar, prop_dictionary_t pkg)
return errno; return errno;
if (!prop_dictionary_get_cstring_nocopy(pkg, "version", &version)) if (!prop_dictionary_get_cstring_nocopy(pkg, "version", &version))
return errno; return errno;
/*
* The following two objects are OPTIONAL.
*/
prop_dictionary_get_bool(pkg, "essential", &essential);
prop_dictionary_get_bool(pkg, "preserve", &preserve); prop_dictionary_get_bool(pkg, "preserve", &preserve);
if (!prop_dictionary_get_cstring_nocopy(pkg, "trans-action", if (!prop_dictionary_get_cstring_nocopy(pkg, "trans-action",
@ -156,19 +153,6 @@ unpack_archive_fini(struct archive *ar, prop_dictionary_t pkg)
while (archive_read_next_header(ar, &entry) == ARCHIVE_OK) { while (archive_read_next_header(ar, &entry) == ARCHIVE_OK) {
entry_str = archive_entry_pathname(entry); entry_str = archive_entry_pathname(entry);
set_extract_flags(&lflags); set_extract_flags(&lflags);
/*
* Now check what currenty entry in the archive contains.
*/
if (((strcmp("./files.plist", entry_str)) == 0) ||
((strcmp("./props.plist", entry_str)) == 0) || essential) {
/*
* Always overwrite files in essential packages,
* and plist metadata files.
*/
lflags &= ~ARCHIVE_EXTRACT_NO_OVERWRITE;
lflags &= ~ARCHIVE_EXTRACT_NO_OVERWRITE_NEWER;
}
/* /*
* Run the pre INSTALL action if the file is there. * Run the pre INSTALL action if the file is there.
*/ */
@ -319,11 +303,11 @@ unpack_archive_fini(struct archive *ar, prop_dictionary_t pkg)
return errno; return errno;
} }
/* /*
* Check if files.plist exists and pkg is marked as * Check if files.plist exists and pkg is NOT marked as
* essential and NOT preserve, in that case we need to check * preserve, in that case we need to check for obsolete files
* for obsolete files and remove them if necessary. * and remove them if necessary.
*/ */
if (!preserve && essential && (access(buf, R_OK) == 0)) { if (!preserve && (access(buf, R_OK) == 0)) {
old_filesd = old_filesd =
prop_dictionary_internalize_from_file(buf); prop_dictionary_internalize_from_file(buf);
if (old_filesd == NULL) { if (old_filesd == NULL) {