From b2984efc9fa5b7368310be29c71c31af9f6d7f32 Mon Sep 17 00:00:00 2001 From: Thomas Schmitt Date: Fri, 26 Sep 2008 16:14:21 +0000 Subject: [PATCH] A first attempt on making bootable ISO images --- libisoburn/trunk/xorriso/xorriso.1 | 54 +++- libisoburn/trunk/xorriso/xorriso.c | 256 ++++++++++++++++++- libisoburn/trunk/xorriso/xorriso_private.h | 7 + libisoburn/trunk/xorriso/xorriso_timestamp.h | 2 +- libisoburn/trunk/xorriso/xorrisoburn.c | 52 +++- libisoburn/trunk/xorriso/xorrisoburn.h | 7 + 6 files changed, 344 insertions(+), 34 deletions(-) diff --git a/libisoburn/trunk/xorriso/xorriso.1 b/libisoburn/trunk/xorriso/xorriso.1 index 3d10696a..aad263e3 100644 --- a/libisoburn/trunk/xorriso/xorriso.1 +++ b/libisoburn/trunk/xorriso/xorriso.1 @@ -2,7 +2,7 @@ .\" First parameter, NAME, should be all caps .\" Second parameter, SECTION, should be 1-8, maybe w/ subsection .\" other parameters are allowed: see man(7), man(1) -.TH XORRISO 1 "Sep 19, 2008" +.TH XORRISO 1 "Sep 26, 2008" .\" Please adjust this date whenever revising the manpage. .\" .\" Some roff macros, for reference: @@ -861,7 +861,7 @@ iso_rr_path. -type type_letter .br matches only files files of the given type: -"block", "char", "dir", "pipe", "file", "link", "socket", +"block", "char", "dir", "pipe", "file", "link", "socket", "eltorito", "Xotic" which eventually matches what is not matched by the other types. .br Only the first letter is interpreted. E.g.: -find / -type d @@ -1352,25 +1352,51 @@ xorriso adds the traditional 300k of padding by default to all images. .br For images which will never get to a CD it is safe to use -padding 0 . .TP -\fB\-boot_image\fR "any"|"isolinux" "discard"|"keep"|"patch" -Defines the handling of an eventual boot image (El-Torito) which has been read -from an existing ISO image. All types ("any") can be discarded or kept -unaltered. The latter makes only sense if the format of the boot image is +\fB\-boot_image\fR "any"|"isolinux" "discard"|"keep"|"patch"|bootspec +Defines the handling of an eventual boot image (El-Torito) which has +been read from an existing ISO image or defines how to make a prepared +ISOLINUX file set bootable. +.br +All types ("any") of El-Torito boot images can be discarded or kept unaltered. +The latter makes only sense if the format of the boot image is relocatable without content changes. .br -The boot image type "isolinux" can be kept unaltered (not advisable), or -discarded, or it can be patched to match its relocation. In the latter case -the resulting ISO image is bootable if the boot image was really complying -to the isolinux standard. -.br -Creation of new boot images is not yet possible. +An existing boot image of type "isolinux" can be +kept unaltered (not advisable), or be discarded, or it can be patched +to match its relocation. In the latter case the resulting ISO image is +bootable if the boot image was really produced by ISOLINUX. .br CAUTION: -This is an expert option. xorriso is not an expert yet. -It cannot recognize the inner form of boot images. +This is an expert option. +xorriso cannot recognize the inner form of boot images. So the user has already to know about the particular needs of the bootimage which is present on the input media. +.br Most safe is the default: "any" "discard". +.br +Regardless whether an El-Torito boot image was detected or not, it is possible +to activate a set of ISOLINUX files for booting. An existing boot image gets +discarded, then. +The files have to be added to the ISO image by normal means (-map, -add, ...) +and should reside either in ISO image directory /isolinux or /boot/isolinux . +In that case it suffices to use as bootspec the text "dir=/isolinux" or +"dir=/boot/isolinux". E.g.: +.br + -boot_image isolinux dir=/boot/isolinux +.br +It is possible to make several individual settings. E.g. +.br + -boot_image isolinux bin_path=/boot/isolinux/isolinux.bin +.br + -boot_image isolinux cat_path=/boot/isolinux/boot.cat +.br + -boot_image isolinux load_size=2048 +.br +But that should hardly be necessary. +.br +CAUTION: xorriso only connects some ISOLINUX files to the El-Torito mechanism. +If the ISOLINUX setup was incorrect or if the given files are not by ISOLINUX +at all, then anything may happen when booting is attempted. .TP .B Exception processing: .PP diff --git a/libisoburn/trunk/xorriso/xorriso.c b/libisoburn/trunk/xorriso/xorriso.c index e2de0b97..c59310bb 100644 --- a/libisoburn/trunk/xorriso/xorriso.c +++ b/libisoburn/trunk/xorriso/xorriso.c @@ -2011,7 +2011,7 @@ int Findjob_set_name_expr(struct FindjoB *o, char *name_expr, int flag) int Findjob_set_file_type(struct FindjoB *o, char file_type, int flag) { - static char known[]= {"bcdpf-lsmX"}; + static char known[]= {"bcdpf-lsmeX"}; if(file_type!=0) if(strchr(known, file_type)==NULL) @@ -2070,7 +2070,8 @@ int Findjob_get_commit_filter(struct FindjoB *o, int *commit_filter, int flag) } -/* @return 0=no match , 1=match , <0 = error +/* @flag bit0=recognize type "e" = El-Torito + @return 0=no match , 1=match , <0 = error */ int Findjob_test(struct FindjoB *o, char *name, struct stat *boss_stbuf, struct stat *stbuf, @@ -2111,6 +2112,9 @@ int Findjob_test(struct FindjoB *o, char *name, } else if(((stbuf->st_mode)&S_IFMT)==S_IFSOCK) { if(o->file_type!='s') return(0); + } else if((flag & 1) && ((stbuf->st_mode) & S_IFMT) == Xorriso_IFBOOT) { + if(o->file_type!='e') + return(0); } else { if(o->file_type!='X') return(0); @@ -3386,6 +3390,10 @@ int Xorriso_new(struct XorrisO ** xorriso,char *progname, int flag) m->do_stream_recording= 0; m->keep_boot_image= 0; m->patch_isolinux_image= 0; + m->boot_image_bin_path[0]= 0; + m->boot_image_emul= 0; + m->boot_image_cat_path[0]= 0; + m->boot_image_load_size= 4 * 512; /* hearsay out of libisofs/demo/iso.c */ m->allow_graft_points= 0; m->allow_restore= 0; m->do_concat_split= 1; @@ -4865,8 +4873,8 @@ int Xorriso_status(struct XorrisO *xorriso, char *filter, FILE *fp, int flag) -options_from_file:${resume_state_file}_pos */ { - int is_default, no_defaults, i, ret, adr_mode; - char *line, sfe[5*SfileadrL], mode[80], *form, *treatment; + int is_default, no_defaults, i, ret, adr_mode, bin_path_in_use= 0; + char *line, sfe[5 * SfileadrL + 80], mode[80], *form, *treatment; static char channel_prefixes[4][4]= {".","R","I","M"}; static char load_names[][20]= {"auto", "session", "track", "lba", "volid"}; static int max_load_mode= 4; @@ -4992,10 +5000,31 @@ int Xorriso_status(struct XorrisO *xorriso, char *filter, FILE *fp, int flag) if(!(is_default && no_defaults)) Xorriso_status_result(xorriso,filter,fp,flag&2); - is_default= (xorriso->keep_boot_image==0 && xorriso->patch_isolinux_image==0); + is_default= (xorriso->keep_boot_image == 0 + && xorriso->patch_isolinux_image == 0 + && xorriso->boot_image_bin_path[0] == 0); form= "any"; treatment= "discard"; - if(xorriso->patch_isolinux_image) { + if(xorriso->boot_image_bin_path[0]) { + form= "isolinux"; + if(strcmp(xorriso->boot_image_bin_path, "/isolinux.bin") == 0 && + strcmp(xorriso->boot_image_cat_path, "/boot.cat") == 0) + strcpy(sfe, "dir=/"); + else if(strcmp(xorriso->boot_image_bin_path, "/isolinux/isolinux.bin") == 0 + && strcmp(xorriso->boot_image_cat_path, "/isolinux/boot.cat") == 0) + strcpy(sfe, "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(sfe, "dir=/boot/isolinux"); + else { + strcpy(sfe, "bin_path="); + Text_shellsafe(xorriso->boot_image_bin_path, sfe + strlen(sfe), 0); + bin_path_in_use= 1; + } + treatment= sfe; + } else if(xorriso->patch_isolinux_image) { form= "isolinux"; treatment= "patch"; } else if(xorriso->keep_boot_image) { @@ -5004,6 +5033,18 @@ int Xorriso_status(struct XorrisO *xorriso, char *filter, FILE *fp, int flag) sprintf(line,"-boot_image %s %s\n", form, treatment); if(!(is_default && no_defaults)) Xorriso_status_result(xorriso,filter,fp,flag&2); + if(xorriso->boot_image_bin_path[0] && bin_path_in_use) { + is_default= 0; + sprintf(line,"-boot_image isolinux cat_path=%s\n", + Text_shellsafe(xorriso->boot_image_cat_path, sfe, 0)); + if(!(is_default && no_defaults)) + Xorriso_status_result(xorriso,filter,fp,flag&2); + is_default= xorriso->boot_image_load_size == 4 * 512; + sprintf(line,"-boot_image isolinux load_size=%.f\n", + (double) xorriso->boot_image_load_size); + if(!(is_default && no_defaults)) + Xorriso_status_result(xorriso,filter,fp,flag&2); + } sprintf(line,"-cd %s\n", (xorriso->wdi[0] ? Text_shellsafe(xorriso->wdi,sfe,0) : "'/'")); @@ -7213,6 +7254,8 @@ int Xorriso__mode_to_perms(mode_t st_mode, char perms[10], int flag) } +/* @param flag bit0= recognize Xorriso_IFBOOT as file type +*/ int Xorriso_format_ls_l(struct XorrisO *xorriso, struct stat *stbuf, int flag) { int show_major_minor= 0; @@ -7240,6 +7283,8 @@ int Xorriso_format_ls_l(struct XorrisO *xorriso, struct stat *stbuf, int flag) strcat(rpt, "p"); else if(S_ISSOCK(st_mode)) strcat(rpt, "s"); + else if((flag & 1) && (st_mode & S_IFMT) == Xorriso_IFBOOT) + strcat(rpt, "e"); else strcat(rpt, "?"); @@ -8498,15 +8543,60 @@ ex:; } +/* @param flag bit0= do not report eventual ignore decision +*/ +int Xorriso_genisofs_ignore(struct XorrisO *xorriso, char *whom, + char **argv, int *i, int flag) +{ + /* mkisofs 2.01 options which are not scheduled for implementation, yet */ + static char ignored_arg0_options[][41]= { + "-allow-leading-dots", "-ldots", "-allow-lowercase", "-allow-multidot", + "-cache-inodes", "-no-cache-inodes", "-check-oldnames", "-d", "-D", + "-joliet-long", "-l", "-L", "-max-iso9660-filenames", "-N", "-nobak", + "-no-bak", "-force-rr", "-r", "-relaxed-filenames", "-T", "-U", + "-no-iso-translate", + "" + }; + static char ignored_arg1_options[][41]= { + "-A", "-biblio", "-check-session", "-p", "-root", + "-old-root", "-sysid", "-table-name", + "" + }; + int k, idx_offset= 0; + char sfe[5*SfileadrL]; + + for(k=0;ignored_arg0_options[k][0]!=0;k++) + if(strcmp(argv[*i],ignored_arg0_options[k])==0) + goto no_volunteer; + for(k=0;ignored_arg1_options[k][0]!=0;k++) + if(strcmp(argv[*i],ignored_arg1_options[k])==0) { + (*i)++; + idx_offset= -1; + goto no_volunteer; + } + return(0); +no_volunteer:; + sprintf(xorriso->info_text, "-as %s: Ignored option %s", + whom, Text_shellsafe(argv[(*i)+idx_offset], sfe, 0)); + if(!(flag & 1)) + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); + return(1); +} + + /* micro emulation of mkisofs */ int Xorriso_genisofs(struct XorrisO *xorriso, char *whom, int argc, char **argv, int flag) { - int ret, i, k, was_path= 0, was_other_option= 0, mem_graft_points, mem; - int do_print_size= 0, idx_offset= 0, fd, idx, iso_level= 0; + int ret, i, was_path= 0, was_other_option= 0, mem_graft_points, mem; + int do_print_size= 0, fd, idx, iso_level= 0, no_emul_boot= 0; + int option_b= 0; char sfe[5*SfileadrL], adr[SfileadrL+8], ra_text[80], pathspec[2*SfileadrL]; char *ept, *add_pt, eff_path[SfileadrL], indev[SfileadrL+8], msc[80], *cpt; +#ifdef Xorriso_old_genisofs_ignorE + int idx_offset= 0, k; + /* mkisofs 2.01 options which are not scheduled for implementation, yet */ static char ignored_arg0_options[][41]= { "-allow-leading-dots", "-ldots", "-allow-lowercase", "-allow-multidot", @@ -8521,6 +8611,8 @@ int Xorriso_genisofs(struct XorrisO *xorriso, char *whom, "-old-root", "-sysid", "-table-name", "" }; +#endif /* Xorriso_old_genisofs_ignorE */ + static char helptext[][80]= { "Usage: xorriso -as mkisofs [options] file...", "Note: This is not mkisofs. See xorriso -help, xorriso -version, man xorriso", @@ -8553,6 +8645,13 @@ int Xorriso_genisofs(struct XorrisO *xorriso, char *whom, adr[0]= indev[0]= msc[0]= 0; for(i= 0; iresult_line, "mkisofs 2.01-Emulation Copyright (C) 2008 see libburnia-project.org xorriso\n" @@ -8621,6 +8720,41 @@ int Xorriso_genisofs(struct XorrisO *xorriso, char *whom, ((off_t) 4) * ((off_t) 1024*1024*1024) - ((off_t) 1); else xorriso->file_size_limit= 0; + } else if(strcmp(argv[i], "-no-emul-boot")==0) { + no_emul_boot= 1; + } else if(strcmp(argv[i], "-boot-info-table")==0) { + ; + } else if(strcmp(argv[i], "-b") == 0) { + if(i+1>=argc) + goto not_enough_args; + i++; + xorriso->boot_image_bin_path[0]= 0; + if(argv[i][0] != '/') + strcat(xorriso->boot_image_bin_path, "/"); + ret= Sfile_str(xorriso->boot_image_bin_path + + strlen(xorriso->boot_image_bin_path), argv[i], 0); + if(ret <= 0) + goto ex; + option_b= 1; + xorriso->keep_boot_image= 0; + xorriso->patch_isolinux_image= 0; + } else if(strcmp(argv[i], "-c") == 0) { + if(i+1>=argc) + goto not_enough_args; + i++; + xorriso->boot_image_cat_path[0]= 0; + if(argv[i][0] != '/') + strcat(xorriso->boot_image_cat_path, "/"); + ret= Sfile_str(xorriso->boot_image_cat_path + + strlen(xorriso->boot_image_cat_path), argv[i], 0); + if(ret <= 0) + goto ex; + } else if(strcmp(argv[i], "-boot-load-size") == 0) { + if(i+1>=argc) + goto not_enough_args; + i++; + sscanf(argv[i], "%d", &ret); + xorriso->boot_image_load_size= ret * 512; } else was_other_option= 1; } @@ -8636,6 +8770,7 @@ int Xorriso_genisofs(struct XorrisO *xorriso, char *whom, whom, (ret==3 ? "symbolic link" : "directory"), Text_shellsafe(adr+6, sfe, 0)); Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + ret= 0; goto ex; } } /* Regard overwriteable as blank, truncate regular files on write start */ @@ -8643,6 +8778,14 @@ int Xorriso_genisofs(struct XorrisO *xorriso, char *whom, if(ret<=0) goto ex; } + if(option_b && !no_emul_boot) { + xorriso->boot_image_bin_path[0]= 0; + sprintf(xorriso->info_text, + "-as %s: Option -b is supported only if option -no-emul-boot is given", + whom); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + ret= 0; goto ex; + } if(was_other_option && xorriso->out_drive_handle==NULL) { ret= Xorriso_option_dev(xorriso, "-", 2|4); /* set outdev to stdout */ if(ret<=0) @@ -8693,6 +8836,8 @@ illegal_c:; sprintf(xorriso->info_text, "-as %s: %s", whom, Text_shellsafe(argv[i], sfe, 0)); Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0); + +#ifdef Xorriso_old_genisofs_ignorE idx_offset= 0; for(k=0;ignored_arg0_options[k][0]!=0;k++) if(strcmp(argv[i],ignored_arg0_options[k])==0) @@ -8711,6 +8856,14 @@ no_volunteer:; continue; } +#else /* Xorriso_old_genisofs_ignorE */ + + ret= Xorriso_genisofs_ignore(xorriso, whom, argv, &i, 0); + if(ret == 1) + continue; + +#endif /* ! Xorriso_old_genisofs_ignorE */ + if(strcmp(argv[i], "-version")==0) { /* was already handled in first argument scan */; @@ -8792,9 +8945,21 @@ not_enough_args:; goto ex; } else if(strcmp(argv[i], "-v")==0 || strcmp(argv[i], "-quiet")==0) { /* was already handled in first argument scan */; + } else if(strcmp(argv[i], "-iso-level")==0) { i++; /* was already handled in first argument scan */; + } else if(strcmp(argv[i], "-b") == 0) { + i++; + /* was already handled in first argument scan */; + } else if(strcmp(argv[i], "-c") == 0) { + i++; + /* was already handled in first argument scan */; + } else if(strcmp(argv[i], "-boot-load-size") == 0) { + i++; + /* was already handled in first argument scan */; + } else if(strcmp(argv[i], "-boot-info-table")==0) { + ; } else if(argv[i][0]=='-' && argv[i][1]!=0) { sprintf(xorriso->info_text, "-as %s: Unknown option %s", whom, Text_shellsafe(argv[i], sfe, 0)); @@ -9766,8 +9931,9 @@ unusable_index:; int Xorriso_option_boot_image(struct XorrisO *xorriso, char *form, char *treatment, int flag) { - int was_ok= 1; + int was_ok= 1, ret; char *formpt, *treatpt; + double num; formpt= form; if(formpt[0]=='-') @@ -9779,25 +9945,88 @@ int Xorriso_option_boot_image(struct XorrisO *xorriso, char *form, if(strcmp(treatpt, "keep")==0) { xorriso->keep_boot_image= 1; xorriso->patch_isolinux_image= 0; + xorriso->boot_image_bin_path[0]= 0; } else if(strcmp(treatpt, "discard")==0) { xorriso->keep_boot_image= 0; xorriso->patch_isolinux_image= 0; + xorriso->boot_image_bin_path[0]= 0; } else was_ok= 0; } else if(strcmp(formpt, "isolinux")==0) { if(strcmp(treatpt, "patch")==0) { xorriso->keep_boot_image= 1; xorriso->patch_isolinux_image= 1; + xorriso->boot_image_bin_path[0]= 0; } else if(strcmp(treatpt, "keep")==0) { xorriso->keep_boot_image= 1; xorriso->patch_isolinux_image= 0; + xorriso->boot_image_bin_path[0]= 0; } else if(strcmp(treatpt, "discard")==0) { xorriso->keep_boot_image= 0; xorriso->patch_isolinux_image= 0; + xorriso->boot_image_bin_path[0]= 0; + } else if(strncmp(treatpt, "dir=", 4) == 0) { + /* The three locations mentioned in http://syslinux.zytor.com/iso.php */ + if(strcmp(treatpt + 4, "/") == 0) + strcpy(xorriso->boot_image_bin_path, "/"); + else if(strcmp(treatpt + 4, "isolinux") == 0 + || strcmp(treatpt + 4, "/isolinux") == 0) + strcpy(xorriso->boot_image_bin_path, "/isolinux/"); + else if(strcmp(treatpt + 4, "boot/isolinux") == 0 + || strcmp(treatpt + 4, "/boot/isolinux") == 0 + || strcmp(treatpt + 4, "boot") == 0 + || strcmp(treatpt + 4, "/boot") == 0) + strcpy(xorriso->boot_image_bin_path, "/boot/isolinux/"); + else { + sprintf(xorriso->info_text, + "Unrecognized keyword with -boot_image %s %s", + form, treatment); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + sprintf(xorriso->info_text, + "Allowed with boot_dir= are / , /isolinux . /boot/isolinux"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "HINT", 0); + return(0); + } + strcpy(xorriso->boot_image_cat_path, xorriso->boot_image_bin_path); + strcat(xorriso->boot_image_bin_path, "isolinux.bin"); + strcat(xorriso->boot_image_cat_path, "boot.cat"); + xorriso->boot_image_load_size= 4 * 512; + xorriso->keep_boot_image= 0; + xorriso->patch_isolinux_image= 0; + } else if(strncmp(treatpt, "bin_path=", 9) == 0) { + ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, treatpt + 9, + xorriso->boot_image_bin_path, 2); + if(ret <= 0) + return(ret); + xorriso->keep_boot_image= 0; + xorriso->patch_isolinux_image= 0; + if(xorriso->boot_image_bin_path[0]) + xorriso->boot_image_load_size= 4 * 512; + } else if(strncmp(treatpt, "cat_path=", 9) == 0) { + ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi, treatpt + 9, + xorriso->boot_image_cat_path, 2); + if(ret <= 0) + return(ret); + } else if(strncmp(treatpt, "load_size=", 10) == 0) { + num= Scanf_io_size(treatpt + 10, 0); + if(num < 512) { + sprintf(xorriso->info_text, + "-boot_image isolinux : load_size too small (%s < 512)", + treatpt + 10); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + return(0); + } + xorriso->boot_image_load_size= num; } else was_ok= 0; } else was_ok= 0; + + /* >>> BOOT : check whether directories and/or files exist: + bin_path , dirname(cat_path), + isolinux.cfg in / , /isolinux , or /boot/isolinux + */ + if(!was_ok) { sprintf(xorriso->info_text, "Unrecognized options with -boot_image: %s %s", form, treatment); @@ -11431,8 +11660,13 @@ int Xorriso_option_help(struct XorrisO *xorriso, int flag) " Specifies the publisher name. (128 chars)", " -joliet \"on\"|\"off\"", " Generate Joliet info additional to Rock Ridge info.", -" -bootimage \"any\"|\"isolinux\" \"discard\"|\"keep\"|\"patch\"", +" -boot_image \"any\"|\"isolinux\" \"discard\"|\"keep\"|\"patch\"|\"dir=\"", +" \"bin_path=\"|\"cat_path=\"|\"load_size=\"", " Whether to discard or keep an exiting El-Torito boot image.", +" isolinux can be made bootable by dir=/ or dir=/isolinux", +" or dir=/boot/isolinux or by bin_path=... and cat_path=...", +" The isolinux files need to be added to the ISO image by", +" help of the usual commands like -map or -add.", "", " -uid uid User id to be used for the whole multi-session ISO image.", " -gid gid Group id for the same purpose.", @@ -11688,7 +11922,7 @@ int Xorriso_option_help(struct XorrisO *xorriso, int flag) "", "Compatibility emulation (argument list may be ended by list delimiter --):", " -as mkisofs [-help|-version|-o|-R|-J|-V|-P|-f|-m|-exclude-list|-no-pad|", -" -M|-C|-graft-points|-path-list|pathspecs]", +" -M|-C|-graft-points|-path-list|pathspecs|-no-emul-boot|-b|-c]", " Perform some mkisofs gestures, understand pathspecs as mkisofs", " does. Commit happens outside emulation at usual occasions.", " -as cdrecord [-help|-v|dev=|speed=|blank=|fs=|-eject|-atip|padsize=|path|-]", diff --git a/libisoburn/trunk/xorriso/xorriso_private.h b/libisoburn/trunk/xorriso/xorriso_private.h index f878c863..299a2ba8 100644 --- a/libisoburn/trunk/xorriso/xorriso_private.h +++ b/libisoburn/trunk/xorriso/xorriso_private.h @@ -185,6 +185,13 @@ struct XorrisO { /* the global context of xorriso */ int keep_boot_image; int patch_isolinux_image; + char boot_image_bin_path[SfileadrL]; + int boot_image_emul; /* 0=no emulation + (1=emulation as hard disk) + (2=emulation as floppy) + */ + char boot_image_cat_path[SfileadrL]; + off_t boot_image_load_size; /* XORRISO options */ diff --git a/libisoburn/trunk/xorriso/xorriso_timestamp.h b/libisoburn/trunk/xorriso/xorriso_timestamp.h index 372694d6..76e3c915 100644 --- a/libisoburn/trunk/xorriso/xorriso_timestamp.h +++ b/libisoburn/trunk/xorriso/xorriso_timestamp.h @@ -1 +1 @@ -#define Xorriso_timestamP "2008.09.26.120934" +#define Xorriso_timestamP "2008.09.26.161331" diff --git a/libisoburn/trunk/xorriso/xorrisoburn.c b/libisoburn/trunk/xorriso/xorrisoburn.c index d7d1bee0..183f3c27 100644 --- a/libisoburn/trunk/xorriso/xorrisoburn.c +++ b/libisoburn/trunk/xorriso/xorrisoburn.c @@ -93,6 +93,8 @@ int Xorriso_read_file_data(struct XorrisO *xorriso, IsoNode *node, S_ISFIFO(iso_node_get_mode(node))) #define LIBISO_ISSOCK(node) (iso_node_get_type(node) == LIBISO_SPECIAL && \ S_ISSOCK(iso_node_get_mode(node))) +#define LIBISO_ISBOOT(node) (iso_node_get_type(node) == LIBISO_BOOT) + /* CD specs say one shall not write tracks < 600 kiB */ #define Xorriso_cd_min_track_sizE 300 @@ -838,7 +840,7 @@ int Xorriso_write_session(struct XorrisO *xorriso, int flag) int ret, relax= 0, i, profile, status, num_formats; int major, minor, micro; unsigned dummy; - char xorriso_id[256], *img_id, profile_name[80], sfe[5*SfileadrL]; + char xorriso_id[256], *img_id, profile_name[80], sfe[5*SfileadrL], *cpt; struct isoburn_imgen_opts *sopts= NULL; struct burn_drive_info *dinfo, *source_dinfo; struct burn_drive *drive, *source_drive; @@ -851,6 +853,8 @@ int Xorriso_write_session(struct XorrisO *xorriso, int flag) enum burn_disc_status s; IsoImage *image= NULL; ElToritoBootImage *bootimg; + enum eltorito_boot_media_type emul_type= ELTORITO_NO_EMUL; + ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive, "on attempt to write", 2); @@ -916,7 +920,40 @@ int Xorriso_write_session(struct XorrisO *xorriso, int flag) /* >>> ??? move down to libisoburn ? */ if(image!=NULL && !(flag&1)) { ret= iso_image_get_boot_image(image, &bootimg, NULL, NULL); - if(xorriso->patch_isolinux_image) { + + if(xorriso->boot_image_bin_path[0]) { + /* discard old boot image, set new one */ + if(ret == 1) + iso_image_remove_boot_image(image); + if(xorriso->boot_image_emul == 1) + emul_type= ELTORITO_HARD_DISC_EMUL; + else if(xorriso->boot_image_emul == 2) + emul_type= ELTORITO_FLOPPY_EMUL; + if(xorriso->boot_image_cat_path[0] == 0) { + strcpy(xorriso->boot_image_cat_path, xorriso->boot_image_bin_path); + cpt= strrchr(xorriso->boot_image_cat_path, '/'); + if(cpt == NULL) + cpt= xorriso->boot_image_cat_path; + else + cpt++; + strcpy(cpt, "boot.cat"); + } + ret= iso_image_set_boot_image(image, xorriso->boot_image_bin_path, + emul_type, xorriso->boot_image_cat_path, + &bootimg); + if(ret < 0) { + Xorriso_process_msg_queues(xorriso,0); + Xorriso_report_iso_error(xorriso, "", ret, + "Error when attaching El-Torito boot image to ISO 9660 image", + 0, "FAILURE", 1); + sprintf(xorriso->info_text, + "Could not attach El-Torito boot image to ISO 9660 image"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + {ret= 0; goto ex;} + } + el_torito_set_load_size(bootimg, xorriso->boot_image_load_size / 512); + el_torito_patch_isolinux_image(bootimg); + } else if(xorriso->patch_isolinux_image) { if(ret==1) { relax|= isoburn_igopt_allow_full_ascii; sprintf(xorriso->info_text, "Patching alleged isolinux boot image"); @@ -1555,9 +1592,8 @@ int Xorriso_fake_stbuf(struct XorrisO *xorriso, char *path, struct stat *stbuf, stbuf->st_mode|= S_IFIFO; else if(LIBISO_ISSOCK(*node)) stbuf->st_mode|= S_IFSOCK; - - /* >>> NG How to represent LIBISO_BOOT ? */ - + else if(LIBISO_ISBOOT(*node)) + stbuf->st_mode|= Xorriso_IFBOOT; /* >>> With directories this should be : number of subdirs + 2 */ /* >>> ??? How to obtain RR hardlink number for other types ? */ @@ -4973,7 +5009,7 @@ int Xorriso_ls_filev(struct XorrisO *xorriso, char *wd, continue; link_target[0]= 0; if((flag&5)==1) { /* -ls_l */ - ret= Xorriso_format_ls_l(xorriso, &stbuf, 0); + ret= Xorriso_format_ls_l(xorriso, &stbuf, 1); if(ret<=0) continue; if(LIBISO_ISLNK(node)) { @@ -5109,7 +5145,7 @@ cannot_create_iter:; ret= Xorriso_fake_stbuf(xorriso, "", &stbuf, &node, 1); if(ret<=0) continue; - ret= Xorriso_format_ls_l(xorriso, &stbuf, 0); + ret= Xorriso_format_ls_l(xorriso, &stbuf, 1); if(ret<=0) continue; } @@ -5890,7 +5926,7 @@ int Xorriso_findi_test(struct XorrisO *xorriso, struct FindjoB *job, off_t damage_start, damage_end, size; int lba_count, *file_end_lbas= NULL, *file_start_lbas= NULL, i; - ret= Findjob_test(job, name, boss_stbuf, stbuf, depth, 0); + ret= Findjob_test(job, name, boss_stbuf, stbuf, depth, 1); if(ret<=0) return(ret); diff --git a/libisoburn/trunk/xorriso/xorrisoburn.h b/libisoburn/trunk/xorriso/xorrisoburn.h index a49226b2..4a451dd6 100644 --- a/libisoburn/trunk/xorriso/xorrisoburn.h +++ b/libisoburn/trunk/xorriso/xorrisoburn.h @@ -338,5 +338,12 @@ int Xorriso_extract_cut(struct XorrisO *xorriso, char *img_path, char *disk_path, off_t img_offset, off_t bytes, int flag); + +/* A pseudo file type for El-Torito bootsectors as in man 2 stat : + For now take the highest possible value. +*/ +#define Xorriso_IFBOOT S_IFMT + + #endif /* Xorrisoburn_includeD */