Radish alpha
H
rad:z3QDZAW2FAfuLvihrhiyDC9fAD8G9
HardenedBSD Package Manager
Radicle
Git
Merge pull request #482 from vstakhov/master
Baptiste Daroussin committed 13 years ago
commit bb6a6168cdc1c755b78f7c52e2ef51cc2b4162db
parent 323cc96
10 files changed +117 -22
modified libpkg/pkg.h.in
@@ -760,10 +760,12 @@ int pkg_load_manifest_file(struct pkg *pkg, const char *fpath);
 * Emit a manifest according to the attributes of pkg.
 * @param buf A pointer which will hold the allocated buffer containing the
 * manifest. To be free'ed.
+
 * @param pdigest A pointer that will hold digest of manifest produced, ignored
+
 * if NULL. To be free'ed if not NULL.
 * @return An error code.
 */
-
int pkg_emit_manifest(struct pkg *pkg, char **buf, bool compact);
-
int pkg_emit_manifest_file(struct pkg*, FILE *, bool);
+
int pkg_emit_manifest(struct pkg *pkg, char **buf, bool compact, char **pdigest);
+
int pkg_emit_manifest_file(struct pkg*, FILE *, bool, char **pdigest);

/* pkg_dep */
const char *pkg_dep_get(struct pkg_dep const * const , const pkg_dep_attr);
modified libpkg/pkg_create.c
@@ -103,7 +103,7 @@ pkg_create_from_dir(struct pkg *pkg, const char *root,
	} else {
		pkg_register_shlibs(pkg);

-
		pkg_emit_manifest(pkg, &m, false);
+
		pkg_emit_manifest(pkg, &m, false, NULL);
		packing_append_buffer(pkg_archive, m, "+MANIFEST", strlen(m));
		free(m);
	}
modified libpkg/pkg_event.c
@@ -381,7 +381,6 @@ pkg_emit_error(const char *fmt, ...)
	ev.type = PKG_EVENT_ERROR;

	va_start(ap, fmt);
-
	pkg_emit_event(&ev);
	vasprintf(&ev.e_pkg_error.msg, fmt, ap);
	va_end(ap);

modified libpkg/pkg_manifest.c
@@ -690,11 +690,38 @@ pkg_parse_manifest(struct pkg *pkg, char *buf)
	return retcode;
}

+
struct pkg_yaml_emitter_data {
+
	SHA256_CTX *sign_ctx;
+
	union {
+
		struct sbuf *sbuf;
+
		FILE *file;
+
		char *dest;
+
	} data;
+
};
+

static int
yaml_write_buf(void *data, unsigned char *buffer, size_t size)
{
-
	struct sbuf *dest = (struct sbuf *)data;
-
	sbuf_bcat(dest, buffer, size);
+
	struct pkg_yaml_emitter_data *dest = (struct pkg_yaml_emitter_data *)data;
+

+
	sbuf_bcat(dest->data.sbuf, buffer, size);
+
	if (dest->sign_ctx != NULL)
+
		SHA256_Update(dest->sign_ctx, buffer, size);
+

+
	return (1);
+
}
+

+
static int
+
yaml_write_file(void *data, unsigned char *buffer, size_t size)
+
{
+
	struct pkg_yaml_emitter_data *dest = (struct pkg_yaml_emitter_data *)data;
+

+
	if (fwrite(buffer, size, 1, dest->data.file) != 1)
+
		return -1;
+

+
	if (dest->sign_ctx != NULL)
+
		SHA256_Update(dest->sign_ctx, buffer, size);
+

	return (1);
}

@@ -735,7 +762,7 @@ pkg_emit_filelist(struct pkg *pkg, FILE *f)
	yaml_emitter_t emitter;
	yaml_document_t doc;

-
	struct pkg_file *file;
+
	struct pkg_file *file = NULL;

	const char *name, *origin, *version;

@@ -990,46 +1017,93 @@ emit_manifest(struct pkg *pkg, yaml_emitter_t *emitter, bool compact)
	return (rc);
}

+
static void
+
pkg_emit_manifest_digest(const unsigned char *digest, size_t len, char *hexdigest)
+
{
+
	unsigned int i;
+

+
	for (i = 0; i < len; i ++)
+
		sprintf(hexdigest + (i * 2), "%02x", digest[i]);
+

+
	hexdigest[len * 2] = '\0';
+
}
+

