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 #############################################################################*/
23 #include <pakfire/constants.h>
24 #include <pakfire/dependencies.h>
25 #include <pakfire/i18n.h>
26 #include <pakfire/logging.h>
27 #include <pakfire/pakfire.h>
28 #include <pakfire/private.h>
29 #include <pakfire/problem.h>
30 #include <pakfire/request.h>
31 #include <pakfire/solution.h>
32 #include <pakfire/util.h>
34 struct pakfire_problem
{
35 struct pakfire
* pakfire
;
38 struct pakfire_request
* request
;
43 static char* pakfire_problem_make_string(struct pakfire_problem
* problem
) {
44 Solver
* solver
= pakfire_request_get_solver(problem
->request
);
45 Pool
* pool
= solver
->pool
;
47 // Get the problem rule
48 Id rule
= solver_findproblemrule(solver
, problem
->id
);
50 // Extract some information about that rule
55 SolverRuleinfo type
= solver_ruleinfo(solver
, rule
, &source
, &target
, &dep
);
61 case SOLVER_RULE_DISTUPGRADE
:
62 r
= asprintf(&s
, _("%s does not belong to a distupgrade repository"),
63 pool_solvid2str(pool
, source
));
66 case SOLVER_RULE_INFARCH
:
67 r
= asprintf(&s
, _("%s has inferior architecture"),
68 pool_solvid2str(pool
, source
));
71 case SOLVER_RULE_UPDATE
:
72 r
= asprintf(&s
, _("problem with installed package %s"),
73 pool_solvid2str(pool
, source
));
77 r
= asprintf(&s
, _("conflicting requests"));
80 case SOLVER_RULE_JOB_UNSUPPORTED
:
81 r
= asprintf(&s
, _("unsupported request"));
84 case SOLVER_RULE_JOB_NOTHING_PROVIDES_DEP
:
85 r
= asprintf(&s
, _("nothing provides requested %s"),
86 pakfire_dep2str(problem
->pakfire
, dep
));
89 case SOLVER_RULE_JOB_UNKNOWN_PACKAGE
:
90 r
= asprintf(&s
, _("package %s does not exist"),
91 pakfire_dep2str(problem
->pakfire
, dep
));
94 case SOLVER_RULE_JOB_PROVIDED_BY_SYSTEM
:
95 r
= asprintf(&s
, _("%s is provided by the system"),
96 pakfire_dep2str(problem
->pakfire
, dep
));
100 r
= asprintf(&s
, _("some dependency problem"));
103 case SOLVER_RULE_BEST
:
105 r
= asprintf(&s
, _("cannot install the best update candidate for package %s"),
106 pool_solvid2str(pool
, source
));
108 r
= asprintf(&s
, _("cannot install the best candidate for the job"));
111 case SOLVER_RULE_RPM_NOT_INSTALLABLE
:
112 r
= asprintf(&s
, _("package %s is not installable"),
113 pool_solvid2str(pool
, source
));
116 case SOLVER_RULE_RPM_NOTHING_PROVIDES_DEP
:
117 r
= asprintf(&s
, _("nothing provides %s needed by %s"),
118 pakfire_dep2str(problem
->pakfire
, dep
), pool_solvid2str(pool
, source
));
121 case SOLVER_RULE_RPM_SAME_NAME
:
122 r
= asprintf(&s
, _("cannot install both %s and %s"),
123 pool_solvid2str(pool
, source
), pool_solvid2str(pool
, target
));
126 case SOLVER_RULE_RPM_PACKAGE_CONFLICT
:
127 r
= asprintf(&s
, _("package %s conflicts with %s provided by %s"),
128 pool_solvid2str(pool
, source
), pakfire_dep2str(problem
->pakfire
, dep
),
129 pool_solvid2str(pool
, target
));
132 case SOLVER_RULE_RPM_PACKAGE_OBSOLETES
:
133 r
= asprintf(&s
, _("package %s obsoletes %s provided by %s"),
134 pool_solvid2str(pool
, source
), pakfire_dep2str(problem
->pakfire
, dep
),
135 pool_solvid2str(pool
, target
));
138 case SOLVER_RULE_RPM_INSTALLEDPKG_OBSOLETES
:
139 r
= asprintf(&s
, _("installed 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_IMPLICIT_OBSOLETES
:
145 r
= asprintf(&s
, _("package %s implicitely 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_PACKAGE_REQUIRES
:
151 r
= asprintf(&s
, _("package %s requires %s, but none of the providers can be installed"),
152 pool_solvid2str(pool
, source
), pakfire_dep2str(problem
->pakfire
, dep
));
155 case SOLVER_RULE_RPM_SELF_CONFLICT
:
156 r
= asprintf(&s
, _("package %s conflicts with %s provided by itself"),
157 pool_solvid2str(pool
, source
), pakfire_dep2str(problem
->pakfire
, dep
));
160 case SOLVER_RULE_YUMOBS
:
161 r
= asprintf(&s
, _("both package %s and %s obsolete %s"),
162 pool_solvid2str(pool
, source
), pool_solvid2str(pool
, target
),
163 pakfire_dep2str(problem
->pakfire
, dep
));
166 case SOLVER_RULE_BLACK
:
167 r
= asprintf(&s
, _("package %s can only be installed by direct request"),
168 pool_solvid2str(pool
, source
));
171 case SOLVER_RULE_PKG_CONSTRAINS
:
172 r
= asprintf(&s
, _("package %s has constraint %s conflicting with %s"),
173 pool_solvid2str(pool
, source
), pakfire_dep2str(problem
->pakfire
, dep
),
174 pool_solvid2str(pool
, target
));
178 r
= asprintf(&s
, _("bad rule type"));
182 // Return nothing if asprintf failed
189 PAKFIRE_EXPORT
int pakfire_problem_create(struct pakfire_problem
** problem
,
190 struct pakfire
* pakfire
, struct pakfire_request
* request
, Id id
) {
191 struct pakfire_problem
* p
= calloc(1, sizeof(*p
));
195 p
->pakfire
= pakfire_ref(pakfire
);
198 p
->request
= pakfire_request_ref(request
);
205 PAKFIRE_EXPORT
struct pakfire_problem
* pakfire_problem_ref(struct pakfire_problem
* problem
) {
211 static void pakfire_problem_free(struct pakfire_problem
* problem
) {
212 pakfire_request_unref(problem
->request
);
215 free(problem
->string
);
217 pakfire_unref(problem
->pakfire
);
221 PAKFIRE_EXPORT
struct pakfire_problem
* pakfire_problem_unref(struct pakfire_problem
* problem
) {
222 if (--problem
->nrefs
> 0)
225 pakfire_problem_free(problem
);
229 struct pakfire
* pakfire_problem_get_pakfire(struct pakfire_problem
* problem
) {
230 return pakfire_ref(problem
->pakfire
);
233 PAKFIRE_EXPORT
const char* pakfire_problem_to_string(struct pakfire_problem
* problem
) {
234 if (!problem
->string
)
235 problem
->string
= pakfire_problem_make_string(problem
);
237 return problem
->string
;
240 Id
pakfire_problem_get_id(struct pakfire_problem
* problem
) {
244 PAKFIRE_EXPORT
struct pakfire_request
* pakfire_problem_get_request(struct pakfire_problem
* problem
) {
245 return pakfire_request_ref(problem
->request
);
248 PAKFIRE_EXPORT
int pakfire_problem_get_solutions(struct pakfire_problem
* problem
,
249 struct pakfire_solution
*** solutions
) {
250 Solver
* solver
= pakfire_request_get_solver(problem
->request
);
253 // How many solutions are there?
254 unsigned int count
= solver_solution_count(solver
, problem
->id
);
260 // Allocate a solutions array
261 *solutions
= calloc(count
+ 1, sizeof(**solutions
));
265 struct pakfire_solution
* solution
= NULL
;
268 for (unsigned int i
= 0; i
< count
; i
++) {
269 s
= solver_next_solution(solver
, problem
->id
, s
);
273 // Create a new solution object
274 r
= pakfire_solution_create(&solution
, problem
, s
);
278 // Append solution to array
279 (*solutions
)[i
] = solution
;
286 for (struct pakfire_solution
** _solution
= *solutions
; *_solution
; _solution
++)
287 pakfire_solution_unref(*_solution
);