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-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, xbps-bin(8), xbps-repo(8): redirect all warning and error
messages to stderr.
* xbps-uhelper: the 'fetch' target now accepts an arbitrary number of
arguments, and sets default libfetch cache connection limits.
* libxbps: changes xbps_yesno() and xbps_noyes() to only accept "yes" or "no"
(case insensitive) answers rather than 'y' or 'n', to avoid mistaken answers.
* xbps-bin(8): when downloading binary packages, it now sets default
libfetch cache connection limits, thus reusing connections to the same host.
* 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-repo(8): added support to the 'search' target to find exact matches,
i.e 'xbps-repo search bash'.
* xbps-bin(8) added support to the 'install', 'remove' and 'update'
targets to accept any arbitrary number of package names, i.e
"xbps-bin install foo blah baz".
See https://blueprints.launchpad.net/xbps/+spec/arbitrary-pkgname-args
* xbps-repo(8): added support to the 'search' target to find exact matches,
i.e 'xbps-repo search bash'.
* 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
* libxbps: changes xbps_yesno() and xbps_noyes() to only accept "yes" or "no"
(case insensitive) answers rather than 'y' or 'n', to avoid mistaken answers.
* libxbps: fixed some bugs while upgrading essential packages when new package
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
messages to stderr.
* libxbps: fixed some memleaks found by cppcheck and valgrind.
* 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);
version = xbps_get_pkg_version(pkgver);
rv = xbps_remove_pkg(reppkgn, version, false, false);
rv = xbps_remove_pkg(reppkgn, version, false);
if (rv != 0) {
fprintf(stderr, "xbps-bin: couldn't remove %s (%s)\n",
reppkgn, strerror(rv));
@ -499,14 +499,14 @@ exec_transaction(struct transaction *trans)
prop_object_iterator_t replaces_iter;
const char *pkgname, *version, *pkgver, *instver, *filename, *tract;
int rv = 0;
bool update, essential, preserve, autoinst;
bool update, preserve, autoinst;
pkg_state_t state = 0;
assert(trans != NULL);
assert(trans->dict != NULL);
assert(trans->iter != NULL);
update = essential = autoinst = preserve = false;
update = autoinst = preserve = false;
/*
* Show download/installed size for the transaction.
*/
@ -546,7 +546,6 @@ exec_transaction(struct transaction *trans)
"pkgver", &pkgver))
return errno;
prop_dictionary_get_bool(obj, "automatic-install", &autoinst);
prop_dictionary_get_bool(obj, "essential", &essential);
prop_dictionary_get_bool(obj, "preserve", &preserve);
if (!prop_dictionary_get_cstring_nocopy(obj,
"filename", &filename))
@ -595,28 +594,17 @@ exec_transaction(struct transaction *trans)
}
prop_object_release(instpkgd);
/*
* 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)
if (preserve)
printf("Conserving %s-%s files, installing new "
"version ...\n", pkgname, instver);
else
printf("Removing %s-%s before installing new "
"version ...\n", pkgname, instver);
printf("Replacing %s files (%s -> %s) ...\n",
pkgname, instver, version);
rv = xbps_remove_pkg(pkgname, version, true, essential);
rv = xbps_remove_pkg(pkgname, version, true);
if (rv != 0) {
fprintf(stderr, "xbps-bin: error "
"%s %s-%s (%s)\n", essential ?
"replacing" : "removing", pkgname,
"replacing %s-%s (%s)\n", pkgname,
instver, strerror(rv));
return rv;
}

View File

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

View File

@ -107,9 +107,10 @@ show_pkg_info(prop_dictionary_t dict)
if (obj && prop_object_type(obj) == PROP_TYPE_STRING)
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)
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");
if (obj && prop_object_type(obj) == PROP_TYPE_ARRAY) {

View File

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

View File

@ -58,7 +58,7 @@ __BEGIN_DECLS
* @def XBPS_RELVER
* Current library release date.
*/
#define XBPS_RELVER "20100121"
#define XBPS_RELVER "20100128"
/**
* @def XBPS_META_PATH
@ -128,9 +128,7 @@ __BEGIN_DECLS
#define ARCHIVE_READ_BLOCKSIZE 10240
#define EXTRACT_FLAGS ARCHIVE_EXTRACT_SECURE_NODOTDOT | \
ARCHIVE_EXTRACT_SECURE_SYMLINKS | \
ARCHIVE_EXTRACT_NO_OVERWRITE | \
ARCHIVE_EXTRACT_NO_OVERWRITE_NEWER
ARCHIVE_EXTRACT_SECURE_SYMLINKS
#define FEXTRACT_FLAGS ARCHIVE_EXTRACT_OWNER | ARCHIVE_EXTRACT_PERM | \
ARCHIVE_EXTRACT_TIME | EXTRACT_FLAGS
@ -637,15 +635,12 @@ void xbps_regpkgs_dictionary_release(void);
*
* @param[in] pkgname Package name to match.
* @param[in] version Package version associated.
* @param[in] update If true, and depending if \a pkgname is an
* <em>essential</em> package, some steps will be skipped. See in the
* detailed description section for more information.
* @param[in] essential Set it to true if \a pkgname is essential.
* @param[in] update If true, some steps will be skipped. See in the
* detailed description above for more information.
*
* @return 0 on success, or an errno value otherwise.
*/
int xbps_remove_pkg(const char *pkgname, const char *version,
bool update, bool essential);
int xbps_remove_pkg(const char *pkgname, const char *version, bool update);
/**
* 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.
*
* @note
* -# If a package is going to be updated and it's an essential package,
* only steps <b>1</b> and <b>4</b> 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 updated, only steps <b>1</b> and <b>4</b>
* 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
@ -186,8 +184,7 @@ xbps_remove_pkg_files(prop_dictionary_t dict, const char *key)
}
int
xbps_remove_pkg(const char *pkgname, const char *version,
bool update, bool essential)
xbps_remove_pkg(const char *pkgname, const char *version, bool update)
{
prop_dictionary_t dict;
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
* the current pre-remove action target, unregister its requiredby
* entries and continue. Its files will be overwritten later in
* the unpack phase.
* If updating a package, we just need to execute the current
* pre-remove action target, unregister its requiredby entries and
* continue. Its files will be overwritten later in unpack phase.
*/
if (essential && update) {
if (update) {
free(buf);
return xbps_requiredby_pkg_remove(pkgname);
}

View File

@ -44,8 +44,8 @@
* - All other kind of files on archive are extracted.
* - Handles configuration files by taking care of updating them with
* new versions if necessary and to not overwrite modified ones.
* - If it's an <b>essential</b> package, files from installed package are
* compared with new package and obsolete files are removed.
* - Files from installed package are compared with new package and
* obsolete files are removed.
* - Finally its state is set to XBPS_PKG_STATE_UNPACKED.
*
* 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;
char *buf;
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;
assert(ar != NULL);
assert(pkg != NULL);
essential = preserve = actgt = skip_entry = update = false;
preserve = actgt = skip_entry = update = false;
props_plist_found = files_plist_found = false;
rootdir = xbps_get_rootdir();
flags = xbps_get_flags();
@ -108,10 +108,7 @@ unpack_archive_fini(struct archive *ar, prop_dictionary_t pkg)
return errno;
if (!prop_dictionary_get_cstring_nocopy(pkg, "version", &version))
return errno;
/*
* The following two objects are OPTIONAL.
*/
prop_dictionary_get_bool(pkg, "essential", &essential);
prop_dictionary_get_bool(pkg, "preserve", &preserve);
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) {
entry_str = archive_entry_pathname(entry);
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.
*/
@ -319,11 +303,11 @@ unpack_archive_fini(struct archive *ar, prop_dictionary_t pkg)
return errno;
}
/*
* Check if files.plist exists and pkg is marked as
* essential and NOT preserve, in that case we need to check
* for obsolete files and remove them if necessary.
* Check if files.plist exists and pkg is NOT marked as
* preserve, in that case we need to check for obsolete files
* and remove them if necessary.
*/
if (!preserve && essential && (access(buf, R_OK) == 0)) {
if (!preserve && (access(buf, R_OK) == 0)) {
old_filesd =
prop_dictionary_internalize_from_file(buf);
if (old_filesd == NULL) {