Пример #1
0
static int
check_deps(struct pkgdb *db, struct pkg *p, struct deps_head *dh, bool noinstall)
{
	struct pkg_dep *dep = NULL;
	char *name, *version, *origin;
	int nbpkgs = 0;

	assert(db != NULL);
	assert(p != NULL);

	name = version = origin = NULL;
	pkg_get(p, PKG_NAME, &name, PKG_VERSION, &version, PKG_ORIGIN, &origin);

	while (pkg_deps(p, &dep) == EPKG_OK) {
		/* do we have a missing dependency? */
		if (pkg_is_installed(db, pkg_dep_origin(dep)) != EPKG_OK) {
			if (noinstall)
				printf("%s\n", pkg_dep_origin(dep));
			else
				printf("%s has a missing dependency: %s\n", origin,
			       pkg_dep_origin(dep));
			add_missing_dep(dep, dh, &nbpkgs);
		}
	}
	
	return (nbpkgs);
}
Пример #2
0
static void
add_missing_dep(struct pkg_dep *d, struct deps_head *dh, int *nbpkgs)
{
	struct deps_entry *e = NULL;
	const char *origin = NULL;

	assert(d != NULL);

	/* do not add duplicate entries in the queue */
	origin = pkg_dep_origin(d);

	STAILQ_FOREACH(e, dh, next)
		if (strcmp(e->origin, origin) == 0)
			return;

	if ((e = calloc(1, sizeof(struct deps_entry))) == NULL)
		err(1, "calloc(deps_entry)");

	e->name = strdup(pkg_dep_name(d));
	e->version = strdup(pkg_dep_version(d));
	e->origin = strdup(pkg_dep_origin(d));

	(*nbpkgs)++;

	STAILQ_INSERT_TAIL(dh, e, next);
}
Пример #3
0
static int
pkg_repo_binary_add_pkg(struct pkg *pkg, const char *pkg_path,
		sqlite3 *sqlite, bool forced)
{
	const char *name, *version, *origin, *comment, *desc;
	const char *arch, *maintainer, *www, *prefix, *sum, *rpath;
	const char *olddigest, *manifestdigest;
	int64_t			 flatsize, pkgsize;
	int64_t			 licenselogic;
	int			 ret;
	struct pkg_dep		*dep      = NULL;
	struct pkg_option	*option   = NULL;
	struct pkg_shlib	*shlib    = NULL;
	const pkg_object	*obj, *licenses, *categories, *annotations;
	pkg_iter		 it;
	int64_t			 package_id;

	pkg_get(pkg, PKG_ORIGIN, &origin, PKG_NAME, &name,
			    PKG_VERSION, &version, PKG_COMMENT, &comment,
			    PKG_DESC, &desc, PKG_ARCH, &arch,
			    PKG_MAINTAINER, &maintainer, PKG_WWW, &www,
			    PKG_PREFIX, &prefix, PKG_FLATSIZE, &flatsize,
			    PKG_LICENSE_LOGIC, &licenselogic, PKG_CKSUM, &sum,
			    PKG_PKGSIZE, &pkgsize, PKG_REPOPATH, &rpath,
			    PKG_LICENSES, &licenses, PKG_CATEGORIES, &categories,
			    PKG_ANNOTATIONS, &annotations, PKG_OLD_DIGEST, &olddigest,
			    PKG_DIGEST, &manifestdigest);

try_again:
	if ((ret = pkg_repo_binary_run_prstatement(PKG, origin, name, version,
			comment, desc, arch, maintainer, www, prefix,
			pkgsize, flatsize, (int64_t)licenselogic, sum,
			rpath, manifestdigest, olddigest)) != SQLITE_DONE) {
		if (ret == SQLITE_CONSTRAINT) {
			switch(pkg_repo_binary_delete_conflicting(origin,
					version, pkg_path, forced)) {
			case EPKG_FATAL: /* sqlite error */
				ERROR_SQLITE(sqlite, pkg_repo_binary_sql_prstatement(PKG));
				return (EPKG_FATAL);
				break;
			case EPKG_END: /* repo already has newer */
				return (EPKG_END);
				break;
			default: /* conflict cleared, try again */
				goto try_again;
				break;
			}
		} else {
			ERROR_SQLITE(sqlite, pkg_repo_binary_sql_prstatement(PKG));
			return (EPKG_FATAL);
		}
	}
	package_id = sqlite3_last_insert_rowid(sqlite);

	if (pkg_repo_binary_run_prstatement (FTS_APPEND, package_id,
			name, version, origin) != SQLITE_DONE) {
		ERROR_SQLITE(sqlite, pkg_repo_binary_sql_prstatement(FTS_APPEND));
		return (EPKG_FATAL);
	}

	dep = NULL;
	while (pkg_deps(pkg, &dep) == EPKG_OK) {
		if (pkg_repo_binary_run_prstatement(DEPS,
				pkg_dep_origin(dep),
				pkg_dep_name(dep),
				pkg_dep_version(dep),
				package_id) != SQLITE_DONE) {
			ERROR_SQLITE(sqlite, pkg_repo_binary_sql_prstatement(DEPS));
			return (EPKG_FATAL);
		}
	}

	it = NULL;
	while ((obj = pkg_object_iterate(categories, &it))) {
		ret = pkg_repo_binary_run_prstatement(CAT1, pkg_object_string(obj));
		if (ret == SQLITE_DONE)
			ret = pkg_repo_binary_run_prstatement(CAT2, package_id,
			    pkg_object_string(obj));
		if (ret != SQLITE_DONE)
		{
			ERROR_SQLITE(sqlite, pkg_repo_binary_sql_prstatement(CAT2));
			return (EPKG_FATAL);
		}
	}

	it = NULL;
	while ((obj = pkg_object_iterate(licenses, &it))) {
		ret = pkg_repo_binary_run_prstatement(LIC1, pkg_object_string(obj));
		if (ret == SQLITE_DONE)
			ret = pkg_repo_binary_run_prstatement(LIC2, package_id,
			    pkg_object_string(obj));
		if (ret != SQLITE_DONE) {
			ERROR_SQLITE(sqlite, pkg_repo_binary_sql_prstatement(LIC2));
			return (EPKG_FATAL);
		}
	}
	option = NULL;
	while (pkg_options(pkg, &option) == EPKG_OK) {
		ret = pkg_repo_binary_run_prstatement(OPT1, pkg_option_opt(option));
		if (ret == SQLITE_DONE)
		    ret = pkg_repo_binary_run_prstatement(OPT2, pkg_option_opt(option),
				pkg_option_value(option), package_id);
		if(ret != SQLITE_DONE) {
			ERROR_SQLITE(sqlite, pkg_repo_binary_sql_prstatement(OPT2));
			return (EPKG_FATAL);
		}
	}

	shlib = NULL;
	while (pkg_shlibs_required(pkg, &shlib) == EPKG_OK) {
		const char *shlib_name = pkg_shlib_name(shlib);

		ret = pkg_repo_binary_run_prstatement(SHLIB1, shlib_name);
		if (ret == SQLITE_DONE)
			ret = pkg_repo_binary_run_prstatement(SHLIB_REQD, package_id,
					shlib_name);
		if (ret != SQLITE_DONE) {
			ERROR_SQLITE(sqlite, pkg_repo_binary_sql_prstatement(SHLIB_REQD));
			return (EPKG_FATAL);
		}
	}

	shlib = NULL;
	while (pkg_shlibs_provided(pkg, &shlib) == EPKG_OK) {
		const char *shlib_name = pkg_shlib_name(shlib);

		ret = pkg_repo_binary_run_prstatement(SHLIB1, shlib_name);
		if (ret == SQLITE_DONE)
			ret = pkg_repo_binary_run_prstatement(SHLIB_PROV, package_id,
					shlib_name);
		if (ret != SQLITE_DONE) {
			ERROR_SQLITE(sqlite, pkg_repo_binary_sql_prstatement(SHLIB_PROV));
			return (EPKG_FATAL);
		}
	}

	it = NULL;
	while ((obj = pkg_object_iterate(annotations, &it))) {
		const char *note_tag = pkg_object_key(obj);
		const char *note_val = pkg_object_string(obj);

		ret = pkg_repo_binary_run_prstatement(ANNOTATE1, note_tag);
		if (ret == SQLITE_DONE)
			ret = pkg_repo_binary_run_prstatement(ANNOTATE1, note_val);
		if (ret == SQLITE_DONE)
			ret = pkg_repo_binary_run_prstatement(ANNOTATE2, package_id,
				  note_tag, note_val);
		if (ret != SQLITE_DONE) {
			ERROR_SQLITE(sqlite, pkg_repo_binary_sql_prstatement(ANNOTATE2));
			return (EPKG_FATAL);
		}
	}

	return (EPKG_OK);
}
Пример #4
0
void
test_manifest(void)
{
	struct pkg *p = NULL;
	struct pkg_dep *dep = NULL;
	struct pkg_conflict *conflict = NULL;
	struct pkg_option *option = NULL;
	struct pkg_category *category = NULL;
	struct pkg_file *file = NULL;
        struct pkg_manifest_key *keys = NULL;
	const char *pkg_str;
	int64_t pkg_int;
	int i;

	pkg_manifest_keys_new(&keys);
	ATF_REQUIRE(keys != NULL);

	ATF_REQUIRE_EQ(EPKG_OK, pkg_new(&p, PKG_FILE));
	ATF_REQUIRE(p != NULL);
	ATF_REQUIRE_EQ(EPKG_OK, pkg_parse_manifest(p, manifest, strlen(manifest), keys));

	pkg_manifest_keys_free(keys);

	ATF_REQUIRE(pkg_get(p, PKG_NAME, &pkg_str) == EPKG_OK);
	ATF_REQUIRE(strcmp(pkg_str, "foobar") == 0);

	ATF_REQUIRE(pkg_get(p, PKG_VERSION, &pkg_str) == EPKG_OK);
	ATF_REQUIRE(strcmp(pkg_str, "0.3") == 0);

	ATF_REQUIRE(pkg_get(p, PKG_ORIGIN, &pkg_str) == EPKG_OK);
	ATF_REQUIRE(strcmp(pkg_str, "foo/bar") == 0);

	ATF_REQUIRE(pkg_get(p, PKG_COMMENT, &pkg_str) == EPKG_OK);
	ATF_REQUIRE(strcmp(pkg_str, "A dummy manifest") == 0);

	ATF_REQUIRE(pkg_get(p, PKG_ARCH, &pkg_str) == EPKG_OK);
	ATF_REQUIRE(strcmp(pkg_str, "amd64") == 0);

	ATF_REQUIRE(pkg_get(p, PKG_WWW, &pkg_str) == EPKG_OK);
	ATF_REQUIRE(strcmp(pkg_str, "http://www.foobar.com") == 0);

	ATF_REQUIRE(pkg_get(p, PKG_MAINTAINER, &pkg_str) == EPKG_OK);
	ATF_REQUIRE(strcmp(pkg_str, "*****@*****.**") == 0);

	ATF_REQUIRE(pkg_get(p, PKG_PREFIX, &pkg_str) == EPKG_OK);
	ATF_REQUIRE(strcmp(pkg_str, "/opt/prefix") == 0);

	ATF_REQUIRE(pkg_get(p, PKG_DESC, &pkg_str) == EPKG_OK);
	ATF_REQUIRE(strcmp(pkg_str, "port description") == 0);

	ATF_REQUIRE(pkg_get(p, PKG_MESSAGE, &pkg_str) == EPKG_OK);
	ATF_REQUIRE(strcmp(pkg_str, "pkg message") == 0);

	ATF_REQUIRE(pkg_get(p, PKG_FLATSIZE, &pkg_int) == EPKG_OK);
	ATF_REQUIRE(pkg_int == 10000);

	i = 0;
	while (pkg_deps(p, &dep) == EPKG_OK) {
		if (i == 0) {
			ATF_REQUIRE(strcmp(pkg_dep_name(dep), "depfoo") == 0);
			ATF_REQUIRE(strcmp(pkg_dep_origin(dep), "dep/foo") == 0);
			ATF_REQUIRE(strcmp(pkg_dep_version(dep), "1.2") == 0);
		} else if (i == 1) {
			ATF_REQUIRE(strcmp(pkg_dep_name(dep), "depbar") == 0);
			ATF_REQUIRE(strcmp(pkg_dep_origin(dep), "dep/bar") == 0);
			ATF_REQUIRE(strcmp(pkg_dep_version(dep), "3.4") == 0);
		}
		i++;
	}
	ATF_REQUIRE(i == 2);

	i = 0;
#if 0
	while (pkg_conflicts(p, &conflict) == EPKG_OK) {
		if (i == 0) {
			ATF_REQUIRE(strcmp(pkg_conflict_glob(conflict), "foo-*") == 0);
		} else if (i == 1) {
			ATF_REQUIRE(strcmp(pkg_conflict_glob(conflict), "bar-*") == 0);
		}
		i++;
	}
	ATF_REQUIRE(i == 2);
#endif

	i = 0;
	while (pkg_options(p, &option) == EPKG_OK) {
		if (i == 0) {
			ATF_REQUIRE(strcmp(pkg_option_opt(option), "foo") == 0);
			ATF_REQUIRE(strcmp(pkg_option_value(option), "true") == 0);
		} else if (i == 1) {
			ATF_REQUIRE(strcmp(pkg_option_opt(option), "bar") == 0);
			ATF_REQUIRE(strcmp(pkg_option_value(option), "false") == 0);
		}
		i++;
	}
	ATF_REQUIRE(i == 2);

	i = 0;
	while (pkg_categories(p, &category) == EPKG_OK) {
		if (i == 0) {
			ATF_REQUIRE(strcmp(pkg_category_name(category), "foo") == 0);
		} else if (i == 1) {
			ATF_REQUIRE(strcmp(pkg_category_name(category), "bar") == 0);
		}
		i++;
	}
	ATF_REQUIRE(i == 2);

	ATF_REQUIRE(pkg_files(p, &file) == EPKG_OK);
	ATF_REQUIRE(strcmp(pkg_file_path(file), "/usr/local/bin/foo") ==
				0);
#if 0
	ATF_REQUIRE(strcmp(pkg_file_sha256(file),
				"01ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546b")
				== 0);
#endif
	pkg_free(p);
/*	p = NULL;

	ATF_REQUIRE(pkg_new(&p, PKG_FILE) == EPKG_OK);
	ATF_REQUIRE(pkg_parse_manifest(p, wrong_manifest1) == EPKG_FATAL);

	pkg_free(p);
	p = NULL;

	ATF_REQUIRE(pkg_new(&p, PKG_FILE) == EPKG_OK);
	ATF_REQUIRE(pkg_parse_manifest(p, wrong_manifest2) == EPKG_FATAL);

	pkg_free(p);
	p = NULL;

	ATF_REQUIRE(pkg_new(&p, PKG_FILE) == EPKG_OK);
	ATF_REQUIRE(pkg_parse_manifest(p, wrong_manifest3) == EPKG_FATAL);

	pkg_free(p);
	p = NULL;

	ATF_REQUIRE(pkg_new(&p, PKG_FILE) == EPKG_OK);
	ATF_REQUIRE(pkg_parse_manifest(p, wrong_manifest4) == EPKG_FATAL);
	pkg_free(p);
*/
}
Пример #5
0
void
test_manifest(void)
{
	struct pkg *p = NULL;
	struct pkg_dep *dep = NULL;
	struct pkg_conflict *conflict = NULL;
	struct pkg_option *option = NULL;
	struct pkg_file *file = NULL;
	int i;

	ATF_REQUIRE_EQ(EPKG_OK, pkg_new(&p, PKG_FILE));
	ATF_REQUIRE(p != NULL);
	ATF_REQUIRE_EQ(EPKG_OK, pkg_parse_manifest(p, manifest));

#if 0
	ATF_REQUIRE(strcmp(pkg_get(p, PKG_NAME), "foobar") == 0);
	ATF_REQUIRE(strcmp(pkg_get(p, PKG_VERSION), "0.3") == 0);
	ATF_REQUIRE(strcmp(pkg_get(p, PKG_ORIGIN), "foo/bar") == 0);
	ATF_REQUIRE(strcmp(pkg_get(p, PKG_COMMENT), "A dummy manifest") == 0);
	ATF_REQUIRE(strcmp(pkg_get(p, PKG_ARCH), "amd64") == 0);
	ATF_REQUIRE(strcmp(pkg_get(p, PKG_VERSION), "800500") == 0);
	ATF_REQUIRE(strcmp(pkg_get(p, PKG_WWW), "http://www.foobar.com") == 0);
	ATF_REQUIRE(strcmp(pkg_get(p, PKG_MAINTAINER), "*****@*****.**") == 0);
#endif

	i = 0;
	while (pkg_deps(p, &dep) == EPKG_OK) {
		if (i == 0) {
			ATF_REQUIRE(strcmp(pkg_dep_name(dep), "depfoo") == 0);
			ATF_REQUIRE(strcmp(pkg_dep_origin(dep), "dep/foo") == 0);
			ATF_REQUIRE(strcmp(pkg_dep_version(dep), "1.2") == 0);
		} else if (i == 1) {
			ATF_REQUIRE(strcmp(pkg_dep_name(dep), "depbar") == 0);
			ATF_REQUIRE(strcmp(pkg_dep_origin(dep), "dep/bar") == 0);
			ATF_REQUIRE(strcmp(pkg_dep_version(dep), "3.4") == 0);
		}
		i++;
	}
	ATF_REQUIRE(i == 2);

	i = 0;
#if 0
	while (pkg_conflicts(p, &conflict) == EPKG_OK) {
		if (i == 0) {
			ATF_REQUIRE(strcmp(pkg_conflict_glob(conflict), "foo-*") == 0);
		} else if (i == 1) {
			ATF_REQUIRE(strcmp(pkg_conflict_glob(conflict), "bar-*") == 0);
		}
		i++;
	}
	ATF_REQUIRE(i == 2);
#endif

	i = 0;
	while (pkg_options(p, &option) == EPKG_OK) {
		if (i == 0) {
			ATF_REQUIRE(strcmp(pkg_option_opt(option), "foo") == 0);
			ATF_REQUIRE(strcmp(pkg_option_value(option), "true") == 0);
		} else if (i == 1) {
			ATF_REQUIRE(strcmp(pkg_option_opt(option), "bar") == 0);
			ATF_REQUIRE(strcmp(pkg_option_value(option), "false") == 0);
		}
		i++;
	}
	ATF_REQUIRE(i == 2);

	ATF_REQUIRE(pkg_files(p, &file) == EPKG_OK);
	ATF_REQUIRE(strcmp(pkg_file_path(file), "/usr/local/bin/foo") ==
				0);
#if 0
	ATF_REQUIRE(strcmp(pkg_file_sha256(file),
				"01ba4719c80b6fe911b091a7c05124b64eeece964e09c058ef8f9805daca546b")
				== 0);
#endif
	pkg_free(p);
/*	p = NULL;

	ATF_REQUIRE(pkg_new(&p, PKG_FILE) == EPKG_OK);
	ATF_REQUIRE(pkg_parse_manifest(p, wrong_manifest1) == EPKG_FATAL);

	pkg_free(p);
	p = NULL;

	ATF_REQUIRE(pkg_new(&p, PKG_FILE) == EPKG_OK);
	ATF_REQUIRE(pkg_parse_manifest(p, wrong_manifest2) == EPKG_FATAL);

	pkg_free(p);
	p = NULL;

	ATF_REQUIRE(pkg_new(&p, PKG_FILE) == EPKG_OK);
	ATF_REQUIRE(pkg_parse_manifest(p, wrong_manifest3) == EPKG_FATAL);

	pkg_free(p);
	p = NULL;

	ATF_REQUIRE(pkg_new(&p, PKG_FILE) == EPKG_OK);
	ATF_REQUIRE(pkg_parse_manifest(p, wrong_manifest4) == EPKG_FATAL);
	pkg_free(p);
*/
}
Пример #6
0
int
pkg_create_repo(char *path, bool force,
    void (progress)(struct pkg *pkg, void *data), void *data)
{
	FTS *fts = NULL;
	struct thd_data thd_data;
	int num_workers;
	size_t len;
	pthread_t *tids = NULL;

	struct pkg_dep *dep = NULL;
	struct pkg_category *category = NULL;
	struct pkg_license *license = NULL;
	struct pkg_option *option = NULL;
	struct pkg_shlib *shlib = NULL;

	sqlite3 *sqlite = NULL;

	int64_t package_id;
	char *errmsg = NULL;
	int retcode = EPKG_OK;
	int ret;

	char *repopath[2];
	char repodb[MAXPATHLEN + 1];
	char repopack[MAXPATHLEN + 1];

	struct archive *a = NULL;
	struct archive_entry *ae = NULL;

	if (!is_dir(path)) {
		pkg_emit_error("%s is not a directory", path);
		return (EPKG_FATAL);
	}

	repopath[0] = path;
	repopath[1] = NULL;

	len = sizeof(num_workers);
	if (sysctlbyname("hw.ncpu", &num_workers, &len, NULL, 0) == -1)
		num_workers = 6;

	if ((fts = fts_open(repopath, FTS_PHYSICAL|FTS_NOCHDIR, NULL)) == NULL) {
		pkg_emit_errno("fts_open", path);
		retcode = EPKG_FATAL;
		goto cleanup;
	}

	snprintf(repodb, sizeof(repodb), "%s/repo.sqlite", path);
	snprintf(repopack, sizeof(repopack), "%s/repo.txz", path);

	if (access(repopack, F_OK) == 0) {
		a = archive_read_new();
		archive_read_support_compression_all(a);
		archive_read_support_format_tar(a);
		ret = archive_read_open_filename(a, repopack, 4096);
		if (ret != ARCHIVE_OK) {
			/* if we can't unpack it it won't be useful for us */
			unlink(repopack);
		} else {
			while (archive_read_next_header(a, &ae) == ARCHIVE_OK) {
				if (!strcmp(archive_entry_pathname(ae),
				    "repo.sqlite")) {
					archive_entry_set_pathname(ae, repodb);
					archive_read_extract(a, ae,
					    EXTRACT_ARCHIVE_FLAGS);
					break;
				}
			}
		}
		if (a != NULL)
			archive_read_finish(a);
	}

	if ((retcode = initialize_repo(repodb, force, &sqlite)) != EPKG_OK)
		goto cleanup;

	if ((retcode = initialize_prepared_statements(sqlite)) != EPKG_OK)
		goto cleanup;

	thd_data.root_path = path;
	thd_data.max_results = num_workers;
	thd_data.num_results = 0;
	thd_data.stop = false;
	thd_data.fts = fts;
	pthread_mutex_init(&thd_data.fts_m, NULL);
	STAILQ_INIT(&thd_data.results);
	thd_data.thd_finished = 0;
	pthread_mutex_init(&thd_data.results_m, NULL);
	pthread_cond_init(&thd_data.has_result, NULL);
	pthread_cond_init(&thd_data.has_room, NULL);

	/* Launch workers */
	tids = calloc(num_workers, sizeof(pthread_t));
	for (int i = 0; i < num_workers; i++) {
		pthread_create(&tids[i], NULL, (void *)&read_pkg_file, &thd_data);
	}

	for (;;) {
		struct pkg_result *r;

		const char *name, *version, *origin, *comment, *desc;
		const char *arch, *maintainer, *www, *prefix;
		int64_t flatsize;
		lic_t licenselogic;

		pthread_mutex_lock(&thd_data.results_m);
		while ((r = STAILQ_FIRST(&thd_data.results)) == NULL) {
			if (thd_data.thd_finished == num_workers) {
				break;
			}
			pthread_cond_wait(&thd_data.has_result, &thd_data.results_m);
		}
		if (r != NULL) {
			STAILQ_REMOVE_HEAD(&thd_data.results, next);
			thd_data.num_results--;
			pthread_cond_signal(&thd_data.has_room);
		}
		pthread_mutex_unlock(&thd_data.results_m);
		if (r == NULL) {
			break;
		}

		if (r->retcode != EPKG_OK) {
			continue;
		}

		/* do not add if package if already in repodb
		   (possibly at a different pkg_path) */

		if (run_prepared_statement(EXISTS, r->cksum) != SQLITE_ROW) {
			ERROR_SQLITE(sqlite);
			goto cleanup;
		}
		if (sqlite3_column_int(STMT(EXISTS), 0) > 0) {
			continue;
		}

		if (progress != NULL)
			progress(r->pkg, data);

		pkg_get(r->pkg, PKG_ORIGIN, &origin, PKG_NAME, &name,
		    PKG_VERSION, &version, PKG_COMMENT, &comment,
		    PKG_DESC, &desc, PKG_ARCH, &arch,
		    PKG_MAINTAINER, &maintainer, PKG_WWW, &www,
		    PKG_PREFIX, &prefix, PKG_FLATSIZE, &flatsize,
		    PKG_LICENSE_LOGIC, &licenselogic);

	try_again:
		if ((ret = run_prepared_statement(PKG, origin, name, version,
		    comment, desc, arch, maintainer, www, prefix,
		    r->size, flatsize, (int64_t)licenselogic, r->cksum,
		    r->path)) != SQLITE_DONE) {
			if (ret == SQLITE_CONSTRAINT) {
				switch(maybe_delete_conflicting(origin,
				    version, r->path)) {
				case EPKG_FATAL: /* sqlite error */
					ERROR_SQLITE(sqlite);
					retcode = EPKG_FATAL;
					goto cleanup;
					break;
				case EPKG_END: /* repo already has newer */
					continue;
					break;
				default: /* conflict cleared, try again */
					goto try_again;
					break;
				}
			} else {
				ERROR_SQLITE(sqlite);
				retcode = EPKG_FATAL;
				goto cleanup;
			}
		}

		package_id = sqlite3_last_insert_rowid(sqlite);

		dep = NULL;
		while (pkg_deps(r->pkg, &dep) == EPKG_OK) {
			if (run_prepared_statement(DEPS,
			    pkg_dep_origin(dep),
			    pkg_dep_name(dep),
			    pkg_dep_version(dep),
			    package_id) != SQLITE_DONE) {
				ERROR_SQLITE(sqlite);
				retcode = EPKG_FATAL;
				goto cleanup;
			}
		}

		category = NULL;
		while (pkg_categories(r->pkg, &category) == EPKG_OK) {
			const char *cat_name = pkg_category_name(category);

			ret = run_prepared_statement(CAT1, cat_name);
			if (ret == SQLITE_DONE)
			    ret = run_prepared_statement(CAT2, package_id,
			        cat_name);
			if (ret != SQLITE_DONE)
			{
				ERROR_SQLITE(sqlite);
				retcode = EPKG_FATAL;
				goto cleanup;
			}
		}

		license = NULL;
		while (pkg_licenses(r->pkg, &license) == EPKG_OK) {
			const char *lic_name = pkg_license_name(license);

			ret = run_prepared_statement(LIC1, lic_name);
			if (ret == SQLITE_DONE)
				ret = run_prepared_statement(LIC2, package_id,
				    lic_name);
			if (ret != SQLITE_DONE) {
				ERROR_SQLITE(sqlite);
				retcode = EPKG_FATAL;
				goto cleanup;
			}
		}
		option = NULL;
		while (pkg_options(r->pkg, &option) == EPKG_OK) {
			if (run_prepared_statement(OPTS,
			    pkg_option_opt(option),
			    pkg_option_value(option),
			    package_id) != SQLITE_DONE) {
				ERROR_SQLITE(sqlite);
				retcode = EPKG_FATAL;
				goto cleanup;
			}
		}

		shlib = NULL;
		while (pkg_shlibs(r->pkg, &shlib) == EPKG_OK) {
			const char *shlib_name = pkg_shlib_name(shlib);

			ret = run_prepared_statement(SHLIB1, shlib_name);
			if (ret == SQLITE_DONE)
			    ret = run_prepared_statement(SHLIB2, package_id,
			        shlib_name);
			if (ret != SQLITE_DONE)
			{
				ERROR_SQLITE(sqlite);
				retcode = EPKG_FATAL;
				goto cleanup;
			}
		}

		pkg_free(r->pkg);
		free(r);
	}

	if (pkgdb_transaction_commit(sqlite, NULL) != SQLITE_OK)
		retcode = EPKG_FATAL;

	cleanup:

	if (tids != NULL) {
		// Cancel running threads
		if (retcode != EPKG_OK) {
			pthread_mutex_lock(&thd_data.fts_m);
			thd_data.stop = true;
			pthread_mutex_unlock(&thd_data.fts_m);
		}
		// Join on threads to release thread IDs
		for (int i = 0; i < num_workers; i++) {
			pthread_join(tids[i], NULL);
		}
		free(tids);
	}

	if (fts != NULL)
		fts_close(fts);

	finalize_prepared_statements();

	if (sqlite != NULL)
		sqlite3_close(sqlite);

	if (errmsg != NULL)
		sqlite3_free(errmsg);

	sqlite3_shutdown();

	return (retcode);
}
Пример #7
0
int
pkg_create_repo(char *path, void (progress)(struct pkg *pkg, void *data), void *data)
{
	FTS *fts = NULL;
	FTSENT *ent = NULL;

	struct stat st;
	struct pkg *pkg = NULL;
	struct pkg_dep *dep = NULL;
	struct pkg_category *category = NULL;
	struct pkg_license *license = NULL;
	struct pkg_option *option = NULL;
	struct sbuf *manifest = sbuf_new_auto();
	char *ext = NULL;

	sqlite3 *sqlite = NULL;
	sqlite3_stmt *stmt_deps = NULL;
	sqlite3_stmt *stmt_pkg = NULL;
	sqlite3_stmt *stmt_lic1 = NULL;
	sqlite3_stmt *stmt_lic2 = NULL;
	sqlite3_stmt *stmt_cat1 = NULL;
	sqlite3_stmt *stmt_cat2 = NULL;
	sqlite3_stmt *stmt_opts = NULL;

	int64_t package_id;
	char *errmsg = NULL;
	int retcode = EPKG_OK;
	char *pkg_path;
	char cksum[SHA256_DIGEST_LENGTH * 2 +1];

	char *repopath[2];
	char repodb[MAXPATHLEN + 1];

	const char initsql[] = ""
		"CREATE TABLE packages ("
			"id INTEGER PRIMARY KEY,"
			"origin TEXT UNIQUE,"
			"name TEXT NOT NULL,"
			"version TEXT NOT NULL,"
			"comment TEXT NOT NULL,"
			"desc TEXT NOT NULL,"
			"arch TEXT NOT NULL,"
			"osversion TEXT NOT NULL,"
			"maintainer TEXT NOT NULL,"
			"www TEXT,"
			"prefix TEXT NOT NULL,"
			"pkgsize INTEGER NOT NULL,"
			"flatsize INTEGER NOT NULL,"
			"licenselogic INTEGER NOT NULL,"
			"cksum TEXT NOT NULL,"
			"path TEXT NOT NULL," /* relative path to the package in the repository */
			"pkg_format_version INTEGER"
		");"
		"CREATE TABLE deps ("
			"origin TEXT,"
			"name TEXT,"
			"version TEXT,"
			"package_id INTEGER REFERENCES packages(id),"
			"UNIQUE(package_id, origin)"
		");"
		"CREATE TABLE categories ("
			"id INTEGER PRIMARY KEY, "
			"name TEXT NOT NULL UNIQUE "
		");"
		"CREATE TABLE pkg_categories ("
			"package_id INTEGER REFERENCES packages(id), "
			"category_id INTEGER REFERENCES categories(id), "
			"UNIQUE(package_id, category_id)"
		");"
		"CREATE TABLE licenses ("
			"id INTEGER PRIMARY KEY,"
			"name TEXT NOT NULL UNIQUE"
		");"
		"CREATE TABLE pkg_licenses ("
			"package_id INTEGER REFERENCES packages(id), "
			"license_id INTEGER REFERENCES licenses(id), "
			"UNIQUE(package_id, license_id)"
		");"
		"CREATE TABLE options ("
			"package_id INTEGER REFERENCES packages(id), "
			"option TEXT,"
			"value TEXT,"
			"UNIQUE (package_id, option)"
		");"
		"PRAGMA user_version=2;"
		;
	const char pkgsql[] = ""
		"INSERT INTO packages ("
				"origin, name, version, comment, desc, arch, osversion, "
				"maintainer, www, prefix, pkgsize, flatsize, licenselogic, cksum, path"
		")"
		"VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13, ?14, ?15);";
	const char depssql[] = ""
		"INSERT INTO deps (origin, name, version, package_id) "
		"VALUES (?1, ?2, ?3, ?4);";
	const char licsql[] = "INSERT OR IGNORE INTO licenses(name) VALUES(?1);";
	const char addlicsql[] = "INSERT OR ROLLBACK INTO pkg_licenses(package_id, license_id) "
		"VALUES (?1, (SELECT id FROM licenses WHERE name = ?2));";
	const char catsql[] = "INSERT OR IGNORE INTO categories(name) VALUES(?1);";
	const char addcatsql[] = "INSERT OR ROLLBACK INTO pkg_categories(package_id, category_id) "
		"VALUES (?1, (SELECT id FROM categories WHERE name = ?2));";
	const char addoption[] = "INSERT OR ROLLBACK INTO options (option, value, package_id) "
		"VALUES (?1, ?2, ?3);";

	if (!is_dir(path)) {
		pkg_emit_error("%s is not a directory", path);
		return EPKG_FATAL;
	}

	repopath[0] = path;
	repopath[1] = NULL;

	snprintf(repodb, sizeof(repodb), "%s/repo.sqlite", path);

	if (stat(repodb, &st) != -1)
		if (unlink(repodb) != 0) {
			pkg_emit_errno("unlink", path);
			return EPKG_FATAL;
		}

	sqlite3_initialize();
	if (sqlite3_open(repodb, &sqlite) != SQLITE_OK) {
		sqlite3_shutdown();
		return (EPKG_FATAL);
	}
	
	if ((retcode = sql_exec(sqlite, initsql)) != EPKG_OK)
		goto cleanup;

	if ((retcode = sql_exec(sqlite, "BEGIN TRANSACTION;")) != EPKG_OK)
		goto cleanup;

	if (sqlite3_prepare_v2(sqlite, pkgsql, -1, &stmt_pkg, NULL) != SQLITE_OK) {
		ERROR_SQLITE(sqlite);
		retcode = EPKG_FATAL;
		goto cleanup;
	}

	if (sqlite3_prepare_v2(sqlite, depssql, -1, &stmt_deps, NULL) != SQLITE_OK) {
		ERROR_SQLITE(sqlite);
		retcode = EPKG_FATAL;
		goto cleanup;
	}

	if (sqlite3_prepare_v2(sqlite, licsql, -1, &stmt_lic1, NULL) != SQLITE_OK) {
		ERROR_SQLITE(sqlite);
		retcode = EPKG_FATAL;
		goto cleanup;
	}

	if (sqlite3_prepare_v2(sqlite, addlicsql, -1, &stmt_lic2, NULL) != SQLITE_OK) {
		ERROR_SQLITE(sqlite);
		retcode = EPKG_FATAL;
		goto cleanup;
	}

	if (sqlite3_prepare_v2(sqlite, addoption, -1, &stmt_opts, NULL) != SQLITE_OK) {
		ERROR_SQLITE(sqlite);
		retcode = EPKG_FATAL;
		goto cleanup;
	}

	if ((fts = fts_open(repopath, FTS_PHYSICAL, NULL)) == NULL) {
		pkg_emit_errno("fts_open", path);
		retcode = EPKG_FATAL;
		goto cleanup;
	}

	if (sqlite3_prepare_v2(sqlite, catsql, -1, &stmt_cat1, NULL) != SQLITE_OK) {
		ERROR_SQLITE(sqlite);
		retcode = EPKG_FATAL;
		goto cleanup;
	}

	if (sqlite3_prepare_v2(sqlite, addcatsql, -1, &stmt_cat2, NULL) != SQLITE_OK) {
		ERROR_SQLITE(sqlite);
		retcode = EPKG_FATAL;
		goto cleanup;
	}

	while ((ent = fts_read(fts)) != NULL) {
		cksum[0] = '\0';
		/* skip everything that is not a file */
		if (ent->fts_info != FTS_F)
			continue;

		ext = strrchr(ent->fts_name, '.');

		if (ext == NULL)
			continue;

		if (strcmp(ext, ".tgz") != 0 &&
				strcmp(ext, ".tbz") != 0 &&
				strcmp(ext, ".txz") != 0 &&
				strcmp(ext, ".tar") != 0)
			continue;

		pkg_path = ent->fts_path;
		pkg_path += strlen(path);
		while (pkg_path[0] == '/' )
			pkg_path++;

		if (pkg_open(&pkg, ent->fts_accpath, manifest) != EPKG_OK) {
			retcode = EPKG_WARN;
			continue;
		}
		if (progress != NULL)
			progress(pkg, data);

		sqlite3_bind_text(stmt_pkg, 1, pkg_get(pkg, PKG_ORIGIN), -1, SQLITE_STATIC);
		sqlite3_bind_text(stmt_pkg, 2, pkg_get(pkg, PKG_NAME), -1, SQLITE_STATIC);
		sqlite3_bind_text(stmt_pkg, 3, pkg_get(pkg, PKG_VERSION), -1, SQLITE_STATIC);
		sqlite3_bind_text(stmt_pkg, 4, pkg_get(pkg, PKG_COMMENT), -1, SQLITE_STATIC);
		sqlite3_bind_text(stmt_pkg, 5, pkg_get(pkg, PKG_DESC), -1, SQLITE_STATIC);
		sqlite3_bind_text(stmt_pkg, 6, pkg_get(pkg, PKG_ARCH), -1, SQLITE_STATIC);
		sqlite3_bind_text(stmt_pkg, 7, pkg_get(pkg, PKG_OSVERSION), -1, SQLITE_STATIC);
		sqlite3_bind_text(stmt_pkg, 8, pkg_get(pkg, PKG_MAINTAINER), -1, SQLITE_STATIC);
		sqlite3_bind_text(stmt_pkg, 9, pkg_get(pkg, PKG_WWW), -1, SQLITE_STATIC);
		sqlite3_bind_text(stmt_pkg, 10, pkg_get(pkg, PKG_PREFIX), -1, SQLITE_STATIC);
		sqlite3_bind_int64(stmt_pkg, 11, ent->fts_statp->st_size);
		sqlite3_bind_int64(stmt_pkg, 12, pkg_flatsize(pkg));
		sha256_file(ent->fts_accpath, cksum);
		sqlite3_bind_int64(stmt_pkg, 13, pkg_licenselogic(pkg));
		sqlite3_bind_text(stmt_pkg, 14, cksum, -1, SQLITE_STATIC);
		sqlite3_bind_text(stmt_pkg, 15, pkg_path, -1, SQLITE_STATIC);

		if (sqlite3_step(stmt_pkg) != SQLITE_DONE) {
			ERROR_SQLITE(sqlite);
			retcode = EPKG_FATAL;
			goto cleanup;
		}
		sqlite3_reset(stmt_pkg);

		package_id = sqlite3_last_insert_rowid(sqlite);

		dep = NULL;
		while (pkg_deps(pkg, &dep) == EPKG_OK) {
			sqlite3_bind_text(stmt_deps, 1, pkg_dep_origin(dep), -1, SQLITE_STATIC);
			sqlite3_bind_text(stmt_deps, 2, pkg_dep_name(dep), -1, SQLITE_STATIC);
			sqlite3_bind_text(stmt_deps, 3, pkg_dep_version(dep), -1, SQLITE_STATIC);
			sqlite3_bind_int64(stmt_deps, 4, package_id);

			if (sqlite3_step(stmt_deps) != SQLITE_DONE) {
				ERROR_SQLITE(sqlite);
				retcode = EPKG_FATAL;
				goto cleanup;
			}
			sqlite3_reset(stmt_deps);
		}

		category = NULL;
		while (pkg_categories(pkg, &category) == EPKG_OK) {
			sqlite3_bind_text(stmt_cat1, 1, pkg_category_name(category), -1, SQLITE_STATIC);
			sqlite3_bind_int64(stmt_cat2, 1, package_id);
			sqlite3_bind_text(stmt_cat2, 2, pkg_category_name(category), -1, SQLITE_STATIC);

			if (sqlite3_step(stmt_cat1) != SQLITE_DONE) {
				ERROR_SQLITE(sqlite);
				retcode = EPKG_FATAL;
				goto cleanup;
			}

			if (sqlite3_step(stmt_cat2) != SQLITE_DONE) {
				ERROR_SQLITE(sqlite);
				retcode = EPKG_FATAL;
				goto cleanup;
			}
			sqlite3_reset(stmt_cat1);
			sqlite3_reset(stmt_cat2);
		}

		license = NULL;
		while (pkg_licenses(pkg, &license) == EPKG_OK) {
			sqlite3_bind_text(stmt_lic1, 1, pkg_license_name(license), -1, SQLITE_STATIC);
			sqlite3_bind_int64(stmt_lic2, 1, package_id);
			sqlite3_bind_text(stmt_lic2, 2, pkg_license_name(license), -1, SQLITE_STATIC);

			if (sqlite3_step(stmt_lic1) != SQLITE_DONE) {
				ERROR_SQLITE(sqlite);
				retcode = EPKG_FATAL;
				goto cleanup;
			}

			if (sqlite3_step(stmt_lic2) != SQLITE_DONE) {
				ERROR_SQLITE(sqlite);
				retcode = EPKG_FATAL;
				goto cleanup;
			}
			sqlite3_reset(stmt_lic1);
			sqlite3_reset(stmt_lic2);
		}
		option = NULL;
		while (pkg_options(pkg, &option) == EPKG_OK) {
			sqlite3_bind_text(stmt_opts, 1, pkg_option_opt(option), -1, SQLITE_STATIC);
			sqlite3_bind_text(stmt_opts, 2, pkg_option_value(option), -1, SQLITE_STATIC);
			sqlite3_bind_int64(stmt_opts, 3, package_id);

			if (sqlite3_step(stmt_opts) != SQLITE_DONE) {
				ERROR_SQLITE(sqlite);
				retcode = EPKG_FATAL;
				goto cleanup;
			}
			sqlite3_reset(stmt_opts);
		}
	}

	if (sqlite3_exec(sqlite, "COMMIT;", NULL, NULL, &errmsg) != SQLITE_OK) {
		pkg_emit_error("sqlite: %s", errmsg);
		retcode = EPKG_FATAL;
	}

	cleanup:
	if (fts != NULL)
		fts_close(fts);

	if (pkg != NULL)
		pkg_free(pkg);

	if (stmt_pkg != NULL)
		sqlite3_finalize(stmt_pkg);

	if (stmt_deps != NULL)
		sqlite3_finalize(stmt_deps);

	if (stmt_cat1 != NULL)
		sqlite3_finalize(stmt_cat1);

	if (stmt_cat2 != NULL)
		sqlite3_finalize(stmt_cat2);

	if (stmt_lic1 != NULL)
		sqlite3_finalize(stmt_lic1);

	if (stmt_lic2 != NULL)
		sqlite3_finalize(stmt_lic2);

	if (stmt_opts != NULL)
		sqlite3_finalize(stmt_opts);

	if (sqlite != NULL)
		sqlite3_close(sqlite);

	if (errmsg != NULL)
		sqlite3_free(errmsg);

	sbuf_delete(manifest);

	sqlite3_shutdown();

	return (retcode);
}
Пример #8
0
int
pkg_old_emit_content(struct pkg *pkg, char **dest)
{
	struct sbuf *content = sbuf_new_auto();

	struct pkg_dep *dep = NULL;
	struct pkg_file *file = NULL;
	struct pkg_dir *dir = NULL;
	struct pkg_option *option = NULL;

	char option_type = 0;

	pkg_sbuf_printf(content,
	    "@comment PKG_FORMAT_REVISION:1.1\n"
	    "@name %n-%v\n"
	    "@comment ORIGIN:%o\n"
	    "@cwd %p\n"
	    /* hack because we can recreate the prefix split or origin */
	    "@cwd /\n", pkg, pkg, pkg, pkg);

	while (pkg_deps(pkg, &dep) == EPKG_OK) {
		sbuf_printf(content,
		    "@pkgdep %s-%s\n"
		    "@comment DEPORIGIN:%s\n",
		    pkg_dep_name(dep),
		    pkg_dep_version(dep),
		    pkg_dep_origin(dep));
	}

	while (pkg_files(pkg, &file) == EPKG_OK) {
		sbuf_printf(content,
		    "%s\n"
		    "@comment MD5:%s\n",
		     file->path + 1,
		     file->sum);
	}

	while (pkg_dirs(pkg, &dir) == EPKG_OK) {
		sbuf_printf(content,
		    "@unexec /sbin/rmdir \"%s\" 2>/dev/null\n",
		    dir->path);
	}

	sbuf_printf(content, "@comment OPTIONS:");
	while (pkg_options(pkg, &option) == EPKG_OK) {
		/* Add space for previous option, if not the first. */
		if (option_type != 0)
			sbuf_cat(content, " ");

		if (strcmp(pkg_option_value(option), "on") == 0)
			option_type = '+';
		else
			option_type = '-';
		sbuf_printf(content, "%c%s",
		    option_type,
		    pkg_option_opt(option));
	}
	sbuf_printf(content, "\n");

	sbuf_finish(content);
	*dest = strdup(sbuf_get(content));
	sbuf_delete(content);

	return (EPKG_OK);
}
Пример #9
0
Файл: query.c Проект: afb/pkgng
static void
format_str(struct pkg *pkg, struct sbuf *dest, const char *qstr, void *data)
{
	char size[7];
	const char *tmp;
	bool tmp2;
	int64_t flatsize;
	int64_t timestamp;
	lic_t licenselogic;

	sbuf_clear(dest);

	while (qstr[0] != '\0') {
		if (qstr[0] == '%') {
			qstr++;
			switch (qstr[0]) {
			case 'n':
				pkg_get(pkg, PKG_NAME, &tmp);
				if (tmp != NULL)
					sbuf_cat(dest, tmp);
				break;
			case 'v':
				pkg_get(pkg, PKG_VERSION, &tmp);
				if (tmp != NULL)
					sbuf_cat(dest, tmp);
				break;
			case 'o':
				pkg_get(pkg, PKG_ORIGIN, &tmp);
				if (tmp != NULL)
					sbuf_cat(dest, tmp);
				break;
			case 'R':
				pkg_get(pkg, PKG_REPONAME, &tmp);
				if (tmp != NULL)
					sbuf_cat(dest, tmp);
				break;
			case 'p':
				pkg_get(pkg, PKG_PREFIX, &tmp);
				if (tmp != NULL)
					sbuf_cat(dest, tmp);
				break;
			case 'm':
				pkg_get(pkg, PKG_MAINTAINER, &tmp);
				if (tmp != NULL)
					sbuf_cat(dest, tmp);
				break;
			case 'c':
				pkg_get(pkg, PKG_COMMENT, &tmp);
				if (tmp != NULL)
					sbuf_cat(dest, tmp);
				break;
			case 'w':
				pkg_get(pkg, PKG_WWW, &tmp);
				if (tmp != NULL)
					sbuf_cat(dest, tmp);
				break;
			case 'i':
				pkg_get(pkg, PKG_INFOS, &tmp);
				if (tmp != NULL)
					sbuf_cat(dest, tmp);
				break;
			case 'a':
				pkg_get(pkg, PKG_AUTOMATIC, &tmp2);
				sbuf_printf(dest, "%d", tmp2);
				break;
			case 'k':
				pkg_get(pkg, PKG_LOCKED, &tmp2);
				sbuf_printf(dest, "%d", tmp2);
				break;
			case 't':
				pkg_get(pkg, PKG_TIME, &timestamp);
				sbuf_printf(dest, "%" PRId64, timestamp);
				break;
			case 's':
				qstr++;
				pkg_get(pkg, PKG_FLATSIZE, &flatsize);
				if (qstr[0] == 'h') {
					humanize_number(size, sizeof(size),
					    flatsize, "B", HN_AUTOSCALE, 0);
					sbuf_cat(dest, size);
				} else if (qstr[0] == 'b') {
					sbuf_printf(dest, "%" PRId64, flatsize);
				}
				break;
			case 'e':
				pkg_get(pkg, PKG_DESC, &tmp);
				if (tmp != NULL)
					sbuf_cat(dest, tmp);
				break;
			case '?':
				qstr++;
				switch (qstr[0]) {
				case 'd':
					sbuf_printf(dest, "%d", pkg_list_count(pkg, PKG_DEPS) > 0);
					break;
				case 'r':
					sbuf_printf(dest, "%d", pkg_list_count(pkg, PKG_RDEPS) > 0);
					break;
				case 'C':
					sbuf_printf(dest, "%d", pkg_list_count(pkg, PKG_CATEGORIES) > 0);
					break;
				case 'F':
					sbuf_printf(dest, "%d", pkg_list_count(pkg, PKG_FILES) > 0);
					break;
				case 'O':
					sbuf_printf(dest, "%d", pkg_list_count(pkg, PKG_OPTIONS) > 0);
					break;
				case 'D':
					sbuf_printf(dest, "%d", pkg_list_count(pkg, PKG_DIRS) > 0);
					break;
				case 'L':
					sbuf_printf(dest, "%d", pkg_list_count(pkg, PKG_LICENSES) > 0);
					break;
				case 'U':
					sbuf_printf(dest, "%d", pkg_list_count(pkg, PKG_USERS) > 0);
					break;
				case 'G':
					sbuf_printf(dest, "%d", pkg_list_count(pkg, PKG_GROUPS) > 0);
					break;
				case 'B':
					sbuf_printf(dest, "%d", pkg_list_count(pkg, PKG_SHLIBS_REQUIRED) > 0);
					break;
				case 'b':
					sbuf_printf(dest, "%d", pkg_list_count(pkg, PKG_SHLIBS_PROVIDED) > 0);
					break;
				case 'A':
					sbuf_printf(dest, "%d", pkg_list_count(pkg, PKG_ANNOTATIONS) > 0);
					break;
				}
				break;
			case '#':
				qstr++;
				switch (qstr[0]) {
				case 'd':
					sbuf_printf(dest, "%d", pkg_list_count(pkg, PKG_DEPS));
					break;
				case 'r':
					sbuf_printf(dest, "%d", pkg_list_count(pkg, PKG_RDEPS));
					break;
				case 'C':
					sbuf_printf(dest, "%d", pkg_list_count(pkg, PKG_CATEGORIES));
					break;
				case 'F':
					sbuf_printf(dest, "%d", pkg_list_count(pkg, PKG_FILES));
					break;
				case 'O':
					sbuf_printf(dest, "%d", pkg_list_count(pkg, PKG_OPTIONS));
					break;
				case 'D':
					sbuf_printf(dest, "%d", pkg_list_count(pkg, PKG_DIRS));
					break;
				case 'L':
					sbuf_printf(dest, "%d", pkg_list_count(pkg, PKG_LICENSES));
					break;
				case 'U':
					sbuf_printf(dest, "%d", pkg_list_count(pkg, PKG_USERS));
					break;
				case 'G':
					sbuf_printf(dest, "%d", pkg_list_count(pkg, PKG_GROUPS));
					break;
				case 'B':
					sbuf_printf(dest, "%d", pkg_list_count(pkg, PKG_SHLIBS_REQUIRED));
					break;
				case 'b':
					sbuf_printf(dest, "%d", pkg_list_count(pkg, PKG_SHLIBS_PROVIDED));
					break;
				case 'A':
					sbuf_printf(dest, "%d", pkg_list_count(pkg, PKG_ANNOTATIONS));
					break;
				}
				break;
			case 'l':
				pkg_get(pkg, PKG_LICENSE_LOGIC, &licenselogic);
				switch (licenselogic) {
				case LICENSE_SINGLE:
					sbuf_cat(dest, "single");
					break;
				case LICENSE_OR:
					sbuf_cat(dest, "or");
					break;
				case LICENSE_AND:
					sbuf_cat(dest, "and");
					break;
				}
				break;
			case 'd':
				qstr++;
				if (qstr[0] == 'n')
					sbuf_cat(dest, pkg_dep_name((struct pkg_dep *)data));
				else if (qstr[0] == 'o')
					sbuf_cat(dest, pkg_dep_origin((struct pkg_dep *)data));
				else if (qstr[0] == 'v')
					sbuf_cat(dest, pkg_dep_version((struct pkg_dep *)data));
				break;
			case 'r':
				qstr++;
				if (qstr[0] == 'n')
					sbuf_cat(dest, pkg_dep_name((struct pkg_dep *)data));
				else if (qstr[0] == 'o')
					sbuf_cat(dest, pkg_dep_origin((struct pkg_dep *)data));
				else if (qstr[0] == 'v')
					sbuf_cat(dest, pkg_dep_version((struct pkg_dep *)data));
				break;
			case 'C':
				sbuf_cat(dest, pkg_category_name((struct pkg_category *)data));
				break;
			case 'F':
				qstr++;
				if (qstr[0] == 'p')
					sbuf_cat(dest, pkg_file_path((struct pkg_file *)data));
				else if (qstr[0] == 's')
					sbuf_cat(dest, pkg_file_cksum((struct pkg_file *)data));
				break;
			case 'O':
				qstr++;
				if (qstr[0] == 'k')
					sbuf_cat(dest, pkg_option_opt((struct pkg_option *)data));
				else if (qstr[0] == 'v')
					sbuf_cat(dest, pkg_option_value((struct pkg_option *)data));
				break;
			case 'D':
				sbuf_cat(dest, pkg_dir_path((struct pkg_dir *)data));
				break;
			case 'L':
				sbuf_cat(dest, pkg_license_name((struct pkg_license *)data));
				break;
			case 'U':
				sbuf_cat(dest, pkg_user_name((struct pkg_user *)data));
				break;
			case 'G':
				sbuf_cat(dest, pkg_group_name((struct pkg_group *)data));
				break;
			case 'B':
			case 'b':
				sbuf_cat(dest, pkg_shlib_name((struct pkg_shlib *)data));
				break;
			case 'A':
				qstr++;
				if (qstr[0] == 't')
					sbuf_cat(dest, pkg_annotation_tag((struct pkg_note *)data));
				else if (qstr[0] == 'v')
					sbuf_cat(dest, pkg_annotation_value((struct pkg_note *)data));
				break;
			case 'M':
				pkg_get(pkg, PKG_MESSAGE, &tmp);
				if (tmp != NULL)
					sbuf_cat(dest, tmp);
				break;
			case '%':
				sbuf_putc(dest, '%');
				break;
			}
		} else  if (qstr[0] == '\\') {
			qstr++;
			switch (qstr[0]) {
			case 'n':
				sbuf_putc(dest, '\n');
				break;
			case 'a':
				sbuf_putc(dest, '\a');
				break;
			case 'b':
				sbuf_putc(dest, '\b');
				break;
			case 'f':
				sbuf_putc(dest, '\f');
				break;
			case 'r':
				sbuf_putc(dest, '\r');
				break;
			case '\\':
				sbuf_putc(dest, '\\');
				break;
			case 't':
				sbuf_putc(dest, '\t');
				break;
			}
		} else {
			sbuf_putc(dest, qstr[0]);
		}
		qstr++;
	}
	sbuf_finish(dest);
}
Пример #10
0
int
pkg_add(struct pkgdb *db, const char *path, unsigned flags, struct pkg_manifest_key *keys)
{
	const char	*arch;
	const char	*origin;
	const char	*name;
	struct archive	*a;
	struct archive_entry *ae;
	struct pkg	*pkg = NULL;
	struct pkg_dep	*dep = NULL;
	struct pkg      *pkg_inst = NULL;
	bool		 extract = true;
	bool		 handle_rc = false;
	bool		 disable_mtree;
	char		 dpath[MAXPATHLEN];
	const char	*basedir;
	const char	*ext;
	char		*mtree;
	char		*prefix;
	int		 retcode = EPKG_OK;
	int		 ret;

	assert(path != NULL);

	/*
	 * Open the package archive file, read all the meta files and set the
	 * current archive_entry to the first non-meta file.
	 * If there is no non-meta files, EPKG_END is returned.
	 */
	ret = pkg_open2(&pkg, &a, &ae, path, keys, 0);
	if (ret == EPKG_END)
		extract = false;
	else if (ret != EPKG_OK) {
		retcode = ret;
		goto cleanup;
	}
	if ((flags & PKG_ADD_UPGRADE) == 0)
		pkg_emit_install_begin(pkg);

	if (pkg_is_valid(pkg) != EPKG_OK) {
		pkg_emit_error("the package is not valid");
		return (EPKG_FATAL);
	}

	if (flags & PKG_ADD_AUTOMATIC)
		pkg_set(pkg, PKG_AUTOMATIC, (int64_t)true);

	/*
	 * Check the architecture
	 */

	pkg_get(pkg, PKG_ARCH, &arch, PKG_ORIGIN, &origin, PKG_NAME, &name);

	if (!is_valid_abi(arch, true)) {
		if ((flags & PKG_ADD_FORCE) == 0) {
			retcode = EPKG_FATAL;
			goto cleanup;
		}
	}

	/*
	 * Check if the package is already installed
	 */

	ret = pkg_try_installed(db, origin, &pkg_inst, PKG_LOAD_BASIC);
	if (ret == EPKG_OK) {
		if ((flags & PKG_FLAG_FORCE) == 0) {
			pkg_emit_already_installed(pkg_inst);
			retcode = EPKG_INSTALLED;
			pkg_free(pkg_inst);
			pkg_inst = NULL;
			goto cleanup;
		}
		else {
			pkg_emit_notice("package %s is already installed, forced install", name);
			pkg_free(pkg_inst);
			pkg_inst = NULL;
		}
	} else if (ret != EPKG_END) {
		retcode = ret;
		goto cleanup;
	}

	/*
	 * Check for dependencies by searching the same directory as
	 * the package archive we're reading.  Of course, if we're
	 * reading from a file descriptor or a unix domain socket or
	 * somesuch, there's no valid directory to search.
	 */

	if (pkg_type(pkg) == PKG_FILE) {
		basedir = dirname(path);
		if ((ext = strrchr(path, '.')) == NULL) {
			pkg_emit_error("%s has no extension", path);
			retcode = EPKG_FATAL;
			goto cleanup;
		}
	} else {
		basedir = NULL;
		ext = NULL;
	}

	while (pkg_deps(pkg, &dep) == EPKG_OK) {
		if (pkg_is_installed(db, pkg_dep_origin(dep)) == EPKG_OK)
			continue;

		if (basedir != NULL) {
			const char *dep_name = pkg_dep_name(dep);
			const char *dep_ver = pkg_dep_version(dep);

			snprintf(dpath, sizeof(dpath), "%s/%s-%s%s", basedir,
			    dep_name, dep_ver, ext);

			if ((flags & PKG_ADD_UPGRADE) == 0 &&
			    access(dpath, F_OK) == 0) {
				ret = pkg_add(db, dpath, PKG_ADD_AUTOMATIC, keys);
				if (ret != EPKG_OK) {
					retcode = EPKG_FATAL;
					goto cleanup;
				}
			} else {
				pkg_emit_error("Missing dependency matching '%s'",
				    pkg_dep_get(dep, PKG_DEP_ORIGIN));
				retcode = EPKG_FATAL;
				goto cleanup;
			}
		} else {
			retcode = EPKG_FATAL;
			pkg_emit_missing_dep(pkg, dep);
			goto cleanup;
		}
	}

	/* register the package before installing it in case there are
	 * problems that could be caught here. */
	retcode = pkgdb_register_pkg(db, pkg, flags & PKG_ADD_UPGRADE, flags & PKG_FLAG_FORCE);

	if (retcode != EPKG_OK)
		goto cleanup;

	/* MTREE replicates much of the standard functionality
	 * inplicit in the way pkg works.  It has to remain available
	 * in the ports for compatibility with the old pkg_tools, but
	 * ultimately, MTREE should be made redundant.  Use this for
	 * experimantal purposes and to develop MTREE-free versions of
	 * packages. */

	pkg_config_bool(PKG_CONFIG_DISABLE_MTREE, &disable_mtree);
	if (!disable_mtree) {
		pkg_get(pkg, PKG_PREFIX, &prefix, PKG_MTREE, &mtree);
		if ((retcode = do_extract_mtree(mtree, prefix)) != EPKG_OK)
			goto cleanup_reg;
	}

	/*
	 * Execute pre-install scripts
	 */
	if ((flags & (PKG_ADD_NOSCRIPT | PKG_ADD_USE_UPGRADE_SCRIPTS)) == 0)
		pkg_script_run(pkg, PKG_SCRIPT_PRE_INSTALL);

	/* add the user and group if necessary */
	/* pkg_add_user_group(pkg); */

	/*
	 * Extract the files on disk.
	 */
	if (extract && (retcode = do_extract(a, ae)) != EPKG_OK) {
		/* If the add failed, clean up (silently) */
		pkg_delete_files(pkg, 2);
		pkg_delete_dirs(db, pkg, 1);
		goto cleanup_reg;
	}

	/*
	 * Execute post install scripts
	 */
	if ((flags & PKG_ADD_NOSCRIPT) == 0) {
		if ((flags & PKG_ADD_USE_UPGRADE_SCRIPTS) == PKG_ADD_USE_UPGRADE_SCRIPTS)
			pkg_script_run(pkg, PKG_SCRIPT_POST_UPGRADE);
		else
			pkg_script_run(pkg, PKG_SCRIPT_POST_INSTALL);
	}

	/*
	 * start the different related services if the users do want that
	 * and that the service is running
	 */

	pkg_config_bool(PKG_CONFIG_HANDLE_RC_SCRIPTS, &handle_rc);
	if (handle_rc)
		pkg_start_stop_rc_scripts(pkg, PKG_RC_START);

	cleanup_reg:
	if ((flags & PKG_ADD_UPGRADE) == 0)
		pkgdb_register_finale(db, retcode);

	if (retcode == EPKG_OK && (flags & PKG_ADD_UPGRADE) == 0)
		pkg_emit_install_finished(pkg);

	cleanup:
	if (a != NULL) {
		archive_read_close(a);
		archive_read_free(a);
	}

	pkg_free(pkg);

	if (pkg_inst != NULL)
		pkg_free(pkg_inst);

	return (retcode);
}
Пример #11
0
static int
test_depends(void *actdata, struct pkg *pkg, const char *fpath,
	     const char *name, bool is_shlib)
{
	struct pkgdb *db = actdata;
	struct pkg_dep *dep = NULL;
	struct pkgdb_it *it = NULL;
	struct pkg *d;
	const char *deporigin, *depname, *depversion;
	bool deplocked;
	char pathbuf[MAXPATHLEN];
	bool found;
	bool shlibs = false;

	assert(db != NULL);

	pkg_config_bool(PKG_CONFIG_SHLIBS, &shlibs);

	switch(filter_system_shlibs(name, pathbuf, sizeof(pathbuf))) {
	case EPKG_OK:		/* A non-system library */
		break;
	case EPKG_END:		/* A system library */
		return (EPKG_OK);
	default:
		/* Ignore link resolution errors if we're analysing a
		   shared library. */
		if (is_shlib)
			return (EPKG_OK);

		warnx("(%s-%s) %s - shared library %s not found",
		      pkg_name(pkg), pkg_version(pkg), fpath, name);
		return (EPKG_FATAL);
	}

	if (shlibs)
		pkg_addshlib_required(pkg, name);

	if ((it = pkgdb_query_which(db, pathbuf)) == NULL)
		return (EPKG_OK);

	d = NULL;
	if (pkgdb_it_next(it, &d, PKG_LOAD_BASIC) == EPKG_OK) {
		found = false;
		pkg_get(d, PKG_ORIGIN,  &deporigin,
			   PKG_NAME,    &depname,
			   PKG_VERSION, &depversion,
			   PKG_LOCKED,  &deplocked);

		dep = NULL;
		found = false;
		while (pkg_deps(pkg, &dep) == EPKG_OK) {
			if (strcmp(pkg_dep_origin(dep), deporigin) == 0) {
				found = true;
				break;
			}
		}
		if (!found) {
			pkg_emit_error("adding forgotten depends (%s): %s-%s",
			    pathbuf, depname, depversion);
			pkg_adddep(pkg, depname, deporigin, depversion,
			    deplocked);
		}
		pkg_free(d);
	}

	pkgdb_it_free(it);
	return (EPKG_OK);
}
Пример #12
0
int
pkgdb_repo_add_package(struct pkg *pkg, const char *pkg_path,
		sqlite3 *sqlite, const char *manifest_digest, bool forced)
{
	const char *name, *version, *origin, *comment, *desc;
	const char *arch, *maintainer, *www, *prefix, *sum, *rpath;
	int64_t			 flatsize, pkgsize;
	lic_t			 licenselogic;
	int			 ret;
	struct pkg_dep		*dep      = NULL;
	struct pkg_category	*category = NULL;
	struct pkg_license	*license  = NULL;
	struct pkg_option	*option   = NULL;
	struct pkg_shlib	*shlib    = NULL;
	struct pkg_note		*note     = NULL;
	int64_t			 package_id;

	pkg_get(pkg, PKG_ORIGIN, &origin, PKG_NAME, &name,
			    PKG_VERSION, &version, PKG_COMMENT, &comment,
			    PKG_DESC, &desc, PKG_ARCH, &arch,
			    PKG_MAINTAINER, &maintainer, PKG_WWW, &www,
			    PKG_PREFIX, &prefix, PKG_FLATSIZE, &flatsize,
			    PKG_LICENSE_LOGIC, &licenselogic, PKG_CKSUM, &sum,
			    PKG_PKGSIZE, &pkgsize, PKG_REPOPATH, &rpath);

try_again:
	if ((ret = run_prepared_statement(PKG, origin, name, version,
			comment, desc, arch, maintainer, www, prefix,
			pkgsize, flatsize, (int64_t)licenselogic, sum,
			rpath, manifest_digest)) != SQLITE_DONE) {
		if (ret == SQLITE_CONSTRAINT) {
			switch(maybe_delete_conflicting(origin,
					version, pkg_path, forced)) {
			case EPKG_FATAL: /* sqlite error */
				ERROR_SQLITE(sqlite);
				return (EPKG_FATAL);
				break;
			case EPKG_END: /* repo already has newer */
				return (EPKG_END);
				break;
			default: /* conflict cleared, try again */
				goto try_again;
				break;
			}
		} else {
			ERROR_SQLITE(sqlite);
			return (EPKG_FATAL);
		}
	}
	package_id = sqlite3_last_insert_rowid(sqlite);

	dep = NULL;
	while (pkg_deps(pkg, &dep) == EPKG_OK) {
		if (run_prepared_statement(DEPS,
				pkg_dep_origin(dep),
				pkg_dep_name(dep),
				pkg_dep_version(dep),
				package_id) != SQLITE_DONE) {
			ERROR_SQLITE(sqlite);
			return (EPKG_FATAL);
		}
	}

	category = NULL;
	while (pkg_categories(pkg, &category) == EPKG_OK) {
		const char *cat_name = pkg_category_name(category);

		ret = run_prepared_statement(CAT1, cat_name);
		if (ret == SQLITE_DONE)
			ret = run_prepared_statement(CAT2, package_id,
					cat_name);
		if (ret != SQLITE_DONE)
		{
			ERROR_SQLITE(sqlite);
			return (EPKG_FATAL);
		}
	}

	license = NULL;
	while (pkg_licenses(pkg, &license) == EPKG_OK) {
		const char *lic_name = pkg_license_name(license);

		ret = run_prepared_statement(LIC1, lic_name);
		if (ret == SQLITE_DONE)
			ret = run_prepared_statement(LIC2, package_id,
					lic_name);
		if (ret != SQLITE_DONE) {
			ERROR_SQLITE(sqlite);
			return (EPKG_FATAL);
		}
	}
	option = NULL;
	while (pkg_options(pkg, &option) == EPKG_OK) {
		ret = run_prepared_statement(OPT1, pkg_option_opt(option));
		if (ret == SQLITE_DONE)
		    ret = run_prepared_statement(OPT2, pkg_option_opt(option),
				pkg_option_value(option), package_id);
		if(ret != SQLITE_DONE) {
			ERROR_SQLITE(sqlite);
			return (EPKG_FATAL);
		}
	}

	shlib = NULL;
	while (pkg_shlibs_required(pkg, &shlib) == EPKG_OK) {
		const char *shlib_name = pkg_shlib_name(shlib);

		ret = run_prepared_statement(SHLIB1, shlib_name);
		if (ret == SQLITE_DONE)
			ret = run_prepared_statement(SHLIB_REQD, package_id,
					shlib_name);
		if (ret != SQLITE_DONE) {
			ERROR_SQLITE(sqlite);
			return (EPKG_FATAL);
		}
	}

	shlib = NULL;
	while (pkg_shlibs_provided(pkg, &shlib) == EPKG_OK) {
		const char *shlib_name = pkg_shlib_name(shlib);

		ret = run_prepared_statement(SHLIB1, shlib_name);
		if (ret == SQLITE_DONE)
			ret = run_prepared_statement(SHLIB_PROV, package_id,
					shlib_name);
		if (ret != SQLITE_DONE) {
			ERROR_SQLITE(sqlite);
			return (EPKG_FATAL);
		}
	}

	note = NULL;
	while (pkg_annotations(pkg, &note) == EPKG_OK) {
		const char *note_tag = pkg_annotation_tag(note);
		const char *note_val = pkg_annotation_value(note);

		ret = run_prepared_statement(ANNOTATE1, note_tag);
		if (ret == SQLITE_DONE)
			ret = run_prepared_statement(ANNOTATE1, note_val);
		if (ret == SQLITE_DONE)
			ret = run_prepared_statement(ANNOTATE2, package_id,
				  note_tag, note_val);
		if (ret != SQLITE_DONE) {
			ERROR_SQLITE(sqlite);
			return (EPKG_FATAL);
		}
	}

	return (EPKG_OK);
}
Пример #13
0
int
pkg_add(struct pkgdb *db, const char *path, unsigned flags)
{
    const char	*arch;
    const char	*myarch;
    const char	*origin;
    struct archive	*a;
    struct archive_entry *ae;
    struct pkg	*pkg = NULL;
    struct pkg_dep	*dep = NULL;
    struct pkg      *pkg_inst = NULL;
    bool		 extract = true;
    bool		 handle_rc = false;
    char		 dpath[MAXPATHLEN + 1];
    const char	*basedir;
    const char	*ext;
    char		*mtree;
    char		*prefix;
    int		 retcode = EPKG_OK;
    int		 ret;

    assert(path != NULL);

    /*
     * Open the package archive file, read all the meta files and set the
     * current archive_entry to the first non-meta file.
     * If there is no non-meta files, EPKG_END is returned.
     */
    ret = pkg_open2(&pkg, &a, &ae, path);
    if (ret == EPKG_END)
        extract = false;
    else if (ret != EPKG_OK) {
        retcode = ret;
        goto cleanup;
    }
    if ((flags & PKG_ADD_UPGRADE) == 0)
        pkg_emit_install_begin(pkg);

    if (pkg_is_valid(pkg) != EPKG_OK) {
        pkg_emit_error("the package is not valid");
        return (EPKG_FATAL);
    }

    if (flags & PKG_ADD_AUTOMATIC)
        pkg_set(pkg, PKG_AUTOMATIC, true);

    /*
     * Check the architecture
     */

    pkg_config_string(PKG_CONFIG_ABI, &myarch);
    pkg_get(pkg, PKG_ARCH, &arch, PKG_ORIGIN, &origin);

    if (fnmatch(myarch, arch, FNM_CASEFOLD) == FNM_NOMATCH &&
            strncmp(arch, myarch, strlen(myarch)) != 0) {
        pkg_emit_error("wrong architecture: %s instead of %s",
                       arch, myarch);
        if ((flags & PKG_ADD_FORCE) == 0) {
            retcode = EPKG_FATAL;
            goto cleanup;
        }
    }

    /*
     * Check if the package is already installed
     */

    ret = pkg_try_installed(db, origin, &pkg_inst, PKG_LOAD_BASIC);
    if (ret == EPKG_OK) {
        pkg_emit_already_installed(pkg_inst);
        retcode = EPKG_INSTALLED;
        goto cleanup;
    } else if (ret != EPKG_END) {
        retcode = ret;
        goto cleanup;
    }

    /*
     * Check for dependencies
     */

    basedir = dirname(path);
    if ((ext = strrchr(path, '.')) == NULL) {
        pkg_emit_error("%s has no extension", path);
        retcode = EPKG_FATAL;
        goto cleanup;
    }

    while (pkg_deps(pkg, &dep) == EPKG_OK) {
        if (pkg_is_installed(db, pkg_dep_origin(dep)) != EPKG_OK) {
            const char *dep_name = pkg_dep_name(dep);
            const char *dep_ver = pkg_dep_version(dep);

            snprintf(dpath, sizeof(dpath), "%s/%s-%s%s", basedir,
                     dep_name, dep_ver, ext);

            if ((flags & PKG_ADD_UPGRADE) == 0 &&
                    access(dpath, F_OK) == 0) {
                ret = pkg_add(db, dpath, PKG_ADD_AUTOMATIC);
                if (ret != EPKG_OK) {
                    retcode = EPKG_FATAL;
                    goto cleanup;
                }
            } else {
                retcode = EPKG_FATAL;
                pkg_emit_missing_dep(pkg, dep);
                goto cleanup;
            }
        }
    }

    /* register the package before installing it in case there are
     * problems that could be caught here. */
    if ((flags & PKG_ADD_UPGRADE) == 0)
        retcode = pkgdb_register_pkg(db, pkg, 0);
    else
        retcode = pkgdb_register_pkg(db, pkg, 1);

    if (retcode != EPKG_OK)
        goto cleanup;

    pkg_get(pkg, PKG_PREFIX, &prefix, PKG_MTREE, &mtree);
    if ((retcode = do_extract_mtree(mtree, prefix)) != EPKG_OK)
        goto cleanup_reg;

    /*
     * Execute pre-install scripts
     */
    if ((flags & (PKG_ADD_NOSCRIPT | PKG_ADD_USE_UPGRADE_SCRIPTS)) == 0)
        pkg_script_run(pkg, PKG_SCRIPT_PRE_INSTALL);

    /* add the user and group if necessary */
    /* pkg_add_user_group(pkg); */

    /*
     * Extract the files on disk.
     */
    if (extract && (retcode = do_extract(a, ae)) != EPKG_OK) {
        /* If the add failed, clean up */
        pkg_delete_files(pkg, 1);
        pkg_delete_dirs(db, pkg, 1);
        goto cleanup_reg;
    }

    /*
     * Execute post install scripts
     */
    if ((flags & PKG_ADD_NOSCRIPT) == 0) {
        if (flags & PKG_ADD_USE_UPGRADE_SCRIPTS)
            pkg_script_run(pkg, PKG_SCRIPT_POST_UPGRADE);
        else
            pkg_script_run(pkg, PKG_SCRIPT_POST_INSTALL);
    }

    /*
     * start the different related services if the users do want that
     * and that the service is running
     */

    pkg_config_bool(PKG_CONFIG_HANDLE_RC_SCRIPTS, &handle_rc);
    if (handle_rc)
        pkg_start_stop_rc_scripts(pkg, PKG_RC_START);

cleanup_reg:
    if ((flags & PKG_ADD_UPGRADE) == 0)
        pkgdb_register_finale(db, retcode);

    if (retcode == EPKG_OK && (flags & PKG_ADD_UPGRADE) == 0)
        pkg_emit_install_finished(pkg);

cleanup:
    if (a != NULL)
        archive_read_free(a);

    pkg_free(pkg);
    pkg_free(pkg_inst);

    return (retcode);
}
Пример #14
0
static int
analyse_elf(struct pkgdb *db, struct pkg *pkg, const char *fpath)
{
	struct pkg_dep *dep = NULL;
	struct pkg *p = NULL;
	struct pkgdb_it *it = NULL;
	Elf *e;
	Elf_Scn *scn = NULL;
	GElf_Shdr shdr;
	Elf_Data *data;
	GElf_Dyn *dyn, dyn_mem;
	size_t numdyn;
	size_t dynidx;
	void *handle;
	Link_map *map;
	char *name;
	bool found=false;

	int fd;

	if ((fd = open(fpath, O_RDONLY, 0)) < 0)
		return (EPKG_FATAL);

	if (( e = elf_begin(fd, ELF_C_READ, NULL)) == NULL)
		return (EPKG_FATAL);

	if (elf_kind(e) != ELF_K_ELF)
		return (EPKG_FATAL);

	while (( scn = elf_nextscn(e, scn)) != NULL) {
		if (gelf_getshdr(scn, &shdr) != &shdr)
			return (EPKG_FATAL);

		if (shdr.sh_type == SHT_DYNAMIC)
			break;
	}

	if  (scn == NULL)
		return (EPKG_OK);

	data = elf_getdata(scn, NULL);
	numdyn = shdr.sh_size / shdr.sh_entsize;

	for (dynidx = 0; dynidx < numdyn; dynidx++) {
		if ((dyn = gelf_getdyn(data, dynidx, &dyn_mem)) == NULL)
			return (EPKG_FATAL);

		if (dyn->d_tag != DT_NEEDED)
			continue;

		name = elf_strptr(e, shdr.sh_link, dyn->d_un.d_val);
		handle = dlopen(name, RTLD_LAZY);

		if (handle != NULL) {
			dlinfo(handle, RTLD_DI_LINKMAP, &map);
			if ((it = pkgdb_query_which(db, map->l_name)) == NULL)
				return (EPKG_FATAL);

			if (pkgdb_it_next(it, &p, PKG_LOAD_BASIC) == EPKG_OK) {
				found = false;
				while (pkg_deps(pkg, &dep) == EPKG_OK) {
					if (strcmp(pkg_dep_origin(dep), pkg_get(p, PKG_ORIGIN)) == 0)
						found = true;
				}
				if (!found) {
					pkg_emit_error("adding forgotten depends (%s): %s-%s",
								   map->l_name, pkg_get(p, PKG_NAME),
								   pkg_get(p, PKG_VERSION));
					pkg_adddep(pkg, pkg_get(p, PKG_NAME), pkg_get(p, PKG_ORIGIN), pkg_get(p, PKG_VERSION));
				}
			}
			dlclose(handle);
		}
		pkgdb_it_free(it);
	}
	pkg_free(p);
	close(fd);

	return (EPKG_OK);

}