X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=tools%2Finstallcheck.c;h=4eb66a02297ad37bb7a6f8e090b00444fb2b089b;hb=6a68988035ea989055076d81b7ab53c7015c8c32;hp=cf3c750ceead039aab0edfca6dd5cbfbeb95b954;hpb=db67f9cb45157f2d4660a8fc2f24dcf3957d4b7c;p=platform%2Fupstream%2Flibsolv.git diff --git a/tools/installcheck.c b/tools/installcheck.c index cf3c750..4eb66a0 100644 --- a/tools/installcheck.c +++ b/tools/installcheck.c @@ -2,7 +2,7 @@ */ /* - * Copyright (c) 2009, Novell Inc. + * Copyright (c) 2009-2015, SUSE LLC * * This program is licensed under the BSD license, read LICENSE.BSD * for further information @@ -15,86 +15,107 @@ #include #include #include -#include #include "pool.h" #include "poolarch.h" #include "repo_solv.h" +#ifdef ENABLE_SUSEREPO #include "repo_susetags.h" +#endif +#ifdef ENABLE_RPMMD #include "repo_rpmmd.h" +#endif +#ifdef ENABLE_DEBIAN +#include "repo_deb.h" +#endif +#ifdef ENABLE_ARCHREPO +#include "repo_arch.h" +#endif #include "solver.h" +#include "solv_xfopen.h" -static ssize_t -cookie_gzread(void *cookie, char *buf, size_t nbytes) -{ - return gzread((gzFile *)cookie, buf, nbytes); -} - -static int -cookie_gzclose(void *cookie) -{ - return gzclose((gzFile *)cookie); -} - -FILE * -myfopen(const char *fn) -{ - cookie_io_functions_t cio; - char *suf; - gzFile *gzf; - - if (!fn) - return 0; - suf = strrchr(fn, '.'); - if (!suf || strcmp(suf, ".gz") != 0) - return fopen(fn, "r"); - gzf = gzopen(fn, "r"); - if (!gzf) - return 0; - memset(&cio, 0, sizeof(cio)); - cio.read = cookie_gzread; - cio.close = cookie_gzclose; - return fopencookie(gzf, "r", cio); -} +#ifdef _WIN32 +#include "strfncs.h" +#endif void usage(char** argv) { - printf("Usage:\n%s: repo [--nocheck repo]...\n", - argv[0]); - exit(1); + printf("Usage:\n%s: [options..] repo [--nocheck repo]...\n" + "\t--exclude \twhitespace-separated list of (sub-)" + "packagenames to ignore\n" + "\t--withobsoletes\t\tCheck for obsoletes on packages contained in repos\n" + "\t--nocheck\t\tDo not warn about all following repos (only use them to fulfill dependencies)\n" + "\t--withsrc\t\tAlso check dependencies of src.rpm\n\n" + , argv[0]); + exit(1); } +#if defined(ENABLE_SUSEREPO) || defined(ENABLE_RPMMD) || defined(ENABLE_DEBIAN) || defined(ENABLE_ARCHREPO) +static int +strlen_comp(const char *str) +{ + size_t l = strlen(str); + if (l > 3 && !strcmp(str + l - 3, ".gz")) + return l - 3; + if (l > 3 && !strcmp(str + l - 3, ".xz")) + return l - 3; + if (l > 4 && !strcmp(str + l - 4, ".bz2")) + return l - 4; + if (l > 5 && !strcmp(str + l - 4, ".lzma")) + return l - 5; + return l; +} +#endif int main(int argc, char **argv) { Pool *pool; Solver *solv; + Repo *repo; Queue job; Queue rids; Queue cand; - Queue archlocks; char *arch, *exclude_pat; int i, j; Id p; - Id rpmid, rpmarch, rpmrel, archlock; + Id archid, noarchid; + Id rpmrel; +#ifndef DEBIAN + Id rpmid; +#endif int status = 0; int nocheck = 0; + int withsrc = 0; + int obsoletepkgcheck = 0; exclude_pat = 0; - archlock = 0; if (argc < 3) usage(argv); arch = argv[1]; pool = pool_create(); pool_setarch(pool, arch); + noarchid = pool->solvables[SYSTEMSOLVABLE].arch; for (i = 2; i < argc; i++) { FILE *fp; + int r; +#if defined(ENABLE_SUSEREPO) || defined(ENABLE_RPMMD) || defined(ENABLE_DEBIAN) || defined(ENABLE_ARCHREPO) int l; +#endif + if (!strcmp(argv[i], "--withsrc")) + { + withsrc++; + continue; + } + if (!strcmp(argv[i], "--withobsoletes")) + { + obsoletepkgcheck++; + continue; + } if (!strcmp(argv[i], "--nocheck")) { if (!nocheck) @@ -112,30 +133,65 @@ main(int argc, char **argv) ++i; continue; } - l = strlen(argv[i]); +#if defined(ENABLE_SUSEREPO) || defined(ENABLE_RPMMD) || defined(ENABLE_DEBIAN) || defined(ENABLE_ARCHREPO) + l = strlen_comp(argv[i]); +#endif if (!strcmp(argv[i], "-")) fp = stdin; - else if ((fp = myfopen(argv[i])) == 0) + else if ((fp = solv_xfopen(argv[i], 0)) == 0) { perror(argv[i]); exit(1); } - Repo *repo = repo_create(pool, argv[i]); - if (l >= 8 && !strcmp(argv[i] + l - 8, "packages")) + repo = repo_create(pool, argv[i]); + r = 0; + if (0) + { + } +#ifdef ENABLE_SUSEREPO + else if (l >= 8 && !strncmp(argv[i] + l - 8, "packages", 8)) { - repo_add_susetags(repo, fp, 0, 0, 0); + r = repo_add_susetags(repo, fp, 0, 0, 0); } - else if (l >= 11 && !strcmp(argv[i] + l - 11, "packages.gz")) +#endif +#ifdef ENABLE_RPMMD + else if (l >= 11 && !strncmp(argv[i] + l - 11, "primary.xml", 11)) { - repo_add_susetags(repo, fp, 0, 0, 0); + r = repo_add_rpmmd(repo, fp, 0, 0); + if (!r && i + 1 < argc) + { + l = strlen_comp(argv[i + 1]); + if (l >= 13 && !strncmp(argv[i + 1] + l - 13, "filelists.xml", 13)) + { + i++; + fclose(fp); + if ((fp = solv_xfopen(argv[i], 0)) == 0) + { + perror(argv[i]); + exit(1); + } + r = repo_add_rpmmd(repo, fp, 0, REPO_EXTEND_SOLVABLES|REPO_LOCALPOOL); + } + } } - else if (l >= 14 && !strcmp(argv[i] + l - 14, "primary.xml.gz")) +#endif +#ifdef ENABLE_DEBIAN + else if (l >= 8 && !strncmp(argv[i] + l - 8, "Packages", 8)) { - repo_add_rpmmd(repo, fp, 0, 0); + r = repo_add_debpackages(repo, fp, 0); } - else if (repo_add_solv(repo, fp)) +#endif +#ifdef ENABLE_ARCHREPO + else if (l >= 7 && (!strncmp(argv[i] + l - 7, ".db.tar", 7))) + { + r = repo_add_arch_repo(repo, fp, 0); + } +#endif + else + r = repo_add_solv(repo, fp, 0); + if (r) { - fprintf(stderr, "could not add repo %s\n", argv[i]); + fprintf(stderr, "could not add repo %s: %s\n", argv[i], pool_errstr(pool)); exit(1); } if (fp != stdin) @@ -143,95 +199,118 @@ main(int argc, char **argv) } pool_addfileprovides(pool); pool_createwhatprovides(pool); - rpmid = str2id(pool, "rpm", 0); - rpmarch = str2id(pool, arch, 0); + archid = pool_str2id(pool, arch, 0); +#ifndef DEBIAN + rpmid = pool_str2id(pool, "rpm", 0); rpmrel = 0; - if (rpmid && rpmarch) + if (rpmid && archid) { for (p = 1; p < pool->nsolvables; p++) { Solvable *s = pool->solvables + p; - if (s->name == rpmid && s->arch == rpmarch) + if (s->name == rpmid && s->arch == archid && pool_installable(pool, s)) break; } if (p < pool->nsolvables) - rpmrel = rel2id(pool, rpmid, rpmarch, REL_ARCH, 1); + rpmrel = pool_rel2id(pool, rpmid, archid, REL_ARCH, 1); } +#else + rpmrel = 0; +#endif queue_init(&job); queue_init(&rids); queue_init(&cand); - queue_init(&archlocks); - for (p = 1; p < pool->nsolvables; p++) + for (p = 1; p < (nocheck ? nocheck : pool->nsolvables); p++) { Solvable *s = pool->solvables + p; if (!s->repo) continue; + if (withsrc && (s->arch == ARCH_SRC || s->arch == ARCH_NOSRC)) + { + queue_push(&cand, p); + continue; + } if (!pool_installable(pool, s)) continue; - if (rpmrel && s->arch != rpmarch) + if (archid && s->arch != archid && s->arch != noarchid) { + /* check if we will conflict with a infarch rule, if yes, + * don't bother checking the package */ Id rp, rpp; FOR_PROVIDES(rp, rpp, s->name) { if (pool->solvables[rp].name != s->name) continue; - if (pool->solvables[rp].arch == rpmarch) + if (pool->solvables[rp].arch == archid) break; } if (rp) - { - queue_push(&archlocks, p); - continue; - } + continue; } queue_push(&cand, p); } - - if (archlocks.count) + if (obsoletepkgcheck) { - archlock = pool_queuetowhatprovides(pool, &archlocks); + int obsoleteusesprovides = pool_get_flag(pool, POOL_FLAG_OBSOLETEUSESPROVIDES); + int obsoleteusescolors = pool_get_flag(pool, POOL_FLAG_OBSOLETEUSESCOLORS); + + for (i = 0; i < cand.count; i++) + { + Solvable *s; + s = pool->solvables + cand.elements[i]; + + if (s->obsoletes) + { + Id obs, *obsp = s->repo->idarraydata + s->obsoletes; + + while ((obs = *obsp++) != 0) + { + Id op, opp; + FOR_PROVIDES(op, opp, obs) + { + Solvable *os = pool->solvables + op; + if (nocheck && op >= nocheck) + continue; + if (solvable_identical(s, os)) + continue; + if (!obsoleteusesprovides && !pool_match_nevr(pool, os, obs)) + continue; + if (obsoleteusescolors && !pool_colormatch(pool, s, os)) + continue; + status = 2; + printf("can't install %s:\n", pool_solvid2str(pool, op)); + printf(" package is obsoleted by %s\n", pool_solvable2str(pool, s)); + } + } + } + } } + + solv = solver_create(pool); + /* prune cand by doing weak installs */ while (cand.count) { - solv = solver_create(pool); queue_empty(&job); for (i = 0; i < cand.count; i++) { p = cand.elements[i]; - queue_push(&job, SOLVER_INSTALL|SOLVER_SOLVABLE|SOLVER_WEAK); - queue_push(&job, p); + queue_push2(&job, SOLVER_INSTALL|SOLVER_SOLVABLE|SOLVER_WEAK, p); } if (rpmrel) - { - queue_push(&job, SOLVER_INSTALL|SOLVER_SOLVABLE_NAME); - queue_push(&job, rpmrel); - } - if (archlock) - { - queue_push(&job, SOLVER_LOCK|SOLVER_SOLVABLE_ONE_OF); - queue_push(&job, archlock); - } - solv->dontinstallrecommended = 1; + queue_push2(&job, SOLVER_INSTALL|SOLVER_SOLVABLE_NAME, rpmrel); + solver_set_flag(solv, SOLVER_FLAG_IGNORE_RECOMMENDED, 1); solver_solve(solv, &job); /* prune... */ for (i = j = 0; i < cand.count; i++) { p = cand.elements[i]; - if (solv->decisionmap[p] <= 0) + if (solver_get_decisionlevel(solv, p) <= 0) { cand.elements[j++] = p; continue; } -#if 0 - Solvable *s = pool->solvables + p; - if (!strcmp(id2str(pool, s->name), "libusb-compat-devel")) - { - cand.elements[j++] = p; - continue; - } -#endif } cand.count = j; if (i == j) @@ -242,54 +321,43 @@ main(int argc, char **argv) for (i = 0; i < cand.count; i++) { Solvable *s; + int problemcount; p = cand.elements[i]; - if (nocheck && p >= nocheck) - continue; if (exclude_pat) { char *ptr, *save = 0, *pattern; int match = 0; - pattern = strdup(exclude_pat); + pattern = solv_strdup(exclude_pat); for (ptr = strtok_r(pattern, " ", &save); ptr; ptr = strtok_r(NULL, " ", &save)) { - if (*ptr && strstr(solvid2str(pool, p), ptr)) + if (*ptr && strstr(pool_solvid2str(pool, p), ptr)) { match = 1; break; } } - free(pattern); + solv_free(pattern); if (match) continue; } s = pool->solvables + p; - solv = solver_create(pool); queue_empty(&job); - queue_push(&job, SOLVER_INSTALL|SOLVER_SOLVABLE); - queue_push(&job, p); + queue_push2(&job, SOLVER_INSTALL|SOLVER_SOLVABLE, p); if (rpmrel) - { - queue_push(&job, SOLVER_INSTALL|SOLVER_SOLVABLE_NAME); - queue_push(&job, rpmrel); - } - if (archlock) - { - queue_push(&job, SOLVER_LOCK|SOLVER_SOLVABLE_ONE_OF); - queue_push(&job, archlock); - } - solv->dontinstallrecommended = 1; - solver_solve(solv, &job); - if (solv->problems.count) + queue_push2(&job, SOLVER_INSTALL|SOLVER_SOLVABLE_NAME, rpmrel); + solver_set_flag(solv, SOLVER_FLAG_IGNORE_RECOMMENDED, 1); + problemcount = solver_solve(solv, &job); + if (problemcount) { Id problem = 0; Solvable *s2; status = 1; - printf("can't install %s:\n", solvable2str(pool, s)); + printf("can't install %s:\n", pool_solvable2str(pool, s)); while ((problem = solver_next_problem(solv, problem)) != 0) { solver_findallproblemrules(solv, problem, &rids); @@ -309,29 +377,34 @@ main(int argc, char **argv) dep = rinfo.elements[k + 3]; switch (rinfo.elements[k]) { - case SOLVER_PROBLEM_DISTUPGRADE_RULE: + case SOLVER_RULE_DISTUPGRADE: break; - case SOLVER_PROBLEM_INFARCH_RULE: + case SOLVER_RULE_INFARCH: s = pool_id2solvable(pool, source); - printf(" %s has inferior architecture\n", solvable2str(pool, s)); + printf(" %s has inferior architecture\n", pool_solvable2str(pool, s)); break; - case SOLVER_PROBLEM_UPDATE_RULE: + case SOLVER_RULE_UPDATE: + s = pool_id2solvable(pool, source); + printf(" %s can not be updated\n", pool_solvable2str(pool, s)); break; - case SOLVER_PROBLEM_JOB_RULE: + case SOLVER_RULE_JOB: + case SOLVER_RULE_JOB_PROVIDED_BY_SYSTEM: + case SOLVER_RULE_JOB_UNKNOWN_PACKAGE: + case SOLVER_RULE_JOB_UNSUPPORTED: break; - case SOLVER_PROBLEM_RPM_RULE: + case SOLVER_RULE_RPM: printf(" some dependency problem\n"); break; - case SOLVER_PROBLEM_JOB_NOTHING_PROVIDES_DEP: - printf(" nothing provides requested %s\n", dep2str(pool, dep)); + case SOLVER_RULE_JOB_NOTHING_PROVIDES_DEP: + printf(" nothing provides requested %s\n", pool_dep2str(pool, dep)); break; - case SOLVER_PROBLEM_NOT_INSTALLABLE: + case SOLVER_RULE_RPM_NOT_INSTALLABLE: s = pool_id2solvable(pool, source); - printf(" package %s is not installable\n", solvable2str(pool, s)); + printf(" package %s is not installable\n", pool_solvable2str(pool, s)); break; - case SOLVER_PROBLEM_NOTHING_PROVIDES_DEP: + case SOLVER_RULE_RPM_NOTHING_PROVIDES_DEP: s = pool_id2solvable(pool, source); - printf(" nothing provides %s needed by %s\n", dep2str(pool, dep), solvable2str(pool, s)); + printf(" nothing provides %s needed by %s\n", pool_dep2str(pool, dep), pool_solvable2str(pool, s)); if (ISRELDEP(dep)) { Reldep *rd = GETRELDEP(pool, dep); @@ -339,48 +412,39 @@ main(int argc, char **argv) { Id rp, rpp; FOR_PROVIDES(rp, rpp, rd->name) - printf(" (we have %s)\n", solvable2str(pool, pool->solvables + rp)); + printf(" (we have %s)\n", pool_solvable2str(pool, pool->solvables + rp)); } } break; - case SOLVER_PROBLEM_SAME_NAME: + case SOLVER_RULE_RPM_SAME_NAME: s = pool_id2solvable(pool, source); s2 = pool_id2solvable(pool, target); - printf(" cannot install both %s and %s\n", solvable2str(pool, s), solvable2str(pool, s2)); + printf(" cannot install both %s and %s\n", pool_solvable2str(pool, s), pool_solvable2str(pool, s2)); break; - case SOLVER_PROBLEM_PACKAGE_CONFLICT: + case SOLVER_RULE_RPM_PACKAGE_CONFLICT: s = pool_id2solvable(pool, source); s2 = pool_id2solvable(pool, target); - printf(" package %s conflicts with %s provided by %s\n", solvable2str(pool, s), dep2str(pool, dep), solvable2str(pool, s2)); + printf(" package %s conflicts with %s provided by %s\n", pool_solvable2str(pool, s), pool_dep2str(pool, dep), pool_solvable2str(pool, s2)); break; - case SOLVER_PROBLEM_PACKAGE_OBSOLETES: + case SOLVER_RULE_RPM_PACKAGE_OBSOLETES: s = pool_id2solvable(pool, source); s2 = pool_id2solvable(pool, target); - printf(" package %s obsoletes %s provided by %s\n", solvable2str(pool, s), dep2str(pool, dep), solvable2str(pool, s2)); + printf(" package %s obsoletes %s provided by %s\n", pool_solvable2str(pool, s), pool_dep2str(pool, dep), pool_solvable2str(pool, s2)); break; - case SOLVER_PROBLEM_DEP_PROVIDERS_NOT_INSTALLABLE: + case SOLVER_RULE_RPM_PACKAGE_REQUIRES: s = pool_id2solvable(pool, source); - printf(" package %s requires %s, but none of the providers can be installed\n", solvable2str(pool, s), dep2str(pool, dep)); + printf(" package %s requires %s, but none of the providers can be installed\n", pool_solvable2str(pool, s), pool_dep2str(pool, dep)); break; - case SOLVER_PROBLEM_SELF_CONFLICT: + case SOLVER_RULE_RPM_SELF_CONFLICT: s = pool_id2solvable(pool, source); - printf(" package %s conflicts with %s provided by itself\n", solvable2str(pool, s), dep2str(pool, dep)); + printf(" package %s conflicts with %s provided by itself\n", pool_solvable2str(pool, s), pool_dep2str(pool, dep)); break; } } } } } -#if 0 - else - { - if (!strcmp(id2str(pool, s->name), "libusb-compat-devel")) - { - solver_printdecisions(solv); - } - } -#endif - solver_free(solv); } + solver_free(solv); exit(status); }