예제 #1
0
파일: update.c 프로젝트: zxombie/pkg
static int
pkg_repo_binary_add_from_manifest(char *buf, const char *origin, const char *digest,
		long offset, sqlite3 *sqlite,
		struct pkg_manifest_key **keys, struct pkg **p, bool is_legacy,
		struct pkg_repo *repo)
{
	int rc = EPKG_OK;
	struct pkg *pkg;
	const char *local_origin, *pkg_arch;

	if (*p == NULL) {
		rc = pkg_new(p, PKG_REMOTE);
		if (rc != EPKG_OK)
			return (EPKG_FATAL);
	} else {
		pkg_reset(*p, PKG_REMOTE);
	}

	pkg = *p;

	pkg_manifest_keys_new(keys);
	rc = pkg_parse_manifest(pkg, buf, offset, *keys);
	if (rc != EPKG_OK) {
		goto cleanup;
	}
	rc = pkg_is_valid(pkg);
	if (rc != EPKG_OK) {
		goto cleanup;
	}

	/* Ensure that we have a proper origin and arch*/
	pkg_get(pkg, PKG_ORIGIN, &local_origin, PKG_ARCH, &pkg_arch);
	if (local_origin == NULL || strcmp(local_origin, origin) != 0) {
		pkg_emit_error("manifest contains origin %s while we wanted to add origin %s",
				local_origin ? local_origin : "NULL", origin);
		rc = EPKG_FATAL;
		goto cleanup;
	}

	if (pkg_arch == NULL || !is_valid_abi(pkg_arch, true)) {
		rc = EPKG_FATAL;
		pkg_emit_error("repository %s contains packages with wrong ABI: %s",
			repo->name, pkg_arch);
		goto cleanup;
	}

	pkg_set(pkg, PKG_REPONAME, repo->name);
	if (is_legacy) {
		pkg_set(pkg, PKG_OLD_DIGEST, digest);
		pkg_checksum_calculate(pkg, NULL);
	}
	else {
		pkg_set(pkg, PKG_DIGEST, digest);
	}

	rc = pkg_repo_binary_add_pkg(pkg, NULL, sqlite, true);

cleanup:
	return (rc);
}
예제 #2
0
static int
pkg_jobs_universe_handle_provide(struct pkg_jobs_universe *universe,
		struct pkgdb_it *it, const char *name, bool is_shlib, struct pkg *parent)
{
	struct pkg_job_universe_item *unit;
	struct pkg_job_provide *pr, *prhead;
	struct pkg *npkg, *rpkg;
	int rc;
	unsigned flags = PKG_LOAD_BASIC|PKG_LOAD_OPTIONS|PKG_LOAD_DEPS|
				PKG_LOAD_REQUIRES|PKG_LOAD_PROVIDES|
				PKG_LOAD_SHLIBS_REQUIRED|PKG_LOAD_SHLIBS_PROVIDED|
				PKG_LOAD_ANNOTATIONS|PKG_LOAD_CONFLICTS;

	rpkg = NULL;

	HASH_FIND_STR(universe->provides, name, prhead);

