Radish alpha
H
rad:z3QDZAW2FAfuLvihrhiyDC9fAD8G9
HardenedBSD Package Manager
Radicle
Git
Rework ordering and jobs solved.
Vsevolod Stakhov committed 12 years ago
commit b755b4be76ca38c52d26110d9bea684edacc7a02
parent daa58b8
7 files changed +162 -241
modified libpkg/pkg.h.in
@@ -509,6 +509,13 @@ typedef enum {
	PKGDB_LOCK_EXCLUSIVE
} pkgdb_lock_t;

+
typedef enum {
+
	PKG_SOLVED_INSTALL,
+
	PKG_SOLVED_DELETE,
+
	PKG_SOLVED_UPGRADE,
+
	PKG_SOLVED_FETCH
+
} pkg_solved_t;
+

#define PKG_OPEN_MANIFEST_ONLY 0x1
#define PKG_OPEN_MANIFEST_COMPACT (0x1 << 1)

@@ -1208,9 +1215,8 @@ int pkg_jobs_total(struct pkg_jobs *jobs);
 * @param iter Must be set to NULL for the first call.
 * @return A next pkg or NULL.
 */
-
bool pkg_jobs_add_iter(struct pkg_jobs *jobs, void **iter, struct pkg **n, struct pkg **o);
-
bool pkg_jobs_delete_iter(struct pkg_jobs *jobs, void **iter, struct pkg **n, struct pkg **o);
-
bool pkg_jobs_upgrade_iter(struct pkg_jobs *jobs, void **iter, struct pkg **n, struct pkg **o);
+
bool pkg_jobs_iter(struct pkg_jobs *jobs, void **iter, struct pkg **n, 
+
	struct pkg **o, int *type);

/**
 * Apply the jobs in the queue (fetch and install).
modified libpkg/pkg_cudf.c
@@ -331,7 +331,8 @@ cudf_strdup(const char *in)
static void
pkg_jobs_cudf_insert_res_job (struct pkg_solved **target,
		struct pkg_job_universe_item *it_new,
-
		struct pkg_job_universe_item *it_old)
+
		struct pkg_job_universe_item *it_old,
+
		int type)
{
	struct pkg_solved *res;

@@ -342,6 +343,7 @@ pkg_jobs_cudf_insert_res_job (struct pkg_solved **target,
	}
	res->priority = it_new->priority;
	res->pkg[0] = it_new->pkg;
+
	res->type = type;
	if (it_old != NULL) {
		res->pkg[1] = it_old->pkg;
		res->priority = MAX(it_old->priority, res->priority);
@@ -405,13 +407,13 @@ pkg_jobs_cudf_add_package(struct pkg_jobs *j, struct pkg_cudf_entry *entry)
		if (entry->installed && selected->pkg->type != PKG_INSTALLED) {
			pkg_debug(3, "pkg_cudf: schedule installation of %s(%d)",
					entry->origin, ver);
-
			pkg_jobs_cudf_insert_res_job (&j->jobs_add, selected, NULL);
+
			pkg_jobs_cudf_insert_res_job (&j->jobs, selected, NULL, PKG_SOLVED_INSTALL);
			j->count ++;
		}
		else if (!entry->installed && selected->pkg->type == PKG_INSTALLED) {
			pkg_debug(3, "pkg_cudf: schedule removing of %s(%d)",
					entry->origin, ver);
-
			pkg_jobs_cudf_insert_res_job (&j->jobs_delete, selected, NULL);
+
			pkg_jobs_cudf_insert_res_job (&j->jobs, selected, NULL, PKG_SOLVED_DELETE);
			j->count ++;
		}
	}
@@ -429,7 +431,7 @@ pkg_jobs_cudf_add_package(struct pkg_jobs *j, struct pkg_cudf_entry *entry)
		/* XXX: this is a hack due to iterators stupidity */
		pkg_get(old->pkg, PKG_VERSION, &oldversion);
		pkg_set(selected->pkg, PKG_OLD_VERSION, oldversion);
-
		pkg_jobs_cudf_insert_res_job (&j->jobs_upgrade, selected, old);
