Introduce new pkg state: half-unpacked.

Packages in this state shall be re-installed and re-unpacked because its
files weren't unpacked properly.
This commit is contained in:
Juan RP 2011-07-28 16:25:01 +02:00
parent 6c0b24029b
commit 5e390b8839
7 changed files with 92 additions and 80 deletions

View File

@ -310,6 +310,8 @@ main(int argc, char **argv)
if (argv[1]) {
if (strcmp(argv[1], "installed") == 0)
lpc.state = XBPS_PKG_STATE_INSTALLED;
if (strcmp(argv[1], "half-unpacked") == 0)
lpc.state = XBPS_PKG_STATE_HALF_UNPACKED;
else if (strcmp(argv[1], "unpacked") == 0)
lpc.state = XBPS_PKG_STATE_UNPACKED;
else if (strcmp(argv[1], "config-files") == 0)

View File

@ -1,4 +1,4 @@
.TH "XBPS\-BIN" "8" "07/23/2011" "\ \&" "\ \&"
.TH "XBPS\-BIN" "8" "07/28/2011" "\ \&" "\ \&"
.\" -----------------------------------------------------------------
.\" * set default formatting
.\" -----------------------------------------------------------------
@ -189,7 +189,8 @@ will be listed if
\fIstate\fR
has not been specified\&. Accepted states are:
\fIconfig\-files\fR,
\fIunpacked\fR
\fIhalf-unpacked\fR,
\fIunpacked\fR,
and
\fIinstalled\fR\&.
.RE
@ -285,6 +286,10 @@ A package can be in a different state while it is being installed, removed, unpa
The package is fully installed, that means it was unpacked and configured correctly\&.
.RE
.PP
\fBhalf\-unpacked\fR
The package was being unpacked but didn't finish properly for unknown reasons.
.RE
.PP
\fBunpacked\fR
.RS 4
The package has been unpacked in destination root directory, but it is not fully installed because it was not yet configured\&. Please note, that some packages will do not work if they are only unpacked\&.

View File

@ -1293,6 +1293,9 @@ int xbps_repository_sync_pkg_index(const char *uri);
* Integer representing a state on which a package may be. Possible
* values for this are:
*
* <b>XBPS_PKG_STATE_HALF_UNPACKED</b>: Package was being unpacked
* but didn't finish properly.
*
* <b>XBPS_PKG_STATE_UNPACKED</b>: Package has been unpacked correctly
* but has not been configured due to unknown reasons.
*
@ -1311,7 +1314,8 @@ typedef enum pkg_state {
XBPS_PKG_STATE_INSTALLED,
XBPS_PKG_STATE_BROKEN,
XBPS_PKG_STATE_CONFIG_FILES,
XBPS_PKG_STATE_NOT_INSTALLED
XBPS_PKG_STATE_NOT_INSTALLED,
XBPS_PKG_STATE_HALF_UNPACKED
} pkg_state_t;
/**

View File

@ -44,7 +44,8 @@
#define EXTRACT_FLAGS ARCHIVE_EXTRACT_SECURE_NODOTDOT | \
ARCHIVE_EXTRACT_SECURE_SYMLINKS
#define FEXTRACT_FLAGS ARCHIVE_EXTRACT_OWNER | ARCHIVE_EXTRACT_PERM | \
ARCHIVE_EXTRACT_TIME | EXTRACT_FLAGS
ARCHIVE_EXTRACT_TIME | ARCHIVE_EXTRACT_UNLINK | \
EXTRACT_FLAGS
#ifndef __UNCONST
#define __UNCONST(a) ((void *)(unsigned long)(const void *)(a))

View File

@ -42,6 +42,7 @@ static const struct state states[] = {
{ "broken", XBPS_PKG_STATE_BROKEN },
{ "config-files", XBPS_PKG_STATE_CONFIG_FILES },
{ "not-installed", XBPS_PKG_STATE_NOT_INSTALLED },
{ "half-unpacked", XBPS_PKG_STATE_HALF_UNPACKED },
{ NULL, 0 }
};
@ -167,18 +168,21 @@ xbps_set_pkg_state_installed(const char *pkgname,
struct xbps_handle *xhp;
prop_dictionary_t dict = NULL, pkgd;
prop_array_t array;
char *plist;
char *metadir, *plist;
int rv = 0;
bool newpkg = false;
assert(pkgname != NULL);
xhp = xbps_handle_get();
plist = xbps_xasprintf("%s/%s/%s", xhp->rootdir,
XBPS_META_PATH, XBPS_REGPKGDB);
if (plist == NULL)
metadir = xbps_xasprintf("%s/%s", xhp->rootdir, XBPS_META_PATH);
if (metadir == NULL)
return ENOMEM;
plist = xbps_xasprintf("%s/%s", metadir, XBPS_REGPKGDB);
if (plist == NULL) {
free(metadir);
return ENOMEM;
}
if ((dict = prop_dictionary_internalize_from_zfile(plist)) == NULL) {
dict = prop_dictionary_create();
if (dict == NULL) {
@ -257,6 +261,19 @@ xbps_set_pkg_state_installed(const char *pkgname,
}
}
/* Create metadir if doesn't exist */
if (access(metadir, X_OK) == -1) {
if (errno == ENOENT) {
if (xbps_mkpath(metadir, 0750) != 0) {
xbps_dbg_printf("[pkgstate] failed to create "
"metadir %s: %s\n", metadir,
strerror(errno));
rv = errno;
goto out;
}
}
}
/* Externalize regpkgdb plist file */
if (!prop_dictionary_externalize_to_zfile(dict, plist)) {
rv = errno;
xbps_dbg_printf("[pkgstate] cannot write plist '%s': %s\n",
@ -266,6 +283,8 @@ xbps_set_pkg_state_installed(const char *pkgname,
out:
if (dict)
prop_object_release(dict);
if (metadir)
free(metadir);
if (plist)
free(plist);

View File

@ -66,25 +66,17 @@
* data type is specified on its edge, i.e string, array, integer, dictionary.
*/
static void
set_extract_flags(int *flags, bool update)
static int
set_extract_flags(void)
{
int lflags = 0;
int flags;
if (getuid() == 0)
lflags = FEXTRACT_FLAGS;
if (geteuid() == 0)
flags = FEXTRACT_FLAGS;
else
lflags = EXTRACT_FLAGS;
flags = EXTRACT_FLAGS;
if (!update) {
/*
* Only overwrite files while updating.
*/
lflags |= ARCHIVE_EXTRACT_NO_OVERWRITE;
lflags |= ARCHIVE_EXTRACT_NO_OVERWRITE_NEWER;
}
*flags = lflags;
return flags;
}
static int
@ -150,10 +142,10 @@ remove_metafile(const char *file, const char *pkgname, const char *version)
* 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 != NULL && xhp->xbps_unpack_cb != NULL && xhp->xucd != NULL) \
(*xhp->xbps_unpack_cb)(xhp->xucd); \
#define RUN_PROGRESS_CB() \
do { \
if (xhp->xbps_unpack_cb != NULL) \
(*xhp->xbps_unpack_cb)(xhp->xucd); \
} while (0)
static int
@ -209,9 +201,9 @@ unpack_archive(prop_dictionary_t pkg_repod,
*/
while (archive_read_next_header(ar, &entry) == ARCHIVE_OK) {
entry_pname = archive_entry_pathname(entry);
set_extract_flags(&flags, update);
if (xhp != NULL && xhp->xbps_unpack_cb != NULL &&
xhp->xucd != NULL) {
flags = set_extract_flags();
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;
@ -245,10 +237,8 @@ unpack_archive(prop_dictionary_t pkg_repod,
goto out;
}
nmetadata++;
if (xhp->xucd != NULL) {
xhp->xucd->entry_is_metadata = true;
xhp->xucd->entry_extract_count++;
}
xhp->xucd->entry_is_metadata = true;
xhp->xucd->entry_extract_count++;
RUN_PROGRESS_CB();
continue;
@ -259,10 +249,8 @@ unpack_archive(prop_dictionary_t pkg_repod,
goto out;
nmetadata++;
if (xhp->xucd != NULL) {
xhp->xucd->entry_is_metadata = true;
xhp->xucd->entry_extract_count++;
}
xhp->xucd->entry_is_metadata = true;
xhp->xucd->entry_extract_count++;
RUN_PROGRESS_CB();
continue;
@ -278,10 +266,8 @@ unpack_archive(prop_dictionary_t pkg_repod,
goto out;
}
nmetadata++;
if (xhp->xucd != NULL) {
xhp->xucd->entry_is_metadata = true;
xhp->xucd->entry_extract_count++;
}
xhp->xucd->entry_is_metadata = true;
xhp->xucd->entry_extract_count++;
RUN_PROGRESS_CB();
continue;
@ -298,10 +284,8 @@ unpack_archive(prop_dictionary_t pkg_repod,
goto out;
}
nmetadata++;
if (xhp->xucd != NULL) {
xhp->xucd->entry_is_metadata = true;
xhp->xucd->entry_extract_count++;
}
xhp->xucd->entry_is_metadata = true;
xhp->xucd->entry_extract_count++;
RUN_PROGRESS_CB();
continue;
}
@ -329,18 +313,16 @@ unpack_archive(prop_dictionary_t pkg_repod,
* Compute total entries in progress data, if set.
* total_entries = metadata + files + conf_files + links.
*/
if (xhp->xucd != NULL) {
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);
}
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);
/*
* Handle configuration files. Check if current entry is
@ -361,13 +343,7 @@ unpack_archive(prop_dictionary_t pkg_repod,
if (rv == -1) {
/* error */
goto out;
} else if (rv == 1) {
/*
* Configuration file should be installed.
*/
flags &= ~ARCHIVE_EXTRACT_NO_OVERWRITE;
flags &= ~ARCHIVE_EXTRACT_NO_OVERWRITE_NEWER;
} else {
} else if (rv == 0) {
/*
* Keep current configuration file
* as is now and pass to next entry.
@ -396,9 +372,7 @@ unpack_archive(prop_dictionary_t pkg_repod,
continue;
}
}
if (xhp->xucd != NULL)
xhp->xucd->entry_extract_count++;
xhp->xucd->entry_extract_count++;
RUN_PROGRESS_CB();
}
@ -482,8 +456,7 @@ xbps_unpack_binary_pkg(prop_dictionary_t pkg_repod)
return errno;
}
ar = archive_read_new();
if (ar == NULL) {
if ((ar = archive_read_new()) == NULL) {
rv = ENOMEM;
goto out;
}
@ -503,15 +476,23 @@ xbps_unpack_binary_pkg(prop_dictionary_t pkg_repod)
* Set extract progress callback if specified.
*/
xhp = xbps_handle_get();
if (xhp != NULL && xhp->xbps_unpack_cb != NULL && xhp->xucd != NULL) {
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));
goto out;
}
/*
* Extract archive files.
*/
rv = unpack_archive(pkg_repod, ar, pkgname, version, xhp);
if (rv != 0) {
if ((rv = unpack_archive(pkg_repod, ar, pkgname, version, xhp)) != 0) {
xbps_error_printf("failed to unpack `%s' binpkg: %s\n",
bpkg, strerror(rv));
goto out;
@ -519,11 +500,10 @@ xbps_unpack_binary_pkg(prop_dictionary_t pkg_repod)
/*
* Set package state to unpacked.
*/
rv = xbps_set_pkg_state_installed(pkgname, version, pkgver,
XBPS_PKG_STATE_UNPACKED);
if (rv != 0) {
xbps_error_printf("failed to set `%s-%s' to unpacked "
"state: %s\n", pkgname, version, strerror(rv));
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));
}
out:
if (bpkg)

View File

@ -129,7 +129,8 @@ repository_find_pkg(const char *pattern, const char *reason)
if (state == XBPS_PKG_STATE_UNPACKED)
reason = "configure";
else if (state == XBPS_PKG_STATE_NOT_INSTALLED)
else if (state == XBPS_PKG_STATE_NOT_INSTALLED ||
state == XBPS_PKG_STATE_HALF_UNPACKED)
reason = "install";
/*