A first attempt on making bootable ISO images

This commit is contained in:
2008-09-26 16:14:21 +00:00
parent 1a0346a1a1
commit b2984efc9f
6 changed files with 344 additions and 34 deletions

View File

@ -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; i<argc; i++) {
#ifndef Xorriso_old_genisofs_ignorE
ret= Xorriso_genisofs_ignore(xorriso, whom, argv, &i, 1);
if(ret == 1)
continue;
#endif /* Xorriso_old_genisofs_ignorE */
if(strcmp(argv[i], "-version")==0) {
sprintf(xorriso->result_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|-]",