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;
|
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
|
static
|
||||||
int transplant_checksum_buffer(Ecma119Image *target, int flag)
|
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_idx_counter + 2, 0);
|
||||||
target->checksum_buffer = NULL;
|
target->checksum_buffer = NULL;
|
||||||
target->checksum_idx_counter = 0;
|
target->checksum_idx_counter = 0;
|
||||||
|
|
||||||
|
/* Delete recorded cx xinfo */
|
||||||
|
process_preserved_cx(target->image->root, 0);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1546,7 +1592,7 @@ void *write_function(void *arg)
|
|||||||
return NULL;
|
return NULL;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
write_error: ;
|
write_error: ;
|
||||||
if (res != (int) ISO_LIBJTE_END_FAILED)
|
if (res != (int) ISO_LIBJTE_END_FAILED)
|
||||||
finish_libjte(target);
|
finish_libjte(target);
|
||||||
target->eff_partition_offset = 0;
|
target->eff_partition_offset = 0;
|
||||||
@ -1562,10 +1608,8 @@ void *write_function(void *arg)
|
|||||||
}
|
}
|
||||||
iso_ring_buffer_writer_close(target->buffer, 1);
|
iso_ring_buffer_writer_close(target->buffer, 1);
|
||||||
|
|
||||||
/* Transplant checksum buffer away from Ecma119Image */
|
/* Re-activate recorded cx xinfo */
|
||||||
transplant_checksum_buffer(target, 0);
|
process_preserved_cx(target->image->root, 1);
|
||||||
/* Invalidate the transplanted checksum buffer in IsoImage */
|
|
||||||
iso_image_free_checksums(target->image, 0);
|
|
||||||
|
|
||||||
target->image->generator_is_running = 0;
|
target->image->generator_is_running = 0;
|
||||||
|
|
||||||
@ -1605,82 +1649,88 @@ int checksum_prepare_nodes(Ecma119Image *target, IsoNode *node, int flag)
|
|||||||
IsoNode *pos;
|
IsoNode *pos;
|
||||||
IsoFile *file;
|
IsoFile *file;
|
||||||
IsoImage *img;
|
IsoImage *img;
|
||||||
int ret, i, no_md5 = 0, has_xinfo = 0;
|
int ret, i, no_md5 = 0, has_xinfo = 0, has_attr = 0;
|
||||||
size_t value_length;
|
size_t old_cx_value_length = 0;
|
||||||
unsigned int idx = 0;
|
unsigned int idx = 0;
|
||||||
char *value= NULL;
|
char *old_cx_value= NULL;
|
||||||
void *xipt = NULL;
|
void *xipt = NULL;
|
||||||
static char *cx_names = "isofs.cx";
|
|
||||||
static size_t cx_value_lengths[1] = {0};
|
|
||||||
char *cx_valuept = "";
|
|
||||||
|
|
||||||
img= target->image;
|
img= target->image;
|
||||||
|
|
||||||
if (node->type == LIBISO_FILE) {
|
if (node->type == LIBISO_FILE) {
|
||||||
file = (IsoFile *) node;
|
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) {
|
if (file->from_old_session && target->appendable) {
|
||||||
/* Save MD5 data of files from old image which will not
|
/* Save MD5 data of files from old image which will not
|
||||||
be copied and have an MD5 recorded in the old image. */
|
be copied and have an MD5 recorded in the old image. */
|
||||||
has_xinfo = iso_node_get_xinfo(node, checksum_md5_xinfo_func,
|
has_xinfo = iso_node_get_xinfo(node, checksum_md5_xinfo_func,
|
||||||
&xipt);
|
&xipt);
|
||||||
if (has_xinfo <= 0) {
|
|
||||||
ret = iso_node_lookup_attr(node, "isofs.cx", &value_length,
|
|
||||||
&value, 0);
|
|
||||||
}
|
|
||||||
if (has_xinfo > 0) {
|
if (has_xinfo > 0) {
|
||||||
/* xinfo MD5 overrides everything else unless data get copied
|
/* xinfo MD5 overrides everything else unless data get copied
|
||||||
and checksummed during that copying
|
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" */
|
/* No checksum array loaded. Delete "isofs.cx" */
|
||||||
if (!target->will_cancel)
|
if (!target->will_cancel)
|
||||||
iso_node_set_attrs(node, (size_t) 1,
|
iso_file_set_isofscx((IsoFile *) node, 0, 1);
|
||||||
&cx_names, cx_value_lengths, &cx_valuept, 4 | 8);
|
|
||||||
no_md5 = 1;
|
no_md5 = 1;
|
||||||
} else if (ret == 1 && value_length == 4) {
|
} else if (!(has_attr == 1 && old_cx_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 {
|
|
||||||
no_md5 = 1;
|
no_md5 = 1;
|
||||||
}
|
}
|
||||||
if (value != NULL) {
|
|
||||||
free(value);
|
|
||||||
value= NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Equip nodes with provisory isofs.cx numbers: 4 byte, all 0.
|
/* 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.
|
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.
|
Do not alter the nodes if this is only a will_cancel run.
|
||||||
*/
|
*/
|
||||||
if (!(target->will_cancel || no_md5)) {
|
if (!(target->will_cancel || no_md5)) {
|
||||||
|
/* Record provisory new index */
|
||||||
ret = iso_file_set_isofscx(file, (unsigned int) 0, 0);
|
ret = iso_file_set_isofscx(file, (unsigned int) 0, 0);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
goto ex;
|
||||||
}
|
}
|
||||||
} else if (node->type == LIBISO_DIR) {
|
} else if (node->type == LIBISO_DIR) {
|
||||||
for (pos = ((IsoDir *) node)->children; pos != NULL; pos = pos->next) {
|
for (pos = ((IsoDir *) node)->children; pos != NULL; pos = pos->next) {
|
||||||
ret = checksum_prepare_nodes(target, pos, 1);
|
ret = checksum_prepare_nodes(target, pos, 1);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
goto ex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ISO_SUCCESS;
|
ret = ISO_SUCCESS;
|
||||||
|
ex:;
|
||||||
|
if (old_cx_value != NULL)
|
||||||
|
free(old_cx_value);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
|
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;
|
int sa_type;
|
||||||
Ecma119Image *target;
|
Ecma119Image *target;
|
||||||
IsoImageWriter *writer;
|
IsoImageWriter *writer;
|
||||||
@ -1994,9 +2044,6 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
|
|||||||
nwriters++; /* Tail padding writer */
|
nwriters++; /* Tail padding writer */
|
||||||
if ((target->md5_file_checksums & 1) || target->md5_session_checksum) {
|
if ((target->md5_file_checksums & 1) || target->md5_session_checksum) {
|
||||||
nwriters++;
|
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);
|
ret = checksum_prepare_image(src, 0);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto target_cleanup;
|
goto target_cleanup;
|
||||||
@ -2367,10 +2414,6 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
|
|||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto target_cleanup;
|
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->apm_block_size == 0) {
|
||||||
if (target->gpt_req_count)
|
if (target->gpt_req_count)
|
||||||
@ -2418,9 +2461,7 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
|
|||||||
*img = target;
|
*img = target;
|
||||||
return ISO_SUCCESS;
|
return ISO_SUCCESS;
|
||||||
|
|
||||||
target_cleanup: ;
|
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;
|
target->image->generator_is_running = 0;
|
||||||
ecma119_image_free(target);
|
ecma119_image_free(target);
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -540,13 +540,12 @@ int checksum_copy_old_nodes(Ecma119Image *target, IsoNode *node, int flag)
|
|||||||
if (value != NULL)
|
if (value != NULL)
|
||||||
free(value);
|
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,
|
At least with the opts->will_cancel runs,
|
||||||
this is not appropriate.
|
this is not appropriate.
|
||||||
*/
|
*/
|
||||||
iso_node_remove_xinfo(node, checksum_md5_xinfo_func);
|
iso_node_remove_xinfo(node, checksum_md5_xinfo_func);
|
||||||
}
|
}
|
||||||
iso_node_remove_xinfo(node, checksum_cx_xinfo_func);
|
|
||||||
}
|
}
|
||||||
} else if (node->type == LIBISO_DIR) {
|
} else if (node->type == LIBISO_DIR) {
|
||||||
for (pos = ((IsoDir *) node)->children; pos != NULL; pos = pos->next) {
|
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 iso_file_set_isofscx(IsoFile *file, unsigned int checksum_index,
|
||||||
int flag)
|
int flag)
|
||||||
{
|
{
|
||||||
@ -2765,9 +2767,14 @@ int iso_file_set_isofscx(IsoFile *file, unsigned int checksum_index,
|
|||||||
char *valuept;
|
char *valuept;
|
||||||
int i, ret;
|
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++)
|
for(i = 0; i < 4; i++)
|
||||||
value[3 - i] = (checksum_index >> (8 * i)) & 0xff;
|
value[3 - i] = (checksum_index >> (8 * i)) & 0xff;
|
||||||
valuept= (char *) value;
|
|
||||||
ret = iso_node_set_attrs((IsoNode *) file, (size_t) 1,
|
ret = iso_node_set_attrs((IsoNode *) file, (size_t) 1,
|
||||||
&names, value_lengths, &valuept, 2 | 8);
|
&names, value_lengths, &valuept, 2 | 8);
|
||||||
return ret;
|
return ret;
|
||||||
|
Loading…
Reference in New Issue
Block a user