From 6b94ed8a7ac353298c4bb7ab1f247b1b1584784e Mon Sep 17 00:00:00 2001
From: Timo Teras <timo.teras@iki.fi>
Date: Thu, 13 Aug 2009 14:33:43 +0300
Subject: fix: parse pkgfile properly (fixes #132)

accept also pkgfile in addition to pkgname. make also the signature
verification stuff work properly again with non-repository files.
---
 src/fix.c     | 43 +++++++++++++++++++++++++++----------------
 src/package.c | 16 ++++++++--------
 2 files changed, 35 insertions(+), 24 deletions(-)

diff --git a/src/fix.c b/src/fix.c
index 756db6a..6423e46 100644
--- a/src/fix.c
+++ b/src/fix.c
@@ -41,38 +41,49 @@ static int fix_main(void *pctx, struct apk_database *db, int argc, char **argv)
 	struct fix_ctx *ctx = (struct fix_ctx *) pctx;
 	struct apk_state *state = NULL;
 	struct apk_name *name;
+	struct apk_package *pkg;
+	struct apk_package **pkgs;
 	int r = 0, i, j;
 
 	state = apk_state_new(db);
 	if (state == NULL)
 		return -1;
 
+	pkgs = alloca(sizeof(struct apk_package *) * argc);
 	for (i = 0; i < argc; i++) {
-		name = apk_db_get_name(db, APK_BLOB_STR(argv[i]));
-		if (name == NULL)
-			goto err;
+		pkg = NULL;
+		if (strstr(argv[i], ".apk") != NULL) {
+			struct apk_sign_ctx sctx;
 
-		for (j = 0; j < name->pkgs->num; j++) {
-			if (name->pkgs->item[j]->ipkg != NULL)
-				break;
+			apk_sign_ctx_init(&sctx, APK_SIGN_VERIFY_AND_GENERATE,
+					  NULL, db->keys_fd);
+			r = apk_pkg_read(db, argv[i], &sctx, &pkg);
+			apk_sign_ctx_free(&sctx);
+			if (r != 0) {
+				apk_error("%s: %s", argv[i], apk_error_str(r));
+				goto err;
+			}
+			name = pkg->name;
+		} else {
+			name = apk_db_get_name(db, APK_BLOB_STR(argv[i]));
+			for (j = 0; name && name->pkgs && j < name->pkgs->num; j++) {
+				if (name->pkgs->item[j]->ipkg != NULL) {
+					pkg = name->pkgs->item[j];
+					break;
+				}
+			}
 		}
-		if (j >= name->pkgs->num) {
-			apk_error("Package '%s' is not installed", name->name);
+		if (pkg == NULL || pkg->ipkg == NULL) {
+			apk_error("%s is not installed", name->name);
 			goto err;
 		}
-
 		if (ctx->reinstall)
 			name->flags |= APK_NAME_REINSTALL;
+		pkgs[i] = pkg;
 	}
 
 	for (i = 0; i < argc; i++) {
-		struct apk_dependency dep;
-
-		r = apk_dep_from_blob(&dep, db, APK_BLOB_STR(argv[i]));
-		if (r != 0)
-			goto err;
-
-		r = apk_state_lock_dependency(state, &dep);
+		r = apk_state_lock_name(state, pkg->name, pkg);
 		if (r != 0) {
 			if (!(apk_flags & APK_FORCE))
 				goto err;
diff --git a/src/package.c b/src/package.c
index 4445aa6..9e74854 100644
--- a/src/package.c
+++ b/src/package.c
@@ -352,11 +352,6 @@ void apk_sign_ctx_init(struct apk_sign_ctx *ctx, int action,
 	ctx->keys_fd = keys_fd;
 	ctx->action = action;
 	switch (action) {
-	case APK_SIGN_NONE:
-		ctx->md = EVP_md_null();
-		ctx->control_started = 1;
-		ctx->data_started = 1;
-		break;
 	case APK_SIGN_VERIFY:
 		ctx->md = EVP_md_null();
 		break;
@@ -377,10 +372,14 @@ void apk_sign_ctx_init(struct apk_sign_ctx *ctx, int action,
 		break;
 	case APK_SIGN_GENERATE:
 	case APK_SIGN_VERIFY_AND_GENERATE:
-	default:
-		action = APK_SIGN_GENERATE;
 		ctx->md = EVP_sha1();
 		break;
+	default:
+		action = APK_SIGN_NONE;
+		ctx->md = EVP_md_null();
+		ctx->control_started = 1;
+		ctx->data_started = 1;
+		break;
 	}
 	EVP_MD_CTX_init(&ctx->mdctx);
 	EVP_DigestInit_ex(&ctx->mdctx, ctx->md, NULL);
@@ -421,7 +420,8 @@ int apk_sign_ctx_process_file(struct apk_sign_ctx *ctx,
 	ctx->num_signatures++;
 
 	/* Found already a trusted key */
-	if (ctx->action != APK_SIGN_VERIFY ||
+	if ((ctx->action != APK_SIGN_VERIFY &&
+	     ctx->action != APK_SIGN_VERIFY_AND_GENERATE) ||
 	    ctx->signature.pkey != NULL)
 		return 0;
 
-- 
cgit v1.2.3-70-g09d2