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
|
||||
array. (Then follows eventual padding.)
|
||||
|
||||
The tags are single lines of printable text, padded by 0 bytes. They have
|
||||
the following format:
|
||||
The tags are single lines of printable text at the very beginning of a block
|
||||
of 2048 bytes. They have the following format:
|
||||
|
||||
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
|
||||
parameter "md5=".
|
||||
|
||||
The newline character at the end is mandatory. For now all bytes of the
|
||||
block after that newline shall be zero. There may arise future extensions.
|
||||
The newline character at the end is mandatory. After that newline there may
|
||||
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"
|
||||
#endif
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <string.h>
|
||||
#include <locale.h>
|
||||
#include <langinfo.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/*
|
||||
* 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_session_checksum = opts->md5_session_checksum;
|
||||
strcpy(target->scdbackup_tag_parm, opts->scdbackup_tag_parm);
|
||||
target->checksum_idx_counter = 0;
|
||||
target->checksum_ctx = NULL;
|
||||
target->checksum_counter = 0;
|
||||
@ -1866,6 +1869,39 @@ int iso_write_opts_set_record_md5(IsoWriteOpts *opts, int session, int files)
|
||||
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 file_mode, int uid, int gid)
|
||||
{
|
||||
|
@ -281,6 +281,15 @@ struct iso_write_opts {
|
||||
*/
|
||||
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;
|
||||
@ -464,6 +473,8 @@ struct ecma119_image
|
||||
is submitted with ecma119_image_new() ?
|
||||
*/
|
||||
|
||||
char scdbackup_tag_parm[96];
|
||||
|
||||
#endif /* Libisofs_with_checksumS */
|
||||
|
||||
/* 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);
|
||||
|
||||
/**
|
||||
* 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
|
||||
* 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
|
||||
|
||||
/**
|
||||
* 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 ! */
|
||||
|
||||
|
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.
|
||||
* @flag bit0-7= tag type
|
||||
* 1= session tag (End checksumming.)
|
||||
@ -719,11 +779,16 @@ int iso_md5_write_tag(Ecma119Image *t, int flag)
|
||||
start = t->checksum_range_start;
|
||||
memset(tag_block, 0, 2048);
|
||||
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) {
|
||||
res = iso_md5_end(&(t->checksum_ctx), md5);
|
||||
size = t->checksum_range_size;
|
||||
pos = t->checksum_tag_pos;
|
||||
} else if (mode >= 2 && mode <= 4) {
|
||||
} else {
|
||||
if (mode == 2) {
|
||||
pos = t->checksum_sb_tag_pos;
|
||||
} else if (mode == 3) {
|
||||
@ -733,46 +798,51 @@ int iso_md5_write_tag(Ecma119Image *t, int flag)
|
||||
start = pos - (pos % 32);
|
||||
}
|
||||
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) {
|
||||
iso_util_tag_magic(mode, &tag_id, &tag_id_len, 0);
|
||||
sprintf(tag_block,
|
||||
"%s pos=%u range_start=%u range_size=%u",
|
||||
tag_id, pos, start, size);
|
||||
if (res < 0)
|
||||
goto ex;
|
||||
|
||||
l = strlen(tag_block);
|
||||
if (mode == 2) {
|
||||
sprintf(tag_block + l, " next=%u", t->checksum_tree_tag_pos);
|
||||
} else if (mode == 3) {
|
||||
sprintf(tag_block + l, " next=%u", t->checksum_tag_pos);
|
||||
} else if (mode == 4) {
|
||||
sprintf(tag_block + l, " session_start=%u", t->ms_block);
|
||||
}
|
||||
strcat(tag_block + l, " md5=");
|
||||
l = strlen(tag_block);
|
||||
iso_util_tag_magic(mode, &tag_id, &tag_id_len, 0);
|
||||
sprintf(tag_block, "%s pos=%u range_start=%u range_size=%u",
|
||||
tag_id, pos, start, size);
|
||||
|
||||
l = strlen(tag_block);
|
||||
if (mode == 2) {
|
||||
sprintf(tag_block + l, " next=%u", t->checksum_tree_tag_pos);
|
||||
} else if (mode == 3) {
|
||||
sprintf(tag_block + l, " next=%u", t->checksum_tag_pos);
|
||||
} 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++)
|
||||
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++)
|
||||
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 (t->opts_overwrite != NULL)
|
||||
memcpy(t->opts_overwrite + pos * 2048, tag_block, 2048);
|
||||
@ -783,6 +853,7 @@ int iso_md5_write_tag(Ecma119Image *t, int flag)
|
||||
goto ex;
|
||||
}
|
||||
}
|
||||
|
||||
res = ISO_SUCCESS;
|
||||
ex:;
|
||||
if (ctx != NULL)
|
||||
|
@ -274,6 +274,8 @@ const char *iso_error_to_msg(int errcode)
|
||||
return "Checksum tag with unexpected address range encountered";
|
||||
case ISO_MD5_STREAM_CHANGE:
|
||||
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:
|
||||
return "Unknown error";
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user