diff --git a/xorriso/xorriso.1 b/xorriso/xorriso.1 index 7958e34c..90532097 100644 --- a/xorriso/xorriso.1 +++ b/xorriso/xorriso.1 @@ -951,6 +951,26 @@ xorriso adds the traditional 300k of padding by default to all images. .br For images which will never get to a CD it is safe to use -padding 0 . .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: .TP \fB\-abort_on\fR severity diff --git a/xorriso/xorriso.c b/xorriso/xorriso.c index 04c4aa1c..22f42422 100644 --- a/xorriso/xorriso.c +++ b/xorriso/xorriso.c @@ -2707,6 +2707,8 @@ int Xorriso_new(struct XorrisO ** xorriso,char *progname, int flag) m->speed= 0; m->fs= 4*512; /* 4 MiB */ m->padding= 300*1024; + m->keep_boot_image= 0; + m->patch_isolinux_image= 0; m->allow_graft_points= 0; m->dialog= 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; - 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"}; 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); } + 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", (xorriso->wdi[0] ? Text_shellsafe(xorriso->wdi,sfe,0) : "'/'")); 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 */ int Xorriso_option_cdi(struct XorrisO *xorriso, char *iso_rr_path, int flag) { @@ -8408,6 +8469,10 @@ next_command:; (*idx)++; 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) { (*idx)++; ret= Xorriso_option_cdi(xorriso, arg1, 0); diff --git a/xorriso/xorriso.h b/xorriso/xorriso.h index 1b599867..8561b41e 100644 --- a/xorriso/xorriso.h +++ b/xorriso/xorriso.h @@ -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); +/* Option -boot_image */ +int Xorriso_option_boot_image(struct XorrisO *xorriso, char *form, + char *treatment, int flag); + /* Option -cd alias -cdi */ 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 *idx, int flag); -/* 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); +/* >>> not yet implemented + / * 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); +*/ /* Options -dev , -indev, -outdev */ /* @param flag bit0=use as indev , bit1= use as outdev diff --git a/xorriso/xorriso_private.h b/xorriso/xorriso_private.h index 64532376..32eca57b 100644 --- a/xorriso/xorriso_private.h +++ b/xorriso/xorriso_private.h @@ -109,6 +109,9 @@ struct XorrisO { /* the global context of xorriso */ int fs; /* fifo size in 2048 byte chunks : at most 1 GB */ int padding; /* number of bytes to add after ISO 9660 image */ + int keep_boot_image; + int patch_isolinux_image; + /* XORRISO options */ int allow_graft_points; diff --git a/xorriso/xorriso_timestamp.h b/xorriso/xorriso_timestamp.h index 861255f7..4a5d0905 100644 --- a/xorriso/xorriso_timestamp.h +++ b/xorriso/xorriso_timestamp.h @@ -1 +1 @@ -#define Xorriso_timestamP "2008.02.10.135822" +#define Xorriso_timestamP "2008.02.11.094742" diff --git a/xorriso/xorrisoburn.c b/xorriso/xorrisoburn.c index 6114055c..cc4798cf 100644 --- a/xorriso/xorrisoburn.c +++ b/xorriso/xorrisoburn.c @@ -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 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 *drive, *out_drive, *in_drive; enum burn_disc_status state; IsoImage *volset = 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) { 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); } 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); if(xorriso->loaded_volid[0]!=0) { 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 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]; struct isoburn_imgen_opts *sopts= NULL; 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_track **tracks; enum burn_disc_status s; + IsoImage *image = NULL; + ElToritoBootImage *bootimg; ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive, "on attempt to write", 2); if(ret<=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); if(ret<=0) 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_extensions(sopts, 1|((!!xorriso->do_joliet)<<1)); 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 || xorriso->in_drive_handle == NULL) { - source_drive= drive; ret= isoburn_prepare_disc(source_drive, &disc, sopts); } 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); } if (ret <= 0) { @@ -870,6 +920,11 @@ no_track:; Xorriso_info(xorriso, 0); ret= 1; ex:; + + if(ret<=0) { + /* >>> ??? revive discarded boot image */; + } + if(disc!=NULL) burn_disc_free(disc); isoburn_igopt_destroy(&sopts, 0);