+
		pkg_jobs_cudf_insert_res_job (&j->jobs, selected, old, PKG_SOLVED_UPGRADE);
		j->count ++;
	}

modified libpkg/pkg_jobs.c
@@ -118,9 +118,7 @@ pkg_jobs_free(struct pkg_jobs *j)
	}
	HASH_FREE(j->seen, pkg_job_seen, free);
	LL_FREE(j->patterns, job_pattern, free);
-
	LL_FREE(j->jobs_add, pkg_solved, free);
-
	LL_FREE(j->jobs_delete, pkg_solved, free);
-
	LL_FREE(j->jobs_upgrade, pkg_solved, free);
+
	LL_FREE(j->jobs, pkg_solved, free);

	free(j);
}
@@ -154,36 +152,31 @@ pkg_jobs_add(struct pkg_jobs *j, match_t match, char **argv, int argc)
	return (EPKG_OK);
}

-
#define MAKE_JOBS_ITER_FUNC(type)											\
-
    bool																	\
-
    pkg_jobs_##type##_iter(struct pkg_jobs *jobs, void **iter, 			\
-
						struct pkg **new, struct pkg **old)				\
-
    {																		\
-
    	struct pkg_solved *s;												\
-
    	assert(iter != NULL);												\
-
    	if (jobs->jobs_##type == NULL) {									\
-
    		return (false);													\
-
    	}																	\
-
    	if (*iter == NULL) {												\
-
    		s = jobs->jobs_##type;											\
-
    	}																	\
-
    	else if (*iter == jobs->jobs_##type) {								\
-
    		return (false);													\
-
    	}																	\
-
    	else {																\
-
    		s = *iter;														\
-
    	}																	\
-
    	*new = s->pkg[0];													\
-
    	*old = s->pkg[1];													\
-
    	*iter = s->next ? s->next : jobs->jobs_##type;						\
-
    	return (true);														\
-
    }
-

-
MAKE_JOBS_ITER_FUNC(add)
-
MAKE_JOBS_ITER_FUNC(delete)
-
MAKE_JOBS_ITER_FUNC(upgrade)
-

-
#undef MAKE_JOBS_ITER_FUNC
+
bool
+
pkg_jobs_iter(struct pkg_jobs *jobs, void **iter,
+
				struct pkg **new, struct pkg **old,
+
				int *type)
+
{
+
	struct pkg_solved *s;
+
	assert(iter != NULL);
+
	if (jobs->jobs == NULL) {
+
		return (false);
+
	}
+
	if (*iter == NULL) {
+
		s = jobs->jobs;
+
	}
+
	else if (*iter == jobs->jobs) {
+
		return (false);
+
	}
+
	else {
+
		s = *iter;
+
	}
+
	*new = s->pkg[0];
+
	*old = s->pkg[1];
+
	*type = s->type;
+
	*iter = s->next ? s->next : jobs->jobs;
+
	return (true);
+
}

static void
pkg_jobs_add_req(struct pkg_jobs *j, const char *origin, struct pkg *pkg,
@@ -988,14 +981,17 @@ jobs_solve_fetch(struct pkg_jobs *j)
}

static int
-
jobs_sort_priority_dec(struct pkg_solved *r1, struct pkg_solved *r2)
-
{
-
	return (r1->priority - r2->priority);
-
}
-

-
static int
-
jobs_sort_priority_inc(struct pkg_solved *r1, struct pkg_solved *r2)
+
pkg_jobs_sort_priority(struct pkg_solved *r1, struct pkg_solved *r2)
{
+
	if (r1->type == PKG_SOLVED_DELETE && r2->type != PKG_SOLVED_DELETE) {
+
		return 1;
+
	}
+
	else if (r1->type != PKG_SOLVED_DELETE && r2->type == PKG_SOLVED_DELETE) {
+
		return -1;
+
	}
+
	else if (r1->type == PKG_SOLVED_DELETE && r2->type == PKG_SOLVED_DELETE) {
+
		return (r1->priority - r2->priority);
+
	}
	return (r2->priority - r1->priority);
}

@@ -1083,11 +1079,8 @@ pkg_jobs_solve(struct pkg_jobs *j)
	}

	/* Resort priorities */
