]> git.ipfire.org Git - pakfire.git/blame - src/libpakfire/problem.c
problem: Store a reference to the context
[pakfire.git] / src / libpakfire / problem.c
CommitLineData
d528058e
MT
1/*#############################################################################
2# #
3# Pakfire - The IPFire package management system #
4# Copyright (C) 2017 Pakfire development team #
5# #
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. #
10# #
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. #
15# #
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/>. #
18# #
19#############################################################################*/
20
aa36f70e 21#include <errno.h>
f0d6233d
MT
22#include <stdlib.h>
23
517708c8
MT
24// Enable legacy logging
25#define PAKFIRE_LEGACY_LOGGING
26
d528058e 27#include <pakfire/constants.h>
d3c74e42 28#include <pakfire/ctx.h>
2a623cf8 29#include <pakfire/dependencies.h>
d528058e 30#include <pakfire/i18n.h>
6f94a65f 31#include <pakfire/logging.h>
12656820 32#include <pakfire/pakfire.h>
9f953e68 33#include <pakfire/private.h>
d528058e 34#include <pakfire/problem.h>
9c8337dd 35#include <pakfire/solution.h>
2f269d34 36#include <pakfire/transaction.h>
d528058e
MT
37#include <pakfire/util.h>
38
014e8eb6 39struct pakfire_problem {
d3c74e42 40 struct pakfire_ctx* ctx;
ac4c607b 41 struct pakfire* pakfire;
cf75652c
MT
42 int nrefs;
43
2f269d34 44 struct pakfire_transaction* transaction;
3dc52735
MT
45 Id id;
46 char* string;
bfe8e8fb
MT
47
48 Solver* solver;
3dc52735
MT
49};
50
ae23fb16 51static char* pakfire_problem_make_string(struct pakfire_problem* problem) {
2f269d34 52 Solver* solver = pakfire_transaction_get_solver(problem->transaction);
d528058e
MT
53 Pool* pool = solver->pool;
54
55 // Get the problem rule
56 Id rule = solver_findproblemrule(solver, problem->id);
57
58 // Extract some information about that rule
59 Id dep;
60 Id source;
61 Id target;
62
63 SolverRuleinfo type = solver_ruleinfo(solver, rule, &source, &target, &dep);
64
ae23fb16
MT
65 char* s = NULL;
66 int r = 1;
67
d528058e
MT
68 switch (type) {
69 case SOLVER_RULE_DISTUPGRADE:
ae23fb16
MT
70 r = asprintf(&s, _("%s does not belong to a distupgrade repository"),
71 pool_solvid2str(pool, source));
d528058e
MT
72 break;
73
74 case SOLVER_RULE_INFARCH:
ae23fb16
MT
75 r = asprintf(&s, _("%s has inferior architecture"),
76 pool_solvid2str(pool, source));
d528058e
MT
77 break;
78
79 case SOLVER_RULE_UPDATE:
ae23fb16
MT
80 r = asprintf(&s, _("problem with installed package %s"),
81 pool_solvid2str(pool, source));
d528058e
MT
82 break;
83
84 case SOLVER_RULE_JOB:
ae23fb16 85 r = asprintf(&s, _("conflicting requests"));
d528058e
MT
86 break;
87
88 case SOLVER_RULE_JOB_UNSUPPORTED:
ae23fb16 89 r = asprintf(&s, _("unsupported request"));
37cb2f41 90 break;
d528058e
MT
91
92 case SOLVER_RULE_JOB_NOTHING_PROVIDES_DEP:
b1171f6a
MT
93 r = asprintf(&s, _("nothing provides requested %s"),
94 pakfire_dep2str(problem->pakfire, dep));
d528058e
MT
95 break;
96
97 case SOLVER_RULE_JOB_UNKNOWN_PACKAGE:
b1171f6a
MT
98 r = asprintf(&s, _("package %s does not exist"),
99 pakfire_dep2str(problem->pakfire, dep));
d528058e
MT
100 break;
101
102 case SOLVER_RULE_JOB_PROVIDED_BY_SYSTEM:
b1171f6a
MT
103 r = asprintf(&s, _("%s is provided by the system"),
104 pakfire_dep2str(problem->pakfire, dep));
d528058e
MT
105 break;
106
107 case SOLVER_RULE_RPM:
ae23fb16 108 r = asprintf(&s, _("some dependency problem"));
d528058e
MT
109 break;
110
111 case SOLVER_RULE_BEST:
112 if (source > 0)
ae23fb16
MT
113 r = asprintf(&s, _("cannot install the best update candidate for package %s"),
114 pool_solvid2str(pool, source));
d528058e 115 else
ae23fb16 116 r = asprintf(&s, _("cannot install the best candidate for the job"));
d528058e
MT
117 break;
118
119 case SOLVER_RULE_RPM_NOT_INSTALLABLE:
ae23fb16
MT
120 r = asprintf(&s, _("package %s is not installable"),
121 pool_solvid2str(pool, source));
d528058e
MT
122 break;
123
124 case SOLVER_RULE_RPM_NOTHING_PROVIDES_DEP:
ae23fb16 125 r = asprintf(&s, _("nothing provides %s needed by %s"),
b1171f6a 126 pakfire_dep2str(problem->pakfire, dep), pool_solvid2str(pool, source));
d528058e
MT
127 break;
128
129 case SOLVER_RULE_RPM_SAME_NAME:
ae23fb16
MT
130 r = asprintf(&s, _("cannot install both %s and %s"),
131 pool_solvid2str(pool, source), pool_solvid2str(pool, target));
d528058e
MT
132 break;
133
134 case SOLVER_RULE_RPM_PACKAGE_CONFLICT:
ae23fb16 135 r = asprintf(&s, _("package %s conflicts with %s provided by %s"),
b1171f6a 136 pool_solvid2str(pool, source), pakfire_dep2str(problem->pakfire, dep),
ae23fb16 137 pool_solvid2str(pool, target));
d528058e
MT
138 break;
139
140 case SOLVER_RULE_RPM_PACKAGE_OBSOLETES:
ae23fb16 141 r = asprintf(&s, _("package %s obsoletes %s provided by %s"),
b1171f6a 142 pool_solvid2str(pool, source), pakfire_dep2str(problem->pakfire, dep),
ae23fb16 143 pool_solvid2str(pool, target));
d528058e
MT
144 break;
145
146 case SOLVER_RULE_RPM_INSTALLEDPKG_OBSOLETES:
ae23fb16 147 r = asprintf(&s, _("installed package %s obsoletes %s provided by %s"),
b1171f6a 148 pool_solvid2str(pool, source), pakfire_dep2str(problem->pakfire, dep),
ae23fb16 149 pool_solvid2str(pool, target));
d528058e
MT
150 break;
151
152 case SOLVER_RULE_RPM_IMPLICIT_OBSOLETES:
ae23fb16 153 r = asprintf(&s, _("package %s implicitely obsoletes %s provided by %s"),
b1171f6a 154 pool_solvid2str(pool, source), pakfire_dep2str(problem->pakfire, dep),
ae23fb16 155 pool_solvid2str(pool, target));
d528058e
MT
156 break;
157
158 case SOLVER_RULE_RPM_PACKAGE_REQUIRES:
ae23fb16 159 r = asprintf(&s, _("package %s requires %s, but none of the providers can be installed"),
b1171f6a 160 pool_solvid2str(pool, source), pakfire_dep2str(problem->pakfire, dep));
d528058e
MT
161 break;
162
163 case SOLVER_RULE_RPM_SELF_CONFLICT:
ae23fb16 164 r = asprintf(&s, _("package %s conflicts with %s provided by itself"),
b1171f6a 165 pool_solvid2str(pool, source), pakfire_dep2str(problem->pakfire, dep));
d528058e
MT
166 break;
167
168 case SOLVER_RULE_YUMOBS:
ae23fb16
MT
169 r = asprintf(&s, _("both package %s and %s obsolete %s"),
170 pool_solvid2str(pool, source), pool_solvid2str(pool, target),
b1171f6a 171 pakfire_dep2str(problem->pakfire, dep));
d528058e
MT
172 break;
173
bd62b874
MT
174 case SOLVER_RULE_BLACK:
175 r = asprintf(&s, _("package %s can only be installed by direct request"),
176 pool_solvid2str(pool, source));
177 break;
178
179 case SOLVER_RULE_PKG_CONSTRAINS:
180 r = asprintf(&s, _("package %s has constraint %s conflicting with %s"),
b1171f6a 181 pool_solvid2str(pool, source), pakfire_dep2str(problem->pakfire, dep),
bd62b874
MT
182 pool_solvid2str(pool, target));
183 break;
184
185 default:
ae23fb16 186 r = asprintf(&s, _("bad rule type"));
d528058e 187 break;
d528058e
MT
188 }
189
ae23fb16
MT
190 // Return nothing if asprintf failed
191 if (r < 0)
192 return NULL;
193
194 return s;
d528058e
MT
195}
196
2f269d34
MT
197int pakfire_problem_create(struct pakfire_problem** problem,
198 struct pakfire* pakfire, struct pakfire_transaction* transaction, Id id) {
e9cca469 199 struct pakfire_problem* p = calloc(1, sizeof(*p));
4896a9a8
MT
200 if (!p)
201 return 1;
12656820 202
d3c74e42 203 p->ctx = pakfire_ctx(pakfire);
f446d92e 204 p->pakfire = pakfire_ref(pakfire);
4896a9a8 205 p->nrefs = 1;
d528058e 206
2f269d34 207 p->transaction = pakfire_transaction_ref(transaction);
4896a9a8 208 p->id = id;
d528058e 209
bfe8e8fb
MT
210 // Fetch a reference to the solver
211 p->solver = pakfire_transaction_get_solver(transaction);
212
4896a9a8
MT
213 *problem = p;
214 return 0;
d528058e
MT
215}
216
014e8eb6 217PAKFIRE_EXPORT struct pakfire_problem* pakfire_problem_ref(struct pakfire_problem* problem) {
d528058e
MT
218 problem->nrefs++;
219
220 return problem;
221}
222
014e8eb6 223static void pakfire_problem_free(struct pakfire_problem* problem) {
2f269d34
MT
224 if (problem->transaction)
225 pakfire_transaction_unref(problem->transaction);
d528058e 226 if (problem->string)
f0d6233d 227 free(problem->string);
d3c74e42
MT
228 if (problem->pakfire)
229 pakfire_unref(problem->pakfire);
230 if (problem->ctx)
231 pakfire_ctx_unref(problem->ctx);
f0d6233d 232 free(problem);
6f94a65f
MT
233}
234
014e8eb6 235PAKFIRE_EXPORT struct pakfire_problem* pakfire_problem_unref(struct pakfire_problem* problem) {
6f94a65f
MT
236 if (--problem->nrefs > 0)
237 return problem;
238
239 pakfire_problem_free(problem);
240 return NULL;
d528058e
MT
241}
242
ac4c607b 243struct pakfire* pakfire_problem_get_pakfire(struct pakfire_problem* problem) {
12656820
MT
244 return pakfire_ref(problem->pakfire);
245}
246
014e8eb6 247PAKFIRE_EXPORT const char* pakfire_problem_to_string(struct pakfire_problem* problem) {
d48f4d8d 248 if (!problem->string)
ae23fb16 249 problem->string = pakfire_problem_make_string(problem);
d48f4d8d 250
d528058e
MT
251 return problem->string;
252}
9c8337dd 253
014e8eb6 254Id pakfire_problem_get_id(struct pakfire_problem* problem) {
3dc52735
MT
255 return problem->id;
256}
257
2f269d34
MT
258struct pakfire_transaction* pakfire_problem_get_transaction(struct pakfire_problem* problem) {
259 return pakfire_transaction_ref(problem->transaction);
3dc52735
MT
260}
261
bfe8e8fb
MT
262PAKFIRE_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;
267 Id id = ID_NULL;
268 int r;
269
270 // Fetch how many solutions we have
271 count = solver_solution_count(problem->solver, problem->id);
272 if (!count)
273 return NULL;
aa36f70e 274
bfe8e8fb
MT
275 // Allocate some space
276 solutions = calloc(count + 1, sizeof(*solutions));
277 if (!solutions) {
278 r = -errno;
279 goto ERROR;
aa36f70e
MT
280 }
281
bfe8e8fb
MT
282 for (unsigned int i = 0; i < count; i++) {
283 id = solver_next_solution(problem->solver, problem->id, id);
284 if (!id)
285 break;
286
287 // Create a new solution
288 r = pakfire_solution_create(&solution, problem->pakfire, problem, id);
289 if (r)
290 goto ERROR;
aa36f70e 291
bfe8e8fb
MT
292 // Store the reference
293 solutions[i] = solution;
aa36f70e
MT
294 }
295
bfe8e8fb
MT
296 return solutions;
297
298ERROR:
299 ERROR_ERRNO(problem->pakfire, r, "Could not import solutions: %m\n");
300
301 if (solutions) {
302 for (struct pakfire_solution** s = solutions; *s; s++)
303 pakfire_solution_unref(*s);
aa36f70e 304
bfe8e8fb
MT
305 free(solutions);
306 }
307
308 return NULL;
aa36f70e 309}