libaaruformat 1.0 Aaru Data Preservation Suite - Format Library

Loading...
Searching...
No Matches
tape.c
Go to the documentation of this file.
1/*
2 * This file is part of the Aaru Data Preservation Suite.
3 * Copyright (c) 2019-2025 Natalia Portillo.
4 *
5 * This library is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU Lesser General Public License as
7 * published by the Free Software Foundation; either version 2.1 of the
8 * License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
17 * */
18
19#include "aaruformat.h"
20#include "log.h"
21
126 void process_tape_files_block(aaruformat_context *ctx, const IndexEntry *entry)
127{
128 long pos = 0;
129 size_t read_bytes = 0;
130 TapeFileHeader tape_file_header = {0};
131
132 // Check if the context and image stream are valid
133 if(ctx == NULL || ctx->imageStream == NULL)
134 {
135 FATAL("Invalid context or image stream.");
136 return;
137 }
138
139 // Seek to block
140 pos = fseek(ctx->imageStream, entry->offset, SEEK_SET);
141 if(pos < 0 || ftell(ctx->imageStream) != entry->offset)
142 {
143 FATAL("Could not seek to %" PRIu64 " as indicated by index entry...", entry->offset);
144
145 return;
146 }
147
148 // Even if those two checks shall have been done before
149 read_bytes = fread(&tape_file_header, 1, sizeof(TapeFileHeader), ctx->imageStream);
150
151 if(read_bytes != sizeof(TapeFileHeader))
152 {
153 TRACE("Could not read tape files header, continuing...");
154 return;
155 }
156
157 if(tape_file_header.identifier != TapeFileBlock)
158 {
159 TRACE("Incorrect identifier for data block at position %" PRIu64 "\n", entry->offset);
160 return;
161 }
162
163 ctx->image_info.ImageSize += sizeof(TapeFileEntry) * tape_file_header.entries;
164
165 uint8_t *buffer = malloc(sizeof(TapeFileEntry) * tape_file_header.entries);
166 if(buffer == NULL)
167 {
168 FATAL("Could not allocate memory for tape files block, continuing...");
169 return;
170 }
171 read_bytes = fread(buffer, sizeof(TapeFileEntry), tape_file_header.entries, ctx->imageStream);
172 if(read_bytes != tape_file_header.entries)
173 {
174 free(buffer);
175 FATAL("Could not read tape files block, continuing...");
176 return;
177 }
178 // Check CRC64
179 uint64_t crc64 = aaruf_crc64_data(buffer, sizeof(TapeFileEntry) * tape_file_header.entries);
180
181 if(crc64 != tape_file_header.crc64)
182 {
183 TRACE("Incorrect CRC found: 0x%" PRIx64 " found, expected 0x%" PRIx64 ", continuing...", crc64,
184 tape_file_header.crc64);
185 free(buffer);
186 return;
187 }
188
189 // Insert entries into UTHASH array indexed by partition << 32 | file number
190 const TapeFileEntry *entries = (TapeFileEntry *)buffer;
191
192 for(uint32_t i = 0; i < tape_file_header.entries; i++)
193 {
194 // Create hash table entry
195 tapeFileHashEntry *hash_entry = malloc(sizeof(tapeFileHashEntry));
196 if(hash_entry == NULL)
197 {
198 FATAL("Could not allocate memory for tape file hash entry");
199 continue;
200 }
201
202 // Create composite key: partition << 32 | file number
203 hash_entry->key = (uint64_t)entries[i].Partition << 32 | entries[i].File;
204
205 // Copy the tape file entry data
206 hash_entry->fileEntry = entries[i];
207
208 // Replace if exists, add if new
209 tapeFileHashEntry *old_entry = NULL;
210 HASH_REPLACE(hh, ctx->tape_files, key, sizeof(uint64_t), hash_entry, old_entry);
211
212 // Free old entry if it was replaced
213 if(old_entry != NULL)
214 {
215 TRACE("Replaced existing tape file entry for partition %u, file %u", entries[i].Partition, entries[i].File);
216 free(old_entry);
217 }
218 else
219 TRACE("Added new tape file entry for partition %u, file %u", entries[i].Partition, entries[i].File);
220 }
221
222 free(buffer);
223}
224
346 void process_tape_partitions_block(aaruformat_context *ctx, const IndexEntry *entry)
347{
348 long pos = 0;
349 size_t read_bytes = 0;
350 TapePartitionHeader tape_partition_header = {0};
351
352 // Check if the context and image stream are valid
353 if(ctx == NULL || ctx->imageStream == NULL)
354 {
355 FATAL("Invalid context or image stream.");
356 return;
357 }
358
359 // Seek to block
360 pos = fseek(ctx->imageStream, entry->offset, SEEK_SET);
361 if(pos < 0 || ftell(ctx->imageStream) != entry->offset)
362 {
363 FATAL("Could not seek to %" PRIu64 " as indicated by index entry...", entry->offset);
364
365 return;
366 }
367
368 // Even if those two checks shall have been done before
369 read_bytes = fread(&tape_partition_header, 1, sizeof(TapePartitionHeader), ctx->imageStream);
370
371 if(read_bytes != sizeof(TapePartitionHeader))
372 {
373 TRACE("Could not read tape partitions header, continuing...");
374 return;
375 }
376
377 if(tape_partition_header.identifier != TapePartitionBlock)
378 {
379 TRACE("Incorrect identifier for data block at position %" PRIu64 "\n", entry->offset);
380 return;
381 }
382
383 ctx->image_info.ImageSize += sizeof(TapePartitionEntry) * tape_partition_header.entries;
384
385 uint8_t *buffer = malloc(sizeof(TapePartitionEntry) * tape_partition_header.entries);
386 if(buffer == NULL)
387 {
388 FATAL("Could not allocate memory for tape partitions block, continuing...");
389 return;
390 }
391 read_bytes = fread(buffer, sizeof(TapePartitionEntry), tape_partition_header.entries, ctx->imageStream);
392 if(read_bytes != tape_partition_header.entries)
393 {
394 free(buffer);
395 FATAL("Could not read tape partitions block, continuing...");
396 return;
397 }
398 // Check CRC64
399 uint64_t crc64 = aaruf_crc64_data(buffer, sizeof(TapePartitionEntry) * tape_partition_header.entries);
400
401 if(crc64 != tape_partition_header.crc64)
402 {
403 TRACE("Incorrect CRC found: 0x%" PRIx64 " found, expected 0x%" PRIx64 ", continuing...", crc64,
404 tape_partition_header.crc64);
405 free(buffer);
406 return;
407 }
408
409 // Insert entries into UTHASH array indexed by partition
410 const TapePartitionEntry *entries = (TapePartitionEntry *)buffer;
411
412 for(uint32_t i = 0; i < tape_partition_header.entries; i++)
413 {
414 // Create hash table entry
415 TapePartitionHashEntry *hash_entry = malloc(sizeof(TapePartitionHashEntry));
416 if(hash_entry == NULL)
417 {
418 FATAL("Could not allocate memory for tape partition hash entry");
419 continue;
420 }
421
422 // Create key: partition
423 hash_entry->key = entries[i].Number;
424
425 // Copy the tape partition entry data
426 hash_entry->partitionEntry = entries[i];
427
428 // Replace if exists, add if new
429 TapePartitionHashEntry *old_entry = NULL;
430 HASH_REPLACE(hh, ctx->tape_partitions, key, sizeof(uint8_t), hash_entry, old_entry);
431
432 // Free old entry if it was replaced
433 if(old_entry != NULL)
434 {
435 TRACE("Replaced existing tape partition entry for partition %u", entries[i].Number);
436 free(old_entry);
437 }
438 else
439 TRACE("Added new tape partition entry for partition %u", entries[i].Number);
440 }
441
442 free(buffer);
443}
444
569 AARU_EXPORT int32_t AARU_CALL aaruf_get_tape_file(const void *context, const uint8_t partition, const uint32_t file,
570 uint64_t *starting_block, uint64_t *ending_block)
571{
572 TRACE("Entering aaruf_get_tape_file(%p, %d, %d, %llu, %llu)", context, partition, file, *starting_block,
573 *ending_block);
574
575 const aaruformat_context *ctx = NULL;
576
577 if(context == NULL)
578 {
579 FATAL("Invalid context");
580
581 TRACE("Exiting aaruf_get_tape_file() = AARUF_ERROR_NOT_AARUFORMAT");
582 return AARUF_ERROR_NOT_AARUFORMAT;
583 }
584
585 ctx = context;
586
587 // Not a libaaruformat context
588 if(ctx->magic != AARU_MAGIC)
589 {
590 FATAL("Invalid context");
591
592 TRACE("Exiting aaruf_get_tape_file() = AARUF_ERROR_NOT_AARUFORMAT");
593 return AARUF_ERROR_NOT_AARUFORMAT;
594 }
595
596 uint64_t key = (uint64_t)partition << 32 | file;
597 tapeFileHashEntry *entry = NULL;
598 HASH_FIND(hh, ctx->tape_files, &key, sizeof(uint64_t), entry);
599
600 if(entry == NULL)
601 {
602 TRACE("Tape file not found");
603 return AARUF_ERROR_TAPE_FILE_NOT_FOUND;
604 }
605
606 *starting_block = entry->fileEntry.FirstBlock;
607 *ending_block = entry->fileEntry.LastBlock;
608
609 TRACE("Exiting aaruf_get_tape_file(%p, %d, %d, %llu, %llu) = AARUF_STATUS_OK", context, partition, file,
610 *starting_block, *ending_block);
611 return AARUF_STATUS_OK;
612}
613
770 AARU_EXPORT int32_t AARU_CALL aaruf_set_tape_file(void *context, const uint8_t partition, const uint32_t file,
771 const uint64_t starting_block, const uint64_t ending_block)
772{
773 TRACE("Entering aaruf_set_tape_file(%p, %d, %d, %llu, %llu)", context, partition, file, starting_block,
774 ending_block);
775
776 aaruformat_context *ctx = NULL;
777
778 if(context == NULL)
779 {
780 FATAL("Invalid context");
781
782 TRACE("Exiting aaruf_set_tape_file() = AARUF_ERROR_NOT_AARUFORMAT");
783 return AARUF_ERROR_NOT_AARUFORMAT;
784 }
785
786 ctx = context;
787
788 // Not a libaaruformat context
789 if(ctx->magic != AARU_MAGIC)
790 {
791 FATAL("Invalid context");
792
793 TRACE("Exiting aaruf_set_tape_file() = AARUF_ERROR_NOT_AARUFORMAT");
794 return AARUF_ERROR_NOT_AARUFORMAT;
795 }
796
797 // Check we are writing
798 if(!ctx->is_writing)
799 {
800 FATAL("Trying to write a read-only image");
801
802 TRACE("Exiting aaruf_set_tape_file() = AARUF_READ_ONLY");
803 return AARUF_READ_ONLY;
804 }
805
806 // Create hash table entry
807 tapeFileHashEntry *hash_entry = malloc(sizeof(tapeFileHashEntry));
808 if(hash_entry == NULL)
809 {
810 FATAL("Could not allocate memory for tape file hash entry");
811
812 TRACE("Exiting aaruf_set_tape_file() = AARUF_ERROR_NOT_ENOUGH_MEMORY");
813 return AARUF_ERROR_NOT_ENOUGH_MEMORY;
814 }
815
816 // Create composite key: partition << 32 | file number
817 hash_entry->key = (uint64_t)partition << 32 | file;
818
819 // Copy the tape file entry data
820 hash_entry->fileEntry.File = file;
821 hash_entry->fileEntry.Partition = partition;
822 hash_entry->fileEntry.FirstBlock = starting_block;
823 hash_entry->fileEntry.LastBlock = ending_block;
824
825 // Replace if exists, add if new
826 tapeFileHashEntry *old_entry = NULL;
827 HASH_REPLACE(hh, ctx->tape_files, key, sizeof(uint64_t), hash_entry, old_entry);
828
829 // Free old entry if it was replaced
830 if(old_entry != NULL)
831 {
832 TRACE("Replaced existing tape file entry for partition %u, file %u", partition, file);
833 free(old_entry);
834 }
835 else
836 TRACE("Added new tape file entry for partition %u, file %u", partition, file);
837
838 TRACE("Exiting aaruf_set_tape_file(%p, %d, %d, %llu, %llu) = AARUF_STATUS_OK", context, partition, file,
839 starting_block, ending_block);
840 return AARUF_STATUS_OK;
841}
842
982 AARU_EXPORT int32_t AARU_CALL aaruf_get_tape_partition(const void *context, const uint8_t partition,
983 uint64_t *starting_block, uint64_t *ending_block)
984{
985 TRACE("Entering aaruf_get_tape_partition(%p, %d, %llu, %llu)", context, partition, *starting_block, *ending_block);
986
987 const aaruformat_context *ctx = NULL;
988
989 if(context == NULL)
990 {
991 FATAL("Invalid context");
992
993 TRACE("Exiting aaruf_get_tape_partition() = AARUF_ERROR_NOT_AARUFORMAT");
994 return AARUF_ERROR_NOT_AARUFORMAT;
995 }
996
997 ctx = context;
998
999 // Not a libaaruformat context
1000 if(ctx->magic != AARU_MAGIC)
1001 {
1002 FATAL("Invalid context");
1003
1004 TRACE("Exiting aaruf_get_tape_partition() = AARUF_ERROR_NOT_AARUFORMAT");
1005 return AARUF_ERROR_NOT_AARUFORMAT;
1006 }
1007
1008 uint8_t key = partition;
1009 TapePartitionHashEntry *entry = NULL;
1010 HASH_FIND(hh, ctx->tape_partitions, &key, sizeof(uint8_t), entry);
1011
1012 if(entry == NULL)
1013 {
1014 TRACE("Tape partition not found");
1015 return AARUF_ERROR_TAPE_PARTITION_NOT_FOUND;
1016 }
1017
1018 *starting_block = entry->partitionEntry.FirstBlock;
1019 *ending_block = entry->partitionEntry.LastBlock;
1020
1021 TRACE("Exiting aaruf_get_tape_partition(%p, %d, %llu, %llu) = AARUF_STATUS_OK", context, partition, *starting_block,
1022 *ending_block);
1023 return AARUF_STATUS_OK;
1024}
1025
1196 AARU_EXPORT int32_t AARU_CALL aaruf_set_tape_partition(void *context, const uint8_t partition,
1197 const uint64_t starting_block, const uint64_t ending_block)
1198{
1199 TRACE("Entering aaruf_set_tape_partition(%p, %d, %llu, %llu)", context, partition, starting_block, ending_block);
1200
1201 aaruformat_context *ctx = NULL;
1202
1203 if(context == NULL)
1204 {
1205 FATAL("Invalid context");
1206
1207 TRACE("Exiting aaruf_set_tape_partition() = AARUF_ERROR_NOT_AARUFORMAT");
1208 return AARUF_ERROR_NOT_AARUFORMAT;
1209 }
1210
1211 ctx = context;
1212
1213 // Not a libaaruformat context
1214 if(ctx->magic != AARU_MAGIC)
1215 {
1216 FATAL("Invalid context");
1217
1218 TRACE("Exiting aaruf_set_tape_partition() = AARUF_ERROR_NOT_AARUFORMAT");
1219 return AARUF_ERROR_NOT_AARUFORMAT;
1220 }
1221
1222 // Check we are writing
1223 if(!ctx->is_writing)
1224 {
1225 FATAL("Trying to write a read-only image");
1226
1227 TRACE("Exiting aaruf_set_tape_partition() = AARUF_READ_ONLY");
1228 return AARUF_READ_ONLY;
1229 }
1230
1231 // Create hash table entry
1232 TapePartitionHashEntry *hash_entry = malloc(sizeof(TapePartitionHashEntry));
1233 if(hash_entry == NULL)
1234 {
1235 FATAL("Could not allocate memory for tape partition hash entry");
1236
1237 TRACE("Exiting aaruf_set_tape_partition() = AARUF_ERROR_NOT_ENOUGH_MEMORY");
1238 return AARUF_ERROR_NOT_ENOUGH_MEMORY;
1239 }
1240
1241 // Create key: partition
1242 hash_entry->key = partition;
1243
1244 // Copy the tape partition entry data
1245 hash_entry->partitionEntry.Number = partition;
1246 hash_entry->partitionEntry.FirstBlock = starting_block;
1247 hash_entry->partitionEntry.LastBlock = ending_block;
1248
1249 // Replace if exists, add if new
1250 TapePartitionHashEntry *old_entry = NULL;
1251 HASH_REPLACE(hh, ctx->tape_partitions, key, sizeof(uint8_t), hash_entry, old_entry);
1252
1253 // Free old entry if it was replaced
1254 if(old_entry != NULL)
1255 {
1256 TRACE("Replaced existing tape partition entry for partition %u", partition);
1257 free(old_entry);
1258 }
1259 else
1260 TRACE("Added new tape partition entry for partition %u", partition);
1261
1262 TRACE("Exiting aaruf_set_tape_partition(%p, %d, %llu, %llu) = AARUF_STATUS_OK", context, partition, starting_block,
1263 ending_block);
1264 return AARUF_STATUS_OK;
1265}
1266
1314 AARU_EXPORT int32_t AARU_CALL aaruf_get_all_tape_files(const void *context, uint8_t *buffer, size_t *length)
1315{
1316 TRACE("Entering aaruf_get_all_tape_files(%p, %p, %zu)", context, buffer, (length ? *length : 0));
1317
1318 // Check context is correct AaruFormat context
1319 if(context == NULL)
1320 {
1321 FATAL("Invalid context");
1322 TRACE("Exiting aaruf_get_all_tape_files() = AARUF_ERROR_NOT_AARUFORMAT");
1323 return AARUF_ERROR_NOT_AARUFORMAT;
1324 }
1325
1326 const aaruformat_context *ctx = context;
1327
1328 // Not a libaaruformat context
1329 if(ctx->magic != AARU_MAGIC)
1330 {
1331 FATAL("Invalid context");
1332 TRACE("Exiting aaruf_get_all_tape_files() = AARUF_ERROR_NOT_AARUFORMAT");
1333 return AARUF_ERROR_NOT_AARUFORMAT;
1334 }
1335
1336 if(ctx->tape_files == NULL)
1337 {
1338 FATAL("Image contains no tape files");
1339 TRACE("Exiting aaruf_get_all_tape_files() = AARUF_ERROR_TAPE_FILE_NOT_FOUND");
1340 return AARUF_ERROR_TAPE_FILE_NOT_FOUND;
1341 }
1342
1343 // Iterate all tape files to count how many do we have
1344 const size_t count = HASH_COUNT(ctx->tape_files);
1345 const size_t required_size = count * sizeof(TapeFileEntry);
1346
1347 if(buffer == NULL || length == NULL || *length < required_size)
1348 {
1349 if(length) *length = required_size;
1350 TRACE("Buffer too small for tape files, required %zu bytes", required_size);
1351 TRACE("Exiting aaruf_get_all_tape_files() = AARUF_ERROR_BUFFER_TOO_SMALL");
1352 return AARUF_ERROR_BUFFER_TOO_SMALL;
1353 }
1354
1355 size_t index = 0;
1356 const tapeFileHashEntry *entry;
1357 const tapeFileHashEntry *tmp;
1358 HASH_ITER(hh, ctx->tape_files, entry, tmp)
1359 {
1360 if(index < count)
1361 {
1362 memcpy(&((TapeFileEntry *)buffer)[index], &entry->fileEntry, sizeof(TapeFileEntry));
1363 index++;
1364 }
1365 }
1366 *length = required_size;
1367
1368 TRACE("Exiting aaruf_get_all_tape_files(%p, %p, %zu) = AARUF_STATUS_OK", context, buffer, *length);
1369 return AARUF_STATUS_OK;
1370}
1371
1416 AARU_EXPORT int32_t AARU_CALL aaruf_get_all_tape_partitions(const void *context, uint8_t *buffer, size_t *length)
1417{
1418 TRACE("Entering aaruf_get_all_tape_partitions(%p, %p, %zu)", context, buffer, (length ? *length : 0));
1419
1420 // Check context is correct AaruFormat context
1421 if(context == NULL)
1422 {
1423 FATAL("Invalid context");
1424 TRACE("Exiting aaruf_get_all_tape_partitions() = AARUF_ERROR_NOT_AARUFORMAT");
1425 return AARUF_ERROR_NOT_AARUFORMAT;
1426 }
1427
1428 const aaruformat_context *ctx = context;
1429
1430 // Not a libaaruformat context
1431 if(ctx->magic != AARU_MAGIC)
1432 {
1433 FATAL("Invalid context");
1434 TRACE("Exiting aaruf_get_all_tape_partitions() = AARUF_ERROR_NOT_AARUFORMAT");
1435 return AARUF_ERROR_NOT_AARUFORMAT;
1436 }
1437
1438 if(ctx->tape_partitions == NULL)
1439 {
1440 FATAL("Image contains no tape partitions");
1441 TRACE("Exiting aaruf_get_all_tape_partitions() = AARUF_ERROR_TAPE_PARTITION_NOT_FOUND");
1442 return AARUF_ERROR_TAPE_PARTITION_NOT_FOUND;
1443 }
1444
1445 // Iterate all tape partitions to count how many do we have
1446 const size_t count = HASH_COUNT(ctx->tape_partitions);
1447 const size_t required_size = count * sizeof(TapePartitionEntry);
1448
1449 if(buffer == NULL || length == NULL || *length < required_size)
1450 {
1451 if(length) *length = required_size;
1452 TRACE("Buffer too small for tape partitions, required %zu bytes", required_size);
1453 TRACE("Exiting aaruf_get_all_tape_partitions() = AARUF_ERROR_BUFFER_TOO_SMALL");
1454 return AARUF_ERROR_BUFFER_TOO_SMALL;
1455 }
1456
1457 size_t index = 0;
1458 const TapePartitionHashEntry *entry;
1459 const TapePartitionHashEntry *tmp;
1460 HASH_ITER(hh, ctx->tape_partitions, entry, tmp)
1461 {
1462 if(index < count)
1463 {
1464 memcpy(&((TapePartitionEntry *)buffer)[index], &entry->partitionEntry, sizeof(TapePartitionEntry));
1465 index++;
1466 }
1467 }
1468 *length = required_size;
1469
1470 TRACE("Exiting aaruf_get_all_tape_partitions(%p, %p, %zu) = AARUF_STATUS_OK", context, buffer, *length);
1471 return AARUF_STATUS_OK;
1472}
aaruformat.h
AARU_MAGIC
#define AARU_MAGIC
Magic identifier for AaruFormat container (ASCII "AARUFRMT").
Definition consts.h:64
tapeFileHashEntry
struct TapeFileHashEntry tapeFileHashEntry
AARU_CALL
#define AARU_CALL
Definition decls.h:45
aaruf_crc64_data
uint64_t aaruf_crc64_data(const uint8_t *data, uint32_t len)
Definition crc64.c:160
AARU_EXPORT
#define AARU_EXPORT
Definition decls.h:54
TapePartitionBlock
@ TapePartitionBlock
Block containing list of partitions for a tape image.
Definition enums.h:158
TapeFileBlock
@ TapeFileBlock
Block containing list of files for a tape image.
Definition enums.h:157
AARUF_ERROR_TAPE_PARTITION_NOT_FOUND
#define AARUF_ERROR_TAPE_PARTITION_NOT_FOUND
Requested tape partition not present in image.
Definition errors.h:68
AARUF_STATUS_OK
#define AARUF_STATUS_OK
Sector present and read without uncorrectable errors.
Definition errors.h:75
AARUF_READ_ONLY
#define AARUF_READ_ONLY
Operation requires write mode but context is read-only.
Definition errors.h:61
AARUF_ERROR_NOT_ENOUGH_MEMORY
#define AARUF_ERROR_NOT_ENOUGH_MEMORY
Memory allocation failure (critical).
Definition errors.h:48
AARUF_ERROR_TAPE_FILE_NOT_FOUND
#define AARUF_ERROR_TAPE_FILE_NOT_FOUND
Requested tape file number not present in image.
Definition errors.h:67
AARUF_ERROR_NOT_AARUFORMAT
#define AARUF_ERROR_NOT_AARUFORMAT
Input file/stream failed magic or structural validation.
Definition errors.h:40
AARUF_ERROR_BUFFER_TOO_SMALL
#define AARUF_ERROR_BUFFER_TOO_SMALL
Caller-supplied buffer insufficient for data.
Definition errors.h:49
log.h
FATAL
#define FATAL(fmt,...)
Definition log.h:40
TRACE
#define TRACE(fmt,...)
Definition log.h:25
ImageInfo::ImageSize
uint64_t ImageSize
Size of the image payload in bytes (excludes headers/metadata)
Definition aaru.h:873
IndexEntry
Single index entry describing a block's type, (optional) data classification, and file offset.
Definition index.h:109
IndexEntry::offset
uint64_t offset
Absolute byte offset in the image where the referenced block header begins.
Definition index.h:112
TapeFileEntry
Describes a single logical file on a tape medium.
Definition tape.h:134
TapeFileEntry::File
uint32_t File
File number (unique within the partition).
Definition tape.h:135
TapeFileEntry::LastBlock
uint64_t LastBlock
Last block of the file (inclusive).
Definition tape.h:142
TapeFileEntry::FirstBlock
uint64_t FirstBlock
First block of the file (inclusive).
Definition tape.h:139
TapeFileEntry::Partition
uint8_t Partition
Partition number containing this file.
Definition tape.h:137
TapeFileHashEntry::key
uint64_t key
Composite key: partition << 32 | file.
Definition context.h:128
TapeFileHashEntry::fileEntry
TapeFileEntry fileEntry
The actual tape file data.
Definition context.h:129
TapeFileHeader
Header for a tape file metadata block containing file layout information.
Definition tape.h:238
TapeFileHeader::entries
uint32_t entries
Number of file entries following this header.
Definition tape.h:241
TapeFileHeader::identifier
uint32_t identifier
Block type identifier.
Definition tape.h:239
TapeFileHeader::crc64
uint64_t crc64
CRC64-ECMA checksum of the entry data.
Definition tape.h:245
TapePartitionEntry
Describes a single physical partition on a tape medium.
Definition tape.h:320
TapePartitionEntry::LastBlock
uint64_t LastBlock
Last block in the partition (inclusive).
Definition tape.h:325
TapePartitionEntry::FirstBlock
uint64_t FirstBlock
First block in the partition (inclusive).
Definition tape.h:323
TapePartitionEntry::Number
uint8_t Number
Partition number (unique identifier for this partition).
Definition tape.h:321
TapePartitionHashEntry
Definition context.h:134
TapePartitionHashEntry::key
uint8_t key
Key: partition.
Definition context.h:135
TapePartitionHashEntry::partitionEntry
TapePartitionEntry partitionEntry
The actual tape partition data.
Definition context.h:136
TapePartitionHeader
Header for a tape partition metadata block containing partition layout information.
Definition tape.h:441
TapePartitionHeader::crc64
uint64_t crc64
CRC64-ECMA checksum of the entry data.
Definition tape.h:448
TapePartitionHeader::entries
uint8_t entries
Number of partition entries following this header.
Definition tape.h:444
TapePartitionHeader::identifier
uint32_t identifier
Block type identifier.
Definition tape.h:442
aaruformat_context
Master context representing an open or in‑creation Aaru image.
Definition context.h:172
aaruformat_context::tape_files
tapeFileHashEntry * tape_files
Hash table root for tape files.
Definition context.h:302
aaruformat_context::is_writing
bool is_writing
True if context opened/created for writing.
Definition context.h:292
aaruformat_context::magic
uint64_t magic
File magic (AARU_MAGIC) post-open.
Definition context.h:174
aaruformat_context::imageStream
FILE * imageStream
Underlying FILE* stream (binary mode).
Definition context.h:176
aaruformat_context::image_info
ImageInfo image_info
Exposed high-level image info summary.
Definition context.h:260
aaruformat_context::tape_partitions
TapePartitionHashEntry * tape_partitions
Hash table root for tape partitions.
Definition context.h:303
aaruf_set_tape_file
int32_t aaruf_set_tape_file(void *context, const uint8_t partition, const uint32_t file, const uint64_t starting_block, const uint64_t ending_block)
Sets or updates the block range for a specific tape file in an Aaru tape image.
Definition tape.c:770
aaruf_get_all_tape_partitions
int32_t aaruf_get_all_tape_partitions(const void *context, uint8_t *buffer, size_t *length)
Retrieves all tape partition entries from the image.
Definition tape.c:1416
aaruf_get_tape_file
int32_t aaruf_get_tape_file(const void *context, const uint8_t partition, const uint32_t file, uint64_t *starting_block, uint64_t *ending_block)
Retrieves the block range for a specific tape file from an Aaru tape image.
Definition tape.c:569
process_tape_files_block
void process_tape_files_block(aaruformat_context *ctx, const IndexEntry *entry)
Processes a tape file metadata block from the image stream.
Definition tape.c:126
aaruf_get_tape_partition
int32_t aaruf_get_tape_partition(const void *context, const uint8_t partition, uint64_t *starting_block, uint64_t *ending_block)
Retrieves the block range for a specific tape partition from an Aaru tape image.
Definition tape.c:982
aaruf_set_tape_partition
int32_t aaruf_set_tape_partition(void *context, const uint8_t partition, const uint64_t starting_block, const uint64_t ending_block)
Sets or updates the block range for a specific tape partition in an Aaru tape image.
Definition tape.c:1196
process_tape_partitions_block
void process_tape_partitions_block(aaruformat_context *ctx, const IndexEntry *entry)
Processes a tape partition metadata block from the image stream.
Definition tape.c:346
aaruf_get_all_tape_files
int32_t aaruf_get_all_tape_files(const void *context, uint8_t *buffer, size_t *length)
Retrieves all tape file entries from the image.
Definition tape.c:1314