int
-
pkg_emit_manifest_file(struct pkg *pkg, FILE *f, bool compact)
+
pkg_emit_manifest_file(struct pkg *pkg, FILE *f, bool compact, char **pdigest)
{
	yaml_emitter_t emitter;
+
	struct pkg_yaml_emitter_data emitter_data;
+
	unsigned char digest[SHA256_DIGEST_LENGTH];
	int rc;

+
	if (pdigest != NULL) {
+
		*pdigest = malloc(sizeof(digest) * 2 + 1);
+
		emitter_data.sign_ctx = malloc(sizeof(SHA256_CTX));
+
		SHA256_Init(emitter_data.sign_ctx);
+
	}
+
	else {
+
		emitter_data.sign_ctx = NULL;
+
	}
+

	yaml_emitter_initialize(&emitter);
	yaml_emitter_set_unicode(&emitter, 1);
-
	yaml_emitter_set_output_file(&emitter, f);
+
	emitter_data.data.file = f;
+
	yaml_emitter_set_output(&emitter, yaml_write_file, &emitter_data);

	rc = emit_manifest(pkg, &emitter, compact);

+
	if (emitter_data.sign_ctx != NULL) {
+
		SHA256_Final(digest, emitter_data.sign_ctx);
+
		pkg_emit_manifest_digest(digest, sizeof(digest), *pdigest);
+
		free(emitter_data.sign_ctx);
+
	}
	yaml_emitter_delete(&emitter);

	return (rc);
}

int
-
pkg_emit_manifest_sbuf(struct pkg *pkg, struct sbuf *b, bool compact)
+
pkg_emit_manifest_sbuf(struct pkg *pkg, struct sbuf *b, bool compact, char **pdigest)
{
	yaml_emitter_t emitter;
+
	struct pkg_yaml_emitter_data emitter_data;
+
	unsigned char digest[SHA256_DIGEST_LENGTH];
	int rc;

+
	if (pdigest != NULL) {
+
		*pdigest = malloc(sizeof(digest) * 2 + 1);
+
		emitter_data.sign_ctx = malloc(sizeof(SHA256_CTX));
+
		SHA256_Init(emitter_data.sign_ctx);
+
	}
+
	else {
+
		emitter_data.sign_ctx = NULL;
+
	}
+

	yaml_emitter_initialize(&emitter);
	yaml_emitter_set_unicode(&emitter, 1);
-
	yaml_emitter_set_output(&emitter, yaml_write_buf, b);
+
	emitter_data.data.sbuf = b;
+
	yaml_emitter_set_output(&emitter, yaml_write_buf, &emitter_data);

	rc = emit_manifest(pkg, &emitter, compact);

+
	if (emitter_data.sign_ctx != NULL) {
+
		SHA256_Final(digest, emitter_data.sign_ctx);
+
		pkg_emit_manifest_digest(digest, sizeof(digest), *pdigest);
+
		free(emitter_data.sign_ctx);
+
	}
+

	yaml_emitter_delete(&emitter);

	return (rc);
}
+

