]>
Commit | Line | Data |
---|---|---|
221cc3ce MT |
1 | /*############################################################################# |
2 | # # | |
3 | # Pakfire - The IPFire package management system # | |
4 | # Copyright (C) 2013 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 | ||
5b1e6c81 | 21 | #include <ctype.h> |
ff0ee874 | 22 | #include <errno.h> |
2693edde | 23 | #include <linux/limits.h> |
f0d6233d | 24 | #include <stdlib.h> |
708096fe | 25 | #include <sys/utsname.h> |
f0d6233d | 26 | |
221cc3ce | 27 | #include <solv/queue.h> |
cdcd6acb | 28 | #include <solv/selection.h> |
221cc3ce MT |
29 | #include <solv/solver.h> |
30 | #include <solv/transaction.h> | |
31 | ||
943ff55c | 32 | #ifdef ENABLE_DEBUG |
221cc3ce MT |
33 | # include <solv/solverdebug.h> |
34 | #endif | |
35 | ||
2693edde | 36 | #include <pakfire/archive.h> |
2a623cf8 | 37 | #include <pakfire/dependencies.h> |
116cbcf4 | 38 | #include <pakfire/logging.h> |
221cc3ce | 39 | #include <pakfire/package.h> |
19f3d106 | 40 | #include <pakfire/pakfire.h> |
9f953e68 | 41 | #include <pakfire/private.h> |
d528058e | 42 | #include <pakfire/problem.h> |
221cc3ce | 43 | #include <pakfire/request.h> |
221cc3ce | 44 | #include <pakfire/transaction.h> |
221cc3ce MT |
45 | #include <pakfire/util.h> |
46 | ||
25141aa0 | 47 | struct pakfire_request { |
ac4c607b | 48 | struct pakfire* pakfire; |
25141aa0 MT |
49 | int nrefs; |
50 | ||
e3993ac6 | 51 | Solver* solver; |
a8394a72 | 52 | Queue jobs; |
25141aa0 | 53 | }; |
221cc3ce | 54 | |
df42ab40 MT |
55 | /* |
56 | These packages can be installed multiple times simultaneously | |
57 | */ | |
58 | const char* pakfire_multiinstall_packages[] = { | |
59 | "kernel", | |
60 | "kernel-devel", | |
61 | NULL, | |
62 | }; | |
63 | ||
df9739f2 | 64 | static void pakfire_request_free(struct pakfire_request* request) { |
df9739f2 MT |
65 | if (request->solver) |
66 | solver_free(request->solver); | |
67 | queue_free(&request->jobs); | |
68 | ||
69 | pakfire_unref(request->pakfire); | |
70 | free(request); | |
71 | } | |
72 | ||
99a56775 MT |
73 | /* |
74 | This function translates any modifying flags into flags for libsolv | |
75 | */ | |
76 | static int pakfire_request_job_flags(int flags) { | |
77 | int solver_flags = 0; | |
78 | ||
79 | // Essential jobs | |
80 | if (flags & PAKFIRE_REQUEST_ESSENTIAL) | |
81 | solver_flags |= SOLVER_ESSENTIAL; | |
82 | ||
83 | return solver_flags; | |
84 | } | |
85 | ||
df42ab40 MT |
86 | static void pakfire_request_add_packages(struct pakfire_request* request, |
87 | int flags, const char** packages) { | |
88 | Pool* pool = pakfire_get_solv_pool(request->pakfire); | |
89 | if (!pool) | |
90 | return; | |
91 | ||
99a56775 MT |
92 | // Translate flags |
93 | flags = pakfire_request_job_flags(flags); | |
94 | ||
df42ab40 MT |
95 | for (const char** package = packages; *package; package++) { |
96 | Id id = pool_str2id(pool, *package, 1); | |
97 | if (id) | |
98 | queue_push2(&request->jobs, flags, id); | |
99 | } | |
100 | } | |
101 | ||
708096fe MT |
102 | static void pakfire_request_lock_running_kernel(struct pakfire_request* request) { |
103 | struct utsname utsname; | |
104 | char buffer[NAME_MAX]; | |
105 | ||
106 | // Call uname() | |
107 | int r = uname(&utsname); | |
108 | if (r) { | |
109 | ERROR(request->pakfire, "uname() failed: %m\n"); | |
110 | return; | |
111 | } | |
112 | ||
113 | DEBUG(request->pakfire, "Locking running kernel %s\n", utsname.release); | |
114 | ||
115 | r = pakfire_string_format(buffer, "kernel(%s)", utsname.release); | |
116 | if (r < 0) | |
117 | return; | |
118 | ||
119 | Pool* pool = pakfire_get_solv_pool(request->pakfire); | |
120 | ||
121 | // Add a locking pool job | |
122 | Id id = pool_str2id(pool, buffer, 1); | |
123 | if (id) | |
124 | queue_push2(&request->jobs, SOLVER_LOCK|SOLVER_SOLVABLE_PROVIDES, id); | |
125 | } | |
126 | ||
df9739f2 | 127 | static int setup_solver(struct pakfire_request* request, int flags) { |
a005d132 MT |
128 | // Can the solver downgrade packages? |
129 | if (flags & PAKFIRE_REQUEST_ALLOW_DOWNGRADE) | |
df9739f2 MT |
130 | solver_set_flag(request->solver, SOLVER_FLAG_ALLOW_DOWNGRADE, 1); |
131 | ||
a005d132 MT |
132 | // Can the solver uninstall packages? |
133 | if (flags & PAKFIRE_REQUEST_ALLOW_UNINSTALL) | |
df9739f2 MT |
134 | solver_set_flag(request->solver, SOLVER_FLAG_ALLOW_UNINSTALL, 1); |
135 | ||
c572abee MT |
136 | // Do not install any recommended packages |
137 | if (flags & PAKFIRE_REQUEST_WITHOUT_RECOMMENDED) | |
df9739f2 MT |
138 | solver_set_flag(request->solver, SOLVER_FLAG_IGNORE_RECOMMENDED, 1); |
139 | ||
df42ab40 MT |
140 | // Add multiinstall packages |
141 | pakfire_request_add_packages(request, | |
142 | SOLVER_MULTIVERSION|SOLVER_SOLVABLE_PROVIDES, pakfire_multiinstall_packages); | |
143 | ||
708096fe MT |
144 | // Lock the running kernel |
145 | if (pakfire_on_root(request->pakfire)) | |
146 | pakfire_request_lock_running_kernel(request); | |
147 | ||
df9739f2 MT |
148 | return 0; |
149 | } | |
150 | ||
cdcd6acb | 151 | PAKFIRE_EXPORT int pakfire_request_create(struct pakfire_request** request, |
ac4c607b | 152 | struct pakfire* pakfire, int flags) { |
df9739f2 MT |
153 | Pool* pool = pakfire_get_solv_pool(pakfire); |
154 | int r = 1; | |
155 | ||
156 | // Cannot create a solver when no installed repository has been set | |
157 | if (!pool->installed) | |
158 | return -EINVAL; | |
159 | ||
160 | // Allocate request | |
25141aa0 MT |
161 | struct pakfire_request* req = calloc(1, sizeof(*req)); |
162 | if (!req) | |
163 | return ENOMEM; | |
d528058e | 164 | |
25141aa0 MT |
165 | req->pakfire = pakfire_ref(pakfire); |
166 | req->nrefs = 1; | |
d528058e | 167 | |
df9739f2 | 168 | // Allocate a job queue |
a8394a72 | 169 | queue_init(&req->jobs); |
d528058e | 170 | |
df9739f2 MT |
171 | // Allocate solver |
172 | req->solver = solver_create(pool); | |
173 | if (!req->solver) { | |
174 | ERROR(pakfire, "Could not allocate solver: %m\n"); | |
175 | goto ERROR; | |
176 | } | |
177 | ||
178 | // Set up solver | |
179 | r = setup_solver(req, flags); | |
180 | if (r) | |
181 | goto ERROR; | |
182 | ||
25141aa0 MT |
183 | *request = req; |
184 | return 0; | |
221cc3ce | 185 | |
df9739f2 MT |
186 | ERROR: |
187 | pakfire_request_free(req); | |
188 | return r; | |
e3993ac6 MT |
189 | } |
190 | ||
25141aa0 MT |
191 | PAKFIRE_EXPORT struct pakfire_request* pakfire_request_ref(struct pakfire_request* request) { |
192 | request->nrefs++; | |
193 | ||
194 | return request; | |
195 | } | |
e3993ac6 | 196 | |
25141aa0 | 197 | PAKFIRE_EXPORT struct pakfire_request* pakfire_request_unref(struct pakfire_request* request) { |
e3993ac6 MT |
198 | if (--request->nrefs > 0) |
199 | return request; | |
200 | ||
201 | pakfire_request_free(request); | |
202 | return NULL; | |
203 | } | |
204 | ||
25141aa0 | 205 | Solver* pakfire_request_get_solver(struct pakfire_request* request) { |
e3993ac6 | 206 | return request->solver; |
221cc3ce MT |
207 | } |
208 | ||
5bdd89a5 MT |
209 | static int pakfire_request_get_problems(struct pakfire_request* request, |
210 | struct pakfire_problem*** problems) { | |
211 | struct pakfire_problem* problem; | |
212 | ||
213 | unsigned int count = solver_problem_count(request->solver); | |
214 | if (!count) | |
215 | return 0; | |
216 | ||
217 | // Allocate array | |
7e91a7f3 | 218 | *problems = calloc(count + 1, sizeof(**problems)); |
5bdd89a5 MT |
219 | if (!*problems) |
220 | return 1; | |
221 | ||
222 | Id p = 0; | |
223 | for (unsigned int i = 0; i < count; i++) { | |
224 | p = solver_next_problem(request->solver, p); | |
225 | if (!p) | |
226 | break; | |
227 | ||
228 | // Create problem | |
f446d92e | 229 | int r = pakfire_problem_create(&problem, request->pakfire, request, p); |
5bdd89a5 MT |
230 | if (r) |
231 | goto ERROR; | |
232 | ||
233 | // Append to array | |
234 | (*problems)[i] = problem; | |
235 | }; | |
236 | ||
237 | return 0; | |
238 | ||
239 | ERROR: | |
240 | if (*problems) { | |
23b93958 MT |
241 | for (struct pakfire_problem** _problem = *problems; *_problem; _problem++) |
242 | free(*_problem); | |
5bdd89a5 | 243 | free(*problems); |
1e27b257 MT |
244 | |
245 | // Reset pointer | |
246 | *problems = NULL; | |
5bdd89a5 MT |
247 | } |
248 | ||
249 | return 1; | |
250 | } | |
251 | ||
41ebf5f0 | 252 | PAKFIRE_EXPORT int pakfire_request_solve(struct pakfire_request* request, |
5bdd89a5 MT |
253 | struct pakfire_transaction** transaction, struct pakfire_problem*** problems) { |
254 | int r; | |
255 | ||
9eba3d65 MT |
256 | // Prepare pool |
257 | pakfire_pool_internalize(request->pakfire); | |
221cc3ce | 258 | |
5bdd89a5 | 259 | // Reset pointers |
41ebf5f0 | 260 | *transaction = NULL; |
5bdd89a5 | 261 | *problems = NULL; |
41ebf5f0 | 262 | |
d5c4772d | 263 | #ifdef ENABLE_DEBUG |
a50b88d4 MT |
264 | Pool* pool = pakfire_get_solv_pool(request->pakfire); |
265 | ||
35901b25 | 266 | const char* selection = pool_selection2str(pool, &request->jobs, 0); |
963bea23 MT |
267 | if (selection) { |
268 | DEBUG(request->pakfire, "Solving: %s\n", selection); | |
269 | } | |
270 | #endif | |
271 | ||
116cbcf4 MT |
272 | // Save time when we starting solving |
273 | clock_t solving_start = clock(); | |
274 | ||
35901b25 | 275 | if (solver_solve(request->solver, &request->jobs)) { |
943ff55c | 276 | #ifdef ENABLE_DEBUG |
221cc3ce MT |
277 | solver_printallsolutions(request->solver); |
278 | #endif | |
279 | ||
5bdd89a5 MT |
280 | // Fetch problems |
281 | r = pakfire_request_get_problems(request, problems); | |
282 | if (r) | |
1e27b257 | 283 | return r; |
5bdd89a5 MT |
284 | |
285 | return 2; | |
221cc3ce MT |
286 | } |
287 | ||
116cbcf4 MT |
288 | // Save time when we finished solving |
289 | clock_t solving_end = clock(); | |
290 | ||
12656820 | 291 | DEBUG(request->pakfire, "Solved request in %.4fms\n", |
116cbcf4 MT |
292 | (double)(solving_end - solving_start) * 1000 / CLOCKS_PER_SEC); |
293 | ||
943ff55c MT |
294 | #ifdef ENABLE_DEBUG |
295 | solver_printdecisions(request->solver); | |
296 | #endif | |
297 | ||
41ebf5f0 | 298 | // If the solving process was successful, we create the transaction |
5bdd89a5 | 299 | r = pakfire_transaction_create(transaction, request->pakfire, request->solver); |
41ebf5f0 MT |
300 | if (r) |
301 | goto ERROR; | |
221cc3ce | 302 | |
41ebf5f0 | 303 | // All okay |
221cc3ce | 304 | return 0; |
41ebf5f0 MT |
305 | |
306 | ERROR: | |
307 | if (*transaction) | |
308 | pakfire_transaction_unref(*transaction); | |
309 | ||
310 | return r; | |
221cc3ce MT |
311 | } |
312 | ||
2693edde MT |
313 | static int pakfire_request_is_file(const char* what) { |
314 | return pakfire_string_endswith(what, ".pfm"); | |
315 | } | |
316 | ||
317 | static int pakfire_request_is_url(const char* what) { | |
318 | static const char* known_schemas[] = { | |
319 | "https://", | |
320 | "http://", | |
321 | "file://", | |
322 | NULL, | |
323 | }; | |
324 | ||
325 | for (const char** schema = known_schemas; *schema; schema++) { | |
326 | if (pakfire_string_startswith(what, *schema)) | |
327 | return 1; | |
328 | } | |
329 | ||
330 | return 0; | |
331 | } | |
332 | ||
4ee2cfec | 333 | static int pakfire_request_add_package(struct pakfire_request* request, int action, |
31480bee | 334 | struct pakfire_package* pkg, int flags) { |
4ee2cfec MT |
335 | // Get the solvable ID |
336 | Id id = pakfire_package_id(pkg); | |
337 | ||
99a56775 MT |
338 | // Translate flags |
339 | flags = pakfire_request_job_flags(flags); | |
340 | ||
4ee2cfec MT |
341 | // Add it to the job queue |
342 | queue_push2(&request->jobs, SOLVER_SOLVABLE|action|flags, id); | |
343 | ||
344 | return 0; | |
345 | } | |
346 | ||
32e0d47a MT |
347 | static int pakfire_request_add_job(struct pakfire_request* request, int action, |
348 | const char* what, int extra_flags) { | |
cdcd6acb MT |
349 | Pool* pool = pakfire_get_solv_pool(request->pakfire); |
350 | ||
24f34626 | 351 | // Make the pool ready |
9eba3d65 | 352 | pakfire_pool_internalize(request->pakfire); |
cdcd6acb MT |
353 | |
354 | Queue jobs; | |
355 | queue_init(&jobs); | |
356 | ||
357 | int flags = | |
358 | // Select packages by name | |
359 | SELECTION_NAME| | |
360 | // Select packages by what they provide | |
361 | SELECTION_PROVIDES| | |
362 | // Process globbing patterns | |
363 | SELECTION_GLOB| | |
364 | // Select packages by their canonical name | |
365 | SELECTION_CANON| | |
366 | // Process .arch | |
367 | SELECTION_DOTARCH| | |
368 | // Process -release | |
369 | SELECTION_REL; | |
370 | ||
371 | // Process filelists? | |
372 | if (*what == '/') | |
373 | flags |= SELECTION_FILELIST; | |
374 | ||
375 | // Select all packages | |
8e257071 | 376 | selection_make(pool, &jobs, what, flags); |
cdcd6acb MT |
377 | |
378 | // Did we find anything? | |
379 | if (jobs.count == 0) { | |
4abdf39d | 380 | Id id = pakfire_str2dep(request->pakfire, what); |
02703c83 MT |
381 | if (!id) |
382 | return 1; | |
383 | ||
384 | queue_push2(&jobs, SOLVER_SOLVABLE_PROVIDES, id); | |
cdcd6acb MT |
385 | } |
386 | ||
387 | DEBUG(request->pakfire, "Found %d match(es) for '%s'\n", jobs.count / 2, what); | |
388 | ||
99a56775 MT |
389 | // Translate flags |
390 | const int job_flags = pakfire_request_job_flags(extra_flags); | |
391 | ||
cdcd6acb MT |
392 | // Set action and global flags |
393 | for (int i = 0; i < jobs.count; i += 2) | |
99a56775 | 394 | jobs.elements[i] |= action | job_flags; |
cdcd6acb MT |
395 | |
396 | // Merge jobs into the main job queue | |
397 | queue_insertn(&request->jobs, request->jobs.count, jobs.count, jobs.elements); | |
398 | queue_free(&jobs); | |
399 | ||
400 | return 0; | |
401 | } | |
402 | ||
2693edde | 403 | static int pakfire_request_add_archive(struct pakfire_request* request, int action, |
900faa2f | 404 | struct pakfire_archive* archive, int extra_flags) { |
20b13a1b | 405 | struct pakfire_package* package = NULL; |
14fe6b07 MT |
406 | int r; |
407 | ||
6ebd55e2 | 408 | struct pakfire_repo* repo = pakfire_get_repo(request->pakfire, PAKFIRE_REPO_COMMANDLINE); |
53482d6d MT |
409 | if (!repo) |
410 | return 1; | |
2693edde MT |
411 | |
412 | // Add it to the repository | |
20b13a1b MT |
413 | r = pakfire_repo_add_archive(repo, archive, &package); |
414 | if (r) | |
2693edde MT |
415 | goto ERROR; |
416 | ||
20b13a1b | 417 | r = pakfire_request_add_package(request, action, package, extra_flags); |
2693edde MT |
418 | if (r) |
419 | goto ERROR; | |
420 | ||
421 | // Success | |
422 | r = 0; | |
423 | ||
424 | ERROR: | |
20b13a1b MT |
425 | if (package) |
426 | pakfire_package_unref(package); | |
2693edde MT |
427 | pakfire_repo_unref(repo); |
428 | ||
429 | return r; | |
430 | } | |
431 | ||
432 | static int pakfire_request_add_file(struct pakfire_request* request, int action, | |
433 | const char* path, int extra_flags) { | |
0ab410c3 | 434 | struct pakfire_archive* archive = NULL; |
2693edde MT |
435 | |
436 | // Open the archive | |
437 | int r = pakfire_archive_open(&archive, request->pakfire, path); | |
438 | if (r) | |
439 | goto ERROR; | |
440 | ||
441 | // Add it to the request | |
442 | r = pakfire_request_add_archive(request, action, archive, extra_flags); | |
443 | if (r) | |
444 | goto ERROR; | |
445 | ||
446 | // Success | |
447 | r = 0; | |
448 | ||
449 | ERROR: | |
0ab410c3 MT |
450 | if (archive) |
451 | pakfire_archive_unref(archive); | |
2693edde MT |
452 | |
453 | return r; | |
454 | } | |
455 | ||
456 | static int pakfire_request_add_url(struct pakfire_request* request, int action, | |
457 | const char* url, int extra_flags) { | |
458 | struct pakfire_downloader* downloader; | |
6bf2cf50 | 459 | char path[PATH_MAX] = PAKFIRE_TMP_DIR "/pakfire-download.XXXXXX"; |
2693edde MT |
460 | |
461 | // Allocate a temporary file name | |
462 | FILE* f = pakfire_mktemp(path); | |
463 | if (!f) | |
464 | return 1; | |
465 | ||
466 | // Create a downloader | |
467 | int r = pakfire_downloader_create(&downloader, request->pakfire); | |
468 | if (r) | |
469 | return r; | |
470 | ||
471 | // Download the file | |
472 | r = pakfire_downloader_retrieve(downloader, NULL, NULL, NULL, | |
7cea394c | 473 | url, path, PAKFIRE_DIGEST_NONE, NULL, 0, PAKFIRE_TRANSFER_NOTEMP); |
2693edde MT |
474 | if (r) |
475 | goto ERROR; | |
476 | ||
477 | // Try adding the archive | |
478 | r = pakfire_request_add_file(request, action, path, extra_flags); | |
479 | if (r) | |
480 | goto ERROR; | |
481 | ||
482 | // Success | |
483 | r = 0; | |
484 | ||
485 | ERROR: | |
486 | if (f) | |
487 | fclose(f); | |
488 | pakfire_downloader_unref(downloader); | |
489 | ||
490 | return r; | |
491 | } | |
492 | ||
493 | static int pakfire_request_add(struct pakfire_request* request, int action, | |
494 | const char* what, int extra_flags) { | |
5b1e6c81 MT |
495 | if (!what) { |
496 | errno = EINVAL; | |
497 | return 1; | |
498 | } | |
499 | ||
500 | // Remove leading whitespace | |
501 | while (*what && isspace(*what)) | |
502 | what++; | |
503 | ||
2693edde MT |
504 | // Download and add any remote files |
505 | if (pakfire_request_is_url(what)) | |
506 | return pakfire_request_add_url(request, action, what, extra_flags); | |
507 | ||
508 | // Add any local files | |
509 | if (pakfire_request_is_file(what)) | |
510 | return pakfire_request_add_file(request, action, what, extra_flags); | |
511 | ||
512 | // Add anything else as a job | |
513 | return pakfire_request_add_job(request, action, what, extra_flags); | |
514 | } | |
515 | ||
325b1df5 MT |
516 | PAKFIRE_EXPORT int pakfire_request_install(struct pakfire_request* request, |
517 | const char* what, int flags) { | |
518 | return pakfire_request_add(request, SOLVER_INSTALL, what, flags); | |
cdcd6acb MT |
519 | } |
520 | ||
4ee2cfec | 521 | PAKFIRE_EXPORT int pakfire_request_install_package( |
31480bee | 522 | struct pakfire_request* request, struct pakfire_package* package) { |
4ee2cfec | 523 | return pakfire_request_add_package(request, SOLVER_INSTALL, package, 0); |
221cc3ce MT |
524 | } |
525 | ||
221cc3ce MT |
526 | static int erase_flags(int flags) { |
527 | int additional = 0; | |
528 | ||
d798b956 MT |
529 | // Keep dependencies |
530 | if (!(flags & PAKFIRE_REQUEST_KEEP_DEPS)) | |
221cc3ce MT |
531 | additional |= SOLVER_CLEANDEPS; |
532 | ||
533 | return additional; | |
534 | } | |
535 | ||
32e0d47a | 536 | PAKFIRE_EXPORT int pakfire_request_erase(struct pakfire_request* request, const char* what, int flags) { |
2693edde | 537 | return pakfire_request_add(request, SOLVER_ERASE, what, erase_flags(flags)); |
32e0d47a MT |
538 | } |
539 | ||
4ee2cfec | 540 | PAKFIRE_EXPORT int pakfire_request_erase_package( |
31480bee | 541 | struct pakfire_request* request, struct pakfire_package* package, int flags) { |
4ee2cfec | 542 | return pakfire_request_add_package(request, SOLVER_ERASE, package, erase_flags(flags)); |
221cc3ce MT |
543 | } |
544 | ||
5921591a | 545 | PAKFIRE_EXPORT int pakfire_request_update(struct pakfire_request* request, const char* what, int flags) { |
79d58f43 | 546 | return pakfire_request_add(request, SOLVER_UPDATE, what, flags); |
32e0d47a MT |
547 | } |
548 | ||
5921591a | 549 | PAKFIRE_EXPORT int pakfire_request_update_package( |
31480bee | 550 | struct pakfire_request* request, struct pakfire_package* package) { |
4ee2cfec | 551 | return pakfire_request_add_package(request, SOLVER_UPDATE, package, 0); |
221cc3ce MT |
552 | } |
553 | ||
c8e6f670 MT |
554 | PAKFIRE_EXPORT int pakfire_request_update_all(struct pakfire_request* request, int flags) { |
555 | queue_push2(&request->jobs, SOLVER_SOLVABLE_ALL|SOLVER_UPDATE|erase_flags(flags), 0); | |
221cc3ce MT |
556 | |
557 | return 0; | |
558 | } | |
559 | ||
550c7c1f MT |
560 | PAKFIRE_EXPORT int pakfire_request_sync(struct pakfire_request* request, int flags) { |
561 | int solver_flags = SOLVER_SOLVABLE_ALL|SOLVER_DISTUPGRADE; | |
562 | ||
563 | // Drop orphans | |
564 | if (!(flags & PAKFIRE_REQUEST_KEEP_ORPHANED)) | |
565 | solver_flags |= SOLVER_DROP_ORPHANED; | |
566 | ||
567 | queue_push2(&request->jobs, solver_flags, 0); | |
221cc3ce MT |
568 | |
569 | return 0; | |
570 | } | |
571 | ||
32e0d47a | 572 | PAKFIRE_EXPORT int pakfire_request_lock(struct pakfire_request* request, const char* what) { |
2693edde | 573 | return pakfire_request_add(request, SOLVER_LOCK, what, 0); |
32e0d47a MT |
574 | } |
575 | ||
31480bee | 576 | PAKFIRE_EXPORT int pakfire_request_lock_package(struct pakfire_request* request, struct pakfire_package* package) { |
4ee2cfec | 577 | return pakfire_request_add_package(request, SOLVER_LOCK, package, 0); |
221cc3ce MT |
578 | } |
579 | ||
550c7c1f | 580 | PAKFIRE_EXPORT int pakfire_request_verify(struct pakfire_request* request, int flags) { |
4ee2cfec | 581 | queue_push2(&request->jobs, SOLVER_SOLVABLE_ALL|SOLVER_VERIFY, 0); |
221cc3ce MT |
582 | |
583 | return 0; | |
584 | } | |
954f0a83 MT |
585 | |
586 | PAKFIRE_EXPORT int pakfire_request_take_solution(struct pakfire_request* request, | |
587 | struct pakfire_solution* solution) { | |
588 | struct pakfire_problem* problem = pakfire_solution_get_problem(solution); | |
589 | ||
590 | // Fetch IDs | |
591 | Id problem_id = pakfire_problem_get_id(problem); | |
592 | Id solution_id = pakfire_solution_get_id(solution); | |
593 | ||
594 | // Feed the solution into the solver | |
595 | solver_take_solution(request->solver, problem_id, solution_id, &request->jobs); | |
596 | ||
597 | pakfire_problem_unref(problem); | |
598 | return 0; | |
599 | } |