summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/apk.c6
-rw-r--r--src/apk_defines.h1
-rw-r--r--src/apk_state.h3
-rw-r--r--src/state.c10
-rw-r--r--src/upgrade.c48
5 files changed, 61 insertions, 7 deletions
diff --git a/src/apk.c b/src/apk.c
index 7663d4c..4b97be5 100644
--- a/src/apk.c
+++ b/src/apk.c
@@ -30,6 +30,8 @@
#include "apk_blob.h"
#include "apk_print.h"
+char **apk_argv;
+
static struct apk_option generic_options[] = {
{ 'h', "help", "Show generic help or applet specific help" },
{ 'p', "root", "Install packages to DIR",
@@ -245,6 +247,10 @@ int main(int argc, char **argv)
struct apk_database db;
struct apk_db_options dbopts;
+ apk_argv = malloc(sizeof(char*[argc+1]));
+ memcpy(apk_argv, argv, sizeof(char*[argc]));
+ apk_argv[argc] = NULL;
+
memset(&dbopts, 0, sizeof(dbopts));
list_init(&dbopts.repository_list);
apk_atom_init();
diff --git a/src/apk_defines.h b/src/apk_defines.h
index 6d5f49c..b11d181 100644
--- a/src/apk_defines.h
+++ b/src/apk_defines.h
@@ -50,6 +50,7 @@
extern int apk_verbosity;
extern unsigned int apk_flags;
extern const char *apk_arch;
+extern char **apk_argv;
#define APK_FORCE 0x0001
#define APK_SIMULATE 0x0002
diff --git a/src/apk_state.h b/src/apk_state.h
index 42d3f3f..1ac049a 100644
--- a/src/apk_state.h
+++ b/src/apk_state.h
@@ -23,7 +23,8 @@ struct apk_change {
};
struct apk_state {
- unsigned int refs, num_names;
+ unsigned int refs, num_names, num_changes;
+ int print_ok;
struct apk_database *db;
struct list_head change_list_head;
struct apk_package_array *conflicts;
diff --git a/src/state.c b/src/state.c
index 0471850..ddfca57 100644
--- a/src/state.c
+++ b/src/state.c
@@ -199,6 +199,7 @@ struct apk_state *apk_state_new(struct apk_database *db)
state->refs = 1;
state->num_names = db->name_id;
state->db = db;
+ state->print_ok = 1;
list_init(&state->change_list_head);
apk_name_array_init(&state->missing);
@@ -235,6 +236,7 @@ static int apk_state_add_change(struct apk_state *state,
list_init(&change->change_list);
list_add_tail(&change->change_list, &state->change_list_head);
+ state->num_changes++;
change->oldpkg = oldpkg;
change->newpkg = newpkg;
@@ -873,13 +875,11 @@ int apk_state_commit(struct apk_state *state,
{
struct progress prog;
struct apk_change *change;
- int r = 0, size_diff = 0, toplevel = FALSE, deleteonly = TRUE;
- int n = 0, numpkg = 0;
+ int n = 0, r = 0, size_diff = 0, toplevel = FALSE, deleteonly = TRUE;
/* Count what needs to be done */
memset(&prog, 0, sizeof(prog));
list_for_each_entry(change, &state->change_list_head, change_list) {
- numpkg++;
if (change->newpkg == NULL) {
if (change->oldpkg->name->flags & APK_NAME_TOPLEVEL)
toplevel = TRUE;
@@ -935,7 +935,7 @@ int apk_state_commit(struct apk_state *state,
n = 0;
list_for_each_entry(change, &state->change_list_head, change_list) {
n++;
- apk_print_change(db, change->oldpkg, change->newpkg, n, numpkg);
+ apk_print_change(db, change->oldpkg, change->newpkg, n, state->num_changes);
prog.pkg = change->newpkg;
if (!(apk_flags & APK_SIMULATE)) {
@@ -963,7 +963,7 @@ update_state:
apk_db_run_triggers(db);
apk_db_write_config(db);
- if (r == 0)
+ if (r == 0 && state->print_ok)
apk_message("OK: %d packages, %d dirs, %d files",
db->installed.stats.packages,
db->installed.stats.dirs,
diff --git a/src/upgrade.c b/src/upgrade.c
index be6a499..8763cb2 100644
--- a/src/upgrade.c
+++ b/src/upgrade.c
@@ -30,6 +30,46 @@ static int upgrade_parse(void *ctx, struct apk_db_options *dbopts,
return 0;
}
+int apk_do_self_upgrade(struct apk_database *db, struct apk_state *state)
+{
+ struct apk_dependency dep;
+ int r, i;
+
+ apk_dep_from_blob(&dep, db, APK_BLOB_STR("apk-tools"));
+
+ if (apk_flags & APK_PREFER_AVAILABLE) {
+ for (i = 0; i < db->world->num; i++) {
+ struct apk_dependency *dep0 = &db->world->item[i];
+ if (dep0->name != dep.name)
+ continue;
+ dep0->version = apk_blob_atomize(APK_BLOB_NULL);
+ dep0->result_mask = APK_VERSION_EQUAL | APK_VERSION_LESS | APK_VERSION_GREATER;
+ break;
+ }
+ }
+
+ r = apk_state_lock_dependency(state, &dep);
+ if (r != 0 || state->num_changes == 0)
+ return r;
+
+ if (apk_flags & APK_SIMULATE) {
+ apk_warning("This simulation is not reliable as apk-tools upgrade is available.");
+ return 0;
+ }
+
+ apk_message("Uprading first to new apk-tools:");
+ state->print_ok = 0;
+ r = apk_state_commit(state, db);
+ apk_state_unref(state);
+ apk_db_close(db);
+
+ apk_message("Performing rest of the operation:");
+ execvp(apk_argv[0], apk_argv);
+
+ apk_error("PANIC! Failed to re-execute new apk-tools!");
+ exit(1);
+}
+
static int upgrade_main(void *ctx, struct apk_database *db, int argc, char **argv)
{
struct apk_state *state = NULL;
@@ -38,12 +78,18 @@ static int upgrade_main(void *ctx, struct apk_database *db, int argc, char **arg
int i, r = 0;
apk_flags |= APK_UPGRADE;
-
apk_name_array_init(&missing);
+
state = apk_state_new(db);
if (state == NULL)
goto err;
+ r = apk_do_self_upgrade(db, state);
+ if (r != 0) {
+ apk_state_print_errors(state);
+ goto err;
+ }
+
for (i = 0; i < db->world->num; i++) {
struct apk_dependency *dep = &db->world->item[i];
if (dep->version != null_atom &&