mirror of
https://github.com/aaru-dps/libaaruformat.git
synced 2025-12-16 19:24:40 +00:00
Decode checksums block on opening.
This commit is contained in:
@@ -22,6 +22,30 @@
|
|||||||
#include "lru.h"
|
#include "lru.h"
|
||||||
#include "structs.h"
|
#include "structs.h"
|
||||||
|
|
||||||
|
#ifndef MD5_DIGEST_LENGTH
|
||||||
|
#define MD5_DIGEST_LENGTH 16
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef SHA1_DIGEST_LENGTH
|
||||||
|
#define SHA1_DIGEST_LENGTH 20
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef SHA256_DIGEST_LENGTH
|
||||||
|
#define SHA256_DIGEST_LENGTH 32
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct Checksums
|
||||||
|
{
|
||||||
|
bool hasMd5;
|
||||||
|
bool hasSha1;
|
||||||
|
bool hasSha256;
|
||||||
|
bool hasSpamSum;
|
||||||
|
uint8_t md5[MD5_DIGEST_LENGTH];
|
||||||
|
uint8_t sha1[SHA1_DIGEST_LENGTH];
|
||||||
|
uint8_t sha256[SHA256_DIGEST_LENGTH];
|
||||||
|
uint8_t* spamsum;
|
||||||
|
} Checksums;
|
||||||
|
|
||||||
typedef struct aaruformatContext
|
typedef struct aaruformatContext
|
||||||
{
|
{
|
||||||
uint64_t magic;
|
uint64_t magic;
|
||||||
@@ -59,6 +83,7 @@ typedef struct aaruformatContext
|
|||||||
bool* readableSectorTags;
|
bool* readableSectorTags;
|
||||||
struct CacheHeader blockHeaderCache;
|
struct CacheHeader blockHeaderCache;
|
||||||
struct CacheHeader blockCache;
|
struct CacheHeader blockCache;
|
||||||
|
struct Checksums checksums;
|
||||||
} aaruformatContext;
|
} aaruformatContext;
|
||||||
|
|
||||||
typedef struct dataLinkedList
|
typedef struct dataLinkedList
|
||||||
|
|||||||
@@ -141,6 +141,9 @@ int aaruf_close(void* context)
|
|||||||
free(ctx->eccCdContext);
|
free(ctx->eccCdContext);
|
||||||
ctx->eccCdContext = NULL;
|
ctx->eccCdContext = NULL;
|
||||||
|
|
||||||
|
free(ctx->checksums.spamsum);
|
||||||
|
ctx->checksums.spamsum = NULL;
|
||||||
|
|
||||||
// TODO: Free caches
|
// TODO: Free caches
|
||||||
|
|
||||||
free(context);
|
free(context);
|
||||||
|
|||||||
80
src/open.c
80
src/open.c
@@ -45,6 +45,8 @@ void* aaruf_open(const char* filepath)
|
|||||||
uint16_t e;
|
uint16_t e;
|
||||||
uint8_t lzmaProperties[LZMA_PROPERTIES_LENGTH];
|
uint8_t lzmaProperties[LZMA_PROPERTIES_LENGTH];
|
||||||
size_t lzmaSize;
|
size_t lzmaSize;
|
||||||
|
ChecksumHeader checksum_header;
|
||||||
|
ChecksumEntry* checksum_entry;
|
||||||
|
|
||||||
ctx = (aaruformatContext*)malloc(sizeof(aaruformatContext));
|
ctx = (aaruformatContext*)malloc(sizeof(aaruformatContext));
|
||||||
memset(ctx, 0, sizeof(aaruformatContext));
|
memset(ctx, 0, sizeof(aaruformatContext));
|
||||||
@@ -1405,6 +1407,84 @@ void* aaruf_open(const char* filepath)
|
|||||||
// TODO: qsort()
|
// TODO: qsort()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case ChecksumBlock:
|
||||||
|
readBytes = fread(&checksum_header, 1, sizeof(ChecksumHeader), ctx->imageStream);
|
||||||
|
|
||||||
|
if(readBytes != sizeof(ChecksumHeader))
|
||||||
|
{
|
||||||
|
memset(&checksum_header, 0, sizeof(ChecksumHeader));
|
||||||
|
fprintf(stderr, "libaaruformat: Could not read checksums block header, continuing...\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(checksum_header.identifier != ChecksumBlock)
|
||||||
|
{
|
||||||
|
memset(&checksum_header, 0, sizeof(ChecksumHeader));
|
||||||
|
fprintf(stderr,
|
||||||
|
"libaaruformat: Incorrect identifier for checksum block at position %" PRIu64 "\n",
|
||||||
|
idxEntries[i].offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
data = (uint8_t*)malloc(checksum_header.length);
|
||||||
|
|
||||||
|
if(data == NULL)
|
||||||
|
{
|
||||||
|
memset(&checksum_header, 0, sizeof(ChecksumHeader));
|
||||||
|
fprintf(stderr, "libaaruformat: Could not allocate memory for checksum block, continuing...\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
readBytes = fread(data, 1, checksum_header.length, ctx->imageStream);
|
||||||
|
|
||||||
|
if(readBytes != checksum_header.length)
|
||||||
|
{
|
||||||
|
memset(&checksum_header, 0, sizeof(ChecksumHeader));
|
||||||
|
free(data);
|
||||||
|
fprintf(stderr, "libaaruformat: Could not read checksums block, continuing...\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
pos = 0;
|
||||||
|
for(j = 0; j < checksum_header.entries; j++)
|
||||||
|
{
|
||||||
|
checksum_entry = (ChecksumEntry*)(&data[pos]);
|
||||||
|
pos += sizeof(ChecksumEntry);
|
||||||
|
|
||||||
|
if(checksum_entry->type == Md5)
|
||||||
|
{
|
||||||
|
memcpy(ctx->checksums.md5, &data[pos], MD5_DIGEST_LENGTH);
|
||||||
|
ctx->checksums.hasMd5 = true;
|
||||||
|
}
|
||||||
|
else if(checksum_entry->type == Sha1)
|
||||||
|
{
|
||||||
|
memcpy(ctx->checksums.sha1, &data[pos], SHA1_DIGEST_LENGTH);
|
||||||
|
ctx->checksums.hasSha1 = true;
|
||||||
|
}
|
||||||
|
else if(checksum_entry->type == Sha256)
|
||||||
|
{
|
||||||
|
memcpy(ctx->checksums.sha256, &data[pos], SHA256_DIGEST_LENGTH);
|
||||||
|
ctx->checksums.hasSha256 = true;
|
||||||
|
}
|
||||||
|
else if(checksum_entry->type == SpamSum)
|
||||||
|
{
|
||||||
|
ctx->checksums.spamsum = malloc(checksum_entry->length + 1);
|
||||||
|
|
||||||
|
if(ctx->checksums.spamsum != NULL)
|
||||||
|
{
|
||||||
|
memcpy(ctx->checksums.spamsum, &data[pos], checksum_entry->length);
|
||||||
|
ctx->checksums.hasSpamSum = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx->checksums.spamsum[checksum_entry->length] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
pos += checksum_entry->length;
|
||||||
|
}
|
||||||
|
|
||||||
|
checksum_entry = NULL;
|
||||||
|
free(data);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
|
|||||||
@@ -4,5 +4,5 @@ find_package(ICU COMPONENTS uc REQUIRED)
|
|||||||
|
|
||||||
include_directories(${ICU_INCLUDE_DIRS})
|
include_directories(${ICU_INCLUDE_DIRS})
|
||||||
|
|
||||||
add_executable(aaruformattool main.c main.h aaruformattool.h identify.c info.c)
|
add_executable(aaruformattool main.c main.h aaruformattool.h identify.c info.c helpers.c)
|
||||||
target_link_libraries(aaruformattool "aaruformat" ICU::uc)
|
target_link_libraries(aaruformattool "aaruformat" ICU::uc)
|
||||||
|
|||||||
@@ -19,7 +19,8 @@
|
|||||||
#ifndef LIBAARUFORMAT_TOOL_AARUFORMATTOOL_H_
|
#ifndef LIBAARUFORMAT_TOOL_AARUFORMATTOOL_H_
|
||||||
#define LIBAARUFORMAT_TOOL_AARUFORMATTOOL_H_
|
#define LIBAARUFORMAT_TOOL_AARUFORMATTOOL_H_
|
||||||
|
|
||||||
int identify(char* path);
|
int identify(char* path);
|
||||||
int info(char *path);
|
int info(char* path);
|
||||||
|
char* byte_array_to_hex_string(const unsigned char* array, int array_size);
|
||||||
|
|
||||||
#endif // LIBAARUFORMAT_TOOL_AARUFORMATTOOL_H_
|
#endif // LIBAARUFORMAT_TOOL_AARUFORMATTOOL_H_
|
||||||
|
|||||||
52
tool/helpers.c
Normal file
52
tool/helpers.c
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the Aaru Data Preservation Suite.
|
||||||
|
* Copyright (c) 2019-2022 Natalia Portillo.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "aaruformattool.h"
|
||||||
|
|
||||||
|
char* byte_array_to_hex_string(const unsigned char* array, int array_size)
|
||||||
|
{
|
||||||
|
char* hex_string = NULL;
|
||||||
|
int j;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
hex_string = malloc(array_size * 2 + 1);
|
||||||
|
|
||||||
|
if(hex_string == NULL) return NULL;
|
||||||
|
|
||||||
|
j = 0;
|
||||||
|
for(i = 0; i < array_size; i++)
|
||||||
|
{
|
||||||
|
hex_string[j] = (array[i] >> 4) + '0';
|
||||||
|
if(hex_string[j] > '9') hex_string[j] += 0x7;
|
||||||
|
|
||||||
|
j++;
|
||||||
|
|
||||||
|
hex_string[j] = (array[i] & 0xF) + '0';
|
||||||
|
if(hex_string[j] > '9') hex_string[j] += 0x7;
|
||||||
|
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
|
||||||
|
hex_string[j] = 0;
|
||||||
|
|
||||||
|
return hex_string;
|
||||||
|
}
|
||||||
33
tool/info.c
33
tool/info.c
@@ -23,6 +23,8 @@
|
|||||||
|
|
||||||
#include <aaruformat.h>
|
#include <aaruformat.h>
|
||||||
|
|
||||||
|
#include "aaruformattool.h"
|
||||||
|
|
||||||
int info(char* path)
|
int info(char* path)
|
||||||
{
|
{
|
||||||
aaruformatContext* ctx;
|
aaruformatContext* ctx;
|
||||||
@@ -287,11 +289,11 @@ int info(char* path)
|
|||||||
printf("\tTrack entry %d:\n", i);
|
printf("\tTrack entry %d:\n", i);
|
||||||
printf("\t\tSequence: %d\n", ctx->trackEntries[i].sequence);
|
printf("\t\tSequence: %d\n", ctx->trackEntries[i].sequence);
|
||||||
printf("\t\tType: %d\n", ctx->trackEntries[i].type);
|
printf("\t\tType: %d\n", ctx->trackEntries[i].type);
|
||||||
printf("\t\tStart: %d\n", ctx->trackEntries[i].start);
|
printf("\t\tStart: %ld\n", ctx->trackEntries[i].start);
|
||||||
printf("\t\tEnd: %d\n", ctx->trackEntries[i].end);
|
printf("\t\tEnd: %ld\n", ctx->trackEntries[i].end);
|
||||||
printf("\t\tPregap: %d\n", ctx->trackEntries[i].pregap);
|
printf("\t\tPregap: %ld\n", ctx->trackEntries[i].pregap);
|
||||||
printf("\t\tSession: %d\n", ctx->trackEntries[i].session);
|
printf("\t\tSession: %d\n", ctx->trackEntries[i].session);
|
||||||
printf("\t\tISRC: %0.13s\n", ctx->trackEntries[i].isrc);
|
printf("\t\tISRC: %.13s\n", ctx->trackEntries[i].isrc);
|
||||||
printf("\t\tFlags: %d\n", ctx->trackEntries[i].flags);
|
printf("\t\tFlags: %d\n", ctx->trackEntries[i].flags);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -507,6 +509,29 @@ int info(char* path)
|
|||||||
ctx->imageInfo.Heads,
|
ctx->imageInfo.Heads,
|
||||||
ctx->imageInfo.SectorsPerTrack);
|
ctx->imageInfo.SectorsPerTrack);
|
||||||
|
|
||||||
|
if(ctx->checksums.hasMd5)
|
||||||
|
{
|
||||||
|
strBuffer = byte_array_to_hex_string(ctx->checksums.md5, MD5_DIGEST_LENGTH);
|
||||||
|
printf("MD5: %s\n", strBuffer);
|
||||||
|
free(strBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ctx->checksums.hasSha1)
|
||||||
|
{
|
||||||
|
strBuffer = byte_array_to_hex_string(ctx->checksums.sha1, SHA1_DIGEST_LENGTH);
|
||||||
|
printf("SHA1: %s\n", strBuffer);
|
||||||
|
free(strBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ctx->checksums.hasSha256)
|
||||||
|
{
|
||||||
|
strBuffer = byte_array_to_hex_string(ctx->checksums.sha256, SHA256_DIGEST_LENGTH);
|
||||||
|
printf("SHA256: %s\n", strBuffer);
|
||||||
|
free(strBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ctx->checksums.hasSpamSum) printf("SpamSum: %s\n", ctx->checksums.spamsum);
|
||||||
|
|
||||||
aaruf_close(ctx);
|
aaruf_close(ctx);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user