From: Michael Tremer Date: Fri, 24 Nov 2017 15:19:04 +0000 (+0100) Subject: libpakfire: Parse checksums file in archives X-Git-Tag: 0.9.28~1285^2~1285 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=6afc1aa63dbb46d17b0cdc6b9001c6b23ff25f9f;p=pakfire.git libpakfire: Parse checksums file in archives Signed-off-by: Michael Tremer --- diff --git a/src/libpakfire/archive.c b/src/libpakfire/archive.c index 4576c282e..7a60035c5 100644 --- a/src/libpakfire/archive.c +++ b/src/libpakfire/archive.c @@ -19,6 +19,7 @@ #############################################################################*/ #include +#include #include #include #include @@ -128,6 +129,23 @@ static int payload_archive_open(struct archive** a, struct archive* source_archi return archive_read_open1(*a); } +static archive_checksum_t* pakfire_archive_checksum_create(const char* filename, const char* checksum, archive_checksum_algo_t algo) { + archive_checksum_t* c = pakfire_calloc(1, sizeof(*c)); + if (c) { + c->filename = pakfire_strdup(filename); + c->checksum = pakfire_strdup(checksum); + c->algo = algo; + } + + return c; +} + +static void pakfire_archive_checksum_free(archive_checksum_t* c) { + pakfire_free(c->filename); + pakfire_free(c->checksum); + pakfire_free(c); +} + PakfireArchive pakfire_archive_create() { PakfireArchive archive = pakfire_calloc(1, sizeof(*archive)); if (archive) { @@ -141,6 +159,11 @@ void pakfire_archive_free(PakfireArchive archive) { if (archive->path) pakfire_free(archive->path); + // Free checksums + archive_checksum_t** checksums = archive->checksums; + while (*checksums) + pakfire_archive_checksum_free(*checksums++); + pakfire_free(archive); } @@ -194,6 +217,73 @@ static int pakfire_archive_parse_entry_filelist(PakfireArchive archive, return 0; } +static int pakfire_archive_parse_entry_checksums(PakfireArchive archive, + struct archive* a, struct archive_entry* e) { + char* data; + size_t data_size; + + int r = archive_read(a, (void**)&data, &data_size); + if (r) + return 1; + + // Empty file + if (data_size <= 0) + return 1; + + // Terminate string. + data[data_size] = '\0'; + + // Allocate some space to save the checksums + archive->checksums = pakfire_calloc(10, sizeof(*archive->checksums)); + + const char* filename = NULL; + const char* checksum = NULL; + archive_checksum_algo_t algo = PAKFIRE_CHECKSUM_SHA512; + + char* p = data; + while (*p) { + // Filename starts here + filename = p; + + // Find end of filename + while (!isspace(*p)) + p++; + + // Terminate filename + *p++ = '\0'; + + // Skip any spaces + while (isspace(*p)) + p++; + + // Checksum starts here + checksum = p; + + // Find end of checksum + while (!isspace(*p)) + p++; + + // Terminate the checksum + *p++ = '\0'; + + // Add new checksum object + if (filename && checksum) { + *archive->checksums++ = pakfire_archive_checksum_create(filename, checksum, algo); + } + + // Eat up any space before next thing starts + while (isspace(*p)) + p++; + } + + // Terminate the list + *archive->checksums = NULL; + + pakfire_free(data); + + return 0; +} + static int pakfire_archive_read_metadata(PakfireArchive archive, struct archive* a) { int ret; @@ -228,6 +318,12 @@ static int pakfire_archive_read_metadata(PakfireArchive archive, struct archive* ret = pakfire_archive_parse_entry_filelist(archive, a, entry); if (ret) return PAKFIRE_E_PKG_INVALID; + + // Parse the checksums + } else if (strcmp(PAKFIRE_ARCHIVE_FN_CHECKSUMS, entry_name) == 0) { + ret = pakfire_archive_parse_entry_checksums(archive, a, entry); + if (ret) + return PAKFIRE_E_PKG_INVALID; } } } diff --git a/src/libpakfire/include/pakfire/archive.h b/src/libpakfire/include/pakfire/archive.h index 3e3e65dc5..2bbea8f65 100644 --- a/src/libpakfire/include/pakfire/archive.h +++ b/src/libpakfire/include/pakfire/archive.h @@ -44,6 +44,7 @@ enum pakfire_archive_flags { PAKFIRE_ARCHIVE_USE_PAYLOAD = 1 << 0, }; +#define PAKFIRE_ARCHIVE_FN_CHECKSUMS "chksums" #define PAKFIRE_ARCHIVE_FN_FILELIST "filelist" #define PAKFIRE_ARCHIVE_FN_FORMAT "pakfire-format" #define PAKFIRE_ARCHIVE_FN_METADATA "info" @@ -54,6 +55,17 @@ enum pakfire_archive_flags { #define PAKFIRE_ARCHIVE_BLOCKSIZE 10240 #define PAKFIRE_ARCHIVE_FORMAT_SIZE 5 +typedef enum archive_checksum_algo { + PAKFIRE_CHECKSUM_UNKNOWN = 0, + PAKFIRE_CHECKSUM_SHA512, +} archive_checksum_algo_t; + +typedef struct archive_checksum { + char* filename; + char* checksum; + archive_checksum_algo_t algo; +} archive_checksum_t; + struct _PakfireArchive { char* path; @@ -61,6 +73,7 @@ struct _PakfireArchive { int format; PakfireFile filelist; + archive_checksum_t** checksums; }; struct payload_archive_data {