"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "xorriso/write_run.c" between
xorriso-1.5.2.tar.gz and xorriso-1.5.4.tar.gz

About: GNU xorriso creates, loads, manipulates and writes ISO 9660 filesystem images with Rock Ridge extensions. It is suitable for incremental data backup and for production of bootable ISO 9660 images. GNU xorriso is a statical compilation of the libraries libburn, libisofs, libisoburn, and libjte.

write_run.c  (xorriso-1.5.2):write_run.c  (xorriso-1.5.4)
/* xorriso - creates, loads, manipulates and burns ISO 9660 filesystem images. /* xorriso - creates, loads, manipulates and burns ISO 9660 filesystem images.
Copyright 2007-2017 Thomas Schmitt, <scdbackup@gmx.net> Copyright 2007-2020 Thomas Schmitt, <scdbackup@gmx.net>
Provided under GPL version 2 or later. Provided under GPL version 2 or later.
This file contains functions which are needed to write sessions. This file contains functions which are needed to write sessions.
*/ */
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
#include "../config.h" #include "../config.h"
#endif #endif
skipping to change at line 686 skipping to change at line 686
Text_shellsafe(bin_path, xorriso->info_text, 1); Text_shellsafe(bin_path, xorriso->info_text, 1);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
{ret= 0; goto ex;} {ret= 0; goto ex;}
} }
} }
if(xorriso->boot_count == 0) { if(xorriso->boot_count == 0) {
if(xorriso->boot_image_cat_path[0] == 0) { if(xorriso->boot_image_cat_path[0] == 0) {
strcpy(xorriso->boot_image_cat_path, bin_path); strcpy(xorriso->boot_image_cat_path, bin_path);
cpt= strrchr(xorriso->boot_image_cat_path, '/'); cpt= strrchr(xorriso->boot_image_cat_path, '/');
if(cpt == NULL) if(cpt == NULL) {
cpt= xorriso->boot_image_cat_path; strcpy(xorriso->boot_image_cat_path, "/");
else cpt= xorriso->boot_image_cat_path + 1;
} else {
cpt++; cpt++;
}
strcpy(cpt, "boot.cat"); strcpy(cpt, "boot.cat");
} }
ret= Xorriso_node_from_path(xorriso, image, xorriso->boot_image_cat_path, ret= Xorriso_node_from_path(xorriso, image, xorriso->boot_image_cat_path,
&node, 1); &node, 1);
if(ret > 0) { if(ret > 0) {
if(!xorriso->do_overwrite) { if(!xorriso->do_overwrite) {
sprintf(xorriso->info_text, sprintf(xorriso->info_text,
"May not overwrite existing -boot_image ... cat_path="); "May not overwrite existing -boot_image ... cat_path=");
Text_shellsafe(xorriso->boot_image_cat_path, xorriso->info_text, 1); Text_shellsafe(xorriso->boot_image_cat_path, xorriso->info_text, 1);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
skipping to change at line 1008 skipping to change at line 1010
ret= Xorriso_eval_problem_status(xorriso, 1, 0); ret= Xorriso_eval_problem_status(xorriso, 1, 0);
if(ret<0) if(ret<0)
{ret= 0; goto ex;} {ret= 0; goto ex;}
if(xorriso->zisofs_by_magic && image != NULL) { if(xorriso->zisofs_by_magic && image != NULL) {
sprintf(xorriso->info_text, sprintf(xorriso->info_text,
"Checking disk file content for zisofs compression headers."); "Checking disk file content for zisofs compression headers.");
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "UPDATE", 0); Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "UPDATE", 0);
root_node= (IsoNode *) iso_image_get_root(image); root_node= (IsoNode *) iso_image_get_root(image);
ret= iso_node_zf_by_magic(root_node, ret= iso_node_zf_by_magic(root_node,
(xorriso->out_drive_handle == xorriso->in_drive_handle) | 2 | 16); (xorriso->out_drive_handle == xorriso->in_drive_handle) |
2 | 16 | (xorriso->zisofs_by_magic << 8));
if(ret<0) { if(ret<0) {
Xorriso_report_iso_error(xorriso, "", ret, Xorriso_report_iso_error(xorriso, "", ret,
"Error when examining file content for zisofs headers", "Error when examining file content for zisofs headers",
0, "FAILURE", 1); 0, "FAILURE", 1);
} }
ret= Xorriso_eval_problem_status(xorriso, 1, 0); ret= Xorriso_eval_problem_status(xorriso, 1, 0);
if(ret<0) if(ret<0)
{ret= 0; goto ex;} {ret= 0; goto ex;}
sprintf(xorriso->info_text, sprintf(xorriso->info_text,
"Check for zisofs compression headers done."); "Check for zisofs compression headers done.");
skipping to change at line 1249 skipping to change at line 1252
is_bootable= iso_image_get_boot_image(image, NULL, NULL, &bootcat_node); is_bootable= iso_image_get_boot_image(image, NULL, NULL, &bootcat_node);
} }
if(image!=NULL && !(flag&1)) { if(image!=NULL && !(flag&1)) {
if(xorriso->boot_count > 0 || freshly_bootable) { if(xorriso->boot_count > 0 || freshly_bootable) {
/* Eventually rename boot catalog node to changed boot_image_cat_path */ /* Eventually rename boot catalog node to changed boot_image_cat_path */
if(is_bootable > 0) { if(is_bootable > 0) {
ret= Xorriso_path_from_node(xorriso, (IsoNode *) bootcat_node, sfe, 0); ret= Xorriso_path_from_node(xorriso, (IsoNode *) bootcat_node, sfe, 0);
if(ret > 0) { if(ret > 0) {
if(strcmp(sfe, xorriso->boot_image_cat_path) != 0) { if(strcmp(sfe, xorriso->boot_image_cat_path) != 0) {
ret= Xorriso_rename(xorriso, NULL, sfe, ret= Xorriso_rename(xorriso, NULL, sfe,
xorriso->boot_image_cat_path, 0); xorriso->boot_image_cat_path, 1);
if(ret <= 0) if(ret <= 0)
goto ex; goto ex;
} }
} }
} }
hide_attr= !!(xorriso->boot_image_cat_hidden); hide_attr= !!(xorriso->boot_image_cat_hidden);
if(xorriso->boot_image_cat_hidden & 1) if(xorriso->boot_image_cat_hidden & 1)
hide_attr|= LIBISO_HIDE_ON_RR; hide_attr|= LIBISO_HIDE_ON_RR;
if(xorriso->boot_image_cat_hidden & 2) if(xorriso->boot_image_cat_hidden & 2)
hide_attr|= LIBISO_HIDE_ON_JOLIET; hide_attr|= LIBISO_HIDE_ON_JOLIET;
skipping to change at line 1768 skipping to change at line 1771
if(ret <= 0) if(ret <= 0)
return(0); return(0);
ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive, ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive,
"on attempt to -blank", 2); "on attempt to -blank", 2);
if(ret<=0) if(ret<=0)
return(0); return(0);
burn_disc_get_profile(drive, &current_profile, current_profile_name); burn_disc_get_profile(drive, &current_profile, current_profile_name);
disc_state = isoburn_disc_get_status(drive); disc_state = isoburn_disc_get_status(drive);
if(current_profile == 0x13) { /* overwriteable DVD-RW */ if(current_profile == 0x13) { /* overwritable DVD-RW */
/* Depending on flag bit1 formatted DVD-RW will get blanked to sequential /* Depending on flag bit1 formatted DVD-RW will get blanked to sequential
state or pseudo blanked by invalidating an eventual ISO image. */ state or pseudo blanked by invalidating an eventual ISO image. */
if(flag&2) if(flag&2)
do_deformat= 1; do_deformat= 1;
} else if(current_profile == 0x14) { /* sequential DVD-RW */ } else if(current_profile == 0x14) { /* sequential DVD-RW */
if((flag&1) && !(flag&2)) { if((flag&1) && !(flag&2)) {
sprintf(xorriso->info_text, sprintf(xorriso->info_text,
"-blank: DVD-RW present. Mode 'fast' defaulted to mode 'all'."); "-blank: DVD-RW present. Mode 'fast' defaulted to mode 'all'.");
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
sprintf(xorriso->info_text, sprintf(xorriso->info_text,
skipping to change at line 2844 skipping to change at line 2847
} }
ex: ex:
Xorriso_process_msg_queues(xorriso,0); Xorriso_process_msg_queues(xorriso,0);
if(boots != NULL) if(boots != NULL)
free(boots); free(boots);
if(bootnodes != NULL) if(bootnodes != NULL)
free(bootnodes); free(bootnodes);
return(ret); return(ret);
} }
int Xorriso_overwrite_iso_head(struct XorrisO *xorriso,
struct burn_drive *drive, char *head_buffer,
int lba, int flag)
{
int ret;
off_t to_write;
to_write= 64 * 1024;
burn_drive_reset_simulate(drive, xorriso->do_dummy);
ret= burn_random_access_write(drive, (off_t) lba * (off_t) 2048,
head_buffer, to_write, 1);
if(ret <= 0) {
Xorriso_process_msg_queues(xorriso, 0);
sprintf(xorriso->info_text,
"Cannot write new ISO image head to LBA %d", lba);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
return(0);
}
return(1);
}
/* @param flag bit0= insist on tag_type 4 (relocated superblock tag)
*/
int Xorriso_find_sb_checksum(struct XorrisO *xorriso,
char *head_buffer, int *vd_end, int flag)
{
int i, tag_type, ret;
uint32_t pos, range_start, range_size, next_tag;
char md5[16];
*vd_end= 0;
/* Look for volume descriptor end */
for(i= 16; i < 32; i++)
if(((unsigned char *) head_buffer)[i * 2048] == 0xff &&
strncmp(head_buffer + i * 2048 + 1, "CD001", 5) == 0)
break;
/* Check whether the next one is a libisofs checksum tag */
if(i < 32) {
*vd_end= i;
i++;
ret= iso_util_decode_md5_tag(head_buffer + i * 2048, &tag_type, &pos,
&range_start, &range_size, &next_tag, md5, 0);
if(ret <= 0)
return(ret);
if((flag & 1) && tag_type != 4)
return(0); /* No other tag type is supposed to occur before type 4 */
}
return(i + 1);
}
/* @param field_head Example: " md5="
*/
int Xorriso__set_iso_check_tag_md5(char *tag_data, char *field_head,
void **ctx, int *field_end, int flag)
{
char md5_bin[16], m32, *cpt;
int i;
iso_md5_end(ctx, md5_bin);
cpt= strstr(tag_data, field_head);
if(cpt == NULL)
return(0);
cpt+= strlen(field_head);
m32= cpt[32];
for(i= 0; i < 16; i++)
sprintf(cpt + 2 * i, "%2.2x", ((unsigned char *) md5_bin)[i]);
cpt[32]= m32;
*field_end= (cpt - tag_data) + 32;
return(1);
}
int Xorriso_verify_sb_tag(struct XorrisO *xorriso, char *head_buffer,
int checksum_block, int flag)
{
int tag_type, ret;
uint32_t pos, range_start, range_size, next_tag;
char md5_rec[16], md5_comp[16];
void *ctx= NULL;
/* Obtain checksum */
iso_util_decode_md5_tag(head_buffer + checksum_block * 2048,
&tag_type, &pos, &range_start, &range_size,
&next_tag, md5_rec, 0);
/* Verify checksum */
ret= iso_md5_start(&ctx);
if(ret <= 0) {
Xorriso_process_msg_queues(xorriso,0);
Xorriso_no_malloc_memory(xorriso, NULL, 0);
return(0);
}
ret= iso_md5_compute(ctx, head_buffer, checksum_block * 2048);
iso_md5_end(&ctx, md5_comp);
if(ret <= 0) {
Xorriso_process_msg_queues(xorriso,0);
return(0);
}
if(iso_md5_match(md5_rec, md5_comp))
return(1);
Xorriso_msgs_submit(xorriso, 0,
"Superblock data do not match superblock checksum tag",
0, "WARNING", 0);
return(0);
}
int Xorriso_refresh_sb_tag(struct XorrisO *xorriso, char *head_buffer,
int checksum_block, int flag)
{
int ret, field_end;
char md5_bin[16];
void *ctx= NULL;
/* Recompute checksum and update found checksum tag */;
ret= iso_md5_start(&ctx);
if(ret <= 0) {
no_md5_ctx:;
Xorriso_process_msg_queues(xorriso,0);
Xorriso_no_malloc_memory(xorriso, NULL, 0);
return(0);
}
ret= iso_md5_compute(ctx, head_buffer, checksum_block * 2048);
if(ret <= 0) {
md5_comp_failed:;
iso_md5_end(&ctx, md5_bin);
return(0);
}
Xorriso__set_iso_check_tag_md5(head_buffer + checksum_block * 2048,
" md5=", &ctx, &field_end, 0);
if(ret <= 0)
return(2);
ret= iso_md5_start(&ctx);
if(ret <= 0)
goto no_md5_ctx;
ret= iso_md5_compute(ctx, head_buffer + checksum_block * 2048,
field_end);
if(ret <= 0)
goto md5_comp_failed;
Xorriso__set_iso_check_tag_md5(head_buffer + checksum_block * 2048,
" self=", &ctx, &field_end, 0);
return(1);
}
/* /*
@param flag bit0= obtain iso_lba from indev @param flag bit0= obtain iso_lba from indev
bit1= head_buffer already contains a valid head bit1= head_buffer already contains a valid head
bit2= issue message about success bit2= issue message about success
bit3= check whether source blocks are banned by in_sector_map bit3= check whether source blocks are banned by in_sector_map
bit4= refresh relocated sb checksum tag
*/ */
int Xorriso_update_iso_lba0(struct XorrisO *xorriso, int iso_lba, int isosize, int Xorriso_update_iso_lba0(struct XorrisO *xorriso, int iso_lba, int isosize,
char *head_buffer, struct CheckmediajoB *job, char *head_buffer, struct CheckmediajoB *job,
int flag) int flag)
{ {
int ret, full_size, i; int ret, full_size, i, checksum_block= -1, vd_end;
char *headpt; char *headpt;
struct burn_drive_info *dinfo; struct burn_drive_info *dinfo;
struct burn_drive *drive = NULL; struct burn_drive *drive = NULL;
off_t seek_ret, to_write; off_t seek_ret, to_write;
int tag_type;
uint32_t pos, range_start, range_size, next_tag;
char md5[16];
ret= Xorriso_may_burn(xorriso, 0); ret= Xorriso_may_burn(xorriso, 0);
if(ret <= 0) if(ret <= 0)
return(0); return(0);
if(flag & 1) { if(flag & 1) {
ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive, ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive,
"on attempt to learn current session lba", 1); "on attempt to learn current session lba", 0);
if(ret<=0) if(ret<=0)
return(0); return(0);
ret= isoburn_disc_get_msc1(drive, &iso_lba); ret= isoburn_disc_get_msc1(drive, &iso_lba);
if(ret<=0) if(ret<=0)
return(0); return(0);
drive= NULL; /* indev will not be used furtherly */ drive= NULL; /* indev will not be used furtherly */
} }
if(job == NULL) { if(job == NULL) {
ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive, ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive,
"on attempt to update at lba 0 to 31", 2); "on attempt to update at lba 0 to 31", 2);
skipping to change at line 2938 skipping to change at line 3081
ret= isoburn_read_iso_head(drive, iso_lba, &isosize, head_buffer, 2); ret= isoburn_read_iso_head(drive, iso_lba, &isosize, head_buffer, 2);
if(ret<=0) { if(ret<=0) {
Xorriso_process_msg_queues(xorriso,0); Xorriso_process_msg_queues(xorriso,0);
sprintf(xorriso->info_text, sprintf(xorriso->info_text,
"Cannot read freshly written ISO image head"); "Cannot read freshly written ISO image head");
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
return(0); return(0);
} }
} }
} }
/* patch ISO header */ /* patch ISO header */
full_size= iso_lba + isosize; full_size= iso_lba + isosize;
headpt= head_buffer + 32*1024; headpt= head_buffer + 32*1024;
for(i=0;i<4;i++) for(i=0;i<4;i++)
headpt[87-i]= headpt[80+i]= (full_size >> (8*i)) & 0xff; headpt[87-i]= headpt[80+i]= (full_size >> (8*i)) & 0xff;
/* >>> What about Joliet et.al. ? */;
if(flag & 16) {
/* Find relocated sb checksum tag */
ret= Xorriso_find_sb_checksum(xorriso, head_buffer, &vd_end, 1);
if(ret > 0) {
/* If it is recognizable then it matched in Xorriso_adjust_relocated_sb */
checksum_block= ret - 1;
ret= Xorriso_refresh_sb_tag(xorriso, head_buffer, checksum_block, 0);
if(ret <= 0)
return(0);
}
}
if(job != NULL) { if(job != NULL) {
/* This is a check_media superblock relocation: /* This is a check_media superblock relocation:
Invalidate eventual libisofs checksum tags. Invalidate eventual libisofs checksum tags.
Write only up to PVD end plus eventual invalidated tag. Write only up to PVD end plus eventual invalidated tag.
*/ */
/* Look for volume descriptor end */ to_write= 2048 * 32;
for(i= 16; i < 32; i++) ret= Xorriso_find_sb_checksum(xorriso, head_buffer, &i, 0);
if(((unsigned char *) head_buffer)[i * 2048] == 0xff && if(ret > 0) {
strncmp(head_buffer + i * 2048 + 1, "CD001", 5) == 0) if(!(flag & 16)) /* invalidate */
break; memset(head_buffer + (ret - 1) * 2048, 0, 8);
/* Check whether the next one is a libisofs checksum tag */ to_write= 2048 * ret;
if(i < 32) { } else if(i > 0) {
i++; to_write= 2048 * (i + 1);
ret= iso_util_decode_md5_tag(head_buffer + i * 2048, &tag_type, &pos,
&range_start, &range_size, &next_tag, md5, 0);
if(ret != 0) /* corrupted or not: invalidate */
memset(head_buffer + i * 2048, 0, 8);
} }
to_write= 2048 * (i + 1);
seek_ret= lseek(job->data_to_fd, (off_t) 0, SEEK_SET); seek_ret= lseek(job->data_to_fd, (off_t) 0, SEEK_SET);
if(seek_ret == -1) if(seek_ret == -1)
ret= 0; ret= 0;
else else
ret= write(job->data_to_fd, head_buffer, to_write); ret= write(job->data_to_fd, head_buffer, to_write);
if(ret < to_write) { if(ret < to_write) {
Xorriso_process_msg_queues(xorriso,0); Xorriso_process_msg_queues(xorriso,0);
sprintf(xorriso->info_text, sprintf(xorriso->info_text,
"Cannot write ISO image head to file copy"); "Cannot write ISO image head to file copy");
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE",0); Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE",0);
return(0); return(0);
} }
} else { } else {
/* This is a regular superblock relocation. Write full 64 kB. */ /* This is a regular superblock relocation. Write full 64 kB. */
to_write= 64 * 1024; ret= Xorriso_overwrite_iso_head(xorriso, drive, head_buffer, 0, 0);
burn_drive_reset_simulate(drive, xorriso->do_dummy); if(ret <= 0)
ret= burn_random_access_write(drive, (off_t) 0, head_buffer, to_write, 1); return(ret);
if(ret<=0) {
Xorriso_process_msg_queues(xorriso,0);
sprintf(xorriso->info_text,
"Cannot write new ISO image head to LBA 0");
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
return(0);
}
} }
if(flag & 4) { if(flag & 4) {
sprintf(xorriso->info_text, sprintf(xorriso->info_text,
"Overwrote LBA 0 to 31 by 64 KiB from LBA %d", iso_lba); "Overwrote LBA 0 to 31 by 64 KiB from LBA %d", iso_lba);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
} }
return(1); return(1);
} }
/* @return 1= ok, 0= no match, -1= MD5 computation error,
-2= MD5 clone or start error
*/
int Xorriso_migrate_checksum_tag(struct XorrisO *xorriso, char *buffer,
int buf_base, int start,
int checksum_block, char md5_rec[16],
void *ctx_unch, void *ctx_chng, int flag)
{
int ret, to_compute;
char *headpt, md5_clone[16];
void *ctx_clone= NULL;
int field_end;
/* Checksum both up to before checksum tag */
headpt= buffer + start * 2048;
to_compute= (checksum_block - start) * 2048;
if(to_compute > 0) {
ret= iso_md5_compute(ctx_unch, headpt, to_compute);
if(ret <= 0)
{ret= -1; goto ex;}
ret= iso_md5_compute(ctx_chng, headpt, to_compute);
if(ret <= 0)
{ret= -1; goto ex;}
}
/* Verify with unchanged checksum */
ret= iso_md5_clone(ctx_unch, &ctx_clone);
if(ret <= 0)
{ret= -2; goto ex;}
iso_md5_end(&ctx_clone, md5_clone);
if(!iso_md5_match(md5_rec, md5_clone))
{ret= 0; goto ex;}
/* Compute unchanged rest of block range */
headpt= buffer + checksum_block * 2048;
to_compute= 2048;
ret= iso_md5_compute(ctx_unch, headpt, to_compute);
if(ret <= 0)
{ret= -1; goto ex;}
/* Replace checksum in tag by changed checksum */
ret= iso_md5_clone(ctx_chng, &ctx_clone);
if(ret <= 0)
{ret= -2; goto ex;}
Xorriso__set_iso_check_tag_md5(headpt, " md5=", &ctx_clone, &field_end, 0);
/* Recompute and write self= checksum */
ret= iso_md5_start(&ctx_clone);
if(ret <= 0)
{ret= -2; goto ex;}
ret= iso_md5_compute(ctx_clone, headpt, field_end);
if(ret <= 0)
{ret= -1; goto ex;}
Xorriso__set_iso_check_tag_md5(headpt, " self=", &ctx_clone, &field_end, 0);
/* Add rest of head_buffer to changed checksum */
ret= iso_md5_compute(ctx_chng, headpt, to_compute);
if(ret <= 0)
{ret= -1; goto ex;}
ret= 1;
ex:;
if(ctx_clone != NULL)
iso_md5_end(&ctx_clone, md5_clone);
return(ret);
}
/* Verify and re-compute tree and session checksum tag */
int Xorriso_refresh_ts_tags(struct XorrisO *xorriso,
struct burn_drive *drive,
void *ctx_unch, void *ctx_chng,
int iso_lba, int session_size,
int checksum_block, int flag)
{
int i, ret, tag_type, look_for_tag, check_start, look_from_block, was_change;
off_t read_pos, to_read, data_count;
uint32_t pos, range_start, range_size, next_tag;
char md5_rec[16];
char *buf= NULL;
look_for_tag= 3; /* tree tag */
look_from_block= checksum_block + 1; /* first buffer is already partly done */
Xorriso_alloc_meM(buf, char, 32 * 2048);
for(read_pos= iso_lba; read_pos < iso_lba + session_size; read_pos+= 32) {
was_change= 0;
to_read= 32;
if(read_pos + to_read > iso_lba + session_size)
to_read= iso_lba + session_size - read_pos;
ret= burn_read_data(drive, read_pos * (off_t) 2048, buf,
to_read * (off_t) 2048, &data_count, 0);
if(ret <= 0)
{ret= 0; goto ex;}
check_start= look_from_block;
for(i= look_from_block; i < to_read; i++) {
/* Watch out for tag */
ret= iso_util_decode_md5_tag(buf + i * 2048,
&tag_type, &pos, &range_start, &range_size,
&next_tag, md5_rec, look_for_tag);
if(ret < 0 ) {
ret= 0; goto ex;
} else if(ret == 1) {
if(tag_type != look_for_tag) {
sprintf(xorriso->info_text,
"Encountered checksum tag type %d while looking for %d",
tag_type, look_for_tag);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "MISHAP", 0);
ret= 2; goto ex;
}
/* Checksum up to before tag, verify,
if match replace checksum and write */
ret= Xorriso_migrate_checksum_tag(xorriso, buf, read_pos, check_start,
i, md5_rec, ctx_unch, ctx_chng, 0);
if(ret == -2)
goto ex;
if(ret < 0)
{ret= 0; goto ex;}
if(ret == 0) {
sprintf(xorriso->info_text,
"Checksum tag MD5 mismatch in old session state");
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "MISHAP", 0);
ret= 2; goto ex;
}
was_change= 1;
if(look_for_tag == 3) {
look_for_tag= 1; /* session tag */
} else {
look_for_tag= -1;
break;
}
check_start= i + 1;
}
}
look_from_block= 0; /* all following buffer need processing from start */
if(was_change) {
ret= burn_random_access_write(drive, (off_t) read_pos * (off_t) 2048,
buf, to_read * (off_t) 2048, 1);
if(ret <= 0) {
Xorriso_process_msg_queues(xorriso, 0);
sprintf(xorriso->info_text,
"Cannot write new checksum tag data to LBA %d", (int) read_pos);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
ret= 0; goto ex;
}
}
if(look_for_tag < 0)
{ret= 1; goto ex;}
/* Checksum what was not checksummed yet */
if(to_read - check_start > 0) {
ret= iso_md5_compute(ctx_unch, buf + 2048 * check_start,
(to_read - check_start) * 2048);
if(ret <= 0)
{ret= 0; goto ex;}
ret= iso_md5_compute(ctx_chng, buf + 2048 * check_start,
(to_read - check_start) * 2048);
if(ret <= 0)
{ret= 0; goto ex;}
}
}
ret= 1;
ex:;
Xorriso_free_meM(buf);
return(ret);
}
int Xorriso_adjust_session_size(struct XorrisO *xorriso,
struct burn_drive *drive,
char *head_buffer,
int iso_lba, int iso_size,
int checksum_block, int session_size, int flag)
{
int i, ret, tag_type;
uint32_t pos, range_start, range_size, next_tag;
char *headpt, md5_unch[16], md5_chng[16], md5_clone[16], md5_rec[16];
void *ctx_unch= NULL, *ctx_chng= NULL, *ctx_clone= NULL;
if(checksum_block > 0) {
/* Obtain recorded superblock MD5 */
ret= iso_util_decode_md5_tag(head_buffer + checksum_block * 2048,
&tag_type, &pos, &range_start, &range_size,
&next_tag, md5_rec, 0);
if(ret <= 0 || tag_type != 2) {
sprintf(xorriso->info_text,
"Encountered checksum tag type %d while looking for 2", tag_type);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "MISHAP", 0);
checksum_block= 0;
}
}
if(checksum_block > 0) {
/* Create md5 context for unchanged state */
ret= iso_md5_start(&ctx_unch);
if(ret <= 0) {
no_ctx:;
Xorriso_process_msg_queues(xorriso, 0);
Xorriso_no_malloc_memory(xorriso, NULL, 0);
goto ex;
}
/* Checksum up to before PVD */
ret= iso_md5_compute(ctx_unch, head_buffer, 32768);
if(ret <= 0)
goto ex;
/* Before the first change: obtain md5 object for changed state */
ret= iso_md5_clone(ctx_unch, &ctx_chng);
if(ret <= 0)
goto no_ctx;
/* Add PVD to unchanged checksum */
ret= iso_md5_compute(ctx_unch, head_buffer + 32768, 2048);
if(ret <= 0)
goto ex;
}
/* Update session PVD at iso_lba+16 to iso_size */
headpt= head_buffer + 32 * 1024;
for(i= 0; i < 4; i++)
headpt[87 - i]= headpt[80 + i]= (iso_size >> (8 * i)) & 0xff;
if(checksum_block > 0) {
/* Add changed PVD to changed checksum */
ret= iso_md5_compute(ctx_chng, head_buffer + 32768, 2048);
if(ret <= 0)
goto ex;
ret= Xorriso_migrate_checksum_tag(xorriso, head_buffer, iso_lba, 17,
checksum_block, md5_rec,
ctx_unch, ctx_chng, 0);
if(ret == -2)
goto no_ctx;
if(ret < 0)
{ret= 0; goto ex;}
if(ret == 0) {
sprintf(xorriso->info_text,
"Superblock MD5 mismatch in old session state");
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "MISHAP", 0);
checksum_block= 0;
}
}
ret= Xorriso_overwrite_iso_head(xorriso, drive, head_buffer, iso_lba, 0);
if(ret <= 0)
goto ex;
if(checksum_block > 0) {
/* Verify and re-compute existing checksum tree and session tag */
ret= Xorriso_refresh_ts_tags(xorriso, drive, ctx_unch, ctx_chng,
iso_lba, session_size, checksum_block, 0);
if(ret == -2)
goto no_ctx;
if(ret <= 0)
goto ex;
}
ret= 1;
ex:;
Xorriso_process_msg_queues(xorriso, 0);
if(ctx_unch != NULL)
iso_md5_end(&ctx_unch, md5_unch);
if(ctx_chng != NULL)
iso_md5_end(&ctx_chng, md5_chng);
if(ctx_clone != NULL)
iso_md5_end(&ctx_clone, md5_clone);
return(ret);
}
/* Read relocated superblock and patch in the VDs of the session superblock */
int Xorriso_adjust_relocated_sb(struct XorrisO *xorriso,
struct burn_drive *drive,
char *head_buffer,
char **sb_buffer,
int flag)
{
int ret, old_size, i, vd_end, checksum_block= -1;
char *buffer, *checksum= NULL;
*sb_buffer= NULL;
Xorriso_alloc_meM(*sb_buffer, char, 32 * 2048);
buffer= *sb_buffer;
Xorriso_alloc_meM(checksum, char, 2048);
ret= isoburn_read_iso_head(drive, 0, &old_size, buffer, 2);
if(ret <= 0)
goto ex;
ret= Xorriso_find_sb_checksum(xorriso, buffer, &vd_end, 0);
if(ret <= 0)
goto ex;
if(ret > 0) {
checksum_block= ret - 1;
memcpy(checksum, buffer + checksum_block * 2048, 2048);
ret= Xorriso_verify_sb_tag(xorriso, buffer, checksum_block, 0);
if(ret <= 0) {
checksum_block= -1;
memset(checksum, 0, 8);
}
}
for(i= 16; i < 32; i++) {
memcpy(buffer + i * 2048, head_buffer + i * 2048, 2048);
if(((unsigned char *) head_buffer)[i * 2048] == 0xff &&
strncmp(head_buffer + i * 2048 + 1, "CD001", 5) == 0) {
i++;
break;
}
}
if(checksum_block >= 0 && i < 32)
memcpy(buffer + i * 2048, checksum, 2048);
ret= 1;
ex:
if(ret <= 0)
Xorriso_free_meM(*sb_buffer);
Xorriso_free_meM(checksum);
return(ret);
}
int Xorriso_truncate_overwritable(struct XorrisO *xorriso, char *adr_mode,
char *adr_value, char *adjust, int flag)
{
int ret, iso_lba= 0, iso_session, iso_track, iso_size= 0, image_start_mode= 0;
int old_size, new_size, blocks, was_indev= 0, checksum_block= 0, vd_end;
int readable_blocks;
char image_start_value[81], *head_buffer= NULL, iso_volid[33];
char *sb_buffer= NULL;
struct burn_drive_info *dinfo;
struct burn_drive *drive = NULL, *in_drive = NULL;
struct burn_multi_caps *caps= NULL;
Xorriso_alloc_meM(head_buffer, char, 32 * 2048);
if(Xorriso_change_is_pending(xorriso, 0)) {
sprintf(xorriso->info_text,
"-truncate_overwritable: Image changes pending. -commit or -rollback first");
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
ret= 0; goto ex;
}
ret= Xorriso_may_burn(xorriso, 0);
if(ret <= 0)
goto ex;
ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive,
"on attempt to activate an older session", 2);
if(ret <= 0)
goto ex;
/* Is it overwritable ? */
ret= burn_disc_get_multi_caps(drive, BURN_WRITE_NONE, &caps, 0);
if(ret > 0) {
if(caps->start_adr == 0)
ret= 0;
}
if(ret <= 0) {
sprintf(xorriso->info_text,
"-truncate_overwritable: Loaded medium is not random-access overwritable");
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
goto ex;
}
ret= Xorriso_reassure(xorriso, "-truncate_overwritable",
"activates an older session and destroys newer ones", 0);
if(ret <= 0)
{ret= 2; goto ex;}
/* Learn old size */
ret= isoburn_read_iso_head(drive, 0, &old_size, iso_volid, 0);
if(ret <= 0) {
sprintf(xorriso->info_text,
"-truncate_overwritable: Cannot read ISO 9660 Volume Descriptor from LBA 0");
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
goto ex;
}
/* Check for PVD at image_start_value and learn new size */
ret= Xorriso_decode_load_adr(xorriso, "-truncate_overwritable",
adr_mode, adr_value, &image_start_mode,
image_start_value, 0);
if(ret <= 0)
goto ex;
ret= isoburn_get_mount_params(drive, image_start_mode, image_start_value,
&iso_lba, &iso_track, &iso_session, iso_volid,
0);
if(ret <= 0)
goto ex;
if(ret != 1) {
sprintf(xorriso->info_text,
"-truncate_overwritable: Given address does not lead to ISO 9660 Volume Desc
riptor");
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
ret= 0; goto ex;
}
if(iso_lba >= old_size) {
sprintf(xorriso->info_text,
"-truncate_overwritable: Given address is larger than current ISO size");
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
ret= 0; goto ex;
}
ret= isoburn_read_iso_head(drive, iso_lba, &new_size, head_buffer, 2);
if(ret <= 0)
goto ex;
ret= Xorriso_find_sb_checksum(xorriso, head_buffer, &vd_end, 0);
if(ret > 0)
checksum_block= ret - 1;
/* Default is "new" */
iso_size= new_size;
if(strcmp(adjust, "old") == 0) {
/* ISO size before truncation */
iso_size= old_size - iso_lba;
} else if(adjust[0] == '+') {
/* Add-on size to new */
blocks= Scanf_io_size(adjust + 1, 0) / 2048;
if(blocks < 0)
goto wrong_adjust;
iso_size+= blocks;
} else if(adjust[0] >= '0' && adjust[0] <= '9') {
/* Add-on size to new */
blocks= Scanf_io_size(adjust, 0) / 2048;
if(blocks < iso_lba + iso_size) {
wrong_adjust:;
sprintf(xorriso->info_text,
"-truncate_overwritable: Given total filesystem size is smaller tha
n new session size");
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
ret= 0; goto ex;
}
iso_size= blocks - iso_lba;
}
ret= burn_get_read_capacity(drive, &readable_blocks, 0);
Xorriso_process_msg_queues(xorriso, 0);
if(ret > 0) {
if(iso_lba + iso_size > readable_blocks) {
sprintf(xorriso->info_text, "-truncate_overwritable: Given total filesystem
size is larger than formatted medium size");
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
ret= 0; goto ex;
}
}
/* Give up possible input drive */
ret= Xorriso_get_drive_handles(xorriso, &dinfo, &in_drive, "", 16);
if(ret < 0)
goto ex;
if(ret == 1) {
ret= Xorriso_give_up_drive(xorriso, 1);
if(ret<=0)
goto ex;
was_indev= 1;
}
if(iso_size != new_size) {
ret=Xorriso_adjust_session_size(xorriso, drive, head_buffer,
iso_lba, iso_size, checksum_block,
new_size, 0);
if(ret <= 0)
goto ex;
}
/* Load first 64 kB and transfer VDs from head_buffer */
ret= Xorriso_adjust_relocated_sb(xorriso, drive, head_buffer, &sb_buffer, 0);
if(ret <= 0)
goto ex;
/* Patch the size and write back */
ret= Xorriso_update_iso_lba0(xorriso, iso_lba, iso_size, sb_buffer,
NULL, 2 | 16);
if(ret <= 0)
goto ex;
ret= Xorriso_reaquire_outdev(xorriso, 2 + was_indev);
if(ret <= 0)
goto ex;
ret= 1;
ex:
if(caps!=NULL)
burn_disc_free_multi_caps(&caps);
Xorriso_free_meM(head_buffer);
Xorriso_free_meM(sb_buffer);
Xorriso_process_msg_queues(xorriso,0);
return(ret);
}
int Xorriso_set_system_area_path(struct XorrisO *xorriso, char *path, int flag) int Xorriso_set_system_area_path(struct XorrisO *xorriso, char *path, int flag)
{ {
int ret; int ret;
char *eff_src= NULL, *intvl; char *eff_src= NULL, *intvl;
struct iso_interval_reader *ivr= NULL; struct iso_interval_reader *ivr= NULL;
off_t byte_count; off_t byte_count;
IsoImage *img= NULL; IsoImage *img= NULL;
struct burn_drive_info *source_dinfo; struct burn_drive_info *source_dinfo;
struct burn_drive *source_drive; struct burn_drive *source_drive;
 End of changes. 17 change blocks. 
36 lines changed or deleted 658 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)