mirror of
https://github.com/aaru-dps/libaaruformat.git
synced 2025-12-16 19:24:40 +00:00
Add checksum writing functionality to close.c
This commit is contained in:
93
src/close.c
93
src/close.c
@@ -497,16 +497,105 @@ int aaruf_close(void *context)
|
||||
TRACE("Failed to write single-level DDT table data to file");
|
||||
}
|
||||
|
||||
uint64_t alignment_mask;
|
||||
uint64_t aligned_position;
|
||||
|
||||
// Write the checksums block
|
||||
bool has_checksums =
|
||||
ctx->checksums.hasMd5 || ctx->checksums.hasSha1 || ctx->checksums.hasSha256 || ctx->checksums.hasSpamSum;
|
||||
|
||||
if(has_checksums)
|
||||
{
|
||||
ChecksumHeader checksum_header = {0};
|
||||
checksum_header.identifier = ChecksumBlock;
|
||||
|
||||
fseek(ctx->imageStream, 0, SEEK_END);
|
||||
long checksum_position = ftell(ctx->imageStream);
|
||||
// Align index position to block boundary if needed
|
||||
alignment_mask = (1ULL << ctx->userDataDdtHeader.blockAlignmentShift) - 1;
|
||||
if(checksum_position & alignment_mask)
|
||||
{
|
||||
aligned_position = checksum_position + alignment_mask & ~alignment_mask;
|
||||
fseek(ctx->imageStream, aligned_position, SEEK_SET);
|
||||
checksum_position = aligned_position;
|
||||
}
|
||||
|
||||
// Skip checksum_header
|
||||
fseek(ctx->imageStream, sizeof(checksum_header), SEEK_CUR);
|
||||
|
||||
if(ctx->checksums.hasMd5)
|
||||
{
|
||||
TRACE("Writing MD5 checksum entry");
|
||||
ChecksumEntry md5_entry = {0};
|
||||
md5_entry.length = MD5_DIGEST_LENGTH;
|
||||
md5_entry.type = Md5;
|
||||
fwrite(&md5_entry, sizeof(ChecksumEntry), 1, ctx->imageStream);
|
||||
fwrite(&ctx->checksums.md5, MD5_DIGEST_LENGTH, 1, ctx->imageStream);
|
||||
checksum_header.length += sizeof(ChecksumEntry) + MD5_DIGEST_LENGTH;
|
||||
checksum_header.entries++;
|
||||
}
|
||||
|
||||
if(ctx->checksums.hasSha1)
|
||||
{
|
||||
TRACE("Writing SHA1 checksum entry");
|
||||
ChecksumEntry sha1_entry = {0};
|
||||
sha1_entry.length = SHA1_DIGEST_LENGTH;
|
||||
sha1_entry.type = Sha1;
|
||||
fwrite(&sha1_entry, sizeof(ChecksumEntry), 1, ctx->imageStream);
|
||||
fwrite(&ctx->checksums.sha1, SHA1_DIGEST_LENGTH, 1, ctx->imageStream);
|
||||
checksum_header.length += sizeof(ChecksumEntry) + SHA1_DIGEST_LENGTH;
|
||||
checksum_header.entries++;
|
||||
}
|
||||
|
||||
if(ctx->checksums.hasSha256)
|
||||
{
|
||||
TRACE("Writing SHA256 checksum entry");
|
||||
ChecksumEntry sha256_entry = {0};
|
||||
sha256_entry.length = SHA256_DIGEST_LENGTH;
|
||||
sha256_entry.type = Sha256;
|
||||
fwrite(&sha256_entry, sizeof(ChecksumEntry), 1, ctx->imageStream);
|
||||
fwrite(&ctx->checksums.sha256, SHA256_DIGEST_LENGTH, 1, ctx->imageStream);
|
||||
checksum_header.length += sizeof(ChecksumEntry) + SHA1_DIGEST_LENGTH;
|
||||
checksum_header.entries++;
|
||||
}
|
||||
|
||||
if(ctx->checksums.hasSpamSum)
|
||||
{
|
||||
TRACE("Writing SpamSum checksum entry");
|
||||
ChecksumEntry spamsum_entry = {0};
|
||||
spamsum_entry.length = strlen((const char *)ctx->checksums.spamsum);
|
||||
spamsum_entry.type = SpamSum;
|
||||
fwrite(&spamsum_entry, sizeof(ChecksumEntry), 1, ctx->imageStream);
|
||||
fwrite(&ctx->checksums.spamsum, spamsum_entry.length, 1, ctx->imageStream);
|
||||
checksum_header.length += sizeof(ChecksumEntry) + spamsum_entry.length;
|
||||
checksum_header.entries++;
|
||||
}
|
||||
|
||||
fseek(ctx->imageStream, checksum_position, SEEK_SET);
|
||||
TRACE("Writing checksum header");
|
||||
fwrite(&checksum_header, sizeof(ChecksumHeader), 1, ctx->imageStream);
|
||||
|
||||
// Add checksum block to index
|
||||
TRACE("Adding checksum block to index");
|
||||
IndexEntry checksum_index_entry;
|
||||
checksum_index_entry.blockType = ChecksumBlock;
|
||||
checksum_index_entry.dataType = 0;
|
||||
checksum_index_entry.offset = checksum_position;
|
||||
|
||||
utarray_push_back(ctx->indexEntries, &checksum_index_entry);
|
||||
TRACE("Added checksum block index entry at offset %" PRIu64, checksum_position);
|
||||
}
|
||||
|
||||
// Write the complete index at the end of the file
|
||||
TRACE("Writing index at the end of the file");
|
||||
fseek(ctx->imageStream, 0, SEEK_END);
|
||||
long index_position = ftell(ctx->imageStream);
|
||||
|
||||
// Align index position to block boundary if needed
|
||||
uint64_t alignment_mask = (1ULL << ctx->userDataDdtHeader.blockAlignmentShift) - 1;
|
||||
alignment_mask = (1ULL << ctx->userDataDdtHeader.blockAlignmentShift) - 1;
|
||||
if(index_position & alignment_mask)
|
||||
{
|
||||
uint64_t aligned_position = index_position + alignment_mask & ~alignment_mask;
|
||||
aligned_position = index_position + alignment_mask & ~alignment_mask;
|
||||
fseek(ctx->imageStream, aligned_position, SEEK_SET);
|
||||
index_position = aligned_position;
|
||||
TRACE("Aligned index position to %" PRIu64, aligned_position);
|
||||
|
||||
Reference in New Issue
Block a user