New command -truncate_overwritable

This commit is contained in:
Thomas Schmitt 2020-08-06 17:39:47 +02:00
parent ec49c627f9
commit 04a82ce28d
10 changed files with 885 additions and 98 deletions

View File

@ -1845,6 +1845,9 @@ int Xorriso_option_help(struct XorrisO *xorriso, int flag)
" -blank [\"force:\"]\"fast\"|\"all\"|\"deformat\"|\"deformat_quickest\"",
" Blank medium or invalidate ISO image on medium.",
" Prefix \"force:\" overrides medium evaluation.",
" -truncate_overwritable entity id adjust",
" Activate an older session on overwritable medium. Adjust",
" its size to some value not smaller than original old size.",
" -close_damaged \"as_needed\"|\"force\"",
" Close track and session of damaged medium.",
" -format \"as_needed\"|\"full\"|\"fast\"|\"by_index_#\"|\"by_size_#\"",

View File

@ -1,7 +1,7 @@
/* xorriso - creates, loads, manipulates and burns ISO 9660 filesystem images.
Copyright 2007-2018 Thomas Schmitt, <scdbackup@gmx.net>
Copyright 2007-2020 Thomas Schmitt, <scdbackup@gmx.net>
Provided under GPL version 2 or later.
@ -1703,6 +1703,18 @@ int Xorriso_option_toc_of(struct XorrisO *xorriso, char *which, int flag)
}
/* Command -truncate_overwritable */
int Xorriso_option_truncate_overwritable(struct XorrisO *xorriso,
char *adr_mode, char *adr_value,
char *adjust, int flag)
{
int ret;
ret= Xorriso_truncate_overwritable(xorriso, adr_mode, adr_value, adjust, 0);
return(ret);
}
/* Option -uid */
int Xorriso_option_uid(struct XorrisO *xorriso, char *uid, int flag)
{

View File

@ -1,7 +1,7 @@
/* xorriso - creates, loads, manipulates and burns ISO 9660 filesystem images.
Copyright 2007-2019 Thomas Schmitt, <scdbackup@gmx.net>
Copyright 2007-2020 Thomas Schmitt, <scdbackup@gmx.net>
Provided under GPL version 2 or later.
@ -573,7 +573,7 @@ int Xorriso_count_args(struct XorrisO *xorriso, int argc, char **argv,
""
};
static char arg3_commands[][40]= {
"append_partition",
"append_partition", "truncate_overwritable",
""
};
static char arg4_commands[][40]= {
@ -778,7 +778,7 @@ int Xorriso_cmd_sorting_rank(struct XorrisO *xorriso,
"print_size", "tell_media_space",
"* Writing the result, drive control:",
"format", "blank", "close_damaged",
"format", "blank", "truncate_overwritable", "close_damaged",
"rollback", "changes_pending", "commit", "commit_eject",
"eject",
@ -1941,6 +1941,10 @@ if (0) {
(*idx)++;
Xorriso_option_toc_of(xorriso, arg1, 0);
} else if(strcmp(cmd,"truncate_overwritable")==0) {
(*idx)+= 3;
ret= Xorriso_option_truncate_overwritable(xorriso, arg1, arg2, arg3, 0);
} else if(strcmp(cmd,"uid")==0) {
(*idx)++;
ret= Xorriso_option_uid(xorriso,arg1,0);

View File

@ -2,7 +2,7 @@
/* 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.
@ -2866,24 +2866,169 @@ ex:
}
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
bit1= head_buffer already contains a valid head
bit2= issue message about success
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,
char *head_buffer, struct CheckmediajoB *job,
int flag)
{
int ret, full_size, i;
int ret, full_size, i, checksum_block= -1, vd_end;
char *headpt;
struct burn_drive_info *dinfo;
struct burn_drive *drive = NULL;
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);
if(ret <= 0)
@ -2960,33 +3105,41 @@ int Xorriso_update_iso_lba0(struct XorrisO *xorriso, int iso_lba, int isosize,
}
}
}
/* patch ISO header */
full_size= iso_lba + isosize;
headpt= head_buffer + 32*1024;
for(i=0;i<4;i++)
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) {
/* This is a check_media superblock relocation:
Invalidate eventual libisofs checksum tags.
Write only up to PVD end plus eventual invalidated tag.
*/
/* 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) {
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) /* corrupted or not: invalidate */
memset(head_buffer + i * 2048, 0, 8);
to_write= 2048 * 32;
ret= Xorriso_find_sb_checksum(xorriso, head_buffer, &i, 0);
if(ret > 0) {
if(!(flag & 16)) /* invalidate */
memset(head_buffer + (ret - 1) * 2048, 0, 8);
to_write= 2048 * ret;
} else if(i > 0) {
to_write= 2048 * (i + 1);
}
to_write= 2048 * (i + 1);
seek_ret= lseek(job->data_to_fd, (off_t) 0, SEEK_SET);
if(seek_ret == -1)
ret= 0;
@ -3001,16 +3154,9 @@ int Xorriso_update_iso_lba0(struct XorrisO *xorriso, int iso_lba, int isosize,
}
} else {
/* This is a regular superblock relocation. Write full 64 kB. */
to_write= 64 * 1024;
burn_drive_reset_simulate(drive, xorriso->do_dummy);
ret= burn_random_access_write(drive, (off_t) 0, 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 0");
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
return(0);
}
ret= Xorriso_overwrite_iso_head(xorriso, drive, head_buffer, 0, 0);
if(ret <= 0)
return(ret);
}
if(flag & 4) {
sprintf(xorriso->info_text,
@ -3021,6 +3167,485 @@ int Xorriso_update_iso_lba0(struct XorrisO *xorriso, int iso_lba, int isosize,
}
/* @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 Descriptor");
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 than 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 ret;

View File

@ -2652,6 +2652,57 @@ as reported by the drive. They would be chosen by \-read_speed "min" or
"max" if they undercut or surpass the built\-in limits. These are "1x",
"52xCD", "24xDVD", "20xBD".
.TP
\fB\-list_profiles\fR "in"|"out"|"all"
Put out a list of media types supported by \-indev, \-outdev, or both,
respectively.
The currently recognized type is marked by text "(current)".
.TP
\fB\-truncate_overwritable\fR entity id adjust
On overwritable medium copy the volume descriptors of an existing session to
the overall descriptors at LBA 0 ff. This makes all sessions
\fBinaccessible\fR which are younger than the activated one.
A reason to do this would be read errors in the younger sessions and
the wish to re\-write or skip them.
.br
This operation is only allowed if no changes to the loaded filesystem are
pending. If an \-indev is acquired then it is released before the write
operation begins and re\-acquired only in case of success.
.br
The parameters "entity" and "id" have the same meaning as with command \-load.
They choose the existing ISO session which shall become the youngest accessible
session. Available entity names are "session", "track", "lba", "sbsector",
"volid". "auto" makes few sense. id is a number or search text as appropriate
for the given entity.
.br
Parameter "adjust" controls the claimed size of the activated session. Text
"new" means the size of the newly activated session as it was before this
command. I.e. the space of the then inaccessible younger sessions will be
re\-used when appending more sessions.
.br
"old" means the size up to the end of the previously youngest session.
I.e. "old" will not free the space of the then inaccessible younger sessions
for re\-use.
.br
A number preceded by "+" gives the number of bytes to be added to "new".
A number without "+" gives the overall number of bytes. In any case the result
may not be smaller than "new". Numbers may have a unit suffix: "d"=512,
"k"=1024, "s"=2048, "m"=1024k, "g"=1024m.
.br
Examples:
.br
Activate session 4 and enable overwriting of the blocks of younger sessions:
.br
\-truncate_overwritable session 4 new
.br
Activate session 4 and claim the blocks of younger sessions as useless part of
session 4:
.br
\-truncate_overwritable session 4 old
.br
Let session 4 claim additional 500 MiB as useless data:
.br
\-truncate_overwritable session 4 +500m
.TP
\fB\-close_damaged\fR "as_needed"|"force"
Try to close the upcoming track and session if the drive reported the medium
as damaged. This may apply to CD\-R, CD\-RW, DVD\-R, DVD\-RW, DVD+R, DVD+R DL,
@ -2668,11 +2719,6 @@ appear undamaged.
No image changes are allowed to be pending before this command is performed.
After closing was attempted, both drives are given up.
.TP
\fB\-list_profiles\fR "in"|"out"|"all"
Put out a list of media types supported by \-indev, \-outdev, or both,
respectively.
The currently recognized type is marked by text "(current)".
.TP
.B Settings for result writing:
.PP
Rock Ridge info will be generated by default.
@ -6268,7 +6314,7 @@ Thomas Schmitt <scdbackup@gmx.net>
.br
for libburnia\-project.org
.SH COPYRIGHT
Copyright (c) 2007 \- 2019 Thomas Schmitt
Copyright (c) 2007 \- 2020 Thomas Schmitt
.br
Permission is granted to distribute this text freely. It shall only be
modified in sync with the technical properties of \fBxorriso\fR.

View File

@ -2,7 +2,7 @@
/* xorriso - libisoburn higher level API which creates, loads, manipulates
and burns ISO 9660 filesystem images.
Copyright 2007-2019 Thomas Schmitt, <scdbackup@gmx.net>
Copyright 2007-2020 Thomas Schmitt, <scdbackup@gmx.net>
Provided under GPL version 2 or later.
@ -2126,6 +2126,12 @@ int Xorriso_option_toc(struct XorrisO *xorriso, int flag);
/* @since 1.2.6 */
int Xorriso_option_toc_of(struct XorrisO *xorriso, char *which, int flag);
/* Command -truncate_overwritable */
/* @since 1.5.4 */
int Xorriso_option_truncate_overwritable(struct XorrisO *xorriso,
char *adr_mode, char *adr_value,
char *adjust, int flag);
/* Command -uid */
/* @since 0.1.0 */
int Xorriso_option_uid(struct XorrisO *xorriso, char *uid, int flag);

View File

@ -4,7 +4,7 @@ xorriso.texi.
xorriso - creates, loads, manipulates and writes ISO 9660 filesystem
images with Rock Ridge extensions.
Copyright (C) 2007 - 2019 Thomas Schmitt
Copyright (C) 2007 - 2020 Thomas Schmitt
Permission is granted to distribute this text freely.
INFO-DIR-SECTION Archiving
@ -2259,6 +2259,48 @@ File: xorriso.info, Node: Writing, Next: SetWrite, Prev: Filter, Up: Command
speeds, as reported by the drive. They would be chosen by
-read_speed "min" or "max" if they undercut or surpass the built-in
limits. These are "1x", "52xCD", "24xDVD", "20xBD".
-list_profiles "in"|"out"|"all"
Put out a list of media types supported by -indev, -outdev, or
both, respectively. The currently recognized type is marked by
text "(current)".
-truncate_overwritable entity id adjust
On overwritable medium copy the volume descriptors of an existing
session to the overall descriptors at LBA 0 ff. This makes all
sessions *inaccessible* which are younger than the activated one.
A reason to do this would be read errors in the younger sessions
and the wish to re-write or skip them.
This operation is only allowed if no changes to the loaded
filesystem are pending. If an -indev is acquired then it is
released before the write operation begins and re-acquired only in
case of success.
The parameters "entity" and "id" have the same meaning as with
command -load. They choose the existing ISO session which shall
become the youngest accessible session. Available entity names are
"session", "track", "lba", "sbsector", "volid". "auto" makes few
sense. id is a number or search text as appropriate for the given
entity.
Parameter "adjust" controls the claimed size of the activated
session. Text "new" means the size of the newly activated session
as it was before this command. I.e. the space of the then
inaccessible younger sessions will be re-used when appending more
sessions.
"old" means the size up to the end of the previously youngest
session. I.e. "old" will not free the space of the then
inaccessible younger sessions for re-use.
A number preceded by "+" gives the number of bytes to be added to
"new". A number without "+" gives the overall number of bytes. In
any case the result may not be smaller than "new". Numbers may
have a unit suffix: "d"=512, "k"=1024, "s"=2048, "m"=1024k,
"g"=1024m.
Examples:
Activate session 4 and enable overwriting of the blocks of younger
sessions:
-truncate_overwritable session 4 new
Activate session 4 and claim the blocks of younger sessions as
useless part of session 4:
-truncate_overwritable session 4 old
Let session 4 claim additional 500 MiB as useless data:
-truncate_overwritable session 4 +500m
-close_damaged "as_needed"|"force"
Try to close the upcoming track and session if the drive reported
the medium as damaged. This may apply to CD-R, CD-RW, DVD-R,
@ -2272,10 +2314,6 @@ File: xorriso.info, Node: Writing, Next: SetWrite, Prev: Filter, Up: Command
media which appear undamaged.
No image changes are allowed to be pending before this command is
performed. After closing was attempted, both drives are given up.
-list_profiles "in"|"out"|"all"
Put out a list of media types supported by -indev, -outdev, or
both, respectively. The currently recognized type is marked by
text "(current)".

File: xorriso.info, Node: SetWrite, Next: Bootable, Prev: Writing, Up: Commands
@ -5307,7 +5345,7 @@ for libburnia-project.org
15.2 Copyright
==============
Copyright (c) 2007 - 2019 Thomas Schmitt
Copyright (c) 2007 - 2020 Thomas Schmitt
Permission is granted to distribute this text freely. It shall only be
modified in sync with the technical properties of 'xorriso'. If you
make use of the license to derive modified versions of 'xorriso' then
@ -5370,7 +5408,7 @@ File: xorriso.info, Node: CommandIdx, Next: ConceptIdx, Prev: Legal, Up: Top
* -chown_r sets ownership in ISO image: Manip. (line 47)
* -clone copies ISO directory tree: Insert. (line 185)
* -close controls media closing: SetWrite. (line 407)
* -close_damaged closes damaged track and session: Writing. (line 163)
* -close_damaged closes damaged track and session: Writing. (line 205)
* -close_filter_list bans filter registration: Filter. (line 50)
* -commit writes pending ISO image: Writing. (line 27)
* -commit_eject writes and ejects: Writing. (line 53)
@ -5448,7 +5486,7 @@ File: xorriso.info, Node: CommandIdx, Next: ConceptIdx, Prev: Legal, Up: Top
* -list_delimiter replaces '--': Scripting. (line 55)
* -list_extras lists compile time extra features: Scripting. (line 24)
* -list_formats lists available formats: Writing. (line 128)
* -list_profiles lists supported media: Writing. (line 176)
* -list_profiles lists supported media: Writing. (line 163)
* -list_speeds lists available write speeds: Writing. (line 139)
* -lns creates ISO symbolic link: Insert. (line 181)
* -load addresses a particular session as input: Loading. (line 33)
@ -5556,6 +5594,7 @@ File: xorriso.info, Node: CommandIdx, Next: ConceptIdx, Prev: Legal, Up: Top
* -temp_mem_limit curbs memory consumption: Scripting. (line 96)
* -toc shows list of sessions: Inquiry. (line 27)
* -toc_of shows list of sessions: Inquiry. (line 41)
* -truncate_overwritable activates older session: Writing. (line 167)
* -uid sets global ownership: SetWrite. (line 290)
* -update inserts path if different: Insert. (line 100)
* -update_l inserts paths if different: Insert. (line 120)
@ -5619,7 +5658,7 @@ File: xorriso.info, Node: ConceptIdx, Prev: CommandIdx, Up: Top
* Create, new ISO image, _definition: Methods. (line 7)
* Cylinder alignment, _definition: Bootable. (line 338)
* Cylinder size, _definition: Bootable. (line 323)
* Damaged track and session, close, -close_damaged: Writing. (line 163)
* Damaged track and session, close, -close_damaged: Writing. (line 205)
* DEC Alpha SRM boot sector, production: Bootable. (line 398)
* Delete, from ISO image, -rm: Manip. (line 20)
* Delete, from ISO image, -rm_r: Manip. (line 26)
@ -5645,7 +5684,7 @@ File: xorriso.info, Node: ConceptIdx, Prev: CommandIdx, Up: Top
* Drive, for output, -outdev: AqDrive. (line 29)
* Drive, get drive list, -devices: Inquiry. (line 7)
* Drive, get drive list, -device_links: Inquiry. (line 17)
* Drive, list supported media, -list_profiles: Writing. (line 176)
* Drive, list supported media, -list_profiles: Writing. (line 163)
* Drive, reduce activity, -calm_drive: Loading. (line 306)
* Drive, report SCSI commands, -scsi_log: Scripting. (line 143)
* Drive, write and eject, -commit_eject: Writing. (line 53)
@ -5772,6 +5811,7 @@ File: xorriso.info, Node: ConceptIdx, Prev: CommandIdx, Up: Top
* Navigate, tell disk working directory, -pwdx: Navigate. (line 21)
* Navigate, tell ISO working directory, -pwd: Navigate. (line 19)
* Next writeable address, -grow_blindly: AqDrive. (line 112)
* Older session, activate, -truncate_overwritable: Writing. (line 167)
* Output Character Set, _definition: Charset. (line 26)
* Overwritable media, _definition: Media. (line 14)
* Ownership, global in ISO image, -uid: SetWrite. (line 290)
@ -5913,42 +5953,42 @@ Node: Manip76969
Node: CmdFind87069
Node: Filter105998
Node: Writing110620
Node: SetWrite120767
Node: Bootable145844
Node: Jigdo172799
Node: Charset177802
Node: Exception181131
Node: DialogCtl187260
Node: Inquiry189862
Node: Navigate198744
Node: Verify207201
Node: Restore217672
Node: Emulation226838
Node: Scripting237294
Node: Frontend245077
Node: Examples254703
Node: ExDevices255881
Node: ExCreate256542
Node: ExDialog257842
Node: ExGrowing259113
Node: ExModifying259922
Node: ExBootable260432
Node: ExCharset260987
Node: ExPseudo261883
Node: ExCdrecord262810
Node: ExMkisofs263130
Node: ExGrowisofs265027
Node: ExException266180
Node: ExTime266638
Node: ExIncBackup267096
Node: ExRestore271122
Node: ExRecovery272068
Node: Files272640
Node: Environ273974
Node: Seealso274722
Node: Bugreport275439
Node: Legal276030
Node: CommandIdx277042
Node: ConceptIdx294585
Node: SetWrite122875
Node: Bootable147952
Node: Jigdo174907
Node: Charset179910
Node: Exception183239
Node: DialogCtl189368
Node: Inquiry191970
Node: Navigate200852
Node: Verify209309
Node: Restore219780
Node: Emulation228946
Node: Scripting239402
Node: Frontend247185
Node: Examples256811
Node: ExDevices257989
Node: ExCreate258650
Node: ExDialog259950
Node: ExGrowing261221
Node: ExModifying262030
Node: ExBootable262540
Node: ExCharset263095
Node: ExPseudo263991
Node: ExCdrecord264918
Node: ExMkisofs265238
Node: ExGrowisofs267135
Node: ExException268288
Node: ExTime268746
Node: ExIncBackup269204
Node: ExRestore273230
Node: ExRecovery274176
Node: Files274748
Node: Environ276082
Node: Seealso276830
Node: Bugreport277547
Node: Legal278138
Node: CommandIdx279150
Node: ConceptIdx296766

End Tag Table

View File

@ -69,7 +69,7 @@
xorriso - creates, loads, manipulates and writes ISO 9660 filesystem images
with Rock Ridge extensions.
Copyright @copyright{} 2007 - 2019 Thomas Schmitt
Copyright @copyright{} 2007 - 2020 Thomas Schmitt
@quotation
Permission is granted to distribute this text freely.
@ -3111,6 +3111,61 @@ as reported by the drive. They would be chosen by -read_speed "min" or
"max" if they undercut or surpass the built-in limits. These are "1x",
"52xCD", "24xDVD", "20xBD".
@c man .TP
@item -list_profiles "in"|"out"|"all"
@kindex -list_profiles lists supported media
@cindex Drive, list supported media, -list_profiles
Put out a list of media types supported by -indev, -outdev, or both,
respectively.
The currently recognized type is marked by text "(current)".
@c man .TP
@item -truncate_overwritable entity id adjust
@kindex -truncate_overwritable activates older session
@cindex Older session, activate, -truncate_overwritable
On overwritable medium copy the volume descriptors of an existing session to
the overall descriptors at LBA 0 ff. This makes all sessions
@strong{inaccessible} which are younger than the activated one.
A reason to do this would be read errors in the younger sessions and
the wish to re-write or skip them.
@*
This operation is only allowed if no changes to the loaded filesystem are
pending. If an -indev is acquired then it is released before the write
operation begins and re-acquired only in case of success.
@*
The parameters "entity" and "id" have the same meaning as with command -load.
They choose the existing ISO session which shall become the youngest accessible
session. Available entity names are "session", "track", "lba", "sbsector",
"volid". "auto" makes few sense. id is a number or search text as appropriate
for the given entity.
@*
Parameter "adjust" controls the claimed size of the activated session. Text
"new" means the size of the newly activated session as it was before this
command. I.e. the space of the then inaccessible younger sessions will be
re-used when appending more sessions.
@*
"old" means the size up to the end of the previously youngest session.
I.e. "old" will not free the space of the then inaccessible younger sessions
for re-use.
@*
A number preceded by "+" gives the number of bytes to be added to "new".
A number without "+" gives the overall number of bytes. In any case the result
may not be smaller than "new". Numbers may have a unit suffix: "d"=512,
"k"=1024, "s"=2048, "m"=1024k, "g"=1024m.
@*
Examples:
@*
Activate session 4 and enable overwriting of the blocks of younger sessions:
@*
-truncate_overwritable session 4 new
@*
Activate session 4 and claim the blocks of younger sessions as useless part of
session 4:
@*
-truncate_overwritable session 4 old
@*
Let session 4 claim additional 500 MiB as useless data:
@*
-truncate_overwritable session 4 +500m
@c man .TP
@item -close_damaged "as_needed"|"force"
@kindex -close_damaged closes damaged track and session
@cindex Damaged track and session, close, -close_damaged
@ -3128,13 +3183,6 @@ appear undamaged.
@*
No image changes are allowed to be pending before this command is performed.
After closing was attempted, both drives are given up.
@c man .TP
@item -list_profiles "in"|"out"|"all"
@kindex -list_profiles lists supported media
@cindex Drive, list supported media, -list_profiles
Put out a list of media types supported by -indev, -outdev, or both,
respectively.
The currently recognized type is marked by text "(current)".
@end table
@c man .TP
@c man .B Settings for result writing:
@ -7327,7 +7375,7 @@ Thomas Schmitt <scdbackup@@gmx.net>
for libburnia-project.org
@c man .SH COPYRIGHT
@section Copyright
Copyright (c) 2007 - 2019 Thomas Schmitt
Copyright (c) 2007 - 2020 Thomas Schmitt
@*
Permission is granted to distribute this text freely. It shall only be
modified in sync with the technical properties of @command{xorriso}.

View File

@ -1 +1 @@
#define Xorriso_timestamP "2020.08.06.101015"
#define Xorriso_timestamP "2020.08.06.153930"

View File

@ -4,7 +4,7 @@
a command line oriented batch and dialog tool which creates, loads,
manipulates and burns ISO 9660 filesystem images.
Copyright 2007-2019 Thomas Schmitt, <scdbackup@gmx.net>
Copyright 2007-2020 Thomas Schmitt, <scdbackup@gmx.net>
Provided under GPL version 2 or later.
@ -338,6 +338,9 @@ int Xorriso_update_iso_lba0(struct XorrisO *xorriso, int iso_lba, int isosize,
char *head_buffer, struct CheckmediajoB *job,
int flag);
int Xorriso_truncate_overwritable(struct XorrisO *xorriso, char *adr_mode,
char *adr_value, char *adjust, int flag);
int Xorriso_get_local_charset(struct XorrisO *xorriso, char **name, int flag);
int Xorriso_set_local_charset(struct XorrisO *xorriso, char *name, int flag);