parent
17145f82ae
commit
7e18398781
|
@ -78,9 +78,6 @@ APK_ARRAY(apk_dependency_array, struct apk_dependency);
|
||||||
|
|
||||||
struct apk_installed_package {
|
struct apk_installed_package {
|
||||||
struct apk_package *pkg;
|
struct apk_package *pkg;
|
||||||
unsigned int run_all_triggers : 1;
|
|
||||||
unsigned int repository_tag : 6;
|
|
||||||
unsigned short replaces_priority;
|
|
||||||
struct list_head installed_pkgs_list;
|
struct list_head installed_pkgs_list;
|
||||||
struct list_head trigger_pkgs_list;
|
struct list_head trigger_pkgs_list;
|
||||||
struct hlist_head owned_dirs;
|
struct hlist_head owned_dirs;
|
||||||
|
@ -88,6 +85,12 @@ struct apk_installed_package {
|
||||||
struct apk_string_array *triggers;
|
struct apk_string_array *triggers;
|
||||||
struct apk_string_array *pending_triggers;
|
struct apk_string_array *pending_triggers;
|
||||||
struct apk_dependency_array *replaces;
|
struct apk_dependency_array *replaces;
|
||||||
|
|
||||||
|
unsigned short replaces_priority;
|
||||||
|
unsigned repository_tag : 6;
|
||||||
|
unsigned run_all_triggers : 1;
|
||||||
|
unsigned broken_files : 1;
|
||||||
|
unsigned broken_script : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define APK_PKG_UNINSTALLABLE ((char*) -1)
|
#define APK_PKG_UNINSTALLABLE ((char*) -1)
|
||||||
|
@ -177,9 +180,8 @@ void apk_pkg_uninstall(struct apk_database *db, struct apk_package *pkg);
|
||||||
int apk_ipkg_add_script(struct apk_installed_package *ipkg,
|
int apk_ipkg_add_script(struct apk_installed_package *ipkg,
|
||||||
struct apk_istream *is,
|
struct apk_istream *is,
|
||||||
unsigned int type, unsigned int size);
|
unsigned int type, unsigned int size);
|
||||||
int apk_ipkg_run_script(struct apk_installed_package *ipkg,
|
void apk_ipkg_run_script(struct apk_installed_package *ipkg, struct apk_database *db,
|
||||||
struct apk_database *db,
|
unsigned int type, char **argv);
|
||||||
unsigned int type, char **argv);
|
|
||||||
|
|
||||||
struct apk_package *apk_pkg_parse_index_entry(struct apk_database *db, apk_blob_t entry);
|
struct apk_package *apk_pkg_parse_index_entry(struct apk_database *db, apk_blob_t entry);
|
||||||
int apk_pkg_write_index_entry(struct apk_package *pkg, struct apk_ostream *os);
|
int apk_pkg_write_index_entry(struct apk_package *pkg, struct apk_ostream *os);
|
||||||
|
|
52
src/commit.c
52
src/commit.c
|
@ -48,7 +48,7 @@ static int print_change(struct apk_database *db, struct apk_change *change,
|
||||||
} else if (newpkg == oldpkg) {
|
} else if (newpkg == oldpkg) {
|
||||||
if (change->reinstall) {
|
if (change->reinstall) {
|
||||||
if (pkg_available(db, newpkg))
|
if (pkg_available(db, newpkg))
|
||||||
msg = "Re-installing";
|
msg = "Reinstalling";
|
||||||
else
|
else
|
||||||
msg = "[APK unavailable, skipped] Re-installing";
|
msg = "[APK unavailable, skipped] Re-installing";
|
||||||
} else if (change->old_repository_tag != change->new_repository_tag) {
|
} else if (change->old_repository_tag != change->new_repository_tag) {
|
||||||
|
@ -161,6 +161,11 @@ static int cmp_new(struct apk_change *change)
|
||||||
return change->old_pkg == NULL;
|
return change->old_pkg == NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int cmp_reinstall(struct apk_change *change)
|
||||||
|
{
|
||||||
|
return change->reinstall;
|
||||||
|
}
|
||||||
|
|
||||||
static int cmp_downgrade(struct apk_change *change)
|
static int cmp_downgrade(struct apk_change *change)
|
||||||
{
|
{
|
||||||
if (change->new_pkg == NULL || change->old_pkg == NULL)
|
if (change->new_pkg == NULL || change->old_pkg == NULL)
|
||||||
|
@ -217,7 +222,9 @@ int apk_solver_commit_changeset(struct apk_database *db,
|
||||||
{
|
{
|
||||||
struct progress prog;
|
struct progress prog;
|
||||||
struct apk_change *change;
|
struct apk_change *change;
|
||||||
int r = 0, size_diff = 0, size_unit;
|
char buf[32], size_unit;
|
||||||
|
ssize_t size_diff = 0;
|
||||||
|
int r, errors = 0;
|
||||||
|
|
||||||
if (apk_db_check_world(db, world) != 0) {
|
if (apk_db_check_world(db, world) != 0) {
|
||||||
apk_error("Not committing changes due to missing repository tags. Use --force to override.");
|
apk_error("Not committing changes due to missing repository tags. Use --force to override.");
|
||||||
|
@ -252,7 +259,9 @@ int apk_solver_commit_changeset(struct apk_database *db,
|
||||||
"The following NEW packages will be installed");
|
"The following NEW packages will be installed");
|
||||||
dump_packages(changeset, cmp_upgrade,
|
dump_packages(changeset, cmp_upgrade,
|
||||||
"The following packages will be upgraded");
|
"The following packages will be upgraded");
|
||||||
printf("After this operation, %d %ciB of %s\n",
|
dump_packages(changeset, cmp_reinstall,
|
||||||
|
"The following packages will be reinstalled");
|
||||||
|
printf("After this operation, %zd %ciB of %s\n",
|
||||||
abs(size_diff), size_unit,
|
abs(size_diff), size_unit,
|
||||||
(size_diff < 0) ?
|
(size_diff < 0) ?
|
||||||
"disk space will be freed." :
|
"disk space will be freed." :
|
||||||
|
@ -269,25 +278,24 @@ int apk_solver_commit_changeset(struct apk_database *db,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Go through changes */
|
/* Go through changes */
|
||||||
r = 0;
|
|
||||||
foreach_array_item(change, changeset->changes) {
|
foreach_array_item(change, changeset->changes) {
|
||||||
|
r = change->old_pkg &&
|
||||||
|
(change->old_pkg->ipkg->broken_files ||
|
||||||
|
change->old_pkg->ipkg->broken_script);
|
||||||
if (print_change(db, change, prog.done.changes, prog.total.changes)) {
|
if (print_change(db, change, prog.done.changes, prog.total.changes)) {
|
||||||
prog.pkg = change->new_pkg;
|
prog.pkg = change->new_pkg;
|
||||||
progress_cb(&prog, 0);
|
progress_cb(&prog, 0);
|
||||||
|
|
||||||
if (!(apk_flags & APK_SIMULATE)) {
|
if (!(apk_flags & APK_SIMULATE) &&
|
||||||
if (change->old_pkg != change->new_pkg ||
|
((change->old_pkg != change->new_pkg) ||
|
||||||
(change->reinstall && pkg_available(db, change->new_pkg)))
|
(change->reinstall && pkg_available(db, change->new_pkg)))) {
|
||||||
r = apk_db_install_pkg(db,
|
r = apk_db_install_pkg(db, change->old_pkg, change->new_pkg,
|
||||||
change->old_pkg, change->new_pkg,
|
progress_cb, &prog) != 0;
|
||||||
progress_cb, &prog);
|
|
||||||
if (r != 0)
|
|
||||||
break;
|
|
||||||
if (change->new_pkg)
|
|
||||||
change->new_pkg->ipkg->repository_tag = change->new_repository_tag;
|
|
||||||
}
|
}
|
||||||
|
if (r == 0 && change->new_pkg && change->new_pkg->ipkg)
|
||||||
|
change->new_pkg->ipkg->repository_tag = change->new_repository_tag;
|
||||||
}
|
}
|
||||||
|
errors += r;
|
||||||
count_change(change, &prog.done);
|
count_change(change, &prog.done);
|
||||||
}
|
}
|
||||||
apk_print_progress(prog.total.bytes + prog.total.packages,
|
apk_print_progress(prog.total.bytes + prog.total.packages,
|
||||||
|
@ -299,21 +307,27 @@ all_done:
|
||||||
apk_dependency_array_copy(&db->world, world);
|
apk_dependency_array_copy(&db->world, world);
|
||||||
apk_db_write_config(db);
|
apk_db_write_config(db);
|
||||||
|
|
||||||
if (r == 0 && !db->performing_self_update) {
|
if (!db->performing_self_update) {
|
||||||
|
if (errors)
|
||||||
|
snprintf(buf, sizeof(buf), "%d errors;", errors);
|
||||||
|
else
|
||||||
|
strcpy(buf, "OK:");
|
||||||
if (apk_verbosity > 1) {
|
if (apk_verbosity > 1) {
|
||||||
apk_message("OK: %d packages, %d dirs, %d files, %zu MiB",
|
apk_message("%s %d packages, %d dirs, %d files, %zu MiB",
|
||||||
|
buf,
|
||||||
db->installed.stats.packages,
|
db->installed.stats.packages,
|
||||||
db->installed.stats.dirs,
|
db->installed.stats.dirs,
|
||||||
db->installed.stats.files,
|
db->installed.stats.files,
|
||||||
db->installed.stats.bytes / (1024 * 1024));
|
db->installed.stats.bytes / (1024 * 1024));
|
||||||
} else {
|
} else {
|
||||||
apk_message("OK: %zu MiB in %d packages",
|
apk_message("%s %zu MiB in %d packages",
|
||||||
|
buf,
|
||||||
db->installed.stats.bytes / (1024 * 1024),
|
db->installed.stats.bytes / (1024 * 1024),
|
||||||
db->installed.stats.packages);
|
db->installed.stats.packages);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return r;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
|
149
src/database.c
149
src/database.c
|
@ -859,12 +859,20 @@ int apk_db_index_read(struct apk_database *db, struct apk_bstream *bs, int repo)
|
||||||
case 's':
|
case 's':
|
||||||
ipkg->repository_tag = apk_db_get_tag_id(db, l);
|
ipkg->repository_tag = apk_db_get_tag_id(db, l);
|
||||||
break;
|
break;
|
||||||
default:
|
case 'f':
|
||||||
if (r != 0 && !(apk_flags & APK_FORCE)) {
|
for (r = 0; r < l.len; r++) {
|
||||||
/* Installed db should not have unsupported fields */
|
switch (l.ptr[r]) {
|
||||||
apk_error("This apk-tools is too old to handle installed packages");
|
case 'f': ipkg->broken_files = 1; break;
|
||||||
return -1;
|
case 's': ipkg->broken_script = 1; break;
|
||||||
|
default:
|
||||||
|
if (!(apk_flags & APK_FORCE))
|
||||||
|
goto old_apk_tools;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (r != 0 && !(apk_flags & APK_FORCE))
|
||||||
|
goto old_apk_tools;
|
||||||
/* Installed. So mark the package as installable. */
|
/* Installed. So mark the package as installable. */
|
||||||
pkg->filename = NULL;
|
pkg->filename = NULL;
|
||||||
continue;
|
continue;
|
||||||
|
@ -874,8 +882,11 @@ int apk_db_index_read(struct apk_database *db, struct apk_bstream *bs, int repo)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
old_apk_tools:
|
||||||
|
/* Installed db should not have unsupported fields */
|
||||||
|
apk_error("This apk-tools is too old to handle installed packages");
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int apk_db_write_fdb(struct apk_database *db, struct apk_ostream *os)
|
static int apk_db_write_fdb(struct apk_database *db, struct apk_ostream *os)
|
||||||
|
@ -919,6 +930,13 @@ static int apk_db_write_fdb(struct apk_database *db, struct apk_ostream *os)
|
||||||
apk_blob_push_uint(&bbuf, diri->gid, 10);
|
apk_blob_push_uint(&bbuf, diri->gid, 10);
|
||||||
apk_blob_push_blob(&bbuf, APK_BLOB_STR(":"));
|
apk_blob_push_blob(&bbuf, APK_BLOB_STR(":"));
|
||||||
apk_blob_push_uint(&bbuf, diri->mode, 8);
|
apk_blob_push_uint(&bbuf, diri->mode, 8);
|
||||||
|
if (ipkg->broken_files || ipkg->broken_script) {
|
||||||
|
apk_blob_push_blob(&bbuf, APK_BLOB_STR("\nf:"));
|
||||||
|
if (ipkg->broken_files)
|
||||||
|
apk_blob_push_blob(&bbuf, APK_BLOB_STR("f"));
|
||||||
|
if (ipkg->broken_script)
|
||||||
|
apk_blob_push_blob(&bbuf, APK_BLOB_STR("s"));
|
||||||
|
}
|
||||||
apk_blob_push_blob(&bbuf, APK_BLOB_STR("\n"));
|
apk_blob_push_blob(&bbuf, APK_BLOB_STR("\n"));
|
||||||
|
|
||||||
hlist_for_each_entry(file, c2, &diri->owned_files, diri_files_list) {
|
hlist_for_each_entry(file, c2, &diri->owned_files, diri_files_list) {
|
||||||
|
@ -2148,23 +2166,12 @@ static void extract_cb(void *_ctx, size_t bytes_done)
|
||||||
ctx->cb(ctx->cb_ctx, min(ctx->installed_size + bytes_done, ctx->pkg->installed_size));
|
ctx->cb(ctx->cb_ctx, min(ctx->installed_size + bytes_done, ctx->pkg->installed_size));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int apk_db_run_pending_script(struct install_ctx *ctx)
|
static void apk_db_run_pending_script(struct install_ctx *ctx)
|
||||||
{
|
{
|
||||||
int r;
|
if (ctx->script_pending && ctx->sctx.control_verified) {
|
||||||
|
ctx->script_pending = FALSE;
|
||||||
if (!ctx->script_pending)
|
apk_ipkg_run_script(ctx->ipkg, ctx->db, ctx->script, ctx->script_args);
|
||||||
return 0;
|
}
|
||||||
if (!ctx->sctx.control_verified)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
ctx->script_pending = FALSE;
|
|
||||||
r = apk_ipkg_run_script(ctx->ipkg, ctx->db, ctx->script,
|
|
||||||
ctx->script_args);
|
|
||||||
if (r != 0)
|
|
||||||
apk_error("%s-%s: Failed to execute "
|
|
||||||
"pre-install/upgrade script",
|
|
||||||
ctx->pkg->name->name, ctx->pkg->version);
|
|
||||||
return r;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int read_info_line(void *_ctx, apk_blob_t line)
|
static int read_info_line(void *_ctx, apk_blob_t line)
|
||||||
|
@ -2251,11 +2258,10 @@ static int apk_db_install_archive_entry(void *_ctx,
|
||||||
apk_ipkg_add_script(ipkg, is, type, ae->size);
|
apk_ipkg_add_script(ipkg, is, type, ae->size);
|
||||||
if (type == ctx->script)
|
if (type == ctx->script)
|
||||||
ctx->script_pending = TRUE;
|
ctx->script_pending = TRUE;
|
||||||
return apk_db_run_pending_script(ctx);
|
apk_db_run_pending_script(ctx);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
r = apk_db_run_pending_script(ctx);
|
apk_db_run_pending_script(ctx);
|
||||||
if (r != 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
/* Installable entry */
|
/* Installable entry */
|
||||||
ctx->current_file_size = apk_calc_installed_size(ae->size);
|
ctx->current_file_size = apk_calc_installed_size(ae->size);
|
||||||
|
@ -2272,9 +2278,10 @@ static int apk_db_install_archive_entry(void *_ctx,
|
||||||
diri = find_diri(ipkg, bdir, diri, &ctx->file_diri_node);
|
diri = find_diri(ipkg, bdir, diri, &ctx->file_diri_node);
|
||||||
if (diri == NULL) {
|
if (diri == NULL) {
|
||||||
if (!APK_BLOB_IS_NULL(bdir)) {
|
if (!APK_BLOB_IS_NULL(bdir)) {
|
||||||
apk_error("%s: File '%*s' entry without directory entry.\n",
|
apk_error(PKG_VER_FMT": "BLOB_FMT": no dirent in archive\n",
|
||||||
pkg->name->name, name.len, name.ptr);
|
pkg, BLOB_PRINTF(name));
|
||||||
return -1;
|
ipkg->broken_files = 1;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
diri = apk_db_install_directory_entry(ctx, bdir);
|
diri = apk_db_install_directory_entry(ctx, bdir);
|
||||||
}
|
}
|
||||||
|
@ -2316,15 +2323,13 @@ static int apk_db_install_archive_entry(void *_ctx,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (!(apk_flags & APK_FORCE)) {
|
if (!(apk_flags & APK_FORCE)) {
|
||||||
apk_error("%s: Trying to overwrite %s "
|
apk_error(PKG_VER_FMT": trying to overwrite %s owned by "PKG_VER_FMT".",
|
||||||
"owned by %s.",
|
PKG_VER_PRINTF(pkg), ae->name, PKG_VER_PRINTF(opkg));
|
||||||
pkg->name->name, ae->name,
|
ipkg->broken_files = 1;
|
||||||
opkg->name->name);
|
return 0;
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
apk_warning("%s: Overwriting %s owned by %s.",
|
apk_warning(PKG_VER_FMT": overwriting %s owned by "PKG_VER_FMT".",
|
||||||
pkg->name->name, ae->name,
|
PKG_VER_PRINTF(pkg), ae->name, PKG_VER_PRINTF(opkg));
|
||||||
opkg->name->name);
|
|
||||||
} while (0);
|
} while (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2521,16 +2526,14 @@ static void apk_db_migrate_files(struct apk_database *db,
|
||||||
|
|
||||||
static int apk_db_unpack_pkg(struct apk_database *db,
|
static int apk_db_unpack_pkg(struct apk_database *db,
|
||||||
struct apk_installed_package *ipkg,
|
struct apk_installed_package *ipkg,
|
||||||
int upgrade, int reinstall,
|
int upgrade, apk_progress_cb cb, void *cb_ctx,
|
||||||
apk_progress_cb cb, void *cb_ctx,
|
|
||||||
char **script_args)
|
char **script_args)
|
||||||
{
|
{
|
||||||
struct install_ctx ctx;
|
struct install_ctx ctx;
|
||||||
struct apk_bstream *bs = NULL;
|
struct apk_bstream *bs = NULL, *cache_bs;
|
||||||
struct apk_istream *tar;
|
struct apk_istream *tar;
|
||||||
struct apk_repository *repo;
|
struct apk_repository *repo;
|
||||||
struct apk_package *pkg = ipkg->pkg;
|
struct apk_package *pkg = ipkg->pkg;
|
||||||
const char *action = "";
|
|
||||||
char file[PATH_MAX];
|
char file[PATH_MAX];
|
||||||
char tmpcacheitem[128], *cacheitem = &tmpcacheitem[tmpprefix.len];
|
char tmpcacheitem[128], *cacheitem = &tmpcacheitem[tmpprefix.len];
|
||||||
int r, filefd = AT_FDCWD, need_copy = FALSE;
|
int r, filefd = AT_FDCWD, need_copy = FALSE;
|
||||||
|
@ -2538,7 +2541,6 @@ static int apk_db_unpack_pkg(struct apk_database *db,
|
||||||
if (pkg->filename == NULL) {
|
if (pkg->filename == NULL) {
|
||||||
repo = apk_db_select_repo(db, pkg);
|
repo = apk_db_select_repo(db, pkg);
|
||||||
if (repo == NULL) {
|
if (repo == NULL) {
|
||||||
action = "unable to select package: ";
|
|
||||||
r = -ENOPKG;
|
r = -ENOPKG;
|
||||||
goto err_msg;
|
goto err_msg;
|
||||||
}
|
}
|
||||||
|
@ -2563,12 +2565,12 @@ static int apk_db_unpack_pkg(struct apk_database *db,
|
||||||
apk_blob_t b = APK_BLOB_BUF(tmpcacheitem);
|
apk_blob_t b = APK_BLOB_BUF(tmpcacheitem);
|
||||||
apk_blob_push_blob(&b, tmpprefix);
|
apk_blob_push_blob(&b, tmpprefix);
|
||||||
apk_pkg_format_cache_pkg(b, pkg);
|
apk_pkg_format_cache_pkg(b, pkg);
|
||||||
bs = apk_bstream_tee(bs, db->cache_fd, tmpcacheitem, NULL, NULL);
|
cache_bs = apk_bstream_tee(bs, db->cache_fd, tmpcacheitem, NULL, NULL);
|
||||||
if (bs == NULL) {
|
if (cache_bs != NULL)
|
||||||
action = "unable cache package: ";
|
bs = cache_bs;
|
||||||
r = -errno;
|
else
|
||||||
goto err_msg;
|
apk_warning(PKG_VER_FMT": unable to cache: %s",
|
||||||
}
|
PKG_VER_PRINTF(pkg), apk_error_str(errno));
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx = (struct install_ctx) {
|
ctx = (struct install_ctx) {
|
||||||
|
@ -2598,26 +2600,15 @@ static int apk_db_unpack_pkg(struct apk_database *db,
|
||||||
if (r != 0)
|
if (r != 0)
|
||||||
goto err_msg;
|
goto err_msg;
|
||||||
|
|
||||||
r = apk_db_run_pending_script(&ctx);
|
apk_db_run_pending_script(&ctx);
|
||||||
if (r != 0) {
|
|
||||||
action = "unable to run script: ";
|
|
||||||
goto err_msg;
|
|
||||||
}
|
|
||||||
|
|
||||||
apk_db_migrate_files(db, ipkg);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
err_msg:
|
err_msg:
|
||||||
apk_error("%s: %s%s", file, action, apk_error_str(r));
|
apk_error(PKG_VER_FMT": %s", PKG_VER_PRINTF(pkg), apk_error_str(r));
|
||||||
if (!reinstall)
|
|
||||||
apk_db_purge_pkg(db, ipkg, ".apk-new");
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
int apk_db_install_pkg(struct apk_database *db,
|
int apk_db_install_pkg(struct apk_database *db, struct apk_package *oldpkg,
|
||||||
struct apk_package *oldpkg,
|
struct apk_package *newpkg, apk_progress_cb cb, void *cb_ctx)
|
||||||
struct apk_package *newpkg,
|
|
||||||
apk_progress_cb cb, void *cb_ctx)
|
|
||||||
{
|
{
|
||||||
char *script_args[] = { NULL, NULL, NULL, NULL };
|
char *script_args[] = { NULL, NULL, NULL, NULL };
|
||||||
struct apk_installed_package *ipkg;
|
struct apk_installed_package *ipkg;
|
||||||
|
@ -2634,18 +2625,11 @@ int apk_db_install_pkg(struct apk_database *db,
|
||||||
/* Just purging? */
|
/* Just purging? */
|
||||||
if (oldpkg != NULL && newpkg == NULL) {
|
if (oldpkg != NULL && newpkg == NULL) {
|
||||||
ipkg = oldpkg->ipkg;
|
ipkg = oldpkg->ipkg;
|
||||||
|
|
||||||
if (ipkg == NULL)
|
if (ipkg == NULL)
|
||||||
goto ret_r;
|
goto ret_r;
|
||||||
|
apk_ipkg_run_script(ipkg, db, APK_SCRIPT_PRE_DEINSTALL, script_args);
|
||||||
r = apk_ipkg_run_script(ipkg, db,
|
|
||||||
APK_SCRIPT_PRE_DEINSTALL, script_args);
|
|
||||||
if (r != 0)
|
|
||||||
goto ret_r;
|
|
||||||
|
|
||||||
apk_db_purge_pkg(db, ipkg, NULL);
|
apk_db_purge_pkg(db, ipkg, NULL);
|
||||||
r = apk_ipkg_run_script(ipkg, db,
|
apk_ipkg_run_script(ipkg, db, APK_SCRIPT_POST_DEINSTALL, script_args);
|
||||||
APK_SCRIPT_POST_DEINSTALL, script_args);
|
|
||||||
apk_pkg_uninstall(db, oldpkg);
|
apk_pkg_uninstall(db, oldpkg);
|
||||||
goto ret_r;
|
goto ret_r;
|
||||||
}
|
}
|
||||||
|
@ -2661,12 +2645,14 @@ int apk_db_install_pkg(struct apk_database *db,
|
||||||
|
|
||||||
if (newpkg->installed_size != 0) {
|
if (newpkg->installed_size != 0) {
|
||||||
r = apk_db_unpack_pkg(db, ipkg, (oldpkg != NULL),
|
r = apk_db_unpack_pkg(db, ipkg, (oldpkg != NULL),
|
||||||
(oldpkg == newpkg), cb, cb_ctx,
|
cb, cb_ctx, script_args);
|
||||||
script_args);
|
|
||||||
if (r != 0) {
|
if (r != 0) {
|
||||||
|
if (oldpkg != newpkg)
|
||||||
|
apk_db_purge_pkg(db, ipkg, ".apk-new");
|
||||||
apk_pkg_uninstall(db, newpkg);
|
apk_pkg_uninstall(db, newpkg);
|
||||||
goto ret_r;
|
goto ret_r;
|
||||||
}
|
}
|
||||||
|
apk_db_migrate_files(db, ipkg);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (oldpkg != NULL && oldpkg != newpkg && oldpkg->ipkg != NULL) {
|
if (oldpkg != NULL && oldpkg != newpkg && oldpkg->ipkg != NULL) {
|
||||||
|
@ -2674,14 +2660,13 @@ int apk_db_install_pkg(struct apk_database *db,
|
||||||
apk_pkg_uninstall(db, oldpkg);
|
apk_pkg_uninstall(db, oldpkg);
|
||||||
}
|
}
|
||||||
|
|
||||||
r = apk_ipkg_run_script(ipkg, db,
|
apk_ipkg_run_script(
|
||||||
(oldpkg == NULL) ?
|
ipkg, db,
|
||||||
APK_SCRIPT_POST_INSTALL : APK_SCRIPT_POST_UPGRADE,
|
(oldpkg == NULL) ? APK_SCRIPT_POST_INSTALL : APK_SCRIPT_POST_UPGRADE,
|
||||||
script_args);
|
script_args);
|
||||||
if (r != 0) {
|
|
||||||
apk_error(PKG_VER_FMT ": Failed to execute post-install/upgrade script",
|
if (ipkg->broken_files || ipkg->broken_script)
|
||||||
PKG_VER_PRINTF(newpkg));
|
r = -1;
|
||||||
}
|
|
||||||
ret_r:
|
ret_r:
|
||||||
free(script_args[1]);
|
free(script_args[1]);
|
||||||
free(script_args[2]);
|
free(script_args[2]);
|
||||||
|
|
18
src/fix.c
18
src/fix.c
|
@ -52,16 +52,20 @@ static int mark_recalculate(apk_hash_item item, void *ctx)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void set_solver_flags(struct apk_database *db, const char *match, struct apk_name *name, void *pctx)
|
static void mark_fix(struct fix_ctx *ctx, struct apk_name *name)
|
||||||
{
|
{
|
||||||
struct fix_ctx *ctx = (struct fix_ctx *) pctx;
|
|
||||||
|
|
||||||
apk_solver_set_name_flags(name, ctx->solver_flags, ctx->fix_depends ? ctx->solver_flags : 0);
|
apk_solver_set_name_flags(name, ctx->solver_flags, ctx->fix_depends ? ctx->solver_flags : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void set_solver_flags(struct apk_database *db, const char *match, struct apk_name *name, void *ctx)
|
||||||
|
{
|
||||||
|
mark_fix(ctx, name);
|
||||||
|
}
|
||||||
|
|
||||||
static int fix_main(void *pctx, struct apk_database *db, struct apk_string_array *args)
|
static int fix_main(void *pctx, struct apk_database *db, struct apk_string_array *args)
|
||||||
{
|
{
|
||||||
struct fix_ctx *ctx = (struct fix_ctx *) pctx;
|
struct fix_ctx *ctx = (struct fix_ctx *) pctx;
|
||||||
|
struct apk_installed_package *ipkg;
|
||||||
|
|
||||||
if (!ctx->solver_flags)
|
if (!ctx->solver_flags)
|
||||||
ctx->solver_flags = APK_SOLVERF_REINSTALL;
|
ctx->solver_flags = APK_SOLVERF_REINSTALL;
|
||||||
|
@ -69,7 +73,13 @@ static int fix_main(void *pctx, struct apk_database *db, struct apk_string_array
|
||||||
if (ctx->fix_directory_permissions)
|
if (ctx->fix_directory_permissions)
|
||||||
apk_hash_foreach(&db->installed.dirs, mark_recalculate, db);
|
apk_hash_foreach(&db->installed.dirs, mark_recalculate, db);
|
||||||
|
|
||||||
apk_name_foreach_matching(db, args, apk_foreach_genid(), set_solver_flags, ctx);
|
if (args->num == 0) {
|
||||||
|
list_for_each_entry(ipkg, &db->installed.packages, installed_pkgs_list) {
|
||||||
|
if (ipkg->broken_files || ipkg->broken_script)
|
||||||
|
mark_fix(ctx, ipkg->pkg->name);
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
apk_name_foreach_matching(db, args, apk_foreach_genid(), set_solver_flags, ctx);
|
||||||
|
|
||||||
return apk_solver_commit(db, 0, db->world);
|
return apk_solver_commit(db, 0, db->world);
|
||||||
}
|
}
|
||||||
|
|
|
@ -796,7 +796,7 @@ int apk_pkg_add_info(struct apk_database *db, struct apk_package *pkg,
|
||||||
pkg->commit = apk_blob_cstr(value);
|
pkg->commit = apk_blob_cstr(value);
|
||||||
break;
|
break;
|
||||||
case 'F': case 'M': case 'R': case 'Z': case 'r': case 'q':
|
case 'F': case 'M': case 'R': case 'Z': case 'r': case 'q':
|
||||||
case 'a': case 's':
|
case 'a': case 's': case 'f':
|
||||||
/* installed db entries which are handled in database.c */
|
/* installed db entries which are handled in database.c */
|
||||||
return 1;
|
return 1;
|
||||||
default:
|
default:
|
||||||
|
@ -973,9 +973,9 @@ int apk_ipkg_add_script(struct apk_installed_package *ipkg,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int apk_ipkg_run_script(struct apk_installed_package *ipkg,
|
void apk_ipkg_run_script(struct apk_installed_package *ipkg,
|
||||||
struct apk_database *db,
|
struct apk_database *db,
|
||||||
unsigned int type, char **argv)
|
unsigned int type, char **argv)
|
||||||
{
|
{
|
||||||
static char * const environment[] = {
|
static char * const environment[] = {
|
||||||
"PATH=/usr/sbin:/usr/bin:/sbin:/bin",
|
"PATH=/usr/sbin:/usr/bin:/sbin:/bin",
|
||||||
|
@ -986,11 +986,8 @@ int apk_ipkg_run_script(struct apk_installed_package *ipkg,
|
||||||
int fd, status, root_fd = db->root_fd;
|
int fd, status, root_fd = db->root_fd;
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
|
|
||||||
if (type >= APK_SCRIPT_MAX)
|
if (type >= APK_SCRIPT_MAX || ipkg->script[type].ptr == NULL)
|
||||||
return -1;
|
return;
|
||||||
|
|
||||||
if (ipkg->script[type].ptr == NULL)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
argv[0] = (char *) apk_script_types[type];
|
argv[0] = (char *) apk_script_types[type];
|
||||||
|
|
||||||
|
@ -1001,43 +998,41 @@ int apk_ipkg_run_script(struct apk_installed_package *ipkg,
|
||||||
|
|
||||||
apk_message("Executing %s", &fn[15]);
|
apk_message("Executing %s", &fn[15]);
|
||||||
if (apk_flags & APK_SIMULATE)
|
if (apk_flags & APK_SIMULATE)
|
||||||
return 0;
|
return;
|
||||||
|
|
||||||
fd = openat(root_fd, fn, O_CREAT|O_RDWR|O_TRUNC|O_CLOEXEC, 0755);
|
fd = openat(root_fd, fn, O_CREAT|O_RDWR|O_TRUNC|O_CLOEXEC, 0755);
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
mkdirat(root_fd, "var/cache/misc", 0755);
|
mkdirat(root_fd, "var/cache/misc", 0755);
|
||||||
fd = openat(root_fd, fn, O_CREAT|O_RDWR|O_TRUNC|O_CLOEXEC, 0755);
|
fd = openat(root_fd, fn, O_CREAT|O_RDWR|O_TRUNC|O_CLOEXEC, 0755);
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
return -errno;
|
goto error;
|
||||||
}
|
}
|
||||||
if (write(fd, ipkg->script[type].ptr, ipkg->script[type].len) < 0) {
|
if (write(fd, ipkg->script[type].ptr, ipkg->script[type].len) < 0) {
|
||||||
close(fd);
|
close(fd);
|
||||||
return -errno;
|
goto error;
|
||||||
}
|
}
|
||||||
close(fd);
|
close(fd);
|
||||||
|
|
||||||
pid = fork();
|
pid = fork();
|
||||||
if (pid == -1)
|
if (pid == -1)
|
||||||
return -1;
|
goto error;
|
||||||
if (pid == 0) {
|
if (pid == 0) {
|
||||||
if (fchdir(root_fd) < 0 || chroot(".") < 0) {
|
if (fchdir(root_fd) == 0 && chroot(".") == 0)
|
||||||
apk_error("chroot: %s", strerror(errno));
|
|
||||||
} else {
|
|
||||||
execve(fn, argv, environment);
|
execve(fn, argv, environment);
|
||||||
}
|
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
waitpid(pid, &status, 0);
|
waitpid(pid, &status, 0);
|
||||||
unlinkat(root_fd, fn, 0);
|
unlinkat(root_fd, fn, 0);
|
||||||
apk_id_cache_reset(&db->id_cache);
|
apk_id_cache_reset(&db->id_cache);
|
||||||
|
|
||||||
if (WIFEXITED(status)) {
|
if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
|
||||||
int rc = WEXITSTATUS(status);
|
apk_error("%s: script exited with error %d", &fn[15], WEXITSTATUS(status));
|
||||||
if (rc != 0)
|
ipkg->broken_script = 1;
|
||||||
apk_warning("%s: returned error %d", &fn[15], rc);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
return -1;
|
return;
|
||||||
|
error:
|
||||||
|
apk_error("%s: failed to execute: %s", &fn[15], apk_error_str(errno));
|
||||||
|
ipkg->broken_script = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int parse_index_line(void *ctx, apk_blob_t line)
|
static int parse_index_line(void *ctx, apk_blob_t line)
|
||||||
|
|
|
@ -4,5 +4,5 @@
|
||||||
--test-world a
|
--test-world a
|
||||||
fix b
|
fix b
|
||||||
@EXPECT
|
@EXPECT
|
||||||
(1/1) Re-installing b (1)
|
(1/1) Reinstalling b (1)
|
||||||
OK: 0 MiB in 2 packages
|
OK: 0 MiB in 2 packages
|
||||||
|
|
|
@ -4,5 +4,5 @@
|
||||||
--test-world a
|
--test-world a
|
||||||
fix a
|
fix a
|
||||||
@EXPECT
|
@EXPECT
|
||||||
(1/1) Re-installing a (1)
|
(1/1) Reinstalling a (1)
|
||||||
OK: 0 MiB in 2 packages
|
OK: 0 MiB in 2 packages
|
||||||
|
|
|
@ -5,6 +5,6 @@
|
||||||
--depends
|
--depends
|
||||||
fix a
|
fix a
|
||||||
@EXPECT
|
@EXPECT
|
||||||
(1/2) Re-installing b (1)
|
(1/2) Reinstalling b (1)
|
||||||
(2/2) Re-installing a (1)
|
(2/2) Reinstalling a (1)
|
||||||
OK: 0 MiB in 2 packages
|
OK: 0 MiB in 2 packages
|
||||||
|
|
Loading…
Reference in New Issue