/* tristate return, -1 for errors, 1 for no errors but no new subscriptions, 0 for no errors and new subscriptions */ int add_subscriptions(struct list *bundles, int current_version, struct manifest *mom) { bool new_bundles = false; char *bundle; int ret; int retries = 0; int timeout = 10; struct file *file; struct list *iter; struct manifest *manifest; srand(time(NULL)); iter = list_head(bundles); while (iter) { bundle = iter->data; iter = iter->next; file = search_bundle_in_manifest(mom, bundle); if (!file) { printf("%s bundle name is invalid, skipping it...\n", bundle); continue; } retry_manifest_download: manifest = load_manifest(current_version, file->last_change, file, mom); if (!manifest) { if (retries < MAX_TRIES) { increment_retries(&retries, &timeout); goto retry_manifest_download; } printf("Unable to download manifest %s version %d, exiting now\n", bundle, file->last_change); ret = -1; goto out; } if (!manifest) { printf("Unable to load manifest %s version %d, exiting now\n", bundle, file->last_change); ret = -1; goto out; } if (manifest->includes) { ret = add_subscriptions(manifest->includes, current_version, mom); if (ret == -1) { free_manifest(manifest); goto out; } else if (ret == 0) { new_bundles = true; } } free_manifest(manifest); if (is_tracked_bundle(bundle)) { continue; } if (component_subscribed(bundle)) { continue; } create_and_append_subscription(bundle); new_bundles = true; } if (new_bundles) { ret = 0; } else { ret = 1; } out: return ret; }
/* do_search() * Description: Perform a lookup of the specified search string in all Clear manifests * for the current os release. */ static void do_search(struct manifest *MoM, char search_type, char *search_term) { struct list *list; struct list *sublist; struct file *file; struct file *subfile; struct list *bundle_info = NULL; struct manifest *subman = NULL; int i; bool done_with_bundle, done_with_search = false; bool hit = false; bool man_load_failures = false; long hit_count = 0; list = MoM->manifests; while (list && !done_with_search) { file = list->data; list = list->next; done_with_bundle = false; /* Load sub-manifest */ subman = load_manifest(file->last_change, file, MoM, false); if (!subman) { fprintf(stderr, "Failed to load manifest %s\n", file->filename); man_load_failures = true; continue; } /* record contentsize and includes for install size calculation */ struct bundle_result *bundle = NULL; bundle = calloc(sizeof(struct bundle_result), 1); ON_NULL_ABORT(bundle); /* copy relevant information over for future use */ strncpy(bundle->bundle_name, subman->component, BUNDLE_NAME_MAXLEN - 1); bundle->topsize = subman->contentsize; /* do a deep copy of the includes list */ bundle->includes = list_deep_clone_strs(subman->includes); bundle_info = list_prepend_data(bundle_info, bundle); if (display_files) { /* Display bundle name. Marked up for pattern matchability */ fprintf(stderr, "--Bundle: %s--\n", file->filename); } /* Loop through sub-manifest, searching for files matching the desired pattern */ sublist = subman->files; while (sublist && !done_with_bundle) { subfile = sublist->data; sublist = sublist->next; if ((!subfile->is_file) && (!subfile->is_link)) { continue; } if (display_files) { /* Just display filename */ file_search(subfile->filename, NULL, NULL); } else if (search_type == '0') { /* Search for exact match, not path addition */ if (file_search(subfile->filename, "", search_term)) { report_find(file->filename, subfile->filename, search_term); hit = true; } } else if (search_type == 'l') { /* Check each supported library path for a match */ for (i = 0; lib_paths[i] != NULL; i++) { if (file_search(subfile->filename, lib_paths[i], search_term)) { report_find(file->filename, subfile->filename, search_term); hit = true; } } } else if (search_type == 'b') { /* Check each supported path for binaries */ for (i = 0; bin_paths[i] != NULL; i++) { if (file_search(subfile->filename, bin_paths[i], search_term)) { report_find(file->filename, subfile->filename, search_term); hit = true; } } } else { fprintf(stderr, "Unrecognized search type. -b or -l supported\n"); done_with_search = true; break; } /* Determine the level of completion we've reached */ if (hit) { if (scope == 'b') { done_with_bundle = true; } else if (scope == 'o') { done_with_bundle = true; done_with_search = true; } hit_count++; } hit = false; } free_manifest(subman); } if (!hit_count) { fprintf(stderr, "Search term not found.\n"); } bool display_size = (scope != 'o' && !man_load_failures); if (display_size) { apply_size_penalty(bundle_info); } list_free_list_and_data(bundle_info, free_bundle_result_data); if (num_results != INT_MAX) { sort_results(); } else { results = list_sort(results, bundle_size_cmp); } if (csv_format) { print_csv_results(); } else { print_final_results(display_size); } list_free_list_and_data(results, free_bundle_result_data); }
/* download_manifests() * Description: To search Clear bundles for a particular entry, a complete set of * manifests must be downloaded. This function does so, asynchronously, using * the curl_multi interface */ static int download_manifests(struct manifest **MoM, struct list **subs) { struct list *list = NULL; struct file *file = NULL; char *tarfile, *untard_file, *url = NULL; struct manifest *subMan = NULL; int current_version; int ret = 0; double size; bool did_download = false; current_version = get_current_version(path_prefix); if (current_version < 0) { fprintf(stderr, "Error: Unable to determine current OS version\n"); return ECURRENT_VERSION; } *MoM = load_mom(current_version, false, false, NULL); if (!(*MoM)) { fprintf(stderr, "Cannot load official manifest MoM for version %i\n", current_version); return EMOM_LOAD; } list = (*MoM)->manifests; size = query_total_download_size(list); if (size == -1) { fprintf(stderr, "Downloading manifests. Expect a delay, up to 100MB may be downloaded\n"); } else if (size > 0) { fprintf(stderr, "Downloading Clear Linux manifests\n"); fprintf(stderr, " %.2f MB total...\n\n", size); } while (list) { file = list->data; list = list->next; create_and_append_subscription(subs, file->filename); string_or_die(&untard_file, "%s/%i/Manifest.%s", state_dir, file->last_change, file->filename); string_or_die(&tarfile, "%s/%i/Manifest.%s.tar", state_dir, file->last_change, file->filename); if (access(untard_file, F_OK) == -1) { /* Do download */ subMan = load_manifest(file->last_change, file, *MoM, false); if (!subMan) { fprintf(stderr, "Cannot load official manifest MoM for version %i\n", current_version); } else { did_download = true; } free_manifest(subMan); } if (access(untard_file, F_OK) == -1) { string_or_die(&url, "%s/%i/Manifest.%s.tar", content_url, current_version, file->filename); fprintf(stderr, "Error: Failure reading from %s\n", url); free_string(&url); } unlink(tarfile); free_string(&untard_file); free_string(&tarfile); } if (did_download) { fprintf(stderr, "Completed manifests download.\n\n"); } return ret; }
/* do_search() * Description: Perform a lookup of the specified search string in all Clear manifests * for the current os release. */ static void do_search(struct manifest *MoM, char search_type, char *search_term) { struct list *list; struct list *sublist; struct file *file; struct file *subfile; struct manifest *subman = NULL; int i; bool done_with_bundle, done_with_search = false; bool hit = false; long hit_count = 0; list = MoM->manifests; while (list && !done_with_search) { file = list->data; list = list->next; done_with_bundle = false; /* Load sub-manifest */ subman = load_manifest(file->last_change, file->last_change, file, MoM); if (!subman) { printf("Failed to load manifest %s\n", file->filename); continue; } if (display_files) { /* Display bundle name. Marked up for pattern matchability */ printf("--Bundle: %s--\n", file->filename); } /* Loop through sub-manifest, searching for files matching the desired pattern */ sublist = subman->files; while (sublist && !done_with_bundle) { subfile = sublist->data; sublist = sublist->next; if ((!subfile->is_file) && (!subfile->is_link)) { continue; } if (display_files) { /* Just display filename */ file_search(subfile->filename, NULL, NULL); } else if (search_type == '0') { /* Search for exact match, not path addition */ if (file_search(subfile->filename, "", search_term)) { report_find(file->filename, subfile->filename); hit = true; } } else if (search_type == 'l') { /* Check each supported library path for a match */ for (i = 0; lib_paths[i] != NULL; i++) { if (file_search(subfile->filename, lib_paths[i], search_term)) { report_find(file->filename, subfile->filename); hit = true; } } } else if (search_type == 'b') { /* Check each supported path for binaries */ for (i = 0; bin_paths[i] != NULL; i++) { if (file_search(subfile->filename, bin_paths[i], search_term)) { report_find(file->filename, subfile->filename); hit = true; } } } else { printf("Unrecognized search type. -b or -l supported\n"); done_with_search = true; break; } /* Determine the level of completion we've reached */ if (hit) { if (scope == 'b') { done_with_bundle = true; } else if (scope == 'o') { done_with_bundle = true; done_with_search = true; } hit_count++; } hit = false; } free_manifest(subman); } if (!hit_count) { printf("Search term not found.\n"); } }