-
	if (j->solved) {
-
		DL_SORT(j->jobs_add, jobs_sort_priority_inc);
-
		DL_SORT(j->jobs_upgrade, jobs_sort_priority_inc);
-
		DL_SORT(j->jobs_delete, jobs_sort_priority_dec);
-
	}
+
	if (j->solved)
+
		DL_SORT(j->jobs, pkg_jobs_sort_priority);

	return (ret);
}
@@ -1189,12 +1182,12 @@ cleanup:
}

static int
-
pkg_jobs_install(struct pkg_jobs *j)
+
pkg_jobs_execute(struct pkg_jobs *j)
{
	struct pkg *p = NULL;
	struct pkg_solved *ps;
	struct pkg_manifest_key *keys = NULL;
-
	const char *cachedir = NULL;
+
	const char *cachedir = NULL, *name;
	int flags = 0;
	int retcode = EPKG_FATAL;
	bool handle_rc = false;
@@ -1219,23 +1212,34 @@ pkg_jobs_install(struct pkg_jobs *j)
	pkgdb_transaction_begin(j->db->sqlite, "upgrade");

	/* Delete conflicts initially */
-
	DL_FOREACH(j->jobs_delete, ps) {
-
		p = ps->pkg[0];
-
		retcode = pkg_delete(p, j->db, flags);
-
		if (retcode != EPKG_OK)
-
			goto cleanup;
-
	}
-
	DL_FOREACH(j->jobs_add, ps) {
-
		retcode = pkg_jobs_handle_install(ps->pkg[0], NULL,
-
				j, handle_rc, cachedir, keys);
-
		if (retcode != EPKG_OK)
-
			goto cleanup;
-
	}
-
	DL_FOREACH(j->jobs_upgrade, ps) {
-
		retcode = pkg_jobs_handle_install(ps->pkg[0], ps->pkg[1],
-
				j, handle_rc, cachedir, keys);
-
		if (retcode != EPKG_OK)
-
			goto cleanup;
+
	DL_FOREACH(j->jobs, ps) {
+
		switch (ps->type) {
+
		case PKG_SOLVED_DELETE:
+
			p = ps->pkg[0];
+
			pkg_get(p, PKG_NAME, &name);
+
			if ((strcmp(name, "pkg") == 0 ||
+
				strcmp(name, "pkg-devel") == 0) && flags != PKG_DELETE_FORCE) {
+
				pkg_emit_error("Cannot delete pkg itself without force flag");
+
				continue;
+
			}
+
			retcode = pkg_delete(p, j->db, flags);
+
			if (retcode != EPKG_OK)
+
				goto cleanup;
+
			break;
+
		case PKG_SOLVED_INSTALL:
+
			retcode = pkg_jobs_handle_install(ps->pkg[0], NULL,
+
					j, handle_rc, cachedir, keys);
+
			if (retcode != EPKG_OK)
+
				goto cleanup;
+
			break;
+
		case PKG_SOLVED_UPGRADE:
+
			retcode = pkg_jobs_handle_install(ps->pkg[0], ps->pkg[1],
+
					j, handle_rc, cachedir, keys);
+
			if (retcode != EPKG_OK)
+
				goto cleanup;
+
			break;
+
		}
+

	}

cleanup:
@@ -1246,46 +1250,6 @@ cleanup:
	return (retcode);
}

-
static int
-
pkg_jobs_deinstall(struct pkg_jobs *j)
-
{
-
	struct pkg *p = NULL;
-
	struct pkg_solved *ps;
-
	const char *name;
-
	int retcode;
-
	int flags = 0;
-

-
	if ((j->flags & PKG_FLAG_DRY_RUN) == PKG_FLAG_DRY_RUN)
-
		return (EPKG_OK); /* Do nothing */
-

-
	if ((j->flags & PKG_FLAG_FORCE) == PKG_FLAG_FORCE)
-
		flags = PKG_DELETE_FORCE;
-

-
	if ((j->flags & PKG_FLAG_NOSCRIPT) == PKG_FLAG_NOSCRIPT)
-
		flags |= PKG_DELETE_NOSCRIPT;
-

-
	/* XXX: get rid of hardcoded values */
-
	retcode = pkgdb_upgrade_lock(j->db, PKGDB_LOCK_ADVISORY,
-
			PKGDB_LOCK_EXCLUSIVE, 0.5, 20);
-

-
	DL_FOREACH(j->jobs_delete, ps) {
-
		p = ps->pkg[0];
-
		pkg_get(p, PKG_NAME, &name);
-
		if ((strcmp(name, "pkg") == 0 ||
-
			 strcmp(name, "pkg-devel") == 0) && flags != PKG_DELETE_FORCE) {
-
			pkg_emit_error("Cannot delete pkg itself without force flag");
-
			continue;
-
		}
-
		retcode = pkg_delete(p, j->db, flags);
-

-
		if (retcode != EPKG_OK)
-
			goto cleanup;
-
	}
-
cleanup:
-
	pkgdb_release_lock(j->db, PKGDB_LOCK_EXCLUSIVE);
-
	return (retcode);
-
}
-

int
pkg_jobs_apply(struct pkg_jobs *j)
{
@@ -1301,14 +1265,24 @@ pkg_jobs_apply(struct pkg_jobs *j)
		pre = PKG_PLUGIN_HOOK_PRE_INSTALL;
		post = PKG_PLUGIN_HOOK_POST_INSTALL;
	}
-
	else {
+
	else if (j->type == PKG_JOBS_UPGRADE) {
		pre = PKG_PLUGIN_HOOK_PRE_UPGRADE;
		post = PKG_PLUGIN_HOOK_POST_UPGRADE;
	}
+
	else if (j->type == PKG_JOBS_AUTOREMOVE){
+
		pre = PKG_PLUGIN_HOOK_PRE_AUTOREMOVE;
+
		post = PKG_PLUGIN_HOOK_POST_AUTOREMOVE;
+
	}
+
	else {
+
		pre = PKG_PLUGIN_HOOK_PRE_DEINSTALL;
+
		post = PKG_PLUGIN_HOOK_POST_DEINSTALL;
+
	}

	switch (j->type) {
	case PKG_JOBS_INSTALL:
	case PKG_JOBS_UPGRADE:
+
	case PKG_JOBS_DEINSTALL:
+
	case PKG_JOBS_AUTOREMOVE:
		pkg_plugins_hook_run(PKG_PLUGIN_HOOK_PRE_FETCH, j, j->db);
		rc = pkg_jobs_fetch(j);
		pkg_plugins_hook_run(PKG_PLUGIN_HOOK_POST_FETCH, j, j->db);
@@ -1322,14 +1296,12 @@ pkg_jobs_apply(struct pkg_jobs *j)
			}
			if (rc == EPKG_OK) {
				pkg_plugins_hook_run(pre, j, j->db);
-
				rc = pkg_jobs_install(j);
+
				rc = pkg_jobs_execute(j);
			}
			else if (rc == EPKG_CONFLICT) {
				/* Cleanup results */
-
				LL_FREE(j->jobs_add, pkg_solved, free);
-
				LL_FREE(j->jobs_delete, pkg_solved, free);
-
				LL_FREE(j->jobs_upgrade, pkg_solved, free);
-
				j->jobs_add = j->jobs_delete = j->jobs_upgrade = NULL;
+
				LL_FREE(j->jobs, pkg_solved, free);
+
				j->jobs = NULL;
				j->count = 0;
				j->total = 0;

@@ -1343,21 +1315,11 @@ pkg_jobs_apply(struct pkg_jobs *j)
		}
		pkg_plugins_hook_run(post, j, j->db);
		break;
-
	case PKG_JOBS_DEINSTALL:
-
		pkg_plugins_hook_run(PKG_PLUGIN_HOOK_PRE_DEINSTALL, j, j->db);
-
		rc = pkg_jobs_deinstall(j);
-
		pkg_plugins_hook_run(PKG_PLUGIN_HOOK_POST_DEINSTALL, j, j->db);
-
		break;
	case PKG_JOBS_FETCH:
		pkg_plugins_hook_run(PKG_PLUGIN_HOOK_PRE_FETCH, j, j->db);
		rc = pkg_jobs_fetch(j);
		pkg_plugins_hook_run(PKG_PLUGIN_HOOK_POST_FETCH, j, j->db);
		break;
-
	case PKG_JOBS_AUTOREMOVE:
-
		pkg_plugins_hook_run(PKG_PLUGIN_HOOK_PRE_AUTOREMOVE, j, j->db);
-
		rc = pkg_jobs_deinstall(j);
-
		pkg_plugins_hook_run(PKG_PLUGIN_HOOK_POST_AUTOREMOVE, j, j->db);
-
		break;
	default:
		rc = EPKG_FATAL;
		pkg_emit_error("bad jobs argument");
@@ -1369,22 +1331,26 @@ pkg_jobs_apply(struct pkg_jobs *j)

#define PKG_JOBS_FETCH_CALCULATE(list) do {										\
	DL_FOREACH((list), ps) {														\
-
		p = ps->pkg[0];																\
-
		int64_t pkgsize;															\
-
		pkg_get(p, PKG_PKGSIZE, &pkgsize, PKG_REPOPATH, &repopath);					\
-
		snprintf(cachedpath, sizeof(cachedpath), "%s/%s", cachedir, repopath);		\
-
		if (stat(cachedpath, &st) == -1)											\
-
			dlsize += pkgsize;														\
-
		else																		\
-
			dlsize += pkgsize - st.st_size;											\
+
		if (ps->type != PKG_SOLVED_DELETE) {										\
+
			p = ps->pkg[0];															\
+
			int64_t pkgsize;														\
+
			pkg_get(p, PKG_PKGSIZE, &pkgsize, PKG_REPOPATH, &repopath);				\
+
			snprintf(cachedpath, sizeof(cachedpath), "%s/%s", cachedir, repopath);	\
+
			if (stat(cachedpath, &st) == -1)										\
+
				dlsize += pkgsize;													\
+
			else																	\
+
				dlsize += pkgsize - st.st_size;										\
+
		}																			\
	}																				\
} while(0)

#define PKG_JOBS_DO_FETCH(list) do {												\
	DL_FOREACH((list), ps) {														\
-
		p = ps->pkg[0];																\
-
		if (pkg_repo_fetch(p) != EPKG_OK)											\
-
			return (EPKG_FATAL);													\
+
		if (ps->type != PKG_SOLVED_DELETE) {										\
+
			p = ps->pkg[0];															\
+
			if (pkg_repo_fetch(p) != EPKG_OK)										\
+
				return (EPKG_FATAL);												\
+
		}																			\
	}																				\
} while(0)

