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 (argv[1]) {
if (strcmp(argv[1], "installed") == 0) if (strcmp(argv[1], "installed") == 0)
lpc.state = XBPS_PKG_STATE_INSTALLED; 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) else if (strcmp(argv[1], "unpacked") == 0)
lpc.state = XBPS_PKG_STATE_UNPACKED; lpc.state = XBPS_PKG_STATE_UNPACKED;
else if (strcmp(argv[1], "config-files") == 0) 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 .\" * set default formatting
.\" ----------------------------------------------------------------- .\" -----------------------------------------------------------------
@ -189,7 +189,8 @@ will be listed if
\fIstate\fR \fIstate\fR
has not been specified\&. Accepted states are: has not been specified\&. Accepted states are:
\fIconfig\-files\fR, \fIconfig\-files\fR,
\fIunpacked\fR \fIhalf-unpacked\fR,
\fIunpacked\fR,
and and
\fIinstalled\fR\&. \fIinstalled\fR\&.
.RE .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\&. The package is fully installed, that means it was unpacked and configured correctly\&.
.RE .RE
.PP .PP
\fBhalf\-unpacked\fR
The package was being unpacked but didn't finish properly for unknown reasons.
.RE
.PP
\fBunpacked\fR \fBunpacked\fR
.RS 4 .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\&. 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 * Integer representing a state on which a package may be. Possible
* values for this are: * 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 * <b>XBPS_PKG_STATE_UNPACKED</b>: Package has been unpacked correctly
* but has not been configured due to unknown reasons. * but has not been configured due to unknown reasons.
* *
@ -1311,7 +1314,8 @@ typedef enum pkg_state {
XBPS_PKG_STATE_INSTALLED, XBPS_PKG_STATE_INSTALLED,
XBPS_PKG_STATE_BROKEN, XBPS_PKG_STATE_BROKEN,
XBPS_PKG_STATE_CONFIG_FILES, XBPS_PKG_STATE_CONFIG_FILES,
XBPS_PKG_STATE_NOT_INSTALLED XBPS_PKG_STATE_NOT_INSTALLED,
XBPS_PKG_STATE_HALF_UNPACKED
} pkg_state_t; } pkg_state_t;
/** /**

View File

@ -44,7 +44,8 @@
#define EXTRACT_FLAGS ARCHIVE_EXTRACT_SECURE_NODOTDOT | \ #define EXTRACT_FLAGS ARCHIVE_EXTRACT_SECURE_NODOTDOT | \
ARCHIVE_EXTRACT_SECURE_SYMLINKS ARCHIVE_EXTRACT_SECURE_SYMLINKS
#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 | ARCHIVE_EXTRACT_UNLINK | \
EXTRACT_FLAGS
#ifndef __UNCONST #ifndef __UNCONST
#define __UNCONST(a) ((void *)(unsigned long)(const void *)(a)) #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 }, { "broken", XBPS_PKG_STATE_BROKEN },
{ "config-files", XBPS_PKG_STATE_CONFIG_FILES }, { "config-files", XBPS_PKG_STATE_CONFIG_FILES },
{ "not-installed", XBPS_PKG_STATE_NOT_INSTALLED }, { "not-installed", XBPS_PKG_STATE_NOT_INSTALLED },
{ "half-unpacked", XBPS_PKG_STATE_HALF_UNPACKED },
{ NULL, 0 } { NULL, 0 }
}; };
@ -167,18 +168,21 @@ xbps_set_pkg_state_installed(const char *pkgname,
struct xbps_handle *xhp; struct xbps_handle *xhp;
prop_dictionary_t dict = NULL, pkgd; prop_dictionary_t dict = NULL, pkgd;
prop_array_t array; prop_array_t array;
char *plist; char *metadir, *plist;
int rv = 0; int rv = 0;
bool newpkg = false; bool newpkg = false;
assert(pkgname != NULL); assert(pkgname != NULL);
xhp = xbps_handle_get(); xhp = xbps_handle_get();
plist = xbps_xasprintf("%s/%s/%s", xhp->rootdir, metadir = xbps_xasprintf("%s/%s", xhp->rootdir, XBPS_META_PATH);
XBPS_META_PATH, XBPS_REGPKGDB); if (metadir == NULL)
if (plist == NULL)
return ENOMEM; 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) { if ((dict = prop_dictionary_internalize_from_zfile(plist)) == NULL) {
dict = prop_dictionary_create(); dict = prop_dictionary_create();
if (dict == NULL) { 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)) { if (!prop_dictionary_externalize_to_zfile(dict, plist)) {
rv = errno; rv = errno;
xbps_dbg_printf("[pkgstate] cannot write plist '%s': %s\n", xbps_dbg_printf("[pkgstate] cannot write plist '%s': %s\n",
@ -266,6 +283,8 @@ xbps_set_pkg_state_installed(const char *pkgname,
out: out:
if (dict) if (dict)
prop_object_release(dict); prop_object_release(dict);
if (metadir)
free(metadir);
if (plist) if (plist)
free(plist); free(plist);

View File

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

View File

@ -129,7 +129,8 @@ repository_find_pkg(const char *pattern, const char *reason)
if (state == XBPS_PKG_STATE_UNPACKED) if (state == XBPS_PKG_STATE_UNPACKED)
reason = "configure"; 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"; reason = "install";
/* /*