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/dependencies.h>
29 #include <pakfire/i18n.h>
30 #include <pakfire/logging.h>
31 #include <pakfire/pakfire.h>
32 #include <pakfire/private.h>
33 #include <pakfire/problem.h>
34 #include <pakfire/solution.h>
35 #include <pakfire/transaction.h>
36 #include <pakfire/util.h>
38 struct pakfire_problem
{
39 struct pakfire
* pakfire
;
42 struct pakfire_transaction
* transaction
;
49 static char* pakfire_problem_make_string(struct pakfire_problem
* problem
) {
50 Solver
* solver
= pakfire_transaction_get_solver(problem
->transaction
);
51 Pool
* pool
= solver
->pool
;
53 // Get the problem rule
54 Id rule
= solver_findproblemrule(solver
, problem
->id
);
56 // Extract some information about that rule
61 SolverRuleinfo type
= solver_ruleinfo(solver
, rule
, &source
, &target
, &dep
);
67 case SOLVER_RULE_DISTUPGRADE
:
68 r
= asprintf(&s
, _("%s does not belong to a distupgrade repository"),
69 pool_solvid2str(pool
, source
));
72 case SOLVER_RULE_INFARCH
:
73 r
= asprintf(&s
, _("%s has inferior architecture"),
74 pool_solvid2str(pool
, source
));
77 case SOLVER_RULE_UPDATE
:
78 r
= asprintf(&s
, _("problem with installed package %s"),
79 pool_solvid2str(pool
, source
));
83 r
= asprintf(&s
, _("conflicting requests"));
86 case SOLVER_RULE_JOB_UNSUPPORTED
:
87 r
= asprintf(&s
, _("unsupported request"));
90 case SOLVER_RULE_JOB_NOTHING_PROVIDES_DEP
:
91 r
= asprintf(&s
, _("nothing provides requested %s"),
92 pakfire_dep2str(problem
->pakfire
, dep
));
95 case SOLVER_RULE_JOB_UNKNOWN_PACKAGE
:
96 r
= asprintf(&s
, _("package %s does not exist"),
97 pakfire_dep2str(problem
->pakfire
, dep
));
100 case SOLVER_RULE_JOB_PROVIDED_BY_SYSTEM
:
101 r
= asprintf(&s
, _("%s is provided by the system"),
102 pakfire_dep2str(problem
->pakfire
, dep
));
105 case SOLVER_RULE_RPM
:
106 r
= asprintf(&s
, _("some dependency problem"));
109 case SOLVER_RULE_BEST
:
111 r
= asprintf(&s
, _("cannot install the best update candidate for package %s"),
112 pool_solvid2str(pool
, source
));
114 r
= asprintf(&s
, _("cannot install the best candidate for the job"));
117 case SOLVER_RULE_RPM_NOT_INSTALLABLE
:
118 r
= asprintf(&s
, _("package %s is not installable"),
119 pool_solvid2str(pool
, source
));
122 case SOLVER_RULE_RPM_NOTHING_PROVIDES_DEP
:
123 r
= asprintf(&s
, _("nothing provides %s needed by %s"),
124 pakfire_dep2str(problem
->pakfire
, dep
), pool_solvid2str(pool
, source
));
127 case SOLVER_RULE_RPM_SAME_NAME
:
128 r
= asprintf(&s
, _("cannot install both %s and %s"),
129 pool_solvid2str(pool
, source
), pool_solvid2str(pool
, target
));
132 case SOLVER_RULE_RPM_PACKAGE_CONFLICT
:
133 r
= asprintf(&s
, _("package %s conflicts with %s provided by %s"),
134 pool_solvid2str(pool
, source
), pakfire_dep2str(problem
->pakfire
, dep
),
135 pool_solvid2str(pool
, target
));
138 case SOLVER_RULE_RPM_PACKAGE_OBSOLETES
:
139 r
= asprintf(&s
, _("package %s obsoletes %s provided by %s"),
140 pool_solvid2str(pool
, source
), pakfire_dep2str(problem
->pakfire
, dep
),
141 pool_solvid2str(pool
, target
));
144 case SOLVER_RULE_RPM_INSTALLEDPKG_OBSOLETES
:
145 r
= asprintf(&s
, _("installed package %s obsoletes %s provided by %s"),
146 pool_solvid2str(pool
, source
), pakfire_dep2str(problem
->pakfire
, dep
),
147 pool_solvid2str(pool
, target
));
150 case SOLVER_RULE_RPM_IMPLICIT_OBSOLETES
:
151 r
= asprintf(&s
, _("package %s implicitely obsoletes %s provided by %s"),
152 pool_solvid2str(pool
, source
), pakfire_dep2str(problem
->pakfire
, dep
),
153 pool_solvid2str(pool
, target
));
156 case SOLVER_RULE_RPM_PACKAGE_REQUIRES
:
157 r
= asprintf(&s
, _("package %s requires %s, but none of the providers can be installed"),
158 pool_solvid2str(pool
, source
), pakfire_dep2str(problem
->pakfire
, dep
));
161 case SOLVER_RULE_RPM_SELF_CONFLICT
:
162 r
= asprintf(&s
, _("package %s conflicts with %s provided by itself"),
163 pool_solvid2str(pool
, source
), pakfire_dep2str(problem
->pakfire
, dep
));
166 case SOLVER_RULE_YUMOBS
:
167 r
= asprintf(&s
, _("both package %s and %s obsolete %s"),
168 pool_solvid2str(pool
, source
), pool_solvid2str(pool
, target
),
169 pakfire_dep2str(problem
->pakfire
, dep
));
172 case SOLVER_RULE_BLACK
:
173 r
= asprintf(&s
, _("package %s can only be installed by direct request"),
174 pool_solvid2str(pool
, source
));
177 case SOLVER_RULE_PKG_CONSTRAINS
:
178 r
= asprintf(&s
, _("package %s has constraint %s conflicting with %s"),
179 pool_solvid2str(pool
, source
), pakfire_dep2str(problem
->pakfire
, dep
),
180 pool_solvid2str(pool
, target
));
184 r
= asprintf(&s
, _("bad rule type"));
188 // Return nothing if asprintf failed
195 int pakfire_problem_create(struct pakfire_problem
** problem
,
196 struct pakfire
* pakfire
, struct pakfire_transaction
* transaction
, Id id
) {
197 struct pakfire_problem
* p
= calloc(1, sizeof(*p
));
201 p
->pakfire
= pakfire_ref(pakfire
);
204 p
->transaction
= pakfire_transaction_ref(transaction
);
207 // Fetch a reference to the solver
208 p
->solver
= pakfire_transaction_get_solver(transaction
);
214 PAKFIRE_EXPORT
struct pakfire_problem
* pakfire_problem_ref(struct pakfire_problem
* problem
) {
220 static void pakfire_problem_free(struct pakfire_problem
* problem
) {
221 if (problem
->transaction
)
222 pakfire_transaction_unref(problem
->transaction
);
224 free(problem
->string
);
225 pakfire_unref(problem
->pakfire
);
229 PAKFIRE_EXPORT
struct pakfire_problem
* pakfire_problem_unref(struct pakfire_problem
* problem
) {
230 if (--problem
->nrefs
> 0)
233 pakfire_problem_free(problem
);
237 struct pakfire
* pakfire_problem_get_pakfire(struct pakfire_problem
* problem
) {
238 return pakfire_ref(problem
->pakfire
);
241 PAKFIRE_EXPORT
const char* pakfire_problem_to_string(struct pakfire_problem
* problem
) {
242 if (!problem
->string
)
243 problem
->string
= pakfire_problem_make_string(problem
);
245 return problem
->string
;
248 Id
pakfire_problem_get_id(struct pakfire_problem
* problem
) {
252 struct pakfire_transaction
* pakfire_problem_get_transaction(struct pakfire_problem
* problem
) {
253 return pakfire_transaction_ref(problem
->transaction
);
256 PAKFIRE_EXPORT
struct pakfire_solution
** pakfire_problem_get_solutions(
257 struct pakfire_problem
* problem
) {
258 struct pakfire_solution
** solutions
= NULL
;
259 struct pakfire_solution
* solution
= NULL
;
260 unsigned int count
= 0;
264 // Fetch how many solutions we have
265 count
= solver_solution_count(problem
->solver
, problem
->id
);
269 // Allocate some space
270 solutions
= calloc(count
+ 1, sizeof(*solutions
));
276 for (unsigned int i
= 0; i
< count
; i
++) {
277 id
= solver_next_solution(problem
->solver
, problem
->id
, id
);
281 // Create a new solution
282 r
= pakfire_solution_create(&solution
, problem
->pakfire
, problem
, id
);
286 // Store the reference
287 solutions
[i
] = solution
;
293 ERROR_ERRNO(problem
->pakfire
, r
, "Could not import solutions: %m\n");
296 for (struct pakfire_solution
** s
= solutions
; *s
; s
++)
297 pakfire_solution_unref(*s
);