@@ -1404,8 +1370,10 @@ pkg_jobs_fetch(struct pkg_jobs *j)
		return (EPKG_FATAL);

	/* check for available size to fetch */
-
	PKG_JOBS_FETCH_CALCULATE(j->jobs_add);
-
	PKG_JOBS_FETCH_CALCULATE(j->jobs_upgrade);
+
	PKG_JOBS_FETCH_CALCULATE(j->jobs);
+

+
	if (dlsize == 0)
+
		return (EPKG_OK);

	while (statfs(cachedir, &fs) == -1) {
		if (errno == ENOENT) {
@@ -1432,8 +1400,7 @@ pkg_jobs_fetch(struct pkg_jobs *j)
		return (EPKG_OK); /* don't download anything */

	/* Fetch */
-
	PKG_JOBS_DO_FETCH(j->jobs_add);
-
	PKG_JOBS_DO_FETCH(j->jobs_upgrade);
+
	PKG_JOBS_DO_FETCH(j->jobs);

	return (EPKG_OK);
}
@@ -1441,23 +1408,6 @@ pkg_jobs_fetch(struct pkg_jobs *j)
#undef PKG_JOBS_FETCH_CALCULATE
#undef PKG_JOBS_DO_FETCH

-
#define PKG_JOBS_CHECK_CONFLICTS_LIST(list) do {						\
-
	DL_FOREACH((list), ps) {											\
-
		p = ps->pkg[0];													\
-
		const char *pkgrepopath;										\
-
		pkg_get(p, PKG_REPOPATH, &pkgrepopath);							\
-
		snprintf(path, sizeof(path), "%s/%s", cachedir,					\
-
				pkgrepopath);											\
-
		if (pkg_open(&pkg, path, keys, 0) != EPKG_OK)					\
-
			return (EPKG_FATAL);										\
-
		if ((res = pkg_conflicts_append_pkg(pkg, j)) != EPKG_OK) {		\
-
			ret = res;													\
-
			if (ret == EPKG_FATAL)										\
-
				break;													\
-
		}																\
-
	}																	\
-
} while(0)
-

