/* xorriso - creates, loads, manipulates and burns ISO 9660 filesystem images. Copyright 2007-2024 Thomas Schmitt, Provided under GPL version 2 or later. This file contains functions which operate on ISO images and their global properties. */ #ifdef HAVE_CONFIG_H #include "../config.h" #endif #include #include #include #include #include #include #include #include #include #include #include #include "xorriso.h" #include "xorriso_private.h" #include "xorrisoburn.h" #include "lib_mgt.h" #include "iso_img.h" #include "iso_tree.h" #include "drive_mgt.h" int Xorriso_set_ignore_aclea(struct XorrisO *xorriso, int flag) { int ret, hflag; IsoImage *volume; ret= Xorriso_get_volume(xorriso, &volume, 1); if(ret<=0) return(ret); hflag= (~xorriso->do_aaip) & 1; if((xorriso->ino_behavior & (1 | 2)) && !(xorriso->do_aaip & (4 | 16))) hflag|= 2; if(xorriso->do_aaip & 1024) hflag|= 8; if(xorriso->do_aaip & 2048) hflag|= 4; if(xorriso->do_aaip & (1 << 17)) hflag|= 64; if(xorriso->do_aaip & (1 << 15)) hflag|= 32; iso_image_set_ignore_aclea(volume, hflag); return(1); } int Xorriso_update_volid(struct XorrisO *xorriso, int flag) { int gret, sret= 1; gret= Xorriso_get_volid(xorriso, xorriso->loaded_volid, 0); if(gret<=0 || (!xorriso->volid_default) || xorriso->loaded_volid[0]==0) sret= Xorriso_set_volid(xorriso, xorriso->volid, 1); return(gret>0 && sret>0); } int Xorriso_create_empty_iso(struct XorrisO *xorriso, int flag) { int ret; IsoImage *volset; struct isoburn_read_opts *ropts; struct burn_drive_info *dinfo= NULL; struct burn_drive *drive= NULL; if(xorriso->out_drive_handle != NULL) { ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive, "on attempt to attach volset to drive", 2); if(ret<=0) return(ret); } if(xorriso->in_volset_handle!=NULL) { iso_image_unref((IsoImage *) xorriso->in_volset_handle); xorriso->in_volset_handle= NULL; Sectorbitmap_destroy(&(xorriso->in_sector_map), 0); Xorriso_destroy_di_array(xorriso, 0); Xorriso_destroy_hln_array(xorriso, 0); xorriso->loaded_volid[0]= 0; xorriso->volset_change_pending= 0; xorriso->boot_count= 0; xorriso->no_volset_present= 0; } ret= isoburn_ropt_new(&ropts, 0); if(ret<=0) return(ret); /* Note: no return before isoburn_ropt_destroy() */ isoburn_ropt_set_extensions(ropts, isoburn_ropt_pretend_blank); isoburn_ropt_set_input_charset(ropts, xorriso->in_charset); isoburn_ropt_set_data_cache(ropts, 1, 1, 0); isoburn_set_read_pacifier(drive, NULL, NULL); isoburn_ropt_set_truncate_mode(ropts, 1, xorriso->file_name_limit); ret= isoburn_read_image(drive, ropts, &volset); Xorriso_process_msg_queues(xorriso,0); isoburn_ropt_destroy(&ropts, 0); if(ret<=0) { sprintf(xorriso->info_text, "Failed to create new empty ISO image object"); Xorriso_report_iso_error(xorriso, "", ret, xorriso->info_text, 0, "FATAL", 0); return(-1); } xorriso->in_volset_handle= (void *) volset; xorriso->in_sector_map= NULL; Xorriso_update_volid(xorriso, 0); xorriso->volset_change_pending= 0; xorriso->boot_count= 0; xorriso->system_area_clear_loaded= (strcmp(xorriso->system_area_disk_path, "/dev/zero") == 0); xorriso->no_volset_present= 0; return(1); } int Xorriso_record_boot_info(struct XorrisO *xorriso, int flag) { int ret; struct burn_drive_info *dinfo; struct burn_drive *drive; IsoImage *image; ElToritoBootImage *bootimg; IsoFile *bootimg_node; IsoBoot *bootcat_node; xorriso->loaded_boot_bin_lba= -1; xorriso->loaded_boot_cat_path[0]= 0; ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive, "on attempt to record boot LBAs", 0); if(ret<=0) return(0); image= isoburn_get_attached_image(drive); if(image == NULL) return(0); ret= iso_image_get_boot_image(image, &bootimg, &bootimg_node, &bootcat_node); iso_image_unref(image); /* release obtained reference */ if(ret != 1) return(0); if(bootimg_node != NULL) Xorriso__file_start_lba((IsoNode *) bootimg_node, &(xorriso->loaded_boot_bin_lba), 0); if(bootcat_node != NULL) Xorriso_path_from_lba(xorriso, (IsoNode *) bootcat_node, (off_t) 0, xorriso->loaded_boot_cat_path, 0); return(1); } int Xorriso_assert_volid(struct XorrisO *xorriso, off_t msc1, int flag) { int ret; off_t image_blocks; char volid[33]; struct burn_drive_info *dinfo; struct burn_drive *drive; if(xorriso->assert_volid[0] == 0) return(1); ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive, "on attempt to perform -assert_volid", 0); if(ret<=0) return(0); ret= isoburn_read_iso_head_v2(drive, msc1, &image_blocks, volid, 1); Xorriso_process_msg_queues(xorriso,0); if(ret <= 0) { sprintf(xorriso->info_text, "-assert_volid: Cannot determine Volume Id at LBA %.f.", (double) msc1); Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, xorriso->assert_volid_sev, 0); return(0); } ret= Sregex_match(xorriso->assert_volid, volid, 0); if(ret < 0) return(2); if(ret == 0) { strcpy(xorriso->info_text, "-assert_volid: Volume id does not match pattern: "); Text_shellsafe(xorriso->assert_volid, xorriso->info_text, 1); strcat(xorriso->info_text, " <> "); Text_shellsafe(volid, xorriso->info_text, 1); Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, xorriso->assert_volid_sev, 0); return(0); } return(ret); } /* @return <0 yes , 0 no , <0 error */ int Xorriso_is_isohybrid(struct XorrisO *xorriso, IsoFile *bootimg_node, int flag) { int ret; unsigned char buf[68]; void *data_stream= NULL; ret= Xorriso_iso_file_open(xorriso, "", (void *) bootimg_node, &data_stream, 1); if(ret <= 0) return(-1); ret= Xorriso_iso_file_read(xorriso, data_stream, (char *) buf, 68, 0); Xorriso_iso_file_close(xorriso, &data_stream, 0); if(ret <= 0) return(0); if(buf[64] == 0xfb && buf[65] == 0xc0 && buf[66] == 0x78 && buf[67] == 0x70) return(1); return(0); } int Xorriso_image_has_md5(struct XorrisO *xorriso, int flag) { int ret; IsoImage *image; uint32_t start_lba, end_lba; char md5[16]; ret= Xorriso_get_volume(xorriso, &image, 0); if(ret<=0) return(ret); ret= iso_image_get_session_md5(image, &start_lba, &end_lba, md5, 0); Xorriso_process_msg_queues(xorriso,0); if(ret <= 0) return(0); return(1); } static const char *un0(const char *text) { if(text == NULL) return(""); return(text); } static int Xorriso_report_pvd_time(struct XorrisO *xorriso, char *head, char *pvd_time, int flag) { char *msg, hr[17]; int at; msg= xorriso->result_line; strncpy(hr, pvd_time, 16); hr[16]= 0; sprintf(msg, "%s %s\n", head, hr); Xorriso_result(xorriso,0); if(pvd_time[16] != 0) { at= abs(pvd_time[16]); sprintf(msg, "%2.2s. Time Zone: %c%-2.2d:%-2.2d\n", head, pvd_time[16] > 0 ? '+' : '-', at / 4, (at - (at / 4) * 4) * 15); Xorriso_result(xorriso,0); } return(1); } int Xorriso_pvd_info(struct XorrisO *xorriso, int flag) { int ret; off_t msc1= -1, msc2, i; IsoImage *image; struct burn_drive_info *dinfo; struct burn_drive *drive; char *msg, block_head[8], *crt, *mdt, *ext, *eft; off_t head_count; msg= xorriso->result_line; ret= Xorriso_get_volume(xorriso, &image, 0); if(ret<=0) return(ret); ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive, "", 16); if(ret > 0) { ret= Xorriso_msinfo(xorriso, &msc1, &msc2, 1 | 4); if(ret<0) return(ret); Xorriso_toc(xorriso, 128); if(msc1 >= 0) { for(i = msc1 + 16; i < msc1 + 32; i++) { ret= burn_read_data(drive, i * (off_t) 2048, block_head, (off_t) sizeof(block_head), &head_count, 2); if(ret <= 0) { i= msc1 + 32; break; } if(block_head[0] == 1 && strncmp(block_head + 1, "CD001", 5) == 0) break; } if(i < msc1 + 32) { sprintf(msg, "PVD address : %.fs\n", (double) i); Xorriso_result(xorriso,0); } } } sprintf(msg, "Volume Id : %s\n", un0(iso_image_get_volume_id(image))); Xorriso_result(xorriso,0); sprintf(msg, "Volume Set Id: %s\n", xorriso->volset_id); Xorriso_result(xorriso,0); sprintf(msg, "Publisher Id : %s\n", xorriso->publisher); Xorriso_result(xorriso,0); sprintf(msg, "Preparer Id : %s\n", un0(iso_image_get_data_preparer_id(image))); Xorriso_result(xorriso,0); sprintf(msg, "App Id : %s\n", xorriso->application_id); Xorriso_result(xorriso,0); sprintf(msg, "System Id : %s\n", xorriso->system_id); Xorriso_result(xorriso,0); sprintf(msg, "CopyrightFile: %s\n", xorriso->copyright_file); Xorriso_result(xorriso,0); sprintf(msg, "Abstract File: %s\n", xorriso->abstract_file); Xorriso_result(xorriso,0); sprintf(msg, "Biblio File : %s\n", xorriso->biblio_file); Xorriso_result(xorriso,0); ret= iso_image_get_pvd_times(image, &crt, &mdt, &ext, &eft); if(ret != ISO_SUCCESS) { crt= mdt= ext= eft= " "; /* Need 17 bytes. Last byte 0. */ } else { Untimezone_ecma119_17byte(crt, 0); Untimezone_ecma119_17byte(mdt, 0); Untimezone_ecma119_17byte(ext, 0); Untimezone_ecma119_17byte(eft, 0); } Xorriso_report_pvd_time(xorriso, "Creation Time:", crt, 0); Xorriso_report_pvd_time(xorriso, "Modif. Time :", mdt, 0); Xorriso_report_pvd_time(xorriso, "Expir. Time :", ext, 0); Xorriso_report_pvd_time(xorriso, "Eff. Time :", eft, 0); return(1); } /* @param flag bit0= do not mark image as changed */ int Xorriso_set_volid(struct XorrisO *xorriso, char *volid, int flag) { int ret; IsoImage *volume; if(xorriso->in_volset_handle == NULL) return(2); ret= Xorriso_get_volume(xorriso, &volume, 0); if(ret<=0) return(ret); if(iso_image_get_volume_id(volume) == NULL || strcmp(iso_image_get_volume_id(volume), volid) != 0) if(!(flag&1)) Xorriso_set_change_pending(xorriso, 1); iso_image_set_volume_id(volume, volid); Xorriso_process_msg_queues(xorriso,0); sprintf(xorriso->info_text,"Volume ID: '%s'",iso_image_get_volume_id(volume)); Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0); return(1); } int Xorriso_get_volid(struct XorrisO *xorriso, char volid[33], int flag) { int ret; IsoImage *volume; ret= Xorriso_get_volume(xorriso, &volume, 0); if(ret<=0) return(ret); strncpy(volid, iso_image_get_volume_id(volume), 32); volid[32]= 0; return(1); } /* bit0= do only report non-default settings bit1= do only report to fp bit2= is_default bit3= append -boot_image any next bit4= concentrate boot options bit5= override load_size by "full" */ int Xorriso_boot_item_status(struct XorrisO *xorriso, char *cat_path, char *bin_path, int platform_id, int patch_isolinux, int emul, off_t load_size, unsigned char *id_string, unsigned char *selection_crit, char *form, char *filter, FILE *fp, int flag) { int is_default, no_defaults, i, is_default_id= 0, ret; char *line, *bspec= NULL, zeros[28], *partition_entry; off_t file_size; struct stat stbuf; Xorriso_alloc_meM(bspec, char, SfileadrL + 80); no_defaults= flag & 1; line= xorriso->result_line; if(flag & 32) load_size= -1; if((flag & 16) && bin_path[0] != 0) { /* Concentrate boot options. */ memset(zeros, 0, 28); if(memcmp(id_string, zeros, 28) == 0 && memcmp(selection_crit, zeros, 20) == 0) is_default_id= 1; /* -boot_image isolinux dir= ... */ bspec[0]= 0; if(strcmp(form, "isolinux") != 0 && strcmp(form, "any") != 0) ; else if(strcmp(bin_path, "/isolinux.bin") == 0 && strcmp(cat_path, "/boot.cat") == 0) strcpy(bspec, "dir=/"); else if(strcmp(bin_path, "/isolinux/isolinux.bin") == 0 && strcmp(cat_path, "/isolinux/boot.cat") == 0) strcpy(bspec, "dir=/isolinux"); else if(strcmp(xorriso->boot_image_bin_path, "/boot/isolinux/isolinux.bin") == 0 && strcmp(xorriso->boot_image_cat_path, "/boot/isolinux/boot.cat") == 0) strcpy(bspec, "dir=/boot/isolinux"); memset(zeros, 0, 28); if(bspec[0] && platform_id == 0 && (patch_isolinux & 0x3ff) == 1 && load_size == 2048 && is_default_id && emul == 0) { sprintf(line, "-boot_image isolinux %s\n", bspec); Xorriso_status_result(xorriso,filter,fp,flag&2); {ret= 1; goto ex;}; } file_size= 0; if(strncmp(bin_path, "--interval:appended_partition_", 30) == 0) { ret= -1; } else { ret= Xorriso_iso_lstat(xorriso, bin_path, &stbuf, 2 | 4); } if(ret == 0) { file_size= ((stbuf.st_size / (off_t) 512) + !!(stbuf.st_size % (off_t) 512)) * 512; if(flag & 32) load_size= file_size * 512; } if(platform_id == 0xef && (patch_isolinux & 0x3ff) == 0 && load_size / 512 == file_size && is_default_id && emul == 0) { sprintf(line, "-boot_image any efi_path="); Text_shellsafe(bin_path, line, 1); strcat(line, "\n"); Xorriso_status_result(xorriso,filter,fp,flag&2); {ret= 1; goto ex;}; } } is_default= (bin_path[0] == 0) || (flag & 4); sprintf(line, "-boot_image %s bin_path=", form); Text_shellsafe(bin_path, line, 1); strcat(line, "\n"); if(!(is_default && no_defaults)) Xorriso_status_result(xorriso,filter,fp,flag&2); is_default= (emul == 0); sprintf(line, "-boot_image %s emul_type=%s\n", form, emul == 2 ? "diskette" : emul == 1 ? "hard_disk" : "no_emulation"); if(!(is_default && no_defaults)) Xorriso_status_result(xorriso,filter,fp,flag&2); is_default= (platform_id == 0 || (flag & 4)); sprintf(line, "-boot_image %s platform_id=0x%-2.2x\n", form, platform_id); if(!(is_default && no_defaults)) Xorriso_status_result(xorriso,filter,fp,flag&2); is_default= ((patch_isolinux & 1) == 0 || bin_path[0] == 0 || (flag & 4)); sprintf(line, "-boot_image %s boot_info_table=%s\n", (patch_isolinux & 2) ? "grub" : form, (patch_isolinux & 1) ? "on" : "off"); if(!(is_default && no_defaults)) Xorriso_status_result(xorriso,filter,fp,flag&2); is_default= ((patch_isolinux & 512) == 0 || bin_path[0] == 0 || (flag & 4)); sprintf(line, "-boot_image grub grub2_boot_info=%s\n", (patch_isolinux & 512) ? "on" : "off"); if(!(is_default && no_defaults)) Xorriso_status_result(xorriso,filter,fp,flag&2); if(flag & 32) { is_default= 0; sprintf(line, "-boot_image %s load_size=full", form); } else { is_default= (load_size == 2048 || (flag & 4)); sprintf(line, "-boot_image %s load_size=%lu\n", form, (unsigned long) load_size); } if(!(is_default && no_defaults)) Xorriso_status_result(xorriso,filter,fp,flag&2); is_default= 1; if(!(flag & 4)) for(i= 0; i < 20; i++) if(selection_crit[i]) is_default= 0; sprintf(line, "-boot_image %s sel_crit=", form); for(i= 0; i < 20; i++) sprintf(line + strlen(line), "%-2.2X", (unsigned int) selection_crit[i]); strcat(line, "\n"); if(!(is_default && no_defaults)) Xorriso_status_result(xorriso,filter,fp,flag&2); is_default= 1; if(!(flag & 4)) for(i= 0; i < 28; i++) if(id_string[i]) is_default= 0; sprintf(line, "-boot_image %s id_string=", form); for(i= 0; i < 28; i++) sprintf(line + strlen(line), "%-2.2X", (unsigned int) id_string[i]); strcat(line, "\n"); if(!(is_default && no_defaults)) Xorriso_status_result(xorriso,filter,fp,flag&2); is_default= 1; partition_entry= ""; if((patch_isolinux & 0x0fc) == (1 << 2)) partition_entry= "gpt_basdat"; else if((patch_isolinux & 0x0fc) == (2 << 2)) partition_entry= "gpt_hfsplus"; if(partition_entry[0]) { sprintf(line, "-boot_image isolinux partition_entry=%s\n", partition_entry); Xorriso_status_result(xorriso, filter, fp, flag & 2); is_default= 0; } if(patch_isolinux & (1 << 8)) { sprintf(line, "-boot_image isolinux partition_entry=apm_hfsplus\n"); Xorriso_status_result(xorriso, filter, fp, flag & 2); is_default= 0; } if(is_default && !no_defaults) { sprintf(line, "-boot_image isolinux partition_entry=off\n"); Xorriso_status_result(xorriso, filter, fp, flag & 2); } ret= 1; ex:; Xorriso_free_meM(bspec); return(ret); } int Xorriso_status_hppa(struct XorrisO *xorriso, char *what, char *value, char *filter, FILE *fp, int flag) { char *line; line= xorriso->result_line; if(value == NULL) return(1); sprintf(line, "-boot_image any hppa_%s=", what); Text_shellsafe(value, line, 1); strcat(line, "\n"); Xorriso_status_result(xorriso, filter, fp, flag & 2); return(1); } /* bit0= do only report non-default settings bit1= do only report to fp */ int Xorriso_boot_status_non_mbr(struct XorrisO *xorriso, IsoImage *image, char *filter, FILE *fp, int flag) { int i, num_boots, sa_type; char *paths[15], *line; int ret; char num[4]; char *cmdline, *bootloader, *kernel_32, *kernel_64, *ramdisk; line= xorriso->result_line; sa_type= (xorriso->system_area_options & 0xfc) >> 2; if(sa_type == 3) { sprintf(line, "-boot_image any sparc_label="); Text_shellsafe(xorriso->ascii_disc_label, line, 1); strcat(line, "\n"); Xorriso_status_result(xorriso, filter, fp, flag & 2); sprintf(line, "-boot_image grub grub2_sparc_core="); Text_shellsafe(xorriso->grub2_sparc_core, line, 1); strcat(line, "\n"); Xorriso_status_result(xorriso, filter, fp, flag & 2); return(0); } else if(sa_type == 1 || sa_type == 2) { num_boots= iso_image_get_mips_boot_files(image, paths, 0); Xorriso_process_msg_queues(xorriso, 0); if(num_boots > 0) { if(sa_type == 2) num_boots= 1; for(i= 0; i < num_boots; i++) { sprintf(line, "-boot_image any mips%s_path=", sa_type ==2 ? "el" : ""); Text_shellsafe(paths[i], line, 1); strcat(line, "\n"); Xorriso_status_result(xorriso, filter, fp, flag & 2); } } return(num_boots); } else if(sa_type == 4 || sa_type == 5) { ret= iso_image_get_hppa_palo(image, &cmdline, &bootloader, &kernel_32, &kernel_64, &ramdisk); if(ret == 1) { Xorriso_status_hppa(xorriso, "cmdline", cmdline, filter, fp, 0); Xorriso_status_hppa(xorriso, "bootloader", bootloader, filter, fp, 0); Xorriso_status_hppa(xorriso, "kernel_32", kernel_32, filter, fp, 0); Xorriso_status_hppa(xorriso, "kernel_64", kernel_64, filter, fp, 0); Xorriso_status_hppa(xorriso, "ramdisk", ramdisk, filter, fp, 0); sprintf(num, "%d", sa_type); Xorriso_status_hppa(xorriso, "hdrversion", num, filter, fp, 0); } return(0); } else if(sa_type == 6) { ret= iso_image_get_alpha_boot(image, &bootloader); if (ret == 1 && bootloader != NULL) { sprintf(line, "-boot_image any alpha_boot="); Text_shellsafe(bootloader, line, 1); strcat(line, "\n"); Xorriso_status_result(xorriso, filter, fp, flag & 2); } return(0); } return(0); } /* bit0= do only report non-default settings bit1= do only report to fp */ int Xorriso_append_part_status(struct XorrisO *xorriso, IsoImage *image, char *filter, FILE *fp, int flag) { int i, l, is_default; is_default= (xorriso->appended_as_gpt == 0); sprintf(xorriso->result_line, "-boot_image any appended_part_as=%s\n", xorriso->appended_as_gpt ? "gpt" : "mbr"); if(!(is_default && (flag & 1))) Xorriso_status_result(xorriso, filter, fp, flag & 2); for(i= 0; i < Xorriso_max_appended_partitionS; i++) { if(xorriso->appended_partitions[i] == NULL) continue; sprintf(xorriso->result_line, "-append_partition %d ", i + 1); l= strlen(xorriso->result_line); if(xorriso->appended_part_gpt_flags[i] & 1) { Xorriso__format_guid(xorriso->appended_part_type_guids[i], xorriso->result_line + l, 0); strcpy(xorriso->result_line + l + 32, " "); } else { sprintf(xorriso->result_line + l, "0x%2.2x ", (unsigned int) xorriso->appended_part_types[i]); } Text_shellsafe(xorriso->appended_partitions[i], xorriso->result_line, 1); strcat(xorriso->result_line, "\n"); Xorriso_status_result(xorriso, filter, fp, flag & 2); } return(1); } /* bit0= do only report non-default settings bit1= do only report to fp */ int Xorriso_boot_image_status(struct XorrisO *xorriso, char *filter, FILE *fp, int flag) { int ret, i, num_boots, hflag; int is_default, no_defaults; char *path= NULL, *form= "any", *line, *hpt; struct burn_drive_info *dinfo; struct burn_drive *drive; IsoImage *image= NULL; ElToritoBootImage **boots = NULL; IsoFile **bootnodes = NULL; int platform_id, patch, load_size; enum eltorito_boot_media_type media_type; unsigned char id_string[29], sel_crit[21]; Xorriso_alloc_meM(path, char, SfileadrL); line= xorriso->result_line; no_defaults= flag & 1; ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive, "on attempt to print boot info", 2 | 16); if(ret<=0) goto no_image; image= isoburn_get_attached_image(drive); Xorriso_process_msg_queues(xorriso,0); if(image == NULL) goto no_image; ret= Xorriso_boot_status_non_mbr(xorriso, image, filter, fp, flag & 3); if(ret < 0) /* == 0 is normal */ {ret= 0; goto ex;} if(xorriso->boot_count == 0 && xorriso->boot_image_bin_path[0] == 0) { no_image:; if(xorriso->patch_isolinux_image & 1) { sprintf(line, "-boot_image %s patch\n", xorriso->patch_isolinux_image & 2 ? "grub" : form); is_default= 0; } else if(xorriso->keep_boot_image) { sprintf(line, "-boot_image %s keep\n", form); is_default= 0; } else { sprintf(line, "-boot_image %s discard\n", form); is_default= 1; } if(!(is_default && no_defaults)) Xorriso_status_result(xorriso,filter,fp,flag&2); goto report_open_item; } is_default= (xorriso->boot_image_cat_path[0] == 0); sprintf(line,"-boot_image %s cat_path=", form); Text_shellsafe(xorriso->boot_image_cat_path, line, 1); strcat(line, "\n"); if(!(is_default && no_defaults)) Xorriso_status_result(xorriso,filter,fp,flag&2); is_default= !xorriso->boot_image_cat_hidden; hpt= Xorriso__hide_mode_text(xorriso->boot_image_cat_hidden & 63, 0); if(hpt != NULL) sprintf(line, "-boot_image %s cat_hidden=%s\n", form, hpt); Xorriso_free_meM(hpt); if(!(is_default && no_defaults)) Xorriso_status_result(xorriso,filter,fp,flag&2); if(xorriso->boot_count > 0) { /* show attached boot image info */; ret= iso_image_get_all_boot_imgs(image, &num_boots, &boots, &bootnodes, 0); Xorriso_process_msg_queues(xorriso,0); if(ret == 1 && num_boots > 0) { for(i= 0; i < num_boots; i++) { ret= Xorriso_path_from_node(xorriso, (IsoNode *) bootnodes[i], path, 0); if(ret <= 0) continue; platform_id= el_torito_get_boot_platform_id(boots[i]); patch= el_torito_get_isolinux_options(boots[i], 0); el_torito_get_boot_media_type(boots[i], &media_type); load_size= el_torito_get_load_size(boots[i]) * 512; el_torito_get_id_string(boots[i], id_string); el_torito_get_selection_crit(boots[i], sel_crit); if(media_type == ELTORITO_FLOPPY_EMUL) media_type= 2; else if(media_type == ELTORITO_HARD_DISC_EMUL) media_type= 1; else media_type= 0; ret= Xorriso_boot_item_status(xorriso, xorriso->boot_image_cat_path, path, platform_id, patch, media_type, load_size, id_string, sel_crit, "any", filter, fp, 16 | (flag & 3)); if(ret <= 0) continue; sprintf(line,"-boot_image %s next\n", form); Xorriso_status_result(xorriso,filter,fp,flag&2); } } } /* Show pending boot image info */ if(strcmp(xorriso->boot_image_bin_form, "isolinux") == 0 || strcmp(xorriso->boot_image_bin_form, "grub") == 0) form= xorriso->boot_image_bin_form; if(xorriso->boot_count > 0 && xorriso->boot_platform_id == 0 && xorriso->patch_isolinux_image == 0 && xorriso->boot_image_bin_path[0] == 0 && xorriso->boot_image_emul == 0 && xorriso->boot_image_load_size == 4 * 512) { for(i= 0; i < 20; i++) if(xorriso->boot_selection_crit[i]) break; if(i >= 20) for(i= 0; i < 28; i++) if(xorriso->boot_id_string[i]) break; if(i >= 28) {ret= 1; goto ex;} /* Images registered, pending is still default */ } report_open_item:; hflag= 16; if(xorriso->boot_platform_id == 0xef && !xorriso->boot_efi_default) hflag= 0; ret= Xorriso_boot_item_status(xorriso, xorriso->boot_image_cat_path, xorriso->boot_image_bin_path, xorriso->boot_platform_id, xorriso->patch_isolinux_image, xorriso->boot_image_emul, xorriso->boot_image_load_size, xorriso->boot_id_string, xorriso->boot_selection_crit, form, filter, fp, hflag | (flag & 3)); if(ret <= 0) goto ex; ret = Xorriso_append_part_status(xorriso, image, filter, fp, flag & 3); if(ret <= 0) goto ex; ret= 1; ex: if(boots != NULL) free(boots); if(bootnodes != NULL) free(bootnodes); if(image != NULL) iso_image_unref(image); Xorriso_free_meM(path); return(ret); } int Xorriso__append_boot_params(char *line, ElToritoBootImage *bootimg, int flag) { unsigned int platform_id; platform_id= el_torito_get_boot_platform_id(bootimg); if(platform_id != 0) sprintf(line + strlen(line), " , platform_id=0x%-2.2X ", (unsigned int) platform_id); if(el_torito_seems_boot_info_table(bootimg, 0)) sprintf(line + strlen(line), " , boot_info_table=on"); if(el_torito_seems_boot_info_table(bootimg, 1)) sprintf(line + strlen(line), " , grub2_boot_info=on"); return(1); } /* @param flag bit0= no output if no boot record was found bit1= short form bit3= report to info channel (else to result channel) */ int Xorriso_show_boot_info(struct XorrisO *xorriso, int flag) { int ret, bin_path_valid= 0, i, num_boots, sa_count; char *respt, *path= NULL, **sa_report= NULL, *sa_summary= NULL; unsigned char *lb0= NULL; struct burn_drive_info *dinfo; struct burn_drive *drive; IsoImage *image= NULL; ElToritoBootImage *bootimg, **boots = NULL; IsoFile *bootimg_node, **bootnodes = NULL; IsoBoot *bootcat_node; Xorriso_alloc_meM(path, char, SfileadrL); Xorriso_alloc_meM(lb0, unsigned char, 2048); respt= xorriso->result_line; if(xorriso->boot_count > 0) { if(!(flag & 1)) { sprintf(respt, "Boot record : (overridden by -boot_image any next)\n"); Xorriso_toc_line(xorriso, flag & 8); } ret= 1; goto ex; } ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive, "on attempt to print boot info", 16); if(ret<=0) goto no_boot; image= isoburn_get_attached_image(drive); if(image == NULL) { ret= 0; no_boot:; if(!(flag & 1)) { sprintf(respt, "Boot record : none\n"); Xorriso_toc_line(xorriso, flag & 8); } goto ex; } ret= iso_image_report_system_area(image, &sa_report, &sa_count, 0); if(ret > 0 && sa_report != NULL) for(i= 0; i < sa_count; i++) if(strncmp(sa_report[i], "System area summary: ", 21) == 0) { Xorriso_alloc_meM(sa_summary, char, strlen(sa_report[i] + 21) + 1); strcpy(sa_summary, sa_report[i] + 21); break; } if(sa_report != NULL) iso_image_report_system_area(image, &sa_report, &sa_count, 1 << 15); Xorriso_process_msg_queues(xorriso,0); /* Using the nodes with extreme care . They might be deleted meanwhile. */ ret= iso_image_get_boot_image(image, &bootimg, &bootimg_node, &bootcat_node); if(ret != 1) { if(sa_summary == NULL) goto no_boot; sprintf(respt, "Boot record : (system area only) , %s\n", sa_summary); Xorriso_toc_line(xorriso, flag & 8); ret= 1; goto ex; } ret= iso_image_get_all_boot_imgs(image, &num_boots, &boots, &bootnodes, 0); Xorriso_process_msg_queues(xorriso,0); if(ret != 1) { num_boots= 0; } else { ret= Xorriso_path_from_node(xorriso, (IsoNode *) bootnodes[0], path, 0); if(ret > 0) bin_path_valid= 1; } sprintf(respt, "Boot record : El Torito"); if(sa_summary != NULL) sprintf(respt + strlen(respt), " , %s", sa_summary); strcat(respt, "\n"); Xorriso_toc_line(xorriso, flag & 8); if(flag & 2) {ret= 1; goto ex;} if(xorriso->loaded_boot_cat_path[0]) { sprintf(respt, "Boot catalog : "); Text_shellsafe(xorriso->loaded_boot_cat_path, respt, 1); strcat(respt, "\n"); } else { sprintf(respt, "Boot catalog : -not-found-at-load-time-\n"); } Xorriso_toc_line(xorriso, flag & 8); if(bin_path_valid) { sprintf(respt, "Boot image : "); Text_shellsafe(path, respt, 1); } else if(xorriso->loaded_boot_bin_lba <= 0) { sprintf(respt, "Boot image : -not-found-at-load-time-"); } else { sprintf(respt, "Boot image : -not-found-any-more-by-lba=%.f", (double) xorriso->loaded_boot_bin_lba); } Xorriso__append_boot_params(respt, bootimg, 0); strcat(respt, "\n"); Xorriso_toc_line(xorriso, flag & 8); if(num_boots > 1) { for(i= 1; i < num_boots; i++) { ret= Xorriso_path_from_node(xorriso, (IsoNode *) bootnodes[i], path, 0); if(ret > 0) { sprintf(respt, "Boot image : "); Text_shellsafe(path, respt, 1); } else sprintf(respt, "Boot image : -not-found-any-more-"); Xorriso__append_boot_params(respt, boots[i], 0); strcat(respt, "\n"); Xorriso_toc_line(xorriso, flag & 8); } } ret= 1; ex:; if(boots != NULL) free(boots); if(bootnodes != NULL) free(bootnodes); if(image != NULL) iso_image_unref(image); /* release obtained reference */ Xorriso_free_meM(path); Xorriso_free_meM(lb0); Xorriso_free_meM(sa_summary); return(ret); } /* @param flag bit0=silently return 0 if no volume/image is present */ int Xorriso_get_volume(struct XorrisO *xorriso, IsoImage **volume, int flag) { *volume= NULL; if(xorriso->in_volset_handle==NULL) { if(flag & 1) return(0); Xorriso_process_msg_queues(xorriso,0); sprintf(xorriso->info_text,"No ISO image present."); if(xorriso->indev[0]==0 && xorriso->outdev[0]==0) sprintf(xorriso->info_text+strlen(xorriso->info_text), " No -dev, -indev, or -outdev selected."); else sprintf(xorriso->info_text+strlen(xorriso->info_text), " Possible program error with drive '%s'.", xorriso->indev); if(!xorriso->no_volset_present) Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); xorriso->no_volset_present= 1; return(0); } *volume= (IsoImage *) xorriso->in_volset_handle; xorriso->no_volset_present= 0; return(*volume != NULL); } /* @param flag bit0= do not return 1 on volset_change_pending != 1 bit1= issue NOTE if return is 0, indev and outdev point to different drives, and no write run or size run has happened */ int Xorriso_change_is_pending(struct XorrisO *xorriso, int flag) { int ret; if(flag & 1) ret= (xorriso->volset_change_pending == 1); else ret= !!xorriso->volset_change_pending; if((flag & 2) && xorriso->volset_change_pending == 0 && xorriso->commit_attempts <= 0 && xorriso->print_size_attempts <= 0 && xorriso->write_session_counter <= 0 && xorriso->print_size_counter <= 0) { if(xorriso->indev[0] != 0 && xorriso->outdev[0] != 0 && strcmp(xorriso->indev, xorriso->outdev) != 0) { Xorriso_msgs_submit(xorriso, 0, "-indev and -outdev differ. But no pending image modifications.", 0, "NOTE", 0); } } return(ret); } /* @param flag bit0= do not set hln_change_pending */ int Xorriso_set_change_pending(struct XorrisO *xorriso, int flag) { int ret; IsoImage *image; ret= Xorriso_get_volume(xorriso, &image, 1); if(ret <= 0) return ret; /* Do not override mark of -as mkisofs -print-size */ if(xorriso->volset_change_pending != 2) xorriso->volset_change_pending= 1; if(!(flag & 1)) xorriso->hln_change_pending= 1; return(1); } /** @param flag bit0= print mount command to result channel rather than performing it bit1= do not allow prefixes with cmd bit2= interpret unprefixed cmd as shell: */ int Xorriso_mount(struct XorrisO *xorriso, char *dev, int adr_mode, char *adr_value, char *cmd, int flag) { int ret, track, session, params_flag= 0, is_safe= 0, is_extra_drive= 0; int give_up= 0, mount_chardev= 0, status, aquire_flag= 0; off_t lba; char volid[33], *devadr, *mount_command= NULL, *adr_data= NULL, *adr_pt; char *dev_path, *libburn_adr= NULL; char *dpt, *sysname= ""; struct stat stbuf; struct burn_drive_info *dinfo= NULL; struct burn_drive *drive= NULL; Xorriso_alloc_meM(mount_command, char, SfileadrL); Xorriso_alloc_meM(adr_data, char, 163); Xorriso_alloc_meM(libburn_adr, char, BURN_DRIVE_ADR_LEN + SfileadrL); devadr= dev; adr_pt= adr_value; if(strcmp(dev, "indev") == 0) { ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive, "on attempt to perform -mount \"indev\"", 0); if(ret<=0) goto ex; dev_path= devadr= xorriso->indev; if(strncmp(dev_path, "stdio:", 6) == 0) dev_path+= 6; else if(strncmp(dev_path, "mmc:", 4) == 0) dev_path+= 4; if(xorriso->in_drive_handle == xorriso->out_drive_handle) give_up= 3; else give_up= 1; } else if(strcmp(dev, "outdev") == 0) { ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive, "on attempt to perform -mount \"outdev\"", 2); if(ret<=0) goto ex; dev_path= devadr= xorriso->outdev; if(strncmp(dev_path, "stdio:", 6) == 0) dev_path+= 6; else if(strncmp(dev_path, "mmc:", 4) == 0) dev_path+= 4; if(xorriso->in_drive_handle == xorriso->out_drive_handle) give_up= 3; else give_up= 2; } else { is_extra_drive= 1; dev_path= dev; if(strncmp(dev_path, "stdio:", 6) == 0) dev_path+= 6; else if(strncmp(dev_path, "mmc:", 4) == 0) dev_path+= 4; /* do only accept regular files and block devices */ ret= stat(dev_path, &stbuf); if(ret == -1) { sprintf(xorriso->info_text, "Cannot determine properties of file "); Text_shellsafe(dev_path, xorriso->info_text, 1); Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); ret= 0; goto ex; } ret= System_uname(&sysname, NULL, NULL, NULL, 0); if(ret > 0 && strcmp(sysname, "FreeBSD") == 0) mount_chardev= 1; if(!(S_ISREG(stbuf.st_mode) || (S_ISBLK(stbuf.st_mode) && !mount_chardev) || (S_ISCHR(stbuf.st_mode) && !mount_chardev))) { sprintf(xorriso->info_text, "File object is not suitable as mount device: "); Text_shellsafe(dev_path, xorriso->info_text, 1); Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); ret= 0; goto ex; } /* Acquire drive as direct libburn address or via stdio: prefix */ if(strncmp(dev, "mmc:", 4) == 0) ret= burn_drive_convert_fs_adr(dev + 4, libburn_adr); else ret= burn_drive_convert_fs_adr(dev, libburn_adr); Xorriso_process_msg_queues(xorriso,0); if(ret < 0) {ret= -1; goto ex;} if(ret == 0 && strncmp(dev, "stdio:", 6) != 0 && strncmp(dev, "mmc:", 4) != 0) sprintf(libburn_adr, "stdio:%s", dev); burn_preset_device_open( (xorriso->drives_exclusive && !(xorriso->mount_opts_flag & 1)) | (xorriso->linux_scsi_dev_family << 2), 0, 0); aquire_flag= 1 | 32 | 64; if((xorriso->toc_emulation_flag & 2) && (adr_mode == 3 || adr_mode == 0)) aquire_flag|= 16; /* -rom_toc_scan emul_off with sbsector or auto */ if(xorriso->toc_emulation_flag & 4) aquire_flag|= 128; if(xorriso->toc_emulation_flag & 8) aquire_flag|= 512; ret= isoburn_drive_aquire(&dinfo, libburn_adr, aquire_flag); burn_preset_device_open(1 | (xorriso->linux_scsi_dev_family << 2), 0, 0); Xorriso_process_msg_queues(xorriso,0); if(ret <= 0) {ret= 0; goto ex;} drive= dinfo[0].drive; } ret= Xorriso_prepare_load_search(xorriso, "-mount", adr_mode, adr_pt, adr_data, ¶ms_flag, 0); if(ret <= 0) goto ex; adr_pt= adr_data; ret= isoburn_get_mount_params_v2(drive, adr_mode, adr_pt, &lba, &track, &session, volid, params_flag); Xorriso_process_msg_queues(xorriso,0); if(ret <= 0) goto ex; if(((session <= 0 || track <= 0) && !(aquire_flag & 16)) || ret == 2) { Xorriso_msgs_submit(xorriso, 0, "-mount : Given address does not point to an ISO 9660 session", 0, "FAILURE", 0); ret= 0; goto ex; } if(strstr(devadr, "stdio:") == devadr) devadr+= 6; if(strstr(devadr, "mmc:") == devadr) devadr+= 4; ret= Xorriso_make_mount_cmd(xorriso, cmd, lba, track, session, volid, devadr, mount_command, (flag & (2 | 4)) | ((flag & 4) << 1)); if(ret <= 0) goto ex; if(ret == 2) is_safe= 1; if(is_extra_drive) { isoburn_drive_release(drive, 0); burn_drive_info_free(dinfo); drive= NULL; } else if(give_up > 0 && !((flag & 1) || (xorriso->mount_opts_flag & 1))) { ret= Xorriso_give_up_drive(xorriso, give_up); if(ret <= 0) goto ex; } Xorriso_process_msg_queues(xorriso,0); sprintf(xorriso->info_text, "Volume id : "); Text_shellsafe(volid, xorriso->info_text, 1); strcat(xorriso->info_text, "\n"); Xorriso_info(xorriso, 0); if(flag & 1) { sprintf(xorriso->result_line, "%s\n", mount_command); Xorriso_result(xorriso,0); } else { sprintf(xorriso->info_text, "Mount command: %s\n", mount_command); Xorriso_info(xorriso, 0); if(!is_safe) { Xorriso_msgs_submit(xorriso, 0, "-mount : Will not perform mount command which stems from command template.", 0, "SORRY", 0); sprintf(xorriso->result_line, "%s\n", mount_command); Xorriso_result(xorriso,0); } else { ret= Xorriso_execv(xorriso, mount_command, 0, NULL, "/bin:/sbin", NULL, NULL, NULL, &status, 1); if(WIFEXITED(status) && WEXITSTATUS(status) != 0) { sprintf(xorriso->info_text, "-mount : mount command failed with exit value %d", (int) WEXITSTATUS(status)); Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); ret= 0; goto ex; } sprintf(xorriso->info_text, "\nMounted session %d of device ", session); Text_shellsafe(dev_path, xorriso->info_text, 1); dpt= strchr(cmd, ':'); if(dpt == NULL) dpt= cmd ; else dpt++; sprintf(xorriso->info_text + strlen(xorriso->info_text), " as directory "); Text_shellsafe(dpt, xorriso->info_text, 1); strcat(xorriso->info_text, "\n"); Xorriso_info(xorriso, 0); } } ret= 1; ex:; if(is_extra_drive && drive != NULL) { isoburn_drive_release(drive, 0); burn_drive_info_free(dinfo); Xorriso_process_msg_queues(xorriso,0); } Xorriso_free_meM(mount_command); Xorriso_free_meM(adr_data); Xorriso_free_meM(libburn_adr); return(ret); } /* @param flag bit0= give up all boot file paths bit1= refuse if already a path is added */ int Xorriso_add_mips_boot_file(struct XorrisO *xorriso, char *path, int flag) { int ret; IsoImage *image; char *paths[15]; ret= Xorriso_get_volume(xorriso, &image, 0); if(ret <= 0) return ret; if(flag & 1) { iso_image_give_up_mips_boot(image, 0); Xorriso_process_msg_queues(xorriso,0); return(1); } if(flag & 2) { ret= iso_image_get_mips_boot_files(image, paths, 0); Xorriso_process_msg_queues(xorriso,0); if(ret < 0) goto report_error; if(ret > 0) { Xorriso_msgs_submit(xorriso, 0, "There is already a boot image file registered.", 0, "FAILURE", 0); return(0); } } ret = iso_image_add_mips_boot_file(image, path, 0); Xorriso_process_msg_queues(xorriso,0); if (ret < 0) { report_error:; Xorriso_report_iso_error(xorriso, "", ret, "Error when adding MIPS boot file", 0, "FAILURE", 1); return(0); } return(1); } /* @param flag bit0= Give up HP-PA boot parameters */ int Xorriso_set_hppa_boot_parm(struct XorrisO *xorriso, char *text, char *what, int flag) { int ret; IsoImage *image; char *par[5]; ret= Xorriso_get_volume(xorriso, &image, 0); if(ret <= 0) return(ret); par[0]= par[1]= par[2]= par[3]= par[4]= NULL; if(flag & 1) { /* Give up HP-PA boot parameters */ iso_image_set_hppa_palo(image, par[0], par[1], par[2], par[3], par[4], 1); return(1); } if(strcmp(what, "cmdline") == 0) { par[0]= text; } else if(strcmp(what, "bootloader") == 0) { par[1]= text; } else if(strcmp(what, "kernel_32") == 0 || strcmp(what, "kernel-32") == 0) { par[2]= text; } else if(strcmp(what, "kernel_64") == 0 || strcmp(what, "kernel-64") == 0) { par[3]= text; } else if(strcmp(what, "ramdisk") == 0) { par[4]= text; } else if(strcmp(what, "hdrversion") == 0) { if(strcmp(text, "4") == 0) { xorriso->system_area_options= (xorriso->system_area_options & ~0xfc) | (4 << 2); } else if(strcmp(text, "5") == 0) { xorriso->system_area_options= (xorriso->system_area_options & ~0xfc) | (5 << 2); } else { strcpy(xorriso->info_text, "Unsupported HP-PA PALO header version "); Text_shellsafe(text, xorriso->info_text, 1); Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); return(0); } return(1); } else { strcpy(xorriso->info_text, "HP-PA boot parameter name not recognized: hppa_"); Text_shellsafe(what, xorriso->info_text, 1); Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); return(0); } ret= iso_image_set_hppa_palo(image, par[0], par[1], par[2], par[3], par[4], 0); if (ret < 0) { Xorriso_report_iso_error(xorriso, "", ret, "Error when adding HP-PA boot parameter", 0, "FAILURE", 1); return(0); } return(1); } /* @param flag bit0= Give up DEC Alpha boot parameters */ int Xorriso_set_alpha_boot(struct XorrisO *xorriso, char *path, int flag) { int ret; IsoImage *image; ret= Xorriso_get_volume(xorriso, &image, 0); if(ret <= 0) return(ret); if(flag & 1) { /* Give up boot parameters */ iso_image_set_alpha_boot(image, NULL, 1); return(1); } ret= iso_image_set_alpha_boot(image, path, 0); if (ret < 0) { Xorriso_report_iso_error(xorriso, "", ret, "Error when adding DEC Alpha boot loader", 0, "FAILURE", 1); return(0); } return(1); } /* @param flag bit0= do not set xorriso->system_area_options, just check bit1= only check for grub2_mbr <-> isolinux partition_table */ int Xorriso_coordinate_system_area(struct XorrisO *xorriso, int sa_type, int options, char *cmd, int flag) { int old_type, old_options, new_options; static char *type_names[7] = { "MBR", "MIPS Big Endian Volume Header", "MIPS Little Endian Boot Block", "SUN Disk Label", "HP-PA PALO v4", "HP-PA PALO v5", "DEC Alpha SRM Boot Block"}; static int num_names = 7; old_type= (xorriso->system_area_options & 0xfc) >> 2; old_options= xorriso->system_area_options & 0x3c03; new_options= options & 0x3c03; if(((options & (1 << 14)) && (xorriso->system_area_options & 2)) || ((options & 2) && (xorriso->system_area_options & (1 << 14)))) goto reject; if(flag & 2) return(1); if((old_type != 0 || old_options != 0) && (old_type != sa_type || (old_options != 0 && old_options != new_options))){ reject:; sprintf(xorriso->info_text, "%s : First sector already occupied by %s", cmd, old_type < num_names ? type_names[old_type] : "other boot facility"); if(old_type == 0 && (old_options & 2)) strcat(xorriso->info_text, " for ISOLINUX isohybrid"); else if (old_type == 0 && (xorriso->system_area_options & (1 << 14))) { strcat(xorriso->info_text, " for GRUB2 patching"); if(old_type == 0 && (old_options & 1)) strcat(xorriso->info_text, " with partition table"); } else if(old_type == 0 && (old_options & 1)) strcat(xorriso->info_text, " for partition table"); Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); goto hint_revoke; } if(!(flag & 1)) xorriso->system_area_options= (xorriso->system_area_options & ~0x3cff) | ((sa_type << 2) & 0xfc) | (options & 0x3c03); return(1); hint_revoke:; if(old_type == 0) sprintf(xorriso->info_text, "Revokable by -boot_image any discard"); else if(old_type == 1 || old_type == 2) sprintf(xorriso->info_text, "Revokable by -boot_image any mips_discard"); else if(old_type == 3) sprintf(xorriso->info_text, "Revokable by -boot_image any sparc_discard"); if(old_type < 4) Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "HINT", 0); return(0); } int Xorriso_gpt_crc(struct XorrisO *xorriso, char *path, int flag) { int ret; char *buf = NULL; FILE *fp = NULL; uint32_t crc; Xorriso_alloc_meM(buf, char, 32 * 1024); ret= Xorriso_afile_fopen(xorriso, path, "rb", &fp, 0); if(ret <= 0) goto ex; ret= fread(buf, 1, 32 * 1024, fp); if(ret == 0) { strcpy(xorriso->info_text, "No bytes readable for GPT CRC from "); Text_shellsafe(path, xorriso->info_text, 1); Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 0); ret= 0; goto ex; } crc= iso_crc32_gpt((unsigned char *) buf, ret, 0); sprintf(xorriso->result_line, "0x%8.8x\n", (unsigned int) crc); Xorriso_result(xorriso, 0); ret= 1; ex:; if(fp != NULL && fp != stdin) fclose(fp); Xorriso_free_meM(buf); return(ret); } static int Xorriso_split_report_line(struct XorrisO *xorriso, char *line, int num_limit, char *name, char **contentpt, double *num, int *num_count, char **textpt, int flag) { int i; char *spt, *ept, *cpt; if(strlen(line) < 21) { undigestible: sprintf(xorriso->info_text, "Undigestible report line with -report_* mode cmd: '%s'", line); Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); return(0); } if(line[19] != ':') goto undigestible; strncpy(name, line, 20); name[20]= 0; for(spt= line + 20; *spt == ' '; spt++); *textpt= *contentpt= spt; *num_count= 0; for(i= 0; i < num_limit; i++) { /* Get word */ for(spt= *textpt; *spt == ' '; spt++); if(*spt == 0) { *textpt= spt; break; } for(ept= spt + 1; *ept != ' ' && *ept != 0; ept++); /* Look for decimal number */ if(ept - spt > 16) break; for(cpt= spt; cpt < ept; cpt++) if(*cpt < '0' || *cpt > '9') break; if(cpt != ept) break; sscanf(spt, "%lf", num + *num_count); (*num_count)++; *textpt= ept; } /* Set *textpt to next non-blank */ for(; **textpt == ' '; (*textpt)++); return(1); } int Xorriso_record_cmd_line(struct XorrisO *xorriso, char *buf, char **cmds, int *cmd_count, int flag) { int ret; if(flag & 1) { (*cmd_count)++; ret= 1; goto ex; } Xorriso_alloc_meM(cmds[*cmd_count], char, strlen(buf) + 1); strcpy(cmds[*cmd_count], buf); (*cmd_count)++; ret= 1; ex:; return(ret); } /* @param flag bit0= zeroize MBR partition table bit1= zeroize GPT bit2= zeroize APM bit30= Source imported_iso rather than local_fs */ int Xorriso_add_intvl_adr(struct XorrisO *xorriso, char *buf, uint64_t start_adr, uint64_t end_adr, char *suffix, int flag) { char *path; sprintf(buf + strlen(buf), "--interval:%s:%.f%s-%.f%s:", ((flag & (1 << 30)) ? "imported_iso" : "local_fs"), (double) start_adr, suffix, (double) end_adr, suffix); if(flag & 1) strcat(buf, "zero_mbrpt,"); if(flag & 2) strcat(buf, "zero_gpt,"); if(flag & 4) strcat(buf, "zero_apm,"); if(buf[strlen(buf) - 1] == ',') buf[strlen(buf) - 1] = 0; strcat(buf, ":"); path= xorriso->indev; if(strncmp(path, "stdio:", 6) == 0) path+= 6; Text_shellsafe(path, buf, 1); return(1); } 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, extract_size; char pltf[8], b[8], emul[8], boot_image_type[16]; char *path, *id_string, *sel_crit; int path_allocated; }; /* @param ptype 0= unknown, 1= gpt-basdat, 2=gpt-hfsplus, 3=EFI @param flag bit0= isohybrid */ static int Xorriso_register_eltorito_gpt(struct XorrisO *xorriso, struct elto_img_par *et_img, int ptype, int *efi_boot_part, int *first_efi, int flag) { if(flag & 1) { if(ptype == 1 || ptype == 3) et_img->do_gpt_basdat= ptype; else if(ptype == 2) et_img->do_gpt_hfsplus= 1; return(1); } else if(*first_efi && et_img->platform_id == 0xef) { if(*efi_boot_part <= 0) *efi_boot_part= 1; return(1); } if(et_img->platform_id == 0xef) *first_efi= 0; return(0); } /* @param ptype 0= unknown, 1= gpt-basdat, 2=gpt-hfsplus, 3=EFI @param flag bit0= isohybrid */ static int Xorriso_search_eltorito_path(struct XorrisO *xorriso, struct elto_img_par *et_imgs, int elto_count, char *path, int ptype, int *found, int *efi_boot_part, int flag) { int first_efi= 1, et_idx, ret; for(et_idx= 0; et_idx < elto_count; et_idx++) { if(strcmp(et_imgs[et_idx].path, path) != 0) continue; ret= Xorriso_register_eltorito_gpt(xorriso, et_imgs + et_idx, ptype, efi_boot_part, &first_efi, flag); if(ret > 0) break; } *found= et_idx; if(et_idx < elto_count) return(1); return(0); } static int Xorriso_search_eltorito_lba(struct XorrisO *xorriso, struct elto_img_par *et_imgs, int elto_count, unsigned int lba, int *found, int flag) { int et_idx; for(et_idx= 0; et_idx < elto_count; et_idx++) if(et_imgs[et_idx].lba == lba) break; *found= et_idx; if(et_idx < elto_count) return(1); return(0); } int Xorriso_highest_data_block(struct XorrisO *xorriso, uint32_t *high_block, int flag) { int ret; struct FindjoB *job= NULL; struct stat dir_stbuf; *high_block= 0; ret= Findjob_new(&job, "/", 0); if(ret <= 0) { Xorriso_no_findjob(xorriso, "[internal:last_data_file_block]", 0); {ret= -1; goto ex;} } Findjob_set_action_type(job, 58, 0, 0); ret= Xorriso_findi(xorriso, job, NULL, (off_t) 0, NULL, "/", &dir_stbuf, 0, 0); if(ret <= 0) goto ex; Findjob_get_last_data_file_block(job, high_block, 0); ex:; Findjob_destroy(&job, 0); return(ret); } /* Note: These macros use local variables of Xorriso_scan_report_lines() and Xorriso_make_boot_cut_out(). */ #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; \ } /* @param flag bit0= do not record but only count bit1= as_mkisofs bit2= no sorry messages */ int Xorriso_make_boot_cut_out(struct XorrisO *xorriso, unsigned long lba, unsigned long blocks, char **cmds, int *cmd_count, char *buf, int buf_size, char **path, int flag) { int ret= 0, i; char uuid_path[37 + 13]; IsoNode *node; /* Choose a path "hidden_boot_$UUID" which must not exist yet */ for(i = 0; i < 10; i++) { strcpy(uuid_path, "/hidden_boot_"); ret = Xorriso_make_guid(xorriso, uuid_path + 13, 1); if(ret <= 0) goto ex; ret= Xorriso_get_node_by_path(xorriso, uuid_path, NULL, &node, 1); if(ret <= 0) break; /* wait a short time just in case that Xorriso_make_guid() relies on time */ usleep(12345); } if(i >= 10) { if(!(flag & 5)) { sprintf(xorriso->info_text, "Composition of -cut_out command failed because no unused file path can be found"); Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); } ret= 0; goto ex; } /* Issue command or option for cutting out from indev */ strcpy(buf, "-cut_out "); if(strlen(buf) + strlen(xorriso->indev) * 5 + 1 > (unsigned long) buf_size) { buffer_overflow: if(!(flag & 5)) { sprintf(xorriso->info_text, "Composition of -cut_out command failed because it becomes too long"); Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); } ret= 0; goto ex; } Text_shellsafe(xorriso->indev, buf, 1); if(strlen(buf) + 1 + 11 + 1 + 11 + 1 + strlen(uuid_path) + 1 > (unsigned long) buf_size) goto buffer_overflow; sprintf(buf + strlen(buf), " %lus %lus %s", lba, blocks, uuid_path); Xorriso_record_cmd_linE /* Issue command or option for hiding cut out file */ if(flag & 2) { sprintf(buf, "-hide_iso_path on %s", uuid_path); Xorriso_record_cmd_linE } else { sprintf(buf, "-hide on %s --", uuid_path); Xorriso_record_cmd_linE } *path= strdup(uuid_path); if(*path == NULL) {ret= -1; goto ex;} ret= 1; ex:; return(ret); } /* @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, 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; int efi_boot_part= 0, full_sparc_part= 0, have_sparc_part= 0, fe_dummy= 1; int appended_as_gpt= 0, have_prep= 0, did_sysarea= 0, cared_for_apm= 0; int cared_for_sparc= 0, have_hfsplus= 0; int have_sysarea= 0, ptable_killer, imported_iso, have_alpha_ldr_path= 0; int have_protective_msdos= 0, part_like_isohybrid= 0, fresh_efi_boot_part; #ifdef Not_any_more_because_padding_is_now_after_partitions int appended_partition= 0; #endif int iso_mbr_part_type= -1, iso_gpt_part_idx= -1, buf_size; unsigned int prev_pltf= 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; off_t 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 mbr_parts_end= 0; off_t extract_size; struct FindjoB *job= NULL; struct stat dir_stbuf; IsoImage *image; char *volid, *crt, *mdt, *ext, *eft, uuid[17], *uuid_time; 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, start_block, num_blocks; uint64_t img_blocks= 0, iso_part_blocks; char *cpt, *npt, *ftext; int ftext_l, l; unsigned char bin_data[8]; uint64_t gpt_part_flags; int was_gpt_iso_bootable= 0, was_gpt_iso_not_ro= 0, bin_count; struct mbr_par { uint8_t ptype; uint64_t start_block; uint64_t block_count; int appended; int has_path; }; struct mbr_par *mbrpts= NULL; int mbr_count= 0; struct gpt_par { int ptype; /* 0= unknown, 1= gpt-basdat, 2=gpt-hfsplus, 3=EFI */ uint8_t type_guid[16]; int is_gap; int has_path; char *path; uint64_t start_block; uint64_t block_count; }; struct gpt_par *gpts= NULL; int gpt_count= 0; struct apm_par { int ptype; /* bit0= type Apple_HFS , bit1= name HFSPLUS_Hybrid */ char *path; }; struct apm_par *apms= NULL; int apm_count= 0; /* 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;} buf_size= 80 + 5 * SfileadrL; Xorriso_alloc_meM(buf, char, buf_size); Xorriso_alloc_meM(lines, char *, line_count); for(i= 0; i < et_line_count; i++) lines[i]= et_lines[i]; for(i= 0; i < sa_line_count; i++) lines[i + et_line_count]= sa_lines[i]; /* Pre-scan to establish context */ for(i= 0; i < line_count; i++) { ret= Xorriso_split_report_line(xorriso, lines[i], 8, name, &contentpt, num, &num_count, &textpt, 0); if(ret <= 0) goto ex; if(strcmp(name, "System area options:") == 0) { sscanf(contentpt, "%lx", &sa_options); } else if(strcmp(name, "System area summary:") == 0) { have_sysarea= 1; } else if(strcmp(name, "El Torito boot img :") == 0) { if(num[0] > elto_count) elto_count= num[0]; } else if(strcmp(name, "PReP boot partition:") == 0) { have_prep= 1; } else if(strcmp(name, "MBR partition :") == 0) { if(num[0] > mbr_count) mbr_count= num[0]; if(strcmp(textpt, "0x80 0x00 0 1") == 0) have_mbr_force_bootable= 1; } else if(strcmp(name, "GPT partition name :") == 0) { if(num[0] > gpt_count) gpt_count= num[0]; } else if(strcmp(name, "APM partition name :") == 0) { if(num[0] > apm_count) apm_count= num[0]; } else if(strcmp(name, "ISO image size/512 :") == 0) { img_blocks= num[0]; } else if(strcmp(name, "Partition offset :") == 0 && (num[0] == 0 || num[0] == 16)) { partition_offset= num[0]; } } ret= Xorriso_highest_data_block(xorriso, &high_block, 0); if(ret < 0) goto ex; if(ret == 0) high_block = img_blocks / 4 - 1; if(elto_count > 0) { Xorriso_alloc_meM(et_imgs, struct elto_img_par, elto_count); for(et_idx= 0; et_idx < elto_count; et_idx++) { et_imgs[et_idx].path= NULL; et_imgs[et_idx].path_allocated= 0; et_imgs[et_idx].ldsiz= -1; } Xorriso_alloc_meM(app_pseudo_paths, char *, elto_count); for(i= 0; i < elto_count; i++) app_pseudo_paths[i]= NULL; for(i= 0; i < elto_count; i++) { Xorriso_alloc_meM(app_pseudo_paths[i], char, 80); app_pseudo_paths[i][0]= 0; } } if(mbr_count > 0) Xorriso_alloc_meM(mbrpts, struct mbr_par, mbr_count); if(gpt_count > 0) { Xorriso_alloc_meM(gpts, struct gpt_par, gpt_count); for(gpt_idx= 0; gpt_idx < gpt_count; gpt_idx++) gpts[gpt_idx].path= NULL; } if(apm_count > 0) { Xorriso_alloc_meM(apms, struct apm_par, apm_count); for(i= 0; i < apm_count; i++) apms[i].path= NULL; } ptable_killer= (mbr_count > 0) | ((gpt_count > 0) << 1) | ((apm_count > 0) << 2); /* Report volume id and GRUB2 modification date */; ret= Xorriso_get_volume(xorriso, &image, 0); if(ret <= 0) goto ex; if(mkisofs) sprintf(buf, "-V "); else sprintf(buf, "-volid "); volid= (char *) un0(iso_image_get_volume_id(image)); Text_shellsafe(volid, buf, 1); Xorriso_record_cmd_linE ret= iso_image_get_pvd_times(image, &crt, &mdt, &ext, &eft); if(ret == ISO_SUCCESS) { uuid_time= crt; /* If Creation Time is bad and Modification Time is ok: use the latter */ ret= Decode_ecma119_format(&tm_erg, crt, 0); if(ret <= 0 || strlen(crt) != 16) { ret= Decode_ecma119_format(&tm_erg, mdt, 0); if(!(ret <= 0 || strlen(mdt) != 16)) uuid_time= mdt; } pad= 0; for(j= 0; j < 16; j++) { if(pad) { uuid[j]= '0'; } else if(uuid_time[j] == 0) { pad= 1; uuid[j]= '0'; } else if(uuid_time[j] < '0' || uuid_time[j] > '9') { uuid[j]= '0'; } else { uuid[j]= uuid_time[j]; } } uuid[16]= 0; ret= Decode_ecma119_format(&tm_erg, uuid, 0); if(!(ret <= 0 || strlen(uuid) != 16)) { if(mkisofs) sprintf(buf, "--modification-date="); else sprintf(buf, "-volume_date uuid "); Text_shellsafe(uuid, buf, 1); Xorriso_record_cmd_linE } } /* First pass: set up objects, record El Torito and info needed in 2nd pass */ for(i= 0; i < line_count; i++) { buf[0]= 0; ret= Xorriso_split_report_line(xorriso, lines[i], 8, name, &contentpt, num, &num_count, &textpt, 0); if(ret <= 0) goto ex; 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 */ idx= num[0] - 1; sscanf(contentpt, "%d %s %s %s %x %x %d %lu", &(et_imgs[idx].n), et_imgs[idx].pltf, et_imgs[idx].b, et_imgs[idx].emul, &(et_imgs[idx].ld_seg), &(et_imgs[idx].hdpt), &(et_imgs[idx].ldsiz), &(et_imgs[idx].lba)); if(strcmp(et_imgs[idx].pltf, "BIOS") == 0) et_imgs[idx].platform_id= 0; else if(strcmp(et_imgs[idx].pltf, "PPC") == 0) et_imgs[idx].platform_id= 1; else if(strcmp(et_imgs[idx].pltf, "Mac") == 0) et_imgs[idx].platform_id= 2; else if(strcmp(et_imgs[idx].pltf, "UEFI") == 0) et_imgs[idx].platform_id= 0xef; else sscanf(et_imgs[idx].pltf, "%x", &(et_imgs[idx].platform_id)); strcpy(et_imgs[idx].boot_image_type, "any"); et_imgs[idx].boot_info_table= 0; et_imgs[idx].grub2_boot_info= 0; 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 + (off_t) 2047) / (off_t) 2048; if(extract_size > (off_t) 0xffffffff) { if(!(flag & 5)) { sprintf(xorriso->info_text, "Boot image size exceeds limit of 32-bit block count: "); Text_shellsafe(et_imgs[idx].path, xorriso->info_text, 1); Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); } continue; } if(extract_size > (off_t) 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; if(strstr(textpt, "boot-info-table") != NULL) et_imgs[idx].boot_info_table= 1; if(strstr(textpt, "isohybrid-suitable") != NULL) strcpy(et_imgs[idx].boot_image_type, "isolinux"); if(strstr(textpt, "grub2-boot-info") != NULL) { strcpy(et_imgs[idx].boot_image_type, "grub"); et_imgs[idx].grub2_boot_info= 1; } } else if(strcmp(name, "El Torito id string:") == 0) { idx= num[0] - 1; et_imgs[idx].id_string= textpt; } else if(strcmp(name, "El Torito sel crit :") == 0) { idx= num[0] - 1; et_imgs[idx].sel_crit= textpt; } else if(strcmp(name, "System area summary:") == 0) { if(strstr(textpt, "protective-msdos-label") != NULL) have_protective_msdos= 1; } else if(strcmp(name, "MBR partition :") == 0) { sscanf(contentpt, "%lu 0x%lx 0x%lx %lu %lu", &partno, &part_status, &part_type, &mbr_start_block, &mbr_num_blocks); idx= partno - 1; mbrpts[idx].ptype= part_type; 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) { idx= num[0] - 1; mbrpts[idx].has_path= 1; } else if(strcmp(name, "GPT lba range :") == 0) { gpt_bheader_block= num[2]; } else if(strcmp(name, "GPT type GUID :") == 0) { idx= num[0] - 1; if(strcmp(textpt, "a2a0d0ebe5b9334487c068b6b72699c7") == 0) gpts[idx].ptype= 1; /* Basic data */ else if(strcmp(textpt, "005346480000aa11aa1100306543ecac") == 0) gpts[idx].ptype= 2; /* HFS+ */ else if(strcmp(textpt, "28732ac11ff8d211ba4b00a0c93ec93b") == 0) gpts[idx].ptype= 3; /* EFI System Partition */ else gpts[idx].ptype= 0; Xorriso_parse_guid(xorriso, textpt, gpts[idx].type_guid, 1); } else if(strcmp(name, "GPT start and size :") == 0) { idx= num[0] - 1; if(num[2] > 0) appended_as_gpt= 1; start_block= gpts[idx].start_block= num[1]; num_blocks= gpts[idx].block_count= num[2]; if(start_block == partition_offset * 4 && (start_block + num_blocks) >= high_block * 4 && iso_gpt_part_idx < 0) iso_gpt_part_idx= idx; } else if(strcmp(name, "GPT partition path :") == 0) { idx= num[0] - 1; gpts[idx].has_path= 1; gpts[idx].path= textpt; } else if(strcmp(name, "GPT partition name :") == 0) { idx= num[0] - 1; if(strstr(contentpt, " 470061007000") != NULL) /* "Gap"... */ gpts[idx].is_gap= 1; } else if(strcmp(name, "APM partition name :") == 0) { idx= num[0] - 1; if(strcmp(textpt, "HFSPLUS_Hybrid") == 0) apms[idx].ptype|= 2; } else if(strcmp(name, "APM partition type :") == 0) { idx= num[0] - 1; if(strcmp(textpt, "Apple_HFS") == 0) apms[idx].ptype|= 1; } else if(strcmp(name, "APM partition path :") == 0) { idx= num[0] - 1; apms[idx].path= textpt; } else if(strcmp(name, "DEC Alpha ldr path :") == 0) { have_alpha_ldr_path= 1; } } if(appended_as_gpt && !have_protective_msdos) { /* Check if really a pure GPT or a nearly pure mbr-force-bootable GPT */ if(mbr_count != 1 && !(mbr_count == 2 && have_mbr_force_bootable)) { appended_as_gpt= 0; } else if(mbrpts[0].ptype != 0xee || mbrpts[0].start_block != 1) { appended_as_gpt= 0; } else if(gpt_bheader_block != mbrpts[0].block_count) { appended_as_gpt= 0; } } iso_part_blocks= img_blocks; for(mbr_idx = 0; mbr_idx < mbr_count; mbr_idx++) { if(mbrpts[mbr_idx].start_block == partition_offset * 4) { iso_part_blocks= mbrpts[mbr_idx].block_count + partition_offset * 4; break; } } /* Second pass: scan for System Area info */ for(i= 0; i < line_count; i++) { buf[0]= 0; ret= Xorriso_split_report_line(xorriso, lines[i], 8, name, &contentpt, num, &num_count, &textpt, 0); if(ret <= 0) goto ex; if(strcmp(name, "System area options:") == 0) { if((sa_options & 0x3c00) == 0x0400) { if(mkisofs) sprintf(buf, "-chrp-boot-part "); else sprintf(buf, "-boot_image any chrp_boot_part=on "); Xorriso_record_cmd_linE buf[0]= 0; ret= Xorriso_assess_written_features(xorriso, mkisofs ? "as_mkisofs" : "cmd", 1); if(ret > 0) { ftext= xorriso->result_line; ftext_l= strlen(ftext); for(cpt= ftext ; cpt - ftext < ftext_l ; cpt+= l + 1) { npt= strchr(cpt, '\n'); if(npt == NULL) l= strlen(cpt); else l= npt - cpt; cpt[l]= 0; /* Only forward relaxations of ISO 9660 defaults, plus no RR */ if(mkisofs) { if(strcmp(cpt, "-iso-level 2") != 0 && strcmp(cpt, "-iso-level 3") != 0 && strcmp(cpt, "--norock") != 0 && strncmp(cpt, "-untranslated_name_len", 22) != 0 && strcmp(cpt, "-N") != 0 && strcmp(cpt, "-D") != 0 && strcmp(cpt, "-U") != 0 && strcmp(cpt, "-max-iso9660-filenames") != 0 && strcmp(cpt, "-d") != 0 && strcmp(cpt, "-allow-lowercase") != 0) continue; } else { /* (Do not forward iso_9660_level because 3 is default and the user possibly had reasons to lower it) */ if(strcmp(cpt, "-rockridge off") != 0 && strncmp(cpt, "-compliance untranslated_name_len=", 34) != 0 && strcmp(cpt, "-compliance omit_version_off:only_iso_version") != 0 && strcmp(cpt, "-compliance omit_version:only_iso_version_off") != 0 && strcmp(cpt, "-compliance deep_paths") != 0 && strcmp(cpt, "-compliance long_paths") != 0 && strcmp(cpt, "-compliance full_ascii") != 0 && strcmp(cpt, "-compliance long_names") != 0 && strncmp(cpt, "-compliance no_force_dots:", 26) != 0 && strcmp(cpt, "-compliance lowercase") != 0) continue; if(strcmp(cpt, "-compliance untranslated_name_len=0") == 0) continue; } if(strncmp(cpt, "-compliance untranslated_name_len=", 34) == 0) { /* Better allow the maximum if it is reported as non-0 */ strcpy(buf, "-compliance untranslated_name_len=96"); } else { strcpy(buf, cpt); } Xorriso_record_cmd_linE } } } } else if(strcmp(name, "System area summary:") == 0) { if(strstr(textpt, "isohybrid") != NULL) { isohybrid= 1; if(mkisofs) sprintf(buf, "-isohybrid-mbr "); else sprintf(buf, "-boot_image isolinux system_area="); 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) { if(mkisofs) sprintf(buf, "--grub2-mbr "); else sprintf(buf, "-boot_image grub grub2_mbr="); 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) { if(mkisofs) sprintf(buf, "--protective-msdos-label"); else sprintf(buf, "-boot_image any partition_table=on"); Xorriso_record_cmd_linE } if(strstr(textpt, "cyl-align-off") != NULL) { if(mkisofs) sprintf(buf, "-partition_cyl_align off"); else sprintf(buf, "-boot_image any partition_cyl_align=off"); } else if(strstr(textpt, "cyl-align-all") != NULL) { if(mkisofs) sprintf(buf, "-partition_cyl_align all"); else sprintf(buf, "-boot_image any partition_cyl_align=all"); } else if(strstr(textpt, "cyl-align-") != NULL) { if(mkisofs) sprintf(buf, "-partition_cyl_align on"); else sprintf(buf, "-boot_image any partition_cyl_align=on"); } else buf[0]= 0; } else if(strcmp(name, "Partition offset :") == 0 && (num[0] == 0 || num[0] == 16)) { if(mkisofs) sprintf(buf, "-partition_offset %.f", num[0]); else sprintf(buf, "-boot_image any partition_offset=%.f", num[0]); } else if(strcmp(name, "MBR heads per cyl :") == 0 && (num[0] > 0 && num[0] <= 255)) { if(mkisofs) sprintf(buf, "-partition_hd_cyl %.f", num[0]); else sprintf(buf, "-boot_image any partition_hd_cyl=%.f", num[0]); } else if(strcmp(name, "MBR secs per head :") == 0 && (num[0] > 0 && num[0] <= 63)) { if(mkisofs) sprintf(buf, "-partition_sec_hd %.f", num[0]); else sprintf(buf, "-boot_image any partition_sec_hd=%.f", num[0]); } else if(strcmp(name, "MBR partition :") == 0) { sscanf(contentpt, "%lu 0x%lx 0x%lx %lu %lu", &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) 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; #ifdef Not_any_more_because_padding_is_now_after_partitions appended_partition= 1; #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) 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 } if(mkisofs) sprintf(buf, "--mbr-force-bootable"); else sprintf(buf, "-boot_image any mbr_force_bootable=on"); } } else if(strcmp(name, "MBR partition path :") == 0) { idx= num[0] - 1; if(mbrpts[idx].ptype == 0x41) { sprintf(xorriso->info_text, "Cannot make proposal to mark PReP partition by data file: "); Text_shellsafe(textpt, xorriso->info_text, 1); if(!(flag & 5)) Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); continue; } ptype= 0; if(mbrpts[idx].ptype == 0xef) ptype= 3; ret= Xorriso_search_eltorito_path(xorriso, et_imgs, elto_count, textpt, ptype, &et_idx, &efi_boot_part, !!isohybrid); if(ret <= 0) { 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 & 5)) Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); } else { for(gpt_idx= 0; gpt_idx < gpt_count; gpt_idx++) { if(gpts[gpt_idx].path != NULL) if(strcmp(gpts[gpt_idx].path, textpt) == 0) break; } if(gpt_idx >= gpt_count) { 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 & 5)) Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); } } } else if(strcmp(name, "GPT disk GUID :") == 0) { /* >>> ??? need command to set disk GUID */; } else if(strcmp(name, "GPT partition name :") == 0) { /* >>> ??? need command to set partition name for partition number */; } else if(strcmp(name, "GPT partition GUID :") == 0) { /* >>> ??? need command to set partition GUID for partition number */; } else if(strcmp(name, "GPT partition flags:") == 0) { /* >>> check whether 0x100000000000000[15] . Else: complain */; cpt= strstr(contentpt, "0x"); if(cpt != NULL) { ret= Hex_to_bin(cpt + 2, 8, &bin_count, bin_data, 0); if(ret > 0) { /* convert big-endian bin_data to local endianness */ gpt_part_flags= 0; for(gpt_idx= 0; gpt_idx < bin_count; gpt_idx++) gpt_part_flags|= (((uint64_t) bin_data[gpt_idx]) << (8 * (bin_count - 1 - gpt_idx))); if((gpt_part_flags & 4) && !was_gpt_iso_bootable) { was_gpt_iso_bootable= 1; if(buf[0]) { Xorriso_record_cmd_linE } if(mkisofs) sprintf(buf, "--gpt-iso-bootable"); else sprintf(buf, "-boot_image any gpt_iso_bootable=on"); } if(num_count > 0 && num[0] == 1 && (!(gpt_part_flags & (((uint64_t) 1) << 60))) && !was_gpt_iso_not_ro) { was_gpt_iso_not_ro= 1; if(buf[0]) { Xorriso_record_cmd_linE } if(mkisofs) sprintf(buf, "--gpt-iso-not-ro"); else sprintf(buf, "-boot_image any gpt_iso_not_ro=on"); } } } } else if(strcmp(name, "GPT partition path :") == 0) { idx= num[0] - 1; ret= Xorriso_search_eltorito_path(xorriso, et_imgs, elto_count, textpt, gpts[idx].ptype, &et_idx, &efi_boot_part, !!isohybrid); if(ret <= 0) { sprintf(xorriso->info_text, "Cannot make proposal to mark data file as GPT partition : "); Text_shellsafe(textpt, xorriso->info_text, 1); if(!(flag & 5)) Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); } } else if(strcmp(name, "GPT start and size :") == 0) { idx= num[0] - 1; if(gpts[idx].ptype == 3) part_type= 0xef; else part_type= 0xcd; fresh_efi_boot_part= 0; if(high_block * 4 < num[1] && num[2] > 0 && !gpts[idx].is_gap) { for(mbr_idx = 0; mbr_idx < mbr_count; mbr_idx++) { if(mbrpts[mbr_idx].start_block == num[1]) { if(mbrpts[mbr_idx].block_count != num[2] && !(flag & 1)) { sprintf(xorriso->info_text, "GPT partition %d has same start block as MBR partition %d but different block count (%.f <> %.f)", idx + 1, mbr_idx + 1, num[2], (double) mbrpts[mbr_idx].block_count); Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 0); } break; } } if(mbr_idx >= mbr_count) { if(appended_as_gpt == 1) { appended_as_gpt= 2; Xorriso__format_guid(gpts[idx].type_guid, part_type_text, 0); } else { sprintf(part_type_text, "0x%lx", part_type); } sprintf(buf, "-append_partition %d %s ", idx + 1, part_type_text); Xorriso_add_intvl_adr(xorriso, buf, (uint64_t) num[1], (uint64_t) (num[1] + num[2] - 1.0), "d", imported_iso); Xorriso_record_cmd_linE #ifdef Not_any_more_because_padding_is_now_after_partitions appended_partition= 1; #endif } } else if(gpts[idx].ptype == 3 && gpts[idx].has_path == 0 && img_blocks >= num[1] + num[2] && !efi_boot_part) { if(mkisofs) sprintf(buf, "-efi-boot-part "); else sprintf(buf, "-boot_image any efi_boot_part="); Xorriso_add_intvl_adr(xorriso, buf, (uint64_t) num[1], (uint64_t) (num[1] + num[2] - 1.0), "d", imported_iso); efi_boot_part= 2; fresh_efi_boot_part= 1; Xorriso_record_cmd_linE } if(!fresh_efi_boot_part) { /* Check for isohybri-ish MBR and GPT mix */ if((mbr_count == 1 || (mbr_count == 2 && have_mbr_force_bootable)) && mbrpts[0].ptype == 0xee && have_protective_msdos) { /* real GPT (+/- mbr_force_bootable) is not -part_like_isohybrid */ ret= 0; } else { ret= Xorriso_search_eltorito_lba(xorriso, et_imgs, elto_count, (unsigned int) (num[1] / 4.0), &et_idx, 0); } if(ret > 0) { if(!(isohybrid || et_imgs[et_idx].do_gpt_basdat || et_imgs[et_idx].do_gpt_hfsplus || part_like_isohybrid)) { if(mkisofs) sprintf(buf, "-part_like_isohybrid"); else sprintf(buf, "-boot_image any part_like_isohybrid=on"); Xorriso_record_cmd_linE part_like_isohybrid= 1; appended_as_gpt= 0; } /* mark el torito for -isohybrid-gpt-... */ Xorriso_register_eltorito_gpt(xorriso, et_imgs + et_idx, gpts[idx].ptype, &efi_boot_part, &fe_dummy, 1); if(efi_boot_part == 1) { /* -isohybrid-gpt- substitutes for -efi-boot-part --efi-boot-image */ efi_boot_part= 2; } } } 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) { if(mkisofs) sprintf(buf, "-apm-block-size %.f", num[0]); else sprintf(buf, "-boot_image any apm_block_size=%.f", num[0]); } else if(strcmp(name, "APM partition name :") == 0) { /* >>> ??? need command to set APM partition name for partition number */; } else if(strcmp(name, "APM partition path :") == 0) { idx= num[0] - 1; /* Check El Torito EFI boot images for same path */ for(et_idx= 0; isohybrid && et_idx < elto_count; et_idx++) if(strcmp(et_imgs[et_idx].path, textpt) == 0) { if(apms[idx].ptype == 1) { et_imgs[et_idx].do_apm_hfsplus= 1; cared_for_apm= 1; } break; } } else if(strcmp(name, "APM start and size :") == 0) { idx= num[0] - 1; if(num[1] + num[2] <= img_blocks && apms[idx].ptype == 3 && apms[idx].path == NULL && !have_hfsplus) { /* >>> HFS+ magic number */; /* >>> Read byte 1024 and 1025 after partition start Must be {'H', '+'} (0x482b big endian) */; /* ??? >>> Do this recognition in libisofs ? */ if(mkisofs) sprintf(buf, "-hfsplus"); else sprintf(buf, "-hfsplus on"); Xorriso_record_cmd_linE /* Report commands for blessings and creator-type */ ret= Findjob_new(&job, "/", 0); if(ret <= 0) { Xorriso_no_findjob(xorriso, "xorriso", 0); {ret= -1; goto ex;} } Findjob_set_action_target(job, 53, NULL, 0); xorriso->show_hfs_cmd_count= *cmd_count; xorriso->show_hfs_cmds= cmds; xorriso->show_hfs_cmd_flag= (flag & 1) | ((!!mkisofs) << 1); ret= Xorriso_findi(xorriso, job, NULL, (off_t) 0, NULL, "/", &dir_stbuf, 0, 0); *cmd_count= xorriso->show_hfs_cmd_count; if(ret <= 0) goto ex; have_hfsplus= 1; cared_for_apm= 1; } } else if(strcmp(name, "MIPS-BE boot path :") == 0) { if(mkisofs) sprintf(buf, "-mips-boot "); else sprintf(buf, "-boot_image any mips_path="); Text_shellsafe(textpt, buf, 1); } else if(strcmp(name, "MIPS-LE boot path :") == 0) { if(mkisofs) sprintf(buf, "-mipsel-boot "); else sprintf(buf, "-boot_image any mipsel_path="); Text_shellsafe(textpt, buf, 1); } else if(strcmp(name, "SUN SPARC disklabel:") == 0) { if(mkisofs) sprintf(buf, "-sparc-label "); else sprintf(buf, "-boot_image any sparc_label="); Text_shellsafe(textpt, buf, 1); } else if(strcmp(name, "SPARC GRUB2 path :") == 0) { if(mkisofs) { sprintf(buf, "-B ,"); Xorriso_record_cmd_linE sprintf(buf, "--grub2-sparc-core "); } else sprintf(buf, "-boot_image grub grub2_sparc_core="); Text_shellsafe(textpt, buf, 1); cared_for_sparc= 1; } else if(strcmp(name, "SUN SPARC partition:") == 0) { have_sparc_part= 1; 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, &mbr_num_blocks); if(partno > 0 && partno < 9 && start_cyl == 0 && 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)); } else if(strcmp(name, "PALO header version:") == 0) { if(mkisofs) sprintf(buf, "-hppa-hdrversion %.f", num[0]); else sprintf(buf, "-boot_image any hppa_hdrversion=%.f", num[0]); } else if(strcmp(name, "HP-PA cmdline :") == 0) { if(mkisofs) sprintf(buf, "-hppa-cmdline "); else sprintf(buf, "-boot_image any hppa_cmdline="); Text_shellsafe(textpt, buf, 1); } else if(strcmp(name, "HP-PA 32-bit kernel:") == 0) { if(mkisofs) sprintf(buf, "-hppa-kernel-32 "); else sprintf(buf, "-boot_image any hppa_kernel_32="); Text_shellsafe(textpt, buf, 1); } else if(strcmp(name, "HP-PA 64-bit kernel:") == 0) { if(mkisofs) sprintf(buf, "-hppa-kernel-64 "); else sprintf(buf, "-boot_image any hppa_kernel_64="); Text_shellsafe(textpt, buf, 1); } else if(strcmp(name, "HP-PA ramdisk :") == 0) { if(mkisofs) sprintf(buf, "-hppa-ramdisk "); else sprintf(buf, "-boot_image any hppa_ramdisk="); Text_shellsafe(textpt, buf, 1); } else if(strcmp(name, "HP-PA bootloader :") == 0) { if(mkisofs) sprintf(buf, "-hppa-bootloader "); else sprintf(buf, "-boot_image any hppa_bootloader="); Text_shellsafe(textpt, buf, 1); } else if(strcmp(name, "DEC Alpha ldr adr :") == 0) { 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"); if(!(flag & 5)) Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); } } else if(strcmp(name, "DEC Alpha ldr path :") == 0) { if(mkisofs) sprintf(buf, "-alpha-boot "); else sprintf(buf, "-boot_image any alpha_boot="); Text_shellsafe(textpt, buf, 1); } if(buf[0]) Xorriso_record_cmd_linE } if(appended_as_gpt == 2) { if(mkisofs) sprintf(buf, "-appended_part_as_gpt"); else sprintf(buf, "-boot_image any appended_part_as=gpt"); Xorriso_record_cmd_linE } if(have_sparc_part) { if(full_sparc_part == 255) { if(mkisofs) { sprintf(buf, "-G "); Xorriso_add_intvl_adr(xorriso, buf, (uint64_t) 0, (uint64_t) 15, "s", imported_iso); Xorriso_record_cmd_linE did_sysarea= 1; sprintf(buf, "-B ..."); Xorriso_record_cmd_linE } else { sprintf(buf, "-boot_image any system_area="); Xorriso_add_intvl_adr(xorriso, buf, (uint64_t) 0, (uint64_t) 15, "s", imported_iso); Xorriso_record_cmd_linE did_sysarea= 1; for(i= 2; i <= 8; i++) { sprintf(buf, "-append_partition %d 0x00 .", i); Xorriso_record_cmd_linE } } cared_for_sparc= 1; } else if(!cared_for_sparc) { sprintf(xorriso->info_text, "Cannot enable SUN Disk Label because of non-trivial partition layout"); if(!(flag & 5)) Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); } } if(have_sysarea && !did_sysarea) { /* Zeroize old partition tables from -indev */ if(mkisofs) sprintf(buf, "-G "); else sprintf(buf, "-boot_image any system_area="); Xorriso_add_intvl_adr(xorriso, buf, (uint64_t) 0, (uint64_t) 15, "s", imported_iso | ptable_killer); 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", (unsigned int) iso_mbr_part_type); else sprintf(buf, "-boot_image any iso_mbr_part_type=0x%2.2x", (unsigned int) iso_mbr_part_type); Xorriso_record_cmd_linE } else if(iso_gpt_part_idx >= 0) { if(mkisofs) sprintf(buf, "-iso_mbr_part_type "); else sprintf(buf, "-boot_image any iso_mbr_part_type="); Xorriso__format_guid(gpts[iso_gpt_part_idx].type_guid, buf + strlen(buf), 0); Xorriso_record_cmd_linE } /* Issue commands related to El Torito */ if(elto_count <= 0) goto after_el_torito; if(efi_boot_part == 1) { if(mkisofs) sprintf(buf, "-efi-boot-part --efi-boot-image"); else sprintf(buf, "-boot_image any efi_boot_part=--efi-boot-image"); Xorriso_record_cmd_linE } if(cat_path[0]) { if(mkisofs) sprintf(buf, "-c "); else sprintf(buf, "-boot_image any cat_path="); Text_shellsafe(cat_path, buf, 1); } else { if(mkisofs) sprintf(buf, "--boot-catalog-hide"); else sprintf(buf, "-boot_image any cat_hidden=on"); } 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 > (off_t) 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 & 5)) { sprintf(xorriso->info_text, "Cannot enable EL Torito boot image #%d because its Load Segment is neither 0x0 nor 0x7c0", idx + 1); Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); } continue; } if(idx > 0) { if(mkisofs) sprintf(buf, "-eltorito-alt-boot"); else sprintf(buf, "-boot_image any next"); Xorriso_record_cmd_linE } if(et_imgs[idx].path[0] == 0) { /* Check whether appended partition */; for(i= 0; i < mbr_count; i++) if((mbrpts[i].appended || !mbrpts[i].has_path) && mbrpts[i].start_block == ((uint64_t) et_imgs[idx].lba) * 4 && (mbrpts[i].block_count == (uint64_t) et_imgs[idx].ldsiz || et_imgs[idx].ldsiz == 0 || et_imgs[idx].ldsiz == 1)) break; if (i < mbr_count) { if(!mbrpts[i].appended) { mbrpts[i].appended= 1; if(!appended_as_gpt) { sprintf(buf, "-append_partition %lu 0x%lx ", (unsigned long) i + 1, (unsigned long) mbrpts[i].ptype); Xorriso_add_intvl_adr(xorriso, buf, (uint64_t) mbrpts[i].start_block, ((uint64_t) mbrpts[i].start_block) + mbrpts[i].block_count - 1, "d", imported_iso); Xorriso_record_cmd_linE #ifdef Not_any_more_because_padding_is_now_after_partitions appended_partition= 1; #endif buf[0]= 0; } } sprintf(app_pseudo_paths[idx], "--interval:appended_partition_%d_start_%lus_size_%lud:all::", i + 1, (unsigned long) et_imgs[idx].lba, (unsigned long) mbrpts[i].block_count); et_imgs[idx].path= app_pseudo_paths[idx]; } if (et_imgs[idx].path[0] == 0 && efi_boot_part != 2) { for(i= 0; i < gpt_count; i++) { if((have_protective_msdos || appended_as_gpt) && ( gpts[i].start_block == ((uint64_t) et_imgs[idx].lba) * 4 && (gpts[i].block_count == (uint64_t) et_imgs[idx].ldsiz || et_imgs[idx].ldsiz == 0 || et_imgs[idx].ldsiz == 1))) break; } if (i < gpt_count) { sprintf(app_pseudo_paths[idx], "--interval:appended_partition_%d_start_%lus_size_%lud:all::", i + 1, (unsigned long) et_imgs[idx].lba, (unsigned long) gpts[i].block_count); et_imgs[idx].path= app_pseudo_paths[idx]; } } if (et_imgs[idx].path[0] == 0 && et_imgs[idx].extract_size > 0) { ret= Xorriso_make_boot_cut_out(xorriso, et_imgs[idx].lba, et_imgs[idx].extract_size, cmds, cmd_count, buf, buf_size, &(et_imgs[idx].path), flag & 7); if(ret <= 0) { if(!(flag & 5)) { sprintf(xorriso->info_text, "Cannot enable hidden EL Torito boot image #%d by a -cut_out command", idx + 1); Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); } buf[0]= 0; continue; } et_imgs[idx].path_allocated= 1; } 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); Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0); } buf[0]= 0; continue; } } if(et_imgs[idx].platform_id != 0xef) { if(mkisofs) { if(prev_pltf != et_imgs[idx].platform_id) { sprintf(buf, "-eltorito-platform 0x%2.2x", et_imgs[idx].platform_id); Xorriso_record_cmd_linE } prev_pltf= et_imgs[idx].platform_id; sprintf(buf, "-b "); } else { sprintf(buf, "-boot_image %s bin_path=", et_imgs[idx].boot_image_type); } } else { if(mkisofs) sprintf(buf, "-e "); else sprintf(buf, "-boot_image %s efi_path=", et_imgs[idx].boot_image_type); } Text_shellsafe(et_imgs[idx].path, buf, 1); Xorriso_record_cmd_linE if(!mkisofs) { sprintf(buf, "-boot_image any platform_id=0x%2.2x", et_imgs[idx].platform_id); Xorriso_record_cmd_linE } if(strcmp(et_imgs[idx].emul, "none") == 0) { if(mkisofs) sprintf(buf, "-no-emul-boot"); else sprintf(buf, "-boot_image any emul_type=no_emulation"); } else if(strcmp(et_imgs[idx].emul, "hd") == 0) { if(mkisofs) sprintf(buf, "-hard-disk-boot"); else sprintf(buf, "-boot_image any emul_type=hard_disk"); } else { if(mkisofs) buf[0]= 0; else sprintf(buf, "-boot_image any emul_type=diskette"); } if(buf[0]) Xorriso_record_cmd_linE if(et_imgs[idx].ldsiz >= 0 && et_imgs[idx].platform_id != 0xef) { if(mkisofs) sprintf(buf, "-boot-load-size %d", et_imgs[idx].ldsiz); else sprintf(buf, "-boot_image any load_size=%d", et_imgs[idx].ldsiz * 512); Xorriso_record_cmd_linE } if(et_imgs[idx].boot_info_table) { if(mkisofs) sprintf(buf, "-boot-info-table"); else sprintf(buf, "-boot_image any boot_info_table=on"); Xorriso_record_cmd_linE } if(et_imgs[idx].grub2_boot_info) { if(mkisofs) sprintf(buf, "--grub2-boot-info"); else sprintf(buf, "-boot_image grub grub2_boot_info=on"); Xorriso_record_cmd_linE } if(et_imgs[idx].id_string[0] != 0) { if(mkisofs) sprintf(buf, "-eltorito-id "); else sprintf(buf, "-boot_image any id_string="); Text_shellsafe(et_imgs[idx].id_string, buf, 1); Xorriso_record_cmd_linE } if(et_imgs[idx].sel_crit[0] != 0) { if(mkisofs) sprintf(buf, "-eltorito-selcrit "); else sprintf(buf, "-boot_image any sel_crit="); Text_shellsafe(et_imgs[idx].sel_crit, buf, 1); Xorriso_record_cmd_linE } if(et_imgs[idx].do_gpt_basdat && !(et_imgs[idx].do_gpt_basdat == 3 && strstr(et_imgs[idx].path, "--interval:appended_partition_") == et_imgs[idx].path)) { /* (not with appended EFI partition) */ if(mkisofs) sprintf(buf, "-isohybrid-gpt-basdat"); else sprintf(buf, "-boot_image isolinux partition_entry=gpt_basdat"); Xorriso_record_cmd_linE } if(et_imgs[idx].do_gpt_hfsplus) { if(mkisofs) sprintf(buf, "-isohybrid-gpt-hfsplus"); else sprintf(buf, "-boot_image isolinux partition_entry=gpt_hfsplus"); Xorriso_record_cmd_linE } if(et_imgs[idx].do_apm_hfsplus) { if(mkisofs) sprintf(buf, "-isohybrid-apm-hfsplus"); else sprintf(buf, "-boot_image isolinux partition_entry=apm_hfsplus"); Xorriso_record_cmd_linE } } after_el_torito: 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); } #ifdef Not_any_more_because_padding_is_now_after_partitions if(appended_partition) { if(mkisofs) sprintf(buf, "-no-pad"); else sprintf(buf, "-padding 0"); Xorriso_record_cmd_linE } #endif /* Not_any_more_because_padding_is_now_after_partitions */ ret= 1; ex: xorriso->show_hfs_cmds= NULL; Findjob_destroy(&job, 0); Xorriso_free_meM(apms); Xorriso_free_meM(gpts); Xorriso_free_meM(mbrpts); if(app_pseudo_paths != NULL) { for(i= 0; i < elto_count; i++) if(app_pseudo_paths[i] != NULL) Xorriso_free_meM(app_pseudo_paths[i]); Xorriso_free_meM(app_pseudo_paths); } for(et_idx= 0; et_idx < elto_count; et_idx++) if(et_imgs[et_idx].path_allocated) Xorriso_free_meM(et_imgs[et_idx].path); Xorriso_free_meM(et_imgs); Xorriso_free_meM(lines); Xorriso_free_meM(buf); 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 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, char ***boot_imgs, int *boot_img_count, int flag) { int ret= 0, i; if(flag & (1 << 15)) {ret= 1; goto ex;} *cmds= NULL; *cmd_count= 0; /* Count commands */ ret= Xorriso_scan_report_lines(xorriso, et_lines, et_line_count, sa_lines, sa_line_count, *cmds, cmd_count, *boot_imgs, boot_img_count, 1 | (flag & 6)); if(ret <= 0) goto ex; if(*cmd_count <= 0 && *boot_img_count <= 0) {ret= 2; goto ex;} 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, *boot_imgs, boot_img_count, flag & 6); if(ret <= 0) goto ex; ret= 1; ex: if(ret <= 0 || (flag & (1 << 15))) { if(*cmds != NULL) { for(i= 0; i < *cmd_count; i++) if((*cmds)[i] != NULL) Xorriso_free_meM((*cmds)[i]); 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); } static void Xorriso_report_lines(struct XorrisO *xorriso, char **lines, int line_count) { int i; for(i = 0; i < line_count ; i++) { sprintf(xorriso->result_line, "%s\n", lines[i]); Xorriso_result(xorriso,0); } } /* @param flag bit0= report El Torito rather than System Area bit1= with form "cmd" do not report but rather execute */ 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, 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; if(strcmp(form, "cmd") == 0 || strcmp(form, "as_mkisofs") == 0 || (flag & 2)) do_cmd= 1; if(strcmp(form, "as_mkisofs") == 0) as_mkisofs= 1; if(strcmp(form, "help") == 0) { if(flag & 1) ret= iso_image_report_el_torito(NULL, &et_lines, &et_line_count, 1); else ret= iso_image_report_system_area(NULL, &sa_lines, &sa_line_count, 1); if(ret <= 0) goto ex; sprintf(xorriso->result_line, "------------------------------------------------------------------------------\n"); Xorriso_result(xorriso, 0); if(flag & 1) sprintf(xorriso->result_line, "With -report_el_torito \"plain\":\n"); else sprintf(xorriso->result_line, "With -report_system_area \"plain\":\n"); Xorriso_result(xorriso, 0); sprintf(xorriso->result_line, "------------------------------------------------------------------------------\n"); Xorriso_result(xorriso, 0); sprintf(xorriso->result_line, "\n"); Xorriso_result(xorriso, 0); } else if(strcmp(form, "") == 0 || strcmp(form, "plain") == 0 || do_cmd) { ret= Xorriso_get_volume(xorriso, &image, 0); if(ret <= 0) goto ex; if(do_cmd || (flag & 1)) ret= iso_image_report_el_torito(image, &et_lines, &et_line_count, 0); if(ret < 0) goto ex; if(do_cmd || !(flag & 1)) ret= iso_image_report_system_area(image, &sa_lines, &sa_line_count, 0); if(ret < 0) goto ex; 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; } else if(strcmp(form, "make_guid") == 0 && !(flag & 1)) { ret= Xorriso_make_guid(xorriso, xorriso->result_line, 0); if(ret < 0) goto ex; strcat(xorriso->result_line, "\n"); Xorriso_result(xorriso,0); goto ex; } else if(strcmp(form, "gpt_disk_guid") == 0 && !(flag & 1)) { ret= Xorriso_get_volume(xorriso, &image, 0); if(ret <= 0) goto ex; ret= iso_image_report_system_area(image, &sa_lines, &sa_line_count, 0); if(ret <= 0) goto ex; for(i= 0; i < sa_line_count; i++) { if(strncmp(sa_lines[i], "GPT disk GUID : ", 26) == 0) { ret= Hex_to_bin(sa_lines[i] + 26, 16, &bin_count, guid, 0); if(ret < 0 || bin_count != 16) break; Xorriso_format_guid(xorriso, guid, xorriso->result_line, 0); strcat(xorriso->result_line, "\n"); Xorriso_result(xorriso,0); ret= 1; goto ex; } } ret= 1; goto ex; } else { sprintf(xorriso->info_text, "%s form parameter not recognized: ", flag & 1 ? "-report_el_torito" : "-report_system_area"); Text_shellsafe(form, xorriso->info_text, 1); Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); ret= 0; goto ex; } if(ret < 0) goto ex; if(flag & 1) { lines= et_lines; line_count= et_line_count; } else { lines= sa_lines; line_count= sa_line_count; } if(!do_cmd) { if(lines == NULL || ret == 0) { if(flag & 1) strcpy(xorriso->info_text, "No El Torito information was loaded"); else strcpy(xorriso->info_text, "No System Area was loaded"); Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); ret= 2; goto ex; } if(line_count == 0) { if(flag & 1) strcpy(xorriso->info_text, "No El Torito information available"); else strcpy(xorriso->info_text, "System Area only contains 0-bytes"); Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); ret= 2; goto ex; } } if(flag & 2) { if(cmd_count > 0) { ret= Xorriso_execute_option(xorriso, "-boot_image any discard -boot_image any system_area=/dev/zero", 1 | 16); if(ret <= 0) goto ex; for(i= 0; i < cmd_count; i++) { ret= Xorriso_execute_option(xorriso, cmds[i], 1 | 16); if(ret <= 0) goto ex; } sprintf(xorriso->info_text, "Replayed %d boot related commands", cmd_count); Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); } else { Xorriso_msgs_submit(xorriso, 0, "No proposals available for boot related commands", 0, "NOTE", 0); ret= 2; goto ex; } } else if(do_cmd) { Xorriso_report_lines(xorriso, cmds, cmd_count); } else { Xorriso_report_lines(xorriso, lines, line_count); } 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) 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) iso_image_report_system_area(NULL, &sa_lines, &sa_line_count, 1 << 15); return(ret); } int Xorriso_decode_lfa_flags(struct XorrisO *xorriso, char *flags_text, uint64_t *lfa_flags, int flag) { int ret; ret= iso_util_decode_lfa_flags(flags_text, lfa_flags, 0); if(ret < 0) { Xorriso_report_iso_error(xorriso, "", ret, "Error when converting chattr attribute letters", 0, "WARNING", 1); return(0); } return(1); } /* @param flags_text will return the resulting text in allocated memory. @param flag bit0= produce lsattr(1) format with '-' and peculiar sequence */ int Xorriso_encode_lfa_flags(struct XorrisO *xorriso, uint64_t lfa_flags, char **flags_text, int flag) { int ret; ret= iso_util_encode_lfa_flags(lfa_flags, flags_text, flag & 1); if(ret < 0) { Xorriso_report_iso_error(xorriso, "", ret, "Error when converting chattr attribute bits", 0, "WARNING", 1); return(0); } return(1); }