diff --git a/include/swupd.h b/include/swupd.h index 350bdd85..e19683f8 100644 --- a/include/swupd.h +++ b/include/swupd.h @@ -184,7 +184,7 @@ extern struct manifest *load_mom(int version); extern struct manifest *load_manifest(int current, int version, struct file *file, struct manifest *mom, bool header_only); extern struct list *create_update_list(struct manifest *current, struct manifest *server); extern void link_manifests(struct manifest *m1, struct manifest *m2); -extern void link_submanifests(struct manifest *m1, struct manifest *m2, struct list *subs1, struct list *subs2); +extern void link_submanifests(struct manifest *m1, struct manifest *m2, struct list *subs1, struct list *subs2, bool server); extern void free_manifest(struct manifest *manifest); extern void remove_manifest_files(char *filename, int version, char *hash); diff --git a/src/manifest.c b/src/manifest.c index f4805e26..88ebad75 100644 --- a/src/manifest.c +++ b/src/manifest.c @@ -850,7 +850,7 @@ void link_manifests(struct manifest *m1, struct manifest *m2) /* m1: old manifest * m2: new manifest */ -void link_submanifests(struct manifest *m1, struct manifest *m2, struct list *subs1, struct list *subs2) +void link_submanifests(struct manifest *m1, struct manifest *m2, struct list *subs1, struct list *subs2, bool server) { struct list *list1, *list2; struct file *file1, *file2; @@ -878,14 +878,15 @@ void link_submanifests(struct manifest *m1, struct manifest *m2, struct list *su list1 = list1->next; list2 = list2->next; + /* server (new) manifests will only bring in new bundles */ if (file2->last_change > m1->version && !file2->is_deleted) { - if (subbed1 && subbed2) { + if (!server && subbed1 && subbed2) { account_changed_bundle(); } else if (!subbed1 && subbed2) { account_new_bundle(); } } - if (file2->last_change > m1->version && file2->is_deleted) { + if (!server && (file2->last_change > m1->version && file2->is_deleted)) { if (subbed1) { account_deleted_bundle(); } diff --git a/src/update.c b/src/update.c index f23e906d..c10f2bd8 100644 --- a/src/update.c +++ b/src/update.c @@ -321,21 +321,11 @@ load_server_manifests: retries = 0; timeout = 10; - // The new subscription is seeded from the list of currently installed bundles - latest_subs = list_clone(current_subs); - ret = add_included_manifests(server_manifest, &latest_subs); - if (ret) { - ret = EMANIFEST_LOAD; - goto clean_exit; - } - - set_subscription_versions(server_manifest, current_manifest, &latest_subs); - - link_submanifests(current_manifest, server_manifest, current_subs, latest_subs); - /* updating subscribed manifests is done as part of recurse_manifest */ - /* read the current collective of manifests that we are subscribed to */ + /* Read the current collective of manifests that we are subscribed to. + * First load up the old (current) manifests. Statedir could have been cleared + * or corrupt, so don't assume things are already there. */ current_manifest->submanifests = recurse_manifest(current_manifest, current_subs, NULL); if (!current_manifest->submanifests) { if (retries < MAX_TRIES) { @@ -349,12 +339,26 @@ load_server_manifests: } retries = 0; timeout = 10; + /* consolidate the current collective manifests down into one in memory */ current_manifest->files = files_from_bundles(current_manifest->submanifests); current_manifest->files = consolidate_files(current_manifest->files); - /* read the new collective of manifests that we are subscribed to */ + latest_subs = list_clone(current_subs); + set_subscription_versions(server_manifest, current_manifest, &latest_subs); + link_submanifests(current_manifest, server_manifest, current_subs, latest_subs, false); + /* The new subscription is seeded from the list of currently installed bundles + * This calls add_subscriptions which recurses for new includes */ + grabtime_start(×, "Add Included Manifests"); + ret = add_included_manifests(server_manifest, current_version, &latest_subs); + grabtime_stop(×); + if (ret) { + ret = EMANIFEST_LOAD; + goto clean_exit; + } + + /* read the new collective of manifests that we are subscribed to in the new MoM */ server_manifest->submanifests = recurse_manifest(server_manifest, latest_subs, NULL); if (!server_manifest->submanifests) { if (retries < MAX_TRIES) { @@ -373,6 +377,9 @@ load_server_manifests: server_manifest->files = consolidate_files(server_manifest->files); + set_subscription_versions(server_manifest, current_manifest, &latest_subs); + link_submanifests(current_manifest, server_manifest, current_subs, latest_subs, true); + /* prepare for an update process based on comparing two in memory manifests */ link_manifests(current_manifest, server_manifest); #if 0