diff --git a/libisoburn/libisoburn.ver b/libisoburn/libisoburn.ver index 77e8a399..d86f9358 100644 --- a/libisoburn/libisoburn.ver +++ b/libisoburn/libisoburn.ver @@ -221,6 +221,7 @@ Xorriso_option_errfile_log; Xorriso_option_error_behavior; Xorriso_option_external_filter; Xorriso_option_extract; +Xorriso_option_extract_boot_images; Xorriso_option_extract_cut; Xorriso_option_file_name_limit; Xorriso_option_file_size_limit; diff --git a/xorriso/check_media.c b/xorriso/check_media.c index deaeb797..6e770de3 100644 --- a/xorriso/check_media.c +++ b/xorriso/check_media.c @@ -1,7 +1,7 @@ /* xorriso - creates, loads, manipulates and burns ISO 9660 filesystem images. - Copyright 2007-2015 Thomas Schmitt, + Copyright 2007-2020 Thomas Schmitt, Provided under GPL version 2 or later. @@ -587,6 +587,7 @@ int Checkmediajob_new(struct CheckmediajoB **o, int flag) m->data_to_fd= -1; m->data_to_offset= 0; m->data_to_limit= -1; + m->data_to_skip= 0; m->patch_lba0= 0; m->patch_lba0_msc1= -1; m->sector_map_path[0]= 0; @@ -604,7 +605,7 @@ int Checkmediajob_destroy(struct CheckmediajoB **o, int flag) { if((*o) == NULL) return(0); - if((*o)->data_to_fd != -1 && strcmp((*o)->data_to_path, "-") == 0) + if((*o)->data_to_fd != -1 && strcmp((*o)->data_to_path, "-") != 0) close((*o)->data_to_fd); Sectorbitmap_destroy(&((*o)->sector_map), 0); free((char *) *o); @@ -628,6 +629,7 @@ int Checkmediajob_copy(struct CheckmediajoB *from, struct CheckmediajoB *to, /* not copied: data_to_fd */ to->data_to_offset= from->data_to_offset; to->data_to_limit= from->data_to_limit; + to->data_to_skip= from->data_to_skip; to->patch_lba0= from->patch_lba0; to->patch_lba0_msc1= from->patch_lba0_msc1; strcpy(to->sector_map_path, from->sector_map_path); @@ -1086,7 +1088,8 @@ int Xorriso_open_job_data_to(struct XorrisO *xorriso, job->data_to_fd= 1; } else { job->data_to_fd= open(job->data_to_path, O_RDWR | O_CREAT | O_BINARY, - S_IRUSR | S_IWUSR); + S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | + S_IROTH | S_IWOTH); } if(job->data_to_fd == -1) { sprintf(xorriso->info_text, "Cannot open path "); diff --git a/xorriso/check_media.h b/xorriso/check_media.h index e9179a4a..2a8b74ce 100644 --- a/xorriso/check_media.h +++ b/xorriso/check_media.h @@ -1,7 +1,7 @@ /* xorriso - creates, loads, manipulates and burns ISO 9660 filesystem images. - Copyright 2007-2011 Thomas Schmitt, + Copyright 2007-2020 Thomas Schmitt, Provided under GPL version 2 or later. @@ -118,6 +118,7 @@ struct CheckmediajoB { int data_to_fd; off_t data_to_offset; /* usually 0 with image copy, negative with file copy */ off_t data_to_limit; /* used with file copy */ + int data_to_skip; /* number of bytes to skip on writing. < 2048 */ int patch_lba0; int patch_lba0_msc1; diff --git a/xorriso/drive_mgt.c b/xorriso/drive_mgt.c index 8d180ce1..12a7af44 100644 --- a/xorriso/drive_mgt.c +++ b/xorriso/drive_mgt.c @@ -2792,7 +2792,7 @@ int Xorriso_check_interval(struct XorrisO *xorriso, struct SpotlisT *spotlist, { int i, j, ret, total_count= 0, sectors= -1, sector_size= -1, skip_reading; int prev_quality= -1, quality= -1, retry= 0, profile_no, is_cd= 0; - int eccb_size= 16, us_corr = 0; + int eccb_size= 16, us_corr = 0, data_skip; int start_sec, end_sec, first_value, fret, suspect_tao_end= 0; char profile_name[80]; int start_lba= 0; @@ -2800,7 +2800,7 @@ int Xorriso_check_interval(struct XorrisO *xorriso, struct SpotlisT *spotlist, struct burn_drive_info *dinfo; char *data= NULL, *data_pt; off_t data_count, to_read, read_count= 0, write_amount, skipped_to_read; - off_t slowdown_count= 0; + off_t slowdown_count= 0, seek_adr; struct timeval prev_time; double pre_read_time, post_read_time, time_diff, total_time_diff= 0; double last_abort_file_time= 0; @@ -2823,6 +2823,7 @@ int Xorriso_check_interval(struct XorrisO *xorriso, struct SpotlisT *spotlist, else if(read_chunk < 1) read_chunk= 1; + data_skip= job->data_to_skip; num_chunks= job->async_chunks; if(((off_t) num_chunks) * ((off_t) read_chunk) > chunks_limit) num_chunks= chunks_limit / read_chunk; @@ -2923,6 +2924,8 @@ int Xorriso_check_interval(struct XorrisO *xorriso, struct SpotlisT *spotlist, to_read= read_chunk; post_read_time= Sfile_microtime(0); for(i= 0; i < block_count; i+= to_read) { + if(i != 0) + data_skip= 0; skip_reading= 0; ret= Xorriso_check_for_abort(xorriso, job->abort_file_path, post_read_time, &last_abort_file_time, 0); @@ -3069,9 +3072,9 @@ abort_check:; } } - write_amount= data_count; + write_amount= data_count - data_skip; if(data_count > 0) { - read_count+= data_count; + read_count+= data_count - data_skip; if(job->data_to_limit >= 0 && read_count > job->data_to_limit) write_amount-= (read_count - job->data_to_limit); } @@ -3086,21 +3089,22 @@ abort_check:; } if(write_amount > 0) { if(job->data_to_fd >= 0) { - ret= 0; - if(strcmp(job->data_to_path, "-") != 0) - ret= lseek(job->data_to_fd, - ((off_t) (i + from_lba)) * (off_t) 2048 + job->data_to_offset, - SEEK_SET); - if(ret == -1) { + seek_adr= ((off_t) (i + from_lba)) * (off_t) 2048 + + job->data_to_skip + job->data_to_offset; + if(strcmp(job->data_to_path, "-") != 0) { + ret= lseek(job->data_to_fd, seek_adr, SEEK_SET); + if(ret == -1) { failed_to_write:; - sprintf(xorriso->info_text, "Cannot write %d bytes to lba %d of ", - (int) data_count, i + from_lba); - Text_shellsafe(job->data_to_path, xorriso->info_text, 1); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, - "FAILURE", 0); - {ret= 0; goto ex;} + sprintf(xorriso->info_text, + "Cannot write %d bytes to position %.f in ", + (int) data_count, (double) seek_adr); + Text_shellsafe(job->data_to_path, xorriso->info_text, 1); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, + "FAILURE", 0); + {ret= 0; goto ex;} + } } - ret= write(job->data_to_fd, data_pt, write_amount); + ret= write(job->data_to_fd, data_pt + data_skip, write_amount); if(ret == -1) goto failed_to_write; } @@ -3580,3 +3584,27 @@ int Xorriso_use_immed_bit(struct XorrisO *xorriso, int flag) } +int Xorriso_obtain_indev_readsize(struct XorrisO *xorriso, uint32_t *blocks, + int flag) +{ + int ret, num_data; + struct burn_drive_info *dinfo; + struct burn_drive *drive; + enum burn_disc_status s; + + *blocks= 0; + ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive, + "on attempt to determine readable size", 0); + if(ret <= 0) + return(0); + s= isoburn_disc_get_status(drive); + if(s == BURN_DISC_BLANK) + return(1); + ret= burn_get_read_capacity(drive, &num_data, 0); + if(ret <= 0) + return(0); + *blocks= num_data; + return(1); +} + + diff --git a/xorriso/iso_img.c b/xorriso/iso_img.c index b51ba9cd..abdce3e2 100644 --- a/xorriso/iso_img.c +++ b/xorriso/iso_img.c @@ -1,7 +1,7 @@ /* xorriso - creates, loads, manipulates and burns ISO 9660 filesystem images. - Copyright 2007-2019 Thomas Schmitt, + Copyright 2007-2020 Thomas Schmitt, Provided under GPL version 2 or later. @@ -1538,11 +1538,22 @@ int Xorriso_add_intvl_adr(struct XorrisO *xorriso, char *buf, } +int Xorriso_add_offset_size(struct XorrisO *xorriso, char *buf, + off_t byte_offset, off_t byte_size, int flag) +{ + strcat(buf, " "); + Sfile_off_t_text(buf + strlen(buf), byte_offset, 0); + strcat(buf, " "); + Sfile_off_t_text(buf + strlen(buf), byte_size, 0); + return(1); +} + + struct elto_img_par { int n, ldsiz, boot_info_table, grub2_boot_info; int do_gpt_basdat, do_gpt_hfsplus, do_apm_hfsplus; unsigned int ld_seg, hdpt, platform_id; - unsigned long int lba; + unsigned long int lba, extract_size; char pltf[8], b[8], emul[8], boot_image_type[16]; char *path, *id_string, *sel_crit; }; @@ -1644,11 +1655,14 @@ ex:; /* @param flag bit0= do not record but only count bit1= as_mkisofs + bit2= no sorry messages */ static int Xorriso_scan_report_lines(struct XorrisO *xorriso, char **et_lines, int et_line_count, char **sa_lines, int sa_line_count, - char **cmds, int *cmd_count, int flag) + char **cmds, int *cmd_count, + char **boot_imgs, int *boot_img_count, + int flag) { int ret= 0, i, num_count, mkisofs, line_count, idx, et_idx, isohybrid= 0; int ptype, gpt_idx, j, pad, mbr_idx; @@ -1664,16 +1678,17 @@ static int Xorriso_scan_report_lines(struct XorrisO *xorriso, int iso_mbr_part_type= -1, iso_gpt_part_idx= -1; unsigned int prev_pltf= 0; - unsigned long int sa_options= 0, partno, id_tag, perms, start_cyl, num_blocks; - unsigned long int part_status, part_type, start_block, partition_offset= 0; - uint32_t high_block= 0; + unsigned long int sa_options= 0, partno, id_tag, perms, start_cyl; + unsigned long int part_status, part_type, mbr_start_block, mbr_num_blocks; + unsigned long int partition_offset= 0; + uint32_t high_block= 0, indev_blocks; char name[24], *textpt, *contentpt, *buf= NULL, part_type_text[37]; char **lines= NULL; double num[8]; char *cat_path= ""; struct elto_img_par *et_imgs= NULL; int elto_count= 0; - uint32_t img_blocks= 0, mbr_parts_end= 0, iso_part_blocks; + uint32_t mbr_parts_end= 0, extract_size; struct FindjoB *job= NULL; struct stat dir_stbuf; IsoImage *image; @@ -1681,7 +1696,8 @@ static int Xorriso_scan_report_lines(struct XorrisO *xorriso, char **app_pseudo_paths= NULL; struct tm tm_erg; int was_force_bootable= 0, have_mbr_force_bootable= 0; - uint64_t gpt_bheader_block= 0; + uint64_t gpt_bheader_block= 0, start_block, num_blocks; + uint64_t img_blocks= 0, iso_part_blocks; struct mbr_par { uint8_t ptype; @@ -1714,14 +1730,26 @@ static int Xorriso_scan_report_lines(struct XorrisO *xorriso, #define Xorriso_record_cmd_linE { \ ret= Xorriso_record_cmd_line(xorriso, buf, cmds, cmd_count, flag & 1); \ + buf[0]= 0; \ if(ret <= 0) \ goto ex; \ } +#define Xorriso_record_boot_imglinE { \ + ret= Xorriso_record_cmd_line(xorriso, buf, boot_imgs, boot_img_count, \ + flag & 1); \ + buf[0]= 0; \ + if(ret <= 0) \ + goto ex; \ + } + +/* 2 exp 19 blocks = 1 GiB */ +#define Xorriso_max_endless_uefi_sizE (1 << 19) mkisofs= !!(flag & 2); imported_iso= (!mkisofs) << 30; *cmd_count= 0; + *boot_img_count= 0; line_count= et_line_count + sa_line_count; if(line_count <= 0) {ret= 1; goto ex;} @@ -1780,7 +1808,7 @@ static int Xorriso_scan_report_lines(struct XorrisO *xorriso, if(ret < 0) goto ex; if(ret == 0) - high_block = img_blocks - 1; + high_block = img_blocks / 4 - 1; if(elto_count > 0) { Xorriso_alloc_meM(et_imgs, struct elto_img_par, elto_count); @@ -1869,6 +1897,12 @@ static int Xorriso_scan_report_lines(struct XorrisO *xorriso, if(strcmp(name, "El Torito cat path :") == 0) { cat_path= textpt; + } else if(strcmp(name, "El Torito catalog :") == 0) { + strcpy(buf, "eltorito_catalog.img/"); + Xorriso_add_offset_size(xorriso, buf, ((off_t) num[0]) * 2048, + ((off_t) num[1]) * 2048, 0); + Xorriso_record_boot_imglinE + } else if(strcmp(name, "El Torito boot img :") == 0) { /* Platform Id, bootability, emulation, load segment, Hard disk emulation partition type, Load size @@ -1895,10 +1929,22 @@ static int Xorriso_scan_report_lines(struct XorrisO *xorriso, et_imgs[idx].path= et_imgs[idx].id_string= et_imgs[idx].sel_crit= ""; et_imgs[idx].do_gpt_basdat= et_imgs[idx].do_gpt_hfsplus= 0; et_imgs[idx].do_apm_hfsplus= 0; + et_imgs[idx].extract_size= (et_imgs[idx].ldsiz + 3) / 4; } else if(strcmp(name, "El Torito img path :") == 0) { idx= num[0] - 1; et_imgs[idx].path= textpt; + ret= Xorriso_iso_lstat(xorriso, et_imgs[idx].path, &dir_stbuf, 0); + if(ret == 0) { + extract_size = (dir_stbuf.st_size + 2047) / 2048; + if(extract_size > et_imgs[idx].extract_size) + et_imgs[idx].extract_size= extract_size; + } + + } else if(strcmp(name, "El Torito img blks :") == 0) { + idx= num[0] - 1; + if(num[1] > et_imgs[idx].extract_size) + et_imgs[idx].extract_size= num[1]; } else if(strcmp(name, "El Torito img opts :") == 0) { idx= num[0] - 1; @@ -1925,15 +1971,17 @@ static int Xorriso_scan_report_lines(struct XorrisO *xorriso, } else if(strcmp(name, "MBR partition :") == 0) { sscanf(contentpt, "%lu 0x%lx 0x%lx %lu %lu", - &partno, &part_status, &part_type, &start_block, &num_blocks); + &partno, &part_status, &part_type, &mbr_start_block, + &mbr_num_blocks); idx= partno - 1; mbrpts[idx].ptype= part_type; - mbrpts[idx].start_block= start_block; - mbrpts[idx].block_count= num_blocks; - if(num_blocks > 0 && start_block + num_blocks > mbr_parts_end) - mbr_parts_end= start_block + num_blocks; - if(start_block == partition_offset * 4 && - (start_block + num_blocks) >= high_block * 4 && iso_mbr_part_type < 0) + mbrpts[idx].start_block= mbr_start_block; + mbrpts[idx].block_count= mbr_num_blocks; + if(mbr_num_blocks > 0 && mbr_start_block + mbr_num_blocks > mbr_parts_end) + mbr_parts_end= mbr_start_block + mbr_num_blocks; + if(mbr_start_block == partition_offset * 4 && + (mbr_start_block + mbr_num_blocks) >= high_block * 4 && + iso_mbr_part_type < 0) iso_mbr_part_type = part_type; } else if(strcmp(name, "MBR partition path :") == 0) { @@ -2040,6 +2088,9 @@ static int Xorriso_scan_report_lines(struct XorrisO *xorriso, Xorriso_add_intvl_adr(xorriso, buf, (uint64_t) 0, (uint64_t) 15, "s", imported_iso | ptable_killer); Xorriso_record_cmd_linE + strcpy(buf, "mbr_code_isohybrid.img/"); + Xorriso_add_offset_size(xorriso, buf, (off_t) 0, (off_t) 446, 0); + Xorriso_record_boot_imglinE did_sysarea= 1; } if(strstr(textpt, "grub2-mbr") != NULL) { @@ -2050,6 +2101,9 @@ static int Xorriso_scan_report_lines(struct XorrisO *xorriso, Xorriso_add_intvl_adr(xorriso, buf, (uint64_t) 0, (uint64_t) 15, "s", imported_iso | ptable_killer); Xorriso_record_cmd_linE + strcpy(buf, "mbr_code_grub2.img/"); + Xorriso_add_offset_size(xorriso, buf, (off_t) 0, (off_t) 446, 0); + Xorriso_record_boot_imglinE did_sysarea= 1; } if(strstr(textpt, "protective-msdos-label") != NULL) { @@ -2100,16 +2154,18 @@ static int Xorriso_scan_report_lines(struct XorrisO *xorriso, } else if(strcmp(name, "MBR partition :") == 0) { sscanf(contentpt, "%lu 0x%lx 0x%lx %lu %lu", - &partno, &part_status, &part_type, &start_block, &num_blocks); - if(num_blocks > 0 && part_type != 0x00 && part_type != 0xee && - (iso_part_blocks <= start_block || + &partno, &part_status, &part_type, &mbr_start_block, + &mbr_num_blocks); + if(mbr_num_blocks > 0 && part_type != 0x00 && part_type != 0xee && + (iso_part_blocks <= mbr_start_block || (have_protective_msdos && img_blocks == mbr_parts_end && partno > 1))) { if(!appended_as_gpt) { sprintf(buf, "-append_partition %lu 0x%lx ", partno, part_type); - Xorriso_add_intvl_adr(xorriso, buf, (uint64_t) start_block, - ((uint64_t) start_block) + num_blocks - 1, "d", - imported_iso); + Xorriso_add_intvl_adr(xorriso, buf, (uint64_t) mbr_start_block, + ((uint64_t) mbr_start_block) + mbr_num_blocks - 1, + "d", imported_iso); + Xorriso_record_cmd_linE if(partno >= 1 && (int) partno <= mbr_count) mbrpts[partno - 1].appended= 1; @@ -2118,21 +2174,36 @@ static int Xorriso_scan_report_lines(struct XorrisO *xorriso, #endif } + if(part_type == 0xef) { + sprintf(buf, "mbr_part%lu_efi.img/", partno); + Xorriso_add_offset_size(xorriso, buf, ((off_t) mbr_start_block) * 512, + ((off_t) mbr_num_blocks) * 512, 0); + Xorriso_record_boot_imglinE + } } else if(part_type == 0x41 && have_prep) { if(mkisofs) { sprintf(buf, "-prep-boot-part "); } else { sprintf(buf, "-boot_image any prep_boot_part="); } - Xorriso_add_intvl_adr(xorriso, buf, (uint64_t) start_block, - ((uint64_t) start_block) + num_blocks - 1, "d", - imported_iso); + Xorriso_add_intvl_adr(xorriso, buf, (uint64_t) mbr_start_block, + ((uint64_t) mbr_start_block) + mbr_num_blocks - 1, + "d", imported_iso); + Xorriso_record_cmd_linE + sprintf(buf, "mbr_part%lu_prep.img/", partno); + Xorriso_add_offset_size(xorriso, buf, ((off_t) mbr_start_block) * 512, + ((off_t) mbr_num_blocks) * 512, 0); + Xorriso_record_boot_imglinE + } else if(part_type == 0xef) { + sprintf(buf, "mbr_part%lu_efi.img/", partno); + Xorriso_add_offset_size(xorriso, buf, ((off_t) mbr_start_block) * 512, + ((off_t) mbr_num_blocks) * 512, 0); + Xorriso_record_boot_imglinE } if((part_status & 0x80) && !was_force_bootable) { was_force_bootable= 1; if(buf[0]) { Xorriso_record_cmd_linE - buf[0]= 0; } if(mkisofs) sprintf(buf, "--mbr-force-bootable"); @@ -2145,7 +2216,7 @@ static int Xorriso_scan_report_lines(struct XorrisO *xorriso, sprintf(xorriso->info_text, "Cannot make proposal to mark PReP partition by data file: "); Text_shellsafe(textpt, xorriso->info_text, 1); - if(!(flag & 1)) + if(!(flag & 5)) Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); continue; } @@ -2159,7 +2230,7 @@ static int Xorriso_scan_report_lines(struct XorrisO *xorriso, sprintf(xorriso->info_text, "Cannot make proposal to mark data file as MBR partition without being an El Torito boot image : "); Text_shellsafe(textpt, xorriso->info_text, 1); - if(!(flag & 1)) + if(!(flag & 5)) Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); } else { for(gpt_idx= 0; gpt_idx < gpt_count; gpt_idx++) { @@ -2171,7 +2242,7 @@ static int Xorriso_scan_report_lines(struct XorrisO *xorriso, sprintf(xorriso->info_text, "Cannot make proposal to mark data file as MBR partition without being in GPT : "); Text_shellsafe(textpt, xorriso->info_text, 1); - if(!(flag & 1)) + if(!(flag & 5)) Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); } } @@ -2201,7 +2272,8 @@ static int Xorriso_scan_report_lines(struct XorrisO *xorriso, sprintf(xorriso->info_text, "Cannot make proposal to mark data file as GPT partition : "); Text_shellsafe(textpt, xorriso->info_text, 1); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); + if(!(flag & 5)) + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); } } else if(strcmp(name, "GPT start and size :") == 0) { @@ -2237,7 +2309,6 @@ static int Xorriso_scan_report_lines(struct XorrisO *xorriso, (uint64_t) (num[1] + num[2] - 1.0), "d", imported_iso); Xorriso_record_cmd_linE - buf[0]= 0; #ifdef Not_any_more_because_padding_is_now_after_partitions appended_partition= 1; @@ -2264,7 +2335,6 @@ static int Xorriso_scan_report_lines(struct XorrisO *xorriso, else sprintf(buf, "-boot_image any part_like_isohybrid=on"); Xorriso_record_cmd_linE - buf[0]= 0; part_like_isohybrid= 1; appended_as_gpt= 0; } @@ -2284,7 +2354,21 @@ static int Xorriso_scan_report_lines(struct XorrisO *xorriso, (uint64_t) (num[1] + num[2] - 1.0), "d", imported_iso); efi_boot_part= 2; + Xorriso_record_cmd_linE + } + if(gpts[idx].ptype == 2 && + (img_blocks / 2 > num[2] || num[1] >= img_blocks)) { + /* Obviously not a HFS+ tree covering the ISO */ + sprintf(buf, "gpt_part%d_hfsplus.img/", idx + 1); + Xorriso_add_offset_size(xorriso, buf, ((off_t) num[1]) * 512, + ((off_t) num[2]) * 512, 0); + Xorriso_record_boot_imglinE + } else if(gpts[idx].ptype == 3) { + sprintf(buf, "gpt_part%d_efi.img/", idx + 1); + Xorriso_add_offset_size(xorriso, buf, ((off_t) num[1]) * 512, + ((off_t) num[2]) * 512, 0); + Xorriso_record_boot_imglinE } } else if(strcmp(name, "APM block size :") == 0) { @@ -2326,7 +2410,6 @@ static int Xorriso_scan_report_lines(struct XorrisO *xorriso, else sprintf(buf, "-hfsplus on"); Xorriso_record_cmd_linE - buf[0]= 0; /* Report commands for blessings and creator-type */ ret= Findjob_new(&job, "/", 0); @@ -2383,9 +2466,9 @@ static int Xorriso_scan_report_lines(struct XorrisO *xorriso, partno= id_tag= perms= num_blocks= 0; start_cyl= 0xffffffff; sscanf(contentpt, "%lu 0x%lx 0x%lx %lu %lu", - &partno, &id_tag, &perms, &start_cyl, &num_blocks); + &partno, &id_tag, &perms, &start_cyl, &mbr_num_blocks); if(partno > 0 && partno < 9 && start_cyl == 0 && - num_blocks >= img_blocks - 600 && num_blocks <= img_blocks && + mbr_num_blocks >= img_blocks - 600 && mbr_num_blocks <= img_blocks && ((partno == 1 && id_tag == 4) || (partno > 1 && id_tag == 2))) full_sparc_part|= (1 << (partno - 1)); @@ -2434,7 +2517,8 @@ static int Xorriso_scan_report_lines(struct XorrisO *xorriso, if(!have_alpha_ldr_path) { sprintf(xorriso->info_text, "Cannot enable DEC Alpha boot loader because it is not a data file in the ISO filesystem"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); + if(!(flag & 5)) + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); } } else if(strcmp(name, "DEC Alpha ldr path :") == 0) { @@ -2483,7 +2567,8 @@ static int Xorriso_scan_report_lines(struct XorrisO *xorriso, } else if(!cared_for_sparc) { sprintf(xorriso->info_text, "Cannot enable SUN Disk Label because of non-trivial partition layout"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); + if(!(flag & 5)) + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); } } if(have_sysarea && !did_sysarea) { @@ -2497,6 +2582,11 @@ static int Xorriso_scan_report_lines(struct XorrisO *xorriso, Xorriso_record_cmd_linE did_sysarea= 1; } + if(have_sysarea) { + strcpy(buf, "systemarea.img/"); + Xorriso_add_offset_size(xorriso, buf, (off_t) 0, (off_t) 16 * 2048, 0); + Xorriso_record_boot_imglinE + } if(iso_mbr_part_type >= 0) { if(mkisofs) sprintf(buf, "-iso_mbr_part_type 0x%2.2x", @@ -2542,8 +2632,29 @@ static int Xorriso_scan_report_lines(struct XorrisO *xorriso, } Xorriso_record_cmd_linE for(idx= 0; idx < elto_count; idx++) { + if(strcmp(et_imgs[idx].pltf, "UEFI") == 0 && + et_imgs[idx].extract_size <= 0) { + ret= Xorriso_obtain_indev_readsize(xorriso, &indev_blocks, 0); + if(ret > 0) { + if(indev_blocks > et_imgs[idx].lba && + indev_blocks - et_imgs[idx].lba <= Xorriso_max_endless_uefi_sizE) + et_imgs[idx].extract_size= indev_blocks - et_imgs[idx].lba; + } + if(et_imgs[idx].extract_size <= 0) + continue; + } + sprintf(buf, "eltorito_img%d_", idx + 1); + for(j= 0; j < 4 && et_imgs[idx].pltf[j] != 0; j++) { + buf[strlen(buf) + 1]= 0; + buf[strlen(buf)]= tolower(et_imgs[idx].pltf[j]); + } + strcat(buf, ".img/"); + Xorriso_add_offset_size(xorriso, buf, ((off_t) et_imgs[idx].lba) * 2048, + ((off_t) et_imgs[idx].extract_size) * 2048, 0); + Xorriso_record_boot_imglinE + if(et_imgs[idx].ld_seg != 0 && et_imgs[idx].ld_seg != 0x07c0) { - if(!(flag & 1)) { + if(!(flag & 5)) { sprintf(xorriso->info_text, "Cannot enable EL Torito boot image #%d because its Load Segment is neither 0x0 nor 0x7c0", idx + 1); @@ -2559,9 +2670,6 @@ static int Xorriso_scan_report_lines(struct XorrisO *xorriso, Xorriso_record_cmd_linE } if(et_imgs[idx].path[0] == 0) { - - /* >>> need way to exploit El Torito img blks : */; - /* Check whether appended partition */; for(i= 0; i < mbr_count; i++) if((mbrpts[i].appended || !mbrpts[i].has_path) && @@ -2613,8 +2721,15 @@ static int Xorriso_scan_report_lines(struct XorrisO *xorriso, et_imgs[idx].path= app_pseudo_paths[idx]; } } + if (et_imgs[idx].path[0] == 0) { - if(!(flag & 1)) { + + /* >>> need way to exploit .extract_size by cutting out from ISO */; + + } + + if (et_imgs[idx].path[0] == 0) { + if(!(flag & 5)) { sprintf(xorriso->info_text, "Cannot enable EL Torito boot image #%d because it is not a data file in the ISO filesystem", idx + 1); @@ -2727,7 +2842,7 @@ static int Xorriso_scan_report_lines(struct XorrisO *xorriso, } after_el_torito: - if((apm_count > 0 && !cared_for_apm) && !(flag & 1)) { + if((apm_count > 0 && !cared_for_apm) && !(flag & 5)) { sprintf(xorriso->info_text, "Cannot make proposal to produce APM of loaded image"); Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); @@ -2764,19 +2879,24 @@ ex: return(ret); #undef Xorriso_record_cmd_linE +#undef Xorriso_record_boot_imglinE +#undef Xorriso_max_endless_uefi_sizE } /* @param flag bit0= currently not significant: report is about El Torito rather than System Area - bit1= report -as mkisofs options - bit15= dispose cmds + bit1= report -as mkisofs options in cmds + bit2= no sorry messages + bit15= dispose cmds and boot_imgs */ static int Xorriso_report_to_cmd(struct XorrisO *xorriso, char **et_lines, int et_line_count, char **sa_lines, int sa_line_count, - char ***cmds, int *cmd_count, int flag) + char ***cmds, int *cmd_count, + char ***boot_imgs, int *boot_img_count, + int flag) { int ret= 0, i; @@ -2788,20 +2908,29 @@ static int Xorriso_report_to_cmd(struct XorrisO *xorriso, /* Count commands */ ret= Xorriso_scan_report_lines(xorriso, et_lines, et_line_count, sa_lines, sa_line_count, *cmds, cmd_count, - 1 | (flag & 2)); + *boot_imgs, boot_img_count, + 1 | (flag & 6)); if(ret <= 0) goto ex; - if(*cmd_count <= 0) + if(*cmd_count <= 0 && *boot_img_count <= 0) {ret= 2; goto ex;} - Xorriso_alloc_meM(*cmds, char *, *cmd_count); - for(i= 0; i < *cmd_count; i++) - (*cmds)[i]= NULL; + if(*cmd_count > 0) { + Xorriso_alloc_meM(*cmds, char *, *cmd_count); + for(i= 0; i < *cmd_count; i++) + (*cmds)[i]= NULL; + } + if(*boot_img_count > 0) { + Xorriso_alloc_meM(*boot_imgs, char *, *boot_img_count); + for(i= 0; i < *boot_img_count; i++) + (*boot_imgs)[i]= NULL; + } /* Record commands */ ret= Xorriso_scan_report_lines(xorriso, et_lines, et_line_count, sa_lines, sa_line_count, *cmds, cmd_count, - flag & 2); + *boot_imgs, boot_img_count, + flag & 6); if(ret <= 0) goto ex; @@ -2815,6 +2944,13 @@ ex: Xorriso_free_meM(*cmds); *cmds= NULL; } + if(*boot_imgs != NULL) { + for(i= 0; i < *boot_img_count; i++) + if((*boot_imgs)[i] != NULL) + Xorriso_free_meM((*boot_imgs)[i]); + Xorriso_free_meM(*boot_imgs); + *boot_imgs= NULL; + } } return(ret); } @@ -2839,8 +2975,9 @@ static void Xorriso_report_lines(struct XorrisO *xorriso, int Xorriso_report_system_area(struct XorrisO *xorriso, char *form, int flag) { int ret, line_count, cmd_count= 0, et_line_count= 0, sa_line_count= 0; - int do_cmd= 0, as_mkisofs= 0, i, bin_count; + int do_cmd= 0, as_mkisofs= 0, i, bin_count, boot_img_count= 0; char **lines = NULL, **et_lines= NULL, **sa_lines= NULL, **cmds= NULL; + char **boot_imgs= NULL; uint8_t guid[16]; IsoImage *image; @@ -2885,10 +3022,12 @@ int Xorriso_report_system_area(struct XorrisO *xorriso, char *form, int flag) if(do_cmd) { ret= Xorriso_report_to_cmd(xorriso, et_lines, et_line_count, sa_lines, sa_line_count, &cmds, &cmd_count, + &boot_imgs, &boot_img_count, (flag & 1) | (as_mkisofs << 1)); if(ret <= 0) goto ex; } + } else if(strncmp(form, "gpt_crc_of:", 11) == 0 && !(flag & 1)) { ret = Xorriso_gpt_crc(xorriso, form + 11, 0); goto ex; @@ -2986,7 +3125,60 @@ int Xorriso_report_system_area(struct XorrisO *xorriso, char *form, int flag) } ret= 1; ex:; - Xorriso_report_to_cmd(xorriso, NULL, 0, NULL, 0, &cmds, &cmd_count, 1 << 15); + Xorriso_report_to_cmd(xorriso, NULL, 0, NULL, 0, &cmds, &cmd_count, + &boot_imgs, &boot_img_count, 1 << 15); + if(et_lines != NULL) + iso_image_report_el_torito(NULL, &et_lines, &et_line_count, 1 << 15); + if(sa_lines != NULL) + iso_image_report_system_area(NULL, &sa_lines, &sa_line_count, 1 << 15); + return(ret); +} + + +/* @param flag bit15= dispose imgs + */ +int Xorriso_list_boot_images(struct XorrisO *xorriso, + char ***imgs, int *img_count, int flag) +{ + int ret, cmd_count= 0, et_line_count= 0, sa_line_count= 0, boot_img_count= 0; + char **et_lines= NULL, **sa_lines= NULL, **cmds= NULL, **boot_imgs= NULL; + IsoImage *image; + + if(flag & (1 << 15)) { + boot_imgs= *imgs; + boot_img_count= *img_count; + Xorriso_report_to_cmd(xorriso, NULL, 0, NULL, 0, &cmds, &cmd_count, + &boot_imgs, &boot_img_count, 1 << 15); + *imgs= NULL; + *img_count= 0; + return(1); + } + + *imgs= NULL; + *img_count= 0; + + ret= Xorriso_get_volume(xorriso, &image, 0); + if(ret <= 0) + goto ex; + ret= iso_image_report_el_torito(image, &et_lines, &et_line_count, 0); + if(ret < 0) + goto ex; + ret= iso_image_report_system_area(image, &sa_lines, &sa_line_count, 0); + if(ret < 0) + goto ex; + ret= Xorriso_report_to_cmd(xorriso, et_lines, et_line_count, + sa_lines, sa_line_count, &cmds, &cmd_count, + &boot_imgs, &boot_img_count, 4); + if(ret <= 0) + goto ex; + *imgs= boot_imgs; + *img_count= boot_img_count; + boot_imgs= NULL; + boot_img_count= 0; + ret= 1; +ex:; + Xorriso_report_to_cmd(xorriso, NULL, 0, NULL, 0, &cmds, &cmd_count, + &boot_imgs, &boot_img_count, 1 << 15); if(et_lines != NULL) iso_image_report_el_torito(NULL, &et_lines, &et_line_count, 1 << 15); if(sa_lines != NULL) diff --git a/xorriso/opts_d_h.c b/xorriso/opts_d_h.c index d948e677..5937593d 100644 --- a/xorriso/opts_d_h.c +++ b/xorriso/opts_d_h.c @@ -647,6 +647,24 @@ ex:; } +/* Command -extract_boot_images */ +int Xorriso_option_extract_boot_images(struct XorrisO *xorriso, + char *disk_dir_path, int flag) +{ + int ret; + + if(xorriso->allow_restore <= 0) { + sprintf(xorriso->info_text, +"-extract_boot_images: image-to-disk copies are not enabled by option -osirrox" + ); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } + ret= Xorriso_extract_boot_images(xorriso, disk_dir_path, 0); + return(ret); +} + + /* Option -extract_cut */ int Xorriso_option_extract_cut(struct XorrisO *xorriso, char *iso_rr_path, char *start, char *count, char *disk_path, int flag) @@ -2327,6 +2345,9 @@ int Xorriso_option_help(struct XorrisO *xorriso, int flag) " -extract_cut iso_rr_path byte_offset byte_count disk_path", " Copy a byte interval from iso_rr_path to disk_path.", " This is governed in part by -check_media_defaults.", +" -extract_boot_images disk_path", +" Copy boot images into files in directory disk_path with", +" names which tell the role inside the ISO.", " -cpx iso_rr_path [***] disk_path", " Copy leaf file objects from ISO image to disk filesystem.", " -cpax iso_rr_path [***] disk_path", diff --git a/xorriso/parse_exec.c b/xorriso/parse_exec.c index 0d2fa001..cab9bee1 100644 --- a/xorriso/parse_exec.c +++ b/xorriso/parse_exec.c @@ -542,6 +542,7 @@ int Xorriso_count_args(struct XorrisO *xorriso, int argc, char **argv, "commit_eject","compliance","copyright_file", "dev","dialog","disk_dev_ino","disk_pattern","displacement", "drive_access","dummy","dvd_obs","early_stdio_test","ecma119_map","eject", + "extract_boot_images", "iso_nowtime","iso_rr_pattern","file_name_limit","follow","format","fs", "gid","grow_blindly","hardlinks", "hfsplus","history","indev","in_charset","joliet","joliet_map", @@ -748,6 +749,7 @@ int Xorriso_cmd_sorting_rank(struct XorrisO *xorriso, "* osirrox ISO-to-disk restore options:", "osirrox", "extract", "extract_single", "extract_l", "extract_cut", + "extract_boot_images", "cpx", "cpax", "cp_rx", "cp_rax", "paste_in", "concat", "mount", @@ -1316,11 +1318,22 @@ next_command:; (*idx)+= 2; ret= Xorriso_option_extract(xorriso, arg1, arg2, 0); + } else if(strcmp(cmd,"extract_boot_images")==0) { + (*idx)+= 1; + if((*idx)>argc) { + sprintf(xorriso->info_text, + "-extract_boot_images: Empty disk_path cannot be used as target directory"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + ret= 0; + } else { + ret= Xorriso_option_extract_boot_images(xorriso, arg1, 0); + } + } else if(strcmp(cmd,"extract_cut")==0) { (*idx)+= 4; if((*idx)>argc) { sprintf(xorriso->info_text, - "-extract_cut: Not enough arguments. Needed are: disk_path start count so_rr_path"); + "-extract_cut: Not enough arguments. Needed are: disk_path start count iso_rr_path"); Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); ret= 0; } else diff --git a/xorriso/read_run.c b/xorriso/read_run.c index d6cf5287..a38f6afe 100644 --- a/xorriso/read_run.c +++ b/xorriso/read_run.c @@ -2332,7 +2332,8 @@ ex:; } -/* @param flag bit1= for Xorriso_check_interval(): no pacifier messages +/* @param flag bit0= ignore node and img_path, operate on whole medium + bit1= for Xorriso_check_interval(): no pacifier messages */ int Xorriso_read_file_data(struct XorrisO *xorriso, IsoNode *node, char *img_path, char *disk_path, @@ -2341,6 +2342,8 @@ int Xorriso_read_file_data(struct XorrisO *xorriso, IsoNode *node, { int ret, i, lba_count= 0, *start_lbas= NULL, *end_lbas= NULL, read_chunk= 16; int lba, count, blocks, quality, spot, bad_extract= 0; + int data_to_skip= 0; + uint32_t indev_blocks; off_t size= 0, file_base_bytes= 0, file_processed_bytes= 0, img_adr; off_t new_file_base_bytes, upto_file_bytes, start_byte= 0; off_t *section_sizes = NULL; @@ -2348,25 +2351,33 @@ int Xorriso_read_file_data(struct XorrisO *xorriso, IsoNode *node, struct CheckmediajoB *job= NULL; upto_file_bytes= img_offset + bytes; + data_to_skip= img_offset % (off_t) 2048; - /* >>> make Xorriso_check_interval() ready for copying in byte granularity */ - if(img_offset % (off_t) 2048) { - sprintf(xorriso->info_text, - "Image address offset is not a multiple of 2048"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - ret= 0; goto ex; - } - - ret= Xorriso__start_end_lbas(node, &lba_count, &start_lbas, &end_lbas, - §ion_sizes, &size, 0); - if(ret <= 0) { - Xorriso_process_msg_queues(xorriso,0); - sprintf(xorriso->info_text, "File object "); - Text_shellsafe(img_path, xorriso->info_text, 1); - strcat(xorriso->info_text, - " is currently not a data file from the loaded image"); - Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); - goto ex; + if(flag & 1) { + lba_count= 1; + Xorriso_alloc_meM(start_lbas, int, 1); + Xorriso_alloc_meM(end_lbas, int, 1); + Xorriso_alloc_meM(section_sizes, off_t, 1); + start_lbas[0]= 0; + ret= Xorriso_obtain_indev_readsize(xorriso, &indev_blocks, 0); + if(ret > 0) + end_lbas[0]= indev_blocks - 1; + else + end_lbas[0]= 0x7ffffffe; + size= ((off_t) end_lbas[0]) * 2048; + section_sizes[0]= size; + } else { + ret= Xorriso__start_end_lbas(node, &lba_count, &start_lbas, &end_lbas, + §ion_sizes, &size, 0); + if(ret <= 0) { + Xorriso_process_msg_queues(xorriso,0); + sprintf(xorriso->info_text, "File object "); + Text_shellsafe(img_path, xorriso->info_text, 1); + strcat(xorriso->info_text, + " is currently not a data file from the loaded image"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + goto ex; + } } if(img_offset + bytes < size && bytes > 0) size= img_offset + bytes; @@ -2409,13 +2420,14 @@ int Xorriso_read_file_data(struct XorrisO *xorriso, IsoNode *node, file_base_bytes= img_offset; } - /* Eventually omit surplus blocks */ + /* Omit surplus blocks */ if(new_file_base_bytes > upto_file_bytes) count-= (new_file_base_bytes - upto_file_bytes) / (off_t) 2048; /* Adjust job */ job->data_to_offset= file_processed_bytes - img_adr + disk_offset; job->data_to_limit= size - file_base_bytes; - + job->data_to_skip= data_to_skip; + data_to_skip= 0; file_processed_bytes+= ((off_t) count) * (off_t) 2048; ret= Xorriso_check_interval(xorriso, spotlist, job, lba, count, read_chunk, 0, (flag & 2)); @@ -2471,6 +2483,103 @@ ex:; } +int Xorriso_extract_boot_images(struct XorrisO *xorriso, char *disk_dir_path, + int flag) +{ + int ret, img_count= 0, i, was_problem= 0; + char **imgs= NULL, *eff_path= NULL, *cpt, *eff_namept; + struct stat stbuf; + off_t byte_offset, byte_size; + + Xorriso_alloc_meM(eff_path, char, SfileadrL); + ret= Xorriso_normalize_img_path(xorriso, xorriso->wdx, disk_dir_path, + eff_path, 2 | 4); + if(ret <= 0) + goto ex; + if(strlen(eff_path) > SfileadrL - 80) { + sprintf(xorriso->info_text, + "-extract_boot_images: disk_path is too long (%lu)\n", + (unsigned long int) strlen(eff_path)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + ret= 0; goto ex; + } + ret= stat(eff_path, &stbuf); + if(ret == 0) { + if(!S_ISDIR(stbuf.st_mode)) { + sprintf(xorriso->info_text, + "-extract_boot_images: disk_path is not a directory : "); + Text_shellsafe(eff_path, xorriso->info_text, 1); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + ret= 0; goto ex; + } + } else { + ret= mkdir(eff_path, 0777); + if(ret == -1) { + sprintf(xorriso->info_text, + "-extract_boot_images: cannot create directory : "); + Text_shellsafe(eff_path, xorriso->info_text, 1); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0); + ret= 0; goto ex; + } + } + strcat(eff_path, "/"); + eff_namept= eff_path + strlen(eff_path); + + ret= Xorriso_list_boot_images(xorriso, &imgs, &img_count, 0); + if(ret <= 0) + goto ex; + + /* Interpret list and create files */ + for(i= 0; i < img_count; i++) { + ret= Xorriso_eval_problem_status(xorriso, 1, 1 | 2); + if(ret < 0) + {ret= 0; goto ex;} + cpt= strchr(imgs[i], '/'); + if(cpt == NULL) + continue; + *cpt= 0; + cpt+= 2; + ret= Sfile_text_to_off_t(cpt, &byte_offset, 0); + if(ret <= 0) + continue; + cpt+= ret; + if(*cpt == 0) + continue; + cpt++; + ret= Sfile_text_to_off_t(cpt, &byte_size, 0); + if(ret <= 0) + continue; + + strcpy(eff_namept, imgs[i]); + sprintf(xorriso->info_text, "%s : offset=%.f size=%.f\n", + eff_path, (double) byte_offset, (double) byte_size); + Xorriso_info(xorriso, 0); + + ret= stat(eff_path, &stbuf); + if(ret != -1) { + sprintf(xorriso->info_text, + "-extract_boot_images: File already exists on disk: "); + Text_shellsafe(eff_path, xorriso->info_text, 1); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0); + continue; + } + ret= Xorriso_read_file_data(xorriso, NULL, NULL, eff_path, + byte_offset, (off_t) 0, byte_size, 1); + if(ret <= 0) + was_problem= 1; + } + ret= Xorriso_eval_problem_status(xorriso, 1, 1 | 2); + if(ret < 0 || was_problem) + {ret= 0; goto ex;} + + ret= 1; +ex:; + Xorriso_free_meM(eff_path); + Xorriso_list_boot_images(xorriso, &imgs, &img_count, 1 << 15); + return(ret); +} + + /* @param node Opaque handle to IsoNode which is to be inquired instead of path if it is not NULL. @param path is used as address if node is NULL. @param flag bit0= do not report to result but only indicate outcome diff --git a/xorriso/sfile.c b/xorriso/sfile.c index 1f353ff6..2c7f91bb 100644 --- a/xorriso/sfile.c +++ b/xorriso/sfile.c @@ -1,7 +1,7 @@ /* xorriso - creates, loads, manipulates and burns ISO 9660 filesystem images. - Copyright 2007-2014 Thomas Schmitt, + Copyright 2007-2020 Thomas Schmitt, Provided under GPL version 2 or later. @@ -430,6 +430,32 @@ int Sfile_off_t_text(char text[80], off_t num, int flag) } +/* @return index number of first not interpreted text byte +*/ +int Sfile_text_to_off_t(char *text, off_t *num, int flag) +{ + int sig= 1, ridx; + + *num= 0; + ridx= 0; + if(text[ridx] == '-') { + sig= -1; + ridx++; + } else if(text[ridx] == '+') { + ridx++; + } + for(; text[ridx] != 0; ridx++) { + if(text[ridx] < '0' || text[ridx] > '9') + break; + if(*num > (((off_t) 1) << 59)) + return(-1); + *num= *num * 10 + text[ridx] - '0'; + } + *num= *num * sig; + return(ridx); +} + + /* Converts backslash codes into single characters: \a BEL 7 , \b BS 8 , \e ESC 27 , \f FF 12 , \n LF 10 , \r CR 13 , \t HT 9 , \v VT 11 , \\ \ 92 diff --git a/xorriso/sfile.h b/xorriso/sfile.h index 758a5ef2..80724222 100644 --- a/xorriso/sfile.h +++ b/xorriso/sfile.h @@ -1,7 +1,7 @@ /* xorriso - creates, loads, manipulates and burns ISO 9660 filesystem images. - Copyright 2007-2014 Thomas Schmitt, + Copyright 2007-2020 Thomas Schmitt, Provided under GPL version 2 or later. @@ -105,6 +105,7 @@ int Sfile_sep_make_argv(char *progname, char *line, char *separators, int Sfile_decode_datestr(struct tm *reply, char *text, int flag); int Sfile_off_t_text(char text[80], off_t num, int flag); +int Sfile_text_to_off_t(char *text, off_t *num, int flag); int Sfile_leafname(char *path, char leafname[SfileadrL], int flag); diff --git a/xorriso/xorriso.1 b/xorriso/xorriso.1 index 444c6303..0865ffb3 100644 --- a/xorriso/xorriso.1 +++ b/xorriso/xorriso.1 @@ -9,7 +9,7 @@ .\" First parameter, NAME, should be all caps .\" Second parameter, SECTION, should be 1-8, maybe w/ subsection .\" other parameters are allowed: see man(7), man(1) -.TH XORRISO 1 "Version 1.5.3, Nov 20, 2020" +.TH XORRISO 1 "Version 1.5.3, Nov 30, 2020" .\" Please adjust this date whenever revising the manpage. .\" .\" Some roff macros, for reference: @@ -5132,6 +5132,43 @@ word are used as arguments with the program start. Example: The further parameters in all modes are the iso_rr_paths of data files. Their content gets concatenated in the copy. .TP +\fB\-extract_boot_images\fR disk_path +Copy boot equipment to disk, which is not necessarily represented as data files +in the ISO filesystem. The data get written into various files in a disk +directory, which may already exist or of which the parent must exist so that +it can get created. +.br +Files may be missing if their corresponding information is +not present in the ISO filesystem. Existing files do not get overwritten but +rather cause a failure event. +.br +The same data may appear in different files. E.g. the El Torito boot image for +EFI is often the same data as the EFI partition in MBR or GPT. +.br +File "eltorito_catalog.img" contains the El Torito Boot Catalog. +.br +Files "eltorito_img*_*.img" contain El Torito Boot images. The first "*" gives +the image number, the second "*" gives the type: "bios", "mac", "ppc", "uefi", +or a hex number. +.br +File "mbr_code_isohybrid.img" contains the ISOLINUX MBR template. +.br +File "mbr_code_grub2.img" contains the GRUB2 MBR template. +.br +File "systemarea.img" contains the whole 32 KiB of System Area if not all zero. +.br +Files "mbr_part*_efi.img" contain EFI partition images from the MBR partition +table. The "*" text part gives the partition number. +.br +Files "mbr_part*_prep.img" contain PReP partition images. +.br +Files "gpt_part*_efi.img" contain EFI partition images from GPT. +.br +Files "gpt_part*_hfsplus.img" contain HFS+ partition images from GPT. +To avoid extracting the whole HFS+ aspect of hybrid ISO filesystems, the +partition image is extracted only if it has less than half of the size of +the ISO filesystem or if the partition is outside the ISO filesystem. +.TP \fB\-mount\fR drive entity id path Produce the same line as \-mount_cmd and then execute it as external program run after giving up the depicted drive. See also \-mount_opts. diff --git a/xorriso/xorriso.h b/xorriso/xorriso.h index f3d462a2..0392564a 100644 --- a/xorriso/xorriso.h +++ b/xorriso/xorriso.h @@ -1568,6 +1568,11 @@ int Xorriso_option_external_filter(struct XorrisO *xorriso, int Xorriso_option_extract(struct XorrisO *xorriso, char *disk_path, char *iso_path, int flag); +/* Command -extract_boot_images */ +/* @sice 1.5.4 */ +int Xorriso_option_extract_boot_images(struct XorrisO *xorriso, + char *disk_dir_path, int flag); + /* Command -extract_cut */ /* @since 0.2.6 */ int Xorriso_option_extract_cut(struct XorrisO *xorriso, char *iso_rr_path, diff --git a/xorriso/xorriso.info b/xorriso/xorriso.info index cbc40838..595c84c0 100644 --- a/xorriso/xorriso.info +++ b/xorriso/xorriso.info @@ -4330,6 +4330,34 @@ The directory permissions on disk have to allow rwx. The further parameters in all modes are the iso_rr_paths of data files. Their content gets concatenated in the copy. +-extract_boot_images disk_path + Copy boot equipment to disk, which is not necessarily represented + as data files in the ISO filesystem. The data get written into + various files in a disk directory, which may already exist or of + which the parent must exist so that it can get created. + Files may be missing if their corresponding information is not + present in the ISO filesystem. Existing files do not get + overwritten but rather cause a failure event. + The same data may appear in different files. E.g. the El Torito + boot image for EFI is often the same data as the EFI partition in + MBR or GPT. + File "eltorito_catalog.img" contains the El Torito Boot Catalog. + Files "eltorito_img*_*.img" contain El Torito Boot images. The + first "*" gives the image number, the second "*" gives the type: + "bios", "mac", "ppc", "uefi", or a hex number. + File "mbr_code_isohybrid.img" contains the ISOLINUX MBR template. + File "mbr_code_grub2.img" contains the GRUB2 MBR template. + File "systemarea.img" contains the whole 32 KiB of System Area if + not all zero. + Files "mbr_part*_efi.img" contain EFI partition images from the MBR + partition table. The "*" text part gives the partition number. + Files "mbr_part*_prep.img" contain PReP partition images. + Files "gpt_part*_efi.img" contain EFI partition images from GPT. + Files "gpt_part*_hfsplus.img" contain HFS+ partition images from + GPT. To avoid extracting the whole HFS+ aspect of hybrid ISO + filesystems, the partition image is extracted only if it has less + than half of the size of the ISO filesystem or if the partition is + outside the ISO filesystem. -mount drive entity id path Produce the same line as -mount_cmd and then execute it as external program run after giving up the depicted drive. See also @@ -5579,6 +5607,8 @@ File: xorriso.info, Node: CommandIdx, Next: ConceptIdx, Prev: Legal, Up: Top * -external_filter registers data filter: Filter. (line 20) * -external_filter unregisters data filter: Filter. (line 47) * -extract copies file tree to disk: Restore. (line 83) +* -extract_boot_images copies boot equipment to disk: Restore. + (line 167) * -extract_cut copies file piece to disk: Restore. (line 101) * -extract_l copies files to disk: Restore. (line 97) * -extract_single copies file to disk: Restore. (line 94) @@ -5636,7 +5666,7 @@ File: xorriso.info, Node: CommandIdx, Next: ConceptIdx, Prev: Legal, Up: Top * -md5 controls handling of MD5 sums: Loading. (line 184) * -mkdir creates ISO directory: Insert. (line 177) * -modesty_on_drive keep drive buffer hungry: SetWrite. (line 406) -* -mount issues mount command for ISO session: Restore. (line 167) +* -mount issues mount command for ISO session: Restore. (line 195) * -mount_cmd composes mount command line: Inquiry. (line 49) * -mount_cmd controls mount command: Inquiry. (line 65) * -msg_op perform operations on program messages: Frontend. (line 27) @@ -5993,6 +6023,8 @@ File: xorriso.info, Node: ConceptIdx, Prev: CommandIdx, Up: Top * Relocation directory, set name, -rr_reloc_dir: SetWrite. (line 150) * Rename, in ISO image, -move: Manip. (line 31) * Rename, in ISO image, -mv: Manip. (line 37) +* Restore, copy boot equipment to disk, -extract_boot_images: Restore. + (line 167) * Restore, copy file into disk file, -paste_in: Restore. (line 135) * Restore, copy file piece to disk, -extract_cut: Restore. (line 101) * Restore, copy file to disk, -extract_single: Restore. (line 94) @@ -6008,7 +6040,7 @@ File: xorriso.info, Node: ConceptIdx, Prev: CommandIdx, Up: Top * Rock Ridge, _definition: Extras. (line 6) * Session, altered start address, -displacement: Loading. (line 78) * Session, info string, -session_string: Inquiry. (line 74) -* Session, issue mount command, -mount: Restore. (line 167) +* Session, issue mount command, -mount: Restore. (line 195) * Session, log when written, -session_log: Scripting. (line 134) * Session, mount command line, -mount_cmd: Inquiry. (line 49) * Session, mount parameters, -mount_opts: Inquiry. (line 65) @@ -6093,32 +6125,32 @@ Node: Inquiry197867 Node: Navigate206749 Node: Verify215456 Node: Restore226605 -Node: Emulation236588 -Node: Scripting247044 -Node: Frontend254827 -Node: Examples264453 -Node: ExDevices265631 -Node: ExCreate266292 -Node: ExDialog267592 -Node: ExGrowing268863 -Node: ExModifying269672 -Node: ExBootable270182 -Node: ExCharset270737 -Node: ExPseudo271633 -Node: ExCdrecord272560 -Node: ExMkisofs272880 -Node: ExGrowisofs274777 -Node: ExException275930 -Node: ExTime276388 -Node: ExIncBackup276846 -Node: ExRestore280872 -Node: ExRecovery281818 -Node: Files282390 -Node: Environ283724 -Node: Seealso284472 -Node: Bugreport285189 -Node: Legal285780 -Node: CommandIdx286792 -Node: ConceptIdx304481 +Node: Emulation238304 +Node: Scripting248760 +Node: Frontend256543 +Node: Examples266169 +Node: ExDevices267347 +Node: ExCreate268008 +Node: ExDialog269308 +Node: ExGrowing270579 +Node: ExModifying271388 +Node: ExBootable271898 +Node: ExCharset272453 +Node: ExPseudo273349 +Node: ExCdrecord274276 +Node: ExMkisofs274596 +Node: ExGrowisofs276493 +Node: ExException277646 +Node: ExTime278104 +Node: ExIncBackup278562 +Node: ExRestore282588 +Node: ExRecovery283534 +Node: Files284106 +Node: Environ285440 +Node: Seealso286188 +Node: Bugreport286905 +Node: Legal287496 +Node: CommandIdx288508 +Node: ConceptIdx306333  End Tag Table diff --git a/xorriso/xorriso.texi b/xorriso/xorriso.texi index 5ac24690..fd3fcc2a 100644 --- a/xorriso/xorriso.texi +++ b/xorriso/xorriso.texi @@ -50,7 +50,7 @@ @c man .\" First parameter, NAME, should be all caps @c man .\" Second parameter, SECTION, should be 1-8, maybe w/ subsection @c man .\" other parameters are allowed: see man(7), man(1) -@c man .TH XORRISO 1 "Version 1.5.3, Nov 20, 2020" +@c man .TH XORRISO 1 "Version 1.5.3, Nov 30, 2020" @c man .\" Please adjust this date whenever revising the manpage. @c man .\" @c man .\" Some roff macros, for reference: @@ -5893,6 +5893,45 @@ word are used as arguments with the program start. Example: The further parameters in all modes are the iso_rr_paths of data files. Their content gets concatenated in the copy. @c man .TP +@item -extract_boot_images disk_path +@kindex -extract_boot_images copies boot equipment to disk +@cindex Restore, copy boot equipment to disk, -extract_boot_images +Copy boot equipment to disk, which is not necessarily represented as data files +in the ISO filesystem. The data get written into various files in a disk +directory, which may already exist or of which the parent must exist so that +it can get created. +@* +Files may be missing if their corresponding information is +not present in the ISO filesystem. Existing files do not get overwritten but +rather cause a failure event. +@* +The same data may appear in different files. E.g. the El Torito boot image for +EFI is often the same data as the EFI partition in MBR or GPT. +@* +File "eltorito_catalog.img" contains the El Torito Boot Catalog. +@* +Files "eltorito_img*_*.img" contain El Torito Boot images. The first "*" gives +the image number, the second "*" gives the type: "bios", "mac", "ppc", "uefi", +or a hex number. +@* +File "mbr_code_isohybrid.img" contains the ISOLINUX MBR template. +@* +File "mbr_code_grub2.img" contains the GRUB2 MBR template. +@* +File "systemarea.img" contains the whole 32 KiB of System Area if not all zero. +@* +Files "mbr_part*_efi.img" contain EFI partition images from the MBR partition +table. The "*" text part gives the partition number. +@* +Files "mbr_part*_prep.img" contain PReP partition images. +@* +Files "gpt_part*_efi.img" contain EFI partition images from GPT. +@* +Files "gpt_part*_hfsplus.img" contain HFS+ partition images from GPT. +To avoid extracting the whole HFS+ aspect of hybrid ISO filesystems, the +partition image is extracted only if it has less than half of the size of +the ISO filesystem or if the partition is outside the ISO filesystem. +@c man .TP @item -mount drive entity id path @kindex -mount issues mount command for ISO session @cindex Session, issue mount command, -mount diff --git a/xorriso/xorriso_timestamp.h b/xorriso/xorriso_timestamp.h index 00d573dc..c603e02f 100644 --- a/xorriso/xorriso_timestamp.h +++ b/xorriso/xorriso_timestamp.h @@ -1 +1 @@ -#define Xorriso_timestamP "2020.12.04.103410" +#define Xorriso_timestamP "2020.12.05.085329" diff --git a/xorriso/xorrisoburn.h b/xorriso/xorrisoburn.h index 697b2fc1..f516e379 100644 --- a/xorriso/xorrisoburn.h +++ b/xorriso/xorrisoburn.h @@ -380,6 +380,8 @@ int Xorriso_extract_cut(struct XorrisO *xorriso, char *img_path, char *disk_path, off_t img_offset, off_t bytes, int flag); +int Xorriso_extract_boot_images(struct XorrisO *xorriso, char *disk_dir_path, + int flag); int Xorriso_relax_compliance(struct XorrisO *xorriso, char *mode, int flag); @@ -642,6 +644,9 @@ int Xorriso_apply_sort_file(struct XorrisO *xorriso, char *path, int flag); int Xorriso_report_system_area(struct XorrisO *xorriso, char *form, int flag); +int Xorriso_list_boot_images(struct XorrisO *xorriso, + char ***imgs, int *img_count, int flag); + int Xorriso_external_filter_banned(struct XorrisO *xorriso, char *purpose, int flag); @@ -668,5 +673,8 @@ int Xorriso_make_guid(struct XorrisO *xorriso, char *line, int flag); int Xorriso_set_libisofs_now(struct XorrisO *xorriso, int flag); +int Xorriso_obtain_indev_readsize(struct XorrisO *xorriso, uint32_t *blocks, + int flag); + #endif /* Xorrisoburn_includeD */