1 /*#############################################################################
3 # Pakfire - The IPFire package management system #
4 # Copyright (C) 2017 Pakfire development team #
6 # This program is free software: you can redistribute it and/or modify #
7 # it under the terms of the GNU General Public License as published by #
8 # the Free Software Foundation, either version 3 of the License, or #
9 # (at your option) any later version. #
11 # This program is distributed in the hope that it will be useful, #
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of #
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
14 # GNU General Public License for more details. #
16 # You should have received a copy of the GNU General Public License #
17 # along with this program. If not, see <http://www.gnu.org/licenses/>. #
19 #############################################################################*/
24 #include <pakfire/constants.h>
25 #include <pakfire/dependencies.h>
26 #include <pakfire/i18n.h>
27 #include <pakfire/logging.h>
28 #include <pakfire/pakfire.h>
29 #include <pakfire/private.h>
30 #include <pakfire/problem.h>
31 #include <pakfire/solution.h>
32 #include <pakfire/transaction.h>
33 #include <pakfire/util.h>
35 struct pakfire_problem
{
36 struct pakfire
* pakfire
;
39 struct pakfire_transaction
* transaction
;
46 static char* pakfire_problem_make_string(struct pakfire_problem
* problem
) {
47 Solver
* solver
= pakfire_transaction_get_solver(problem
->transaction
);
48 Pool
* pool
= solver
->pool
;
50 // Get the problem rule
51 Id rule
= solver_findproblemrule(solver
, problem
->id
);
53 // Extract some information about that rule
58 SolverRuleinfo type
= solver_ruleinfo(solver
, rule
, &source
, &target
, &dep
);
64 case SOLVER_RULE_DISTUPGRADE
:
65 r
= asprintf(&s
, _("%s does not belong to a distupgrade repository"),
66 pool_solvid2str(pool
, source
));
69 case SOLVER_RULE_INFARCH
:
70 r
= asprintf(&s
, _("%s has inferior architecture"),
71 pool_solvid2str(pool
, source
));
74 case SOLVER_RULE_UPDATE
:
75 r
= asprintf(&s
, _("problem with installed package %s"),
76 pool_solvid2str(pool
, source
));
80 r
= asprintf(&s
, _("conflicting requests"));
83 case SOLVER_RULE_JOB_UNSUPPORTED
:
84 r
= asprintf(&s
, _("unsupported request"));
87 case SOLVER_RULE_JOB_NOTHING_PROVIDES_DEP
:
88 r
= asprintf(&s
, _("nothing provides requested %s"),
89 pakfire_dep2str(problem
->pakfire
, dep
));
92 case SOLVER_RULE_JOB_UNKNOWN_PACKAGE
:
93 r
= asprintf(&s
, _("package %s does not exist"),
94 pakfire_dep2str(problem
->pakfire
, dep
));
97 case SOLVER_RULE_JOB_PROVIDED_BY_SYSTEM
:
98 r
= asprintf(&s
, _("%s is provided by the system"),
99 pakfire_dep2str(problem
->pakfire
, dep
));
102 case SOLVER_RULE_RPM
:
103 r
= asprintf(&s
, _("some dependency problem"));
106 case SOLVER_RULE_BEST
:
108 r
= asprintf(&s
, _("cannot install the best update candidate for package %s"),
109 pool_solvid2str(pool
, source
));
111 r
= asprintf(&s
, _("cannot install the best candidate for the job"));
114 case SOLVER_RULE_RPM_NOT_INSTALLABLE
:
115 r
= asprintf(&s
, _("package %s is not installable"),
116 pool_solvid2str(pool
, source
));
119 case SOLVER_RULE_RPM_NOTHING_PROVIDES_DEP
:
120 r
= asprintf(&s
, _("nothing provides %s needed by %s"),
121 pakfire_dep2str(problem
->pakfire
, dep
), pool_solvid2str(pool
, source
));
124 case SOLVER_RULE_RPM_SAME_NAME
:
125 r
= asprintf(&s
, _("cannot install both %s and %s"),
126 pool_solvid2str(pool
, source
), pool_solvid2str(pool
, target
));
129 case SOLVER_RULE_RPM_PACKAGE_CONFLICT
:
130 r
= asprintf(&s
, _("package %s conflicts with %s provided by %s"),
131 pool_solvid2str(pool
, source
), pakfire_dep2str(problem
->pakfire
, dep
),
132 pool_solvid2str(pool
, target
));
135 case SOLVER_RULE_RPM_PACKAGE_OBSOLETES
:
136 r
= asprintf(&s
, _("package %s obsoletes %s provided by %s"),
137 pool_solvid2str(pool
, source
), pakfire_dep2str(problem
->pakfire
, dep
),
138 pool_solvid2str(pool
, target
));
141 case SOLVER_RULE_RPM_INSTALLEDPKG_OBSOLETES
:
142 r
= asprintf(&s
, _("installed package %s obsoletes %s provided by %s"),
143 pool_solvid2str(pool
, source
), pakfire_dep2str(problem
->pakfire
, dep
),
144 pool_solvid2str(pool
, target
));
147 case SOLVER_RULE_RPM_IMPLICIT_OBSOLETES
:
148 r
= asprintf(&s
, _("package %s implicitely obsoletes %s provided by %s"),
149 pool_solvid2str(pool
, source
), pakfire_dep2str(problem
->pakfire
, dep
),
150 pool_solvid2str(pool
, target
));
153 case SOLVER_RULE_RPM_PACKAGE_REQUIRES
:
154 r
= asprintf(&s
, _("package %s requires %s, but none of the providers can be installed"),
155 pool_solvid2str(pool
, source
), pakfire_dep2str(problem
->pakfire
, dep
));
158 case SOLVER_RULE_RPM_SELF_CONFLICT
:
159 r
= asprintf(&s
, _("package %s conflicts with %s provided by itself"),
160 pool_solvid2str(pool
, source
), pakfire_dep2str(problem
->pakfire
, dep
));
163 case SOLVER_RULE_YUMOBS
:
164 r
= asprintf(&s
, _("both package %s and %s obsolete %s"),
165 pool_solvid2str(pool
, source
), pool_solvid2str(pool
, target
),
166 pakfire_dep2str(problem
->pakfire
, dep
));
169 case SOLVER_RULE_BLACK
:
170 r
= asprintf(&s
, _("package %s can only be installed by direct request"),
171 pool_solvid2str(pool
, source
));
174 case SOLVER_RULE_PKG_CONSTRAINS
:
175 r
= asprintf(&s
, _("package %s has constraint %s conflicting with %s"),
176 pool_solvid2str(pool
, source
), pakfire_dep2str(problem
->pakfire
, dep
),
177 pool_solvid2str(pool
, target
));
181 r
= asprintf(&s
, _("bad rule type"));
185 // Return nothing if asprintf failed
192 int pakfire_problem_create(struct pakfire_problem
** problem
,
193 struct pakfire
* pakfire
, struct pakfire_transaction
* transaction
, Id id
) {
194 struct pakfire_problem
* p
= calloc(1, sizeof(*p
));
198 p
->pakfire
= pakfire_ref(pakfire
);
201 p
->transaction
= pakfire_transaction_ref(transaction
);
204 // Fetch a reference to the solver
205 p
->solver
= pakfire_transaction_get_solver(transaction
);
211 PAKFIRE_EXPORT
struct pakfire_problem
* pakfire_problem_ref(struct pakfire_problem
* problem
) {
217 static void pakfire_problem_free(struct pakfire_problem
* problem
) {
218 if (problem
->transaction
)
219 pakfire_transaction_unref(problem
->transaction
);
221 free(problem
->string
);
222 pakfire_unref(problem
->pakfire
);
226 PAKFIRE_EXPORT
struct pakfire_problem
* pakfire_problem_unref(struct pakfire_problem
* problem
) {
227 if (--problem
->nrefs
> 0)
230 pakfire_problem_free(problem
);
234 struct pakfire
* pakfire_problem_get_pakfire(struct pakfire_problem
* problem
) {
235 return pakfire_ref(problem
->pakfire
);
238 PAKFIRE_EXPORT
const char* pakfire_problem_to_string(struct pakfire_problem
* problem
) {
239 if (!problem
->string
)
240 problem
->string
= pakfire_problem_make_string(problem
);
242 return problem
->string
;
245 Id
pakfire_problem_get_id(struct pakfire_problem
* problem
) {
249 struct pakfire_transaction
* pakfire_problem_get_transaction(struct pakfire_problem
* problem
) {
250 return pakfire_transaction_ref(problem
->transaction
);
253 PAKFIRE_EXPORT
struct pakfire_solution
** pakfire_problem_get_solutions(
254 struct pakfire_problem
* problem
) {
255 struct pakfire_solution
** solutions
= NULL
;
256 struct pakfire_solution
* solution
= NULL
;
257 unsigned int count
= 0;
261 // Fetch how many solutions we have
262 count
= solver_solution_count(problem
->solver
, problem
->id
);
266 // Allocate some space
267 solutions
= calloc(count
+ 1, sizeof(*solutions
));
273 for (unsigned int i
= 0; i
< count
; i
++) {
274 id
= solver_next_solution(problem
->solver
, problem
->id
, id
);
278 // Create a new solution
279 r
= pakfire_solution_create(&solution
, problem
->pakfire
, problem
, id
);
283 // Store the reference
284 solutions
[i
] = solution
;
290 ERROR_ERRNO(problem
->pakfire
, r
, "Could not import solutions: %m\n");
293 for (struct pakfire_solution
** s
= solutions
; *s
; s
++)
294 pakfire_solution_unref(*s
);