From 251656734dc72dd462facd790b4cd6609df3acb4 Mon Sep 17 00:00:00 2001
From: Timo Teras <timo.teras@iki.fi>
Date: Thu, 16 Jul 2009 15:27:00 +0300
Subject: archive: use the abuild-tar mangled checksum if available

to speed up apk installation avoid calculating checksums.
---
 src/archive.c | 36 ++++++++++++++++++++++++++++--------
 1 file changed, 28 insertions(+), 8 deletions(-)

diff --git a/src/archive.c b/src/archive.c
index f30463f..717c67c 100644
--- a/src/archive.c
+++ b/src/archive.c
@@ -44,6 +44,13 @@ struct tar_header {
 	char padding[12];   /* 500-512 */
 };
 
+struct apk_tar_digest_info {
+	char id[4];
+	uint16_t nid;
+	uint16_t size;
+	char digest[];
+};
+
 #define GET_OCTAL(s)	get_octal(s, sizeof(s))
 #define PUT_OCTAL(s,v)	put_octal(s, sizeof(s), v)
 
@@ -82,13 +89,17 @@ static size_t tar_entry_read(void *stream, void *ptr, size_t size)
 	if (size > teis->bytes_left)
 		size = teis->bytes_left;
 	size = teis->tar_is->read(teis->tar_is, ptr, size);
-	if (size > 0) {
-		teis->bytes_left -= size;
-		EVP_DigestUpdate(&teis->mdctx, ptr, size);
-		if (teis->bytes_left == 0) {
-			teis->csum->type = EVP_MD_CTX_size(&teis->mdctx);
-			EVP_DigestFinal_ex(&teis->mdctx, teis->csum->data, NULL);
-		}
+	if (size < 0)
+		return -1;
+
+	teis->bytes_left -= size;
+	if (teis->csum != NULL)
+		return size;
+
+	EVP_DigestUpdate(&teis->mdctx, ptr, size);
+	if (teis->bytes_left == 0) {
+		teis->csum->type = EVP_MD_CTX_size(&teis->mdctx);
+		EVP_DigestFinal_ex(&teis->mdctx, teis->csum->data, NULL);
 	}
 	return size;
 }
@@ -100,13 +111,14 @@ int apk_tar_parse(struct apk_istream *is, apk_archive_entry_parser parser,
 	struct apk_tar_entry_istream teis = {
 		.is.read = tar_entry_read,
 		.tar_is = is,
-		.csum = &entry.csum,
 	};
 	struct tar_header buf;
+	struct apk_tar_digest_info *di;
 	unsigned long offset = 0;
 	int end = 0, r;
 	size_t toskip;
 
+	di = (struct apk_tar_digest_info *) &buf.linkname[3];
 	EVP_MD_CTX_init(&teis.mdctx);
 	memset(&entry, 0, sizeof(entry));
 	while ((r = is->read(is, &buf, 512)) == 512) {
@@ -146,6 +158,14 @@ int apk_tar_parse(struct apk_istream *is, apk_archive_entry_parser parser,
 		case '0':
 		case '7': /* regular file */
 			entry.mode |= S_IFREG;
+			if (memcmp(di->id, "APK2", 4) == 0 &&
+			    di->size <= sizeof(entry.csum.data)) {
+				entry.csum.type = di->size;
+				memcpy(entry.csum.data, di->digest, di->size);
+				teis.csum = NULL;
+			} else {
+				teis.csum = &entry.csum;
+			}
 			break;
 		case '1': /* hard link */
 			entry.mode |= S_IFREG;
-- 
cgit v1.2.3-70-g09d2