	while (pkgdb_it_next(it, &rpkg, flags) == EPKG_OK) {
		/* Check for local packages */
		HASH_FIND_STR(universe->items, rpkg->uid, unit);
		if (unit != NULL) {
			/* Remote provide is newer, so we can add it */
			if (pkg_jobs_universe_process_item(universe, rpkg,
					&unit) != EPKG_OK) {
				continue;
			}

			rpkg = NULL;
		}
		else {
			/* Maybe local package has just been not added */
			npkg = pkg_jobs_universe_get_local(universe, rpkg->uid, 0);
			if (npkg != NULL) {
				if (pkg_jobs_universe_process_item(universe, npkg,
						&unit) != EPKG_OK) {
					return (EPKG_FATAL);
				}
				if (pkg_jobs_universe_process_item(universe, rpkg,
						&unit) != EPKG_OK) {
					continue;
				}
				if (unit != NULL)
					rpkg = NULL;
			}
		}

		/* Skip seen packages */
		if (unit == NULL) {
			if (rpkg->digest == NULL) {
				pkg_debug(3, "no digest found for package %s", rpkg->uid);
				if (pkg_checksum_calculate(rpkg, universe->j->db) != EPKG_OK) {
					return (EPKG_FATAL);
				}
			}
			rc = pkg_jobs_universe_process_item(universe, rpkg,
					&unit);

			if (rc != EPKG_OK) {
				return (rc);
			}

			/* Reset package to avoid freeing */
			rpkg = NULL;
		}

		pr = calloc (1, sizeof (*pr));
		if (pr == NULL) {
			pkg_emit_errno("pkg_jobs_add_universe", "calloc: "
					"struct pkg_job_provide");
			return (EPKG_FATAL);
		}

		pr->un = unit;
		pr->provide = name;
		pr->is_shlib = is_shlib;

		if (prhead == NULL) {
			DL_APPEND(prhead, pr);
			HASH_ADD_KEYPTR(hh, universe->provides, pr->provide,
					strlen(pr->provide), prhead);
			pkg_debug (4, "universe: add new provide %s-%s(%s) for require %s",
					pr->un->pkg->name, pr->un->pkg->version,
					pr->un->pkg->type == PKG_INSTALLED ? "l" : "r",
					pr->provide);
		}
		else {
			DL_APPEND(prhead, pr);
			pkg_debug (4, "universe: append provide %s-%s(%s) for require %s",
					pr->un->pkg->name, pr->un->pkg->version,
					pr->un->pkg->type == PKG_INSTALLED ? "l" : "r",
					pr->provide);
		}
	}

	return (EPKG_OK);
}
예제 #3
0
/**
 * Check whether a package is in the universe already or add it
 * @return item or NULL
 */
int
pkg_jobs_universe_add_pkg(struct pkg_jobs_universe *universe, struct pkg *pkg,
		bool force, struct pkg_job_universe_item **found)
{
	struct pkg_job_universe_item *item, *seen, *tmp = NULL;

	pkg_validate(pkg, universe->j->db);

	if (pkg->digest == NULL) {
		pkg_debug(3, "no digest found for package %s (%s-%s)",
		    pkg->uid, pkg->name, pkg->version);
		if (pkg_checksum_calculate(pkg, universe->j->db) != EPKG_OK) {
			*found = NULL;
			return (EPKG_FATAL);
		}
	}

	kh_find(pkg_jobs_seen, universe->seen, pkg->digest, seen);
	if (seen) {
		bool same_package = false;

		DL_FOREACH(seen, tmp) {
			if (tmp->pkg == pkg || (tmp->pkg->type == pkg->type &&
			    strcmp(tmp->pkg->digest, pkg->digest) == 0)) {
				if (tmp->pkg->reponame != NULL) {
					if (strcmp(tmp->pkg->reponame, pkg->reponame) == 0) {
						same_package = true;
						break;
					}
				} else {
					same_package = true;
					break;
				}
			}
		}

		if (same_package) {
			if (found != NULL) {
				*found = seen;
			}

			return (EPKG_END);
		}
	}

	if (pkg_is_locked(pkg)) {
		pkg_emit_locked(pkg);
		return (EPKG_LOCKED);
	}

	pkg_debug(2, "universe: add new %s pkg: %s, (%s-%s:%s)",
	    (pkg->type == PKG_INSTALLED ? "local" : "remote"), pkg->uid,
	    pkg->name, pkg->version, pkg->digest);

	item = calloc(1, sizeof (struct pkg_job_universe_item));
	if (item == NULL) {
		pkg_emit_errno("pkg_jobs_pkg_insert_universe", "calloc: struct pkg_job_universe_item");
		return (EPKG_FATAL);
	}

	item->pkg = pkg;


	HASH_FIND_STR(universe->items, pkg->uid, tmp);
	if (tmp == NULL)
		HASH_ADD_KEYPTR(hh, universe->items, pkg->uid, strlen(pkg->uid), item);

	DL_APPEND(tmp, item);

	if (seen == NULL)
		kh_safe_add(pkg_jobs_seen, universe->seen, item, item->pkg->digest);

	universe->nitems++;

	if (found != NULL)
		*found = item;

	return (EPKG_OK);
}