Discarding, keeping or patching boot images from existing ISO images

This commit is contained in:
Thomas Schmitt 2008-02-11 09:48:29 +00:00
parent a0ed94f55b
commit 74e691e355
6 changed files with 174 additions and 25 deletions

View File

@ -951,6 +951,26 @@ xorriso adds the traditional 300k of padding by default to all images.
.br .br
For images which will never get to a CD it is safe to use -padding 0 . For images which will never get to a CD it is safe to use -padding 0 .
.TP .TP
\fB\-boot_image\fR "any"|"isolinux" "discard"|"keep"|"patch"
Defines the handling of an eventual boot image (El-Torito) which has been read
from an existing ISO image. All types ("any") can be discarded or kept
unaltered. The latter makes only sense if the format of the boot image is
relocatable without content changes.
.br
The boot image type "isolinux" can be kept unaltered (not advisable), or
discarded, or it can be patched to match its relocation. In the latter case
the resulting ISO image is bootable if the boot image was really complying
to the isolinux standard.
.br
Creation of new boot images is not yet possible.
.br
CAUTION:
This is an expert option. xorriso is not an expert yet.
It cannot recognize the inner form of boot images.
So the user has already to know about the particular needs of the
bootimage which is present on the input media.
Most safe is the default: "any" "discard".
.TP
.B Exception processing: .B Exception processing:
.TP .TP
\fB\-abort_on\fR severity \fB\-abort_on\fR severity

View File