static int
pkg_jobs_check_conflicts(struct pkg_jobs *j)
{
@@ -1475,8 +1425,25 @@ pkg_jobs_check_conflicts(struct pkg_jobs *j)
	pkg_emit_integritycheck_begin();

	pkg_manifest_keys_new(&keys);
-
	PKG_JOBS_CHECK_CONFLICTS_LIST(j->jobs_add);
-
	PKG_JOBS_CHECK_CONFLICTS_LIST(j->jobs_upgrade);
+
	DL_FOREACH(j->jobs, ps) {
+
		if (ps->type == PKG_SOLVED_DELETE) {
+
			continue;
+
		}
+
		else {
+
			p = ps->pkg[0];
+
			const char *pkgrepopath;
+
			pkg_get(p, PKG_REPOPATH, &pkgrepopath);
+
			snprintf(path, sizeof(path), "%s/%s", cachedir,
+
				pkgrepopath);
+
			if (pkg_open(&pkg, path, keys, 0) != EPKG_OK)
+
				return (EPKG_FATAL);
+
		}
+
		if ((res = pkg_conflicts_append_pkg(pkg, j)) != EPKG_OK) {
+
			ret = res;
+
			if (ret == EPKG_FATAL)
+
				break;
+
		}
+
	}
	pkg_manifest_keys_free(keys);

	pkg_free(pkg);
modified libpkg/pkg_solve.c
@@ -840,14 +840,16 @@ pkg_solve_insert_res_job (struct pkg_solve_variable *var,
		if (seen_add == 0 && seen_del != 0) {
			res->priority = del_var->priority;
			res->pkg[0] = del_var->pkg;
-
			DL_APPEND(j->jobs_delete, res);
+
			res->type = PKG_SOLVED_DELETE;
+
			DL_APPEND(j->jobs, res);
			pkg_debug(3, "pkg_solve: schedule deletion of %s(%s)",
					del_var->origin, del_var->digest);
		}
		else if (seen_del == 0 && seen_add != 0) {
			res->priority = add_var->priority;
			res->pkg[0] = add_var->pkg;
-
			DL_APPEND(j->jobs_add, res);
+
			res->type = PKG_SOLVED_INSTALL;
+
			DL_APPEND(j->jobs, res);
			pkg_debug(3, "pkg_solve: schedule installation of %s(%s)",
					add_var->origin, add_var->digest);
		}
@@ -855,25 +857,10 @@ pkg_solve_insert_res_job (struct pkg_solve_variable *var,
			res->priority = MAX(del_var->priority, add_var->priority);
			res->pkg[0] = add_var->pkg;
			res->pkg[1] = del_var->pkg;
-
			DL_APPEND(j->jobs_upgrade, res);
+
			res->type = PKG_SOLVED_UPGRADE;
+
			DL_APPEND(j->jobs, res);
			pkg_debug(3, "pkg_solve: schedule upgrade of %s from %s to %s",
					del_var->origin, del_var->digest, add_var->digest);
-
#if 0
-
			/* Need some more tasks */
-
			res_a = calloc(1, sizeof(struct pkg_solved));
-
			res_d = calloc(1, sizeof(struct pkg_solved));
-
			if (res_a == NULL || res_d == NULL) {
-
				pkg_emit_errno("calloc", "pkg_solved");
-
				return;
-
			}
-
			/* Priority for individual tasks are the same as for the upgrade task */
-
			res_a->priority = res->priority;
-
			res_a->pkg[0] = add_var->pkg;
-
			DL_APPEND(j->jobs_add, res_a);
-
			res_d->priority = res->priority;
-
			res_d->pkg[0] = del_var->pkg;
-
			DL_APPEND(j->jobs_delete, res_d);
-
#endif
		}
		j->count ++;
	}
modified libpkg/pkgdb.c
@@ -3834,10 +3834,13 @@ pkgdb_integrity_append(struct pkgdb *db, struct pkg *p,
			    -1, SQLITE_STATIC);
			cur = conflicts_list;
			while (sqlite3_step(stmt_conflicts) != SQLITE_DONE) {
+

				cur = calloc(1, sizeof (struct pkg_event_conflict));
				cur->name = strdup(sqlite3_column_text(stmt_conflicts, 0));
				cur->origin = strdup(sqlite3_column_text(stmt_conflicts, 1));
				cur->version = strdup(sqlite3_column_text(stmt_conflicts, 2));
+
				pkg_debug(3, "found conflict between %s and %s on path %s",
+
						porigin, cur->origin, pkg_path);
				LL_PREPEND(conflicts_list, cur);

				if (cb != NULL)
modified libpkg/private/pkg.h
@@ -206,6 +206,7 @@ struct pkg_job_request {
struct pkg_solved {
	struct pkg *pkg[2];
	int priority;
+
	pkg_solved_t type;
	struct pkg_solved *prev, *next;
};

@@ -226,9 +227,7 @@ struct pkg_jobs {
	struct pkg_job_universe_item *universe;
	struct pkg_job_request	*request_add;
	struct pkg_job_request	*request_delete;
-
	struct pkg_solved *jobs_add;
-
	struct pkg_solved *jobs_delete;
-
	struct pkg_solved *jobs_upgrade;
+
	struct pkg_solved *jobs;
	struct pkg_job_seen *seen;
	struct pkgdb	*db;
	pkg_jobs_t	 type;
modified src/utils.c
@@ -529,7 +529,7 @@ print_info(struct pkg * const pkg, uint64_t options)

static void
print_jobs_summary_pkg(struct pkg *new_pkg, struct pkg *old_pkg,
-
		pkg_jobs_t type, int64_t *oldsize,
+
		pkg_solved_t type, int64_t *oldsize,
		int64_t *newsize, int64_t *dlsize)
{
	const char *oldversion, *cachedir, *why;
@@ -549,8 +549,8 @@ print_jobs_summary_pkg(struct pkg *new_pkg, struct pkg *old_pkg,
	if (old_pkg != NULL && pkg_is_locked(old_pkg)) {
		pkg_printf("\tPackage %n-%v is locked ", old_pkg, old_pkg);
		switch (type) {
-
		case PKG_JOBS_INSTALL:
-
		case PKG_JOBS_UPGRADE:
+
		case PKG_SOLVED_INSTALL:
+
		case PKG_SOLVED_UPGRADE:
			/* If it's a new install, then it
			 * cannot have been locked yet. */
			if (oldversion != NULL) {
@@ -568,12 +568,11 @@ print_jobs_summary_pkg(struct pkg *new_pkg, struct pkg *old_pkg,
				return;
			}
			break;
-
		case PKG_JOBS_DEINSTALL:
-
		case PKG_JOBS_AUTOREMOVE:
+
		case PKG_SOLVED_DELETE:
			printf("and may not be deinstalled\n");
			return;
			break;
-
		case PKG_JOBS_FETCH:
+
		case PKG_SOLVED_FETCH:
			printf("but a new package can still be fetched\n");
			break;
		}
@@ -581,8 +580,8 @@ print_jobs_summary_pkg(struct pkg *new_pkg, struct pkg *old_pkg,
	}

	switch (type) {
-
	case PKG_JOBS_INSTALL:
-
	case PKG_JOBS_UPGRADE:
+
	case PKG_SOLVED_INSTALL:
+
	case PKG_SOLVED_UPGRADE:
		pkg_snprintf(path, MAXPATHLEN, "%S/%R", cachedir, new_pkg);

		if (stat(path, &st) == -1 || pkgsize != st.st_size)
@@ -627,14 +626,13 @@ print_jobs_summary_pkg(struct pkg *new_pkg, struct pkg *old_pkg,
			printf("\n");
		}
		break;
-
	case PKG_JOBS_DEINSTALL:
-
	case PKG_JOBS_AUTOREMOVE:
+
	case PKG_SOLVED_DELETE:
		*oldsize += oldflatsize;
		*newsize += flatsize;

		pkg_printf("\tRemoving %n-%v\n", new_pkg, new_pkg);
		break;
-
	case PKG_JOBS_FETCH:
+
	case PKG_SOLVED_FETCH:
		*dlsize += pkgsize;
		pkg_snprintf(path, MAXPATHLEN, "%S/%R", cachedir, new_pkg);
		if (stat(path, &st) != -1)
@@ -658,7 +656,7 @@ print_jobs_summary(struct pkg_jobs *jobs, const char *msg, ...)
	void *iter = NULL;
	char size[7];
	va_list ap;
-
	pkg_jobs_t type, inv_type = PKG_JOBS_DEINSTALL;
+
	int type;
	int64_t dlsize, oldsize, newsize;

	dlsize = oldsize = newsize = 0;
@@ -668,61 +666,20 @@ print_jobs_summary(struct pkg_jobs *jobs, const char *msg, ...)
	vprintf(msg, ap);
	va_end(ap);

-
	while (pkg_jobs_add_iter(jobs, &iter, &new_pkg, &old_pkg)) {
-
		print_jobs_summary_pkg(new_pkg, old_pkg, type, &oldsize, &newsize, &dlsize);
-
	}
-

-
	iter = NULL;
-
	while (pkg_jobs_delete_iter(jobs, &iter, &new_pkg, &old_pkg)) {
-
		print_jobs_summary_pkg(new_pkg, old_pkg, inv_type, &oldsize, &newsize, &dlsize);
-
	}
-
	iter = NULL;
-
	while (pkg_jobs_upgrade_iter(jobs, &iter, &new_pkg, &old_pkg)) {
+
	while (pkg_jobs_iter(jobs, &iter, &new_pkg, &old_pkg, &type)) {
		print_jobs_summary_pkg(new_pkg, old_pkg, type, &oldsize, &newsize, &dlsize);
	}

	if (oldsize > newsize) {
		humanize_number(size, sizeof(size), oldsize - newsize, "B", HN_AUTOSCALE, 0);
-

-
		switch (type) {
-
		case PKG_JOBS_INSTALL:
-
			printf("\nThe installation will free %s\n", size);
-
			break;
-
		case PKG_JOBS_UPGRADE:
-
			printf("\nThe upgrade will free %s\n", size);
-
			break;
-
		case PKG_JOBS_DEINSTALL:
-
		case PKG_JOBS_AUTOREMOVE:
-
			printf("\nThe deinstallation will free %s\n", size);
-
			break;
-
		case PKG_JOBS_FETCH:
-
			/* nothing to report here */
-
			break;
-
		}
+
		printf("\nThe operation will free %s\n", size);
	} else if (newsize > oldsize) {
		humanize_number(size, sizeof(size), newsize - oldsize, "B", HN_AUTOSCALE, 0);
-

-
		switch (type) {
-
		case PKG_JOBS_INSTALL:
-
			printf("\nThe installation will require %s more space\n", size);
-
			break;
-
		case PKG_JOBS_UPGRADE:
-
			printf("\nThe upgrade will require %s more space\n", size);
-
			break;
-
		case PKG_JOBS_DEINSTALL:
-
		case PKG_JOBS_AUTOREMOVE:
-
			printf("\nThe deinstallation will free %s\n", size);
-
			break;
-
		case PKG_JOBS_FETCH:
-
			/* nothing to report here */
-
			break;
-
		}
+
		printf("\nThe process will require %s more space\n", size);
	}

-
	if ((type == PKG_JOBS_INSTALL) || (type == PKG_JOBS_FETCH) || (type == PKG_JOBS_UPGRADE)) {
-
		humanize_number(size, sizeof(size), dlsize, "B", HN_AUTOSCALE, 0);
-
		printf("\n%s to be downloaded\n", size);
-
	}
+
	humanize_number(size, sizeof(size), dlsize, "B", HN_AUTOSCALE, 0);
+
	printf("\n%s to be downloaded\n", size);
}

struct sbuf *