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 // Enable legacy logging
25 #define PAKFIRE_LEGACY_LOGGING
27 #include <pakfire/constants.h>
28 #include <pakfire/ctx.h>
29 #include <pakfire/dependencies.h>
30 #include <pakfire/i18n.h>
31 #include <pakfire/logging.h>
32 #include <pakfire/pakfire.h>
33 #include <pakfire/private.h>
34 #include <pakfire/problem.h>
35 #include <pakfire/solution.h>
36 #include <pakfire/transaction.h>
37 #include <pakfire/util.h>
39 struct pakfire_problem
{
40 struct pakfire_ctx
* ctx
;
41 struct pakfire
* pakfire
;
44 struct pakfire_transaction
* transaction
;
51 static char* pakfire_problem_make_string(struct pakfire_problem
* problem
) {
52 Solver
* solver
= pakfire_transaction_get_solver(problem
->transaction
);
53 Pool
* pool
= solver
->pool
;
55 // Get the problem rule
56 Id rule
= solver_findproblemrule(solver
, problem
->id
);
58 // Extract some information about that rule
63 SolverRuleinfo type
= solver_ruleinfo(solver
, rule
, &source
, &target
, &dep
);
69 case SOLVER_RULE_DISTUPGRADE
:
70 r
= asprintf(&s
, _("%s does not belong to a distupgrade repository"),
71 pool_solvid2str(pool
, source
));
74 case SOLVER_RULE_INFARCH
:
75 r
= asprintf(&s
, _("%s has inferior architecture"),
76 pool_solvid2str(pool
, source
));
79 case SOLVER_RULE_UPDATE
:
80 r
= asprintf(&s
, _("problem with installed package %s"),
81 pool_solvid2str(pool
, source
));
85 r
= asprintf(&s
, _("conflicting requests"));
88 case SOLVER_RULE_JOB_UNSUPPORTED
:
89 r
= asprintf(&s
, _("unsupported request"));
92 case SOLVER_RULE_JOB_NOTHING_PROVIDES_DEP
:
93 r
= asprintf(&s
, _("nothing provides requested %s"),
94 pakfire_dep2str(problem
->ctx
, pool
, dep
));
97 case SOLVER_RULE_JOB_UNKNOWN_PACKAGE
:
98 r
= asprintf(&s
, _("package %s does not exist"),
99 pakfire_dep2str(problem
->ctx
, pool
, dep
));
102 case SOLVER_RULE_JOB_PROVIDED_BY_SYSTEM
:
103 r
= asprintf(&s
, _("%s is provided by the system"),
104 pakfire_dep2str(problem
->ctx
, pool
, dep
));
107 case SOLVER_RULE_RPM
:
108 r
= asprintf(&s
, _("some dependency problem"));
111 case SOLVER_RULE_BEST
:
113 r
= asprintf(&s
, _("cannot install the best update candidate for package %s"),
114 pool_solvid2str(pool
, source
));
116 r
= asprintf(&s
, _("cannot install the best candidate for the job"));
119 case SOLVER_RULE_RPM_NOT_INSTALLABLE
:
120 r
= asprintf(&s
, _("package %s is not installable"),
121 pool_solvid2str(pool
, source
));
124 case SOLVER_RULE_RPM_NOTHING_PROVIDES_DEP
:
125 r
= asprintf(&s
, _("nothing provides %s needed by %s"),
126 pakfire_dep2str(problem
->ctx
, pool
, dep
), pool_solvid2str(pool
, source
));
129 case SOLVER_RULE_RPM_SAME_NAME
:
130 r
= asprintf(&s
, _("cannot install both %s and %s"),
131 pool_solvid2str(pool
, source
), pool_solvid2str(pool
, target
));
134 case SOLVER_RULE_RPM_PACKAGE_CONFLICT
:
135 r
= asprintf(&s
, _("package %s conflicts with %s provided by %s"),
136 pool_solvid2str(pool
, source
), pakfire_dep2str(problem
->ctx
, pool
, dep
),
137 pool_solvid2str(pool
, target
));
140 case SOLVER_RULE_RPM_PACKAGE_OBSOLETES
:
141 r
= asprintf(&s
, _("package %s obsoletes %s provided by %s"),
142 pool_solvid2str(pool
, source
), pakfire_dep2str(problem
->ctx
, pool
, dep
),
143 pool_solvid2str(pool
, target
));
146 case SOLVER_RULE_RPM_INSTALLEDPKG_OBSOLETES
:
147 r
= asprintf(&s
, _("installed package %s obsoletes %s provided by %s"),
148 pool_solvid2str(pool
, source
), pakfire_dep2str(problem
->ctx
, pool
, dep
),
149 pool_solvid2str(pool
, target
));
152 case SOLVER_RULE_RPM_IMPLICIT_OBSOLETES
:
153 r
= asprintf(&s
, _("package %s implicitely obsoletes %s provided by %s"),
154 pool_solvid2str(pool
, source
), pakfire_dep2str(problem
->ctx
, pool
, dep
),
155 pool_solvid2str(pool
, target
));
158 case SOLVER_RULE_RPM_PACKAGE_REQUIRES
:
159 r
= asprintf(&s
, _("package %s requires %s, but none of the providers can be installed"),
160 pool_solvid2str(pool
, source
), pakfire_dep2str(problem
->ctx
, pool
, dep
));
163 case SOLVER_RULE_RPM_SELF_CONFLICT
:
164 r
= asprintf(&s
, _("package %s conflicts with %s provided by itself"),
165 pool_solvid2str(pool
, source
), pakfire_dep2str(problem
->ctx
, pool
, dep
));
168 case SOLVER_RULE_YUMOBS
:
169 r
= asprintf(&s
, _("both package %s and %s obsolete %s"),
170 pool_solvid2str(pool
, source
), pool_solvid2str(pool
, target
),
171 pakfire_dep2str(problem
->ctx
, pool
, dep
));
174 case SOLVER_RULE_BLACK
:
175 r
= asprintf(&s
, _("package %s can only be installed by direct request"),
176 pool_solvid2str(pool
, source
));
179 case SOLVER_RULE_PKG_CONSTRAINS
:
180 r
= asprintf(&s
, _("package %s has constraint %s conflicting with %s"),
181 pool_solvid2str(pool
, source
), pakfire_dep2str(problem
->ctx
, pool
, dep
),
182 pool_solvid2str(pool
, target
));
186 r
= asprintf(&s
, _("bad rule type"));
190 // Return nothing if asprintf failed
197 int pakfire_problem_create(struct pakfire_problem
** problem
,
198 struct pakfire
* pakfire
, struct pakfire_transaction
* transaction
, Id id
) {
199 struct pakfire_problem
* p
= calloc(1, sizeof(*p
));
203 p
->ctx
= pakfire_ctx(pakfire
);
204 p
->pakfire
= pakfire_ref(pakfire
);
207 p
->transaction
= pakfire_transaction_ref(transaction
);
210 // Fetch a reference to the solver
211 p
->solver
= pakfire_transaction_get_solver(transaction
);
217 PAKFIRE_EXPORT
struct pakfire_problem
* pakfire_problem_ref(struct pakfire_problem
* problem
) {
223 static void pakfire_problem_free(struct pakfire_problem
* problem
) {
224 if (problem
->transaction
)
225 pakfire_transaction_unref(problem
->transaction
);
227 free(problem
->string
);
228 if (problem
->pakfire
)
229 pakfire_unref(problem
->pakfire
);
231 pakfire_ctx_unref(problem
->ctx
);
235 PAKFIRE_EXPORT
struct pakfire_problem
* pakfire_problem_unref(struct pakfire_problem
* problem
) {
236 if (--problem
->nrefs
> 0)
239 pakfire_problem_free(problem
);
243 struct pakfire
* pakfire_problem_get_pakfire(struct pakfire_problem
* problem
) {
244 return pakfire_ref(problem
->pakfire
);
247 PAKFIRE_EXPORT
const char* pakfire_problem_to_string(struct pakfire_problem
* problem
) {
248 if (!problem
->string
)
249 problem
->string
= pakfire_problem_make_string(problem
);
251 return problem
->string
;
254 Id
pakfire_problem_get_id(struct pakfire_problem
* problem
) {
258 struct pakfire_transaction
* pakfire_problem_get_transaction(struct pakfire_problem
* problem
) {
259 return pakfire_transaction_ref(problem
->transaction
);
262 PAKFIRE_EXPORT
struct pakfire_solution
** pakfire_problem_get_solutions(
263 struct pakfire_problem
* problem
) {
264 struct pakfire_solution
** solutions
= NULL
;
265 struct pakfire_solution
* solution
= NULL
;
266 unsigned int count
= 0;
270 // Fetch how many solutions we have
271 count
= solver_solution_count(problem
->solver
, problem
->id
);
275 // Allocate some space
276 solutions
= calloc(count
+ 1, sizeof(*solutions
));
282 for (unsigned int i
= 0; i
< count
; i
++) {
283 id
= solver_next_solution(problem
->solver
, problem
->id
, id
);
287 // Create a new solution
288 r
= pakfire_solution_create(&solution
, problem
->pakfire
, problem
, id
);
292 // Store the reference
293 solutions
[i
] = solution
;
299 ERROR_ERRNO(problem
->pakfire
, r
, "Could not import solutions: %m\n");
302 for (struct pakfire_solution
** s
= solutions
; *s
; s
++)
303 pakfire_solution_unref(*s
);