@ -2707,6 +2707,8 @@ int Xorriso_new(struct XorrisO ** xorriso,char *progname, int flag)
m->speed= 0; m->speed= 0;
m->fs= 4*512; /* 4 MiB */ m->fs= 4*512; /* 4 MiB */
m->padding= 300*1024; m->padding= 300*1024;
m->keep_boot_image= 0;
m->patch_isolinux_image= 0;
m->allow_graft_points= 0; m->allow_graft_points= 0;
m->dialog= 0; m->dialog= 0;
m->search_mode= 0; m->search_mode= 0;
@ -3756,7 +3758,7 @@ int Xorriso_status(struct XorrisO *xorriso, char *filter, FILE *fp, int flag)
*/ */
{ {
int is_default,no_defaults,i; int is_default,no_defaults,i;
char *line, sfe[5*SfileadrL], mode[80]; char *line, sfe[5*SfileadrL], mode[80], *form, *treatment;
static char channel_prefixes[4][4]= {".","R","I","M"}; static char channel_prefixes[4][4]= {".","R","I","M"};
no_defaults= flag&1; no_defaults= flag&1;
@ -3824,6 +3826,19 @@ int Xorriso_status(struct XorrisO *xorriso, char *filter, FILE *fp, int flag)
Xorriso_status_result(xorriso,filter,fp,flag&2); Xorriso_status_result(xorriso,filter,fp,flag&2);
} }
is_default= (xorriso->keep_boot_image==0 && xorriso->patch_isolinux_image==0);
form= "any";
treatment= "discard";
if(xorriso->patch_isolinux_image) {
form= "isolinux";
treatment= "patch";
} else if(xorriso->keep_boot_image) {
treatment= "keep";
}
sprintf(line,"-boot_image %s %s\n", form, treatment);
if(!(is_default && no_defaults))
Xorriso_status_result(xorriso,filter,fp,flag&2);
sprintf(line,"-cd %s\n", sprintf(line,"-cd %s\n",
(xorriso->wdi[0] ? Text_shellsafe(xorriso->wdi,sfe,0) : "'/'")); (xorriso->wdi[0] ? Text_shellsafe(xorriso->wdi,sfe,0) : "'/'"));
Xorriso_status_result(xorriso,filter,fp,flag&2); Xorriso_status_result(xorriso,filter,fp,flag&2);
@ -6101,6 +6116,52 @@ int Xorriso_option_blank(struct XorrisO *xorriso, char *mode, int flag)
} }
/* Option -boot_image */
int Xorriso_option_boot_image(struct XorrisO *xorriso, char *form,
char *treatment, int flag)
{
int was_ok= 1;
char *formpt, *treatpt;
formpt= form;
if(formpt[0]=='-')
formpt++;
treatpt= treatment;
if(treatpt[0]=='-')
treatpt++;
if(strcmp(formpt, "any")==0) {
if(strcmp(treatpt, "keep")==0) {
xorriso->keep_boot_image= 1;
xorriso->patch_isolinux_image= 0;
} else if(strcmp(treatpt, "discard")==0) {
xorriso->keep_boot_image= 0;
xorriso->patch_isolinux_image= 0;
} else
was_ok= 0;
} else if(strcmp(formpt, "isolinux")==0) {
if(strcmp(treatpt, "patch")==0) {
xorriso->keep_boot_image= 1;
xorriso->patch_isolinux_image= 1;
} else if(strcmp(treatpt, "keep")==0) {
xorriso->keep_boot_image= 1;
xorriso->patch_isolinux_image= 0;
} else if(strcmp(treatpt, "discard")==0) {
xorriso->keep_boot_image= 0;
xorriso->patch_isolinux_image= 0;
} else
was_ok= 0;
} else
was_ok= 0;
if(!was_ok) {
sprintf(xorriso->info_text, "Unrecognized options with -boot_image: %s %s",
form, treatment);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
return(0);
}
return(1);
}
/* Option -cd alias -cdi */ /* Option -cd alias -cdi */
int Xorriso_option_cdi(struct XorrisO *xorriso, char *iso_rr_path, int flag) int Xorriso_option_cdi(struct XorrisO *xorriso, char *iso_rr_path, int flag)
{ {
@ -8408,6 +8469,10 @@ next_command:;
(*idx)++; (*idx)++;
ret= Xorriso_option_blank(xorriso, arg1, 0); ret= Xorriso_option_blank(xorriso, arg1, 0);
} else if(strcmp(cmd,"boot_image")==0) {
(*idx)+= 2;
ret= Xorriso_option_boot_image(xorriso, arg1, arg2, 0);
} else if(strcmp(cmd,"cd")==0 || strcmp(cmd,"cdi")==0) { } else if(strcmp(cmd,"cd")==0 || strcmp(cmd,"cdi")==0) {
(*idx)++; (*idx)++;
ret= Xorriso_option_cdi(xorriso, arg1, 0); ret= Xorriso_option_cdi(xorriso, arg1, 0);

View File

@ -176,6 +176,10 @@ int Xorriso_option_ban_stdio_write(struct XorrisO *xorriso, int flag);
*/ */
int Xorriso_option_blank(struct XorrisO *xorriso, char *mode, int flag); int Xorriso_option_blank(struct XorrisO *xorriso, char *mode, int flag);
/* Option -boot_image */
int Xorriso_option_boot_image(struct XorrisO *xorriso, char *form,
char *treatment, int flag);
/* Option -cd alias -cdi */ /* Option -cd alias -cdi */
int Xorriso_option_cdi(struct XorrisO *xorriso, char *iso_rr_path, int flag); int Xorriso_option_cdi(struct XorrisO *xorriso, char *iso_rr_path, int flag);
@ -220,9 +224,11 @@ int Xorriso_option_commit_eject(struct XorrisO *xorriso, char *which, int flag);
int Xorriso_option_cpri( struct XorrisO *xorriso, int argc, char **argv, int Xorriso_option_cpri( struct XorrisO *xorriso, int argc, char **argv,
int *idx, int flag); int *idx, int flag);
/* Option -cut_out */ /* >>> not yet implemented
int Xorriso_option_cut_out(struct XorrisO *xorriso, char *disk_path, / * Option -cut_out * /
int Xorriso_option_cut_out(struct XorrisO *xorriso, char *disk_path,
off_t startbyte, off_t bytecount, char *iso_rr_path, int flag); off_t startbyte, off_t bytecount, char *iso_rr_path, int flag);
*/
/* Options -dev , -indev, -outdev */ /* Options -dev , -indev, -outdev */
/* @param flag bit0=use as indev , bit1= use as outdev /* @param flag bit0=use as indev , bit1= use as outdev

View File

@ -109,6 +109,9 @@ struct XorrisO { /* the global context of xorriso */
int fs; /* fifo size in 2048 byte chunks : at most 1 GB */ int fs; /* fifo size in 2048 byte chunks : at most 1 GB */
int padding; /* number of bytes to add after ISO 9660 image */ int padding; /* number of bytes to add after ISO 9660 image */
int keep_boot_image;
int patch_isolinux_image;
/* XORRISO options */ /* XORRISO options */
int allow_graft_points; int allow_graft_points;

View File

@ -1 +1 @@
#define Xorriso_timestamP "2008.02.10.135822" #define Xorriso_timestamP "2008.02.11.094742"

View File

@ -407,13 +407,14 @@ int Xorriso_create_empty_iso(struct XorrisO *xorriso, int flag)
*/ */
int Xorriso_aquire_drive(struct XorrisO *xorriso, char *adr, int flag) int Xorriso_aquire_drive(struct XorrisO *xorriso, char *adr, int flag)
{ {
int ret, hret, not_writeable= 0; int ret, hret, not_writeable= 0, has_what;
uint32_t size;
struct burn_drive_info *dinfo= NULL, *out_dinfo, *in_dinfo; struct burn_drive_info *dinfo= NULL, *out_dinfo, *in_dinfo;
struct burn_drive *drive, *out_drive, *in_drive; struct burn_drive *drive, *out_drive, *in_drive;
enum burn_disc_status state; enum burn_disc_status state;
IsoImage *volset = NULL; IsoImage *volset = NULL;
struct isoburn_read_opts *ropts= NULL; struct isoburn_read_opts *ropts= NULL;
char adr_data[SfileadrL], *libburn_adr; char adr_data[SfileadrL], *libburn_adr, *boot_fate;
if((flag&3)==0) { if((flag&3)==0) {
sprintf(xorriso->info_text, sprintf(xorriso->info_text,
@ -568,6 +569,20 @@ int Xorriso_aquire_drive(struct XorrisO *xorriso, char *adr, int flag)
isoburn_attach_image(out_drive, xorriso->in_volset_handle); isoburn_attach_image(out_drive, xorriso->in_volset_handle);
} }
Xorriso_process_msg_queues(xorriso,0); Xorriso_process_msg_queues(xorriso,0);
isoburn_ropt_get_size_what(ropts, &size, &has_what);
if(has_what & isoburn_ropt_has_el_torito) {
if(xorriso->patch_isolinux_image)
boot_fate= "patched as isolinux image";
else if(xorriso->keep_boot_image)
boot_fate= "kept unchanged";
else
boot_fate= "discarded";
sprintf(xorriso->info_text,
"Detected El-Torito boot information which currently is set to be %s",
boot_fate);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
}
Xorriso_toc(xorriso, 1); Xorriso_toc(xorriso, 1);
if(xorriso->loaded_volid[0]!=0) { if(xorriso->loaded_volid[0]!=0) {
sprintf(xorriso->result_line,"Volume id : '%s'\n",xorriso->loaded_volid); sprintf(xorriso->result_line,"Volume id : '%s'\n",xorriso->loaded_volid);
@ -688,7 +703,7 @@ int Xorriso_make_write_options(
*/ */
int Xorriso_write_session(struct XorrisO *xorriso, int flag) int Xorriso_write_session(struct XorrisO *xorriso, int flag)
{ {
int ret, media_space, img_sectors, padding= 0, profile= 0; int ret, media_space, img_sectors, padding= 0, profile= 0, relax= 0;
char profile_name[80]; char profile_name[80];
struct isoburn_imgen_opts *sopts= NULL; struct isoburn_imgen_opts *sopts= NULL;
struct burn_drive_info *dinfo, *source_dinfo; struct burn_drive_info *dinfo, *source_dinfo;
@ -700,15 +715,67 @@ int Xorriso_write_session(struct XorrisO *xorriso, int flag)
struct burn_session **sessions; struct burn_session **sessions;
struct burn_track **tracks; struct burn_track **tracks;
enum burn_disc_status s; enum burn_disc_status s;
IsoImage *image = NULL;
ElToritoBootImage *bootimg;
ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive, ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive,
"on attempt to write", 2); "on attempt to write", 2);
if(ret<=0) if(ret<=0)
return(0); return(0);
if(xorriso->out_drive_handle == xorriso->in_drive_handle ||
xorriso->in_drive_handle == NULL) {
source_drive= drive;
} else {
ret= Xorriso_get_drive_handles(xorriso, &source_dinfo, &source_drive,
"on attempt to get source for write", 0);
if(ret<=0)
goto ex;
s= isoburn_disc_get_status(drive);
if(s!=BURN_DISC_BLANK) {
s= burn_disc_get_status(drive);
if(s!=BURN_DISC_BLANK)
sprintf(xorriso->info_text,
"-indev differs from -outdev and -outdev media is not blank");
else
sprintf(xorriso->info_text,
"-indev differs from -outdev and -outdev media holds valid ISO image");
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
{ret= 0; goto ex;}
}
}
ret= isoburn_igopt_new(&sopts, 0); ret= isoburn_igopt_new(&sopts, 0);
if(ret<=0) if(ret<=0)
return(ret); return(ret);
relax= isoburn_igopt_allow_deep_paths;
/* Adjust or discard boot image */
image= isoburn_get_attached_image(source_drive);
/* >>> ??? move down to libisoburn ? */
if(image!=NULL && !(flag&1)) {
ret= iso_image_get_boot_image(image, &bootimg, NULL, NULL);
if(xorriso->patch_isolinux_image) {
if(ret==1) {
relax|= isoburn_igopt_allow_full_ascii;
el_torito_patch_isolinux_image(bootimg);
sprintf(xorriso->info_text, "Patched alleged isolinux boot image");
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
} else {
sprintf(xorriso->info_text,
"Could not find any boot image for -patch_isolinux_image");
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 0);
}
} else if(xorriso->keep_boot_image) {
sprintf(xorriso->info_text, "Keeping boot image unchanged");
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
} else if(ret==1) {
iso_image_remove_boot_image(image);
sprintf(xorriso->info_text, "Discarded boot image from old session");
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
}
}
isoburn_igopt_set_level(sopts, 2); isoburn_igopt_set_level(sopts, 2);
isoburn_igopt_set_extensions(sopts, 1|((!!xorriso->do_joliet)<<1)); isoburn_igopt_set_extensions(sopts, 1|((!!xorriso->do_joliet)<<1));
isoburn_igopt_set_relaxed(sopts, isoburn_igopt_allow_deep_paths); isoburn_igopt_set_relaxed(sopts, isoburn_igopt_allow_deep_paths);
@ -747,25 +814,8 @@ int Xorriso_write_session(struct XorrisO *xorriso, int flag)
if(xorriso->out_drive_handle == xorriso->in_drive_handle || if(xorriso->out_drive_handle == xorriso->in_drive_handle ||
xorriso->in_drive_handle == NULL) { xorriso->in_drive_handle == NULL) {
source_drive= drive;
ret= isoburn_prepare_disc(source_drive, &disc, sopts); ret= isoburn_prepare_disc(source_drive, &disc, sopts);
} else { } else {
s= isoburn_disc_get_status(drive);
if(s!=BURN_DISC_BLANK) {
s= burn_disc_get_status(drive);
if(s!=BURN_DISC_BLANK)
sprintf(xorriso->info_text,
"-indev differs from -outdev and -outdev media is not blank");
else
sprintf(xorriso->info_text,
"-indev differs from -outdev and -outdev media holds valid ISO image");
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
{ret= 0; goto ex;}
}
ret= Xorriso_get_drive_handles(xorriso, &source_dinfo, &source_drive,
"on attempt to get source for write", 0);
if(ret<=0)
goto ex;
ret= isoburn_prepare_new_image(source_drive, &disc, sopts, drive); ret= isoburn_prepare_new_image(source_drive, &disc, sopts, drive);
} }
if (ret <= 0) { if (ret <= 0) {
@ -870,6 +920,11 @@ no_track:;
Xorriso_info(xorriso, 0); Xorriso_info(xorriso, 0);
ret= 1; ret= 1;
ex:; ex:;
if(ret<=0) {
/* >>> ??? revive discarded boot image */;
}
if(disc!=NULL) if(disc!=NULL)
burn_disc_free(disc); burn_disc_free(disc);
isoburn_igopt_destroy(&sopts, 0); isoburn_igopt_destroy(&sopts, 0);