END_TEST static void check_filelist(Pool *pool) { Dataiterator di; int count; Id last_found_solvable = 0; dataiterator_init(&di, pool, 0, 0, SOLVABLE_FILELIST, "/usr/bin/ste", SEARCH_STRING | SEARCH_FILES | SEARCH_COMPLETE_FILELIST); for (count = 0; dataiterator_step(&di); ++count) last_found_solvable = di.solvid; fail_unless(count == 1); fail_if(last_found_solvable == 0); dataiterator_free(&di); dataiterator_init(&di, pool, 0, last_found_solvable, SOLVABLE_FILELIST, "/", SEARCH_STRINGSTART | SEARCH_FILES); for (count = 0; dataiterator_step(&di); ++count) fail_if(strncmp(di.kv.str, "/usr/bin/", strlen("/usr/bin/"))); fail_unless(count == 3); dataiterator_free(&di); dataiterator_init(&di, pool, 0, 0, SOLVABLE_FILELIST, "/usr/lib/python2.7/site-packages/tour/today.pyc", SEARCH_STRING | SEARCH_FILES | SEARCH_COMPLETE_FILELIST); for (count = 0; dataiterator_step(&di); ++count) ; fail_unless(count == 1); dataiterator_free(&di); }
static void susetags_add_ext(Repo *repo, Repodata *data) { Pool *pool = repo->pool; Dataiterator di; char ext[3]; Id handle, filechksumtype; const unsigned char *filechksum; dataiterator_init(&di, pool, repo, SOLVID_META, SUSETAGS_FILE_NAME, 0, 0); dataiterator_prepend_keyname(&di, SUSETAGS_FILE); while (dataiterator_step(&di)) { if (strncmp(di.kv.str, "packages.", 9) != 0) continue; if (!strcmp(di.kv.str + 9, "gz")) continue; if (!di.kv.str[9] || !di.kv.str[10] || (di.kv.str[11] && di.kv.str[11] != '.')) continue; ext[0] = di.kv.str[9]; ext[1] = di.kv.str[10]; ext[2] = 0; if (!strcmp(ext, "en")) continue; if (!susetags_find(repo, di.kv.str, &filechksum, &filechksumtype)) continue; handle = repodata_new_handle(data); repodata_set_str(data, handle, SUSETAGS_FILE_NAME, di.kv.str); if (filechksumtype) repodata_set_bin_checksum(data, handle, SUSETAGS_FILE_CHECKSUM, filechksumtype, filechksum); add_ext_keys(data, handle, ext); repodata_add_flexarray(data, SOLVID_META, REPOSITORY_EXTERNAL, handle); } dataiterator_free(&di); }
HyAdvisoryList hy_package_get_advisories(HyPackage pkg, int cmp_type) { Dataiterator di; Id evr; int cmp; HyAdvisory advisory; Pool *pool = package_pool(pkg); HyAdvisoryList advisorylist = advisorylist_create(pool); Solvable *s = get_solvable(pkg); dataiterator_init(&di, pool, 0, 0, UPDATE_COLLECTION_NAME, pool_id2str(pool, s->name), SEARCH_STRING); dataiterator_prepend_keyname(&di, UPDATE_COLLECTION); while (dataiterator_step(&di)) { dataiterator_setpos_parent(&di); if (pool_lookup_id(pool, SOLVID_POS, UPDATE_COLLECTION_ARCH) != s->arch) continue; evr = pool_lookup_id(pool, SOLVID_POS, UPDATE_COLLECTION_EVR); if (!evr) continue; cmp = pool_evrcmp(pool, evr, s->evr, EVRCMP_COMPARE); if ((cmp > 0 && (cmp_type & HY_GT)) || (cmp < 0 && (cmp_type & HY_LT)) || (cmp == 0 && (cmp_type & HY_EQ))) { advisory = advisory_create(pool, di.solvid); advisorylist_add(advisorylist, advisory); hy_advisory_free(advisory); dataiterator_skip_solvable(&di); } } dataiterator_free(&di); return advisorylist; }
/** * dnf_package_get_delta_from_evr: * @pkg: a #DnfPackage instance. * @from_evr: the EVR string of what's installed * * Gets the package delta for the package given an existing EVR. * * Returns: a #DnfPackageDelta, or %NULL * * Since: 0.7.0 */ DnfPackageDelta * dnf_package_get_delta_from_evr(DnfPackage *pkg, const char *from_evr) { Pool *pool = dnf_package_get_pool(pkg); Solvable *s = get_solvable(pkg); DnfPackageDelta *delta = NULL; Dataiterator di; const char *name = dnf_package_get_name(pkg); dataiterator_init(&di, pool, s->repo, SOLVID_META, DELTA_PACKAGE_NAME, name, SEARCH_STRING); dataiterator_prepend_keyname(&di, REPOSITORY_DELTAINFO); while (dataiterator_step(&di)) { dataiterator_setpos_parent(&di); if (pool_lookup_id(pool, SOLVID_POS, DELTA_PACKAGE_EVR) != s->evr || pool_lookup_id(pool, SOLVID_POS, DELTA_PACKAGE_ARCH) != s->arch) continue; const char * base_evr = pool_id2str(pool, pool_lookup_id(pool, SOLVID_POS, DELTA_BASE_EVR)); if (strcmp(base_evr, from_evr)) continue; // we have the right delta info, set up DnfPackageDelta *and break out: delta = dnf_packagedelta_new(pool); break; } dataiterator_free(&di); return delta; }
/** * dnf_package_get_advisories: * @pkg: a #DnfPackage instance. * * Gets the list of advisories for the package. * * Returns: (transfer container) (element-type DnfAdvisory): a list * * Since: 0.7.0 */ GPtrArray * dnf_package_get_advisories(DnfPackage *pkg, int cmp_type) { Dataiterator di; Id evr; int cmp; DnfAdvisory *advisory; Pool *pool = dnf_package_get_pool(pkg); DnfSack *sack = dnf_package_get_sack(pkg); GPtrArray *advisorylist = g_ptr_array_new(); Solvable *s = get_solvable(pkg); dataiterator_init(&di, pool, 0, 0, UPDATE_COLLECTION_NAME, pool_id2str(pool, s->name), SEARCH_STRING); dataiterator_prepend_keyname(&di, UPDATE_COLLECTION); while (dataiterator_step(&di)) { dataiterator_setpos_parent(&di); if (pool_lookup_id(pool, SOLVID_POS, UPDATE_COLLECTION_ARCH) != s->arch) continue; evr = pool_lookup_id(pool, SOLVID_POS, UPDATE_COLLECTION_EVR); if (!evr) continue; cmp = pool_evrcmp(pool, evr, s->evr, EVRCMP_COMPARE); if ((cmp > 0 && (cmp_type & HY_GT)) || (cmp < 0 && (cmp_type & HY_LT)) || (cmp == 0 && (cmp_type & HY_EQ))) { advisory = dnf_advisory_new(sack, di.solvid); g_ptr_array_add(advisorylist, advisory); dataiterator_skip_solvable(&di); } } dataiterator_free(&di); return advisorylist; }
/** * dnf_advisory_get_packages: * @advisory: a #DnfAdvisory instance. * * Gets any packages referenced by the advisory. * * Returns: (transfer container) (element-type DnfAdvisoryPkg): a list of packages * * Since: 0.7.0 */ GPtrArray * dnf_advisory_get_packages(DnfAdvisory *advisory) { DnfAdvisoryPrivate *priv = GET_PRIVATE(advisory); Dataiterator di; DnfAdvisoryPkg *pkg; GPtrArray *pkglist = g_ptr_array_new_with_free_func((GDestroyNotify) g_object_unref); dataiterator_init(&di, priv->pool, 0, priv->a_id, UPDATE_COLLECTION, 0, 0); while (dataiterator_step(&di)) { dataiterator_setpos(&di); pkg = dnf_advisorypkg_new(); dnf_advisorypkg_set_name(pkg, pool_lookup_str(priv->pool, SOLVID_POS, UPDATE_COLLECTION_NAME)); dnf_advisorypkg_set_evr(pkg, pool_lookup_str(priv->pool, SOLVID_POS, UPDATE_COLLECTION_EVR)); dnf_advisorypkg_set_arch(pkg, pool_lookup_str(priv->pool, SOLVID_POS, UPDATE_COLLECTION_ARCH)); dnf_advisorypkg_set_filename(pkg, pool_lookup_str(priv->pool, SOLVID_POS, UPDATE_COLLECTION_FILENAME)); g_ptr_array_add(pkglist, pkg); } dataiterator_free(&di); return pkglist; }
static const char * susetags_find(Repo *repo, const char *what, const unsigned char **chksump, Id *chksumtypep) { Pool *pool = repo->pool; Dataiterator di; const char *filename; filename = 0; *chksump = 0; *chksumtypep = 0; dataiterator_init(&di, pool, repo, SOLVID_META, SUSETAGS_FILE_NAME, what, SEARCH_STRING); dataiterator_prepend_keyname(&di, SUSETAGS_FILE); if (dataiterator_step(&di)) { dataiterator_setpos_parent(&di); *chksump = pool_lookup_bin_checksum(pool, SOLVID_POS, SUSETAGS_FILE_CHECKSUM, chksumtypep); filename = what; } dataiterator_free(&di); if (filename && !*chksumtypep) { printf("no %s file checksum!\n", what); filename = 0; } return filename; }
HyAdvisoryPkgList hy_advisory_get_packages(HyAdvisory advisory) { Dataiterator di; HyAdvisoryPkg pkg; Pool *pool = advisory->pool; Id a_id = advisory->a_id; HyAdvisoryPkgList pkglist = advisorypkglist_create(); dataiterator_init(&di, pool, 0, a_id, UPDATE_COLLECTION, 0, 0); while (dataiterator_step(&di)) { dataiterator_setpos(&di); pkg = advisorypkg_create(); advisorypkg_set_string(pkg, HY_ADVISORYPKG_NAME, pool_lookup_str(pool, SOLVID_POS, UPDATE_COLLECTION_NAME)); advisorypkg_set_string(pkg, HY_ADVISORYPKG_EVR, pool_lookup_str(pool, SOLVID_POS, UPDATE_COLLECTION_EVR)); advisorypkg_set_string(pkg, HY_ADVISORYPKG_ARCH, pool_lookup_str(pool, SOLVID_POS, UPDATE_COLLECTION_ARCH)); advisorypkg_set_string(pkg, HY_ADVISORYPKG_FILENAME, pool_lookup_str(pool, SOLVID_POS, UPDATE_COLLECTION_FILENAME)); advisorypkglist_add(pkglist, pkg); hy_advisorypkg_free(pkg); } dataiterator_free(&di); return pkglist; }
static void doquery(Pool *pool, Repo *repo, const char *query) { Id id, type = 0; char qbuf[256]; const char *qp; Dataiterator di; qp = strchr(query, ':'); if (qp) { type = strn2id(pool, query, qp - query, 0); if (!type) exit(0); qp++; } else qp = query; snprintf(qbuf, sizeof(qbuf), "repository:repomd:%s", qp); id = str2id(pool, qbuf, 0); if (!id) exit(0); dataiterator_init(&di, pool, repo, SOLVID_META, id, 0, 0); dataiterator_prepend_keyname(&di, REPOSITORY_REPOMD); while (dataiterator_step(&di)) { if (type) { dataiterator_setpos_parent(&di); if (pool_lookup_id(pool, SOLVID_POS, REPOSITORY_REPOMD_TYPE) != type) continue; } switch (di.key->type) { case REPOKEY_TYPE_ID: case REPOKEY_TYPE_CONSTANTID: printf("%s\n", id2str(pool, di.kv.id)); break; case REPOKEY_TYPE_STR: printf("%s\n", di.kv.str); break; case REPOKEY_TYPE_NUM: printf("%d\n", di.kv.num); break; case REPOKEY_TYPE_SHA1: printf("sha1:%s\n", repodata_chk2str(di.data, di.key->type, (unsigned char *)di.kv.str)); break; case REPOKEY_TYPE_SHA256: printf("sha256:%s\n", repodata_chk2str(di.data, di.key->type, (unsigned char *)di.kv.str)); break; default: break; } } dataiterator_free(&di); }
/** * dnf_advisory_get_references: * @advisory: a #DnfAdvisory instance. * * Gets any references referenced by the advisory. * * Returns: (transfer container) (element-type DnfAdvisoryRef): a list of references * * Since: 0.7.0 */ GPtrArray * dnf_advisory_get_references(DnfAdvisory *advisory) { DnfAdvisoryPrivate *priv = GET_PRIVATE(advisory); Dataiterator di; DnfAdvisoryRef *ref; GPtrArray *reflist = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref); dataiterator_init(&di, priv->pool, 0, priv->a_id, UPDATE_REFERENCE, 0, 0); for (int index = 0; dataiterator_step(&di); index++) { ref = dnf_advisoryref_new(priv->pool, priv->a_id, index); g_ptr_array_add(reflist, ref); } dataiterator_free(&di); return reflist; }
static void queue_di(Pool *pool, Queue *queue, const char *str, int di_key, int flags) { Dataiterator di; int di_flags = SEARCH_STRING; if (flags & HY_ICASE) di_flags |= SEARCH_NOCASE; if (flags & HY_GLOB) di_flags |= SEARCH_GLOB; dataiterator_init(&di, pool, 0, 0, di_key, str, di_flags); while (dataiterator_step(&di)) if (is_package(pool, pool_id2solvable(pool, di.solvid))) queue_push(queue, di.solvid); dataiterator_free(&di); return; }
static void iterate_solvable_dirs(Pool *pool, Id p, void (*cb)(void *, const char *, struct filelistinfo *), void *cbdata) { Repodata *lastdata = 0; Id lastdirid = -1; Dataiterator di; dataiterator_init(&di, pool, 0, p, SOLVABLE_FILELIST, 0, SEARCH_COMPLETE_FILELIST); while (dataiterator_step(&di)) { if (di.data == lastdata && di.kv.id == lastdirid) continue; lastdata = di.data; lastdirid = di.kv.id; cb(cbdata, repodata_dir2str(di.data, di.kv.id, ""), 0); } dataiterator_free(&di); }
HyAdvisoryRefList hy_advisory_get_references(HyAdvisory advisory) { Dataiterator di; HyAdvisoryRef ref; Pool *pool = advisory->pool; Id a_id = advisory->a_id; HyAdvisoryRefList reflist = advisoryreflist_create(); dataiterator_init(&di, pool, 0, a_id, UPDATE_REFERENCE, 0, 0); for (int index = 0; dataiterator_step(&di); index++) { ref = advisoryref_create(pool, a_id, index); advisoryreflist_add(reflist, ref); hy_advisoryref_free(ref); } dataiterator_free(&di); return reflist; }
HyStringArray hy_package_get_files(HyPackage pkg) { Pool *pool = package_pool(pkg); Solvable *s = get_solvable(pkg); Dataiterator di; int len = 0; HyStringArray strs = solv_extend(0, 0, 1, sizeof(char*), BLOCK_SIZE); repo_internalize_trigger(s->repo); dataiterator_init(&di, pool, s->repo, pkg->id, SOLVABLE_FILELIST, NULL, SEARCH_FILES | SEARCH_COMPLETE_FILELIST); while (dataiterator_step(&di)) { strs[len++] = solv_strdup(di.kv.str); strs = solv_extend(strs, len, 1, sizeof(char*), BLOCK_SIZE); } dataiterator_free(&di); strs[len++] = NULL; return strs; }
HyPackageDelta hy_package_get_delta_from_evr(HyPackage pkg, const char *from_evr) { Pool *pool = package_pool(pkg); Solvable *s = get_solvable(pkg); HyPackageDelta delta = NULL; Dataiterator di; Id checksum_type; const unsigned char *checksum; const char *name = hy_package_get_name(pkg); dataiterator_init(&di, pool, s->repo, SOLVID_META, DELTA_PACKAGE_NAME, name, SEARCH_STRING); dataiterator_prepend_keyname(&di, REPOSITORY_DELTAINFO); while (dataiterator_step(&di)) { dataiterator_setpos_parent(&di); if (pool_lookup_id(pool, SOLVID_POS, DELTA_PACKAGE_EVR) != s->evr || pool_lookup_id(pool, SOLVID_POS, DELTA_PACKAGE_ARCH) != s->arch) continue; const char * base_evr = pool_id2str(pool, pool_lookup_id(pool, SOLVID_POS, DELTA_BASE_EVR)); if (strcmp(base_evr, from_evr)) continue; // we have the right delta info, set up HyPackageDelta and break out: delta = delta_create(); delta->location = solv_strdup(pool_lookup_deltalocation(pool, SOLVID_POS, 0)); delta->baseurl = solv_strdup(pool_lookup_str(pool, SOLVID_POS, DELTA_LOCATION_BASE)); delta->downloadsize = pool_lookup_num(pool, SOLVID_POS, DELTA_DOWNLOADSIZE, 0); checksum = pool_lookup_bin_checksum(pool, SOLVID_POS, DELTA_CHECKSUM, &checksum_type); if (checksum) { delta->checksum_type = checksumt_l2h(checksum_type); delta->checksum = solv_memdup((void*)checksum, checksum_type2length(delta->checksum_type)); } break; } dataiterator_free(&di); return delta; }
END_TEST static void check_prestoinfo(Pool *pool) { Dataiterator di; dataiterator_init(&di, pool, NULL, SOLVID_META, DELTA_PACKAGE_NAME, "tour", SEARCH_STRING); dataiterator_prepend_keyname(&di, REPOSITORY_DELTAINFO); fail_unless(dataiterator_step(&di)); dataiterator_setpos_parent(&di); const char *attr; attr = pool_lookup_str(pool, SOLVID_POS, DELTA_SEQ_NAME); ck_assert_str_eq(attr, "tour"); attr = pool_lookup_str(pool, SOLVID_POS, DELTA_SEQ_EVR); ck_assert_str_eq(attr, "4-5"); attr = pool_lookup_str(pool, SOLVID_POS, DELTA_LOCATION_DIR); ck_assert_str_eq(attr, "drpms"); dataiterator_free(&di); return; }
int main(int argc, char **argv) { Pool *pool; Repo *commandlinerepo = 0; Id *commandlinepkgs = 0; Id p; struct repoinfo *repoinfos, installedrepoinfo; int nrepoinfos = 0; int mainmode = 0, mode = 0; int i, newpkgs; Queue job, checkq; Solver *solv = 0; Transaction *trans; FILE **newpkgsfps; Queue repofilter; Queue kindfilter; Queue archfilter; int archfilter_src = 0; int cleandeps = 0; int forcebest = 0; char *rootdir = 0; char *keyname = 0; int keyname_depstr = 0; int debuglevel = 0; int answer, acnt = 0; argc--; argv++; while (argc && !strcmp(argv[0], "-d")) { debuglevel++; argc--; argv++; } if (!argv[0]) usage(1); if (!strcmp(argv[0], "install") || !strcmp(argv[0], "in")) { mainmode = MODE_INSTALL; mode = SOLVER_INSTALL; } #if defined(SUSE) || defined(FEDORA) else if (!strcmp(argv[0], "patch")) { mainmode = MODE_PATCH; mode = SOLVER_INSTALL; } #endif else if (!strcmp(argv[0], "erase") || !strcmp(argv[0], "rm")) { mainmode = MODE_ERASE; mode = SOLVER_ERASE; } else if (!strcmp(argv[0], "list") || !strcmp(argv[0], "ls")) { mainmode = MODE_LIST; mode = 0; } else if (!strcmp(argv[0], "info")) { mainmode = MODE_INFO; mode = 0; } else if (!strcmp(argv[0], "search") || !strcmp(argv[0], "se")) { mainmode = MODE_SEARCH; mode = 0; } else if (!strcmp(argv[0], "verify")) { mainmode = MODE_VERIFY; mode = SOLVER_VERIFY; } else if (!strcmp(argv[0], "update") || !strcmp(argv[0], "up")) { mainmode = MODE_UPDATE; mode = SOLVER_UPDATE; } else if (!strcmp(argv[0], "dist-upgrade") || !strcmp(argv[0], "dup")) { mainmode = MODE_DISTUPGRADE; mode = SOLVER_DISTUPGRADE; } else if (!strcmp(argv[0], "repos") || !strcmp(argv[0], "repolist") || !strcmp(argv[0], "lr")) { mainmode = MODE_REPOLIST; mode = 0; } else usage(1); for (;;) { if (argc > 2 && !strcmp(argv[1], "--root")) { rootdir = argv[2]; argc -= 2; argv += 2; } else if (argc > 1 && !strcmp(argv[1], "--clean")) { cleandeps = 1; argc--; argv++; } else if (argc > 1 && !strcmp(argv[1], "--best")) { forcebest = 1; argc--; argv++; } else if (argc > 1 && !strcmp(argv[1], "--depstr")) { keyname_depstr = 1; argc--; argv++; } else if (argc > 2 && !strcmp(argv[1], "--keyname")) { keyname = argv[2]; argc -= 2; argv += 2; } else break; } set_userhome(); pool = pool_create(); pool_set_rootdir(pool, rootdir); #if 0 { const char *langs[] = {"de_DE", "de", "en"}; pool_set_languages(pool, langs, sizeof(langs)/sizeof(*langs)); } #endif pool_setloadcallback(pool, load_stub, 0); #ifdef SUSE pool->nscallback = nscallback; #endif if (debuglevel) pool_setdebuglevel(pool, debuglevel); setarch(pool); pool_set_flag(pool, POOL_FLAG_ADDFILEPROVIDESFILTERED, 1); repoinfos = read_repoinfos(pool, &nrepoinfos); sort_repoinfos(repoinfos, nrepoinfos); if (mainmode == MODE_REPOLIST) { int j = 1; for (i = 0; i < nrepoinfos; i++) { struct repoinfo *cinfo = repoinfos + i; if (!cinfo->enabled) continue; printf("%d: %-20s %s (prio %d)\n", j++, cinfo->alias, cinfo->name, cinfo->priority); } exit(0); } memset(&installedrepoinfo, 0, sizeof(installedrepoinfo)); if (!read_installed_repo(&installedrepoinfo, pool)) exit(1); read_repos(pool, repoinfos, nrepoinfos); /* setup filters */ queue_init(&repofilter); queue_init(&kindfilter); queue_init(&archfilter); while (argc > 1) { if (!strcmp(argv[1], "-i")) { queue_push2(&repofilter, SOLVER_SOLVABLE_REPO | SOLVER_SETREPO, pool->installed->repoid); argc--; argv++; } else if (argc > 2 && (!strcmp(argv[1], "-r") || !strcmp(argv[1], "--repo"))) { Id repoid = find_repo(argv[2], pool, repoinfos, nrepoinfos); if (!repoid) { fprintf(stderr, "%s: no such repo\n", argv[2]); exit(1); } /* SETVENDOR is actually wrong but useful */ queue_push2(&repofilter, SOLVER_SOLVABLE_REPO | SOLVER_SETREPO | SOLVER_SETVENDOR, repoid); argc -= 2; argv += 2; } else if (argc > 2 && !strcmp(argv[1], "--arch")) { if (!strcmp(argv[2], "src") || !strcmp(argv[2], "nosrc")) archfilter_src = 1; queue_push2(&archfilter, SOLVER_SOLVABLE_PROVIDES, pool_rel2id(pool, 0, pool_str2id(pool, argv[2], 1), REL_ARCH, 1)); argc -= 2; argv += 2; } else if (argc > 2 && (!strcmp(argv[1], "-t") || !strcmp(argv[1], "--type"))) { const char *kind = argv[2]; if (!strcmp(kind, "srcpackage")) { /* hey! should use --arch! */ queue_push2(&archfilter, SOLVER_SOLVABLE_PROVIDES, pool_rel2id(pool, 0, ARCH_SRC, REL_ARCH, 1)); archfilter_src = 1; argc -= 2; argv += 2; continue; } if (!strcmp(kind, "package")) kind = ""; if (!strcmp(kind, "all")) queue_push2(&kindfilter, SOLVER_SOLVABLE_ALL, 0); else queue_push2(&kindfilter, SOLVER_SOLVABLE_PROVIDES, pool_rel2id(pool, 0, pool_str2id(pool, kind, 1), REL_KIND, 1)); argc -= 2; argv += 2; } else break; } if (mainmode == MODE_SEARCH) { Queue sel, q; Dataiterator di; if (argc != 2) usage(1); pool_createwhatprovides(pool); queue_init(&sel); dataiterator_init(&di, pool, 0, 0, 0, argv[1], SEARCH_SUBSTRING|SEARCH_NOCASE); dataiterator_set_keyname(&di, SOLVABLE_NAME); dataiterator_set_search(&di, 0, 0); while (dataiterator_step(&di)) queue_push2(&sel, SOLVER_SOLVABLE, di.solvid); dataiterator_set_keyname(&di, SOLVABLE_SUMMARY); dataiterator_set_search(&di, 0, 0); while (dataiterator_step(&di)) queue_push2(&sel, SOLVER_SOLVABLE, di.solvid); dataiterator_set_keyname(&di, SOLVABLE_DESCRIPTION); dataiterator_set_search(&di, 0, 0); while (dataiterator_step(&di)) queue_push2(&sel, SOLVER_SOLVABLE, di.solvid); dataiterator_free(&di); if (repofilter.count) selection_filter(pool, &sel, &repofilter); queue_init(&q); selection_solvables(pool, &sel, &q); queue_free(&sel); for (i = 0; i < q.count; i++) { Solvable *s = pool_id2solvable(pool, q.elements[i]); printf(" - %s [%s]: %s\n", pool_solvable2str(pool, s), s->repo->name, solvable_lookup_str(s, SOLVABLE_SUMMARY)); } queue_free(&q); exit(0); } /* process command line packages */ if (mainmode == MODE_LIST || mainmode == MODE_INFO || mainmode == MODE_INSTALL) { for (i = 1; i < argc; i++) { if (!is_cmdline_package((const char *)argv[i])) continue; if (access(argv[i], R_OK)) { perror(argv[i]); exit(1); } if (!commandlinepkgs) commandlinepkgs = solv_calloc(argc, sizeof(Id)); if (!commandlinerepo) commandlinerepo = repo_create(pool, "@commandline"); p = add_cmdline_package(commandlinerepo, (const char *)argv[i]); if (!p) { fprintf(stderr, "could not add '%s'\n", argv[i]); exit(1); } commandlinepkgs[i] = p; } if (commandlinerepo) repo_internalize(commandlinerepo); } #if defined(ENABLE_RPMDB) if (pool->disttype == DISTTYPE_RPM) addfileprovides(pool); #endif #ifdef SUSE add_autopackages(pool); #endif pool_createwhatprovides(pool); if (keyname) keyname = solv_dupjoin("solvable:", keyname, 0); queue_init(&job); for (i = 1; i < argc; i++) { Queue job2; int flags, rflags; if (commandlinepkgs && commandlinepkgs[i]) { queue_push2(&job, SOLVER_SOLVABLE, commandlinepkgs[i]); continue; } queue_init(&job2); flags = SELECTION_NAME|SELECTION_PROVIDES|SELECTION_GLOB; flags |= SELECTION_CANON|SELECTION_DOTARCH|SELECTION_REL; if (kindfilter.count) flags |= SELECTION_SKIP_KIND; if (mode == MODE_LIST || archfilter_src) flags |= SELECTION_WITH_SOURCE; if (argv[i][0] == '/') flags |= SELECTION_FILELIST | (mode == MODE_ERASE ? SELECTION_INSTALLED_ONLY : 0); if (!keyname) rflags = selection_make(pool, &job2, argv[i], flags); else { if (keyname_depstr) flags |= SELECTION_MATCH_DEPSTR; rflags = selection_make_matchdeps(pool, &job2, argv[i], flags, pool_str2id(pool, keyname, 1), 0); } if (repofilter.count) selection_filter(pool, &job2, &repofilter); if (archfilter.count) selection_filter(pool, &job2, &archfilter); if (kindfilter.count) selection_filter(pool, &job2, &kindfilter); if (!job2.count) { flags |= SELECTION_NOCASE; if (!keyname) rflags = selection_make(pool, &job2, argv[i], flags); else rflags = selection_make_matchdeps(pool, &job2, argv[i], flags, pool_str2id(pool, keyname, 1), 0); if (repofilter.count) selection_filter(pool, &job2, &repofilter); if (archfilter.count) selection_filter(pool, &job2, &archfilter); if (kindfilter.count) selection_filter(pool, &job2, &kindfilter); if (job2.count) printf("[ignoring case for '%s']\n", argv[i]); } if (!job2.count) { fprintf(stderr, "nothing matches '%s'\n", argv[i]); exit(1); } if (rflags & SELECTION_FILELIST) printf("[using file list match for '%s']\n", argv[i]); if (rflags & SELECTION_PROVIDES) printf("[using capability match for '%s']\n", argv[i]); queue_insertn(&job, job.count, job2.count, job2.elements); queue_free(&job2); } keyname = solv_free(keyname); if (!job.count && (mainmode == MODE_UPDATE || mainmode == MODE_DISTUPGRADE || mainmode == MODE_VERIFY || repofilter.count || archfilter.count || kindfilter.count)) { queue_push2(&job, SOLVER_SOLVABLE_ALL, 0); if (repofilter.count) selection_filter(pool, &job, &repofilter); if (archfilter.count) selection_filter(pool, &job, &archfilter); if (kindfilter.count) selection_filter(pool, &job, &kindfilter); } queue_free(&repofilter); queue_free(&archfilter); queue_free(&kindfilter); if (!job.count && mainmode != MODE_PATCH) { printf("no package matched\n"); exit(1); } if (mainmode == MODE_LIST || mainmode == MODE_INFO) { /* list mode, no solver needed */ Queue q; queue_init(&q); for (i = 0; i < job.count; i += 2) { int j; queue_empty(&q); pool_job2solvables(pool, &q, job.elements[i], job.elements[i + 1]); for (j = 0; j < q.count; j++) { Solvable *s = pool_id2solvable(pool, q.elements[j]); if (mainmode == MODE_INFO) { const char *str; printf("Name: %s\n", pool_solvable2str(pool, s)); printf("Repo: %s\n", s->repo->name); printf("Summary: %s\n", solvable_lookup_str(s, SOLVABLE_SUMMARY)); str = solvable_lookup_str(s, SOLVABLE_URL); if (str) printf("Url: %s\n", str); str = solvable_lookup_str(s, SOLVABLE_LICENSE); if (str) printf("License: %s\n", str); printf("Description:\n%s\n", solvable_lookup_str(s, SOLVABLE_DESCRIPTION)); printf("\n"); } else { #if 1 const char *sum = solvable_lookup_str_lang(s, SOLVABLE_SUMMARY, "de", 1); #else const char *sum = solvable_lookup_str_poollang(s, SOLVABLE_SUMMARY); #endif printf(" - %s [%s]\n", pool_solvable2str(pool, s), s->repo->name); if (sum) printf(" %s\n", sum); } } } queue_free(&q); queue_free(&job); pool_free(pool); free_repoinfos(repoinfos, nrepoinfos); solv_free(commandlinepkgs); exit(0); } #if defined(SUSE) || defined(FEDORA) if (mainmode == MODE_PATCH) add_patchjobs(pool, &job); #endif // add mode for (i = 0; i < job.count; i += 2) { job.elements[i] |= mode; if (mode == SOLVER_UPDATE && pool_isemptyupdatejob(pool, job.elements[i], job.elements[i + 1])) job.elements[i] ^= SOLVER_UPDATE ^ SOLVER_INSTALL; if (cleandeps) job.elements[i] |= SOLVER_CLEANDEPS; if (forcebest) job.elements[i] |= SOLVER_FORCEBEST; } // multiversion test // queue_push2(&job, SOLVER_MULTIVERSION|SOLVER_SOLVABLE_NAME, pool_str2id(pool, "kernel-pae", 1)); // queue_push2(&job, SOLVER_MULTIVERSION|SOLVER_SOLVABLE_NAME, pool_str2id(pool, "kernel-pae-base", 1)); // queue_push2(&job, SOLVER_MULTIVERSION|SOLVER_SOLVABLE_NAME, pool_str2id(pool, "kernel-pae-extra", 1)); #if 0 queue_push2(&job, SOLVER_INSTALL|SOLVER_SOLVABLE_PROVIDES, pool_rel2id(pool, NAMESPACE_LANGUAGE, 0, REL_NAMESPACE, 1)); queue_push2(&job, SOLVER_ERASE|SOLVER_CLEANDEPS|SOLVER_SOLVABLE_PROVIDES, pool_rel2id(pool, NAMESPACE_LANGUAGE, 0, REL_NAMESPACE, 1)); #endif rerunsolver: solv = solver_create(pool); solver_set_flag(solv, SOLVER_FLAG_SPLITPROVIDES, 1); #ifdef FEDORA solver_set_flag(solv, SOLVER_FLAG_ALLOW_VENDORCHANGE, 1); #endif if (mainmode == MODE_ERASE) solver_set_flag(solv, SOLVER_FLAG_ALLOW_UNINSTALL, 1); /* don't nag */ solver_set_flag(solv, SOLVER_FLAG_BEST_OBEY_POLICY, 1); for (;;) { Id problem, solution; int pcnt, scnt; if (!solver_solve(solv, &job)) break; pcnt = solver_problem_count(solv); printf("Found %d problems:\n", pcnt); for (problem = 1; problem <= pcnt; problem++) { int take = 0; printf("Problem %d/%d:\n", problem, pcnt); solver_printprobleminfo(solv, problem); printf("\n"); scnt = solver_solution_count(solv, problem); for (solution = 1; solution <= scnt; solution++) { printf("Solution %d:\n", solution); solver_printsolution(solv, problem, solution); printf("\n"); } for (;;) { char inbuf[128], *ip; printf("Please choose a solution: "); fflush(stdout); *inbuf = 0; if (!(ip = fgets(inbuf, sizeof(inbuf), stdin))) { printf("Abort.\n"); exit(1); } while (*ip == ' ' || *ip == '\t') ip++; if (*ip >= '0' && *ip <= '9') { take = atoi(ip); if (take >= 1 && take <= scnt) break; } if (*ip == 's') { take = 0; break; } if (*ip == 'q') { printf("Abort.\n"); exit(1); } } if (!take) continue; solver_take_solution(solv, problem, take, &job); } } trans = solver_create_transaction(solv); if (!trans->steps.count) { printf("Nothing to do.\n"); transaction_free(trans); solver_free(solv); queue_free(&job); pool_free(pool); free_repoinfos(repoinfos, nrepoinfos); solv_free(commandlinepkgs); exit(1); } /* display transaction to the user and ask for confirmation */ printf("\n"); printf("Transaction summary:\n\n"); transaction_print(trans); #if defined(SUSE) showdiskusagechanges(trans); #endif printf("install size change: %d K\n", transaction_calc_installsizechange(trans)); printf("\n"); acnt = solver_alternatives_count(solv); if (acnt) { if (acnt == 1) printf("Have one alternative:\n"); else printf("Have %d alternatives:\n", acnt); for (i = 1; i <= acnt; i++) { Id id, from; int atype = solver_get_alternative(solv, i, &id, &from, 0, 0, 0); printf(" - %s\n", solver_alternative2str(solv, atype, id, from)); } printf("\n"); answer = yesno("OK to continue (y/n/a)? ", 'a'); } else answer = yesno("OK to continue (y/n)? ", 0); if (answer == 'a') { Queue choicesq; Queue answerq; Id id, from, chosen; int j; queue_init(&choicesq); queue_init(&answerq); for (i = 1; i <= acnt; i++) { int atype = solver_get_alternative(solv, i, &id, &from, &chosen, &choicesq, 0); printf("\n%s\n", solver_alternative2str(solv, atype, id, from)); for (j = 0; j < choicesq.count; j++) { Id p = choicesq.elements[j]; if (p < 0) p = -p; queue_push(&answerq, p); printf("%6d: %s\n", answerq.count, pool_solvid2str(pool, p)); } } queue_free(&choicesq); printf("\n"); for (;;) { char inbuf[128], *ip; int neg = 0; printf("OK to continue (y/n), or number to change alternative: "); fflush(stdout); *inbuf = 0; if (!(ip = fgets(inbuf, sizeof(inbuf), stdin))) { printf("Abort.\n"); exit(1); } while (*ip == ' ' || *ip == '\t') ip++; if (*ip == '-' && ip[1] >= '0' && ip[1] <= '9') { neg = 1; ip++; } if (*ip >= '0' && *ip <= '9') { int take = atoi(ip); if (take > 0 && take <= answerq.count) { Id p = answerq.elements[take - 1]; queue_free(&answerq); queue_push2(&job, (neg ? SOLVER_DISFAVOR : SOLVER_FAVOR) | SOLVER_SOLVABLE_NAME, pool->solvables[p].name); solver_free(solv); solv = 0; goto rerunsolver; break; } } if (*ip == 'n' || *ip == 'y') { answer = *ip == 'n' ? 0 : *ip; break; } } queue_free(&answerq); } if (!answer) { printf("Abort.\n"); transaction_free(trans); solver_free(solv); queue_free(&job); pool_free(pool); free_repoinfos(repoinfos, nrepoinfos); solv_free(commandlinepkgs); exit(1); } /* download all new packages */ queue_init(&checkq); newpkgs = transaction_installedresult(trans, &checkq); newpkgsfps = 0; if (newpkgs) { int downloadsize = 0; for (i = 0; i < newpkgs; i++) { Solvable *s; p = checkq.elements[i]; s = pool_id2solvable(pool, p); downloadsize += solvable_lookup_sizek(s, SOLVABLE_DOWNLOADSIZE, 0); } printf("Downloading %d packages, %d K\n", newpkgs, downloadsize); newpkgsfps = solv_calloc(newpkgs, sizeof(*newpkgsfps)); for (i = 0; i < newpkgs; i++) { const char *loc; Solvable *s; struct repoinfo *cinfo; p = checkq.elements[i]; s = pool_id2solvable(pool, p); if (s->repo == commandlinerepo) { loc = solvable_lookup_location(s, 0); if (!loc) continue; if (!(newpkgsfps[i] = fopen(loc, "r"))) { perror(loc); exit(1); } putchar('.'); continue; } cinfo = s->repo->appdata; if (!cinfo || cinfo->type == TYPE_INSTALLED) { printf("%s: no repository information\n", s->repo->name); exit(1); } loc = solvable_lookup_location(s, 0); if (!loc) continue; /* pseudo package? */ #if defined(ENABLE_RPMDB) if (pool->installed && pool->installed->nsolvables) { if ((newpkgsfps[i] = trydeltadownload(s, loc)) != 0) { putchar('d'); fflush(stdout); continue; /* delta worked! */ } } #endif if ((newpkgsfps[i] = downloadpackage(s, loc)) == 0) { printf("\n%s: %s not found in repository\n", s->repo->name, loc); exit(1); } putchar('.'); fflush(stdout); } putchar('\n'); } #if defined(ENABLE_RPMDB) && (defined(SUSE) || defined(FEDORA) || defined(MANDRIVA) || defined(MAGEIA)) /* check for file conflicts */ if (newpkgs) { Queue conflicts; queue_init(&conflicts); if (checkfileconflicts(pool, &checkq, newpkgs, newpkgsfps, &conflicts)) { if (yesno("Re-run solver (y/n/q)? ", 0)) { for (i = 0; i < newpkgs; i++) if (newpkgsfps[i]) fclose(newpkgsfps[i]); newpkgsfps = solv_free(newpkgsfps); solver_free(solv); solv = 0; pool_add_fileconflicts_deps(pool, &conflicts); queue_free(&conflicts); goto rerunsolver; } } queue_free(&conflicts); } #endif /* and finally commit the transaction */ printf("Committing transaction:\n\n"); transaction_order(trans, 0); for (i = 0; i < trans->steps.count; i++) { int j; FILE *fp; Id type; p = trans->steps.elements[i]; type = transaction_type(trans, p, SOLVER_TRANSACTION_RPM_ONLY); switch(type) { case SOLVER_TRANSACTION_ERASE: printf("erase %s\n", pool_solvid2str(pool, p)); commit_transactionelement(pool, type, p, 0); break; case SOLVER_TRANSACTION_INSTALL: case SOLVER_TRANSACTION_MULTIINSTALL: printf("install %s\n", pool_solvid2str(pool, p)); for (j = 0; j < newpkgs; j++) if (checkq.elements[j] == p) break; fp = j < newpkgs ? newpkgsfps[j] : 0; if (!fp) continue; commit_transactionelement(pool, type, p, fp); fclose(fp); newpkgsfps[j] = 0; break; default: break; } } for (i = 0; i < newpkgs; i++) if (newpkgsfps[i]) fclose(newpkgsfps[i]); solv_free(newpkgsfps); queue_free(&checkq); transaction_free(trans); solver_free(solv); queue_free(&job); pool_free(pool); free_repoinfos(repoinfos, nrepoinfos); solv_free(commandlinepkgs); exit(0); }
/* before calling the expensive findfileconflicts_cb we check if any of * the files match. This only makes sense when cbdata->create is off. */ static int precheck_solvable_files(struct cbdata *cbdata, Pool *pool, Id p) { Dataiterator di; Id hx, qx; Hashval h, hh; int found = 0; int aliases = cbdata->aliases; unsigned int lastdirid = -1; Hashval lastdirhash = 0; int lastdirlen = 0; int checkthisdir = 0; Repodata *lastrepodata = 0; dataiterator_init(&di, pool, 0, p, SOLVABLE_FILELIST, 0, SEARCH_COMPLETE_FILELIST); while (dataiterator_step(&di)) { if (aliases) { /* hash just the basename */ hx = strhash(di.kv.str); if (!hx) hx = strlen(di.kv.str) + 1; } else { /* hash the full path */ if (di.data != lastrepodata || di.kv.id != lastdirid) { const char *dir; lastrepodata = di.data; lastdirid = di.kv.id; dir = repodata_dir2str(lastrepodata, lastdirid, ""); lastdirlen = strlen(dir); lastdirhash = strhash(dir); checkthisdir = isindirmap(cbdata, lastdirhash ? lastdirhash : lastdirlen + 1); } if (!checkthisdir) continue; hx = strhash_cont(di.kv.str, lastdirhash); if (!hx) hx = lastdirlen + strlen(di.kv.str) + 1; } h = hx & cbdata->cflmapn; hh = HASHCHAIN_START; for (;;) { qx = cbdata->cflmap[2 * h]; if (!qx) break; if (qx == hx) { found = 1; break; } h = HASHCHAIN_NEXT(h, hh, cbdata->cflmapn); } if (found) break; } dataiterator_free(&di); return found; }
void repo_add_rpmmd(Repo *repo, FILE *fp, const char *language, int flags) { Pool *pool = repo->pool; struct parsedata pd; char buf[BUFF_SIZE]; int i, l; struct stateswitch *sw; Repodata *data; unsigned int now; now = sat_timems(0); data = repo_add_repodata(repo, flags); memset(&pd, 0, sizeof(pd)); for (i = 0, sw = stateswitches; sw->from != NUMSTATES; i++, sw++) { if (!pd.swtab[sw->from]) pd.swtab[sw->from] = sw; pd.sbtab[sw->to] = sw->from; } pd.common.pool = pool; pd.common.repo = repo; pd.data = data; pd.content = sat_malloc(256); pd.acontent = 256; pd.lcontent = 0; pd.common.tmp = 0; pd.common.tmpl = 0; pd.kind = 0; pd.language = language; /* initialize the string pool where we will store the package checksums we know about, to get an Id we can use in a cache */ stringpool_init_empty(&pd.cspool); if ((flags & REPO_EXTEND_SOLVABLES) != 0) { /* setup join data */ Dataiterator di; dataiterator_init(&di, pool, repo, 0, SOLVABLE_CHECKSUM, 0, 0); while (dataiterator_step(&di)) { const char *str; int index; if (!sat_chksum_len(di.key->type)) continue; str = repodata_chk2str(di.data, di.key->type, (const unsigned char *)di.kv.str); index = stringpool_str2id(&pd.cspool, str, 1); if (index >= pd.ncscache) { pd.cscache = sat_zextend(pd.cscache, pd.ncscache, index + 1 - pd.ncscache, sizeof(Id), 255); pd.ncscache = index + 1; } pd.cscache[index] = di.solvid; } dataiterator_free(&di); } XML_Parser parser = XML_ParserCreate(NULL); XML_SetUserData(parser, &pd); pd.parser = &parser; XML_SetElementHandler(parser, startElement, endElement); XML_SetCharacterDataHandler(parser, characterData); for (;;) { l = fread(buf, 1, sizeof(buf), fp); if (XML_Parse(parser, buf, l, l == 0) == XML_STATUS_ERROR) { pool_debug(pool, SAT_FATAL, "repo_rpmmd: %s at line %u:%u\n", XML_ErrorString(XML_GetErrorCode(parser)), (unsigned int)XML_GetCurrentLineNumber(parser), (unsigned int)XML_GetCurrentColumnNumber(parser)); exit(1); } if (l == 0) break; } XML_ParserFree(parser); sat_free(pd.content); sat_free(pd.lastdirstr); join_freemem(); stringpool_free(&pd.cspool); sat_free(pd.cscache); if (!(flags & REPO_NO_INTERNALIZE)) repodata_internalize(data); POOL_DEBUG(SAT_DEBUG_STATS, "repo_add_rpmmd took %d ms\n", sat_timems(now)); POOL_DEBUG(SAT_DEBUG_STATS, "repo size: %d solvables\n", repo->nsolvables); POOL_DEBUG(SAT_DEBUG_STATS, "repo memory used: %d K incore, %d K idarray\n", data->incoredatalen/1024, repo->idarraysize / (int)(1024/sizeof(Id))); }