Initial implementation of MD5 checksums for session and single data files.
To be activated by macro Libisofs_with_checksumS. New AAIP attributes "isfs.ca" and "isofs.cx". New API calls iso_image_get_session_md5() and iso_file_get_md5().
This commit is contained in:
parent
55690756ae
commit
b5f4a66c59
@ -12,6 +12,93 @@ specification of AAIP :
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
Name:
|
||||
isofs.ca
|
||||
|
||||
Purpose:
|
||||
Records the range of checksummed image data (START, END), the number
|
||||
of checksum items (COUNT), the number of bytes in a single checksum item
|
||||
(SIZE), and the name of the checksum algorithm (CHECKSUM_TYPE).
|
||||
END is also the block address of the start of the checksum recording
|
||||
area in the image.
|
||||
See also isofs.cx .
|
||||
|
||||
Format of Value:
|
||||
START_LEN | START_BYTES | END_LEN | END_BYTES |
|
||||
COUNT_LEN | COUNT_BYTES | SIZE_LEN | SIZE_BYTES | CHECKSUM_TYPE
|
||||
Each number is encoded as _LEN byte and _BYTES value string.
|
||||
The _LEN fields comply to ISO 9660 Format section 7.1.1.
|
||||
The byte strings START_BYTES, END_BYTES, COUNT_BYTES, SIZE_BYTES begin
|
||||
with the most significant byte. Leading zero bytes are allowed.
|
||||
CHECKSUM_TYPE consists of the bytes after
|
||||
START_LEN + END_LEN + COUNT_LEN + SIZE_LEN + 4.
|
||||
It shall be a string of printable characters without terminating 0-byte.
|
||||
Type names shall be registered here.
|
||||
For now there is:
|
||||
"MD5" 128 bit message digest, see RFC 1321, see man md5sum
|
||||
|
||||
Example:
|
||||
LBA range 32 to 1000000 , 520 checksums recorded, MD5
|
||||
{ 1, 32,
|
||||
3, 15, 66, 64,
|
||||
2, 2, 8,
|
||||
1, 16,
|
||||
'M', 'D', '5' }
|
||||
or
|
||||
{ 4, 0, 0, 0, 32,
|
||||
4, 0, 15, 66, 64,
|
||||
4, 0, 0, 2, 8,
|
||||
1, 16,
|
||||
'M', 'D', '5' }
|
||||
|
||||
Registered:
|
||||
16 Jul 2009 by Thomas Schmitt for libisofs.
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
Name:
|
||||
isofs.cs
|
||||
|
||||
Purpose:
|
||||
Records the name of the character set that was used as output character
|
||||
set when writing the RRIP name tree of the ISO 9660 image. It shall be
|
||||
suitable as parameter for function iconv_open(3).
|
||||
This attribute shall eventually be attached to the root directory entry
|
||||
and be global for the whole image.
|
||||
|
||||
Format of Value:
|
||||
Shall hold the character set name without terminating 0-byte.
|
||||
|
||||
Example:
|
||||
{ 'I', 'S', 'O', '-', '8', '8', '5', '9' , '-', '1' }
|
||||
|
||||
Registered:
|
||||
18 Mar 2009 by Thomas Schmitt for libisofs.
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
Name:
|
||||
isofs.cx
|
||||
|
||||
Purpose:
|
||||
Records the index of the file's checksum in the checksum area at the
|
||||
end of the image. The byte address of the checksum is
|
||||
checksum_area_lba * 2048 + isofs.cx * checksum_size
|
||||
Default checksum algorithm is MD5 with a size of 16 byte.
|
||||
See also isofs.ca .
|
||||
|
||||
Format of Value:
|
||||
A byte string which begins with the most significant byte.
|
||||
|
||||
Example:
|
||||
Index 123456
|
||||
{ 1, 226, 64 }
|
||||
|
||||
Registered:
|
||||
16 Jul 2009 by Thomas Schmitt for libisofs.
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
Name:
|
||||
isofs.di
|
||||
|
||||
@ -34,27 +121,6 @@ Registered:
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
Name:
|
||||
isofs.cs
|
||||
|
||||
Purpose:
|
||||
Records the name of the character set that was used as output character
|
||||
set when writing the RRIP name tree of the ISO 9660 image. It shall be
|
||||
suitable as parameter for function iconv_open(3).
|
||||
This attribute shall eventually be attached to the root directory entry
|
||||
and be global for the whole image.
|
||||
|
||||
Format of Value:
|
||||
Shall hold the character set name without terminating 0-byte.
|
||||
|
||||
Example:
|
||||
{ 'I', 'S', 'O', '-', '8', '8', '5', '9' , '-', '1' }
|
||||
|
||||
Registered:
|
||||
18 Mar 2009 by Thomas Schmitt for libisofs.
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
Name:
|
||||
isofs.st
|
||||
|
||||
|
@ -27,6 +27,10 @@
|
||||
#include "util.h"
|
||||
#include "system_area.h"
|
||||
|
||||
#ifdef Libisofs_with_checksumS
|
||||
#include "md5.h"
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <string.h>
|
||||
@ -57,6 +61,14 @@ void ecma119_image_free(Ecma119Image *t)
|
||||
}
|
||||
free(t->input_charset);
|
||||
free(t->output_charset);
|
||||
|
||||
#ifdef Libisofs_with_checksumS
|
||||
if (t->checksum_ctx != NULL) /* dispose checksum context */
|
||||
libisofs_md5(&(t->checksum_ctx), NULL, 0, NULL, (1 << 15));
|
||||
if (t->checksum_buffer != NULL)
|
||||
free(t->checksum_buffer);
|
||||
#endif
|
||||
|
||||
free(t->writers);
|
||||
free(t);
|
||||
}
|
||||
@ -294,7 +306,7 @@ void write_one_dir_record(Ecma119Image *t, Ecma119Node *node, int file_id,
|
||||
rec->len_dr[0] = len_dr + (info != NULL ? info->suf_len : 0);
|
||||
iso_bb(rec->block, block, 4);
|
||||
iso_bb(rec->length, len, 4);
|
||||
if(t->dir_rec_mtime) {
|
||||
if (t->dir_rec_mtime) {
|
||||
iso= node->node;
|
||||
iso_datetime_7(rec->recording_time,
|
||||
t->replace_timestamps ? t->timestamp : iso->mtime,
|
||||
@ -860,6 +872,79 @@ void *write_function(void *arg)
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
|
||||
|
||||
#ifdef Libisofs_with_checksumS
|
||||
|
||||
|
||||
static
|
||||
int checksum_prepare_image(IsoImage *src, int flag)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Set provisory value of isofs.ca with
|
||||
4 byte LBA, 4 byte count, size 16, name MD5 */
|
||||
ret = iso_root_set_isofsca((IsoNode *) src->root, 0, 0, 0, 16, "MD5", 0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
@flag bit0= recursion
|
||||
*/
|
||||
static
|
||||
int checksum_prepare_nodes(IsoImage *img, IsoNode *node, int flag)
|
||||
{
|
||||
IsoNode *pos;
|
||||
IsoFile *file;
|
||||
int ret, i;
|
||||
size_t value_length;
|
||||
unsigned int idx = 0;
|
||||
char *value;
|
||||
void *xipt = NULL;
|
||||
|
||||
if (node->type == LIBISO_FILE) {
|
||||
file = (IsoFile *) node;
|
||||
if (file->from_old_session) {
|
||||
/* Save eventual MD5 data of files from old image */
|
||||
value= NULL;
|
||||
ret = iso_node_lookup_attr(node, "isofs.cx", &value_length,
|
||||
&value, 0);
|
||||
if (ret == 1 && value_length == 4) {
|
||||
for (i = 0; i < 4; i++)
|
||||
idx = (idx << 8) | ((unsigned char *) value)[i];
|
||||
if (idx > 0 && idx < 0x8000000) {
|
||||
/* xipt is an int disguised as void pointer */
|
||||
for (i = 0; i < 4; i++)
|
||||
((char *) &xipt)[i] = value[i];
|
||||
ret = iso_node_add_xinfo(node, checksum_xinfo_func,
|
||||
xipt);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
if (value != NULL)
|
||||
free(value);
|
||||
}
|
||||
/* Equip all nodes with provisory isofs.cx numbers: 4 byte, all 0. */
|
||||
ret = iso_file_set_isofscx(file, (unsigned int) 0, 0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
} else if (node->type == LIBISO_DIR) {
|
||||
for (pos = ((IsoDir *) node)->children; pos != NULL; pos = pos->next) {
|
||||
ret = checksum_prepare_nodes(img, pos, 1);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
#endif /* Libisofs_with_checksumS */
|
||||
|
||||
|
||||
static
|
||||
int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
|
||||
{
|
||||
@ -951,6 +1036,18 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
|
||||
return ISO_OUT_OF_MEM;
|
||||
}
|
||||
|
||||
#ifdef Libisofs_with_checksumS
|
||||
|
||||
/* >>> need an IsoWriteOpts component to control this */;
|
||||
target->md5_checksums = 1;
|
||||
|
||||
target->checksum_idx_counter = 0;
|
||||
target->checksum_ctx = NULL;
|
||||
target->checksum_counter = 0;
|
||||
target->checksum_buffer = NULL;
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* 2. Based on those options, create needed writers: iso, joliet...
|
||||
* Each writer inits its structures and stores needed info into
|
||||
@ -974,6 +1071,25 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
|
||||
nwriters++;
|
||||
}
|
||||
|
||||
|
||||
#ifdef Libisofs_with_checksumS
|
||||
|
||||
if (target->md5_checksums) {
|
||||
nwriters++;
|
||||
ret = checksum_prepare_image(src, 0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
if (target->appendable) {
|
||||
ret = checksum_prepare_nodes(src, (IsoNode *) src->root, 0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
target->checksum_idx_counter = 0;
|
||||
}
|
||||
|
||||
#endif /* Libisofs_with_checksumS */
|
||||
|
||||
|
||||
target->writers = malloc(nwriters * sizeof(void*));
|
||||
if (target->writers == NULL) {
|
||||
iso_image_unref(src);
|
||||
@ -1019,7 +1135,7 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
|
||||
|
||||
/*
|
||||
* Create the writer for possible padding to ensure that in case of image
|
||||
* growing we can safety overwrite the first 64 KiB of image.
|
||||
* growing we can safely overwrite the first 64 KiB of image.
|
||||
*/
|
||||
ret = pad_writer_create(target);
|
||||
if (ret < 0) {
|
||||
@ -1033,6 +1149,20 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
|
||||
}
|
||||
file_src_writer_index = target->nwriters - 1;
|
||||
|
||||
|
||||
#ifdef Libisofs_with_checksumS
|
||||
|
||||
/* ??? Is it safe to add a writer after the content writer ? */
|
||||
|
||||
if (target->md5_checksums) {
|
||||
ret = checksum_writer_create(target);
|
||||
if (ret < 0)
|
||||
goto target_cleanup;
|
||||
}
|
||||
|
||||
#endif /* Libisofs_with_checksumS */
|
||||
|
||||
|
||||
/*
|
||||
* 3.
|
||||
* Call compute_data_blocks() in each Writer.
|
||||
@ -1140,7 +1270,15 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
|
||||
target->vol_space_size = target->curblock - target->ms_block;
|
||||
target->total_size = (off_t) target->vol_space_size * BLOCK_SIZE;
|
||||
|
||||
/* 4. Create and start writting thread */
|
||||
|
||||
/* 4. Create and start writing thread */
|
||||
|
||||
#ifdef Libisofs_with_checksumS
|
||||
/* After any fake writes are done: Initialize image checksum context */
|
||||
ret = libisofs_md5(&(target->checksum_ctx), NULL, 0, NULL, 1);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
#endif /* Libisofs_with_checksumS */
|
||||
|
||||
/* ensure the thread is created joinable */
|
||||
pthread_attr_init(&(target->th_attr));
|
||||
@ -1306,6 +1444,17 @@ int iso_write(Ecma119Image *target, void *buf, size_t count)
|
||||
return ISO_CANCELED;
|
||||
}
|
||||
|
||||
#ifdef Libisofs_with_checksumS
|
||||
|
||||
if (target->checksum_ctx != NULL) {
|
||||
/* Add to image checksum */
|
||||
target->checksum_counter += count;
|
||||
libisofs_md5(&(target->checksum_ctx), (char *) buf, (int) count,
|
||||
NULL, 0);
|
||||
}
|
||||
|
||||
#endif /* Libisofs_with_checksumS */
|
||||
|
||||
/* total size is 0 when writing the overwrite buffer */
|
||||
if (ret > 0 && (target->total_size != (off_t) 0)){
|
||||
unsigned int kbw, kbt;
|
||||
@ -1710,7 +1859,7 @@ int iso_write_opts_set_fifo_size(IsoWriteOpts *opts, size_t fifo_size)
|
||||
int iso_write_opts_get_data_start(IsoWriteOpts *opts, uint32_t *data_start,
|
||||
int flag)
|
||||
{
|
||||
if(opts->data_start_lba == 0)
|
||||
if (opts->data_start_lba == 0)
|
||||
return ISO_ERROR;
|
||||
*data_start = opts->data_start_lba;
|
||||
return ISO_SUCCESS;
|
||||
|
@ -312,6 +312,12 @@ struct ecma119_image
|
||||
/* Store in ECMA-119 timestamp mtime of source */
|
||||
unsigned int dir_rec_mtime :1;
|
||||
|
||||
#ifdef Libisofs_with_checksumS
|
||||
|
||||
unsigned int md5_checksums :1;
|
||||
|
||||
#endif /* Libisofs_with_checksumS */
|
||||
|
||||
/*
|
||||
* Mode replace. If one of these flags is set, the correspodent values are
|
||||
* replaced with values below.
|
||||
@ -421,6 +427,16 @@ struct ecma119_image
|
||||
/* tree of files sources */
|
||||
IsoRBTree *files;
|
||||
|
||||
#ifdef Libisofs_with_checksumS
|
||||
|
||||
unsigned int checksum_idx_counter;
|
||||
void *checksum_ctx;
|
||||
off_t checksum_counter;
|
||||
char image_md5[16];
|
||||
char *checksum_buffer;
|
||||
|
||||
#endif /* Libisofs_with_checksumS */
|
||||
|
||||
/* Buffer for communication between burn_source and writer thread */
|
||||
IsoRingBuffer *buffer;
|
||||
|
||||
|
@ -14,6 +14,10 @@
|
||||
#include "image.h"
|
||||
#include "stream.h"
|
||||
|
||||
#ifdef Libisofs_with_checksumS
|
||||
#include "md5.h"
|
||||
#endif /* Libisofs_with_checksumS */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
@ -44,6 +48,10 @@ int iso_file_src_create(Ecma119Image *img, IsoFile *file, IsoFileSrc **src)
|
||||
dev_t dev_id;
|
||||
ino_t ino_id;
|
||||
|
||||
#ifdef Libisofs_with_checksumS
|
||||
int cret;
|
||||
#endif
|
||||
|
||||
if (img == NULL || file == NULL || src == NULL) {
|
||||
return ISO_NULL_POINTER;
|
||||
}
|
||||
@ -88,11 +96,42 @@ int iso_file_src_create(Ecma119Image *img, IsoFile *file, IsoFileSrc **src)
|
||||
/* insert the filesrc in the tree */
|
||||
ret = iso_rbtree_insert(img->files, fsrc, (void**)src);
|
||||
if (ret <= 0) {
|
||||
|
||||
#ifdef Libisofs_with_checksumS
|
||||
|
||||
if (ret == 0) {
|
||||
/* Duplicate file source was mapped to previously registered source
|
||||
*/
|
||||
cret = iso_file_set_isofscx(file, (*src)->checksum_index, 0);
|
||||
if (cret < 0)
|
||||
ret = cret;
|
||||
}
|
||||
|
||||
#endif /* Libisofs_with_checksumS */
|
||||
|
||||
free(fsrc->sections);
|
||||
free(fsrc);
|
||||
return ret;
|
||||
}
|
||||
iso_stream_ref(fsrc->stream);
|
||||
|
||||
#ifdef Libisofs_with_checksumS
|
||||
|
||||
if(img->md5_checksums) {
|
||||
img->checksum_idx_counter++;
|
||||
if (img->checksum_idx_counter < 0x80000000) {
|
||||
fsrc->checksum_index= img->checksum_idx_counter;
|
||||
} else {
|
||||
fsrc->checksum_index= 0;
|
||||
img->checksum_idx_counter= 0x80000000; /* keep from rolling over */
|
||||
}
|
||||
cret = iso_file_set_isofscx(file, (*src)->checksum_index, 0);
|
||||
if (cret < 0)
|
||||
return cret;
|
||||
}
|
||||
|
||||
#endif /* Libisofs_with_checksumS */
|
||||
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
@ -276,6 +315,14 @@ int filesrc_writer_write_data(IsoImageWriter *writer)
|
||||
IsoFileSrc **filelist;
|
||||
char name[PATH_MAX];
|
||||
char buffer[BLOCK_SIZE];
|
||||
off_t file_size;
|
||||
uint32_t nblocks;
|
||||
|
||||
#ifdef Libisofs_with_checksumS
|
||||
void *ctx= NULL;
|
||||
char md5[16];
|
||||
#endif
|
||||
|
||||
|
||||
if (writer == NULL) {
|
||||
return ISO_ASSERT_FAILURE;
|
||||
@ -288,8 +335,10 @@ int filesrc_writer_write_data(IsoImageWriter *writer)
|
||||
|
||||
i = 0;
|
||||
while ((file = filelist[i++]) != NULL) {
|
||||
file_size = iso_file_src_get_size(file);
|
||||
nblocks = DIV_UP(file_size, BLOCK_SIZE);
|
||||
|
||||
uint32_t nblocks = DIV_UP(iso_file_src_get_size(file), BLOCK_SIZE);
|
||||
/* >>> Eventually obtain an MD5 of content by a first read pass */;
|
||||
|
||||
res = filesrc_open(file);
|
||||
iso_stream_get_file_name(file->stream, name);
|
||||
@ -329,6 +378,18 @@ int filesrc_writer_write_data(IsoImageWriter *writer)
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef Libisofs_with_checksumS
|
||||
|
||||
if (file->checksum_index > 0) {
|
||||
/* initialize file checksum */
|
||||
res = libisofs_md5(&ctx, NULL, 0, md5, 1);
|
||||
if (res <= 0)
|
||||
file->checksum_index = 0;
|
||||
}
|
||||
|
||||
#endif /* Libisofs_with_checksumS */
|
||||
|
||||
/* write file contents to image */
|
||||
for (b = 0; b < nblocks; ++b) {
|
||||
int wres;
|
||||
@ -343,6 +404,21 @@ int filesrc_writer_write_data(IsoImageWriter *writer)
|
||||
filesrc_close(file);
|
||||
return wres;
|
||||
}
|
||||
|
||||
#ifdef Libisofs_with_checksumS
|
||||
|
||||
if (file->checksum_index > 0) {
|
||||
/* Add to file checksum */
|
||||
res = file_size - b * BLOCK_SIZE;
|
||||
if (res > BLOCK_SIZE)
|
||||
res = BLOCK_SIZE;
|
||||
res = libisofs_md5(&ctx, buffer, res, md5, 0);
|
||||
if (res <= 0)
|
||||
file->checksum_index = 0;
|
||||
}
|
||||
|
||||
#endif /* Libisofs_with_checksumS */
|
||||
|
||||
}
|
||||
|
||||
filesrc_close(file);
|
||||
@ -374,8 +450,41 @@ int filesrc_writer_write_data(IsoImageWriter *writer)
|
||||
/* ko, writer error, we need to go out! */
|
||||
return res;
|
||||
}
|
||||
|
||||
#ifdef Libisofs_with_checksumS
|
||||
|
||||
if (file->checksum_index > 0) {
|
||||
/* Add to file checksum */
|
||||
res = file_size - b * BLOCK_SIZE;
|
||||
if (res > BLOCK_SIZE)
|
||||
res = BLOCK_SIZE;
|
||||
res = libisofs_md5(&ctx, buffer, res, md5, 0);
|
||||
if (res <= 0)
|
||||
file->checksum_index = 0;
|
||||
}
|
||||
|
||||
#endif /* Libisofs_with_checksumS */
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef Libisofs_with_checksumS
|
||||
|
||||
if (file->checksum_index > 0) {
|
||||
/* Obtain checksum and dispose checksum context */
|
||||
res = libisofs_md5(&ctx, buffer, 0, md5, 2 | (1 << 15));
|
||||
if (res <= 0)
|
||||
file->checksum_index = 0;
|
||||
|
||||
/* >>> Eventually compare with MD5 of first read pass
|
||||
and issue error if mismatch */;
|
||||
|
||||
/* Write md5 into checksum buffer at file->checksum_index */
|
||||
memcpy(t->checksum_buffer + 16 * file->checksum_index, md5, 16);
|
||||
}
|
||||
|
||||
#endif /* Libisofs_with_checksumS */
|
||||
|
||||
}
|
||||
|
||||
return ISO_SUCCESS;
|
||||
@ -395,7 +504,7 @@ int iso_file_src_writer_create(Ecma119Image *target)
|
||||
|
||||
writer = malloc(sizeof(IsoImageWriter));
|
||||
if (writer == NULL) {
|
||||
return ISO_ASSERT_FAILURE;
|
||||
return ISO_OUT_OF_MEM;
|
||||
}
|
||||
|
||||
writer->compute_data_blocks = filesrc_writer_compute_data_blocks;
|
||||
|
@ -18,6 +18,13 @@ struct Iso_File_Src
|
||||
{
|
||||
unsigned int prev_img :1; /**< if the file comes from a previous image */
|
||||
|
||||
#ifdef Libisofs_with_checksumS
|
||||
|
||||
unsigned int checksum_index :31;
|
||||
|
||||
#endif /* Libisofs_with_checksumS */
|
||||
|
||||
|
||||
/** File Sections of the file in the image */
|
||||
struct iso_file_section *sections;
|
||||
int nsections;
|
||||
@ -43,7 +50,7 @@ int iso_file_src_cmp(const void *n1, const void *n2);
|
||||
* @param src
|
||||
* Will be filled with a pointer to the IsoFileSrc
|
||||
* @return
|
||||
* 1 on success, < 0 on error
|
||||
* 1 if new object was created, 0 if object existed, < 0 on error
|
||||
*/
|
||||
int iso_file_src_create(Ecma119Image *img, IsoFile *file, IsoFileSrc **src);
|
||||
|
||||
|
@ -2935,6 +2935,18 @@ int iso_image_import(IsoImage *image, IsoDataSource *src,
|
||||
_ImageFsData *data;
|
||||
struct el_torito_boot_catalog *oldbootcat;
|
||||
|
||||
#ifdef Libisofs_with_checksumS
|
||||
int i;
|
||||
uint32_t old_checksum_start_lba;
|
||||
uint32_t old_checksum_end_lba;
|
||||
uint32_t old_checksum_idx_count;
|
||||
char *old_checksum_array = NULL;
|
||||
char checksum_type[81];
|
||||
uint32_t checksum_size;
|
||||
size_t size;
|
||||
uint8_t *rpt;
|
||||
#endif
|
||||
|
||||
if (image == NULL || src == NULL || opts == NULL) {
|
||||
return ISO_NULL_POINTER;
|
||||
}
|
||||
@ -2956,9 +2968,16 @@ int iso_image_import(IsoImage *image, IsoDataSource *src,
|
||||
blback = image->builder;
|
||||
oldroot = image->root;
|
||||
oldbootcat = image->bootcat; /* could be NULL */
|
||||
|
||||
image->bootcat = NULL;
|
||||
|
||||
#ifdef Libisofs_with_checksumS
|
||||
old_checksum_start_lba = image->checksum_start_lba;
|
||||
old_checksum_end_lba = image->checksum_end_lba;
|
||||
old_checksum_idx_count = image->checksum_idx_count;
|
||||
old_checksum_array = image->checksum_array;
|
||||
image->checksum_array = NULL;
|
||||
#endif
|
||||
|
||||
/* create new builder */
|
||||
ret = iso_image_builder_new(blback, &image->builder);
|
||||
if (ret < 0) {
|
||||
@ -3119,7 +3138,7 @@ int iso_image_import(IsoImage *image, IsoDataSource *src,
|
||||
*features = malloc(sizeof(IsoReadImageFeatures));
|
||||
if (*features == NULL) {
|
||||
ret = ISO_OUT_OF_MEM;
|
||||
goto import_cleanup;
|
||||
goto import_revert;
|
||||
}
|
||||
(*features)->hasJoliet = data->joliet;
|
||||
(*features)->hasRR = data->rr_version != 0;
|
||||
@ -3128,6 +3147,39 @@ int iso_image_import(IsoImage *image, IsoDataSource *src,
|
||||
(*features)->size = data->nblocks;
|
||||
}
|
||||
|
||||
#ifdef Libisofs_with_checksumS
|
||||
|
||||
/* Read checksum buffer */
|
||||
|
||||
/* >>> needs to be controlled by iso_read_opts */;
|
||||
|
||||
ret = iso_root_get_isofsca((IsoNode *) image->root,
|
||||
&(image->checksum_start_lba),
|
||||
&(image->checksum_end_lba),
|
||||
&(image->checksum_idx_count),
|
||||
&checksum_size, checksum_type, 0);
|
||||
if (ret > 0)
|
||||
if (checksum_size != 16 || strcmp(checksum_type, "MD5") != 0)
|
||||
ret = 0;
|
||||
if (ret > 0) {
|
||||
size = image->checksum_idx_count / 128 + 1;
|
||||
image->checksum_array = calloc(size, 2048);
|
||||
if (image->checksum_array == NULL) {
|
||||
ret = ISO_OUT_OF_MEM;
|
||||
goto import_revert;
|
||||
}
|
||||
|
||||
/* Load from image->checksum_end_lba */;
|
||||
for (i = 0; i < size; i++) {
|
||||
rpt = (uint8_t *) (image->checksum_array + i * 2048);
|
||||
ret = src->read_block(src, image->checksum_end_lba + i, rpt);
|
||||
if (ret <= 0)
|
||||
goto import_revert;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* Libisofs_with_checksumS */
|
||||
|
||||
ret = ISO_SUCCESS;
|
||||
goto import_cleanup;
|
||||
|
||||
@ -3136,9 +3188,16 @@ int iso_image_import(IsoImage *image, IsoDataSource *src,
|
||||
iso_node_unref((IsoNode*)image->root);
|
||||
el_torito_boot_catalog_free(image->bootcat);
|
||||
image->root = oldroot;
|
||||
image->fs = fsback;
|
||||
image->bootcat = oldbootcat;
|
||||
|
||||
#ifdef Libisofs_with_checksumS
|
||||
old_checksum_start_lba = image->checksum_start_lba;
|
||||
old_checksum_end_lba = image->checksum_end_lba;
|
||||
old_checksum_idx_count = image->checksum_idx_count;
|
||||
image->checksum_array = old_checksum_array;
|
||||
old_checksum_array = NULL;
|
||||
#endif
|
||||
|
||||
import_cleanup:;
|
||||
|
||||
/* recover backed fs and builder */
|
||||
@ -3149,6 +3208,12 @@ int iso_image_import(IsoImage *image, IsoDataSource *src,
|
||||
fs->close(fs);
|
||||
iso_filesystem_unref(fs);
|
||||
|
||||
#ifdef Libisofs_with_checksumS
|
||||
if (old_checksum_array != NULL)
|
||||
free(old_checksum_array);
|
||||
#endif
|
||||
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -78,6 +78,14 @@ int iso_image_new(const char *name, IsoImage **image)
|
||||
img->inode_counter = 0;
|
||||
img->used_inodes = NULL;
|
||||
img->used_inodes_start = 0;
|
||||
|
||||
#ifdef Libisofs_with_checksumS
|
||||
img->checksum_start_lba = 0;
|
||||
img->checksum_end_lba = 0;
|
||||
img->checksum_idx_count = 0;
|
||||
img->checksum_array = NULL;
|
||||
#endif
|
||||
|
||||
*image = img;
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
@ -529,3 +537,25 @@ ex:;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* API */
|
||||
int iso_image_get_session_md5(IsoImage *image, uint32_t *start_lba,
|
||||
uint32_t *end_lba, char md5[16], int flag)
|
||||
{
|
||||
|
||||
#ifdef Libisofs_with_checksumS
|
||||
|
||||
if (image->checksum_array == NULL || image->checksum_idx_count < 1)
|
||||
return 0;
|
||||
*start_lba = image->checksum_start_lba;
|
||||
*end_lba = image->checksum_end_lba;
|
||||
memcpy(md5, image->checksum_array, 16);
|
||||
return ISO_SUCCESS;
|
||||
|
||||
#else
|
||||
|
||||
return 0;
|
||||
|
||||
#endif /* ! Libisofs_with_checksumS */
|
||||
|
||||
}
|
||||
|
@ -148,6 +148,22 @@ struct Iso_Image
|
||||
uint8_t *used_inodes;
|
||||
ino_t used_inodes_start;
|
||||
|
||||
#ifdef Libisofs_with_checksumS
|
||||
|
||||
/**
|
||||
* Array of MD5 checksums as announced by xattr "isofs.ca" of the
|
||||
* root node. Array element 0 contains an overall image checksum for the
|
||||
* block range checksum_start_lba,checksum_end_lba. Element size is
|
||||
* 16 bytes. IsoFile objects in the image may have xattr "isofs.cx"
|
||||
* which gives their index in checksum_array.
|
||||
*/
|
||||
uint32_t checksum_start_lba;
|
||||
uint32_t checksum_end_lba;
|
||||
uint32_t checksum_idx_count;
|
||||
char *checksum_array;
|
||||
|
||||
#endif /* Libisofs_with_checksumS */
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
@ -4442,7 +4442,11 @@ int iso_node_lookup_attr(IsoNode *node, char *name,
|
||||
* bit0= Do not maintain eventual existing ACL of the node.
|
||||
* Set eventual new ACL from value of empty name.
|
||||
* bit1= Do not clear the existing attribute list but merge it with
|
||||
* the list given by this call
|
||||
* the list given by this call.
|
||||
* The given values override the values of their eventually existing
|
||||
* names. If no xattr with a given name exists, then it will be
|
||||
* added as new xattr. So this bit can be used to set a single
|
||||
* xattr without inquiring any other xattr of the node.
|
||||
* bit2= Delete the attributes with the given names
|
||||
* bit3= Allow to affect non-user attributes.
|
||||
* I.e. those with a non-empty name which does not begin by "user."
|
||||
@ -4953,6 +4957,57 @@ int iso_file_add_gzip_filter(IsoFile *file, int flag);
|
||||
int iso_gzip_get_refcounts(off_t *gzip_count, off_t *gunzip_count, int flag);
|
||||
|
||||
|
||||
/* ---------------------------- MD5 Checksums --------------------------- */
|
||||
|
||||
|
||||
/**
|
||||
* Eventually obtain the recorded MD5 checksum of the session which was
|
||||
* loaded as ISO image. Such a checksum may be stored together with others
|
||||
* in a contiguous array at the end of the ISO image. The session checksum
|
||||
* covers the data blocks from address start_lba to address end_lba - 1.
|
||||
* It does not cover the recorded array of md5 checksums.
|
||||
* Layout, size, and position of the checksum array is recorded in the xattr
|
||||
* "isofs.ca" of the session root node.
|
||||
* @param image
|
||||
* The image to inquire
|
||||
* @param start_lba
|
||||
* Eventually returns the first block address covered by md5
|
||||
* @param start_lba
|
||||
* Eventually returns the first block address not covered by md5 any more
|
||||
* @param md5
|
||||
* Eventually returns 16 byte of MD5 checksum
|
||||
* @param flag
|
||||
* Bitfield for control purposes, unused yet, submit 0
|
||||
* @return
|
||||
* 1= md5 found , 0= no md5 available , <0 indicates error
|
||||
*
|
||||
* @since 0.6.22
|
||||
*/
|
||||
int iso_image_get_session_md5(IsoImage *image, uint32_t *start_lba,
|
||||
uint32_t *end_lba, char md5[16], int flag);
|
||||
|
||||
/**
|
||||
* Eventually obtain the recorded MD5 checksum of a data file from the loaded
|
||||
* ISO image. Such a checksum may be stored with others in a contiguous
|
||||
* array at the end of the ISO image. The data file eventually has an xattr
|
||||
* "isofs.cx" which gives the index in that array.
|
||||
* @param image
|
||||
* The image from which file stems.
|
||||
* @param file
|
||||
* The file object to inquire
|
||||
* @param md5
|
||||
* Eventually returns 16 byte of MD5 checksum
|
||||
* @param flag
|
||||
* Bitfield for control purposes, unused yet, submit 0
|
||||
* @return
|
||||
* 1= md5 found , 0= no md5 available , <0 indicates error
|
||||
*
|
||||
* @since 0.6.22
|
||||
*/
|
||||
int iso_file_get_md5(IsoImage *image, IsoFile *file, char md5[16], int flag);
|
||||
|
||||
|
||||
|
||||
/************ Error codes and return values for libisofs ********************/
|
||||
|
||||
/** successfully execution */
|
||||
@ -5412,12 +5467,9 @@ struct burn_source {
|
||||
|
||||
/* currently none being tested */
|
||||
|
||||
|
||||
/* ---------------------------- Improvements --------------------------- */
|
||||
|
||||
/* currently none being tested */
|
||||
|
||||
/* ---------------------------- Experiments ---------------------------- */
|
||||
|
||||
/* Hardlinks : During image generation accompany the tree of IsoFileSrc
|
||||
by a sorted array of Ecma119Node.
|
||||
The sorting order shall bring together candidates for being
|
||||
@ -5439,7 +5491,10 @@ struct burn_source {
|
||||
#define Libisofs_hardlink_prooF yes
|
||||
|
||||
|
||||
/* Experiment: Ignore PX inode numbers,
|
||||
/* ---------------------------- Experiments ---------------------------- */
|
||||
|
||||
/* <<< on its way out
|
||||
Experiment: Ignore PX inode numbers,
|
||||
have boot image inode number counted by fs_give_ino_number()
|
||||
|
||||
Overridden if Libisofs_hardlink_prooF is defined.
|
||||
@ -5455,5 +5510,14 @@ struct burn_source {
|
||||
*/
|
||||
|
||||
|
||||
/* Experiment: During image writing equip IsoFile objects with MD5 checksums
|
||||
and compute an overall checksum of the image. Store them in
|
||||
a separate checksum block area after the data area of the
|
||||
image.
|
||||
|
||||
ENABLE ONLY FOR DEVELOPMENT TESTS !
|
||||
#define Libisofs_with_checksumS yes
|
||||
*/
|
||||
|
||||
|
||||
#endif /*LIBISO_LIBISOFS_H_*/
|
||||
|
514
libisofs/md5.c
Normal file
514
libisofs/md5.c
Normal file
@ -0,0 +1,514 @@
|
||||
/*
|
||||
* Copyright (c) 2009 Thomas Schmitt
|
||||
*
|
||||
* This file is part of the libisofs project; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation. See COPYING file for details.
|
||||
*/
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "writer.h"
|
||||
#include "messages.h"
|
||||
#include "ecma119.h"
|
||||
#include "image.h"
|
||||
|
||||
#include "md5.h"
|
||||
|
||||
|
||||
/* This code is derived from RFC 1321 and implements computation of the
|
||||
"RSA Data Security, Inc. MD5 Message-Digest Algorithm" */
|
||||
|
||||
#define Libisofs_md5_S11 7
|
||||
#define Libisofs_md5_S12 12
|
||||
#define Libisofs_md5_S13 17
|
||||
#define Libisofs_md5_S14 22
|
||||
#define Libisofs_md5_S21 5
|
||||
#define Libisofs_md5_S22 9
|
||||
#define Libisofs_md5_S23 14
|
||||
#define Libisofs_md5_S24 20
|
||||
#define Libisofs_md5_S31 4
|
||||
#define Libisofs_md5_S32 11
|
||||
#define Libisofs_md5_S33 16
|
||||
#define Libisofs_md5_S34 23
|
||||
#define Libisofs_md5_S41 6
|
||||
#define Libisofs_md5_S42 10
|
||||
#define Libisofs_md5_S43 15
|
||||
#define Libisofs_md5_S44 21
|
||||
|
||||
|
||||
/* F, G, H and I are basic MD5 functions.
|
||||
*/
|
||||
#define Libisofs_md5_F(x, y, z) (((x) & (y)) | ((~x) & (z)))
|
||||
#define Libisofs_md5_G(x, y, z) (((x) & (z)) | ((y) & (~z)))
|
||||
#define Libisofs_md5_H(x, y, z) ((x) ^ (y) ^ (z))
|
||||
#define Libisofs_md5_I(x, y, z) ((y) ^ ((x) | (~z)))
|
||||
|
||||
/* ROTATE_LEFT rotates x left n bits.
|
||||
*/
|
||||
#define Libisofs_md5_ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
|
||||
|
||||
/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
|
||||
Rotation is separate from addition to prevent recomputation.
|
||||
*/
|
||||
#define Libisofs_md5_FF(a, b, c, d, x, s, ac) { \
|
||||
(a) += Libisofs_md5_F ((b), (c), (d)) + (x) + (uint32_t)(ac); \
|
||||
(a) = Libisofs_md5_ROTATE_LEFT ((a), (s)); \
|
||||
(a) += (b); \
|
||||
}
|
||||
#define Libisofs_md5_GG(a, b, c, d, x, s, ac) { \
|
||||
(a) += Libisofs_md5_G ((b), (c), (d)) + (x) + (uint32_t)(ac); \
|
||||
(a) = Libisofs_md5_ROTATE_LEFT ((a), (s)); \
|
||||
(a) += (b); \
|
||||
}
|
||||
#define Libisofs_md5_HH(a, b, c, d, x, s, ac) { \
|
||||
(a) += Libisofs_md5_H ((b), (c), (d)) + (x) + (uint32_t)(ac); \
|
||||
(a) = Libisofs_md5_ROTATE_LEFT ((a), (s)); \
|
||||
(a) += (b); \
|
||||
}
|
||||
#define Libisofs_md5_II(a, b, c, d, x, s, ac) { \
|
||||
(a) += Libisofs_md5_I ((b), (c), (d)) + (x) + (uint32_t)(ac); \
|
||||
(a) = Libisofs_md5_ROTATE_LEFT ((a), (s)); \
|
||||
(a) += (b); \
|
||||
}
|
||||
|
||||
|
||||
/* MD5 context. */
|
||||
struct _libisofs_md5_ctx {
|
||||
uint32_t state[4]; /* state (ABCD) */
|
||||
uint32_t count[2]; /* number of bits, modulo 2^64 (lsb first) */
|
||||
unsigned char buffer[64]; /* input buffer */
|
||||
};
|
||||
|
||||
typedef struct _libisofs_md5_ctx libisofs_md5_ctx;
|
||||
|
||||
|
||||
/* MD5 basic transformation. Transforms state based on block.
|
||||
*/
|
||||
static int md5__transform (uint32_t state[4], unsigned char block[64])
|
||||
{
|
||||
uint32_t a = state[0], b = state[1], c = state[2], d = state[3], x[16];
|
||||
unsigned int i, j;
|
||||
|
||||
for (i = 0, j = 0; j < 64; i++, j += 4)
|
||||
x[i] = ((uint32_t)block[j]) | (((uint32_t)block[j+1]) << 8) |
|
||||
(((uint32_t)block[j+2]) << 16) | (((uint32_t)block[j+3]) << 24);
|
||||
|
||||
/* Round 1 */
|
||||
Libisofs_md5_FF (a, b, c, d, x[ 0], Libisofs_md5_S11, 0xd76aa478); /* 1 */
|
||||
Libisofs_md5_FF (d, a, b, c, x[ 1], Libisofs_md5_S12, 0xe8c7b756); /* 2 */
|
||||
Libisofs_md5_FF (c, d, a, b, x[ 2], Libisofs_md5_S13, 0x242070db); /* 3 */
|
||||
Libisofs_md5_FF (b, c, d, a, x[ 3], Libisofs_md5_S14, 0xc1bdceee); /* 4 */
|
||||
Libisofs_md5_FF (a, b, c, d, x[ 4], Libisofs_md5_S11, 0xf57c0faf); /* 5 */
|
||||
Libisofs_md5_FF (d, a, b, c, x[ 5], Libisofs_md5_S12, 0x4787c62a); /* 6 */
|
||||
Libisofs_md5_FF (c, d, a, b, x[ 6], Libisofs_md5_S13, 0xa8304613); /* 7 */
|
||||
Libisofs_md5_FF (b, c, d, a, x[ 7], Libisofs_md5_S14, 0xfd469501); /* 8 */
|
||||
Libisofs_md5_FF (a, b, c, d, x[ 8], Libisofs_md5_S11, 0x698098d8); /* 9 */
|
||||
Libisofs_md5_FF (d, a, b, c, x[ 9], Libisofs_md5_S12, 0x8b44f7af); /* 10 */
|
||||
Libisofs_md5_FF (c, d, a, b, x[10], Libisofs_md5_S13, 0xffff5bb1); /* 11 */
|
||||
Libisofs_md5_FF (b, c, d, a, x[11], Libisofs_md5_S14, 0x895cd7be); /* 12 */
|
||||
Libisofs_md5_FF (a, b, c, d, x[12], Libisofs_md5_S11, 0x6b901122); /* 13 */
|
||||
Libisofs_md5_FF (d, a, b, c, x[13], Libisofs_md5_S12, 0xfd987193); /* 14 */
|
||||
Libisofs_md5_FF (c, d, a, b, x[14], Libisofs_md5_S13, 0xa679438e); /* 15 */
|
||||
Libisofs_md5_FF (b, c, d, a, x[15], Libisofs_md5_S14, 0x49b40821); /* 16 */
|
||||
|
||||
/* Round 2 */
|
||||
Libisofs_md5_GG (a, b, c, d, x[ 1], Libisofs_md5_S21, 0xf61e2562); /* 17 */
|
||||
Libisofs_md5_GG (d, a, b, c, x[ 6], Libisofs_md5_S22, 0xc040b340); /* 18 */
|
||||
Libisofs_md5_GG (c, d, a, b, x[11], Libisofs_md5_S23, 0x265e5a51); /* 19 */
|
||||
Libisofs_md5_GG (b, c, d, a, x[ 0], Libisofs_md5_S24, 0xe9b6c7aa); /* 20 */
|
||||
Libisofs_md5_GG (a, b, c, d, x[ 5], Libisofs_md5_S21, 0xd62f105d); /* 21 */
|
||||
Libisofs_md5_GG (d, a, b, c, x[10], Libisofs_md5_S22, 0x2441453); /* 22 */
|
||||
Libisofs_md5_GG (c, d, a, b, x[15], Libisofs_md5_S23, 0xd8a1e681); /* 23 */
|
||||
Libisofs_md5_GG (b, c, d, a, x[ 4], Libisofs_md5_S24, 0xe7d3fbc8); /* 24 */
|
||||
Libisofs_md5_GG (a, b, c, d, x[ 9], Libisofs_md5_S21, 0x21e1cde6); /* 25 */
|
||||
Libisofs_md5_GG (d, a, b, c, x[14], Libisofs_md5_S22, 0xc33707d6); /* 26 */
|
||||
Libisofs_md5_GG (c, d, a, b, x[ 3], Libisofs_md5_S23, 0xf4d50d87); /* 27 */
|
||||
Libisofs_md5_GG (b, c, d, a, x[ 8], Libisofs_md5_S24, 0x455a14ed); /* 28 */
|
||||
Libisofs_md5_GG (a, b, c, d, x[13], Libisofs_md5_S21, 0xa9e3e905); /* 29 */
|
||||
Libisofs_md5_GG (d, a, b, c, x[ 2], Libisofs_md5_S22, 0xfcefa3f8); /* 30 */
|
||||
Libisofs_md5_GG (c, d, a, b, x[ 7], Libisofs_md5_S23, 0x676f02d9); /* 31 */
|
||||
Libisofs_md5_GG (b, c, d, a, x[12], Libisofs_md5_S24, 0x8d2a4c8a); /* 32 */
|
||||
|
||||
/* Round 3 */
|
||||
Libisofs_md5_HH (a, b, c, d, x[ 5], Libisofs_md5_S31, 0xfffa3942); /* 33 */
|
||||
Libisofs_md5_HH (d, a, b, c, x[ 8], Libisofs_md5_S32, 0x8771f681); /* 34 */
|
||||
Libisofs_md5_HH (c, d, a, b, x[11], Libisofs_md5_S33, 0x6d9d6122); /* 35 */
|
||||
Libisofs_md5_HH (b, c, d, a, x[14], Libisofs_md5_S34, 0xfde5380c); /* 36 */
|
||||
Libisofs_md5_HH (a, b, c, d, x[ 1], Libisofs_md5_S31, 0xa4beea44); /* 37 */
|
||||
Libisofs_md5_HH (d, a, b, c, x[ 4], Libisofs_md5_S32, 0x4bdecfa9); /* 38 */
|
||||
Libisofs_md5_HH (c, d, a, b, x[ 7], Libisofs_md5_S33, 0xf6bb4b60); /* 39 */
|
||||
Libisofs_md5_HH (b, c, d, a, x[10], Libisofs_md5_S34, 0xbebfbc70); /* 40 */
|
||||
Libisofs_md5_HH (a, b, c, d, x[13], Libisofs_md5_S31, 0x289b7ec6); /* 41 */
|
||||
Libisofs_md5_HH (d, a, b, c, x[ 0], Libisofs_md5_S32, 0xeaa127fa); /* 42 */
|
||||
Libisofs_md5_HH (c, d, a, b, x[ 3], Libisofs_md5_S33, 0xd4ef3085); /* 43 */
|
||||
Libisofs_md5_HH (b, c, d, a, x[ 6], Libisofs_md5_S34, 0x4881d05); /* 44 */
|
||||
Libisofs_md5_HH (a, b, c, d, x[ 9], Libisofs_md5_S31, 0xd9d4d039); /* 45 */
|
||||
Libisofs_md5_HH (d, a, b, c, x[12], Libisofs_md5_S32, 0xe6db99e5); /* 46 */
|
||||
Libisofs_md5_HH (c, d, a, b, x[15], Libisofs_md5_S33, 0x1fa27cf8); /* 47 */
|
||||
Libisofs_md5_HH (b, c, d, a, x[ 2], Libisofs_md5_S34, 0xc4ac5665); /* 48 */
|
||||
|
||||
/* Round 4 */
|
||||
Libisofs_md5_II (a, b, c, d, x[ 0], Libisofs_md5_S41, 0xf4292244); /* 49 */
|
||||
Libisofs_md5_II (d, a, b, c, x[ 7], Libisofs_md5_S42, 0x432aff97); /* 50 */
|
||||
Libisofs_md5_II (c, d, a, b, x[14], Libisofs_md5_S43, 0xab9423a7); /* 51 */
|
||||
Libisofs_md5_II (b, c, d, a, x[ 5], Libisofs_md5_S44, 0xfc93a039); /* 52 */
|
||||
Libisofs_md5_II (a, b, c, d, x[12], Libisofs_md5_S41, 0x655b59c3); /* 53 */
|
||||
Libisofs_md5_II (d, a, b, c, x[ 3], Libisofs_md5_S42, 0x8f0ccc92); /* 54 */
|
||||
Libisofs_md5_II (c, d, a, b, x[10], Libisofs_md5_S43, 0xffeff47d); /* 55 */
|
||||
Libisofs_md5_II (b, c, d, a, x[ 1], Libisofs_md5_S44, 0x85845dd1); /* 56 */
|
||||
Libisofs_md5_II (a, b, c, d, x[ 8], Libisofs_md5_S41, 0x6fa87e4f); /* 57 */
|
||||
Libisofs_md5_II (d, a, b, c, x[15], Libisofs_md5_S42, 0xfe2ce6e0); /* 58 */
|
||||
Libisofs_md5_II (c, d, a, b, x[ 6], Libisofs_md5_S43, 0xa3014314); /* 59 */
|
||||
Libisofs_md5_II (b, c, d, a, x[13], Libisofs_md5_S44, 0x4e0811a1); /* 60 */
|
||||
Libisofs_md5_II (a, b, c, d, x[ 4], Libisofs_md5_S41, 0xf7537e82); /* 61 */
|
||||
Libisofs_md5_II (d, a, b, c, x[11], Libisofs_md5_S42, 0xbd3af235); /* 62 */
|
||||
Libisofs_md5_II (c, d, a, b, x[ 2], Libisofs_md5_S43, 0x2ad7d2bb); /* 63 */
|
||||
Libisofs_md5_II (b, c, d, a, x[ 9], Libisofs_md5_S44, 0xeb86d391); /* 64 */
|
||||
|
||||
state[0] += a;
|
||||
state[1] += b;
|
||||
state[2] += c;
|
||||
state[3] += d;
|
||||
|
||||
/* Zeroize sensitive information. */
|
||||
memset ((char *) x, 0, sizeof (x));
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
static int md5__encode(unsigned char *output, uint32_t *input,
|
||||
unsigned int len)
|
||||
{
|
||||
unsigned int i, j;
|
||||
|
||||
for (i = 0, j = 0; j < len; i++, j += 4) {
|
||||
output[j] = (unsigned char)(input[i] & 0xff);
|
||||
output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
|
||||
output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
|
||||
output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
|
||||
}
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int md5_init(libisofs_md5_ctx *ctx, int flag)
|
||||
{
|
||||
ctx->count[0] = ctx->count[1] = 0;
|
||||
/* Load magic initialization constants. */
|
||||
ctx->state[0] = 0x67452301;
|
||||
ctx->state[1] = 0xefcdab89;
|
||||
ctx->state[2] = 0x98badcfe;
|
||||
ctx->state[3] = 0x10325476;
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
/* MD5 block update operation. Continues an MD5 message-digest
|
||||
operation, processing another message block, and updating the
|
||||
context.
|
||||
*/
|
||||
static int md5_update(libisofs_md5_ctx *ctx, unsigned char *data,
|
||||
int datalen, int flag)
|
||||
{
|
||||
unsigned int i, index, partlen;
|
||||
|
||||
/* Compute number of bytes mod 64 */
|
||||
index = (unsigned int)((ctx->count[0] >> 3) & 0x3F);
|
||||
/* Update number of bits */
|
||||
if ((ctx->count[0] += ((uint32_t) datalen << 3)) <
|
||||
((uint32_t) datalen << 3))
|
||||
ctx->count[1]++;
|
||||
ctx->count[1] += ((uint32_t) datalen >> 29);
|
||||
partlen = 64 - index;
|
||||
|
||||
/* Transform as many times as possible. */
|
||||
if (datalen >= partlen) {
|
||||
memcpy((char *) &ctx->buffer[index], (char *) data, partlen);
|
||||
md5__transform(ctx->state, ctx->buffer);
|
||||
for (i = partlen; i + 63 < datalen; i += 64)
|
||||
md5__transform(ctx->state, &data[i]);
|
||||
index = 0;
|
||||
} else
|
||||
i = 0;
|
||||
|
||||
/* Buffer remaining data */
|
||||
memcpy((char *) &ctx->buffer[index], (char *) &data[i],datalen-i);
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
static int md5_final(libisofs_md5_ctx *ctx, char result[16], int flag)
|
||||
{
|
||||
unsigned char bits[8], *respt;
|
||||
unsigned int index, padlen;
|
||||
static unsigned char PADDING[64] = {
|
||||
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
/* Save number of bits */
|
||||
md5__encode(bits, ctx->count, 8);
|
||||
/* Pad out to 56 mod 64. */
|
||||
index = (unsigned int)((ctx->count[0] >> 3) & 0x3f);
|
||||
padlen = (index < 56) ? (56 - index) : (120 - index);
|
||||
md5_update(ctx, PADDING, padlen,0);
|
||||
/* Append length (before padding) */
|
||||
md5_update(ctx, bits, 8,0);
|
||||
/* Store state in result */
|
||||
respt= (unsigned char *) result;
|
||||
md5__encode(respt, ctx->state, 16);
|
||||
/* Zeroize sensitive information. */
|
||||
memset ((char *) ctx, 0, sizeof (*ctx));
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
int libisofs_md5(void **ctx_in, char *data, int datalen,
|
||||
char result[16], int flag)
|
||||
/* *ctx has to be NULL or point to freeable memory */
|
||||
/*
|
||||
bit0= allocate and init *ctx
|
||||
bit1= transfer ctx to result
|
||||
bit2= with bit 0 : clone new *ctx from data
|
||||
bit15= free *ctx
|
||||
*/
|
||||
{
|
||||
unsigned char *datapt;
|
||||
libisofs_md5_ctx **ctx;
|
||||
|
||||
ctx= (libisofs_md5_ctx **) ctx_in;
|
||||
if(flag&1) {
|
||||
if(*ctx!=NULL)
|
||||
free((char *) *ctx);
|
||||
*ctx= calloc(1, sizeof(libisofs_md5_ctx));
|
||||
if(*ctx==NULL)
|
||||
return(-1);
|
||||
md5_init(*ctx,0);
|
||||
if(flag&4)
|
||||
memcpy((char *) *ctx,data,sizeof(libisofs_md5_ctx));
|
||||
}
|
||||
if(*ctx==NULL)
|
||||
return(0);
|
||||
if(datalen>0) {
|
||||
datapt= (unsigned char *) data;
|
||||
md5_update(*ctx, datapt, datalen, 0);
|
||||
}
|
||||
if(flag&2)
|
||||
md5_final(*ctx, result, 0);
|
||||
if(flag&(1<<15)) {
|
||||
free((char *) *ctx);
|
||||
*ctx= NULL;
|
||||
}
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
/* ----------------------------------------------------------------------- */
|
||||
|
||||
|
||||
/* Function to identify and manage md5sum indice of the old image.
|
||||
* data is supposed to be a 4 byte integer, bit 31 shall be 0,
|
||||
* value 0 of this integer means that it is not a valid index.
|
||||
*/
|
||||
int checksum_xinfo_func(void *data, int flag)
|
||||
{
|
||||
/* data is an int disguised as pointer. It does not point to memory. */
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
#ifdef Libisofs_with_checksumS
|
||||
|
||||
/*
|
||||
@flag bit0= recursion
|
||||
bit1= session will be appended to an existing image
|
||||
*/
|
||||
static
|
||||
int checksum_copy_old_nodes(Ecma119Image *target, IsoNode *node, int flag)
|
||||
{
|
||||
IsoNode *pos;
|
||||
IsoFile *file;
|
||||
IsoImage *img;
|
||||
int ret, i;
|
||||
size_t value_length;
|
||||
unsigned int idx = 0, old_idx = 0;
|
||||
char *value = NULL;
|
||||
void *xipt;
|
||||
|
||||
img = target->image;
|
||||
if (img->checksum_array == NULL || target->checksum_buffer == NULL)
|
||||
return 0;
|
||||
|
||||
if (node->type == LIBISO_FILE) {
|
||||
file = (IsoFile *) node;
|
||||
if (file->from_old_session) {
|
||||
ret = iso_node_get_xinfo(node, checksum_xinfo_func, &xipt);
|
||||
if (ret <= 0)
|
||||
return ret;
|
||||
/* xipt is an int disguised as void pointer */
|
||||
old_idx = 0;
|
||||
for (i = 0; i < 4; i++)
|
||||
old_idx = (old_idx << 8) | ((unsigned char *) &xipt)[i];
|
||||
|
||||
if (old_idx == 0 || old_idx > img->checksum_idx_count - 1)
|
||||
return 0;
|
||||
|
||||
ret = iso_node_lookup_attr(node, "isofs.cx", &value_length,
|
||||
&value, 0);
|
||||
if (ret == 1 && value_length == 4) {
|
||||
for (i = 0; i < 4; i++)
|
||||
idx = (idx << 8) | ((unsigned char *) value)[i];
|
||||
if (idx > 0 && idx <= target->checksum_idx_counter) {
|
||||
memcpy(target->checksum_buffer + 16 * idx,
|
||||
img->checksum_array + 16 * old_idx, 16);
|
||||
}
|
||||
}
|
||||
if (value != NULL)
|
||||
free(value);
|
||||
}
|
||||
} else if (node->type == LIBISO_DIR) {
|
||||
for (pos = ((IsoDir *) node)->children; pos != NULL; pos = pos->next) {
|
||||
ret = checksum_copy_old_nodes(target, pos, 1);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
#endif /* Libisofs_with_checksumS */
|
||||
|
||||
|
||||
static
|
||||
int checksum_writer_compute_data_blocks(IsoImageWriter *writer)
|
||||
{
|
||||
|
||||
#ifdef Libisofs_with_checksumS
|
||||
|
||||
size_t size;
|
||||
Ecma119Image *t;
|
||||
int ret;
|
||||
unsigned int lba;
|
||||
|
||||
if (writer == NULL) {
|
||||
return ISO_ASSERT_FAILURE;
|
||||
}
|
||||
t = writer->target;
|
||||
|
||||
lba = t->curblock; /* (t->curblock already contains t->ms_block) */
|
||||
size = (t->checksum_idx_counter + 2) / 128 + 1;
|
||||
t->curblock += size;
|
||||
|
||||
/* >>> ??? reserve extra block for stream detectable checksum */;
|
||||
|
||||
/* Allocate array of MD5 sums */
|
||||
t->checksum_buffer = calloc(size, 2048);
|
||||
if (t->checksum_buffer == NULL)
|
||||
return ISO_OUT_OF_MEM;
|
||||
|
||||
/* Copy MD5 from nodes of old image into writer->data */
|
||||
ret = checksum_copy_old_nodes(t, (IsoNode *) t->image->root, 0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* Record lba,count,size,cecksum_type in "isofs.ca" of root node */
|
||||
ret = iso_root_set_isofsca((IsoNode *) t->image->root,
|
||||
(unsigned int) t->ms_block, lba,
|
||||
t->checksum_idx_counter + 2, 16, "MD5", 0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
#endif /* Libisofs_with_checksumS */
|
||||
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
int checksum_writer_write_vol_desc(IsoImageWriter *writer)
|
||||
{
|
||||
/* nothing needed */
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
int checksum_writer_write_data(IsoImageWriter *writer)
|
||||
{
|
||||
|
||||
#ifdef Libisofs_with_checksumS
|
||||
|
||||
int wres, res;
|
||||
size_t i, size;
|
||||
Ecma119Image *t;
|
||||
|
||||
if (writer == NULL) {
|
||||
return ISO_ASSERT_FAILURE;
|
||||
}
|
||||
|
||||
t = writer->target;
|
||||
iso_msg_debug(t->image->id, "Writing Checksums...");
|
||||
|
||||
/* Write image checksum to index 0 */
|
||||
/* >>> rather fork a result than killing t->checksum_ctx */;
|
||||
res = libisofs_md5(&(t->checksum_ctx), NULL, 0, t->image_md5,
|
||||
2 | (1 << 15));
|
||||
if (res > 0)
|
||||
memcpy(t->checksum_buffer + 0, t->image_md5, 16);
|
||||
|
||||
size = (t->checksum_idx_counter + 2) / 128 + 1;
|
||||
|
||||
/* >>> write overall checksum as index t->checksum_idx_counter + 1 */;
|
||||
|
||||
for (i = 0; i < size; i++) {
|
||||
wres = iso_write(t, t->checksum_buffer + ((size_t) 2048) * i,
|
||||
BLOCK_SIZE);
|
||||
if (wres < 0)
|
||||
return wres;
|
||||
}
|
||||
|
||||
/* >>> write scdbackup checksum tag to an extra block */;
|
||||
|
||||
#endif /* Libisofs_with_checksumS */
|
||||
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
int checksum_writer_free_data(IsoImageWriter *writer)
|
||||
{
|
||||
/* nothing was allocated at writer->data */
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
int checksum_writer_create(Ecma119Image *target)
|
||||
{
|
||||
IsoImageWriter *writer;
|
||||
|
||||
writer = malloc(sizeof(IsoImageWriter));
|
||||
if (writer == NULL) {
|
||||
return ISO_OUT_OF_MEM;
|
||||
}
|
||||
|
||||
writer->compute_data_blocks = checksum_writer_compute_data_blocks;
|
||||
writer->write_vol_desc = checksum_writer_write_vol_desc;
|
||||
writer->write_data = checksum_writer_write_data;
|
||||
writer->free_data = checksum_writer_free_data;
|
||||
writer->data = NULL;
|
||||
writer->target = target;
|
||||
|
||||
/* add this writer to image */
|
||||
target->writers[target->nwriters++] = writer;
|
||||
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
53
libisofs/md5.h
Normal file
53
libisofs/md5.h
Normal file
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright (c) 2009 Thomas Schmitt
|
||||
*
|
||||
* This file is part of the libisofs project; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation. See COPYING file for details.
|
||||
*/
|
||||
|
||||
#ifndef LIBISO_MD5_H_
|
||||
#define LIBISO_MD5_H_
|
||||
|
||||
|
||||
/** Compute a MD5 checksum from one or more calls of this function.
|
||||
The first call has to be made with flag bit0 == 1. It may already submit
|
||||
processing payload in data and datalen.
|
||||
The last call has to be made with bit15 set. Normally bit1 will be set
|
||||
too in order to receive the checksum before it gets disposed.
|
||||
bit1 may only be set in the last call or together with bit2.
|
||||
The combination of bit1 and bit2 may be used to get an intermediate
|
||||
result without hampering an ongoing checksum computation.
|
||||
|
||||
@param ctx the checksum context which stores the state between calls.
|
||||
It gets created with flag bit0 and disposed with bit15.
|
||||
With flag bit0, *ctx has to be NULL or point to freeable
|
||||
memory.
|
||||
@param data the bytes to be checksummed
|
||||
@param datalen the number of bytes in data
|
||||
@param result returns the 16 bytes of checksum if called with bit1 set
|
||||
@param flag bit0= allocate and init *ctx
|
||||
bit1= transfer ctx to result
|
||||
bit2= with bit 0 : clone new *ctx from data
|
||||
bit15= free *ctx
|
||||
*/
|
||||
int libisofs_md5(void **ctx, char *data, int datalen,
|
||||
char result[16], int flag);
|
||||
|
||||
|
||||
/** Create a writer object for checksums and add it to the writer list of
|
||||
the given Ecma119Image.
|
||||
*/
|
||||
int checksum_writer_create(Ecma119Image *target);
|
||||
|
||||
|
||||
/* Function to identify and manage md5sum indice of the old image.
|
||||
* data is supposed to be a 4 byte integer, bit 31 shall be 0,
|
||||
* value 0 of this integer means that it is not a valid index.
|
||||
*/
|
||||
int checksum_xinfo_func(void *data, int flag);
|
||||
|
||||
|
||||
#endif /* ! LIBISO_MD5_H_ */
|
||||
|
||||
|
136
libisofs/node.c
136
libisofs/node.c
@ -13,6 +13,7 @@
|
||||
#include "stream.h"
|
||||
#include "aaip_0_2.h"
|
||||
#include "messages.h"
|
||||
#include "util.h"
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
@ -2575,3 +2576,138 @@ int iso_node_cmp_ino(IsoNode *n1, IsoNode *n2, int flag)
|
||||
{
|
||||
return iso_node_cmp_flag(n1, n2, 1);
|
||||
}
|
||||
|
||||
|
||||
int iso_file_set_isofscx(IsoFile *file, unsigned int checksum_index,
|
||||
int flag)
|
||||
{
|
||||
static char *names = "isofs.cx";
|
||||
static size_t value_lengths[1] = {4};
|
||||
unsigned char value[4];
|
||||
char *valuept;
|
||||
int i, ret;
|
||||
|
||||
for(i = 0; i < 4; i++)
|
||||
value[3 - i] = (checksum_index >> (8 * i)) & 0xff;
|
||||
valuept= (char *) value;
|
||||
ret = iso_node_set_attrs((IsoNode *) file, (size_t) 1,
|
||||
&names, value_lengths, &valuept, 2 | 8);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int iso_root_set_isofsca(IsoNode *node, uint32_t start_lba, uint32_t end_lba,
|
||||
uint32_t count, uint32_t size, char *typetext,
|
||||
int flag)
|
||||
{
|
||||
char buffer[5 + 5 + 5 + 2 + 81], *wpt = buffer, *valuept = buffer;
|
||||
int result_len, ret;
|
||||
static char *names = "isofs.ca";
|
||||
static size_t value_lengths[1];
|
||||
|
||||
/* Set value of isofs.ca with
|
||||
4 byte START, 4 byte END, 4 byte COUNT, SIZE = 16, MD5 */
|
||||
iso_util_encode_len_bytes(start_lba, wpt, 4, &result_len, 0);
|
||||
wpt += result_len;
|
||||
iso_util_encode_len_bytes(end_lba, wpt, 4, &result_len, 0);
|
||||
wpt += result_len;
|
||||
iso_util_encode_len_bytes(count, wpt, 4, &result_len, 0);
|
||||
wpt += result_len;
|
||||
iso_util_encode_len_bytes(size, wpt, 1, &result_len, 0);
|
||||
wpt += result_len;
|
||||
strncpy(wpt, typetext, 80);
|
||||
if (strlen(typetext) > 80)
|
||||
wpt += 80;
|
||||
else
|
||||
wpt += strlen(typetext);
|
||||
value_lengths[0] = wpt - buffer;
|
||||
ret = iso_node_set_attrs(node, (size_t) 1,
|
||||
&names, value_lengths, &valuept, 2 | 8);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int iso_root_get_isofsca(IsoNode *node, uint32_t *start_lba, uint32_t *end_lba,
|
||||
uint32_t *count, uint32_t *size, char typetext[81],
|
||||
int flag)
|
||||
{
|
||||
int ret, len;
|
||||
size_t value_len;
|
||||
char *value = NULL, *rpt;
|
||||
|
||||
ret = iso_node_lookup_attr(node, "isofs.ca", &value_len, &value, 0);
|
||||
if (ret <= 0)
|
||||
goto ex;
|
||||
|
||||
/* Parse value of isofs.ca with
|
||||
4 byte START, 4 byte END, 4 byte COUNT, SIZE = 16, MD5 */
|
||||
rpt = value;
|
||||
iso_util_decode_len_bytes(start_lba, rpt, &len,
|
||||
value_len - (rpt - value), 0);
|
||||
rpt += len + 1;
|
||||
iso_util_decode_len_bytes(end_lba, rpt, &len,
|
||||
value_len - (rpt - value), 0);
|
||||
rpt += len + 1;
|
||||
iso_util_decode_len_bytes(count, rpt, &len,
|
||||
value_len - (rpt - value), 0);
|
||||
rpt += len + 1;
|
||||
iso_util_decode_len_bytes(size, rpt, &len,
|
||||
value_len - (rpt - value), 0);
|
||||
rpt += len + 1;
|
||||
len = value_len - (rpt - value);
|
||||
if (len > 80)
|
||||
len = 80;
|
||||
memcpy(typetext, rpt, len);
|
||||
typetext[len] = 0;
|
||||
|
||||
ret= ISO_SUCCESS;
|
||||
ex:;
|
||||
if (value != NULL)
|
||||
free(value);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* API */
|
||||
int iso_file_get_md5(IsoImage *image, IsoFile *file, char md5[16], int flag)
|
||||
{
|
||||
|
||||
#ifdef Libisofs_with_checksumS
|
||||
|
||||
int ret, i;
|
||||
size_t value_len;
|
||||
char *value = NULL;
|
||||
uint32_t idx = 0;
|
||||
|
||||
if (image->checksum_array == NULL)
|
||||
return 0;
|
||||
ret = iso_node_lookup_attr((IsoNode *) file, "isofs.cx",
|
||||
&value_len, &value, 0);
|
||||
if (ret <= 0)
|
||||
goto ex;
|
||||
if (value_len > 4) {
|
||||
ret = 0;
|
||||
goto ex;
|
||||
}
|
||||
for (i = 0; i < value_len; i++)
|
||||
idx = (idx << 8) | ((unsigned char *) value)[i];
|
||||
if (idx == 0 || idx > image->checksum_idx_count - 1) {
|
||||
/* (last index is not MD5 of a file) */
|
||||
ret = 0;
|
||||
goto ex;
|
||||
}
|
||||
memcpy(md5, image->checksum_array + ((size_t) 16) * ((size_t) idx), 16);
|
||||
ret = ISO_SUCCESS;
|
||||
ex:;
|
||||
if (value != NULL)
|
||||
free(value);
|
||||
return ret;
|
||||
|
||||
#else
|
||||
|
||||
return 0;
|
||||
|
||||
#endif /* ! Libisofs_with_checksumS */
|
||||
|
||||
}
|
||||
|
||||
|
@ -24,7 +24,7 @@
|
||||
/**
|
||||
* The extended information is a way to attach additional information to each
|
||||
* IsoNode. External applications may want to use this extension system to
|
||||
* store application speficic information related to each node. On the other
|
||||
* store application specific information related to each node. On the other
|
||||
* side, libisofs may make use of this struct to attach information to nodes in
|
||||
* some particular, uncommon, cases, without incrementing the size of the
|
||||
* IsoNode struct.
|
||||
@ -67,7 +67,7 @@ struct iso_extended_info {
|
||||
struct Iso_Node
|
||||
{
|
||||
/*
|
||||
* Initilized to 1, originally owned by user, until added to another node.
|
||||
* Initialized to 1, originally owned by user, until added to another node.
|
||||
* Then it is owned by the parent node, so the user must take his own ref
|
||||
* if needed. With the exception of the creation functions, none of the
|
||||
* other libisofs functions that return an IsoNode increment its
|
||||
@ -451,4 +451,31 @@ int iso_node_set_ino(IsoNode *node, ino_t ino, int flag);
|
||||
*/
|
||||
int iso_node_cmp_flag(IsoNode *n1, IsoNode *n2, int flag);
|
||||
|
||||
|
||||
/**
|
||||
* Set the checksum index (typically comming from IsoFileSrc.checksum_index)
|
||||
* of a regular file node. The index is encoded as xattr "isofs.cx" with
|
||||
* four bytes of value.
|
||||
*/
|
||||
int iso_file_set_isofscx(IsoFile *file, unsigned int checksum_index,
|
||||
int flag);
|
||||
|
||||
|
||||
/**
|
||||
* Set the checksum area description. node should be the root node.
|
||||
* It is encoded as xattr "isofs.ca".
|
||||
*/
|
||||
int iso_root_set_isofsca(IsoNode *node, uint32_t start_lba, uint32_t end_lba,
|
||||
uint32_t count, uint32_t size, char *typetext,
|
||||
int flag);
|
||||
|
||||
/**
|
||||
* Get the checksum area description. node should be the root node.
|
||||
* It is encoded as xattr "isofs.ca".
|
||||
*/
|
||||
int iso_root_get_isofsca(IsoNode *node, uint32_t *start_lba, uint32_t *end_lba,
|
||||
uint32_t *count, uint32_t *size, char typetext[81],
|
||||
int flag);
|
||||
|
||||
|
||||
#endif /*LIBISO_NODE_H_*/
|
||||
|
@ -1489,3 +1489,42 @@ int iso_init_locale(int flag)
|
||||
}
|
||||
|
||||
|
||||
int iso_util_encode_len_bytes(uint32_t data, char *buffer, int data_len,
|
||||
int *result_len, int flag)
|
||||
{
|
||||
uint32_t x;
|
||||
int i, l;
|
||||
char *wpt = buffer;
|
||||
|
||||
if (data_len <= 0) {
|
||||
x = data;
|
||||
for (i = 0; i < 4 && x != 0; i++)
|
||||
x = x >> 8;
|
||||
l = i;
|
||||
if (l == 0)
|
||||
l = 1;
|
||||
} else
|
||||
l = data_len;
|
||||
*((unsigned char *) (wpt++)) = l;
|
||||
for (i = 0; i < l; i++)
|
||||
*((unsigned char *) (wpt++)) = data >> (8 * (l - i - 1));
|
||||
*result_len = l + 1;
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
int iso_util_decode_len_bytes(uint32_t *data, char *buffer, int *data_len,
|
||||
int buffer_len, int flag)
|
||||
{
|
||||
int i;
|
||||
|
||||
*data = 0;
|
||||
*data_len = ((unsigned char *) buffer)[0];
|
||||
if (*data_len > buffer_len - 1)
|
||||
*data_len = buffer_len - 1;
|
||||
for (i = 1; i <= *data_len; i++)
|
||||
*data = (*data << 8) | ((unsigned char *) buffer)[i];
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
@ -440,4 +440,22 @@ void iso_htable_destroy(IsoHTable *table, hfree_data_t free_data);
|
||||
*/
|
||||
unsigned int iso_str_hash(const void *key);
|
||||
|
||||
/**
|
||||
* Encode an integer as LEN,BYTES for being a component in certain AAIP
|
||||
* attribute values.
|
||||
*/
|
||||
int iso_util_encode_len_bytes(uint32_t data, char *buffer, int data_len,
|
||||
int *result_len, int flag);
|
||||
|
||||
/**
|
||||
* Decode an integer as LEN,BYTES for being a component in certain AAIP
|
||||
* attribute values.
|
||||
* @param data returns the decoded value
|
||||
* @param buffer contains the encoded value
|
||||
* @param data_len returns the number of value bytes (without len byte)
|
||||
* @param buffer_len tells the number of valid buffer bytes
|
||||
*/
|
||||
int iso_util_decode_len_bytes(uint32_t *data, char *buffer, int *data_len,
|
||||
int buffer_len, int flag);
|
||||
|
||||
#endif /*LIBISO_UTIL_H_*/
|
||||
|
Loading…
Reference in New Issue
Block a user