2 * Copyright (c) 2009-2015, SUSE LLC.
4 * This program is licensed under the BSD license, read LICENSE.BSD
5 * for further information
8 /* solv, a little software installer demoing the sat solver library */
11 * - understands globs for package names / dependencies
12 * - understands .arch suffix
13 * - installation of commandline packages
14 * - repository data caching
15 * - on demand loading of secondary repository data
16 * - gpg and checksum verification
19 * - fastestmirror implementation
21 * things available in the library but missing from solv:
22 * - vendor policy loading
23 * - multi version handling
29 #include <sys/utsname.h>
34 #include "selection.h"
37 #include "solverdebug.h"
38 #include "transaction.h"
41 #include "repo_autopattern.h"
45 #include "repoinfo_cache.h"
46 #include "repoinfo_download.h"
48 #if defined(ENABLE_RPMDB)
49 #include "fileprovides.h"
50 #include "fileconflicts.h"
53 #if defined(SUSE) || defined(FEDORA) || defined(MAGEIA)
54 #include "patchjobs.h"
66 pool_setarch(pool, un.machine);
71 yesno(const char *str, int other)
80 if (!(ip = fgets(inbuf, sizeof(inbuf), stdin)))
85 while (*ip == ' ' || *ip == '\t')
92 if (*ip == 'y' || *ip == 'n' || *ip == other)
93 return *ip == 'n' ? 0 : *ip;
99 nscallback(Pool *pool, void *data, Id name, Id evr)
102 if (name == NAMESPACE_LANGUAGE)
104 if (!strcmp(pool_id2str(pool, evr), "ja"))
106 if (!strcmp(pool_id2str(pool, evr), "de"))
108 if (!strcmp(pool_id2str(pool, evr), "en"))
110 if (!strcmp(pool_id2str(pool, evr), "en_US"))
120 showdiskusagechanges(Transaction *trans)
125 /* XXX: use mountpoints here */
126 memset(duc, 0, sizeof(duc));
128 duc[1].path = "/usr/share/man";
129 duc[2].path = "/sbin";
130 duc[3].path = "/etc";
131 transaction_calc_duchanges(trans, duc, 4);
132 for (i = 0; i < 4; i++)
133 if (duc[i].kbytes || duc[i].files)
134 printf("duchanges %s: %lld K %lld inodes\n", duc[i].path, duc[i].kbytes, duc[i].files);
139 doshowproof(Solver *solv, Id id, int flags, Queue *lq)
141 Pool *pool = solv->pool;
147 solver_get_decisionlist(solv, id, flags | SOLVER_DECISIONLIST_SORTED | SOLVER_DECISIONLIST_WITHINFO | SOLVER_DECISIONLIST_MERGEDINFO, &q);
148 for (i = 0; i < q.count; i += 8)
150 Id v = q.elements[i];
151 int reason = q.elements[i + 1], bits = q.elements[i + 3], type = q.elements[i + 4];
152 Id from = q.elements[i + 5], to = q.elements[i + 6], dep = q.elements[i + 7];
153 if (reason != SOLVER_REASON_UNSOLVABLE && type == SOLVER_RULE_PKG_SAME_NAME)
154 continue; /* do not show "obvious" decisions */
155 solver_decisionlist_solvables(solv, &q, i, &qp);
157 i += qp.count * 8 - 8;
158 if (reason == SOLVER_REASON_UNSOLVABLE)
159 printf("unsolvable: ");
161 printf("%s %s: ", v < 0 ? "conflicted" : "installed", pool_solvidset2str(pool, &qp));
164 printf("%s\n", solver_reason2str(solv, reason));
167 if (type == SOLVER_RULE_LEARNT && lq)
169 for (j = 0; j < lq->count; j++)
170 if (lq->elements[j] == q.elements[i + 2])
174 printf("learnt rule #%d\n", j + 1);
178 printf("%s\n", solver_decisioninfo2str(solv, bits, type, from, to, dep));
186 showproof(Solver *solv, int problem)
193 solver_get_learnt(solv, problem, SOLVER_DECISIONLIST_PROBLEM, &lq);
194 for (i = 0; i < lq.count; i++)
196 printf("Learnt rule #%d:\n", i + 1);
197 doshowproof(solv, lq.elements[i], SOLVER_DECISIONLIST_LEARNTRULE, &lq);
200 doshowproof(solv, problem, SOLVER_DECISIONLIST_PROBLEM, &lq);
205 find_repo(const char *name, Pool *pool, struct repoinfo *repoinfos, int nrepoinfos)
210 for (rp = name; *rp; rp++)
211 if (*rp <= '0' || *rp >= '9')
215 /* repo specified by number */
216 int rnum = atoi(name);
217 for (i = 0; i < nrepoinfos; i++)
219 struct repoinfo *cinfo = repoinfos + i;
220 if (!cinfo->enabled || !cinfo->repo)
223 return cinfo->repo->repoid;
228 /* repo specified by alias */
232 if (!strcasecmp(name, repo->name))
240 #define MODE_INSTALL 1
242 #define MODE_UPDATE 3
243 #define MODE_DISTUPGRADE 4
244 #define MODE_VERIFY 5
247 #define MODE_REPOLIST 8
248 #define MODE_SEARCH 9
253 fprintf(stderr, "Usage: solv COMMAND <select>\n");
254 fprintf(stderr, "\n");
255 fprintf(stderr, " dist-upgrade: replace installed packages with\n");
256 fprintf(stderr, " versions from the repositories\n");
257 fprintf(stderr, " erase: erase installed packages\n");
258 fprintf(stderr, " info: display package information\n");
259 fprintf(stderr, " install: install packages\n");
260 fprintf(stderr, " list: list packages\n");
261 fprintf(stderr, " repos: list enabled repositories\n");
262 fprintf(stderr, " search: search name/summary/description\n");
263 fprintf(stderr, " update: update installed packages\n");
264 fprintf(stderr, " verify: check dependencies of installed packages\n");
265 #if defined(SUSE) || defined(FEDORA) || defined(MAGEIA)
266 fprintf(stderr, " patch: install newest maintenance updates\n");
268 fprintf(stderr, "\n");
273 main(int argc, char **argv)
276 Repo *commandlinerepo = 0;
277 Id *commandlinepkgs = 0;
279 struct repoinfo *repoinfos, installedrepoinfo;
281 int mainmode = 0, mode = 0;
290 int archfilter_src = 0;
295 int keyname_depstr = 0;
296 int keyname_alldeps = 0; /* dnf repoquery --alldeps */
298 int answer, acnt = 0;
303 while (argc && !strcmp(argv[0], "-d"))
311 if (!strcmp(argv[0], "install") || !strcmp(argv[0], "in"))
313 mainmode = MODE_INSTALL;
314 mode = SOLVER_INSTALL;
316 #if defined(SUSE) || defined(FEDORA) || defined(MAGEIA)
317 else if (!strcmp(argv[0], "patch"))
319 mainmode = MODE_PATCH;
320 mode = SOLVER_INSTALL;
323 else if (!strcmp(argv[0], "erase") || !strcmp(argv[0], "rm"))
325 mainmode = MODE_ERASE;
328 else if (!strcmp(argv[0], "list") || !strcmp(argv[0], "ls"))
330 mainmode = MODE_LIST;
333 else if (!strcmp(argv[0], "info"))
335 mainmode = MODE_INFO;
338 else if (!strcmp(argv[0], "search") || !strcmp(argv[0], "se"))
340 mainmode = MODE_SEARCH;
343 else if (!strcmp(argv[0], "verify"))
345 mainmode = MODE_VERIFY;
346 mode = SOLVER_VERIFY;
348 else if (!strcmp(argv[0], "update") || !strcmp(argv[0], "up"))
350 mainmode = MODE_UPDATE;
351 mode = SOLVER_UPDATE;
353 else if (!strcmp(argv[0], "dist-upgrade") || !strcmp(argv[0], "dup"))
355 mainmode = MODE_DISTUPGRADE;
356 mode = SOLVER_DISTUPGRADE;
358 else if (!strcmp(argv[0], "repos") || !strcmp(argv[0], "repolist") || !strcmp(argv[0], "lr"))
360 mainmode = MODE_REPOLIST;
368 if (argc > 2 && !strcmp(argv[1], "--root"))
374 else if (argc > 1 && !strcmp(argv[1], "--clean"))
380 else if (argc > 1 && !strcmp(argv[1], "--best"))
386 else if (argc > 1 && !strcmp(argv[1], "--alldeps"))
388 keyname_alldeps = 1; /* dnf repoquery --alldeps */
392 else if (argc > 1 && !strcmp(argv[1], "--depstr"))
394 keyname_depstr = 1; /* do literal matching instead of dep intersection */
398 else if (argc > 2 && !strcmp(argv[1], "--keyname"))
404 else if (argc > 2 && !strcmp(argv[1], "--testcase"))
415 pool = pool_create();
416 pool_set_rootdir(pool, rootdir);
420 const char *langs[] = {"de_DE", "de", "en"};
421 pool_set_languages(pool, langs, sizeof(langs)/sizeof(*langs));
425 pool_setloadcallback(pool, load_stub, 0);
427 pool->nscallback = nscallback;
430 pool_setdebuglevel(pool, debuglevel);
432 pool_set_flag(pool, POOL_FLAG_ADDFILEPROVIDESFILTERED, 1);
433 repoinfos = read_repoinfos(pool, &nrepoinfos);
434 sort_repoinfos(repoinfos, nrepoinfos);
436 if (mainmode == MODE_REPOLIST)
439 for (i = 0; i < nrepoinfos; i++)
441 struct repoinfo *cinfo = repoinfos + i;
444 printf("%d: %-20s %s (prio %d)\n", j++, cinfo->alias, cinfo->name, cinfo->priority);
448 memset(&installedrepoinfo, 0, sizeof(installedrepoinfo));
449 if (!read_installed_repo(&installedrepoinfo, pool))
451 read_repos(pool, repoinfos, nrepoinfos);
454 queue_init(&repofilter);
455 queue_init(&kindfilter);
456 queue_init(&archfilter);
459 if (!strcmp(argv[1], "-i"))
461 queue_push2(&repofilter, SOLVER_SOLVABLE_REPO | SOLVER_SETREPO, pool->installed->repoid);
465 else if (argc > 2 && (!strcmp(argv[1], "-r") || !strcmp(argv[1], "--repo")))
467 Id repoid = find_repo(argv[2], pool, repoinfos, nrepoinfos);
470 fprintf(stderr, "%s: no such repo\n", argv[2]);
473 /* SETVENDOR is actually wrong but useful */
474 queue_push2(&repofilter, SOLVER_SOLVABLE_REPO | SOLVER_SETREPO | SOLVER_SETVENDOR, repoid);
478 else if (argc > 2 && !strcmp(argv[1], "--arch"))
480 if (!strcmp(argv[2], "src") || !strcmp(argv[2], "nosrc"))
482 queue_push2(&archfilter, SOLVER_SOLVABLE_PROVIDES, pool_rel2id(pool, 0, pool_str2id(pool, argv[2], 1), REL_ARCH, 1));
486 else if (argc > 2 && (!strcmp(argv[1], "-t") || !strcmp(argv[1], "--type")))
488 const char *kind = argv[2];
489 if (!strcmp(kind, "srcpackage"))
491 /* hey! should use --arch! */
492 queue_push2(&archfilter, SOLVER_SOLVABLE_PROVIDES, pool_rel2id(pool, 0, ARCH_SRC, REL_ARCH, 1));
498 if (!strcmp(kind, "package"))
500 if (!strcmp(kind, "all"))
501 queue_push2(&kindfilter, SOLVER_SOLVABLE_ALL, 0);
503 queue_push2(&kindfilter, SOLVER_SOLVABLE_PROVIDES, pool_rel2id(pool, 0, pool_str2id(pool, kind, 1), REL_KIND, 1));
511 if (mainmode == MODE_SEARCH)
517 pool_createwhatprovides(pool);
519 dataiterator_init(&di, pool, 0, 0, 0, argv[1], SEARCH_SUBSTRING|SEARCH_NOCASE);
520 dataiterator_set_keyname(&di, SOLVABLE_NAME);
521 dataiterator_set_search(&di, 0, 0);
522 while (dataiterator_step(&di))
523 queue_push2(&sel, SOLVER_SOLVABLE, di.solvid);
524 dataiterator_set_keyname(&di, SOLVABLE_SUMMARY);
525 dataiterator_set_search(&di, 0, 0);
526 while (dataiterator_step(&di))
527 queue_push2(&sel, SOLVER_SOLVABLE, di.solvid);
528 dataiterator_set_keyname(&di, SOLVABLE_DESCRIPTION);
529 dataiterator_set_search(&di, 0, 0);
530 while (dataiterator_step(&di))
531 queue_push2(&sel, SOLVER_SOLVABLE, di.solvid);
532 dataiterator_free(&di);
533 if (repofilter.count)
534 selection_filter(pool, &sel, &repofilter);
535 if (archfilter.count)
536 selection_filter(pool, &sel, &archfilter);
537 if (kindfilter.count)
538 selection_filter(pool, &sel, &kindfilter);
541 selection_solvables(pool, &sel, &q);
543 for (i = 0; i < q.count; i++)
545 Solvable *s = pool_id2solvable(pool, q.elements[i]);
546 printf(" - %s [%s]: %s\n", pool_solvable2str(pool, s), s->repo->name, solvable_lookup_str(s, SOLVABLE_SUMMARY));
552 /* process command line packages */
553 if (mainmode == MODE_LIST || mainmode == MODE_INFO || mainmode == MODE_INSTALL)
555 for (i = 1; i < argc; i++)
557 if (!is_cmdline_package((const char *)argv[i]))
559 if (access(argv[i], R_OK))
564 if (!commandlinepkgs)
565 commandlinepkgs = solv_calloc(argc, sizeof(Id));
566 if (!commandlinerepo)
567 commandlinerepo = repo_create(pool, "@commandline");
568 p = add_cmdline_package(commandlinerepo, (const char *)argv[i]);
571 fprintf(stderr, "could not add '%s'\n", argv[i]);
574 commandlinepkgs[i] = p;
578 repo_internalize(commandlinerepo);
580 repo_add_autopattern(commandlinerepo, 0);
585 #if defined(ENABLE_RPMDB)
586 if (pool->disttype == DISTTYPE_RPM)
587 addfileprovides(pool);
589 pool_createwhatprovides(pool);
592 keyname = solv_dupjoin("solvable:", keyname, 0);
594 for (i = 1; i < argc; i++)
599 if (commandlinepkgs && commandlinepkgs[i])
601 queue_push2(&job, SOLVER_SOLVABLE, commandlinepkgs[i]);
605 flags = SELECTION_NAME|SELECTION_PROVIDES|SELECTION_GLOB;
606 flags |= SELECTION_CANON|SELECTION_DOTARCH|SELECTION_REL;
607 if (kindfilter.count)
608 flags |= SELECTION_SKIP_KIND;
609 if (mode == MODE_LIST || archfilter_src)
610 flags |= SELECTION_WITH_SOURCE;
611 if (argv[i][0] == '/')
612 flags |= SELECTION_FILELIST | (mode == MODE_ERASE ? SELECTION_INSTALLED_ONLY : 0);
613 if (keyname && keyname_depstr)
614 flags |= SELECTION_MATCH_DEPSTR;
615 if (!keyname || keyname_alldeps)
616 rflags = selection_make(pool, &job2, argv[i], flags);
618 rflags = selection_make_matchdeps(pool, &job2, argv[i], flags, pool_str2id(pool, keyname, 1), 0);
619 if (repofilter.count)
620 selection_filter(pool, &job2, &repofilter);
621 if (archfilter.count)
622 selection_filter(pool, &job2, &archfilter);
623 if (kindfilter.count)
624 selection_filter(pool, &job2, &kindfilter);
627 flags |= SELECTION_NOCASE;
628 if (!keyname || keyname_alldeps)
629 rflags = selection_make(pool, &job2, argv[i], flags);
631 rflags = selection_make_matchdeps(pool, &job2, argv[i], flags, pool_str2id(pool, keyname, 1), 0);
632 if (repofilter.count)
633 selection_filter(pool, &job2, &repofilter);
634 if (archfilter.count)
635 selection_filter(pool, &job2, &archfilter);
636 if (kindfilter.count)
637 selection_filter(pool, &job2, &kindfilter);
639 printf("[ignoring case for '%s']\n", argv[i]);
643 fprintf(stderr, "nothing matches '%s'\n", argv[i]);
646 if (rflags & SELECTION_FILELIST)
647 printf("[using file list match for '%s']\n", argv[i]);
648 if (rflags & SELECTION_PROVIDES)
649 printf("[using capability match for '%s']\n", argv[i]);
650 if (keyname && keyname_alldeps)
654 selection_solvables(pool, &job2, &q);
655 selection_make_matchsolvablelist(pool, &job2, &q, 0, pool_str2id(pool, keyname, 1), 0);
658 queue_insertn(&job, job.count, job2.count, job2.elements);
661 keyname = solv_free(keyname);
663 if (!job.count && (mainmode == MODE_UPDATE || mainmode == MODE_DISTUPGRADE || mainmode == MODE_VERIFY || repofilter.count || archfilter.count || kindfilter.count))
665 queue_push2(&job, SOLVER_SOLVABLE_ALL, 0);
666 if (repofilter.count)
667 selection_filter(pool, &job, &repofilter);
668 if (archfilter.count)
669 selection_filter(pool, &job, &archfilter);
670 if (kindfilter.count)
671 selection_filter(pool, &job, &kindfilter);
673 queue_free(&repofilter);
674 queue_free(&archfilter);
675 queue_free(&kindfilter);
677 if (!job.count && mainmode != MODE_PATCH)
679 printf("no package matched\n");
683 if (mainmode == MODE_LIST || mainmode == MODE_INFO)
685 /* list mode, no solver needed */
688 for (i = 0; i < job.count; i += 2)
692 pool_job2solvables(pool, &q, job.elements[i], job.elements[i + 1]);
693 for (j = 0; j < q.count; j++)
695 Solvable *s = pool_id2solvable(pool, q.elements[j]);
696 if (mainmode == MODE_INFO)
699 printf("Name: %s\n", pool_solvable2str(pool, s));
700 printf("Repo: %s\n", s->repo->name);
701 printf("Summary: %s\n", solvable_lookup_str(s, SOLVABLE_SUMMARY));
702 str = solvable_lookup_str(s, SOLVABLE_URL);
704 printf("Url: %s\n", str);
705 str = solvable_lookup_str(s, SOLVABLE_LICENSE);
707 printf("License: %s\n", str);
708 printf("Description:\n%s\n", solvable_lookup_str(s, SOLVABLE_DESCRIPTION));
714 const char *sum = solvable_lookup_str_lang(s, SOLVABLE_SUMMARY, "de", 1);
716 const char *sum = solvable_lookup_str_poollang(s, SOLVABLE_SUMMARY);
718 printf(" - %s [%s]\n", pool_solvable2str(pool, s), s->repo->name);
720 printf(" %s\n", sum);
727 free_repoinfos(repoinfos, nrepoinfos);
728 solv_free(commandlinepkgs);
732 #if defined(SUSE) || defined(FEDORA) || defined(MAGEIA)
733 if (mainmode == MODE_PATCH)
734 add_patchjobs(pool, &job);
738 for (i = 0; i < job.count; i += 2)
740 job.elements[i] |= mode;
741 if (mode == SOLVER_UPDATE && pool_isemptyupdatejob(pool, job.elements[i], job.elements[i + 1]))
742 job.elements[i] ^= SOLVER_UPDATE ^ SOLVER_INSTALL;
744 job.elements[i] |= SOLVER_CLEANDEPS;
746 job.elements[i] |= SOLVER_FORCEBEST;
751 queue_push2(&job, SOLVER_MULTIVERSION|SOLVER_SOLVABLE_PROVIDES, pool_str2id(pool, "multiversion(kernel)", 1));
754 queue_push2(&job, SOLVER_INSTALL|SOLVER_SOLVABLE_PROVIDES, pool_rel2id(pool, NAMESPACE_LANGUAGE, 0, REL_NAMESPACE, 1));
755 queue_push2(&job, SOLVER_ERASE|SOLVER_CLEANDEPS|SOLVER_SOLVABLE_PROVIDES, pool_rel2id(pool, NAMESPACE_LANGUAGE, 0, REL_NAMESPACE, 1));
759 solv = solver_create(pool);
760 solver_set_flag(solv, SOLVER_FLAG_SPLITPROVIDES, 1);
762 solver_set_flag(solv, SOLVER_FLAG_IGNORE_RECOMMENDED, 1);
764 #if defined(FEDORA) || defined(MAGEIA)
765 solver_set_flag(solv, SOLVER_FLAG_ALLOW_VENDORCHANGE, 1);
767 if (mainmode == MODE_ERASE)
768 solver_set_flag(solv, SOLVER_FLAG_ALLOW_UNINSTALL, 1); /* don't nag */
769 solver_set_flag(solv, SOLVER_FLAG_BEST_OBEY_POLICY, 1);
773 Id problem, solution;
776 pcnt = solver_solve(solv, &job);
779 printf("Writing solver testcase:\n");
780 if (!testcase_write(solv, testcase, TESTCASE_RESULT_TRANSACTION | TESTCASE_RESULT_PROBLEMS, 0, 0))
781 printf("%s\n", pool_errstr(pool));
786 pcnt = solver_problem_count(solv);
787 printf("Found %d problems:\n", pcnt);
788 for (problem = 1; problem <= pcnt; problem++)
791 printf("Problem %d/%d:\n%s\n\n", problem, pcnt, solver_problem2str(solv, problem));
792 scnt = solver_solution_count(solv, problem);
793 for (solution = 1; solution <= scnt; solution++)
796 printf("Solution %d:\n", solution);
798 solver_all_solutionelements(solv, problem, solution, 1, &sq);
799 for (i = 0; i < sq.count; i += 3)
800 printf(" - %s\n", solver_solutionelementtype2str(solv, sq.elements[i], sq.elements[i + 1], sq.elements[i + 2]));
806 char inbuf[128], *ip;
807 printf("Please choose a solution: ");
810 if (!(ip = fgets(inbuf, sizeof(inbuf), stdin)))
815 while (*ip == ' ' || *ip == '\t')
817 if (*ip >= '0' && *ip <= '9')
820 if (take >= 1 && take <= scnt)
829 showproof(solv, problem);
838 solver_take_solution(solv, problem, take, &job);
842 trans = solver_create_transaction(solv);
843 if (!trans->steps.count)
845 printf("Nothing to do.\n");
846 transaction_free(trans);
850 free_repoinfos(repoinfos, nrepoinfos);
851 solv_free(commandlinepkgs);
855 /* display transaction to the user and ask for confirmation */
857 printf("Transaction summary:\n\n");
858 transaction_print(trans);
860 showdiskusagechanges(trans);
862 printf("install size change: %lld K\n", transaction_calc_installsizechange(trans));
865 acnt = solver_alternatives_count(solv);
869 printf("Have one alternative:\n");
871 printf("Have %d alternatives:\n", acnt);
872 for (i = 1; i <= acnt; i++)
875 int atype = solver_get_alternative(solv, i, &id, &from, 0, 0, 0);
876 printf(" - %s\n", solver_alternative2str(solv, atype, id, from));
879 answer = yesno("OK to continue (y/n/a)? ", 'a');
882 answer = yesno("OK to continue (y/n)? ", 0);
890 queue_init(&choicesq);
891 queue_init(&answerq);
892 for (i = 1; i <= acnt; i++)
894 int atype = solver_get_alternative(solv, i, &id, &from, &chosen, &choicesq, 0);
895 printf("\n%s\n", solver_alternative2str(solv, atype, id, from));
896 for (j = 0; j < choicesq.count; j++)
898 Id p = choicesq.elements[j];
901 queue_push(&answerq, p);
902 printf("%6d: %s\n", answerq.count, pool_solvid2str(pool, p));
905 queue_free(&choicesq);
909 char inbuf[128], *ip;
911 printf("OK to continue (y/n), or number to change alternative: ");
914 if (!(ip = fgets(inbuf, sizeof(inbuf), stdin)))
919 while (*ip == ' ' || *ip == '\t')
921 if (*ip == '-' && ip[1] >= '0' && ip[1] <= '9')
926 if (*ip >= '0' && *ip <= '9')
929 if (take > 0 && take <= answerq.count)
931 Id p = answerq.elements[take - 1];
932 queue_free(&answerq);
933 queue_push2(&job, (neg ? SOLVER_DISFAVOR : SOLVER_FAVOR) | SOLVER_SOLVABLE_NAME, pool->solvables[p].name);
940 if (*ip == 'n' || *ip == 'y')
942 answer = *ip == 'n' ? 0 : *ip;
946 queue_free(&answerq);
951 transaction_free(trans);
955 free_repoinfos(repoinfos, nrepoinfos);
956 solv_free(commandlinepkgs);
960 /* download all new packages */
962 newpkgs = transaction_installedresult(trans, &checkq);
966 int downloadsize = 0;
967 for (i = 0; i < newpkgs; i++)
971 p = checkq.elements[i];
972 s = pool_id2solvable(pool, p);
973 downloadsize += solvable_lookup_sizek(s, SOLVABLE_DOWNLOADSIZE, 0);
975 printf("Downloading %d packages, %d K\n", newpkgs, downloadsize);
976 newpkgsfps = solv_calloc(newpkgs, sizeof(*newpkgsfps));
977 for (i = 0; i < newpkgs; i++)
981 struct repoinfo *cinfo;
983 p = checkq.elements[i];
984 s = pool_id2solvable(pool, p);
985 if (s->repo == commandlinerepo)
987 loc = solvable_lookup_location(s, 0);
990 if (!(newpkgsfps[i] = fopen(loc, "r")))
998 cinfo = s->repo->appdata;
999 if (!cinfo || cinfo->type == TYPE_INSTALLED)
1001 printf("%s: no repository information\n", s->repo->name);
1004 loc = solvable_lookup_location(s, 0);
1006 continue; /* pseudo package? */
1007 #if defined(ENABLE_RPMDB)
1008 if (pool->installed && pool->installed->nsolvables)
1010 if ((newpkgsfps[i] = trydeltadownload(s, loc)) != 0)
1014 continue; /* delta worked! */
1018 if ((newpkgsfps[i] = downloadpackage(s, loc)) == 0)
1020 printf("\n%s: %s not found in repository\n", s->repo->name, loc);
1029 #if defined(ENABLE_RPMDB) && (defined(SUSE) || defined(FEDORA) || defined(MANDRIVA) || defined(MAGEIA))
1030 /* check for file conflicts */
1034 queue_init(&conflicts);
1035 if (checkfileconflicts(pool, &checkq, newpkgs, newpkgsfps, &conflicts))
1037 if (yesno("Re-run solver (y/n/q)? ", 0))
1039 for (i = 0; i < newpkgs; i++)
1041 fclose(newpkgsfps[i]);
1042 newpkgsfps = solv_free(newpkgsfps);
1045 pool_add_fileconflicts_deps(pool, &conflicts);
1046 queue_free(&conflicts);
1050 queue_free(&conflicts);
1054 /* and finally commit the transaction */
1055 printf("Committing transaction:\n\n");
1056 transaction_order(trans, 0);
1057 for (i = 0; i < trans->steps.count; i++)
1063 p = trans->steps.elements[i];
1064 type = transaction_type(trans, p, SOLVER_TRANSACTION_RPM_ONLY);
1067 case SOLVER_TRANSACTION_ERASE:
1068 printf("erase %s\n", pool_solvid2str(pool, p));
1069 commit_transactionelement(pool, type, p, 0);
1071 case SOLVER_TRANSACTION_INSTALL:
1072 case SOLVER_TRANSACTION_MULTIINSTALL:
1073 printf("install %s\n", pool_solvid2str(pool, p));
1074 for (j = 0; j < newpkgs; j++)
1075 if (checkq.elements[j] == p)
1077 fp = j < newpkgs ? newpkgsfps[j] : 0;
1080 commit_transactionelement(pool, type, p, fp);
1089 for (i = 0; i < newpkgs; i++)
1091 fclose(newpkgsfps[i]);
1092 solv_free(newpkgsfps);
1093 queue_free(&checkq);
1094 transaction_free(trans);
1098 free_repoinfos(repoinfos, nrepoinfos);
1099 solv_free(commandlinepkgs);