New API call iso_write_opts_set_scdbackup_tag()
This commit is contained in:
parent
9cfa55345e
commit
c992687200
@ -67,8 +67,8 @@ The tree checksum tag is written after the ECMA-119 directory entries.
|
|||||||
The session checksum tag is written after all payload including the checksum
|
The session checksum tag is written after all payload including the checksum
|
||||||
array. (Then follows eventual padding.)
|
array. (Then follows eventual padding.)
|
||||||
|
|
||||||
The tags are single lines of printable text, padded by 0 bytes. They have
|
The tags are single lines of printable text at the very beginning of a block
|
||||||
the following format:
|
of 2048 bytes. They have the following format:
|
||||||
|
|
||||||
Tag_id pos=# range_start=# range_size=# [session_start|next=#] md5=# self=#\n
|
Tag_id pos=# range_start=# range_size=# [session_start|next=#] md5=# self=#\n
|
||||||
|
|
||||||
@ -161,9 +161,14 @@ checksums as strings of 32 hex digits.
|
|||||||
The MD5 checksum of the tag itself up to and including the last hex digit of
|
The MD5 checksum of the tag itself up to and including the last hex digit of
|
||||||
parameter "md5=".
|
parameter "md5=".
|
||||||
|
|
||||||
The newline character at the end is mandatory. For now all bytes of the
|
The newline character at the end is mandatory. After that newline there may
|
||||||
block after that newline shall be zero. There may arise future extensions.
|
follow more lines. Their meaning is not necessarily described in this document.
|
||||||
|
|
||||||
|
One such line type is the scdbackup checksum tag, an ancestor of libisofs tags
|
||||||
|
which is suitable only for single session images which begin at LBA 0. It bears
|
||||||
|
a checksum record which by its MD5 covers all bytes from LBA 0 up to the
|
||||||
|
newline character preceding the scdbackup tag. See scdbackup/README appendix
|
||||||
|
VERIFY for details.
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -31,11 +31,13 @@
|
|||||||
#include "md5.h"
|
#include "md5.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <locale.h>
|
#include <locale.h>
|
||||||
#include <langinfo.h>
|
#include <langinfo.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* TODO #00011 : guard against bad path table usage with more than 65535 dirs
|
* TODO #00011 : guard against bad path table usage with more than 65535 dirs
|
||||||
@ -1132,6 +1134,7 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
|
|||||||
|
|
||||||
target->md5_file_checksums = opts->md5_file_checksums;
|
target->md5_file_checksums = opts->md5_file_checksums;
|
||||||
target->md5_session_checksum = opts->md5_session_checksum;
|
target->md5_session_checksum = opts->md5_session_checksum;
|
||||||
|
strcpy(target->scdbackup_tag_parm, opts->scdbackup_tag_parm);
|
||||||
target->checksum_idx_counter = 0;
|
target->checksum_idx_counter = 0;
|
||||||
target->checksum_ctx = NULL;
|
target->checksum_ctx = NULL;
|
||||||
target->checksum_counter = 0;
|
target->checksum_counter = 0;
|
||||||
@ -1866,6 +1869,39 @@ int iso_write_opts_set_record_md5(IsoWriteOpts *opts, int session, int files)
|
|||||||
return ISO_SUCCESS;
|
return ISO_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int iso_write_opts_set_scdbackup_tag(IsoWriteOpts *opts,
|
||||||
|
char *name, char *timestamp)
|
||||||
|
{
|
||||||
|
|
||||||
|
#ifdef Libisofs_with_checksumS
|
||||||
|
|
||||||
|
char eff_name[81], eff_time[19];
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; name[i] != 0 && i < 80; i++)
|
||||||
|
if (isspace((int) ((unsigned char *) name)[i]))
|
||||||
|
eff_name[i] = '_';
|
||||||
|
else
|
||||||
|
eff_name[i] = name[i];
|
||||||
|
if (i == 0)
|
||||||
|
eff_name[i++] = '_';
|
||||||
|
eff_name[i] = 0;
|
||||||
|
for (i = 0; timestamp[i] != 0 && i < 18; i++)
|
||||||
|
if (isspace((int) ((unsigned char *) timestamp)[i]))
|
||||||
|
eff_time[i] = '_';
|
||||||
|
else
|
||||||
|
eff_time[i] = timestamp[i];
|
||||||
|
if (i == 0)
|
||||||
|
eff_time[i++] = '_';
|
||||||
|
eff_time[i] = 0;
|
||||||
|
|
||||||
|
sprintf(opts->scdbackup_tag_parm, "%s %s", eff_name, eff_time);
|
||||||
|
|
||||||
|
#endif /* Libisofs_with_checksumS */
|
||||||
|
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
int iso_write_opts_set_replace_mode(IsoWriteOpts *opts, int dir_mode,
|
int iso_write_opts_set_replace_mode(IsoWriteOpts *opts, int dir_mode,
|
||||||
int file_mode, int uid, int gid)
|
int file_mode, int uid, int gid)
|
||||||
{
|
{
|
||||||
|
@ -281,6 +281,15 @@ struct iso_write_opts {
|
|||||||
*/
|
*/
|
||||||
uint32_t data_start_lba;
|
uint32_t data_start_lba;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If not empty: A text holding parameters "name" and "timestamp" for
|
||||||
|
* a scdbackup stream checksum tag. See scdbackup/README appendix VERIFY.
|
||||||
|
* It makes sense only for single session images which start at LBA 0.
|
||||||
|
* Such a tag may be part of a libisofs checksum tag block after the
|
||||||
|
* session tag line. It then covers the whole session up to its own start
|
||||||
|
* position.
|
||||||
|
*/
|
||||||
|
char scdbackup_tag_parm[100];
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct ecma119_image Ecma119Image;
|
typedef struct ecma119_image Ecma119Image;
|
||||||
@ -464,6 +473,8 @@ struct ecma119_image
|
|||||||
is submitted with ecma119_image_new() ?
|
is submitted with ecma119_image_new() ?
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
char scdbackup_tag_parm[96];
|
||||||
|
|
||||||
#endif /* Libisofs_with_checksumS */
|
#endif /* Libisofs_with_checksumS */
|
||||||
|
|
||||||
/* Buffer for communication between burn_source and writer thread */
|
/* Buffer for communication between burn_source and writer thread */
|
||||||
|
@ -1446,6 +1446,27 @@ int iso_write_opts_set_sort_files(IsoWriteOpts *opts, int sort);
|
|||||||
*/
|
*/
|
||||||
int iso_write_opts_set_record_md5(IsoWriteOpts *opts, int session, int files);
|
int iso_write_opts_set_record_md5(IsoWriteOpts *opts, int session, int files);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the parameters "name" and "timestamp" for a scdbackup checksum tag.
|
||||||
|
* It will be appended to the libisofs session tag if the image starts at
|
||||||
|
* LBA 0 (see iso_write_opts_set_ms_block()). The scdbackup tag can be used
|
||||||
|
* to verify the image by command scdbackup_verify <device> -auto_end.
|
||||||
|
* See scdbackup/README appendix VERIFY for its inner details.
|
||||||
|
*
|
||||||
|
* @param name
|
||||||
|
* A word of up to 80 characters. Typically <volno>_<totalno> telling
|
||||||
|
* that this is volume <volno> of a total of <totalno> volumes.
|
||||||
|
* @param timestamp
|
||||||
|
* A string of 13 characters YYMMDD.hhmmss (e.g. A90831.190324).
|
||||||
|
* A9 = 2009, B0 = 2010, B1 = 2011, ... C0 = 2020, ...
|
||||||
|
* @return
|
||||||
|
* 1 indicates success, <0 is error
|
||||||
|
*
|
||||||
|
* @since 0.6.24
|
||||||
|
*/
|
||||||
|
int iso_write_opts_set_scdbackup_tag(IsoWriteOpts *opts,
|
||||||
|
char *name, char *timestamp);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether to set default values for files and directory permissions, gid and
|
* Whether to set default values for files and directory permissions, gid and
|
||||||
* uid. All these take one of three values: 0, 1 or 2.
|
* uid. All these take one of three values: 0, 1 or 2.
|
||||||
@ -5522,6 +5543,13 @@ int iso_md5_match(char first_md5[16], char second_md5[16]);
|
|||||||
*/
|
*/
|
||||||
#define ISO_MD5_STREAM_CHANGE 0xE430FE9A
|
#define ISO_MD5_STREAM_CHANGE 0xE430FE9A
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Session does not start at LBA 0. scdbackup checksum tag not written.
|
||||||
|
* (WARNING, HIGH, -359)
|
||||||
|
* @since 0.6.24
|
||||||
|
*/
|
||||||
|
#define ISO_SCDBACKUP_TAG_NOT_0 0xD030FE99
|
||||||
|
|
||||||
|
|
||||||
/* ! PLACE NEW ERROR CODES HERE ! */
|
/* ! PLACE NEW ERROR CODES HERE ! */
|
||||||
|
|
||||||
|
143
libisofs/md5.c
143
libisofs/md5.c
@ -698,6 +698,66 @@ int checksum_writer_create(Ecma119Image *target)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static
|
||||||
|
int iso_md5_write_scdbackup_tag(Ecma119Image *t, char *tag_block, int flag)
|
||||||
|
{
|
||||||
|
|
||||||
|
#ifdef Libisofs_with_checksumS
|
||||||
|
|
||||||
|
void *ctx = NULL;
|
||||||
|
off_t pos = 0, line_start;
|
||||||
|
int record_len, block_len, res, i;
|
||||||
|
char postext[20], md5[16], record[160];
|
||||||
|
|
||||||
|
line_start = strlen(tag_block);
|
||||||
|
iso_md5_compute(t->checksum_ctx, tag_block, line_start);
|
||||||
|
res = iso_md5_clone(t->checksum_ctx, &ctx);
|
||||||
|
if (res < 0)
|
||||||
|
goto ex;
|
||||||
|
res = iso_md5_end(&ctx, md5);
|
||||||
|
|
||||||
|
pos = (off_t) t->checksum_tag_pos * (off_t) 2048 + line_start;
|
||||||
|
if(pos >= 1000000000)
|
||||||
|
sprintf(postext, "%u%9.9u", (unsigned int) (pos / 1000000000),
|
||||||
|
(unsigned int) (pos % 1000000000));
|
||||||
|
else
|
||||||
|
sprintf(postext, "%u", (unsigned int) pos),
|
||||||
|
|
||||||
|
sprintf(record, "%s %s ", t->scdbackup_tag_parm, postext);
|
||||||
|
record_len = strlen(record);
|
||||||
|
for (i = 0; i < 16; i++)
|
||||||
|
sprintf(record + record_len + 2 * i,
|
||||||
|
"%2.2x", ((unsigned char *) md5)[i]);
|
||||||
|
record_len+= 32;
|
||||||
|
res = iso_md5_start(&ctx);
|
||||||
|
if (res < 0)
|
||||||
|
goto ex;
|
||||||
|
iso_md5_compute(ctx, record, record_len);
|
||||||
|
iso_md5_end(&ctx, md5);
|
||||||
|
|
||||||
|
sprintf(tag_block + line_start, "scdbackup_checksum_tag_v0.1 %s %d %s ",
|
||||||
|
postext, record_len, record);
|
||||||
|
block_len = strlen(tag_block);
|
||||||
|
for (i = 0; i < 16; i++)
|
||||||
|
sprintf(tag_block + block_len + 2 * i,
|
||||||
|
"%2.2x", ((unsigned char *) md5)[i]);
|
||||||
|
block_len+= 32;
|
||||||
|
tag_block[block_len++]= '\n';
|
||||||
|
|
||||||
|
res = ISO_SUCCESS;
|
||||||
|
ex:;
|
||||||
|
if (ctx != NULL)
|
||||||
|
iso_md5_end(&ctx, md5);
|
||||||
|
return res;
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
|
||||||
|
#endif /* Libisofs_with_checksumS */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Write stream detectable checksum tag to extra block.
|
/* Write stream detectable checksum tag to extra block.
|
||||||
* @flag bit0-7= tag type
|
* @flag bit0-7= tag type
|
||||||
* 1= session tag (End checksumming.)
|
* 1= session tag (End checksumming.)
|
||||||
@ -719,11 +779,16 @@ int iso_md5_write_tag(Ecma119Image *t, int flag)
|
|||||||
start = t->checksum_range_start;
|
start = t->checksum_range_start;
|
||||||
memset(tag_block, 0, 2048);
|
memset(tag_block, 0, 2048);
|
||||||
mode = flag & 255;
|
mode = flag & 255;
|
||||||
|
if (mode < 1 || mode > 4)
|
||||||
|
return ISO_WRONG_ARG_VALUE;
|
||||||
|
res = iso_md5_clone(t->checksum_ctx, &ctx);
|
||||||
|
if (res < 0)
|
||||||
|
return res;
|
||||||
|
res = iso_md5_end(&ctx, md5);
|
||||||
if (mode == 1) {
|
if (mode == 1) {
|
||||||
res = iso_md5_end(&(t->checksum_ctx), md5);
|
|
||||||
size = t->checksum_range_size;
|
size = t->checksum_range_size;
|
||||||
pos = t->checksum_tag_pos;
|
pos = t->checksum_tag_pos;
|
||||||
} else if (mode >= 2 && mode <= 4) {
|
} else {
|
||||||
if (mode == 2) {
|
if (mode == 2) {
|
||||||
pos = t->checksum_sb_tag_pos;
|
pos = t->checksum_sb_tag_pos;
|
||||||
} else if (mode == 3) {
|
} else if (mode == 3) {
|
||||||
@ -733,46 +798,51 @@ int iso_md5_write_tag(Ecma119Image *t, int flag)
|
|||||||
start = pos - (pos % 32);
|
start = pos - (pos % 32);
|
||||||
}
|
}
|
||||||
size = pos - start;
|
size = pos - start;
|
||||||
res = iso_md5_clone(t->checksum_ctx, &ctx);
|
|
||||||
if (res < 0)
|
|
||||||
return res;
|
|
||||||
res = iso_md5_end(&ctx, md5);
|
|
||||||
} else {
|
|
||||||
return ISO_WRONG_ARG_VALUE;
|
|
||||||
}
|
}
|
||||||
if (res > 0) {
|
if (res < 0)
|
||||||
iso_util_tag_magic(mode, &tag_id, &tag_id_len, 0);
|
goto ex;
|
||||||
sprintf(tag_block,
|
|
||||||
"%s pos=%u range_start=%u range_size=%u",
|
|
||||||
tag_id, pos, start, size);
|
|
||||||
|
|
||||||
l = strlen(tag_block);
|
iso_util_tag_magic(mode, &tag_id, &tag_id_len, 0);
|
||||||
if (mode == 2) {
|
sprintf(tag_block, "%s pos=%u range_start=%u range_size=%u",
|
||||||
sprintf(tag_block + l, " next=%u", t->checksum_tree_tag_pos);
|
tag_id, pos, start, size);
|
||||||
} else if (mode == 3) {
|
|
||||||
sprintf(tag_block + l, " next=%u", t->checksum_tag_pos);
|
l = strlen(tag_block);
|
||||||
} else if (mode == 4) {
|
if (mode == 2) {
|
||||||
sprintf(tag_block + l, " session_start=%u", t->ms_block);
|
sprintf(tag_block + l, " next=%u", t->checksum_tree_tag_pos);
|
||||||
}
|
} else if (mode == 3) {
|
||||||
strcat(tag_block + l, " md5=");
|
sprintf(tag_block + l, " next=%u", t->checksum_tag_pos);
|
||||||
l = strlen(tag_block);
|
} else if (mode == 4) {
|
||||||
|
sprintf(tag_block + l, " session_start=%u", t->ms_block);
|
||||||
|
}
|
||||||
|
strcat(tag_block + l, " md5=");
|
||||||
|
l = strlen(tag_block);
|
||||||
|
for (i = 0; i < 16; i++)
|
||||||
|
sprintf(tag_block + l + 2 * i, "%2.2x",
|
||||||
|
((unsigned char *) md5)[i]);
|
||||||
|
l+= 32;
|
||||||
|
|
||||||
|
res = iso_md5_start(&ctx);
|
||||||
|
if (res > 0) {
|
||||||
|
iso_md5_compute(ctx, tag_block, l);
|
||||||
|
iso_md5_end(&ctx, md5);
|
||||||
|
strcpy(tag_block + l, " self=");
|
||||||
|
l += 6;
|
||||||
for (i = 0; i < 16; i++)
|
for (i = 0; i < 16; i++)
|
||||||
sprintf(tag_block + l + 2 * i, "%2.2x",
|
sprintf(tag_block + l + 2 * i, "%2.2x",
|
||||||
((unsigned char *) md5)[i]);
|
((unsigned char *) md5)[i]);
|
||||||
l+= 32;
|
|
||||||
|
|
||||||
res = iso_md5_start(&ctx);
|
|
||||||
if (res > 0) {
|
|
||||||
iso_md5_compute(ctx, tag_block, l);
|
|
||||||
iso_md5_end(&ctx, md5);
|
|
||||||
strcpy(tag_block + l, " self=");
|
|
||||||
l += 6;
|
|
||||||
for (i = 0; i < 16; i++)
|
|
||||||
sprintf(tag_block + l + 2 * i, "%2.2x",
|
|
||||||
((unsigned char *) md5)[i]);
|
|
||||||
}
|
|
||||||
tag_block[l + 32] = '\n';
|
|
||||||
}
|
}
|
||||||
|
tag_block[l + 32] = '\n';
|
||||||
|
|
||||||
|
if (mode == 1 && t->scdbackup_tag_parm[0]) {
|
||||||
|
if (t->ms_block > 0) {
|
||||||
|
iso_msg_submit(t->image->id, ISO_SCDBACKUP_TAG_NOT_0, 0, NULL);
|
||||||
|
} else {
|
||||||
|
res = iso_md5_write_scdbackup_tag(t, tag_block, 0);
|
||||||
|
if (res < 0)
|
||||||
|
goto ex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (mode == 4) {
|
if (mode == 4) {
|
||||||
if (t->opts_overwrite != NULL)
|
if (t->opts_overwrite != NULL)
|
||||||
memcpy(t->opts_overwrite + pos * 2048, tag_block, 2048);
|
memcpy(t->opts_overwrite + pos * 2048, tag_block, 2048);
|
||||||
@ -783,6 +853,7 @@ int iso_md5_write_tag(Ecma119Image *t, int flag)
|
|||||||
goto ex;
|
goto ex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
res = ISO_SUCCESS;
|
res = ISO_SUCCESS;
|
||||||
ex:;
|
ex:;
|
||||||
if (ctx != NULL)
|
if (ctx != NULL)
|
||||||
|
@ -274,6 +274,8 @@ const char *iso_error_to_msg(int errcode)
|
|||||||
return "Checksum tag with unexpected address range encountered";
|
return "Checksum tag with unexpected address range encountered";
|
||||||
case ISO_MD5_STREAM_CHANGE:
|
case ISO_MD5_STREAM_CHANGE:
|
||||||
return "Detected file content changes while it was written into the image";
|
return "Detected file content changes while it was written into the image";
|
||||||
|
case ISO_SCDBACKUP_TAG_NOT_0:
|
||||||
|
return "Session does not start at LBA 0. scdbackup checksum tag not written.";
|
||||||
default:
|
default:
|
||||||
return "Unknown error";
|
return "Unknown error";
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user