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/i18n.h>
25 #include <pakfire/logging.h>
26 #include <pakfire/pakfire.h>
27 #include <pakfire/private.h>
28 #include <pakfire/problem.h>
29 #include <pakfire/request.h>
30 #include <pakfire/solution.h>
31 #include <pakfire/util.h>
33 struct pakfire_problem
{
34 struct pakfire
* pakfire
;
37 struct pakfire_request
* request
;
42 static char* pakfire_problem_make_string(struct pakfire_problem
* problem
) {
43 Solver
* solver
= pakfire_request_get_solver(problem
->request
);
44 Pool
* pool
= solver
->pool
;
46 // Get the problem rule
47 Id rule
= solver_findproblemrule(solver
, problem
->id
);
49 // Extract some information about that rule
54 SolverRuleinfo type
= solver_ruleinfo(solver
, rule
, &source
, &target
, &dep
);
60 case SOLVER_RULE_DISTUPGRADE
:
61 r
= asprintf(&s
, _("%s does not belong to a distupgrade repository"),
62 pool_solvid2str(pool
, source
));
65 case SOLVER_RULE_INFARCH
:
66 r
= asprintf(&s
, _("%s has inferior architecture"),
67 pool_solvid2str(pool
, source
));
70 case SOLVER_RULE_UPDATE
:
71 r
= asprintf(&s
, _("problem with installed package %s"),
72 pool_solvid2str(pool
, source
));
76 r
= asprintf(&s
, _("conflicting requests"));
79 case SOLVER_RULE_JOB_UNSUPPORTED
:
80 r
= asprintf(&s
, _("unsupported request"));
83 case SOLVER_RULE_JOB_NOTHING_PROVIDES_DEP
:
84 r
= asprintf(&s
, _("nothing provides requested %s"), pool_dep2str(pool
, dep
));
87 case SOLVER_RULE_JOB_UNKNOWN_PACKAGE
:
88 r
= asprintf(&s
, _("package %s does not exist"), pool_dep2str(pool
, dep
));
91 case SOLVER_RULE_JOB_PROVIDED_BY_SYSTEM
:
92 r
= asprintf(&s
, _("%s is provided by the system"), pool_dep2str(pool
, dep
));
96 r
= asprintf(&s
, _("some dependency problem"));
99 case SOLVER_RULE_BEST
:
101 r
= asprintf(&s
, _("cannot install the best update candidate for package %s"),
102 pool_solvid2str(pool
, source
));
104 r
= asprintf(&s
, _("cannot install the best candidate for the job"));
107 case SOLVER_RULE_RPM_NOT_INSTALLABLE
:
108 r
= asprintf(&s
, _("package %s is not installable"),
109 pool_solvid2str(pool
, source
));
112 case SOLVER_RULE_RPM_NOTHING_PROVIDES_DEP
:
113 r
= asprintf(&s
, _("nothing provides %s needed by %s"),
114 pool_dep2str(pool
, dep
), pool_solvid2str(pool
, source
));
117 case SOLVER_RULE_RPM_SAME_NAME
:
118 r
= asprintf(&s
, _("cannot install both %s and %s"),
119 pool_solvid2str(pool
, source
), pool_solvid2str(pool
, target
));
122 case SOLVER_RULE_RPM_PACKAGE_CONFLICT
:
123 r
= asprintf(&s
, _("package %s conflicts with %s provided by %s"),
124 pool_solvid2str(pool
, source
), pool_dep2str(pool
, dep
),
125 pool_solvid2str(pool
, target
));
128 case SOLVER_RULE_RPM_PACKAGE_OBSOLETES
:
129 r
= asprintf(&s
, _("package %s obsoletes %s provided by %s"),
130 pool_solvid2str(pool
, source
), pool_dep2str(pool
, dep
),
131 pool_solvid2str(pool
, target
));
134 case SOLVER_RULE_RPM_INSTALLEDPKG_OBSOLETES
:
135 r
= asprintf(&s
, _("installed package %s obsoletes %s provided by %s"),
136 pool_solvid2str(pool
, source
), pool_dep2str(pool
, dep
),
137 pool_solvid2str(pool
, target
));
140 case SOLVER_RULE_RPM_IMPLICIT_OBSOLETES
:
141 r
= asprintf(&s
, _("package %s implicitely obsoletes %s provided by %s"),
142 pool_solvid2str(pool
, source
), pool_dep2str(pool
, dep
),
143 pool_solvid2str(pool
, target
));
146 case SOLVER_RULE_RPM_PACKAGE_REQUIRES
:
147 r
= asprintf(&s
, _("package %s requires %s, but none of the providers can be installed"),
148 pool_solvid2str(pool
, source
), pool_dep2str(pool
, dep
));
151 case SOLVER_RULE_RPM_SELF_CONFLICT
:
152 r
= asprintf(&s
, _("package %s conflicts with %s provided by itself"),
153 pool_solvid2str(pool
, source
), pool_dep2str(pool
, dep
));
156 case SOLVER_RULE_YUMOBS
:
157 r
= asprintf(&s
, _("both package %s and %s obsolete %s"),
158 pool_solvid2str(pool
, source
), pool_solvid2str(pool
, target
),
159 pool_dep2str(pool
, dep
));
162 case SOLVER_RULE_BLACK
:
163 r
= asprintf(&s
, _("package %s can only be installed by direct request"),
164 pool_solvid2str(pool
, source
));
167 case SOLVER_RULE_PKG_CONSTRAINS
:
168 r
= asprintf(&s
, _("package %s has constraint %s conflicting with %s"),
169 pool_solvid2str(pool
, source
), pool_dep2str(pool
, dep
),
170 pool_solvid2str(pool
, target
));
174 r
= asprintf(&s
, _("bad rule type"));
178 // Return nothing if asprintf failed
185 PAKFIRE_EXPORT
int pakfire_problem_create(struct pakfire_problem
** problem
,
186 struct pakfire
* pakfire
, struct pakfire_request
* request
, Id id
) {
187 struct pakfire_problem
* p
= calloc(1, sizeof(*p
));
191 p
->pakfire
= pakfire_ref(pakfire
);
194 p
->request
= pakfire_request_ref(request
);
201 PAKFIRE_EXPORT
struct pakfire_problem
* pakfire_problem_ref(struct pakfire_problem
* problem
) {
207 static void pakfire_problem_free(struct pakfire_problem
* problem
) {
208 pakfire_request_unref(problem
->request
);
211 free(problem
->string
);
213 pakfire_unref(problem
->pakfire
);
217 PAKFIRE_EXPORT
struct pakfire_problem
* pakfire_problem_unref(struct pakfire_problem
* problem
) {
218 if (--problem
->nrefs
> 0)
221 pakfire_problem_free(problem
);
225 struct pakfire
* pakfire_problem_get_pakfire(struct pakfire_problem
* problem
) {
226 return pakfire_ref(problem
->pakfire
);
229 PAKFIRE_EXPORT
const char* pakfire_problem_to_string(struct pakfire_problem
* problem
) {
230 if (!problem
->string
)
231 problem
->string
= pakfire_problem_make_string(problem
);
233 return problem
->string
;
236 Id
pakfire_problem_get_id(struct pakfire_problem
* problem
) {
240 PAKFIRE_EXPORT
struct pakfire_request
* pakfire_problem_get_request(struct pakfire_problem
* problem
) {
241 return pakfire_request_ref(problem
->request
);
244 PAKFIRE_EXPORT
int pakfire_problem_get_solutions(struct pakfire_problem
* problem
,
245 struct pakfire_solution
*** solutions
) {
246 Solver
* solver
= pakfire_request_get_solver(problem
->request
);
249 // How many solutions are there?
250 unsigned int count
= solver_solution_count(solver
, problem
->id
);
256 // Allocate a solutions array
257 *solutions
= calloc(count
+ 1, sizeof(**solutions
));
261 struct pakfire_solution
* solution
= NULL
;
264 for (unsigned int i
= 0; i
< count
; i
++) {
265 s
= solver_next_solution(solver
, problem
->id
, s
);
269 // Create a new solution object
270 r
= pakfire_solution_create(&solution
, problem
, s
);
274 // Append solution to array
275 (*solutions
)[i
] = solution
;
282 for (struct pakfire_solution
** solution
= *solutions
; *solution
; solution
++)
283 pakfire_solution_unref(*solution
);