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