1 /* vim: sw=2 et cino=>4,n-2,{1s
5 * Copyright (c) 2009, Novell Inc.
7 * This program is licensed under the BSD license, read LICENSE.BSD
8 * for further information
22 #include "repo_solv.h"
24 #include "repo_susetags.h"
25 #include "repo_rpmmd.h"
32 cookie_gzread(void *cookie, char *buf, size_t nbytes)
34 return gzread((gzFile *)cookie, buf, nbytes);
38 cookie_gzclose(void *cookie)
40 return gzclose((gzFile *)cookie);
44 myfopen(const char *fn)
46 cookie_io_functions_t cio;
52 suf = strrchr(fn, '.');
53 if (!suf || strcmp(suf, ".gz") != 0)
54 return fopen(fn, "r");
55 gzf = gzopen(fn, "r");
58 memset(&cio, 0, sizeof(cio));
59 cio.read = cookie_gzread;
60 cio.close = cookie_gzclose;
61 return fopencookie(gzf, "r", cio);
67 printf("Usage:\n%s: <arch> [options..] repo [--nocheck repo]...\n"
68 "\t--exclude <pattern>\twhitespace-separated list of (sub-)"
69 "packagenames to ignore\n"
70 "\t--withsrc\t\tAlso check dependencies of src.rpm\n\n"
77 main(int argc, char **argv)
85 char *arch, *exclude_pat;
88 Id rpmid, rpmarch, rpmrel, archlock;
100 pool_setarch(pool, arch);
101 for (i = 2; i < argc; i++)
106 if (!strcmp(argv[i], "--withsrc"))
111 if (!strcmp(argv[i], "--nocheck"))
114 nocheck = pool->nsolvables;
117 if (!strcmp(argv[i], "--exclude"))
121 printf("--exclude needs a whitespace separated list of substrings as parameter\n");
124 exclude_pat = argv[i + 1];
129 if (!strcmp(argv[i], "-"))
131 else if ((fp = myfopen(argv[i])) == 0)
136 Repo *repo = repo_create(pool, argv[i]);
138 if (l >= 8 && !strcmp(argv[i] + l - 8, "packages"))
140 repo_add_susetags(repo, fp, 0, 0, 0);
142 else if (l >= 11 && !strcmp(argv[i] + l - 11, "packages.gz"))
144 repo_add_susetags(repo, fp, 0, 0, 0);
146 else if (l >= 14 && !strcmp(argv[i] + l - 14, "primary.xml.gz"))
148 repo_add_rpmmd(repo, fp, 0, 0);
151 if (l >= 8 && !strcmp(argv[i] + l - 8, "Packages"))
153 repo_add_debpackages(repo, fp, 0);
155 else if (l >= 11 && !strcmp(argv[i] + l - 11, "Packages.gz"))
157 repo_add_debpackages(repo, fp, 0);
160 else if (repo_add_solv(repo, fp))
162 fprintf(stderr, "could not add repo %s\n", argv[i]);
168 pool_addfileprovides(pool);
169 pool_createwhatprovides(pool);
170 rpmid = str2id(pool, "rpm", 0);
171 rpmarch = str2id(pool, arch, 0);
174 if (rpmid && rpmarch)
176 for (p = 1; p < pool->nsolvables; p++)
178 Solvable *s = pool->solvables + p;
179 if (s->name == rpmid && s->arch == rpmarch)
182 if (p < pool->nsolvables)
183 rpmrel = rel2id(pool, rpmid, rpmarch, REL_ARCH, 1);
190 queue_init(&archlocks);
191 for (p = 1; p < pool->nsolvables; p++)
193 Solvable *s = pool->solvables + p;
196 if (withsrc && (s->arch == ARCH_SRC || s->arch == ARCH_NOSRC))
198 queue_push(&cand, p);
201 if (!pool_installable(pool, s))
203 if (rpmrel && s->arch != rpmarch)
206 FOR_PROVIDES(rp, rpp, s->name)
208 if (pool->solvables[rp].name != s->name)
210 if (pool->solvables[rp].arch == rpmarch)
215 queue_push(&archlocks, p);
219 queue_push(&cand, p);
224 archlock = pool_queuetowhatprovides(pool, &archlocks);
226 /* prune cand by doing weak installs */
229 solv = solver_create(pool);
231 for (i = 0; i < cand.count; i++)
233 p = cand.elements[i];
234 queue_push(&job, SOLVER_INSTALL|SOLVER_SOLVABLE|SOLVER_WEAK);
239 queue_push(&job, SOLVER_INSTALL|SOLVER_SOLVABLE_NAME);
240 queue_push(&job, rpmrel);
244 queue_push(&job, SOLVER_LOCK|SOLVER_SOLVABLE_ONE_OF);
245 queue_push(&job, archlock);
247 solv->dontinstallrecommended = 1;
248 solver_solve(solv, &job);
250 for (i = j = 0; i < cand.count; i++)
252 p = cand.elements[i];
253 if (solv->decisionmap[p] <= 0)
255 cand.elements[j++] = p;
259 Solvable *s = pool->solvables + p;
260 if (!strcmp(id2str(pool, s->name), "libusb-compat-devel"))
262 cand.elements[j++] = p;
272 /* now check every candidate */
273 for (i = 0; i < cand.count; i++)
277 p = cand.elements[i];
278 if (nocheck && p >= nocheck)
282 char *ptr, *save = 0, *pattern;
284 pattern = strdup(exclude_pat);
286 for (ptr = strtok_r(pattern, " ", &save);
288 ptr = strtok_r(NULL, " ", &save))
290 if (*ptr && strstr(solvid2str(pool, p), ptr))
300 s = pool->solvables + p;
301 solv = solver_create(pool);
303 queue_push(&job, SOLVER_INSTALL|SOLVER_SOLVABLE);
307 queue_push(&job, SOLVER_INSTALL|SOLVER_SOLVABLE_NAME);
308 queue_push(&job, rpmrel);
312 queue_push(&job, SOLVER_LOCK|SOLVER_SOLVABLE_ONE_OF);
313 queue_push(&job, archlock);
315 solv->dontinstallrecommended = 1;
316 solver_solve(solv, &job);
317 if (solv->problems.count)
323 printf("can't install %s:\n", solvable2str(pool, s));
324 while ((problem = solver_next_problem(solv, problem)) != 0)
326 solver_findallproblemrules(solv, problem, &rids);
327 for (j = 0; j < rids.count; j++)
329 Id probr = rids.elements[j];
334 solver_allruleinfos(solv, probr, &rinfo);
335 for (k = 0; k < rinfo.count; k += 4)
337 Id dep, source, target;
338 source = rinfo.elements[k + 1];
339 target = rinfo.elements[k + 2];
340 dep = rinfo.elements[k + 3];
341 switch (rinfo.elements[k])
343 case SOLVER_PROBLEM_DISTUPGRADE_RULE:
345 case SOLVER_PROBLEM_INFARCH_RULE:
346 s = pool_id2solvable(pool, source);
347 printf(" %s has inferior architecture\n", solvable2str(pool, s));
349 case SOLVER_PROBLEM_UPDATE_RULE:
351 case SOLVER_PROBLEM_JOB_RULE:
353 case SOLVER_PROBLEM_RPM_RULE:
354 printf(" some dependency problem\n");
356 case SOLVER_PROBLEM_JOB_NOTHING_PROVIDES_DEP:
357 printf(" nothing provides requested %s\n", dep2str(pool, dep));
359 case SOLVER_PROBLEM_NOT_INSTALLABLE:
360 s = pool_id2solvable(pool, source);
361 printf(" package %s is not installable\n", solvable2str(pool, s));
363 case SOLVER_PROBLEM_NOTHING_PROVIDES_DEP:
364 s = pool_id2solvable(pool, source);
365 printf(" nothing provides %s needed by %s\n", dep2str(pool, dep), solvable2str(pool, s));
368 Reldep *rd = GETRELDEP(pool, dep);
369 if (!ISRELDEP(rd->name))
372 FOR_PROVIDES(rp, rpp, rd->name)
373 printf(" (we have %s)\n", solvable2str(pool, pool->solvables + rp));
377 case SOLVER_PROBLEM_SAME_NAME:
378 s = pool_id2solvable(pool, source);
379 s2 = pool_id2solvable(pool, target);
380 printf(" cannot install both %s and %s\n", solvable2str(pool, s), solvable2str(pool, s2));
382 case SOLVER_PROBLEM_PACKAGE_CONFLICT:
383 s = pool_id2solvable(pool, source);
384 s2 = pool_id2solvable(pool, target);
385 printf(" package %s conflicts with %s provided by %s\n", solvable2str(pool, s), dep2str(pool, dep), solvable2str(pool, s2));
387 case SOLVER_PROBLEM_PACKAGE_OBSOLETES:
388 s = pool_id2solvable(pool, source);
389 s2 = pool_id2solvable(pool, target);
390 printf(" package %s obsoletes %s provided by %s\n", solvable2str(pool, s), dep2str(pool, dep), solvable2str(pool, s2));
392 case SOLVER_PROBLEM_DEP_PROVIDERS_NOT_INSTALLABLE:
393 s = pool_id2solvable(pool, source);
394 printf(" package %s requires %s, but none of the providers can be installed\n", solvable2str(pool, s), dep2str(pool, dep));
396 case SOLVER_PROBLEM_SELF_CONFLICT:
397 s = pool_id2solvable(pool, source);
398 printf(" package %s conflicts with %s provided by itself\n", solvable2str(pool, s), dep2str(pool, dep));
408 if (!strcmp(id2str(pool, s->name), "libusb-compat-devel"))
410 solver_printdecisions(solv);