int
-
pkg_emit_manifest(struct pkg *pkg, char **dest, bool compact)
+
pkg_emit_manifest(struct pkg *pkg, char **dest, bool compact, char **pdigest)
{
	struct sbuf *b = sbuf_new_auto();
	int rc;

-
	rc = pkg_emit_manifest_sbuf(pkg, b, compact);
+
	rc = pkg_emit_manifest_sbuf(pkg, b, compact, pdigest);

	if (rc != EPKG_OK) {
		sbuf_delete(b);
modified libpkg/pkg_repo.c
@@ -585,9 +585,10 @@ pkg_create_repo(char *path, __unused bool force, void (progress)(struct pkg *pkg
	char *repopath[2];
	char repodb[MAXPATHLEN + 1];
	char repopack[MAXPATHLEN + 1];
-
	FILE *psyml, *fsyml;
+
	char *manifest_digest;
+
	FILE *psyml, *fsyml, *mandigests;

-
	psyml = fsyml = NULL;
+
	psyml = fsyml = mandigests = NULL;

	if (!is_dir(path)) {
		pkg_emit_error("%s is not a directory", path);
@@ -617,6 +618,11 @@ pkg_create_repo(char *path, __unused bool force, void (progress)(struct pkg *pkg
		retcode = EPKG_FATAL;
		goto cleanup;
	}
+
	snprintf(repodb, sizeof(repodb), "%s/digests", path);
+
	if ((mandigests = fopen(repodb, "w")) == NULL) {
+
		retcode = EPKG_FATAL;
+
		goto cleanup;
+
	}

	snprintf(repodb, sizeof(repodb), "%s/repo.sqlite", path);
	snprintf(repopack, sizeof(repopack), "%s/repoy.txz", path);
@@ -690,9 +696,10 @@ pkg_create_repo(char *path, __unused bool force, void (progress)(struct pkg *pkg
		if (progress != NULL)
			progress(r->pkg, data);

-
		pkg_emit_manifest_file(r->pkg, psyml, true);
+
		pkg_emit_manifest_file(r->pkg, psyml, true, &manifest_digest);
		pkg_emit_filelist(r->pkg, fsyml);

+

		pkg_get(r->pkg, PKG_ORIGIN, &origin, PKG_NAME, &name,
		    PKG_VERSION, &version, PKG_COMMENT, &comment,
		    PKG_DESC, &desc, PKG_ARCH, &arch,
@@ -700,6 +707,8 @@ pkg_create_repo(char *path, __unused bool force, void (progress)(struct pkg *pkg
		    PKG_PREFIX, &prefix, PKG_FLATSIZE, &flatsize,
		    PKG_LICENSE_LOGIC, &licenselogic, PKG_CKSUM, &sum,
		    PKG_NEW_PKGSIZE, &pkgsize, PKG_REPOPATH, &rpath);
+
		fprintf(mandigests, "%s: %s\n", origin, manifest_digest);
+
		free(manifest_digest);

	try_again:
		if ((ret = run_prepared_statement(PKG, origin, name, version,
@@ -850,6 +859,9 @@ cleanup:
	if (psyml != NULL)
		fclose(psyml);

+
	if (mandigests != NULL)
+
		fclose(mandigests);
+

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

@@ -916,7 +928,9 @@ read_pkg_file(void *data)
				strcmp(ext, ".tar") != 0)
			continue;

-
		if (strcmp(fts_name, "repo.txz") == 0)
+
		if (strcmp(fts_name, "repo.txz") == 0 ||
+
			strcmp(fts_name, "packagesite.txz") == 0 ||
+
			strcmp(fts_name, "filesite.txz") == 0)
			continue;

		pkg_path = fts_path;
modified libpkg/private/pkg.h
@@ -383,7 +383,7 @@ int pkg_register_shlibs(struct pkg *pkg);

void pkg_config_parse(yaml_document_t *doc, yaml_node_t *node, struct pkg_config *conf_by_key);

-
int pkg_emit_manifest_sbuf(struct pkg*, struct sbuf *, bool);
+
int pkg_emit_manifest_sbuf(struct pkg*, struct sbuf *, bool, char **);
int pkg_emit_filelist(struct pkg *, FILE *);

#endif
modified pkg/install.c
@@ -70,7 +70,7 @@ exec_install(int argc, char **argv)
	pkg_config_bool(PKG_CONFIG_ASSUME_ALWAYS_YES, &yes);
	pkg_config_bool(PKG_CONFIG_REPO_AUTOUPDATE, &auto_update);

-
	while ((ch = getopt(argc, argv, "AfgIiLnqRr:Uxy")) != -1) {
+
	while ((ch = getopt(argc, argv, "AfgIiLFnqRr:Uxy")) != -1) {
		switch (ch) {
		case 'A':
			f |= PKG_FLAG_AUTOMATIC;
@@ -84,6 +84,9 @@ exec_install(int argc, char **argv)
		case 'I':
			f |= PKG_FLAG_NOSCRIPT;
			break;
+
		case 'F':
+
			f |= PKG_FLAG_SKIP_INSTALL;
+
			break;
		case 'i':
			pkgdb_set_case_sensitivity(false);
			break;
modified pkg/pkg-install.8
@@ -23,7 +23,7 @@
.Nd installs packages from remote package repositories
.Sh SYNOPSIS
.Nm
-
.Op Fl AfgIinqRUxy
+
.Op Fl AfgIinFqRUxy
.Op Fl r Ar reponame
.Ar <pkg-origin> ...
.Sh DESCRIPTION
@@ -134,6 +134,9 @@ This is planned to be removed.
Dry-run mode.
The list of changes to packages is always printed, but
no changes are actually made.
+
.It Fl F
+
Do not perform actual installation of packages, merely fetch packages 
+
that should be upgraded and detect possible conflicts.
.It Fl q
Force quiet output, except when
.Fl n
modified pkg/pkg-upgrade.8
@@ -68,7 +68,7 @@ Repository catalogues will be updated as usual unless the
.Fl U
option is also given.
.It Fl F
-
Do not perform installation of packages, just fetch packages that should be 
+
Do not perform installation of packages, merely fetch packages that should be 
upgraded and detect possible conflicts.
.It Fl q
Force quiet output, except when
modified pkg/utils.c
@@ -229,7 +229,7 @@ print_info(struct pkg * const pkg, unsigned int options)

	if (options & INFO_RAW) { /* Not for remote packages */
		if (pkg_type(pkg) != PKG_REMOTE)
-
			pkg_emit_manifest_file(pkg, stdout, false);
+
			pkg_emit_manifest_file(pkg, stdout, false, NULL);
		return;
	}