2 * Copyright (c) 2009-2015, SUSE LLC
4 * This program is licensed under the BSD license, read LICENSE.BSD
5 * for further information
18 #include "repo_solv.h"
19 #ifdef ENABLE_SUSEREPO
20 #include "repo_susetags.h"
23 #include "repo_rpmmd.h"
28 #ifdef ENABLE_ARCHREPO
29 #include "repo_arch.h"
32 #include "solv_xfopen.h"
41 printf("Usage:\n%s: <arch> [options..] repo [--nocheck repo]...\n"
42 "\t--exclude <pattern>\twhitespace-separated list of (sub-)"
43 "packagenames to ignore\n"
44 "\t--withobsoletes\t\tCheck for obsoletes on packages contained in repos\n"
45 "\t--nocheck\t\tDo not warn about all following repos (only use them to fulfill dependencies)\n"
46 "\t--withsrc\t\tAlso check dependencies of src.rpm\n\n"
51 #if defined(ENABLE_SUSEREPO) || defined(ENABLE_RPMMD) || defined(ENABLE_DEBIAN) || defined(ENABLE_ARCHREPO)
53 strlen_comp(const char *str)
55 const char *suf = strrchr(str, '.');
56 return strlen(str) - (suf && solv_xfopen_iscompressed(suf) ? strlen(suf) : 0);
61 main(int argc, char **argv)
69 char *arch, *exclude_pat;
80 int obsoletepkgcheck = 0;
88 pool_setarch(pool, arch);
89 noarchid = pool->solvables[SYSTEMSOLVABLE].arch;
90 for (i = 2; i < argc; i++)
94 #if defined(ENABLE_SUSEREPO) || defined(ENABLE_RPMMD) || defined(ENABLE_DEBIAN) || defined(ENABLE_ARCHREPO)
98 if (!strcmp(argv[i], "--withsrc"))
103 if (!strcmp(argv[i], "--withobsoletes"))
108 if (!strcmp(argv[i], "--nocheck"))
111 nocheck = pool->nsolvables;
114 if (!strcmp(argv[i], "--exclude"))
118 printf("--exclude needs a whitespace separated list of substrings as parameter\n");
121 exclude_pat = argv[i + 1];
125 #if defined(ENABLE_SUSEREPO) || defined(ENABLE_RPMMD) || defined(ENABLE_DEBIAN) || defined(ENABLE_ARCHREPO)
126 l = strlen_comp(argv[i]);
128 if (!strcmp(argv[i], "-"))
130 else if ((fp = solv_xfopen(argv[i], 0)) == 0)
135 repo = repo_create(pool, argv[i]);
140 #ifdef ENABLE_SUSEREPO
141 else if (l >= 8 && !strncmp(argv[i] + l - 8, "packages", 8))
143 r = repo_add_susetags(repo, fp, 0, 0, 0);
147 else if (l >= 11 && !strncmp(argv[i] + l - 11, "primary.xml", 11))
149 r = repo_add_rpmmd(repo, fp, 0, 0);
150 if (!r && i + 1 < argc)
152 l = strlen_comp(argv[i + 1]);
153 if (l >= 13 && !strncmp(argv[i + 1] + l - 13, "filelists.xml", 13))
157 if ((fp = solv_xfopen(argv[i], 0)) == 0)
162 r = repo_add_rpmmd(repo, fp, 0, REPO_EXTEND_SOLVABLES|REPO_LOCALPOOL);
168 else if (l >= 8 && !strncmp(argv[i] + l - 8, "Packages", 8))
170 r = repo_add_debpackages(repo, fp, 0);
173 #ifdef ENABLE_ARCHREPO
174 else if (l >= 7 && (!strncmp(argv[i] + l - 7, ".db.tar", 7)))
176 r = repo_add_arch_repo(repo, fp, 0);
180 r = repo_add_solv(repo, fp, 0);
183 fprintf(stderr, "could not add repo %s: %s\n", argv[i], pool_errstr(pool));
189 pool_addfileprovides(pool);
190 pool_createwhatprovides(pool);
191 archid = pool_str2id(pool, arch, 0);
193 rpmid = pool_str2id(pool, "rpm", 0);
197 for (p = 1; p < pool->nsolvables; p++)
199 Solvable *s = pool->solvables + p;
200 if (s->name == rpmid && s->arch == archid && pool_installable(pool, s))
203 if (p < pool->nsolvables)
204 rpmrel = pool_rel2id(pool, rpmid, archid, REL_ARCH, 1);
213 for (p = 1; p < (nocheck ? nocheck : pool->nsolvables); p++)
215 Solvable *s = pool->solvables + p;
218 if (withsrc && (s->arch == ARCH_SRC || s->arch == ARCH_NOSRC))
220 queue_push(&cand, p);
223 if (!pool_installable(pool, s))
225 if (archid && s->arch != archid && s->arch != noarchid)
227 /* check if we will conflict with a infarch rule, if yes,
228 * don't bother checking the package */
230 FOR_PROVIDES(rp, rpp, s->name)
232 if (pool->solvables[rp].name != s->name)
234 if (pool->solvables[rp].arch == archid)
240 queue_push(&cand, p);
242 if (obsoletepkgcheck)
244 int obsoleteusesprovides = pool_get_flag(pool, POOL_FLAG_OBSOLETEUSESPROVIDES);
245 int obsoleteusescolors = pool_get_flag(pool, POOL_FLAG_OBSOLETEUSESCOLORS);
247 for (i = 0; i < cand.count; i++)
250 s = pool->solvables + cand.elements[i];
254 Id obs, *obsp = s->repo->idarraydata + s->obsoletes;
256 while ((obs = *obsp++) != 0)
259 FOR_PROVIDES(op, opp, obs)
261 Solvable *os = pool->solvables + op;
262 if (nocheck && op >= nocheck)
264 if (solvable_identical(s, os))
266 if (!obsoleteusesprovides && !pool_match_nevr(pool, os, obs))
268 if (obsoleteusescolors && !pool_colormatch(pool, s, os))
271 printf("can't install %s:\n", pool_solvid2str(pool, op));
272 printf(" package is obsoleted by %s\n", pool_solvable2str(pool, s));
279 solv = solver_create(pool);
281 /* prune cand by doing weak installs */
285 for (i = 0; i < cand.count; i++)
287 p = cand.elements[i];
288 queue_push2(&job, SOLVER_INSTALL|SOLVER_SOLVABLE|SOLVER_WEAK, p);
291 queue_push2(&job, SOLVER_INSTALL|SOLVER_SOLVABLE_NAME, rpmrel);
292 solver_set_flag(solv, SOLVER_FLAG_IGNORE_RECOMMENDED, 1);
293 solver_solve(solv, &job);
295 for (i = j = 0; i < cand.count; i++)
297 p = cand.elements[i];
298 if (solver_get_decisionlevel(solv, p) <= 0)
300 cand.elements[j++] = p;
309 /* now check every candidate */
310 for (i = 0; i < cand.count; i++)
315 p = cand.elements[i];
318 char *ptr, *save = 0, *pattern;
320 pattern = solv_strdup(exclude_pat);
322 for (ptr = strtok_r(pattern, " ", &save);
324 ptr = strtok_r(NULL, " ", &save))
326 if (*ptr && strstr(pool_solvid2str(pool, p), ptr))
336 s = pool->solvables + p;
338 queue_push2(&job, SOLVER_INSTALL|SOLVER_SOLVABLE, p);
340 queue_push2(&job, SOLVER_INSTALL|SOLVER_SOLVABLE_NAME, rpmrel);
341 solver_set_flag(solv, SOLVER_FLAG_IGNORE_RECOMMENDED, 1);
342 problemcount = solver_solve(solv, &job);
348 printf("can't install %s:\n", pool_solvable2str(pool, s));
349 while ((problem = solver_next_problem(solv, problem)) != 0)
351 solver_findallproblemrules(solv, problem, &rids);
352 for (j = 0; j < rids.count; j++)
354 Id probr = rids.elements[j];
359 solver_allruleinfos(solv, probr, &rinfo);
360 for (k = 0; k < rinfo.count; k += 4)
362 Id type, dep, source, target;
363 type = rinfo.elements[k];
364 source = rinfo.elements[k + 1];
365 target = rinfo.elements[k + 2];
366 dep = rinfo.elements[k + 3];
371 case SOLVER_RULE_DISTUPGRADE:
372 case SOLVER_RULE_JOB:
373 case SOLVER_RULE_JOB_PROVIDED_BY_SYSTEM:
374 case SOLVER_RULE_JOB_UNKNOWN_PACKAGE:
375 case SOLVER_RULE_JOB_UNSUPPORTED:
377 case SOLVER_RULE_UPDATE:
378 printf(" %s can not be updated\n", pool_solvid2str(pool, source));
380 case SOLVER_RULE_PKG_NOTHING_PROVIDES_DEP:
381 printf(" %s\n", solver_problemruleinfo2str(solv, type, source, target, dep));
384 Reldep *rd = GETRELDEP(pool, dep);
385 if (!ISRELDEP(rd->name))
388 FOR_PROVIDES(rp, rpp, rd->name)
389 printf(" (we have %s)\n", pool_solvable2str(pool, pool->solvables + rp));
394 printf(" %s\n", solver_problemruleinfo2str(solv, type, source, target, dep));