diff --git a/src/manifest.c b/src/manifest.c index a31657657..bbab400a7 100644 --- a/src/manifest.c +++ b/src/manifest.c @@ -609,6 +609,11 @@ void remove_manifest_files(char *filename, int version, char *hash) } } +struct manifest *load_mom(int version, bool latest, bool mix_exists) +{ + return load_mom_err(version, latest, mix_exists, NULL); +} + /* Loads the MoM (Manifest of Manifests) for VERSION. * * Implementation note: MoMs are not huge so deltas do not give much benefit, @@ -618,9 +623,10 @@ void remove_manifest_files(char *filename, int version, char *hash) * getting the whole MoM and verifying it. * * Note that if the manifest fails to download, or if the manifest fails to be - * loaded into memory, this function will return NULL. + * loaded into memory, this function will return NULL. If err is passed, it is set + * with the error code. */ -struct manifest *load_mom(int version, bool latest, bool mix_exists) +struct manifest *load_mom_err(int version, bool latest, bool mix_exists, int *err) { struct manifest *manifest = NULL; int ret = 0; @@ -635,6 +641,9 @@ struct manifest *load_mom(int version, bool latest, bool mix_exists) ret = retrieve_manifests(version, version, "MoM", NULL, mix_exists); if (ret != 0) { fprintf(stderr, "Failed to retrieve %d MoM manifest\n", version); + if (err) { + *err = ret; + } return NULL; } @@ -647,7 +656,10 @@ struct manifest *load_mom(int version, bool latest, bool mix_exists) goto verify_mom; } fprintf(stderr, "Failed to load %d MoM manifest\n", version); - goto out; + if (err) { + *err = EMANIFEST_LOAD; + } + return NULL; } string_or_die(&filename, "%s/%i/Manifest.MoM", state_dir, version); @@ -671,6 +683,9 @@ struct manifest *load_mom(int version, bool latest, bool mix_exists) free_string(&filename); free_string(&url); free_manifest(manifest); + if (err) { + *err = ESIGNATURE; + } return NULL; } fprintf(stderr, "FAILED TO VERIFY SIGNATURE OF Manifest.MoM. Operation proceeding due to\n" @@ -698,9 +713,6 @@ struct manifest *load_mom(int version, bool latest, bool mix_exists) free_string(&filename); free_string(&url); return manifest; - -out: - return NULL; } /* Loads the MANIFEST for bundle associated with FILE at VERSION, referenced by diff --git a/src/swupd.h b/src/swupd.h index 24eb062b1..ee8b7dfb2 100644 --- a/src/swupd.h +++ b/src/swupd.h @@ -208,6 +208,7 @@ extern void apply_heuristics(struct file *file); extern int file_sort_filename(const void *a, const void *b); extern int file_sort_filename_reverse(const void *a, const void *b); +extern struct manifest *load_mom_err(int version, bool latest, bool mix_exists, int *err); extern struct manifest *load_mom(int version, bool latest, bool mix_exists); extern struct manifest *load_manifest(int current, int version, struct file *file, struct manifest *mom, bool header_only); extern struct manifest *load_manifest_full(int version, bool mix); diff --git a/src/update.c b/src/update.c index 4004a0e8f..7157fd892 100644 --- a/src/update.c +++ b/src/update.c @@ -423,15 +423,20 @@ static int main_update() load_server_mom: grabtime_stop(×); // Close step 2 grabtime_start(×, "Recurse and Consolidate Manifests"); - server_manifest = load_mom(server_version, true, mix_exists); + int server_manifest_err; + server_manifest = load_mom_err(server_version, true, mix_exists, &server_manifest_err); if (!server_manifest) { - if (retries < MAX_TRIES) { + if (retries < MAX_TRIES && server_manifest_err != -ENET404) { increment_retries(&retries, &timeout); fprintf(stderr, "Retry #%d downloading server Manifests\n", retries); goto load_server_mom; } fprintf(stderr, "Failure retrieving manifest from server\n"); - fprintf(stderr, "Unable to load manifest after retrying (config or network problem?)\n"); + if (server_manifest_err == -ENET404) { + fprintf(stderr, "Version %d not available\n", server_version); + } else { + fprintf(stderr, "Unable to load manifest after retrying (config or network problem?)\n"); + } ret = EMOM_NOTFOUND; goto clean_exit; }