Preserving MD5s of files from old session until the end of the new
write run. If the write run fails, the old MD5s get restored.
This commit is contained in:
parent
567d3ddafb
commit
3f29d70aba
@ -1230,6 +1230,48 @@ int zero_writer_create(Ecma119Image *target, uint32_t num_blocks, int flag)
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/* @param flag bit0= restore preserved cx (else dispose them)
|
||||
*/
|
||||
static
|
||||
int process_preserved_cx(IsoDir *dir, int flag)
|
||||
{
|
||||
int ret, i;
|
||||
unsigned int cx_value;
|
||||
void *xipt;
|
||||
IsoNode *pos;
|
||||
|
||||
pos = dir->children;
|
||||
for (pos = dir->children; pos != NULL; pos = pos->next) {
|
||||
if (pos->type == LIBISO_FILE) {
|
||||
if (flag & 1) {
|
||||
/* Restore preserved cx state of nodes */
|
||||
ret = iso_node_get_xinfo(pos, checksum_cx_xinfo_func,
|
||||
&xipt);
|
||||
if (ret == 1) {
|
||||
/* xipt is an int disguised as void pointer */
|
||||
cx_value = 0;
|
||||
for (i = 0; i < 4; i++)
|
||||
cx_value =
|
||||
(cx_value << 8) | ((unsigned char *) &xipt)[i];
|
||||
ret = iso_file_set_isofscx((IsoFile *) pos, cx_value, 0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
} else if (ret == 0) {
|
||||
/* Node had no cx before the write run. Delete cx. */
|
||||
iso_file_set_isofscx((IsoFile *) pos, 0, 1);
|
||||
}
|
||||
}
|
||||
iso_node_remove_xinfo(pos, checksum_cx_xinfo_func);
|
||||
} else if (pos->type == LIBISO_DIR) {
|
||||
ret = process_preserved_cx((IsoDir *) pos, flag);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static
|
||||
int transplant_checksum_buffer(Ecma119Image *target, int flag)
|
||||
{
|
||||
@ -1240,6 +1282,10 @@ int transplant_checksum_buffer(Ecma119Image *target, int flag)
|
||||
target->checksum_idx_counter + 2, 0);
|
||||
target->checksum_buffer = NULL;
|
||||
target->checksum_idx_counter = 0;
|
||||
|
||||
/* Delete recorded cx xinfo */
|
||||
process_preserved_cx(target->image->root, 0);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -1562,10 +1608,8 @@ void *write_function(void *arg)
|
||||
}
|
||||
iso_ring_buffer_writer_close(target->buffer, 1);
|
||||
|
||||
/* Transplant checksum buffer away from Ecma119Image */
|
||||
transplant_checksum_buffer(target, 0);
|
||||
/* Invalidate the transplanted checksum buffer in IsoImage */
|
||||
iso_image_free_checksums(target->image, 0);
|
||||
/* Re-activate recorded cx xinfo */
|
||||
process_preserved_cx(target->image->root, 1);
|
||||
|
||||
target->image->generator_is_running = 0;
|
||||
|
||||
@ -1605,82 +1649,88 @@ int checksum_prepare_nodes(Ecma119Image *target, IsoNode *node, int flag)
|
||||
IsoNode *pos;
|
||||
IsoFile *file;
|
||||
IsoImage *img;
|
||||
int ret, i, no_md5 = 0, has_xinfo = 0;
|
||||
size_t value_length;
|
||||
int ret, i, no_md5 = 0, has_xinfo = 0, has_attr = 0;
|
||||
size_t old_cx_value_length = 0;
|
||||
unsigned int idx = 0;
|
||||
char *value= NULL;
|
||||
char *old_cx_value= NULL;
|
||||
void *xipt = NULL;
|
||||
static char *cx_names = "isofs.cx";
|
||||
static size_t cx_value_lengths[1] = {0};
|
||||
char *cx_valuept = "";
|
||||
|
||||
img= target->image;
|
||||
|
||||
if (node->type == LIBISO_FILE) {
|
||||
file = (IsoFile *) node;
|
||||
if (file->from_old_session) {
|
||||
/* Record attribute isofs.cx as xinfo before it can get overwritten
|
||||
for the emerging image.
|
||||
The recorded index will be used to retrieve the loaded MD5
|
||||
and it will be brought back into effect if cancellation of
|
||||
image production prevents that the old MD5 array gets replaced
|
||||
by the new one.
|
||||
*/
|
||||
has_attr = iso_node_lookup_attr(node, "isofs.cx",
|
||||
&old_cx_value_length, &old_cx_value, 0);
|
||||
if (has_attr == 1 && old_cx_value_length == 4) {
|
||||
for (i = 0; i < 4; i++)
|
||||
idx = (idx << 8) | ((unsigned char *) old_cx_value)[i];
|
||||
if (idx > 0 && idx < 0x8000000) {
|
||||
/* xipt is an int disguised as void pointer */
|
||||
for (i = 0; i < 4; i++)
|
||||
((char *) &xipt)[i] = old_cx_value[i];
|
||||
ret = iso_node_add_xinfo(node, checksum_cx_xinfo_func,
|
||||
xipt);
|
||||
if (ret < 0)
|
||||
goto ex;
|
||||
} else
|
||||
no_md5 = 1;
|
||||
}
|
||||
}
|
||||
if (file->from_old_session && target->appendable) {
|
||||
/* Save MD5 data of files from old image which will not
|
||||
be copied and have an MD5 recorded in the old image. */
|
||||
has_xinfo = iso_node_get_xinfo(node, checksum_md5_xinfo_func,
|
||||
&xipt);
|
||||
if (has_xinfo <= 0) {
|
||||
ret = iso_node_lookup_attr(node, "isofs.cx", &value_length,
|
||||
&value, 0);
|
||||
}
|
||||
if (has_xinfo > 0) {
|
||||
/* xinfo MD5 overrides everything else unless data get copied
|
||||
and checksummed during that copying
|
||||
*/;
|
||||
} else if (ret == 1 && img->checksum_array == NULL) {
|
||||
} else if (has_attr == 1 && img->checksum_array == NULL) {
|
||||
/* No checksum array loaded. Delete "isofs.cx" */
|
||||
if (!target->will_cancel)
|
||||
iso_node_set_attrs(node, (size_t) 1,
|
||||
&cx_names, cx_value_lengths, &cx_valuept, 4 | 8);
|
||||
iso_file_set_isofscx((IsoFile *) node, 0, 1);
|
||||
no_md5 = 1;
|
||||
} else 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_cx_xinfo_func,
|
||||
xipt);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
} else
|
||||
no_md5 = 1;
|
||||
} else {
|
||||
} else if (!(has_attr == 1 && old_cx_value_length == 4)) {
|
||||
no_md5 = 1;
|
||||
}
|
||||
if (value != NULL) {
|
||||
free(value);
|
||||
value= NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Equip nodes with provisory isofs.cx numbers: 4 byte, all 0.
|
||||
Omit those from old image which will not be copied and have no MD5.
|
||||
Do not alter the nodes if this is only a will_cancel run.
|
||||
*/
|
||||
if (!(target->will_cancel || no_md5)) {
|
||||
/* Record provisory new index */
|
||||
ret = iso_file_set_isofscx(file, (unsigned int) 0, 0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
goto ex;
|
||||
}
|
||||
} else if (node->type == LIBISO_DIR) {
|
||||
for (pos = ((IsoDir *) node)->children; pos != NULL; pos = pos->next) {
|
||||
ret = checksum_prepare_nodes(target, pos, 1);
|
||||
if (ret < 0)
|
||||
goto ex;
|
||||
}
|
||||
}
|
||||
ret = ISO_SUCCESS;
|
||||
ex:;
|
||||
if (old_cx_value != NULL)
|
||||
free(old_cx_value);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
return ISO_SUCCESS;
|
||||
}
|
||||
|
||||
static
|
||||
int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
|
||||
{
|
||||
int ret, i, voldesc_size, nwriters, image_checksums_mad = 0, tag_pos;
|
||||
int ret, i, voldesc_size, nwriters, tag_pos;
|
||||
int sa_type;
|
||||
Ecma119Image *target;
|
||||
IsoImageWriter *writer;
|
||||
@ -1994,9 +2044,6 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
|
||||
nwriters++; /* Tail padding writer */
|
||||
if ((target->md5_file_checksums & 1) || target->md5_session_checksum) {
|
||||
nwriters++;
|
||||
image_checksums_mad = 1; /* from here on the loaded checksums are
|
||||
not consistent with isofs.cx any more.
|
||||
*/
|
||||
ret = checksum_prepare_image(src, 0);
|
||||
if (ret < 0)
|
||||
goto target_cleanup;
|
||||
@ -2367,10 +2414,6 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
|
||||
if (ret < 0)
|
||||
goto target_cleanup;
|
||||
}
|
||||
/* Dispose old image checksum buffer. The one of target is supposed to
|
||||
get attached at the end of write_function(). */
|
||||
iso_image_free_checksums(target->image, 0);
|
||||
image_checksums_mad = 0;
|
||||
|
||||
if (target->apm_block_size == 0) {
|
||||
if (target->gpt_req_count)
|
||||
@ -2419,8 +2462,6 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
|
||||
return ISO_SUCCESS;
|
||||
|
||||
target_cleanup: ;
|
||||
if(image_checksums_mad) /* No checksums is better than mad checksums */
|
||||
iso_image_free_checksums(target->image, 0);
|
||||
target->image->generator_is_running = 0;
|
||||
ecma119_image_free(target);
|
||||
return ret;
|
||||
|
@ -540,13 +540,12 @@ int checksum_copy_old_nodes(Ecma119Image *target, IsoNode *node, int flag)
|
||||
if (value != NULL)
|
||||
free(value);
|
||||
|
||||
/* ts B30114 : It is unclear why these are removed here.
|
||||
/* >>> ts B30114 : It is unclear why these are removed here.
|
||||
At least with the opts->will_cancel runs,
|
||||
this is not appropriate.
|
||||
*/
|
||||
iso_node_remove_xinfo(node, checksum_md5_xinfo_func);
|
||||
}
|
||||
iso_node_remove_xinfo(node, checksum_cx_xinfo_func);
|
||||
}
|
||||
} else if (node->type == LIBISO_DIR) {
|
||||
for (pos = ((IsoDir *) node)->children; pos != NULL; pos = pos->next) {
|
||||
|
@ -2756,6 +2756,8 @@ int iso_node_cmp_ino(IsoNode *n1, IsoNode *n2, int flag)
|
||||
}
|
||||
|
||||
|
||||
/* @param flag bit0= delete isofs.cx rather than setting it
|
||||
*/
|
||||
int iso_file_set_isofscx(IsoFile *file, unsigned int checksum_index,
|
||||
int flag)
|
||||
{
|
||||
@ -2765,9 +2767,14 @@ int iso_file_set_isofscx(IsoFile *file, unsigned int checksum_index,
|
||||
char *valuept;
|
||||
int i, ret;
|
||||
|
||||
valuept= (char *) value;
|
||||
if (flag & 1) {
|
||||
ret = iso_node_set_attrs((IsoNode *) file, (size_t) 1,
|
||||
&names, value_lengths, &valuept, 4 | 8);
|
||||
return 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;
|
||||
|
Loading…
Reference in New Issue
Block a user