1 /*-
2 * Copyright (c) 2011-2016 Baptiste Daroussin <bapt@FreeBSD.org>
3 * Copyright (c) 2011-2012 Julien Laffaye <jlaffaye@FreeBSD.org>
4 * Copyright (c) 2011-2012 Marin Atanasov Nikolov <dnaeon@gmail.com>
5 * Copyright (c) 2013 Matthew Seaman <matthew@FreeBSD.org>
6 * Copyright (c) 2013-2016 Vsevolod Stakhov <vsevolod@FreeBSD.org>
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer
14 * in this position and unchanged.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22 * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31 #ifdef HAVE_CONFIG_H
32 #include "pkg_config.h"
33 #endif
34
35 #include <bsd_compat.h>
36
37 #include <sys/param.h>
38 #include <sys/mount.h>
39 #include <sys/types.h>
40
41 #include <archive.h>
42 #include <archive_entry.h>
43 #include <assert.h>
44 #include <errno.h>
45 #ifdef HAVE_LIBUTIL_H
46 #include <libutil.h>
47 #endif
48 #include <search.h>
49 #include <stdbool.h>
50 #include <stdlib.h>
51 #include <string.h>
52 #include <sys/wait.h>
53 #include <ctype.h>
54
55 #ifdef HAVE_SYS_STATFS_H
56 #include <sys/statfs.h>
57 #endif
58 #if defined(HAVE_SYS_STATVFS_H)
59 #include <sys/statvfs.h>
60 #endif
61
62 #include "pkg.h"
63 #include "private/event.h"
64 #include "private/pkg.h"
65 #include "private/pkgdb.h"
66 #include "private/pkg_jobs.h"
67 #include "kvec.h"
68
69 extern struct pkg_ctx ctx;
70
71 static int pkg_jobs_installed_local_pkg(struct pkg_jobs *j, struct pkg *pkg);
72 static int pkg_jobs_find_upgrade(struct pkg_jobs *j, const char *pattern, match_t m);
73 static int pkg_jobs_find_upgrade_cond(struct pkg_jobs *j, const char *cond,
74 const char *pattern, match_t m);
75 static int pkg_jobs_fetch(struct pkg_jobs *j);
76 static bool new_pkg_version(struct pkg_jobs *j);
77 static int pkg_jobs_check_conflicts(struct pkg_jobs *j);
78 struct pkg_jobs_locked {
79 int (*locked_pkg_cb)(struct pkg *, void *);
80 void *context;
81 };
82 static struct pkg_jobs_locked *pkgs_job_lockedpkg;
83
84 #define IS_DELETE(j) ((j)->type == PKG_JOBS_DEINSTALL || (j)->type == PKG_JOBS_AUTOREMOVE)
85
86 int
pkg_jobs_new(struct pkg_jobs ** j,pkg_jobs_t t,struct pkgdb * db)87 pkg_jobs_new(struct pkg_jobs **j, pkg_jobs_t t, struct pkgdb *db)
88 {
89 assert(db != NULL);
90
91 *j = xcalloc(1, sizeof(struct pkg_jobs));
92
93 (*j)->universe = pkg_jobs_universe_new(*j);
94
95 if ((*j)->universe == NULL) {
96 free(*j);
97 return (EPKG_FATAL);
98 }
99
100 (*j)->db = db;
101 (*j)->type = t;
102 (*j)->solved = 0;
103 (*j)->pinning = true;
104 (*j)->flags = PKG_FLAG_NONE;
105 (*j)->conservative = pkg_object_bool(pkg_config_get("CONSERVATIVE_UPGRADE"));
106
107 return (EPKG_OK);
108 }
109
110 void
pkg_jobs_set_flags(struct pkg_jobs * j,pkg_flags flags)111 pkg_jobs_set_flags(struct pkg_jobs *j, pkg_flags flags)
112 {
113 j->flags = flags;
114 }
115
116 int
pkg_jobs_set_repository(struct pkg_jobs * j,const char * ident)117 pkg_jobs_set_repository(struct pkg_jobs *j, const char *ident)
118 {
119 if ((pkg_repo_find(ident)) == NULL) {
120 pkg_emit_error("Unknown repository: %s", ident);
121 return (EPKG_FATAL);
122 }
123
124 j->reponame = ident;
125
126 return (EPKG_OK);
127 }
128
129 int
pkg_jobs_set_destdir(struct pkg_jobs * j,const char * dir)130 pkg_jobs_set_destdir(struct pkg_jobs *j, const char *dir)
131 {
132 if (dir == NULL)
133 return (EPKG_FATAL);
134
135 j->destdir = dir;
136
137 return (EPKG_OK);
138 }
139
140 const char*
pkg_jobs_destdir(struct pkg_jobs * j)141 pkg_jobs_destdir(struct pkg_jobs *j)
142 {
143 return (j->destdir);
144 }
145
146 static void
pkg_jobs_pattern_free(struct job_pattern * jp)147 pkg_jobs_pattern_free(struct job_pattern *jp)
148 {
149 free(jp->pattern);
150 free(jp->path);
151 free(jp);
152 }
153
154 void
pkg_jobs_request_free(struct pkg_job_request * req)155 pkg_jobs_request_free(struct pkg_job_request *req)
156 {
157 struct pkg_job_request_item *it, *tmp;
158
159 if (req != NULL) {
160 DL_FOREACH_SAFE(req->item, it, tmp) {
161 free(it);
162 }
163
164 free(req);
165 }
166 }
167
168 void
pkg_jobs_free(struct pkg_jobs * j)169 pkg_jobs_free(struct pkg_jobs *j)
170 {
171 struct pkg_job_request *req, *tmp;
172
173 if (j == NULL)
174 return;
175
176 HASH_ITER(hh, j->request_add, req, tmp) {
177 HASH_DEL(j->request_add, req);
178 pkg_jobs_request_free(req);
179 }
180 HASH_ITER(hh, j->request_delete, req, tmp) {
181 HASH_DEL(j->request_delete, req);
182 pkg_jobs_request_free(req);
183 }
184
185 pkg_jobs_universe_free(j->universe);
186 LL_FREE(j->jobs, free);
187 LL_FREE(j->patterns, pkg_jobs_pattern_free);
188 free(j);
189 }
190
191 static bool
pkg_jobs_maybe_match_file(struct job_pattern * jp,const char * pattern)192 pkg_jobs_maybe_match_file(struct job_pattern *jp, const char *pattern)
193 {
194 const char *dot_pos;
195 char *pkg_path;
196
197 assert(jp != NULL);
198 assert(pattern != NULL);
199
200 dot_pos = strrchr(pattern, '.');
201 if (dot_pos != NULL) {
202 /*
203 * Compare suffix with .txz or .tbz
204 */
205 dot_pos ++;
206 if (strcmp(dot_pos, "pkg") == 0 ||
207 strcmp(dot_pos, "tzst") == 0 ||
208 strcmp(dot_pos, "txz") == 0 ||
209 strcmp(dot_pos, "tbz") == 0 ||
210 strcmp(dot_pos, "tgz") == 0 ||
211 strcmp(dot_pos, "tar") == 0) {
212 if ((pkg_path = realpath(pattern, NULL)) != NULL) {
213 /* Dot pos is one character after the dot */
214 int len = dot_pos - pattern;
215
216 pkg_debug(1, "Jobs> Adding file: %s", pattern);
217 jp->flags |= PKG_PATTERN_FLAG_FILE;
218 jp->path = pkg_path;
219 jp->pattern = xmalloc(len);
220 strlcpy(jp->pattern, pattern, len);
221
222 return (true);
223 }
224 }
225 }
226 else if (strcmp(pattern, "-") == 0) {
227 /*
228 * Read package from stdin
229 */
230 jp->flags = PKG_PATTERN_FLAG_FILE;
231 jp->path = xstrdup(pattern);
232 jp->pattern = xstrdup(pattern);
233 }
234
235 return (false);
236 }
237
238 int
pkg_jobs_add(struct pkg_jobs * j,match_t match,char ** argv,int argc)239 pkg_jobs_add(struct pkg_jobs *j, match_t match, char **argv, int argc)
240 {
241 struct job_pattern *jp;
242 int i = 0;
243
244 if (j->solved) {
245 pkg_emit_error("The job has already been solved. "
246 "Impossible to append new elements");
247 return (EPKG_FATAL);
248 }
249
250 for (i = 0; i < argc; i++) {
251 jp = xcalloc(1, sizeof(struct job_pattern));
252 if (j->type == PKG_JOBS_DEINSTALL ||
253 !pkg_jobs_maybe_match_file(jp, argv[i])) {
254 jp->pattern = xstrdup(argv[i]);
255 jp->match = match;
256 }
257 LL_APPEND(j->patterns, jp);
258 }
259
260 if (argc == 0 && match == MATCH_ALL) {
261 jp = xcalloc(1, sizeof(struct job_pattern));
262 jp->pattern = NULL;
263 jp->match = match;
264 LL_APPEND(j->patterns, jp);
265 }
266
267 return (EPKG_OK);
268 }
269
270 bool
pkg_jobs_iter(struct pkg_jobs * jobs,void ** iter,struct pkg ** new,struct pkg ** old,int * type)271 pkg_jobs_iter(struct pkg_jobs *jobs, void **iter,
272 struct pkg **new, struct pkg **old,
273 int *type)
274 {
275 struct pkg_solved *s;
276 assert(iter != NULL);
277 if (jobs->jobs == NULL) {
278 return (false);
279 }
280 if (*iter == NULL) {
281 s = jobs->jobs;
282 }
283 else if (*iter == jobs->jobs) {
284 return (false);
285 }
286 else {
287 s = *iter;
288 }
289 *new = s->items[0]->pkg;
290 *old = s->items[1] ? s->items[1]->pkg : NULL;
291 *type = s->type;
292 *iter = s->next ? s->next : jobs->jobs;
293 return (true);
294 }
295
296 static struct pkg_job_request_item*
pkg_jobs_add_req_from_universe(struct pkg_job_request ** head,struct pkg_job_universe_item * un,bool local,bool automatic)297 pkg_jobs_add_req_from_universe(struct pkg_job_request **head,
298 struct pkg_job_universe_item *un, bool local, bool automatic)
299 {
300 struct pkg_job_request *req;
301 struct pkg_job_request_item *nit;
302 struct pkg_job_universe_item *uit;
303 bool new_req = false;
304
305 assert(un != NULL);
306 HASH_FIND_STR(*head, un->pkg->uid, req);
307
308 if (req == NULL) {
309 req = xcalloc(1, sizeof(*req));
310 new_req = true;
311 req->automatic = automatic;
312 pkg_debug(4, "add new uid %s to the request", un->pkg->uid);
313 }
314 else {
315 if (req->item->unit == un) {
316 /* We have exactly the same request, skip it */
317 return (req->item);
318 }
319 }
320
321 DL_FOREACH(un, uit) {
322 if ((uit->pkg->type == PKG_INSTALLED && local) ||
323 (uit->pkg->type != PKG_INSTALLED && !local)) {
324 nit = xcalloc(1, sizeof(*nit));
325 nit->pkg = uit->pkg;
326 nit->unit = uit;
327 DL_APPEND(req->item, nit);
328 }
329 }
330
331 if (new_req) {
332 if (req->item != NULL) {
333 HASH_ADD_KEYPTR(hh, *head, un->pkg->uid, strlen(un->pkg->uid), req);
334 }
335 else {
336 free(req);
337 return (NULL);
338 }
339 }
340
341 return (req->item);
342 }
343
344 static struct pkg_job_request_item*
pkg_jobs_add_req(struct pkg_jobs * j,struct pkg * pkg)345 pkg_jobs_add_req(struct pkg_jobs *j, struct pkg *pkg)
346 {
347 struct pkg_job_request *req, **head;
348 struct pkg_job_request_item *nit;
349 struct pkg_job_universe_item *un;
350 int rc;
351
352 assert(pkg != NULL);
353
354 if (!IS_DELETE(j)) {
355 head = &j->request_add;
356 assert(pkg->type != PKG_INSTALLED);
357 }
358 else {
359 head = &j->request_delete;
360 assert(pkg->type == PKG_INSTALLED);
361 }
362
363 pkg_debug(4, "universe: add package %s-%s to the request", pkg->name,
364 pkg->version);
365 rc = pkg_jobs_universe_add_pkg(j->universe, pkg, false, &un);
366
367 if (rc == EPKG_END) {
368 /*
369 * This means that we have a package in the universe with the same
370 * digest. In turn, that means that two upgrade candidates are equal,
371 * we thus won't do anything with this item, as it is definitely useless
372 */
373 HASH_FIND_STR(*head, pkg->uid, req);
374 if (req != NULL) {
375 DL_FOREACH(req->item, nit) {
376 if (nit->unit == un)
377 return (nit);
378 }
379 }
380 else {
381 /*
382 * We need to add request chain from the universe chain
383 */
384 return (pkg_jobs_add_req_from_universe(head, un, IS_DELETE(j), false));
385 }
386
387 return (NULL);
388 }
389 else if (rc == EPKG_FATAL) {
390 /*
391 * Something bad has happened
392 */
393 return (NULL);
394 }
395
396 if (pkg->locked) {
397 pkg_emit_locked(pkg);
398 return (NULL);
399 }
400
401 HASH_FIND_STR(*head, pkg->uid, req);
402
403 nit = xcalloc(1, sizeof(*nit));
404 nit->pkg = pkg;
405 nit->unit = un;
406
407 if (req == NULL) {
408 /* Allocate new unique request item */
409 req = xcalloc(1, sizeof(*req));
410 HASH_ADD_KEYPTR(hh, *head, pkg->uid, strlen(pkg->uid), req);
411 }
412
413 /* Append candidate to the list of candidates */
414 DL_APPEND(req->item, nit);
415
416 return (nit);
417 }
418
419 /*
420 * Post-process add request and handle flags:
421 * upgrade - search for upgrades for dependencies and add them to the request
422 * force - all upgrades are forced
423 * reverse - try to upgrade reverse deps as well
424 */
425 static void
pkg_jobs_process_add_request(struct pkg_jobs * j)426 pkg_jobs_process_add_request(struct pkg_jobs *j)
427 {
428 bool force = j->flags & PKG_FLAG_FORCE,
429 reverse = j->flags & PKG_FLAG_RECURSIVE,
430 upgrade = j->type == PKG_JOBS_UPGRADE;
431 struct pkg_job_request *req, *tmp, *found;
432 struct pkg_job_request_item *it;
433 struct pkg_job_universe_item *un, *cur;
434 struct pkg_dep *d;
435 struct pkg *lp;
436 int (*deps_func)(const struct pkg *pkg, struct pkg_dep **d);
437 kvec_t(struct pkg_job_universe_item *) to_process;
438
439 if (!upgrade && !reverse)
440 return;
441
442 kv_init(to_process);
443 HASH_ITER(hh, j->request_add, req, tmp) {
444 it = req->item;
445
446 if (reverse)
447 deps_func = pkg_rdeps;
448 else
449 deps_func = pkg_deps;
450
451 d = NULL;
452 /*
453 * Here we get deps of local packages only since we are pretty sure
454 * that they are completely expanded
455 */
456 lp = pkg_jobs_universe_get_local(j->universe,
457 it->pkg->uid, 0);
458 while (lp != NULL && deps_func(lp, &d) == EPKG_OK) {
459 /*
460 * Do not add duplicated upgrade candidates
461 */
462 HASH_FIND_STR(j->request_add, d->uid, found);
463 if (found != NULL)
464 continue;
465
466 pkg_debug(4, "adding dependency %s to request", d->uid);
467 lp = pkg_jobs_universe_get_local(j->universe,
468 d->uid, 0);
469 /*
470 * Here we need to check whether specific remote package
471 * is newer than a local one
472 */
473 un = pkg_jobs_universe_get_upgrade_candidates(j->universe,
474 d->uid, lp, force, NULL);
475 if (un == NULL)
476 continue;
477
478 cur = un->prev;
479 while (cur != un) {
480 if (cur->pkg->type != PKG_INSTALLED) {
481 kv_push(typeof(un), to_process, un);
482 break;
483 }
484 cur = cur->prev;
485 }
486 }
487 }
488
489 /* Add all items to the request */
490 for (int i = 0; i < kv_size(to_process); i++) {
491 un = kv_A(to_process, i);
492 pkg_jobs_add_req_from_universe(&j->request_add, un, false, true);
493 }
494 /* Now recursively process all items checked */
495 if (kv_size(to_process) > 0)
496 pkg_jobs_process_add_request(j);
497
498 kv_destroy(to_process);
499 }
500
501 /*
502 * For delete request we merely check rdeps and force flag
503 */
504 static int
pkg_jobs_process_delete_request(struct pkg_jobs * j)505 pkg_jobs_process_delete_request(struct pkg_jobs *j)
506 {
507 bool force = j->flags & PKG_FLAG_FORCE;
508 struct pkg_job_request *req, *tmp, *found;
509 struct pkg_dep *d = NULL;
510 struct pkg *lp;
511 int rc = EPKG_OK;
512 kvec_t(struct pkg *) to_process;
513
514 if (force)
515 return (EPKG_OK);
516
517 kv_init(to_process);
518 /*
519 * Need to add also all reverse deps here
520 */
521 HASH_ITER(hh, j->request_delete, req, tmp) {
522 d = NULL;
523 while (pkg_rdeps(req->item->pkg, &d) == EPKG_OK) {
524 HASH_FIND_STR(j->request_delete, d->uid, found);
525 if (found)
526 continue;
527
528 lp = pkg_jobs_universe_get_local(j->universe, d->uid, 0);
529 if (lp) {
530 if (lp->locked) {
531 pkg_emit_error("%s is locked, "
532 "cannot delete %s", lp->name,
533 req->item->pkg->name);
534 rc = EPKG_FATAL;
535 }
536 kv_push(typeof(lp), to_process, lp);
537 }
538 }
539 }
540
541 if (rc == EPKG_FATAL)
542 return (rc);
543
544 for (int i = 0; i < kv_size(to_process); i++) {
545 lp = kv_A(to_process, i);
546 if (pkg_jobs_add_req(j, lp) == NULL) {
547 kv_destroy(to_process);
548 return (EPKG_FATAL);
549 }
550 }
551 if (kv_size(to_process) > 0)
552 rc = pkg_jobs_process_delete_request(j);
553 kv_destroy(to_process);
554
555 return (rc);
556 }
557
558 static int
pkg_jobs_set_execute_priority(struct pkg_jobs * j,struct pkg_solved * solved)559 pkg_jobs_set_execute_priority(struct pkg_jobs *j, struct pkg_solved *solved)
560 {
561 struct pkg_solved *ts;
562
563 if (solved->type == PKG_SOLVED_UPGRADE
564 && solved->items[1]->pkg->conflicts != NULL) {
565 /*
566 * We have an upgrade request that has some conflicting packages, therefore
567 * update priorities of local packages and try to update priorities of remote ones
568 */
569 if (solved->items[0]->priority == 0)
570 pkg_jobs_update_conflict_priority(j->universe, solved);
571
572 if (solved->items[1]->priority > solved->items[0]->priority &&
573 !solved->already_deleted) {
574 /*
575 * Split conflicting upgrade request into delete -> upgrade request
576 */
577 ts = xcalloc(1, sizeof(struct pkg_solved));
578 ts->type = PKG_SOLVED_UPGRADE_REMOVE;
579 ts->items[0] = solved->items[1];
580 solved->items[1] = NULL;
581 solved->type = PKG_SOLVED_UPGRADE_INSTALL;
582 DL_APPEND(j->jobs, ts);
583 j->count ++;
584 solved->already_deleted = true;
585 pkg_debug(2, "split upgrade request for %s",
586 ts->items[0]->pkg->uid);
587 return (EPKG_CONFLICT);
588 }
589 }
590 else if (solved->type == PKG_SOLVED_DELETE) {
591 if (solved->items[0]->priority == 0)
592 pkg_jobs_update_universe_priority(j->universe, solved->items[0],
593 PKG_PRIORITY_UPDATE_DELETE);
594 }
595 else {
596 if (solved->items[0]->priority == 0)
597 pkg_jobs_update_universe_priority(j->universe, solved->items[0],
598 PKG_PRIORITY_UPDATE_REQUEST);
599 }
600
601 return (EPKG_OK);
602 }
603
604 static bool
pkg_jobs_is_delete(struct pkg_solved * req)605 pkg_jobs_is_delete(struct pkg_solved *req)
606 {
607 return (req->type == PKG_SOLVED_DELETE ||
608 req->type == PKG_SOLVED_UPGRADE_REMOVE);
609 }
610
611 static int
pkg_jobs_sort_priority(struct pkg_solved * r1,struct pkg_solved * r2)612 pkg_jobs_sort_priority(struct pkg_solved *r1, struct pkg_solved *r2)
613 {
614 if (r1->items[0]->priority == r2->items[0]->priority) {
615 if (pkg_jobs_is_delete(r1) && !pkg_jobs_is_delete(r2))
616 return (-1);
617 if (pkg_jobs_is_delete(r2) && !pkg_jobs_is_delete(r1))
618 return (1);
619
620 return (0);
621 }
622 return (r2->items[0]->priority - r1->items[0]->priority);
623 }
624
625 static void
pkg_jobs_set_priorities(struct pkg_jobs * j)626 pkg_jobs_set_priorities(struct pkg_jobs *j)
627 {
628 struct pkg_solved *req;
629
630 iter_again:
631 LL_FOREACH(j->jobs, req) {
632 req->items[0]->priority = 0;
633 if (req->items[1] != NULL)
634 req->items[1]->priority = 0;
635 }
636 LL_FOREACH(j->jobs, req) {
637 if (pkg_jobs_set_execute_priority(j, req) == EPKG_CONFLICT)
638 goto iter_again;
639 }
640
641 DL_SORT(j->jobs, pkg_jobs_sort_priority);
642 }
643
644
645 /**
646 * Test whether package specified is automatic with all its rdeps
647 * @param j
648 * @param p
649 * @return
650 */
651 static bool
pkg_jobs_test_automatic(struct pkg_jobs * j,struct pkg * p)652 pkg_jobs_test_automatic(struct pkg_jobs *j, struct pkg *p)
653 {
654 struct pkg_dep *d = NULL;
655 struct pkg_job_universe_item *unit;
656 struct pkg *npkg;
657 bool ret = true;
658
659 while (pkg_rdeps(p, &d) == EPKG_OK && ret) {
660 unit = pkg_jobs_universe_find(j->universe, d->uid);
661 if (unit != NULL) {
662 if (!unit->pkg->automatic) {
663 return (false);
664 }
665 npkg = unit->pkg;
666 }
667 else {
668 npkg = pkg_jobs_universe_get_local(j->universe, d->uid,
669 PKG_LOAD_BASIC|PKG_LOAD_RDEPS|PKG_LOAD_ANNOTATIONS);
670 if (npkg == NULL)
671 return (false);
672 if (!npkg->automatic) {
673 /*
674 * Safe to free, as d->uid is not in the universe
675 */
676 pkg_free(npkg);
677 return (false);
678 }
679 if (pkg_jobs_universe_process(j->universe, npkg) != EPKG_OK)
680 return (false);
681 }
682
683 ret = pkg_jobs_test_automatic(j, npkg);
684 }
685
686 return (ret);
687 }
688
689
690
691 static bool
new_pkg_version(struct pkg_jobs * j)692 new_pkg_version(struct pkg_jobs *j)
693 {
694 struct pkg *p;
695 const char *uid = "pkg";
696 pkg_flags old_flags;
697 bool ret = false;
698 struct pkg_job_universe_item *nit, *cit;
699
700 /* Disable -f for pkg self-check, and restore at end. */
701 old_flags = j->flags;
702 j->flags &= ~(PKG_FLAG_FORCE|PKG_FLAG_RECURSIVE);
703
704 /* determine local pkgng */
705 p = pkg_jobs_universe_get_local(j->universe, uid, 0);
706
707 if (p == NULL) {
708 uid = "pkg-devel";
709 p = pkg_jobs_universe_get_local(j->universe, uid, 0);
710 }
711
712 /* you are using git version skip */
713 if (p == NULL) {
714 ret = false;
715 goto end;
716 }
717
718 /* Use maximum priority for pkg */
719 if (pkg_jobs_find_upgrade(j, uid, MATCH_EXACT) == EPKG_OK) {
720 /*
721 * Now we can have *potential* upgrades, but we can have a situation,
722 * when our upgrade candidate comes from another repo
723 */
724 nit = pkg_jobs_universe_find(j->universe, uid);
725
726 if (nit) {
727 DL_FOREACH(nit, cit) {
728 if (pkg_version_change_between (cit->pkg, p) == PKG_UPGRADE) {
729 /* We really have newer version which is not installed */
730 ret = true;
731 break;
732 }
733 }
734 }
735 }
736
737 end:
738 j->flags = old_flags;
739
740 return (ret);
741 }
742
743 static int
pkg_jobs_process_remote_pkg(struct pkg_jobs * j,struct pkg * rp,struct pkg_job_request_item ** req,int with_version)744 pkg_jobs_process_remote_pkg(struct pkg_jobs *j, struct pkg *rp,
745 struct pkg_job_request_item **req, int with_version)
746 {
747 struct pkg_job_universe_item *nit, *cur;
748 struct pkg_job_request_item *nrit = NULL;
749 struct pkg *lp = NULL;
750 struct pkg_dep *rdep = NULL;
751
752 if (rp->digest == NULL) {
753 if (pkg_checksum_calculate(rp, j->db, false, true, false) != EPKG_OK) {
754 return (EPKG_FATAL);
755 }
756 }
757 if (j->type != PKG_JOBS_FETCH) {
758 lp = pkg_jobs_universe_get_local(j->universe, rp->uid, 0);
759 if (lp && lp->locked)
760 return (EPKG_LOCKED);
761 }
762
763 nit = pkg_jobs_universe_get_upgrade_candidates(j->universe, rp->uid, lp,
764 j->flags & PKG_FLAG_FORCE,
765 with_version != 0 ? rp->version : NULL);
766
767 if (nit != NULL) {
768 nrit = pkg_jobs_add_req_from_universe(&j->request_add, nit, false, false);
769
770 if (req != NULL)
771 *req = nrit;
772
773 if (j->flags & PKG_FLAG_UPGRADE_VULNERABLE) {
774 /* Set the proper reason */
775 DL_FOREACH(nit, cur) {
776 if (cur->pkg->type != PKG_INSTALLED) {
777 free(cur->pkg->reason);
778 xasprintf(&cur->pkg->reason, "vulnerability found");
779 }
780 }
781 /* Also process all rdeps recursively */
782 while (pkg_rdeps(nrit->pkg, &rdep) == EPKG_OK) {
783 lp = pkg_jobs_universe_get_local(j->universe, rdep->uid, 0);
784
785 if (lp) {
786 (void)pkg_jobs_process_remote_pkg(j, lp, NULL, 0);
787 }
788 }
789 }
790 }
791
792 if (nrit == NULL && lp)
793 return (EPKG_INSTALLED);
794
795 return (nrit != NULL ? EPKG_OK : EPKG_FATAL);
796 }
797
798 static bool
pkg_jobs_has_replacement(struct pkg_jobs * j,const char * uid)799 pkg_jobs_has_replacement(struct pkg_jobs *j, const char *uid)
800 {
801 struct pkg_job_replace *cur;
802
803 LL_FOREACH(j->universe->uid_replaces, cur) {
804 if (strcmp (cur->new_uid, uid) == 0) {
805 return (true);
806 }
807 }
808
809 return (false);
810 }
811
812 static int
pkg_jobs_try_remote_candidate(struct pkg_jobs * j,const char * cond,const char * pattern,const char * uid,match_t m)813 pkg_jobs_try_remote_candidate(struct pkg_jobs *j, const char *cond, const char *pattern,
814 const char *uid, match_t m)
815 {
816 struct pkg *p = NULL;
817 struct pkgdb_it *it;
818 unsigned flags = PKG_LOAD_BASIC|PKG_LOAD_OPTIONS|PKG_LOAD_DEPS|
819 PKG_LOAD_REQUIRES|PKG_LOAD_PROVIDES|
820 PKG_LOAD_SHLIBS_REQUIRED|PKG_LOAD_SHLIBS_PROVIDED|
821 PKG_LOAD_ANNOTATIONS|PKG_LOAD_CONFLICTS;
822 int rc = EPKG_FATAL;
823 xstring *qmsg = NULL;
824 struct pkg_job_universe_item *unit;
825
826 if ((it = pkgdb_repo_query_cond(j->db, cond, pattern, m, j->reponame)) == NULL)
827 return (EPKG_FATAL);
828
829 while (it != NULL && pkgdb_it_next(it, &p, flags) == EPKG_OK) {
830 xstring_renew(qmsg);
831 if (pkg_jobs_has_replacement(j, p->uid)) {
832 pkg_debug(1, "replacement %s is already used", p->uid);
833 continue;
834 }
835
836 fprintf(qmsg->fp, "%s has no direct installation candidates, change it to "
837 "%s? ", uid, p->uid);
838 fflush(qmsg->fp);
839 if (pkg_emit_query_yesno(true, qmsg->buf)) {
840 /* Change the origin of the local package */
841 pkg_validate(p, j->db);
842 unit = pkg_jobs_universe_find(j->universe, uid);
843 if (unit != NULL)
844 pkg_jobs_universe_change_uid(j->universe, unit, p->uid,
845 strlen(p->uid), false);
846 else
847 assert(0);
848
849 rc = EPKG_OK;
850 pkg_jobs_process_remote_pkg(j, p, NULL, 0);
851 if (rc == EPKG_OK) {
852 /* Avoid freeing */
853 p = NULL;
854 }
855 break;
856 }
857 }
858
859
860 pkg_free(p);
861
862 xstring_free(qmsg);
863 pkgdb_it_free(it);
864
865 return (rc);
866 }
867
868 static int
pkg_jobs_guess_upgrade_candidate(struct pkg_jobs * j,const char * pattern)869 pkg_jobs_guess_upgrade_candidate(struct pkg_jobs *j, const char *pattern)
870 {
871
872 int rc = EPKG_FATAL;
873 const char *pos, *opattern = pattern;
874 char *cpy;
875 size_t len, olen;
876
877 /* First of all, try to search a package with the same name */
878 pos = strchr(pattern, '/');
879 if (pos != NULL && pos[1] != '\0') {
880 if (pkg_jobs_try_remote_candidate(j, pos + 1, NULL, opattern, MATCH_EXACT)
881 == EPKG_OK)
882 return (EPKG_OK);
883
884 pos ++;
885 } else {
886 pos = pattern;
887 }
888
889 /* Figure, if we have any numbers at the end of the package */
890 olen = strlen(pos);
891 len = olen;
892 while (len > 0) {
893 if (isdigit(pos[len - 1]) || pos[len - 1] == '.')
894 len --;
895 else
896 break;
897 }
898
899 if (olen != len) {
900 /* Try exact pattern without numbers */
901 cpy = xmalloc(len + 1);
902 strlcpy(cpy, pos, len + 1);
903 if (pkg_jobs_try_remote_candidate(j, cpy, NULL, opattern, MATCH_EXACT) != EPKG_OK) {
904 free(cpy);
905 cpy = sqlite3_mprintf(" WHERE name REGEXP ('^' || %.*Q || '[0-9.]*$')",
906 len, pos);
907
908 if (pkg_jobs_try_remote_candidate(j, cpy, opattern, NULL, MATCH_ALL)
909 == EPKG_OK)
910 rc = EPKG_OK;
911 sqlite3_free(cpy);
912 }
913 else {
914 free(cpy);
915 rc = EPKG_OK;
916 }
917 }
918
919 return (rc);
920 }
921
922 static int
pkg_jobs_find_upgrade_cond(struct pkg_jobs * j,const char * cond,const char * pattern,match_t m)923 pkg_jobs_find_upgrade_cond(struct pkg_jobs *j, const char *cond, const char *pattern, match_t m)
924 {
925 struct pkg *p = NULL;
926 struct pkgdb_it *it;
927 bool checklocal, found = false;
928 int rc = EPKG_FATAL;
929 int with_version;
930 struct pkg_dep *rdep = NULL;
931 unsigned flags = PKG_LOAD_BASIC|PKG_LOAD_OPTIONS|PKG_LOAD_DEPS|
932 PKG_LOAD_REQUIRES|PKG_LOAD_PROVIDES|
933 PKG_LOAD_SHLIBS_REQUIRED|PKG_LOAD_SHLIBS_PROVIDED|
934 PKG_LOAD_ANNOTATIONS|PKG_LOAD_CONFLICTS;
935 struct pkg_job_universe_item *unit = NULL;
936
937 if ((it = pkgdb_repo_query(j->db, pattern, m, j->reponame)) == NULL)
938 rc = EPKG_FATAL;
939
940 /*
941 * MATCH_EXACT is handled at a higher level, so that we can complain if a
942 * specific upgrade was requested without the package being locally installed.
943 *
944 * MATCH_ALL is a non-issue, because we will not get that from pkg-upgrade
945 * anyways.
946
947 * Pattern matches are the main target, as the above query may grab packages
948 * that are not installed that we can ignore.
949 */
950 checklocal = j->type == PKG_JOBS_UPGRADE && m != MATCH_EXACT && m != MATCH_ALL;
951 while (it != NULL && pkgdb_it_next(it, &p, flags) == EPKG_OK) {
952 if (checklocal && pkg_jobs_installed_local_pkg(j, p) != EPKG_OK)
953 continue;
954 if (pattern != NULL) {
955 with_version = strcmp(p->name, pattern);
956 } else {
957 with_version = 0;
958 }
959 rc = pkg_jobs_process_remote_pkg(j, p, NULL, with_version);
960 if (rc == EPKG_FATAL)
961 break;
962 else if (rc == EPKG_OK)
963 found = true;
964
965 p = NULL;
966 }
967
968 pkgdb_it_free(it);
969
970 if (!found && rc != EPKG_INSTALLED) {
971 /*
972 * Here we need to ensure that this package has no
973 * reverse deps installed
974 */
975 p = pkg_jobs_universe_get_local(j->universe, pattern,
976 PKG_LOAD_BASIC|PKG_LOAD_RDEPS);
977 if (p == NULL)
978 return (EPKG_FATAL);
979
980 while(pkg_rdeps(p, &rdep) == EPKG_OK) {
981 struct pkg *rdep_package;
982
983 rdep_package = pkg_jobs_universe_get_local(j->universe, rdep->uid,
984 PKG_LOAD_BASIC);
985 if (rdep_package != NULL)
986 return (EPKG_END);
987 }
988
989 pkg_debug(2, "non-automatic package with pattern %s has not been found in "
990 "remote repo", pattern);
991 rc = pkg_jobs_universe_add_pkg(j->universe, p, false, &unit);
992 if (rc == EPKG_OK) {
993 rc = pkg_jobs_guess_upgrade_candidate(j, pattern);
994 }
995 }
996
997 return (rc);
998 }
999
1000 static int
pkg_jobs_find_upgrade(struct pkg_jobs * j,const char * pattern,match_t m)1001 pkg_jobs_find_upgrade(struct pkg_jobs *j, const char *pattern, match_t m)
1002 {
1003 return pkg_jobs_find_upgrade_cond(j, NULL, pattern, m);
1004 }
1005
1006 static int
pkg_jobs_check_local_pkg(struct pkg_jobs * j,struct job_pattern * jp)1007 pkg_jobs_check_local_pkg(struct pkg_jobs *j, struct job_pattern *jp)
1008 {
1009 struct pkgdb_it *it;
1010 struct pkg *pkg = NULL;
1011 int rc = EPKG_OK;
1012
1013 it = pkgdb_query(j->db, jp->pattern, jp->match);
1014 if (it != NULL) {
1015 if (pkgdb_it_next(it, &pkg, PKG_LOAD_BASIC|PKG_LOAD_ANNOTATIONS) != EPKG_OK)
1016 rc = EPKG_FATAL;
1017 else
1018 pkg_free(pkg);
1019
1020 pkgdb_it_free(it);
1021 }
1022 else {
1023 rc = EPKG_FATAL;
1024 }
1025
1026 return (rc);
1027 }
1028
1029 static int
pkg_jobs_installed_local_pkg(struct pkg_jobs * j,struct pkg * pkg)1030 pkg_jobs_installed_local_pkg(struct pkg_jobs *j, struct pkg *pkg)
1031 {
1032 struct job_pattern jfp;
1033
1034 jfp.match = MATCH_EXACT;
1035 jfp.pattern = pkg->name;
1036 return (pkg_jobs_check_local_pkg(j, &jfp));
1037 }
1038
1039 static int
pkg_jobs_find_remote_pattern(struct pkg_jobs * j,struct job_pattern * jp)1040 pkg_jobs_find_remote_pattern(struct pkg_jobs *j, struct job_pattern *jp)
1041 {
1042 int rc = EPKG_OK;
1043 struct pkg *pkg = NULL;
1044 struct pkg_manifest_key *keys = NULL;
1045 struct pkg_job_request *req;
1046
1047 if (!(jp->flags & PKG_PATTERN_FLAG_FILE)) {
1048 if (j->type == PKG_JOBS_UPGRADE && jp->match == MATCH_EXACT) {
1049 /*
1050 * For upgrade patterns we must ensure that a local package is
1051 * installed as well. This only works if we're operating on an
1052 * exact match, as we otherwise don't know exactly what packages
1053 * are in store for us.
1054 */
1055 if (pkg_jobs_check_local_pkg(j, jp) != EPKG_OK) {
1056 pkg_emit_error("%s is not installed, therefore upgrade is impossible",
1057 jp->pattern);
1058 return (EPKG_NOTINSTALLED);
1059 }
1060 }
1061 rc = pkg_jobs_find_upgrade(j, jp->pattern, jp->match);
1062 }
1063 else {
1064 pkg_manifest_keys_new(&keys);
1065 if (pkg_open(&pkg, jp->path, keys, PKG_OPEN_MANIFEST_ONLY) != EPKG_OK) {
1066 rc = EPKG_FATAL;
1067 } else if (pkg_validate(pkg, j->db) == EPKG_OK) {
1068 if (j->type == PKG_JOBS_UPGRADE && pkg_jobs_installed_local_pkg(j, pkg) != EPKG_OK) {
1069 pkg_emit_error("%s is not installed, therefore upgrade is impossible",
1070 pkg->name);
1071 pkg_manifest_keys_free(keys);
1072 return (EPKG_NOTINSTALLED);
1073 }
1074 pkg->type = PKG_FILE;
1075 pkg_jobs_add_req(j, pkg);
1076
1077 HASH_FIND_STR(j->request_add, pkg->uid, req);
1078 if (req != NULL)
1079 req->item->jp = jp;
1080 }
1081 else {
1082 pkg_emit_error("cannot load %s: invalid format",
1083 jp->pattern);
1084 rc = EPKG_FATAL;
1085 }
1086 pkg_manifest_keys_free(keys);
1087 }
1088
1089 return (rc);
1090 }
1091
1092 bool
pkg_jobs_need_upgrade(struct pkg * rp,struct pkg * lp)1093 pkg_jobs_need_upgrade(struct pkg *rp, struct pkg *lp)
1094 {
1095 int ret, ret1, ret2;
1096 struct pkg_option *lo = NULL, *ro = NULL;
1097 struct pkg_dep *ld = NULL, *rd = NULL;
1098 struct pkg_conflict *lc = NULL, *rc = NULL;
1099 char *lb, *rb;
1100
1101 /* If no local package, then rp is obviously need to be added */
1102 if (lp == NULL)
1103 return true;
1104
1105 /* Do not upgrade locked packages */
1106 if (lp->locked) {
1107 pkg_emit_locked(lp);
1108 return (false);
1109 }
1110
1111 if (lp->digest != NULL && rp->digest != NULL &&
1112 strcmp(lp->digest, rp->digest) == 0) {
1113 /* Remote and local packages has the same digest, hence they are the same */
1114 return (false);
1115 }
1116 /*
1117 * XXX: for a remote package we also need to check whether options
1118 * are compatible.
1119 */
1120 ret = pkg_version_cmp(lp->version, rp->version);
1121 if (ret > 0)
1122 return (false);
1123 else if (ret < 0)
1124 return (true);
1125
1126 /* Compare archs */
1127 if (strcmp (lp->arch, rp->arch) != 0) {
1128 free(rp->reason);
1129 xasprintf(&rp->reason, "ABI changed: '%s' -> '%s'",
1130 lp->arch, rp->arch);
1131 assert(rp->reason != NULL);
1132 return (true);
1133 }
1134
1135 /* compare options */
1136 for (;;) {
1137 ret1 = pkg_options(rp, &ro);
1138 ret2 = pkg_options(lp, &lo);
1139 if (ret1 != ret2) {
1140 free(rp->reason);
1141 if (ro == NULL)
1142 xasprintf(&rp->reason, "option removed: %s",
1143 lo->key);
1144 else if (lo == NULL)
1145 xasprintf(&rp->reason, "option added: %s",
1146 ro->key);
1147 else
1148 xasprintf(&rp->reason, "option changed: %s",
1149 ro->key);
1150 assert(rp->reason != NULL);
1151 return (true);
1152 }
1153 if (ret1 == EPKG_OK) {
1154 if (strcmp(lo->key, ro->key) != 0 ||
1155 strcmp(lo->value, ro->value) != 0) {
1156 free(rp->reason);
1157 xasprintf(&rp->reason, "options changed");
1158 return (true);
1159 }
1160 }
1161 else
1162 break;
1163 }
1164
1165 /* What about the direct deps */
1166 for (;;) {
1167 ret1 = pkg_deps(rp, &rd);
1168 ret2 = pkg_deps(lp, &ld);
1169 if (ret1 != ret2) {
1170 free(rp->reason);
1171 if (rd == NULL)
1172 xasprintf(&rp->reason, "direct dependency removed: %s",
1173 ld->name);
1174 else if (ld == NULL)
1175 xasprintf(&rp->reason, "direct dependency added: %s",
1176 rd->name);
1177 else
1178 xasprintf(&rp->reason, "direct dependency changed: %s",
1179 rd->name);
1180 assert (rp->reason != NULL);
1181 return (true);
1182 }
1183 if (ret1 == EPKG_OK) {
1184 if ((strcmp(rd->name, ld->name) != 0) ||
1185 (strcmp(rd->origin, ld->origin) != 0)) {
1186 free(rp->reason);
1187 xasprintf(&rp->reason, "direct dependency changed: %s",
1188 rd->name);
1189 assert (rp->reason != NULL);
1190 return (true);
1191 }
1192 }
1193 else
1194 break;
1195 }
1196
1197 /* Conflicts */
1198 for (;;) {
1199 ret1 = pkg_conflicts(rp, &rc);
1200 ret2 = pkg_conflicts(lp, &lc);
1201 if (ret1 != ret2) {
1202 free(rp->reason);
1203 rp->reason = xstrdup("direct conflict changed");
1204 return (true);
1205 }
1206 if (ret1 == EPKG_OK) {
1207 if (strcmp(rc->uid, lc->uid) != 0) {
1208 free(rp->reason);
1209 rp->reason = xstrdup("direct conflict changed");
1210 return (true);
1211 }
1212 }
1213 else
1214 break;
1215 }
1216
1217 /* Provides */
1218 lb = rb = NULL;
1219 for (;;) {
1220 ret1 = pkg_provides(rp, &rb);
1221 ret2 = pkg_provides(lp, &lb);
1222 if (ret1 != ret2) {
1223 free(rp->reason);
1224 rp->reason = xstrdup("provides changed");
1225 return (true);
1226 }
1227 if (ret1 == EPKG_OK) {
1228 if (strcmp(rb, lb) != 0) {
1229 free(rp->reason);
1230 rp->reason = xstrdup("provides changed");
1231 return (true);
1232 }
1233 }
1234 else
1235 break;
1236 }
1237 /* Requires */
1238 lb = rb = NULL;
1239 for (;;) {
1240 ret1 = pkg_requires(rp, &rb);
1241 ret2 = pkg_requires(lp, &lb);
1242 if (ret1 != ret2) {
1243 free(rp->reason);
1244 rp->reason = xstrdup("requires changed");
1245 return (true);
1246 }
1247 if (ret1 == EPKG_OK) {
1248 if (strcmp(rb, lb) != 0) {
1249 free(rp->reason);
1250 rp->reason = xstrdup("requires changed");
1251 return (true);
1252 }
1253 }
1254 else
1255 break;
1256 }
1257
1258 /* Finish by the shlibs */
1259 lb = rb = NULL;
1260 for (;;) {
1261 ret1 = pkg_shlibs_provided(rp, &rb);
1262 ret2 = pkg_shlibs_provided(lp, &lb);
1263 if (ret1 != ret2) {
1264 free(rp->reason);
1265 rp->reason = xstrdup("provided shared library changed");
1266 return (true);
1267 }
1268 if (ret1 == EPKG_OK) {
1269 if (strcmp(rb, lb) != 0) {
1270 free(rp->reason);
1271 rp->reason = xstrdup("provided shared library changed");
1272 pkg_debug(1, "provided shlib changed %s -> %s",
1273 lb, rb);
1274 return (true);
1275 }
1276 }
1277 else
1278 break;
1279 }
1280
1281 lb = rb = NULL;
1282 for (;;) {
1283 ret1 = pkg_shlibs_required(rp, &rb);
1284 ret2 = pkg_shlibs_required(lp, &lb);
1285 if (ret1 != ret2) {
1286 free(rp->reason);
1287 rp->reason = xstrdup("needed shared library changed");
1288 return (true);
1289 }
1290 if (ret1 == EPKG_OK) {
1291 if (strcmp(rb, lb) != 0) {
1292 free(rp->reason);
1293 rp->reason = xstrdup("needed shared library changed");
1294 pkg_debug(1, "Required shlib changed %s -> %s",
1295 lb, rb);
1296 return (true);
1297 }
1298 }
1299 else
1300 break;
1301 }
1302
1303 return (false);
1304 }
1305
1306 static void
pkg_jobs_propagate_automatic(struct pkg_jobs * j)1307 pkg_jobs_propagate_automatic(struct pkg_jobs *j)
1308 {
1309 struct pkg_job_universe_item *unit, *utmp, *cur, *local;
1310 struct pkg_job_request *req;
1311 bool automatic;
1312
1313 HASH_ITER(hh, j->universe->items, unit, utmp) {
1314 if (unit->next == NULL) {
1315 /*
1316 * For packages that are alone in the installation list
1317 * we search them in the corresponding request
1318 */
1319 HASH_FIND_STR(j->request_add, unit->pkg->uid, req);
1320 if ((req == NULL || req->automatic) &&
1321 unit->pkg->type != PKG_INSTALLED) {
1322 automatic = true;
1323 pkg_debug(2, "set automatic flag for %s", unit->pkg->uid);
1324 unit->pkg->automatic = automatic;
1325 }
1326 else {
1327 if (j->type == PKG_JOBS_INSTALL) {
1328 unit->pkg->automatic = false;
1329 }
1330 }
1331 }
1332 else {
1333 /*
1334 * For packages that are in the conflict chain we need to inherit
1335 * automatic flag from the local package
1336 */
1337 local = NULL;
1338 automatic = false;
1339 LL_FOREACH(unit, cur) {
1340 if (cur->pkg->type == PKG_INSTALLED) {
1341 local = cur;
1342 automatic = local->pkg->automatic;
1343 break;
1344 }
1345 }
1346 if (local != NULL) {
1347 LL_FOREACH(unit, cur) {
1348 /*
1349 * Propagate automatic from local package
1350 */
1351 if (cur->pkg->type != PKG_INSTALLED) {
1352 cur->pkg->automatic = automatic;
1353 }
1354 }
1355 }
1356 else {
1357 /*
1358 * For packages that are not unique, we might still have
1359 * a situation when we need to set automatic for all
1360 * non-local packages
1361 *
1362 * See #1374
1363 */
1364 HASH_FIND_STR(j->request_add, unit->pkg->uid, req);
1365 if ((req == NULL || req->automatic)) {
1366 automatic = true;
1367 pkg_debug(2, "set automatic flag for %s", unit->pkg->uid);
1368 LL_FOREACH(unit, cur) {
1369 cur->pkg->automatic = automatic;
1370 }
1371 }
1372 }
1373 }
1374 }
1375 }
1376
1377 static struct pkg_job_request *
pkg_jobs_find_deinstall_request(struct pkg_job_universe_item * item,struct pkg_jobs * j,int rec_level)1378 pkg_jobs_find_deinstall_request(struct pkg_job_universe_item *item,
1379 struct pkg_jobs *j, int rec_level)
1380 {
1381 struct pkg_job_request *found;
1382 struct pkg_job_universe_item *dep_item;
1383 struct pkg_dep *d = NULL;
1384 struct pkg *pkg = item->pkg;
1385
1386 if (rec_level > 128) {
1387 pkg_debug(2, "cannot find deinstall request after 128 iterations for %s,"
1388 "circular dependency maybe", pkg->uid);
1389 return (NULL);
1390 }
1391
1392 HASH_FIND_STR(j->request_delete, pkg->uid, found);
1393 if (found == NULL) {
1394 while (pkg_deps(pkg, &d) == EPKG_OK) {
1395 dep_item = pkg_jobs_universe_find(j->universe, d->uid);
1396 if (dep_item) {
1397 found = pkg_jobs_find_deinstall_request(dep_item, j, rec_level + 1);
1398 if (found)
1399 return (found);
1400 }
1401 }
1402 }
1403 else {
1404 return (found);
1405 }
1406
1407 return (NULL);
1408 }
1409
1410 static void
pkg_jobs_set_deinstall_reasons(struct pkg_jobs * j)1411 pkg_jobs_set_deinstall_reasons(struct pkg_jobs *j)
1412 {
1413 struct pkg_solved *sit;
1414 struct pkg_job_request *jreq;
1415 struct pkg *req_pkg, *pkg;
1416
1417 LL_FOREACH(j->jobs, sit) {
1418 jreq = pkg_jobs_find_deinstall_request(sit->items[0], j, 0);
1419 if (jreq != NULL && jreq->item->unit != sit->items[0]) {
1420 req_pkg = jreq->item->pkg;
1421 pkg = sit->items[0]->pkg;
1422 /* Set the reason */
1423 free(pkg->reason);
1424 pkg_asprintf(&pkg->reason, "depends on %n-%v", req_pkg, req_pkg);
1425 }
1426 }
1427 }
1428
1429 static int
comp(const void * a,const void * b)1430 comp(const void *a, const void *b)
1431 {
1432 const struct pkg *pa = a;
1433 const struct pkg *pb = b;
1434
1435 return strcmp(pa->name, pb->name);
1436 }
1437
1438 static int
jobs_solve_deinstall(struct pkg_jobs * j)1439 jobs_solve_deinstall(struct pkg_jobs *j)
1440 {
1441 struct job_pattern *jp;
1442 struct pkg *pkg = NULL;
1443 struct pkgdb_it *it;
1444 LL_FOREACH(j->patterns, jp) {
1445 if ((it = pkgdb_query(j->db, jp->pattern, jp->match)) == NULL)
1446 return (EPKG_FATAL);
1447
1448 if (pkgdb_it_count(it) == 0) {
1449 pkg_emit_notice("No packages matched for pattern '%s'\n", jp->pattern);
1450 }
1451
1452 while (pkgdb_it_next(it, &pkg,
1453 PKG_LOAD_BASIC|PKG_LOAD_RDEPS|PKG_LOAD_DEPS|PKG_LOAD_ANNOTATIONS) == EPKG_OK) {
1454 if(pkg->locked) {
1455 if (tsearch(pkg, &j->lockedpkgs, comp) == NULL) {
1456 return (EPKG_FATAL);
1457 }
1458 }
1459 else {
1460 pkg_jobs_add_req(j, pkg);
1461 }
1462 pkg = NULL;
1463 }
1464 pkgdb_it_free(it);
1465 }
1466
1467 j->solved = 1;
1468
1469 return (pkg_jobs_process_delete_request(j));
1470 }
1471
1472 static int
jobs_solve_autoremove(struct pkg_jobs * j)1473 jobs_solve_autoremove(struct pkg_jobs *j)
1474 {
1475 struct pkg *pkg = NULL;
1476 struct pkgdb_it *it;
1477
1478 if ((it = pkgdb_query_cond(j->db, " WHERE automatic=1 AND vital=0 ", NULL, MATCH_ALL)) == NULL)
1479 return (EPKG_FATAL);
1480
1481 while (pkgdb_it_next(it, &pkg,
1482 PKG_LOAD_BASIC|PKG_LOAD_RDEPS|PKG_LOAD_DEPS|PKG_LOAD_ANNOTATIONS)
1483 == EPKG_OK) {
1484 if(pkg->locked) {
1485 pkg_emit_locked(pkg);
1486 }
1487 else if (pkg_jobs_test_automatic(j, pkg)) {
1488 assert(pkg_jobs_add_req(j, pkg));
1489 }
1490
1491 pkg = NULL;
1492 }
1493 pkgdb_it_free(it);
1494
1495 j->solved = true;
1496 pkg_jobs_process_delete_request(j);
1497
1498 return (EPKG_OK);
1499 }
1500
1501 struct pkg_jobs_install_candidate {
1502 int64_t id;
1503 struct pkg_jobs_install_candidate *next;
1504 };
1505
1506 static struct pkg_jobs_install_candidate *
pkg_jobs_new_candidate(struct pkg * pkg)1507 pkg_jobs_new_candidate(struct pkg *pkg)
1508 {
1509 struct pkg_jobs_install_candidate *n;
1510
1511 n = xmalloc(sizeof(*n));
1512 n->id = pkg->id;
1513 return (n);
1514 }
1515
1516 static bool
pkg_jobs_check_remote_candidate(struct pkg_jobs * j,struct pkg * pkg)1517 pkg_jobs_check_remote_candidate(struct pkg_jobs *j, struct pkg *pkg)
1518 {
1519 struct pkgdb_it *it;
1520 struct pkg *p = NULL;
1521
1522 /* If we have no digest, we need to check this package */
1523 if (pkg->digest == NULL)
1524 return (true);
1525
1526 it = pkgdb_repo_query(j->db, pkg->uid, MATCH_EXACT, j->reponame);
1527 if (it != NULL) {
1528 /*
1529 * If we have the same package in a remote repo, it is not an
1530 * installation candidate
1531 */
1532 int npkg = 0;
1533
1534 while (pkgdb_it_next(it, &p, PKG_LOAD_BASIC) == EPKG_OK) {
1535 /*
1536 * Check package with the same uid and explore whether digest
1537 * has been changed
1538 */
1539 if (strcmp(p->digest, pkg->digest) != 0)
1540 npkg ++;
1541
1542 pkg_free(p);
1543 p = NULL;
1544 }
1545
1546 pkgdb_it_free(it);
1547
1548 if (npkg == 0)
1549 return (false);
1550 }
1551
1552 return (true);
1553 }
1554
1555 static struct pkg_jobs_install_candidate *
pkg_jobs_find_install_candidates(struct pkg_jobs * j,size_t * count)1556 pkg_jobs_find_install_candidates(struct pkg_jobs *j, size_t *count)
1557 {
1558 struct pkg *pkg = NULL;
1559 struct pkgdb_it *it;
1560 struct pkg_jobs_install_candidate *candidates = NULL, *c;
1561
1562 if ((it = pkgdb_query(j->db, NULL, MATCH_ALL)) == NULL)
1563 return (NULL);
1564
1565 while (pkgdb_it_next(it, &pkg, PKG_LOAD_BASIC) == EPKG_OK) {
1566 if ((j->flags & PKG_FLAG_FORCE) ||
1567 pkg_jobs_check_remote_candidate(j, pkg)) {
1568 c = pkg_jobs_new_candidate(pkg);
1569 LL_PREPEND(candidates, c);
1570 (*count)++;
1571 }
1572 pkg_free(pkg);
1573 pkg = NULL;
1574 }
1575 pkgdb_it_free(it);
1576
1577 return (candidates);
1578 }
1579
1580 static int
jobs_solve_full_upgrade(struct pkg_jobs * j)1581 jobs_solve_full_upgrade(struct pkg_jobs *j)
1582 {
1583 struct pkg *pkg = NULL;
1584 size_t jcount = 0;
1585 size_t elt_num = 0;
1586 char sqlbuf[256];
1587 struct pkg_jobs_install_candidate *candidates, *c;
1588 struct pkg_job_request *req, *rtmp;
1589 struct pkgdb_it *it;
1590 unsigned flags = PKG_LOAD_BASIC|PKG_LOAD_OPTIONS|PKG_LOAD_DEPS|PKG_LOAD_REQUIRES|
1591 PKG_LOAD_SHLIBS_REQUIRED|PKG_LOAD_ANNOTATIONS|PKG_LOAD_CONFLICTS;
1592
1593 candidates = pkg_jobs_find_install_candidates(j, &jcount);
1594
1595 pkg_emit_progress_start("Checking for upgrades (%zd candidates)",
1596 jcount);
1597
1598 LL_FOREACH(candidates, c) {
1599 pkg_emit_progress_tick(++elt_num, jcount);
1600 sqlite3_snprintf(sizeof(sqlbuf), sqlbuf, " WHERE id=%" PRId64,
1601 c->id);
1602 if ((it = pkgdb_query_cond(j->db, sqlbuf, NULL, MATCH_ALL)) == NULL)
1603 return (EPKG_FATAL);
1604
1605 pkg = NULL;
1606 while (pkgdb_it_next(it, &pkg, flags) == EPKG_OK) {
1607 /* Do not test we ignore what doesn't exists remotely */
1608 pkg_jobs_find_upgrade(j, pkg->uid, MATCH_EXACT);
1609 }
1610 pkg_free(pkg);
1611 pkgdb_it_free(it);
1612 }
1613 pkg_emit_progress_tick(jcount, jcount);
1614 LL_FREE(candidates, free);
1615
1616 pkg_emit_progress_start("Processing candidates (%zd candidates)",
1617 jcount);
1618 elt_num = 0;
1619
1620 HASH_ITER(hh, j->request_add, req, rtmp) {
1621 pkg_emit_progress_tick(++elt_num, jcount);
1622 pkg_jobs_universe_process(j->universe, req->item->pkg);
1623 }
1624 pkg_emit_progress_tick(jcount, jcount);
1625
1626 pkg_jobs_universe_process_upgrade_chains(j);
1627
1628 return (EPKG_OK);
1629 }
1630
1631 static int
jobs_solve_partial_upgrade(struct pkg_jobs * j)1632 jobs_solve_partial_upgrade(struct pkg_jobs *j)
1633 {
1634 struct job_pattern *jp;
1635 struct pkg_job_request *req, *rtmp;
1636 bool error_found = false;
1637 int retcode;
1638
1639 LL_FOREACH(j->patterns, jp) {
1640 retcode = pkg_jobs_find_remote_pattern(j, jp);
1641 if (retcode == EPKG_FATAL) {
1642 pkg_emit_error("No packages available to %s matching '%s' "
1643 "have been found in the "
1644 "repositories",
1645 (j->type == PKG_JOBS_UPGRADE) ? "upgrade" : "install",
1646 jp->pattern);
1647 /* delay the return to be sure we print a message for all issues */
1648 if ((j->flags & PKG_FLAG_UPGRADE_VULNERABLE) == 0)
1649 error_found = true;
1650 }
1651 if (retcode == EPKG_LOCKED) {
1652 return (retcode);
1653 }
1654 }
1655 if (error_found)
1656 return (EPKG_FATAL);
1657 /*
1658 * Here we have not selected the proper candidate among all
1659 * possible choices.
1660 * Hence, we want to perform this procedure now to ensure that
1661 * we are processing the correct packages.
1662 */
1663 pkg_jobs_universe_process_upgrade_chains(j);
1664 /*
1665 * Need to iterate request one more time to recurse depends
1666 */
1667 HASH_ITER(hh, j->request_add, req, rtmp) {
1668 pkg_jobs_universe_process(j->universe, req->item->pkg);
1669 }
1670 return (EPKG_OK);
1671 }
1672
1673 static int
jobs_solve_install_upgrade(struct pkg_jobs * j)1674 jobs_solve_install_upgrade(struct pkg_jobs *j)
1675 {
1676 struct pkg_job_request *req, *rtmp;
1677 int retcode = 0;
1678
1679 /* Check for new pkg. Skip for 'upgrade -F'. */
1680 if (((j->flags & PKG_FLAG_SKIP_INSTALL) == 0 &&
1681 (j->flags & PKG_FLAG_DRY_RUN) == 0) &&
1682 (j->flags & PKG_FLAG_PKG_VERSION_TEST) == PKG_FLAG_PKG_VERSION_TEST)
1683 if (new_pkg_version(j)) {
1684 j->flags &= ~PKG_FLAG_PKG_VERSION_TEST;
1685 j->conservative = false;
1686 j->pinning = false;
1687 pkg_emit_newpkgversion();
1688 goto order;
1689 }
1690
1691 if (j->patterns == NULL && j->type == PKG_JOBS_INSTALL) {
1692 pkg_emit_error("no patterns are specified for install job");
1693 return (EPKG_FATAL);
1694 }
1695
1696 if (j->solved == 0) {
1697 if (j->patterns == NULL) {
1698 retcode = jobs_solve_full_upgrade(j);
1699 if (retcode != EPKG_OK)
1700 return (retcode);
1701 } else {
1702 retcode = jobs_solve_partial_upgrade(j);
1703 if (retcode != EPKG_OK)
1704 return (retcode);
1705 }
1706 }
1707 else {
1708 /*
1709 * If we have tried to solve request, then we just want to re-add all
1710 * request packages to the universe to find out any potential conflicts
1711 */
1712 HASH_ITER(hh, j->request_add, req, rtmp) {
1713 pkg_jobs_universe_process(j->universe, req->item->pkg);
1714 }
1715 }
1716
1717 #if 0
1718 /* XXX: check if we can safely remove this function */
1719 pkg_jobs_process_add_request(j);
1720 #endif
1721 if (pkg_conflicts_request_resolve(j) != EPKG_OK) {
1722 pkg_emit_error("Cannot resolve conflicts in a request");
1723 return (EPKG_FATAL);
1724 }
1725
1726 pkg_jobs_propagate_automatic(j);
1727
1728 order:
1729
1730 j->solved ++;
1731
1732 return (EPKG_OK);
1733 }
1734
1735 static int
jobs_solve_fetch(struct pkg_jobs * j)1736 jobs_solve_fetch(struct pkg_jobs *j)
1737 {
1738 struct job_pattern *jp;
1739 struct pkg *pkg = NULL;
1740 struct pkgdb_it *it;
1741 struct pkg_job_request *req, *rtmp;
1742
1743 if ((j->flags & PKG_FLAG_UPGRADES_FOR_INSTALLED) == PKG_FLAG_UPGRADES_FOR_INSTALLED) {
1744 if ((it = pkgdb_query(j->db, NULL, MATCH_ALL)) == NULL)
1745 return (EPKG_FATAL);
1746
1747 while (pkgdb_it_next(it, &pkg, PKG_LOAD_BASIC) == EPKG_OK) {
1748 if(pkg->locked) {
1749 pkg_emit_locked(pkg);
1750 }
1751 else {
1752 /* Do not test we ignore what doesn't exists remotely */
1753 pkg_jobs_find_upgrade(j, pkg->uid, MATCH_EXACT);
1754 }
1755 pkg = NULL;
1756 }
1757 pkgdb_it_free(it);
1758 } else {
1759 LL_FOREACH(j->patterns, jp) {
1760 /* TODO: use repository priority here */
1761 if (pkg_jobs_find_upgrade(j, jp->pattern, jp->match) == EPKG_FATAL)
1762 pkg_emit_error("No packages matching '%s' have been found in the "
1763 "repositories", jp->pattern);
1764 }
1765 HASH_ITER(hh, j->request_add, req, rtmp)
1766 pkg_jobs_universe_process(j->universe, req->item->pkg);
1767 }
1768
1769 j->solved ++;
1770
1771 return (EPKG_OK);
1772 }
1773
1774 static void
pkg_jobs_apply_replacements(struct pkg_jobs * j)1775 pkg_jobs_apply_replacements(struct pkg_jobs *j)
1776 {
1777 struct pkg_job_replace *r;
1778 static const char sql[] = ""
1779 "UPDATE packages SET name=?1 "
1780 " WHERE name=?2;" ;
1781 sqlite3_stmt *stmt;
1782 int ret;
1783
1784 pkg_debug(4, "jobs: running '%s'", sql);
1785 ret = sqlite3_prepare_v2(j->db->sqlite, sql, -1, &stmt, NULL);
1786 if (ret != SQLITE_OK) {
1787 ERROR_SQLITE(j->db->sqlite, sql);
1788 return;
1789 }
1790
1791 LL_FOREACH(j->universe->uid_replaces, r) {
1792 pkg_debug(4, "changing uid %s -> %s", r->old_uid, r->new_uid);
1793 sqlite3_bind_text(stmt, 1, r->new_uid, -1, SQLITE_TRANSIENT);
1794 sqlite3_bind_text(stmt, 2, r->old_uid, -1, SQLITE_TRANSIENT);
1795
1796 if (sqlite3_step(stmt) != SQLITE_DONE)
1797 ERROR_STMT_SQLITE(j->db->sqlite, stmt);
1798
1799 sqlite3_reset(stmt);
1800 }
1801
1802 sqlite3_finalize(stmt);
1803 }
1804
1805 static int
solve_with_external_cudf_solver(struct pkg_jobs * j,const char * solver)1806 solve_with_external_cudf_solver(struct pkg_jobs *j, const char *solver)
1807 {
1808 int ret, pstatus;
1809 FILE *spipe[2];
1810 pid_t pchild;
1811
1812 pchild = process_spawn_pipe(spipe, solver);
1813 if (pchild == -1)
1814 return (EPKG_FATAL);
1815
1816 ret = pkg_jobs_cudf_emit_file(j, j->type, spipe[1]);
1817 fclose(spipe[1]);
1818
1819 if (ret == EPKG_OK)
1820 ret = pkg_jobs_cudf_parse_output(j, spipe[0]);
1821
1822 fclose(spipe[0]);
1823 waitpid(pchild, &pstatus, WNOHANG);
1824
1825 return (ret);
1826 }
1827
1828 static int
solve_with_external_sat_solver(struct pkg_solve_problem * pb,const char * solver)1829 solve_with_external_sat_solver(struct pkg_solve_problem *pb, const char *solver)
1830 {
1831 int ret, pstatus;
1832 FILE *spipe[2];
1833 pid_t pchild;
1834
1835 pchild = process_spawn_pipe(spipe, solver);
1836 if (pchild == -1)
1837 return (EPKG_FATAL);
1838
1839 ret = pkg_solve_dimacs_export(pb, spipe[1]);
1840 fclose(spipe[1]);
1841
1842 if (ret == EPKG_OK)
1843 ret = pkg_solve_parse_sat_output(spipe[0], pb);
1844
1845 fclose(spipe[0]);
1846 waitpid(pchild, &pstatus, WNOHANG);
1847
1848 return (ret);
1849 }
1850
1851 static int
solve_with_sat_solver(struct pkg_jobs * j)1852 solve_with_sat_solver(struct pkg_jobs *j)
1853 {
1854 const char *sat_solver = pkg_object_string(pkg_config_get("SAT_SOLVER"));
1855 struct pkg_solve_problem *problem;
1856 const char *dotfile;
1857 FILE *dot = NULL;
1858 int ret;
1859
1860 pkg_jobs_universe_process_upgrade_chains(j);
1861 problem = pkg_solve_jobs_to_sat(j);
1862 if (problem == NULL) {
1863 pkg_emit_error("cannot convert job to SAT problem");
1864 j->solved = 0;
1865 return (EPKG_FATAL);
1866 }
1867
1868 if (sat_solver != NULL)
1869 return (solve_with_external_sat_solver(problem, sat_solver));
1870
1871 if ((dotfile = pkg_object_string(pkg_config_get("DOT_FILE")))
1872 != NULL) {
1873 dot = fopen(dotfile, "we");
1874
1875 if (dot == NULL) {
1876 pkg_emit_errno("fopen", dotfile);
1877 }
1878 }
1879
1880 ret = pkg_solve_sat_problem(problem);
1881 if (ret == EPKG_AGAIN) {
1882 pkg_solve_problem_free(problem);
1883 return (solve_with_sat_solver(j));
1884 }
1885
1886 if (ret == EPKG_FATAL) {
1887 pkg_emit_error("cannot solve job using SAT solver");
1888 pkg_solve_problem_free(problem);
1889 j->solved = 0;
1890 } else {
1891 ret = pkg_solve_sat_to_jobs(problem);
1892 }
1893
1894 if ((dotfile = pkg_object_string(pkg_config_get("DOT_FILE")))
1895 != NULL) {
1896 dot = fopen(dotfile, "we");
1897
1898 if (dot == NULL) {
1899 pkg_emit_errno("fopen", dotfile);
1900 } else {
1901 pkg_solve_dot_export(problem, dot);
1902 fclose(dot);
1903 }
1904 }
1905 pkg_solve_problem_free(problem);
1906
1907 return (ret);
1908 }
1909
1910 int
pkg_jobs_solve(struct pkg_jobs * j)1911 pkg_jobs_solve(struct pkg_jobs *j)
1912 {
1913 int ret;
1914 struct pkg_solved *job;
1915 const char *cudf_solver;
1916
1917 pkgdb_begin_solver(j->db);
1918
1919 switch (j->type) {
1920 case PKG_JOBS_AUTOREMOVE:
1921 ret = jobs_solve_autoremove(j);
1922 break;
1923 case PKG_JOBS_DEINSTALL:
1924 ret = jobs_solve_deinstall(j);
1925 break;
1926 case PKG_JOBS_UPGRADE:
1927 case PKG_JOBS_INSTALL:
1928 ret = jobs_solve_install_upgrade(j);
1929 break;
1930 case PKG_JOBS_FETCH:
1931 ret = jobs_solve_fetch(j);
1932 break;
1933 default:
1934 pkgdb_end_solver(j->db);
1935 return (EPKG_FATAL);
1936 }
1937
1938 cudf_solver = pkg_object_string(pkg_config_get("CUDF_SOLVER"));
1939
1940 if (ret == EPKG_OK) {
1941 if (cudf_solver != NULL) {
1942 ret = solve_with_external_cudf_solver(j, cudf_solver);
1943 } else {
1944 ret = solve_with_sat_solver(j);
1945 }
1946 }
1947
1948 if (j->type == PKG_JOBS_DEINSTALL && j->solved)
1949 pkg_jobs_set_deinstall_reasons(j);
1950
1951 pkgdb_end_solver(j->db);
1952
1953 if (ret != EPKG_OK)
1954 return (ret);
1955
1956 pkg_jobs_apply_replacements(j);
1957
1958 /* Check if we need to fetch and re-run the solver */
1959 DL_FOREACH(j->jobs, job) {
1960 struct pkg *p;
1961
1962 p = job->items[0]->pkg;
1963 if (p->type != PKG_REMOTE)
1964 continue;
1965
1966 if (pkgdb_ensure_loaded(j->db, p, PKG_LOAD_FILES|PKG_LOAD_DIRS)
1967 == EPKG_FATAL) {
1968 j->need_fetch = true;
1969 break;
1970 }
1971 }
1972
1973 if (j->solved == 1 && !j->need_fetch && j->type != PKG_JOBS_FETCH) {
1974 int rc;
1975 bool has_conflicts = false;
1976 do {
1977 j->conflicts_registered = 0;
1978 rc = pkg_jobs_check_conflicts(j);
1979 if (rc == EPKG_CONFLICT) {
1980 /* Cleanup results */
1981 LL_FREE(j->jobs, free);
1982 j->jobs = NULL;
1983 j->count = 0;
1984 has_conflicts = true;
1985 pkg_jobs_solve(j);
1986 }
1987 else if (rc == EPKG_OK && !has_conflicts) {
1988 break;
1989 }
1990 } while (j->conflicts_registered > 0);
1991 }
1992
1993 return (ret);
1994 }
1995
1996 int
pkg_jobs_count(struct pkg_jobs * j)1997 pkg_jobs_count(struct pkg_jobs *j)
1998 {
1999 assert(j != NULL);
2000
2001 return (j->count);
2002 }
2003
2004 int
pkg_jobs_total(struct pkg_jobs * j)2005 pkg_jobs_total(struct pkg_jobs *j)
2006 {
2007 assert(j != NULL);
2008
2009 return (j->total);
2010 }
2011
2012 pkg_jobs_t
pkg_jobs_type(struct pkg_jobs * j)2013 pkg_jobs_type(struct pkg_jobs *j)
2014 {
2015 assert(j != NULL);
2016
2017 return (j->type);
2018 }
2019
2020 static int
pkg_jobs_handle_install(struct pkg_solved * ps,struct pkg_jobs * j,struct pkg_manifest_key * keys)2021 pkg_jobs_handle_install(struct pkg_solved *ps, struct pkg_jobs *j,
2022 struct pkg_manifest_key *keys)
2023 {
2024 struct pkg *new, *old;
2025 struct pkg_job_request *req;
2026 char path[MAXPATHLEN], *target;
2027 int flags = 0;
2028 int retcode = EPKG_FATAL;
2029
2030 old = ps->items[1] ? ps->items[1]->pkg : NULL;
2031 new = ps->items[0]->pkg;
2032
2033 HASH_FIND_STR(j->request_add, new->uid, req);
2034 if (req != NULL && req->item->jp != NULL &&
2035 (req->item->jp->flags & PKG_PATTERN_FLAG_FILE)) {
2036 /*
2037 * We have package as a file, set special repository name
2038 */
2039 target = req->item->jp->path;
2040 free(new->reponame);
2041 new->reponame = xstrdup("local file");
2042 }
2043 else {
2044 pkg_snprintf(path, sizeof(path), "%R", new);
2045 if (*path != '/')
2046 pkg_repo_cached_name(new, path, sizeof(path));
2047 target = path;
2048 }
2049
2050 if (old != NULL)
2051 new->old_version = xstrdup(old->version);
2052
2053 if ((j->flags & PKG_FLAG_FORCE) == PKG_FLAG_FORCE)
2054 flags |= PKG_ADD_FORCE;
2055 if ((j->flags & PKG_FLAG_NOSCRIPT) == PKG_FLAG_NOSCRIPT)
2056 flags |= PKG_ADD_NOSCRIPT;
2057 if ((j->flags & PKG_FLAG_FORCE_MISSING) == PKG_FLAG_FORCE_MISSING)
2058 flags |= PKG_ADD_FORCE_MISSING;
2059 flags |= PKG_ADD_UPGRADE;
2060 if (ps->type == PKG_SOLVED_UPGRADE_INSTALL)
2061 flags |= PKG_ADD_SPLITTED_UPGRADE;
2062 if (new->automatic || (j->flags & PKG_FLAG_AUTOMATIC) == PKG_FLAG_AUTOMATIC)
2063 flags |= PKG_ADD_AUTOMATIC;
2064
2065 if (old != NULL)
2066 retcode = pkg_add_upgrade(j->db, target, flags, keys, NULL, new, old);
2067 else
2068 retcode = pkg_add_from_remote(j->db, target, flags, keys, NULL, new);
2069
2070 return (retcode);
2071 }
2072
2073 static int
pkg_jobs_execute(struct pkg_jobs * j)2074 pkg_jobs_execute(struct pkg_jobs *j)
2075 {
2076 struct pkg *p = NULL;
2077 struct pkg_solved *ps;
2078 struct pkg_manifest_key *keys = NULL;
2079 int flags = 0;
2080 int retcode = EPKG_FATAL;
2081 pkg_plugin_hook_t pre, post;
2082 struct trigger *cleanup_triggers;
2083
2084 cleanup_triggers = triggers_load(true);
2085 if (j->type == PKG_JOBS_INSTALL) {
2086 pre = PKG_PLUGIN_HOOK_PRE_INSTALL;
2087 post = PKG_PLUGIN_HOOK_POST_INSTALL;
2088 }
2089 else if (j->type == PKG_JOBS_UPGRADE) {
2090 pre = PKG_PLUGIN_HOOK_PRE_UPGRADE;
2091 post = PKG_PLUGIN_HOOK_POST_UPGRADE;
2092 }
2093 else if (j->type == PKG_JOBS_AUTOREMOVE){
2094 pre = PKG_PLUGIN_HOOK_PRE_AUTOREMOVE;
2095 post = PKG_PLUGIN_HOOK_POST_AUTOREMOVE;
2096 }
2097 else {
2098 pre = PKG_PLUGIN_HOOK_PRE_DEINSTALL;
2099 post = PKG_PLUGIN_HOOK_POST_DEINSTALL;
2100 }
2101
2102 if (j->flags & PKG_FLAG_SKIP_INSTALL)
2103 return (EPKG_OK);
2104
2105 if ((j->flags & PKG_FLAG_FORCE) == PKG_FLAG_FORCE)
2106 flags |= PKG_DELETE_FORCE;
2107
2108 if ((j->flags & PKG_FLAG_NOSCRIPT) == PKG_FLAG_NOSCRIPT)
2109 flags |= PKG_DELETE_NOSCRIPT;
2110
2111 retcode = pkgdb_upgrade_lock(j->db, PKGDB_LOCK_ADVISORY,
2112 PKGDB_LOCK_EXCLUSIVE);
2113 if (retcode != EPKG_OK)
2114 return (retcode);
2115
2116 pkg_plugins_hook_run(pre, j, j->db);
2117
2118 p = NULL;
2119 pkg_manifest_keys_new(&keys);
2120
2121 pkg_jobs_set_priorities(j);
2122
2123 DL_FOREACH(j->jobs, ps) {
2124 switch (ps->type) {
2125 case PKG_SOLVED_DELETE:
2126 case PKG_SOLVED_UPGRADE_REMOVE:
2127 p = ps->items[0]->pkg;
2128 if (ps->type == PKG_SOLVED_DELETE && p->vital && ((flags & PKG_DELETE_FORCE) == 0)) {
2129 pkg_emit_error("Cannot delete vital package: %s!", p->name);
2130 pkg_emit_error("If you are sure you want to remove %s, ", p->name);
2131 pkg_emit_error("unset the 'vital' flag with: pkg set -v 0 %s", p->name);
2132 retcode = EPKG_FATAL;
2133 goto cleanup;
2134 }
2135 if (ps->type == PKG_SOLVED_DELETE &&
2136 (strcmp(p->name, "pkg") == 0 ||
2137 strcmp(p->name, "pkg-devel") == 0) &&
2138 (flags & PKG_DELETE_FORCE) == 0) {
2139 if (j->patterns->match == MATCH_ALL) {
2140 continue;
2141 } else {
2142 pkg_emit_error("Cannot delete pkg itself without force flag");
2143 retcode = EPKG_FATAL;
2144 goto cleanup;
2145 }
2146 }
2147 /*
2148 * Assume that in upgrade we can remove packages with rdeps as
2149 * in further they will be upgraded correctly.
2150 */
2151 if (j->type == PKG_JOBS_UPGRADE)
2152 retcode = pkg_delete(p, j->db, flags | PKG_DELETE_CONFLICT);
2153 else
2154 retcode = pkg_delete(p, j->db, flags);
2155 if (retcode != EPKG_OK)
2156 goto cleanup;
2157 break;
2158 case PKG_SOLVED_INSTALL:
2159 case PKG_SOLVED_UPGRADE_INSTALL:
2160 retcode = pkg_jobs_handle_install(ps, j, keys);
2161 if (retcode != EPKG_OK)
2162 goto cleanup;
2163 break;
2164 case PKG_SOLVED_UPGRADE:
2165 retcode = pkg_jobs_handle_install(ps, j, keys);
2166 if (retcode != EPKG_OK)
2167 goto cleanup;
2168 break;
2169 case PKG_SOLVED_FETCH:
2170 retcode = EPKG_FATAL;
2171 pkg_emit_error("internal error: bad job type");
2172 goto cleanup;
2173 break;
2174 }
2175
2176 }
2177
2178 pkg_plugins_hook_run(post, j, j->db);
2179 triggers_execute(cleanup_triggers);
2180
2181 cleanup:
2182 pkgdb_release_lock(j->db, PKGDB_LOCK_EXCLUSIVE);
2183 pkg_manifest_keys_free(keys);
2184
2185 return (retcode);
2186 }
2187
2188 int
pkg_jobs_apply(struct pkg_jobs * j)2189 pkg_jobs_apply(struct pkg_jobs *j)
2190 {
2191 int rc;
2192 bool has_conflicts = false;
2193
2194 if (!j->solved) {
2195 pkg_emit_error("The jobs hasn't been solved");
2196 return (EPKG_FATAL);
2197 }
2198
2199 switch (j->type) {
2200 case PKG_JOBS_INSTALL:
2201 case PKG_JOBS_UPGRADE:
2202 case PKG_JOBS_DEINSTALL:
2203 case PKG_JOBS_AUTOREMOVE:
2204 if (j->need_fetch) {
2205 pkg_plugins_hook_run(PKG_PLUGIN_HOOK_PRE_FETCH, j, j->db);
2206 rc = pkg_jobs_fetch(j);
2207 pkg_plugins_hook_run(PKG_PLUGIN_HOOK_POST_FETCH, j, j->db);
2208 if (rc == EPKG_OK) {
2209 /* Check local conflicts in the first run */
2210 if (j->solved == 1) {
2211 do {
2212 j->conflicts_registered = 0;
2213 rc = pkg_jobs_check_conflicts(j);
2214 if (rc == EPKG_CONFLICT) {
2215 /* Cleanup results */
2216 LL_FREE(j->jobs, free);
2217 j->jobs = NULL;
2218 j->count = 0;
2219 has_conflicts = true;
2220 rc = pkg_jobs_solve(j);
2221 }
2222 else if (rc == EPKG_OK && !has_conflicts) {
2223 rc = pkg_jobs_execute(j);
2224 break;
2225 }
2226 } while (j->conflicts_registered > 0);
2227
2228 if (has_conflicts) {
2229 if (j->conflicts_registered == 0)
2230 pkg_jobs_set_priorities(j);
2231
2232 return (EPKG_CONFLICT);
2233 }
2234 }
2235 else {
2236 /* Not the first run, conflicts are resolved already */
2237 rc = pkg_jobs_execute(j);
2238 }
2239 }
2240 }
2241 else {
2242 rc = pkg_jobs_execute(j);
2243 }
2244
2245 break;
2246 case PKG_JOBS_FETCH:
2247 pkg_plugins_hook_run(PKG_PLUGIN_HOOK_PRE_FETCH, j, j->db);
2248 rc = pkg_jobs_fetch(j);
2249 pkg_plugins_hook_run(PKG_PLUGIN_HOOK_POST_FETCH, j, j->db);
2250 break;
2251 default:
2252 rc = EPKG_FATAL;
2253 pkg_emit_error("bad jobs argument");
2254 break;
2255 }
2256
2257 return (rc);
2258 }
2259
2260
2261 static int
pkg_jobs_fetch(struct pkg_jobs * j)2262 pkg_jobs_fetch(struct pkg_jobs *j)
2263 {
2264 struct pkg *p = NULL;
2265 struct pkg_solved *ps;
2266 struct stat st;
2267 int64_t dlsize = 0, fs_avail = -1;
2268 const char *cachedir = NULL;
2269 char cachedpath[MAXPATHLEN];
2270 bool mirror = (j->flags & PKG_FLAG_FETCH_MIRROR) ? true : false;
2271
2272
2273 if (j->destdir == NULL || !mirror)
2274 cachedir = ctx.cachedir;
2275 else
2276 cachedir = j->destdir;
2277
2278 /* check for available size to fetch */
2279 DL_FOREACH(j->jobs, ps) {
2280 if (ps->type != PKG_SOLVED_DELETE && ps->type != PKG_SOLVED_UPGRADE_REMOVE) {
2281 p = ps->items[0]->pkg;
2282 if (p->type != PKG_REMOTE)
2283 continue;
2284
2285 if (mirror) {
2286 snprintf(cachedpath, sizeof(cachedpath),
2287 "%s/%s", cachedir, p->repopath);
2288 }
2289 else
2290 pkg_repo_cached_name(p, cachedpath, sizeof(cachedpath));
2291
2292 if (stat(cachedpath, &st) == -1)
2293 dlsize += p->pkgsize;
2294 else
2295 dlsize += p->pkgsize - st.st_size;
2296 }
2297 }
2298
2299 if (dlsize == 0)
2300 return (EPKG_OK);
2301
2302 #ifdef HAVE_FSTATFS
2303 struct statfs fs;
2304 while (statfs(cachedir, &fs) == -1) {
2305 if (errno == ENOENT) {
2306 if (mkdirs(cachedir) != EPKG_OK)
2307 return (EPKG_FATAL);
2308 } else {
2309 pkg_emit_errno("statfs", cachedir);
2310 return (EPKG_FATAL);
2311 }
2312 }
2313 fs_avail = fs.f_bsize * (int64_t)fs.f_bavail;
2314 #elif defined(HAVE_SYS_STATVFS_H)
2315 struct statvfs fs;
2316 while (statvfs(cachedir, &fs) == -1) {
2317 if (errno == ENOENT) {
2318 if (mkdirs(cachedir) != EPKG_OK)
2319 return (EPKG_FATAL);
2320 } else {
2321 pkg_emit_errno("statvfs", cachedir);
2322 return (EPKG_FATAL);
2323 }
2324 }
2325 fs_avail = fs.f_bsize * (int64_t)fs.f_bavail;
2326 #endif
2327
2328 if (fs_avail != -1 && dlsize > fs_avail) {
2329 char dlsz[9], fsz[9];
2330
2331 humanize_number(dlsz, sizeof(dlsz), dlsize, "B",
2332 HN_AUTOSCALE, HN_IEC_PREFIXES);
2333 humanize_number(fsz, sizeof(fsz), fs_avail, "B",
2334 HN_AUTOSCALE, HN_IEC_PREFIXES);
2335 pkg_emit_error("Not enough space in %s, needed %s available %s",
2336 cachedir, dlsz, fsz);
2337 return (EPKG_FATAL);
2338 }
2339
2340 if ((j->flags & PKG_FLAG_DRY_RUN) == PKG_FLAG_DRY_RUN)
2341 return (EPKG_OK); /* don't download anything */
2342
2343 /* Fetch */
2344 DL_FOREACH(j->jobs, ps) {
2345 if (ps->type != PKG_SOLVED_DELETE
2346 && ps->type != PKG_SOLVED_UPGRADE_REMOVE) {
2347 p = ps->items[0]->pkg;
2348 if (p->type != PKG_REMOTE)
2349 continue;
2350
2351 if (mirror) {
2352 if (pkg_repo_mirror_package(p, cachedir) != EPKG_OK)
2353 return (EPKG_FATAL);
2354 }
2355 else {
2356 if (pkg_repo_fetch_package(p) != EPKG_OK)
2357 return (EPKG_FATAL);
2358 }
2359 }
2360 }
2361
2362 return (EPKG_OK);
2363 }
2364
2365 static int
pkg_jobs_check_conflicts(struct pkg_jobs * j)2366 pkg_jobs_check_conflicts(struct pkg_jobs *j)
2367 {
2368 struct pkg_solved *ps;
2369 struct pkg *p = NULL;
2370 int ret = EPKG_OK, res, added = 0;
2371
2372 pkg_emit_integritycheck_begin();
2373 j->conflicts_registered = 0;
2374
2375 DL_FOREACH(j->jobs, ps) {
2376 if (ps->type == PKG_SOLVED_DELETE || ps->type == PKG_SOLVED_UPGRADE_REMOVE) {
2377 continue;
2378 }
2379 else {
2380 p = ps->items[0]->pkg;
2381
2382 if (p->type == PKG_REMOTE)
2383 pkgdb_ensure_loaded(j->db, p, PKG_LOAD_FILES|PKG_LOAD_DIRS);
2384 }
2385 if ((res = pkg_conflicts_append_chain(ps->items[0], j)) != EPKG_OK)
2386 ret = res;
2387 else
2388 added ++;
2389 }
2390
2391 pkg_debug(1, "check integrity for %d items added", added);
2392
2393 pkg_emit_integritycheck_finished(j->conflicts_registered);
2394 if (j->conflicts_registered > 0)
2395 ret = EPKG_CONFLICT;
2396
2397 return (ret);
2398 }
2399
2400 bool
pkg_jobs_has_lockedpkgs(struct pkg_jobs * j)2401 pkg_jobs_has_lockedpkgs(struct pkg_jobs *j)
2402 {
2403
2404 return j->lockedpkgs ? true : false;
2405 }
2406
2407 static void
pkg_jobs_visit_lockedpkgs(const void * node,VISIT v,int i __unused)2408 pkg_jobs_visit_lockedpkgs(const void * node, VISIT v, int i __unused)
2409 {
2410
2411 if (v == postorder || v == leaf) {
2412 pkgs_job_lockedpkg->locked_pkg_cb(*(struct pkg **)node,
2413 pkgs_job_lockedpkg->context);
2414 }
2415 }
2416
2417 void
pkg_jobs_iter_lockedpkgs(struct pkg_jobs * j,locked_pkgs_cb cb,void * ctx)2418 pkg_jobs_iter_lockedpkgs(struct pkg_jobs *j, locked_pkgs_cb cb, void * ctx)
2419 {
2420 struct pkg_jobs_locked foo;
2421
2422 foo.locked_pkg_cb = cb;
2423 foo.context = ctx;
2424 pkgs_job_lockedpkg = &foo;
2425
2426 twalk(j->lockedpkgs, pkg_jobs_visit_lockedpkgs);
2427 }
2428