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