1 /* vim: sw=2 et cino=>4,n-2,{1s
5 * Copyright (c) 2009-2015, SUSE LLC
7 * This program is licensed under the BSD license, read LICENSE.BSD
8 * for further information
21 #include "repo_solv.h"
22 #ifdef ENABLE_SUSEREPO
23 #include "repo_susetags.h"
26 #include "repo_rpmmd.h"
31 #ifdef ENABLE_ARCHREPO
32 #include "repo_arch.h"
35 #include "solv_xfopen.h"
44 printf("Usage:\n%s: <arch> [options..] repo [--nocheck repo]...\n"
45 "\t--exclude <pattern>\twhitespace-separated list of (sub-)"
46 "packagenames to ignore\n"
47 "\t--withobsoletes\t\tCheck for obsoletes on packages contained in repos\n"
48 "\t--nocheck\t\tDo not warn about all following repos (only use them to fulfill dependencies)\n"
49 "\t--withsrc\t\tAlso check dependencies of src.rpm\n\n"
54 #if defined(ENABLE_SUSEREPO) || defined(ENABLE_RPMMD) || defined(ENABLE_DEBIAN) || defined(ENABLE_ARCHREPO)
56 strlen_comp(const char *str)
58 size_t l = strlen(str);
59 if (l > 3 && !strcmp(str + l - 3, ".gz"))
61 if (l > 3 && !strcmp(str + l - 3, ".xz"))
63 if (l > 4 && !strcmp(str + l - 4, ".bz2"))
65 if (l > 5 && !strcmp(str + l - 4, ".lzma"))
72 main(int argc, char **argv)
80 char *arch, *exclude_pat;
91 int obsoletepkgcheck = 0;
99 pool_setarch(pool, arch);
100 noarchid = pool->solvables[SYSTEMSOLVABLE].arch;
101 for (i = 2; i < argc; i++)
105 #if defined(ENABLE_SUSEREPO) || defined(ENABLE_RPMMD) || defined(ENABLE_DEBIAN) || defined(ENABLE_ARCHREPO)
109 if (!strcmp(argv[i], "--withsrc"))
114 if (!strcmp(argv[i], "--withobsoletes"))
119 if (!strcmp(argv[i], "--nocheck"))
122 nocheck = pool->nsolvables;
125 if (!strcmp(argv[i], "--exclude"))
129 printf("--exclude needs a whitespace separated list of substrings as parameter\n");
132 exclude_pat = argv[i + 1];
136 #if defined(ENABLE_SUSEREPO) || defined(ENABLE_RPMMD) || defined(ENABLE_DEBIAN) || defined(ENABLE_ARCHREPO)
137 l = strlen_comp(argv[i]);
139 if (!strcmp(argv[i], "-"))
141 else if ((fp = solv_xfopen(argv[i], 0)) == 0)
146 repo = repo_create(pool, argv[i]);
151 #ifdef ENABLE_SUSEREPO
152 else if (l >= 8 && !strncmp(argv[i] + l - 8, "packages", 8))
154 r = repo_add_susetags(repo, fp, 0, 0, 0);
158 else if (l >= 11 && !strncmp(argv[i] + l - 11, "primary.xml", 11))
160 r = repo_add_rpmmd(repo, fp, 0, 0);
161 if (!r && i + 1 < argc)
163 l = strlen_comp(argv[i + 1]);
164 if (l >= 13 && !strncmp(argv[i + 1] + l - 13, "filelists.xml", 13))
168 if ((fp = solv_xfopen(argv[i], 0)) == 0)
173 r = repo_add_rpmmd(repo, fp, 0, REPO_EXTEND_SOLVABLES|REPO_LOCALPOOL);
179 else if (l >= 8 && !strncmp(argv[i] + l - 8, "Packages", 8))
181 r = repo_add_debpackages(repo, fp, 0);
184 #ifdef ENABLE_ARCHREPO
185 else if (l >= 7 && (!strncmp(argv[i] + l - 7, ".db.tar", 7)))
187 r = repo_add_arch_repo(repo, fp, 0);
191 r = repo_add_solv(repo, fp, 0);
194 fprintf(stderr, "could not add repo %s: %s\n", argv[i], pool_errstr(pool));
200 pool_addfileprovides(pool);
201 pool_createwhatprovides(pool);
202 archid = pool_str2id(pool, arch, 0);
204 rpmid = pool_str2id(pool, "rpm", 0);
208 for (p = 1; p < pool->nsolvables; p++)
210 Solvable *s = pool->solvables + p;
211 if (s->name == rpmid && s->arch == archid && pool_installable(pool, s))
214 if (p < pool->nsolvables)
215 rpmrel = pool_rel2id(pool, rpmid, archid, REL_ARCH, 1);
224 for (p = 1; p < (nocheck ? nocheck : pool->nsolvables); p++)
226 Solvable *s = pool->solvables + p;
229 if (withsrc && (s->arch == ARCH_SRC || s->arch == ARCH_NOSRC))
231 queue_push(&cand, p);
234 if (!pool_installable(pool, s))
236 if (archid && s->arch != archid && s->arch != noarchid)
238 /* check if we will conflict with a infarch rule, if yes,
239 * don't bother checking the package */
241 FOR_PROVIDES(rp, rpp, s->name)
243 if (pool->solvables[rp].name != s->name)
245 if (pool->solvables[rp].arch == archid)
251 queue_push(&cand, p);
253 if (obsoletepkgcheck)
255 int obsoleteusesprovides = pool_get_flag(pool, POOL_FLAG_OBSOLETEUSESPROVIDES);
256 int obsoleteusescolors = pool_get_flag(pool, POOL_FLAG_OBSOLETEUSESCOLORS);
258 for (i = 0; i < cand.count; i++)
261 s = pool->solvables + cand.elements[i];
265 Id obs, *obsp = s->repo->idarraydata + s->obsoletes;
267 while ((obs = *obsp++) != 0)
270 FOR_PROVIDES(op, opp, obs)
272 Solvable *os = pool->solvables + op;
273 if (nocheck && op >= nocheck)
275 if (solvable_identical(s, os))
277 if (!obsoleteusesprovides && !pool_match_nevr(pool, os, obs))
279 if (obsoleteusescolors && !pool_colormatch(pool, s, os))
282 printf("can't install %s:\n", pool_solvid2str(pool, op));
283 printf(" package is obsoleted by %s\n", pool_solvable2str(pool, s));
290 solv = solver_create(pool);
292 /* prune cand by doing weak installs */
296 for (i = 0; i < cand.count; i++)
298 p = cand.elements[i];
299 queue_push2(&job, SOLVER_INSTALL|SOLVER_SOLVABLE|SOLVER_WEAK, p);
302 queue_push2(&job, SOLVER_INSTALL|SOLVER_SOLVABLE_NAME, rpmrel);
303 solver_set_flag(solv, SOLVER_FLAG_IGNORE_RECOMMENDED, 1);
304 solver_solve(solv, &job);
306 for (i = j = 0; i < cand.count; i++)
308 p = cand.elements[i];
309 if (solver_get_decisionlevel(solv, p) <= 0)
311 cand.elements[j++] = p;
320 /* now check every candidate */
321 for (i = 0; i < cand.count; i++)
326 p = cand.elements[i];
329 char *ptr, *save = 0, *pattern;
331 pattern = solv_strdup(exclude_pat);
333 for (ptr = strtok_r(pattern, " ", &save);
335 ptr = strtok_r(NULL, " ", &save))
337 if (*ptr && strstr(pool_solvid2str(pool, p), ptr))
347 s = pool->solvables + p;
349 queue_push2(&job, SOLVER_INSTALL|SOLVER_SOLVABLE, p);
351 queue_push2(&job, SOLVER_INSTALL|SOLVER_SOLVABLE_NAME, rpmrel);
352 solver_set_flag(solv, SOLVER_FLAG_IGNORE_RECOMMENDED, 1);
353 problemcount = solver_solve(solv, &job);
360 printf("can't install %s:\n", pool_solvable2str(pool, s));
361 while ((problem = solver_next_problem(solv, problem)) != 0)
363 solver_findallproblemrules(solv, problem, &rids);
364 for (j = 0; j < rids.count; j++)
366 Id probr = rids.elements[j];
371 solver_allruleinfos(solv, probr, &rinfo);
372 for (k = 0; k < rinfo.count; k += 4)
374 Id dep, source, target;
375 source = rinfo.elements[k + 1];
376 target = rinfo.elements[k + 2];
377 dep = rinfo.elements[k + 3];
378 switch (rinfo.elements[k])
380 case SOLVER_RULE_DISTUPGRADE:
382 case SOLVER_RULE_INFARCH:
383 s = pool_id2solvable(pool, source);
384 printf(" %s has inferior architecture\n", pool_solvable2str(pool, s));
386 case SOLVER_RULE_UPDATE:
387 s = pool_id2solvable(pool, source);
388 printf(" %s can not be updated\n", pool_solvable2str(pool, s));
390 case SOLVER_RULE_JOB:
391 case SOLVER_RULE_JOB_PROVIDED_BY_SYSTEM:
392 case SOLVER_RULE_JOB_UNKNOWN_PACKAGE:
393 case SOLVER_RULE_JOB_UNSUPPORTED:
395 case SOLVER_RULE_RPM:
396 printf(" some dependency problem\n");
398 case SOLVER_RULE_JOB_NOTHING_PROVIDES_DEP:
399 printf(" nothing provides requested %s\n", pool_dep2str(pool, dep));
401 case SOLVER_RULE_RPM_NOT_INSTALLABLE:
402 s = pool_id2solvable(pool, source);
403 printf(" package %s is not installable\n", pool_solvable2str(pool, s));
405 case SOLVER_RULE_RPM_NOTHING_PROVIDES_DEP:
406 s = pool_id2solvable(pool, source);
407 printf(" nothing provides %s needed by %s\n", pool_dep2str(pool, dep), pool_solvable2str(pool, s));
410 Reldep *rd = GETRELDEP(pool, dep);
411 if (!ISRELDEP(rd->name))
414 FOR_PROVIDES(rp, rpp, rd->name)
415 printf(" (we have %s)\n", pool_solvable2str(pool, pool->solvables + rp));
419 case SOLVER_RULE_RPM_SAME_NAME:
420 s = pool_id2solvable(pool, source);
421 s2 = pool_id2solvable(pool, target);
422 printf(" cannot install both %s and %s\n", pool_solvable2str(pool, s), pool_solvable2str(pool, s2));
424 case SOLVER_RULE_RPM_PACKAGE_CONFLICT:
425 s = pool_id2solvable(pool, source);
426 s2 = pool_id2solvable(pool, target);
427 printf(" package %s conflicts with %s provided by %s\n", pool_solvable2str(pool, s), pool_dep2str(pool, dep), pool_solvable2str(pool, s2));
429 case SOLVER_RULE_RPM_PACKAGE_OBSOLETES:
430 s = pool_id2solvable(pool, source);
431 s2 = pool_id2solvable(pool, target);
432 printf(" package %s obsoletes %s provided by %s\n", pool_solvable2str(pool, s), pool_dep2str(pool, dep), pool_solvable2str(pool, s2));
434 case SOLVER_RULE_RPM_PACKAGE_REQUIRES:
435 s = pool_id2solvable(pool, source);
436 printf(" package %s requires %s, but none of the providers can be installed\n", pool_solvable2str(pool, s), pool_dep2str(pool, dep));
438 case SOLVER_RULE_RPM_SELF_CONFLICT:
439 s = pool_id2solvable(pool, source);
440 printf(" package %s conflicts with %s provided by itself\n", pool_solvable2str(pool, s), pool_dep2str(pool, dep));