libisoburn/xorriso/emulators.c

2820 lines
103 KiB
C

/* xorriso - creates, loads, manipulates and burns ISO 9660 filesystem images.
Copyright 2007-2019 Thomas Schmitt, <scdbackup@gmx.net>
Provided under GPL version 2 or later.
This file contains the implementation of emulators for mkisofs and cdrecord.
*/
#ifdef HAVE_CONFIG_H
#include "../config.h"
#endif
#include <ctype.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <time.h>
#include <fcntl.h>
#include <errno.h>
#include "xorriso.h"
#include "xorriso_private.h"
#include "xorrisoburn.h"
int Xorriso_cdrskin_uses_stdout(struct XorrisO *xorriso, int argc, char **argv,
int flag)
{
int i;
for(i= 0; i < argc; i++) {
if(strcmp(argv[i], "dev=-") == 0 ||
strcmp(argv[i], "dev=stdio:/dev/fd/1") == 0 ||
strcmp(argv[i], "-dev=-") == 0 ||
strcmp(argv[i], "-dev=stdio:/dev/fd/1") == 0)
return(1);
}
return(0);
}
int Xorriso_cdrskin_help(struct XorrisO *xorriso, int flag)
{
static char helptext[][80]= {
"Usage: xorriso -as cdrecord [options|source_addresses]",
"Note: This is not cdrecord. See xorriso -help, xorriso -version, man xorrecord",
"Options:",
"\t-version\tprint version information and exit emulation",
"\t--devices\tprint list of available MMC drives and exit emulation",
"\tdev=target\tpseudo-SCSI target to use as CD-Recorder",
"\tdrive_scsi_dev_family=sr|scd|sg\t\tselect Linux device type",
"\t--drive_not_exclusive\tdo not try to prevent use of busy drive",
"\t-v\t\tincrement verbose level by one",
"\t-V\t\tincrement SCSI command transport verbose level by one",
"\t-checkdrive\tcheck if a driver for the drive is present",
"\t-inq\t\tdo an inquiry for the drive",
"\tspeed=#\t\tset speed of drive",
"\tblank=type\tblank a CD-RW disc (see blank=help)",
"\tfs=#\t\tSet fifo size to # (0 to disable, default is 4 MB)",
"\t-eject\t\teject the disk after doing the work",
"\t-dummy\t\tdo everything with laser turned off",
"\t-msinfo\t\tretrieve multi-session info for mkisofs >= 1.10",
"\t-toc\t\tretrieve and print TOC/PMA data",
"\t-atip\t\tretrieve media state, print \"Is *erasable\"",
"\t-multi\t\tgenerate a TOC that allows multi session",
"\t--multi_if_possible\tapply -multi if the medium supports it",
"\t-waiti\t\twait until input is available before opening SCSI",
"\t-tao\t\tWrite disk in TAO mode.",
"\t-dao\t\tWrite disk in SAO mode.",
"\t-sao\t\tWrite disk in SAO mode.",
"\ttsize=#\t\tannounces exact size of source data",
"\tpadsize=#\tAmount of padding",
"\t-data\t\tSubsequent tracks are CD-ROM data mode 1 (default)",
"\t-isosize\tUse iso9660 file system size for next data track",
"\t-pad\t\tpadsize=30k",
"\t-nopad\t\tDo not pad",
"\tminbuf=\t\tKeep drive buffer hungry",
"\tmodesty_on_drive=\tLike minbuf=, but with more parameters",
"\t-immed\t\tEquivalent to minbuf=75",
"\t--grow_overwriteable_iso\temulate multi-session on DVD+RW, BD-RE",
"\twrite_start_address=#\t\twrite to byte address on DVD+RW, BD-RE",
"\tstream_recording=on|number\ttry to get full speed on DVD-RAM, BD",
"\tuse_immed_bit=on|off|default\tcontrol use of Immed bit",
"\tdvd_obs=default|32k|64k\t\tbytes per DVD/BD write operation",
"\tstdio_sync=on|off|end|number\twhether to fsync output to \"stdio:\"",
"\t--no_rc\t\tDo not execute xorriso startup files",
"\t-help\t\tprint this text to stderr and exit emulation",
"Actually this is the integrated ISO RockRidge filesystem manipulator xorriso",
"lending its libburn capabilities to a very limited cdrecord emulation. Only",
"a single data track can be burnt to blank, appendable or overwritable media.",
"A much more elaborate cdrecord emulator is cdrskin from the libburn package.",
"",
#ifdef Xorriso_GNU_xorrisO
"Report bugs to: bug-xorriso@gnu.org , or in private to: scdbackup@gmx.net .",
"xorriso home page: <https://www.gnu.org/software/xorriso/>",
"General help using GNU software: <https://www.gnu.org/gethelp/>",
#else
"Report any bugs to bug-xorriso@gnu.org or in private to scdbackup@gmx.net .",
#endif
"@End_of_helptexT@"
};
int i;
for(i= 0; strcmp(helptext[i], "@End_of_helptexT@")!=0; i++) {
sprintf(xorriso->info_text, "%s\n", helptext[i]);
Xorriso_info(xorriso,0);
}
return(1);
}
/* micro version of cdrskin */
int Xorriso_cdrskin(struct XorrisO *xorriso, char *whom, int argc, char **argv,
int flag)
{
int ret, i, k, mem_do_close, aq_ret, eject_ret, msc1, msc2, hflag;
int do_atip= 0, do_checkdrive= 0, do_eject= 0, do_scanbus= 0;
int do_toc= 0, do_verbous= 0, do_version= 0, do_help= 0, do_waiti= 0;
int do_multi= 0, do_msinfo= 0, do_grow= 0, do_isosize= 0, do_xa1= 0;
int do_auto_close= 0;
double write_start_address= -1.0, tsize= -1.0, mem_auto_close;
char *track_source= NULL, *dev_adr= NULL, *cpt;
char mem_report_about_text[80], *report_about= "SORRY", blank_mode[80];
char speed[80], *argpt;
/* cdrecord 2.01 options which are not scheduled for implementation, yet */
static char ignored_partial_options[][41]= {
"timeout=", "debug=", "kdebug=", "kd=", "driver=", "ts=",
"pregap=", "defpregap=", "mcn=", "isrc=", "index=", "textfile=",
"pktsize=", "cuefile=",
"gracetime=",
"assert_write_lba=", "fifo_start_at=", "dev_translation=",
"fallback_program=",
"tao_to_sao_tsize=",
"direct_write_amount=", "msifile=",
""
};
static char ignored_full_options[][41]= {
"-d", "-silent", "-s", "-setdropts", "-prcap",
"-reset", "-abort", "-overburn", "-ignsize", "-useinfo",
"-fix", "-nofix",
"-raw", "-raw96p", "-raw16",
"-clone", "-text",
"-cdi", "-preemp", "-nopreemp", "-copy", "-nocopy",
"-scms", "-shorttrack", "-noshorttrack", "-packet", "-noclose",
"-media-info", "-minfo",
"-load", "-lock", "-raw96r", "-swab",
"-force", "-format",
"--adjust_speed_to_drive", "--allow_emulated_drives", "--allow_setuid",
"--allow_untested_media", "--any_track", "--demand_a_drive",
"--fifo_disable", "--fifo_start_empty", "--fill_up_media",
"--list_ignored_options", "--no_rc", "--no_convert_fs_adr",
"--prodvd_cli_compatible", "--single_track",
"--tell_media_space",
""
};
static char blank_help[][80]= {
"Blanking options:",
"\tall\t\tblank the entire disk",
"\tdisc\t\tblank the entire disk",
"\tdisk\t\tblank the entire disk",
"\tfast\t\tminimally blank the entire disk",
"\tminimal\t\tminimally blank the entire disk",
"\tas_needed\tblank or format medium to make it ready for (re-)use",
"\tdeformat\t\tblank a formatted DVD-RW",
"\tdeformat_quickest\tminimally blank a formatted DVD-RW to DAO only",
"\tformat_overwrite\tformat a DVD-RW to \"Restricted Overwrite\"",
"@End_of_helptexT@"
};
mem_do_close= xorriso->do_close;
mem_auto_close= xorriso->auto_close;
Xorriso_alloc_meM(track_source, char, SfileadrL);
Xorriso_alloc_meM(dev_adr, char, SfileadrL);
strcpy(mem_report_about_text, xorriso->report_about_text);
track_source[0]= 0;
dev_adr[0]= 0;
blank_mode[0]= 0;
speed[0]= 0;
if(xorriso->in_drive_handle != NULL) {
ret= Xorriso_option_dev(xorriso, "", 1|32); /* give up indev */
if(ret!=1)
goto ex;
}
/* Assess plan, make settings */
for(i= 0; i<argc; i++) {
sprintf(xorriso->info_text, "-as %s: ", whom);
Text_shellsafe(argv[i], xorriso->info_text, 1);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0);
argpt= argv[i];
if (strncmp(argpt, "--", 2) == 0 && strlen(argpt) > 3)
argpt++;
for(k=0;ignored_partial_options[k][0]!=0;k++) {
if(argpt[0]=='-')
if(strncmp(argpt+1,ignored_partial_options[k],
strlen(ignored_partial_options[k]))==0) {
argpt++;
goto no_volunteer;
}
if(strncmp(argpt,ignored_partial_options[k],
strlen(ignored_partial_options[k]))==0)
goto no_volunteer;
}
for(k=0;ignored_full_options[k][0]!=0;k++)
if(strcmp(argpt,ignored_full_options[k])==0)
goto no_volunteer;
if(0) {
no_volunteer:;
sprintf(xorriso->info_text, "-as %s: Ignored option ", whom);
Text_shellsafe(argpt, xorriso->info_text, 1);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
continue;
}
if(strcmp(argpt, "-atip")==0) {
do_atip= 1;
} else if(strcmp(argpt, "-audio")==0) {
sprintf(xorriso->info_text, "-as %s: Option -audio not supported.", whom);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
ret= 0; goto ex;
} else if(strncmp(argpt, "-blank=", 7)==0 ||
strncmp(argpt, "blank=", 6)==0) {
cpt= strchr(argpt, '=')+1;
if(strcmp(cpt,"all")==0 || strcmp(cpt,"disc")==0
|| strcmp(cpt,"disk")==0) {
strcpy(blank_mode, "all");
} else if(strcmp(cpt,"fast")==0 || strcmp(cpt,"minimal")==0) {
strcpy(blank_mode, "fast");
} else if(strcmp(cpt,"help")==0) {
strcpy(blank_mode, "help");
} else if(strcmp(cpt,"deformat")==0 ||
strcmp(cpt,"deformat_sequential")==0 ||
strcmp(cpt,"deformat_quickest")==0 ||
strcmp(cpt,"deformat_sequential_quickest")==0) {
strcpy(blank_mode, cpt);
} else if(strcmp(cpt,"format_overwrite")==0) {
strcpy(blank_mode, "format_overwrite");
} else if(strcmp(cpt,"as_needed")==0) {
strcpy(blank_mode, "as_needed");
} else {
sprintf(xorriso->info_text, "-as %s: blank=", whom);
Text_shellsafe(cpt, xorriso->info_text, 1);
strcat(xorriso->info_text, " not supported. See blank=help .");
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
ret= 0; goto ex;
}
} else if(strcmp(argpt, "-checkdrive")==0) {
do_checkdrive= 1;
} else if(strcmp(argpt, "-dao")==0) {
xorriso->do_tao= -1;
} else if(strcmp(argpt, "-data")==0) {
/* ok */;
} else if(strncmp(argpt, "-dev=", 5)==0 ||
strncmp(argpt, "dev=", 4)==0) {
cpt= strchr(argpt, '=')+1;
strcpy(dev_adr, cpt);
} else if(strcmp(argv[i], "--devices")==0) { /* intentional: argv[i] */
do_scanbus= 2;
} else if(strcmp(argv[i], "--drive_not_exclusive") == 0) { /* intentional */
Xorriso_option_drive_access(xorriso, "shared:unrestricted", 0);
} else if(strncmp(argpt,"driveropts=", 11)==0 ||
strncmp(argpt,"-driveropts=", 12)==0) {
if(strcmp(argpt+11, "help")==0) {
fprintf(stderr,"Driver options:\n");
fprintf(stderr,
"burnfree\tPrepare writer to use BURN-Free technology\n");
}
} else if(strcmp(argpt, "-dummy")==0) {
xorriso->do_dummy= 1;
} else if(strncmp(argpt, "-dvd_obs=", 9)==0 ||
strncmp(argpt, "dvd_obs=", 8)==0) {
cpt= strchr(argpt, '=') + 1;
Xorriso_option_dvd_obs(xorriso, cpt, 0);
} else if(strcmp(argpt, "-eject")==0) {
do_eject= 1;
} else if(strncmp(argpt, "-fs=", 4)==0 || strncmp(argpt, "fs=", 3)==0) {
cpt= strchr(argpt, '=')+1;
ret= Xorriso_option_fs(xorriso, cpt, 0);
if(ret<=0)
goto ex;
} else if(strcmp(argv[i], "--grow_overwriteable_iso")==0 ||
strcmp(argv[i], "--grow_overwritable_iso")==0 ||
strcmp(argv[i], "--grow_overriteable_iso")==0
) { /* (A history of typos) */
/* intentional: argv[i] */
do_grow= 1;
} else if(strcmp(argpt, "-help")==0) {
do_help= 1;
} else if(strcmp(argpt, "-isosize")==0) {
do_isosize= 1;
} else if(strcmp(argpt, "-inq")==0) {
do_checkdrive= 2;
} else if(strcmp(argpt, "-mode2")==0) {
Xorriso_msgs_submit(xorriso, 0,
"Defaulting option -mode2 to option -data", 0, "NOTE", 0);
} else if(strcmp(argpt, "-msinfo")==0) {
do_msinfo= 1;
} else if(strcmp(argpt, "-multi")==0) {
do_multi= 1;
do_auto_close= 0;
} else if(strcmp(argv[i], "--multi_if_possible") == 0) {
do_multi= 1;
do_auto_close= 1;
} else if(strcmp(argpt, "-nopad")==0) {
xorriso->padding= 0;
} else if(strcmp(argv[i], "--no_rc")==0) { /* intentional: argv[i] */
/* already performed in Xorriso_prescan_args */;
} else if(strcmp(argpt, "-pad")==0) {
xorriso->padding= 15*2048;
} else if(strncmp(argpt, "-padsize=", 9)==0 ||
strncmp(argpt, "padsize=", 8)==0) {
cpt= strchr(argpt, '=')+1;
ret= Xorriso_option_padding(xorriso, cpt, 0);
if(ret<=0)
goto ex;
} else if(strcmp(argpt, "-sao")==0) {
xorriso->do_tao= -1;
} else if(strcmp(argpt, "-scanbus")==0) {
sprintf(xorriso->info_text, "-as %s: Option -scanbus not supported.",
whom);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
ret= 0; goto ex;
} else if(strncmp(argpt, "-speed=", 7)==0 ||
strncmp(argpt, "speed=", 6)==0) {
cpt= strchr(argpt, '=')+1;
strncpy(speed, cpt, 79);
speed[79]= 0;
} else if(strncmp(argpt, "-stream_recording=", 18)==0 ||
strncmp(argpt, "stream_recording=", 17)==0) {
cpt= strchr(argpt, '=')+1;
Xorriso_option_stream_recording(xorriso, cpt, 0);
} else if(strncmp(argpt, "-use_immed_bit=", 15) == 0 ||
strncmp(argpt, "use_immed_bit=", 14) == 0) {
cpt= strchr(argpt, '=') + 1;
Xorriso_option_use_immed_bit(xorriso, cpt, 0);
} else if(strcmp(argpt, "-immed") == 0) {
Xorriso_option_modesty_on_drive(xorriso, "75", 0);
} else if(strncmp(argpt, "-minbuf=", 8) == 0 ||
strncmp(argpt, "minbuf=", 7) == 0 ||
strncmp(argpt, "-modesty_on_drive=", 18) == 0 ||
strncmp(argpt, "modesty_on_drive=", 17) == 0) {
cpt= strchr(argpt, '=') + 1;
Xorriso_option_modesty_on_drive(xorriso, cpt, 0);
} else if(strncmp(argpt, "-drive_scsi_dev_family=", 23) == 0 ||
strncmp(argpt, "drive_scsi_dev_family=", 22) == 0) {
cpt= strchr(argpt, '=') + 1;
Xorriso_option_scsi_dev_family(xorriso, cpt, 0);
} else if(strncmp(argpt, "-stdio_sync=", 12)==0 ||
strncmp(argpt, "stdio_sync=", 11)==0) {
cpt= strchr(argpt, '=') + 1;
Xorriso_option_stdio_sync(xorriso, cpt, 0);
} else if(strcmp(argpt, "-tao")==0) {
xorriso->do_tao= 1;
} else if(strcmp(argpt, "-toc")==0 || strcmp(argv[i], "--long_toc")==0) {
/* intentional: argpt , argv[i] */
do_toc= 1;
} else if(strncmp(argpt, "-tsize=", 7)==0 ||
strncmp(argpt, "tsize=", 6)==0) {
cpt= strchr(argpt, '=')+1;
tsize= Scanf_io_size(cpt, 1);
if(tsize > 1024.0*1024.0*1024.0*1024.0*1024.0) {
sprintf(xorriso->info_text, "-as %s: much too large: %s",whom, argpt);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
ret= 0; goto ex;
}
} else if(strcmp(argv[i], "-V")==0 || strcmp(argpt,"-Verbose")==0) {
Xorriso_option_scsi_log(xorriso, "on", 0);
} else if(strcmp(argv[i], "-v")==0 || strcmp(argpt,"-verbose")==0) {
do_verbous++;
} else if(strcmp(argv[i], "-vv")==0) { /* intentional: argv[i] */
do_verbous+= 2;
} else if(strcmp(argv[i], "-vvv")==0) { /* intentional: argv[i] */
do_verbous+= 3;
} else if(strcmp(argpt, "-version")==0) {
do_version= 1;
} else if(strcmp(argpt, "-waiti")==0) {
do_waiti= 1;
} else if(strncmp(argv[i], "write_start_address=", 20)==0) {
/* intentional: argv[i] */
write_start_address= Scanf_io_size(argv[i]+20,0);
} else if(strcmp(argpt, "-xa")==0) {
Xorriso_msgs_submit(xorriso, 0,
"Defaulting option -xa to option -data", 0, "NOTE", 0);
} else if(strcmp(argpt, "-xa1")==0) {
if(do_xa1 == 0)
do_xa1= 1;
} else if(strcmp(argv[i], "--xa1-ignore")==0) { /* intentional: argv[i] */
do_xa1= -1;
} else if(strcmp(argpt, "-xa2")==0) {
Xorriso_msgs_submit(xorriso, 0,
"Defaulting option -xa2 to option -data", 0, "NOTE", 0);
} else if(strcmp(argpt, "-xamix")==0) {
Xorriso_msgs_submit(xorriso, 0,
"Option -xamix not implemented and data not yet convertible to other modes",
0, "FATAL", 0);
ret= 0; goto ex;
} else if(argpt[0]=='-' && argpt[1]!=0) {
sprintf(xorriso->info_text, "-as %s: Unknown option ", whom);
Text_shellsafe(argv[i], xorriso->info_text, 1);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
ret= 0; goto ex;
} else {
if(track_source[0]) {
sprintf(xorriso->info_text, "-as %s: Surplus track source ", whom);
Text_shellsafe(argv[i], xorriso->info_text, 1);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
sprintf(xorriso->info_text, "First and only track source is ");
Text_shellsafe(track_source, xorriso->info_text, 1);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
ret= 0; goto ex;
}
if(Sfile_str(track_source, argv[i], 0)<=0)
{ret= -1; goto ex;}
}
}
/* Perform actions */
Xorriso_option_report_about(xorriso, "NOTE", 0);
if(do_version) {
sprintf(xorriso->result_line, "Cdrecord 2.01-Emulation Copyright (C) 2019 see libburnia-project.org xorriso\n");
Xorriso_result(xorriso, 1);
Xorriso_option_version(xorriso, 0);
}
if(do_help) {
Xorriso_cdrskin_help(xorriso, 0);
}
if(strcmp(blank_mode, "help")==0) {
for(i= 0; strcmp(blank_help[i], "@End_of_helptexT@")!=0; i++) {
sprintf(xorriso->info_text, "%s\n", blank_help[i]);
Xorriso_info(xorriso,0);
}
}
if(do_help || strcmp(blank_mode, "help") == 0 || do_version) {
ret= 1; goto ex;
}
if(do_verbous<=0)
report_about= "NOTE";
else if(do_verbous<=2)
report_about= "UPDATE";
else if(do_verbous==3)
report_about= "DEBUG";
else
report_about= "ALL";
Xorriso_option_report_about(xorriso, report_about, 0);
if(do_scanbus) {
if(do_scanbus==1)
/* >>> would need -scanbus compatible output and input format */;
else
Xorriso_option_devices(xorriso, 0);
ret= 1; goto ex;
}
if(!(do_checkdrive || do_atip || do_toc || blank_mode[0] || track_source[0] ||
do_eject || do_msinfo)) {
sprintf(xorriso->info_text,
"-as cdrskin: No option specified, which would cause an action.");
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0);
ret= 1; goto ex;
}
if(do_waiti) {
sprintf(xorriso->info_text,
"xorriso: Option -waiti pauses program until input appears at stdin\n");
Xorriso_info(xorriso,0);
sprintf(xorriso->result_line, "Waiting for data on stdin...\n");
Xorriso_result(xorriso, 1);
for(ret= 0; ret==0; )
ret= Wait_for_input(0,1000000,0);
if(ret<0 || feof(stdin)) {
Xorriso_msgs_submit(xorriso, 0,
"stdin produces exception rather than data", 0, "NOTE", 0);
}
sprintf(xorriso->info_text, "xorriso: Option -waiti pausing is done.\n");
}
if(dev_adr[0]) {
hflag= 2 | 64; /* ts B11201 no more: | 32 */
if(!do_grow)
hflag|= 8; /* consider overwritables as blank */
ret= Xorriso_option_dev(xorriso, dev_adr, hflag);
if(ret<=0)
goto ex;
}
if(xorriso->out_drive_handle==NULL) {
sprintf(xorriso->info_text, "-as %s: No output drive selected", whom);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
ret= 0; goto ex;
}
if(do_msinfo) {
ret= Xorriso_msinfo(xorriso, &msc1, &msc2, 2 | !!do_grow);
if(ret<=0)
goto ex;
sprintf(xorriso->result_line, "%d,%d\n", msc1, msc2);
Xorriso_result(xorriso, 1);
}
if(speed[0]) {
ret= Xorriso_option_speed(xorriso, speed, 0);
if(ret<=0)
goto ex;
}
if(do_checkdrive) {
ret= Xorriso_atip(xorriso, 2-(do_checkdrive==2));
if(ret<=0)
goto ex;
}
if(do_atip) {
ret= Xorriso_atip(xorriso, 0);
if(ret<=0)
goto ex;
}
if(do_toc) {
ret= Xorriso_option_toc(xorriso, 0);
if(ret<=0)
goto ex;
}
if(strcmp(blank_mode, "format_overwrite")==0) {
ret= Xorriso_option_blank(xorriso, "fast", 1);
if(ret<=0)
goto ex;
} else if(blank_mode[0]) {
ret= Xorriso_option_blank(xorriso, blank_mode, 0);
if(ret<=0)
goto ex;
}
if(track_source[0]) {
xorriso->do_close= !do_multi;
xorriso->auto_close= do_auto_close;
ret= Xorriso_burn_track(xorriso, (off_t) write_start_address,
track_source, (off_t) tsize,
(!!do_grow) | ((!!do_isosize) << 1) | ((do_xa1 == 1) << 2));
if(ret == 2) {
ret= Xorriso_retry_burn_track(xorriso, (off_t) write_start_address,
track_source, (off_t) tsize,
(!!do_grow) | ((!!do_isosize) << 1) | ((do_xa1 == 1) << 2));
}
aq_ret= Xorriso_reaquire_outdev(xorriso, 2*(ret>0));
if(ret<=0 && ret<aq_ret)
goto ex;
if(aq_ret<=0)
{ret= aq_ret; goto ex;}
}
ret= 1;
ex:;
if(do_eject && ret>=0) {
eject_ret= Xorriso_option_eject(xorriso, "out", 0);
if(eject_ret<ret)
ret= eject_ret;
}
if(ret<=0) {
sprintf(xorriso->info_text, "-as %s: Job could not be performed properly.",
whom);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
}
Xorriso_option_report_about(xorriso, mem_report_about_text, 0);
xorriso->do_close= mem_do_close;
xorriso->auto_close= mem_auto_close;
Xorriso_free_meM(dev_adr);
Xorriso_free_meM(track_source);
return(ret);
}
/* This function shall know all options of mkisofs, genisoimage, xorrisofs, ...
and the number of arguments which they expect and consume.
*/
int Xorriso_genisofs_count_args(struct XorrisO *xorriso, int argc, char **argv,
int *count, int flag)
{
int i;
char *cmd;
static char partial_options[][41]= {
"errctl=",
"isolinux_mbr=", "--modification-date=",
""
};
static char arg0_options[][41]= {
"-allow-leading-dots", "-ldots", "-allow-lowercase", "-allow-multidot",
"-cache-inodes", "-no-cache-inodes", "-eltorito-alt-boot",
"-hard-disk-boot", "-no-emul-boot", "-no-boot", "-boot-info-table",
"-check-oldnames", "-d", "-D", "-dvd-video", "-f", "-gui", "-graft-points",
"-hide-joliet-trans-tbl", "-hide-rr-moved", "-J", "-joliet-long", "-l",
"-L", "-max-iso9660-filenames", "-N", "-nobak", "-no-bak",
"-no-limit-pathtables", "-force-rr", "-no-rr",
"-no-split-symlink-components", "-no-split-symlink-fields", "-pad",
"-no-pad", "-posix-H", "-posix-L", "-posix-P", "-print-size",
"-quiet", "-R", "-r", "-relaxed-filenames", "-rrip110", "-rrip112",
"-split-output", "-T", "-UDF", "-udf", "-udf-symlinks", "-no-udf-symlinks",
"-U", "-no-iso-translate", "-v", "-XA", "-xa", "-z",
"-hfs", "-no-hfs", "-apple", "-probe", "-no-desktop", "-mac-name",
"-part", "-icon-position", "-chrp-t", "-hfs-unlock", "--cap", "--netatalk",
"--double", "--ethershare", "--ushare", "--exchange", "--sgi", "--xinet",
"--macbin", "--single", "--dave", "--sfm", "--osx-double", "--osx-hfs",
"-debug", "-omit-period", "-disable-deep-relocation", "-joliet",
"-full-iso9660-filenames", "-follow-links", "-help",
"-transparent-compression",
"-omit-version-number", "-rational-rock", "-rock", "-translation-table",
"-untranslated-filenames", "-verbose", "-version", "-g", "-h",
"-no-mac-files", "-chrp-boot",
"--hardlinks", "--acl", "--xattr", "--xattr-any", "--md5", "--for_backup",
"--protective-msdos-label", "--boot-catalog-hide", "--no-emul-toc",
"--emul-toc", "-disallow_dir_id_ext", "--old-empty",
"--old-root-no-md5", "--old-root-devno", "--old-root-no-ino",
"--no_rc", "--norock", "-hfsplus", "-fat", "-chrp-boot-part",
"-isohybrid-gpt-basdat", "-isohybrid-gpt-hfsplus",
"-isohybrid-apm-hfsplus", "--grub2-boot-info", "-joliet-utf16",
"-appended_part_as_gpt", "-appended_part_as_apm", "--mbr-force-bootable",
"-part_like_isohybrid",
""
};
static char arg1_options[][41]= {
"-abstract", "-A", "-appid", "--application_use",
"-biblio", "-b", "-B", "-boot-load-seg",
"-boot-load-size", "-C", "-c", "-check-session", "-copyright",
"-dir-mode", "-eltorito-id", "-eltorito-selcrit",
"-file-mode", "-G", "-gid", "-hide", "-hide-list",
"-hidden", "-hidden-list", "-hide-joliet", "-hide-joliet-list",
"-hide-hfsplus", "-hide-hfsplus-list",
"-hide-udf", "-hide-udf-list", "-input-charset", "-output-charset",
"-iso-level", "-jcharset", "-log-file", "-m", "-exclude-list", "-M",
"-dev", "-new-dir-mode", "-o", "-p", "-preparer",
"-path-list", "-publisher", "-root",
"-old-root", "-s", "-sectype", "-sort", "-sparc-boot", "-sparc-label",
"-stream-media-size", "-stream-file-name", "-sunx86-boot", "-sunx86-label",
"-sysid", "-table-name", "-ucs-level", "-uid", "-V", "-volset",
"-volset-size", "-volset-seqno", "-x", "-P",
"-map", "-magic", "-hfs-creator", "-hfs-type", "-boot-hfs-file", "-auto",
"-cluster-size", "-hide-hfs", "-hide-hfs-list", "-hfs-volid",
"-root-info", "-prep-boot", "-input-hfs-charset", "-output-hfs-charset",
"-hfs-bless", "-hfs-parms",
"-eltorito-boot", "-generic-boot", "-eltorito-catalog", "-cdrecord-params",
"-errctl", "-exclude", "-prev-session", "-output", "-use-fileversion",
"-volid", "-old-exclude",
"-alpha-boot", "-hppa-cmdline", "-hppa-kernel-32", "-hppa-kernel-64",
"-hppa-bootloader", "-hppa-ramdisk", "-mips-boot", "-mipsel-boot",
"-jigdo-jigdo", "-jigdo-template", "-jigdo-min-file-size",
"-jigdo-force-md5", "-jigdo-force-checksum",
"-md5-list", "-checksum-list",
"-jigdo-exclude", "-jigdo-map",
"-jigdo-template-compress", "-jigdo-checksum-algorithm",
"-checksum_algorithm_iso", "-checksum_algorithm_template",
"--stdio_sync", "--quoted_path_list", "--efi-boot", "--embedded-boot",
"-isohybrid-mbr", "-e", "-partition_offset", "-partition_hd_cyl",
"-partition_sec_hd", "-partition_cyl_align", "-untranslated_name_len",
"-rr_reloc_dir", "-hfsplus-serial-no", "-prep-boot-part", "-efi-boot-part",
"-hfsplus-block-size", "-apm-block-size", "--grub2-mbr",
"--grub2-sparc-core", "--sort-weight-list", "--sort-weight-patterns",
"-hppa-hdrversion", "-file_name_limit", "--set_all_file_dates",
"--gpt_disk_guid", "-iso_mbr_part_type", "-eltorito-platform",
""
};
static char arg2_options[][41]= {
"-hfs-bless-by", "--scdbackup_tag", "--sort-weight",
""
};
static char arg3_options[][41]= {
"-append_partition", "-hfsplus-file-creator-type",
""
};
static char final_options[][41]= {
"-find",
""
};
cmd= argv[0];
*count= 0;
for(i=0; partial_options[i][0]!=0; i++)
if(strncmp(partial_options[i], cmd, strlen(partial_options[i]))==0)
return(1);
for(i=0; arg0_options[i][0]!=0; i++)
if(strcmp(arg0_options[i], cmd)==0)
return(1);
*count= 1;
for(i=0; arg1_options[i][0]!=0; i++)
if(strcmp(arg1_options[i], cmd)==0)
return(1);
*count= 2;
for(i=0; arg2_options[i][0]!=0; i++)
if(strcmp(arg2_options[i], cmd)==0)
return(1);
*count= 3;
for(i=0; arg3_options[i][0]!=0; i++)
if(strcmp(arg3_options[i], cmd)==0)
return(1);
*count= argc - 1;
for(i=0; final_options[i][0]!=0; i++)
if(strcmp(final_options[i], cmd)==0)
return(1);
*count= 0;
return(0);
}
/* @param flag bit0= do not report eventual ignore decision
*/
int Xorriso_genisofs_ignore(struct XorrisO *xorriso, char *whom,
char *argpt, 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-multidot",
"-cache-inodes", "-check-oldnames",
"-L", "-no-bak", "-no-cache-inodes",
"-no-split-symlink-components", "-no-split-symlink-fields", "-nobak",
"-force-rr", "-T",
"-no-iso-translate",
""
};
static char ignored_arg1_options[][41]= {
"-check-session", "-hide-hfs", "-hide-hfs-list",
"-table-name", "-volset-seqno", "-volset-size", "-sort",
""
};
int k;
for(k=0;ignored_arg0_options[k][0]!=0;k++)
if(strcmp(argpt,ignored_arg0_options[k])==0)
goto no_volunteer;
for(k=0;ignored_arg1_options[k][0]!=0;k++)
if(strcmp(argpt,ignored_arg1_options[k])==0) {
(*i)++;
goto no_volunteer;
}
return(0);
no_volunteer:;
sprintf(xorriso->info_text, "-as %s: Ignored option ", whom);
Text_shellsafe(argpt, xorriso->info_text, 1);
if(!(flag & 1))
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
return(1);
}
int Xorriso_genisofs_add_boot(struct XorrisO *xorriso, int flag)
{
int ret;
if(xorriso->boot_img_size_default && xorriso->boot_image_emul == 0)
xorriso->boot_img_full_size= 1;
ret= Xorriso_attach_boot_image(xorriso, 0);
if(ret <= 0)
xorriso->boot_image_bin_path[0]= 0;
return(ret);
}
int Xorriso_genisofs_help(struct XorrisO *xorriso, int flag)
{
static char helptext[][160]= {
"Usage: xorriso -as mkisofs [options] file...",
"Note: This is not mkisofs. See xorriso -help, xorriso -version, man xorrisofs",
"Options:",
" -f, -follow-links Follow symbolic links",
" -graft-points Allow to use graft points for filenames",
" -help Print option help",
" -hfsplus Generate HFS+ filesystem",
" -hfsplus-file-creator-type CREATOR TYPE iso_rr_path",
" Attach creator and type to a File",
" -hfs-bless FOLDER_NAME Name of Folder to be blessed",
" -hfs-bless-by BLESS_TYPE ISO_RR_PATH",
" Bless ISO_RR_PATH by BLESS_TYPE {p,i,s,9,x}",
" -hfsplus-serial-no HEXSTRING",
" HFS serial number: 16 characters [0-9a-fA-F]",
" -hfsplus-block-size NUMBER Set HFS+ block size",
" -apm-block-size NUMBER Set Apple Partition Map block size",
" -hide GLOBFILE Hide ISO9660/RR file",
" -hide-list FILE File with list of ISO9660/RR files to hide",
" -hide-joliet GLOBFILE Hide Joliet file",
" -hide-joliet-list FILE File with list of Joliet files to hide",
" -hide-hfsplus GLOBFILE Hide HFS+ file",
" -hide-hfsplus-list FILE File with list of HFS+ files to hide",
" -input-charset CHARSET Local input charset for file name conversion",
" -output-charset CHARSET Output charset for file name conversion",
" -iso-level LEVEL Set ISO9660 conformance level (1..3) or 4 for ISO9660 version 2",
" -disallow_dir_id_ext Do not allow dot in ISO directory names",
" -J, -joliet Generate Joliet directory information",
" -joliet-long Allow Joliet file names to be 103 Unicode characters",
" -joliet-utf16 Encode Joliet names in UTF-16BE rather than UCS-2",
" -U, -untranslated-filenames Allow Untranslated filenames (for HPUX & AIX - violates ISO9660).",
" -untranslated_name_len LEN Allow up to LEN (1..96) name characters (heavily violates ISO9660).",
" -allow-lowercase Allow lower case characters in addition to the current character set (violates ISO9660)",
" -relaxed-filenames Allow 7 bit ASCII except lower case characters (violates ISO9660)",
" -d, -omit-period Omit trailing periods from filenames (violates ISO9660)",
" -l, -full-iso9660-filenames Allow full 31 character filenames for ISO9660 names",
" -max-iso9660-filenames Allow 37 character filenames for ISO9660 names (violates ISO9660)",
" -N, -omit-version-number Omit version number from ISO9660 filename (violates ISO9660)",
" -D, -disable-deep-relocation",
" Disable deep directory relocation (violates ISO9660)",
" -hide-rr-moved Relocate deep directories to /.rr_moved",
" -rr_reloc_dir NAME Set deep directory relocation target in root",
" -uid uid Make the owner of all files this uid.",
" -gid gid Make the group owner of all files this gid.",
" -o FILE, -output FILE Set output file name",
" -m GLOBFILE, -exclude GLOBFILE",
" Exclude file name",
" -x FILE, -old-exclude FILE Exclude file name",
" -exclude-list FILE File with list of file names to exclude",
" -pad Pad output by 300k (default)",
" -no-pad Do not pad output",
" -M FILE, -prev-session FILE Set path to previous session to merge",
" -C PARAMS, -cdrecord-params PARAMS",
" Magic paramters from cdrecord",
" -dir-mode mode Make the mode of all directories this mode.",
" -file-mode mode Make the mode of all plain files this mode.",
" -path-list FILE File with list of pathnames to process",
" --quoted_path_list FILE File with list of quoted pathnames to process",
" -print-size Print estimated filesystem size and exit",
" -quiet Run quietly",
" -gui Switch behaviour for GUI",
" -R, -rock Generate Rock Ridge directory information",
" -r, -rational-rock Generate rationalized Rock Ridge directory information",
" --norock Disable Rock Ridge. (Strongly discouraged !)",
" -file_name_limit LEN Set truncation limit for Rock Ridge names",
" --hardlinks Record eventual hard link relations of files",
" --acl Record eventual ACLs of files",
" --xattr Record eventual user space xattr of files",
" --xattr-any Record xattr of any namespace, not only user.",
" --md5 Compute and record MD5 checksums of data files",
" --scdbackup_tag PATH NAME With --md5 record a scdbackup checksum tag",
" --for_backup Use all options which improve backup fidelity",
" -V ID, -volid ID Set Volume ID",
" -volset ID Set Volume set ID",
" -publisher PUB Set Volume publisher",
" -A ID, -appid ID Set Application ID",
" -sysid ID Set System ID",
" -p PREP, -preparer PREP Set Volume preparer",
" -abstract FILE Set Abstract filename",
" -biblio FILE Set Bibliographic filename",
" -copyright FILE Set Copyright filename",
" --application_use CHAR|PATH Set content of Application Use field",
" -jigdo-jigdo FILE Produce a jigdo .jigdo file as well as the .iso",
" -jigdo-template FILE Produce a jigdo .template file as well as the .iso",
" -jigdo-min-file-size SIZE Minimum size for a file to be listed in the jigdo file",
" -jigdo-force-checksum PTRN Pattern(s) where files MUST match an externally-supplied checksum",
" -jigdo-force-md5 PATTERN Outdated alias of -jigdo-force-checksum",
" -jigdo-exclude PATTERN Pattern(s) to exclude from the jigdo file",
" -jigdo-map PATTERN1=PATTERN2",
" Pattern(s) to map paths (e.g. Debian=/mirror/debian)",
" -checksum-list FILE File containing checksums of the files that should be checked",
" -md5-list FILE Outdated alias of -checksum-list",
" -jigdo-checksum-algorithm ALGORITHM",
" Choose algorithm for file matching checksums: md5, sha256",
" Expected in the -checksum-list FILE, written into .jigdo file.",
" -jigdo-template-compress ALGORITHM",
" Choose to use gzip or bzip2 compression for template data; default is gzip",
" -checksum_algorithm_iso alg1,alg2,...",
" Specify the checksum types desired for the output image (in .jigdo)",
" -checksum_algorithm_template alg1,alg2,...",
" Specify the checksum types desired for the output jigdo template",
" -eltorito-platform Set El Torito platform id for the next boot entry",
" -b FILE, -eltorito-boot FILE",
" Set El Torito boot image name",
" -eltorito-alt-boot Start specifying alternative El Torito boot parameters",
" --efi-boot FILE Set El Torito EFI boot image name and type",
" -e FILE Set EFI boot image name (more rawly)",
" -c FILE, -eltorito-catalog FILE",
" Set El Torito boot catalog name",
" --boot-catalog-hide Hide boot catalog from ISO9660/RR and Joliet",
" -boot-load-size # Set numbers of load sectors",
" -hard-disk-boot Boot image is a hard disk image",
" -no-emul-boot Boot image is 'no emulation' image",
" -boot-info-table Patch boot image with info table",
" --grub2-boot-info Patch boot image at byte 2548",
" -eltorito-id ID Set El Torito Id String",
" -eltorito-selcrit HEXBYTES Set El Torito Selection Criteria",
" -isohybrid-gpt-basdat Mark El Torito boot image as Basic Data in GPT",
" -isohybrid-gpt-hfsplus Mark El Torito boot image as HFS+ in GPT",
" -isohybrid-apm-hfsplus Mark El Torito boot image as HFS+ in APM",
" -part_like_isohybrid Mark in MBR, GPT, APM without -isohybrid-mbr",
" -iso_mbr_part_type Set type byte or GUID of ISO partition in MBR",
" or type GUID if a GPT ISO partition emerges.",
" --gpt_disk_guid GUID Set GPT disk GUID or choose automatic GUID",
" -G FILE, -generic-boot FILE Set generic boot image name",
" --embedded-boot FILE Alias of -G",
" --protective-msdos-label Patch System Area by partition table",
" --mbr-force-bootable Enforce existence of bootable flag in MBR",
" -partition_offset LBA Make image mountable by first partition, too",
" -partition_sec_hd NUMBER Define number of sectors per head",
" -partition_hd_cyl NUMBER Define number of heads per cylinder",
" -partition_cyl_align MODE Control cylinder alignment: off, on, auto, all",
" -mips-boot FILE Set mips boot image name (relative to image root)",
" -mipsel-boot FILE Set mipsel boot image name (relative to image root)",
" -B FILES, -sparc-boot FILES Set sparc boot image names",
" -sparc-label label text Set sparc boot disk label",
" -hppa-cmdline CMDLINE Set hppa boot command line",
" -hppa-kernel-32 FILE Set hppa 32-bit image name (relative to image root)",
" -hppa-kernel-64 FILE Set hppa 64-bit image name (relative to image root)",
" -hppa-bootloader FILE Set hppa boot loader file name (relative to image root)",
" -hppa-ramdisk FILE Set hppa ramdisk file name (relative to image root)",
" -hppa-hdrversion NUMBER Set hppa PALO header version to 4 or 5",
" -alpha-boot FILE Set alpha boot image name (relative to image root)",
" --grub2-sparc-core FILE Set path of core file for disk label patching",
" -efi-boot-part DISKFILE|--efi-boot-image",
" Set data source for EFI System Partition",
" -chrp-boot-part Mark ISO image size by MBR partition type 0x96",
" -chrp-boot Alias of -chrp-boot-part",
" -prep-boot-part DISKFILE Set data source for MBR partition type 0x41",
" -append_partition NUMBER TYPE FILE",
" Append FILE after image. TYPE is hex: 0x.. or",
" a GUID to be used if -appended_part_as_gpt.",
" -appended_part_as_gpt mark appended partitions in GPT instead of MBR.",
" -appended_part_as_apm mark appended partitions in APM.",
" --modification-date=YYYYMMDDhhmmsscc",
" Override date of creation and modification",
" --set_all_file_dates TIME Override mtime, atime, ctime in all files",
" -isohybrid-mbr FILE Set SYSLINUX mbr/isohdp[fp]x*.bin for isohybrid",
" --grub2-mbr FILE Set GRUB2 MBR for boot image address patching",
#ifdef Xorriso_with_isohybriD
" isolinux_mbr=on|auto|off Control eventual isohybrid MBR generation",
#endif
" --sort-weight NUMBER FILE Set LBA weight number to file or file tree",
" --sort-weight-list DISKFILE Read list of NUMBER FILE pairs for --sort-weight",
" --sort-weight-patterns DISKFILE --sort-weight-list with pattern expansion",
" --stdio_sync on|off|number Control forced output to disk files",
" --no-emul-toc Save 64 kB size on random access output files",
" --emul-toc Multi-session history on such output files",
" --old-empty Use old style block addresses for empty files",
" -z, -transparent-compression",
" Enable transparent compression of files",
" -root DIR Set root directory for all new files and directories",
" -old-root DIR Set root directory in previous session that is searched for files",
" --old-root-no-md5 Do not record and use MD5 with -old-root",
" --old-root-no-ino Do not use disk inode numbers with -old-root",
" --old-root-devno Use disk device numbers with -old-root",
" -log-file LOG_FILE Re-direct messages to LOG_FILE",
" --no_rc Do not execute startup files",
" -v, -verbose Verbose",
" -version Print the current version",
"",
#ifdef Xorriso_GNU_xorrisO
"Report bugs to: bug-xorriso@gnu.org , or in private to: scdbackup@gmx.net .",
"xorriso home page: <https://www.gnu.org/software/xorriso/>",
"General help using GNU software: <https://www.gnu.org/gethelp/>",
#else
"Report any bugs to bug-xorriso@gnu.org or in private to scdbackup@gmx.net .",
#endif
"@End_of_helptexT@"
};
char ra_text[80];
int i;
strcpy(ra_text, xorriso->report_about_text);
Xorriso_option_report_about(xorriso, "NOTE", 0);
for(i= 0; strcmp(helptext[i], "@End_of_helptexT@")!=0; i++) {
sprintf(xorriso->info_text, "%s\n", helptext[i]);
Xorriso_info(xorriso, 1 | 2);
}
Xorriso_option_report_about(xorriso, ra_text, 0);
return(1);
}
/* Perform hiding.
Cumbersome: The paths and patterns apply to the disk address and not
to the Rock Ridge address. Actually even the literal form of the
mkisofs pathspec would matter (e.g. "./" versus "").
But xorriso normalizes disk_paths before further processing. Thus
the literal form does not matter.
@param hide_attrs
bit0= hide in ISO/RR
bit1= hide in Joliet
bit2= hide in HFS+
bit3 to bit5 are reserved for future hidings
*/
int Xorriso_genisofs_hide(struct XorrisO *xorriso, char *whom,
char *pattern, int hide_attrs, int flag)
{
int zero= 0, ret;
char *argv[1];
if((hide_attrs & 63) == 0)
return(2);
if(strchr(pattern, '/') != NULL) {
argv[0]= pattern;
ret= Xorriso_option_not_paths(xorriso, 1, argv, &zero,
4 | ((hide_attrs & 63) << 8));
} else {
ret= Xorriso_option_not_leaf(xorriso, pattern, hide_attrs & 63);
}
return(ret);
}
/* @param flag bit0= quoted list */
int Xorriso_genisofs_hide_list(struct XorrisO *xorriso, char *whom,
char *adr, int hide_attrs, int flag)
{
int ret, linecount= 0, argc= 0, was_failure= 0, i, fret;
char **argv= NULL, *id= "";
FILE *fp= NULL;
if(adr[0]==0) {
if (hide_attrs & 2)
id = "joliet-";
else if (hide_attrs & 4)
id = "hfsplus-";
sprintf(xorriso->info_text,
"Empty file name given with -as %s -hide-%slist", whom, id);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING", 0);
return(0);
}
ret= Xorriso_afile_fopen(xorriso, adr, "rb", &fp, 0);
if(ret <= 0)
return(0);
while(1) {
ret= Xorriso_read_lines(xorriso, fp, &linecount, &argc, &argv,
4 | (flag & 1) );
if(ret <= 0)
goto ex;
if(ret == 2)
break;
for(i= 0; i < argc; i++) {
if(argv[i][0] == 0)
continue;
ret= Xorriso_genisofs_hide(xorriso, whom, argv[i], hide_attrs, 0);
if(ret <= 0 || xorriso->request_to_abort) {
was_failure= 1;
fret= Xorriso_eval_problem_status(xorriso, ret, 1|2);
if(fret>=0)
continue;
if(ret > 0)
ret= 0;
goto ex;
}
}
}
ret= 1;
ex:;
Xorriso_read_lines(xorriso, fp, &linecount, &argc, &argv, 2);
if(fp != NULL && fp != stdin)
fclose(fp);
if(ret<=0)
return(ret);
return(!was_failure);
}
/* Strip surplus dash from known single-dash long options */
int Xorriso_genisofs_strip_dash(struct XorrisO *xorriso, char *arg_in,
char **arg_out, int flag)
{
int ret, count;
char *argv[1];
*arg_out= arg_in;
if(strlen(arg_in) < 4)
return(1);
if(arg_in[0] != '-' || arg_in[1] != '-' || arg_in[2] == '-')
return(1);
argv[0]= arg_in + 1;
ret= Xorriso_genisofs_count_args(xorriso, 1, argv, &count, 0);
if(ret > 0)
*arg_out= arg_in + 1;
return(1);
}
/* Interprets a string of single-char options which have no parameters
@param flag bit0=check whether string is ok
bit1=this is pass 1
@return with flag bit0: 0=no , 1=yes, 2= with bit1: non-pass-1 options seen
else : 1 = ok , <= 0 indicates error
*/
int Xorriso_genisofs_fused_options(struct XorrisO *xorriso, char *whom,
char *opts,
int *option_d, int *iso_level, int *lower_r,
char ra_text[80], int flag)
{
int ret, non_pass1= 0;
char *cpt;
static char pass1_covered[]= {"fvz"};
static char covered[]= {"dDfJlNRrTUvz"};
if(flag & 1) {
for(cpt= opts; *cpt != 0; cpt++) {
if(strchr(covered, *cpt) == NULL)
{ret= 0; goto ex;}
if(flag & 2)
if(strchr(pass1_covered, *cpt) == NULL)
non_pass1= 1;
}
ret= 1 + non_pass1; goto ex;
}
for(cpt= opts; *cpt != 0; cpt++) {
if(*cpt == 'd') {
if(flag & 2)
continue;
Xorriso_relax_compliance(xorriso, "no_force_dots", 0);
} else if(*cpt == 'D') {
if(flag & 2)
continue;
*option_d= 1;
} else if(*cpt == 'f') {
if(!(flag & 2))
continue;
ret= Xorriso_option_follow(xorriso, "on", 0);
if(ret <= 0)
goto ex;
} else if(*cpt == 'J') {
if(flag & 2)
continue;
xorriso->do_joliet= 1;
} else if(*cpt == 'l') {
if(flag & 2)
continue;
if(xorriso->iso_level <= 2)
Xorriso_relax_compliance(xorriso, "iso_9660_level=2", 0);
if(*iso_level <= 2)
*iso_level= 2;
} else if(*cpt == 'N') {
if(flag & 2)
continue;
Xorriso_relax_compliance(xorriso, "omit_version", 0);
} else if(*cpt == 'R') {
if(flag & 2)
continue;
xorriso->do_rockridge= 1;
} else if(*cpt == 'r') {
if(flag & 2)
continue;
xorriso->do_rockridge= 1;
*lower_r= 1;
} else if(*cpt == 'T') {
/* ignored */;
} else if(*cpt == 'U') {
if(flag & 2)
continue;
Xorriso_relax_compliance(xorriso,
"no_force_dots:long_paths:long_names:omit_version:full_ascii:lowercase",
0);
} else if(*cpt == 'v') {
if(!(flag & 2))
continue;
strcpy(ra_text, "UPDATE");
} else if(*cpt == 'z') {
if(!(flag & 2))
continue;
Xorriso_option_zisofs(xorriso, "by_magic=on", 0);
} else {
sprintf(xorriso->info_text, "-as %s: Unsupported option -%c", whom, *cpt);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
ret= 0; goto ex;
}
}
ret= 1;
ex:;
return(ret);
}
/* Implementing mkisofs tendency to map single-path pathspecs to / */
int Xorriso_graftable_pathspec(struct XorrisO *xorriso, char *in_pathspec,
char *pathspec, int flag)
{
int ret, l;
char *esc_wdx= NULL, *eff_path= NULL, *ept;
if((!xorriso->allow_graft_points) ||
Fileliste__target_source_limit(in_pathspec, '=', &ept, 0) <= 0) {
Xorriso_alloc_meM(esc_wdx, char, SfileadrL);
Xorriso_alloc_meM(eff_path, char, SfileadrL);
strcpy(esc_wdx, xorriso->wdx);
if(!xorriso->allow_graft_points) {
ret= Fileliste__escape_source_path(esc_wdx, SfileadrL, 0);
if(ret <= 0) {
Xorriso_msgs_submit(xorriso, 0,
"Escaped -cdx directory gets much too long", 0, "FAILURE", 0);
ret= 0; goto ex;
}
}
ret= Xorriso_normalize_img_path(xorriso, esc_wdx, in_pathspec,
eff_path, 2|4);
if(ret <= 0)
{ret= 0; goto ex;}
ret= Sfile_type(eff_path,
1 | ((xorriso->do_follow_param || xorriso->do_follow_links) << 2));
if(ret == 2) {
strcpy(pathspec, "/=");
} else {
pathspec[0]= '/';
pathspec[1]= 0;
ret= Sfile_leafname(eff_path, pathspec + 1, 0);
if(ret>0) {
if(!xorriso->allow_graft_points) {
ret= Fileliste__escape_source_path(pathspec, SfileadrL, 0);
if(ret <= 0) {
Xorriso_msgs_submit(xorriso, 0,
"Escaped leaf name gets much too long", 0, "FAILURE", 0);
ret= 0; goto ex;
}
}
strcat(pathspec, "=");
} else
pathspec[0]= 0;
}
l= strlen(pathspec);
strcat(pathspec, eff_path);
if(!xorriso->allow_graft_points) {
ret= Fileliste__escape_source_path(pathspec + l, 2 * SfileadrL - l, 0);
if(ret <= 0) {
Xorriso_msgs_submit(xorriso, 0,
"Escaped path gets much too long", 0, "FAILURE", 0);
ret= 0; goto ex;
}
}
} else {
Sfile_str(pathspec, in_pathspec, 0);
}
ret= 1;
ex:;
Xorriso_free_meM(esc_wdx);
Xorriso_free_meM(eff_path);
return(ret);
}
int Xorriso_genisofs_path_pecul(struct XorrisO *xorriso, int *was_path,
int with_emul_toc, int *allow_dir_id_ext,
int *iso_level, int flag)
{
char *sfe= NULL;
int ret;
if(*was_path) {
ret= 1; goto ex;
}
*was_path= 1;
Xorriso_alloc_meM(sfe, char, 5*SfileadrL);
/* Enforce odd mkisofs defaults on first pathspec */
xorriso->pacifier_style= 1;
if(xorriso->allow_dir_id_ext_dflt && *allow_dir_id_ext < 0)
*allow_dir_id_ext= 1;
if(*allow_dir_id_ext == 1) {
Xorriso_relax_compliance(xorriso, "allow_dir_id_ext", 0);
*allow_dir_id_ext= 2;
}
if(xorriso->iso_level_is_default && *iso_level < 0)
*iso_level= 1;
if(*iso_level >= 1 && *iso_level <= 3) {
sprintf(sfe, "iso_9660_level=%d", *iso_level);
Xorriso_relax_compliance(xorriso, sfe, 0);
iso_level= 0;
}
/* For the sake of compatibility give up emulated multi-session by default
*/
if(with_emul_toc == 0)
xorriso->no_emul_toc|= 1;
/* mkisofs records mtime in ECMA-119 and Joliet
*/
Xorriso_relax_compliance(xorriso, "rec_mtime", 0);
/* mkisofs is substantially faster than xorriso by not fsyncing
*/
if(xorriso->stdio_sync_is_default)
Xorriso_option_stdio_sync(xorriso, "off", 0);
Xorriso_free_meM(sfe);
ret= 1;
ex:;
return(ret);
}
int Xorriso_genisofs_platform(struct XorrisO *xorriso, char *id, int flag)
{
unsigned int u;
char re_id[64];
if(strcmp(id, "x86") == 0)
return(0);
else if(strcmp(id, "PPC") == 0)
return(1);
else if(strcmp(id, "Mac") == 0)
return(2);
else if(strcmp(id, "efi") == 0)
return(0xef);
u= 0x100;
if(strncmp(id, "0x", 2) == 0) {
sscanf(id + 2, "%x", &u);
} else {
sscanf(id, "%u", &u);
sprintf(re_id, "%u", u);
if(strcmp(id, re_id) != 0)
goto wrong_id;
}
if(u <= 0xff)
return((int) u);
wrong_id:;
sprintf(xorriso->info_text,
"Unrecognized El Torito Platform Id : '%.16s%s'",
id, strlen(id) > 16 ? "..." : "");
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
sprintf(xorriso->info_text,
"Recognizable are: x86, PPC, Mac, efi, [0...255], [0x00...0xff]");
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "HINT", 0);
return(-1);
}
/* micro emulation of mkisofs */
int Xorriso_genisofs(struct XorrisO *xorriso, char *whom,
int argc, char **argv, int flag)
{
int ret, i, j, was_path= 0, was_other_option= 0, mem_graft_points, mem;
int do_print_size= 0, fd, idx, iso_level= -1, palohdrversion;
int was_failure= 0, fret, lower_r= 0, zero= 0;
int dir_mode= -1, file_mode= -1, count, partition_number;
int allow_dir_id_ext= -1;
int root_seen= 0, do_md5_mem, option_d= 0, arg_count;
mode_t mode_and, mode_or;
int with_boot_image= 0, with_cat_path= 0, with_emul_toc= 0;
int old_root_md5= 1, old_root_dev= 0, old_root_ino= 1, sort_file_pattern= 0;
int *weight_list= NULL, weight_count= 0;
int *delay_opt_list= NULL, delay_opt_count= 0;
int mkisofs_b_platform_id= 0x00;
char *sfe= NULL, *adr= NULL, ra_text[80], *pathspec= NULL, *sort_file= NULL;
char *ept, *add_pt, *eff_path= NULL, *indev= NULL, msc[80], *cpt;
char *old_root= NULL, *argpt, *hargv[1];
char *boot_path, partno_text[24], *iso_rr_pt, *disk_pt, *rpt, *wpt;
char *rm_merge_args[3], *rr_reloc_dir_pt= NULL;
char *sort_weight_args[4], *bless_args[6], *sa_path;
struct stat stbuf;
Xorriso_alloc_meM(sfe, char, 5*SfileadrL);
Xorriso_alloc_meM(adr, char, SfileadrL+8);
Xorriso_alloc_meM(pathspec, char, 2*SfileadrL);
Xorriso_alloc_meM(eff_path, char, SfileadrL);
Xorriso_alloc_meM(indev, char, SfileadrL+8);
Xorriso_alloc_meM(old_root, char, SfileadrL);
Xorriso_alloc_meM(sort_file, char, SfileadrL);
for(i= 0; i<argc; i++) {
if(strcmp(argv[i], "-log-file") == 0 ||
strcmp(argv[i], "--log-file") == 0 ) {
if(i + 1 >= argc)
goto not_enough_args;
i+= 1;
if(argv[i][0]) {
sprintf(xorriso->info_text, "re-directing all messages to %s\n",
argv[i]);
Xorriso_info(xorriso, 0);
}
ret= Xorriso_write_to_channel(xorriso, argv[i], 2,
8 | ((argv[i][0] == 0) << 15));
if(ret <= 0) {
sprintf(xorriso->info_text, "Cannot open logfile: %s", argv[i]);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno * (ret == 0),
"SORRY", 0);
was_failure= 1;
fret= Xorriso_eval_problem_status(xorriso, ret, 1|2);
if(fret < 0)
{ret= 0; goto ex;}
}
if(argv[i][0] == 0) {
sprintf(xorriso->info_text, "Revoked stderr message redirection");
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
}
}
}
strcpy(ra_text, xorriso->report_about_text);
weight_list= TSOB_FELD(int, (argc / 3) + 1);
if(weight_list == NULL) {
Xorriso_no_malloc_memory(xorriso, NULL, 0);
{ret= -1; goto ex;}
}
delay_opt_list= TSOB_FELD(int, argc + 1);
if(delay_opt_list == NULL) {
cpt= (char *) weight_list;
Xorriso_no_malloc_memory(xorriso, &cpt, 0);
{ret= -1; goto ex;}
}
if(xorriso->boot_image_cat_path[0])
with_cat_path= -1;
adr[0]= indev[0]= msc[0]= old_root[0]= sort_file[0]= 0;
for(i= 0; i<argc; i++) {
ret= Xorriso_genisofs_strip_dash(xorriso, argv[i], &argpt, 0);
if(ret <= 0)
goto ex;
ret= Xorriso_genisofs_ignore(xorriso, whom, argpt, &i, 1);
if(ret == 1)
continue;
if(strcmp(argpt, "-version")==0) {
sprintf(xorriso->result_line,
"mkisofs 2.01-Emulation Copyright (C) 2019 see libburnia-project.org xorriso\n"
);
fd= xorriso->dev_fd_1;
if(fd<0)
fd= 1;
ret= write(fd, xorriso->result_line, strlen(xorriso->result_line));
/* (result of write intentionally ignored) */
fsync(fd);
Xorriso_option_version(xorriso, 0);
} else if(strcmp(argpt, "-o")==0 || strcmp(argpt, "-output")==0) {
if(i+1>=argc)
goto not_enough_args;
i++;
adr[0]= 0;
if(strcmp(argv[i],"-")!=0 && strncmp(argv[i], "stdio:", 6)!=0)
strcpy(adr, "stdio:");
if(Sfile_str(adr+strlen(adr), argv[i], 0)<=0)
{ret= -1; goto ex;}
} else if(strcmp(argpt, "-M")==0 || strcmp(argpt, "-dev")==0 ||
strcmp(argpt, "-prev-session")==0) {
if(i+1>=argc)
goto not_enough_args;
i++;
if(strncmp(argv[i], "stdio:", 6)!=0)
strcpy(indev, "stdio:");
if(Sfile_str(indev+strlen(indev), argv[i], 0)<=0)
{ret= -1; goto ex;}
} else if(strcmp(argpt, "-C")==0 ||
strcmp(argpt, "-cdrecord-params")==0) {
if(i+1>=argc)
goto not_enough_args;
i++;
strncpy(msc, argv[i], sizeof(msc)-1);
msc[sizeof(msc)-1]= 0;
} else if(strcmp(argpt, "-help")==0) {
Xorriso_genisofs_help(xorriso, 0);
} else if(strcmp(argpt, "-v")==0 || strcmp(argpt, "-verbose")==0) {
ret= Xorriso_genisofs_fused_options(xorriso, whom, "v",
&option_d, &iso_level, &lower_r, ra_text, 2);
if(ret <= 0)
goto problem_handler_1;
} else if(strcmp(argpt, "-quiet")==0) {
strcpy(ra_text, "SORRY");
} else if(strcmp(argpt, "-f")==0 || strcmp(argpt, "-follow-links")==0) {
ret= Xorriso_genisofs_fused_options(xorriso, whom, "f",
&option_d, &iso_level, &lower_r, ra_text, 2);
if(ret <= 0)
goto problem_handler_1;
} else if(strcmp(argpt, "-iso-level")==0) {
if(i+1>=argc)
goto not_enough_args;
i++;
sscanf(argv[i], "%d", &iso_level);
if(iso_level < 1 || iso_level > 4) {
sprintf(xorriso->info_text,
"-as %s: unsupported -iso-level '%s' (use one of: 1,2,3,4)",
whom, argv[i]);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
ret= 0; goto problem_handler_1;
}
if(iso_level == 4)
xorriso->do_iso1999= 1;
else {
sprintf(sfe, "iso_9660_level=%s", argv[i]);
ret= Xorriso_relax_compliance(xorriso, sfe, 0);
if(ret <= 0)
goto problem_handler_1;
}
} else if(strcmp(argpt, "-input-charset")==0) {
if(i+1>=argc)
goto not_enough_args;
i++;
/* -local_charset */
if(strcmp(argv[i], "default") == 0)
ret= Xorriso_option_charset(xorriso, "ISO-8859-1", 4);
else
ret= Xorriso_option_charset(xorriso, argv[i], 4);
if(ret <= 0)
goto problem_handler_1;
} else if(strcmp(argpt, "-output-charset")==0) {
if(i+1>=argc)
goto not_enough_args;
i++;
/* -charset */
if(strcmp(argv[i], "default") == 0)
ret= Xorriso_option_charset(xorriso, "ISO-8859-1", 3);
else
ret= Xorriso_option_charset(xorriso, argv[i], 3);
if(ret <= 0)
goto problem_handler_1;
} else if(strcmp(argpt, "-hide") == 0 ||
strcmp(argpt, "-hide-list") == 0 ||
strcmp(argpt, "-hide-joliet") == 0 ||
strcmp(argpt, "-hide-joliet-list") == 0 ||
strcmp(argpt, "-hide-hfsplus") == 0 ||
strcmp(argpt, "-hide-hfsplus-list") == 0) {
if(i+1>=argc)
goto not_enough_args;
i++;
if(strcmp(argpt, "-hide") == 0)
ret= Xorriso_genisofs_hide(xorriso, whom, argv[i], 1, 0);
else if(strcmp(argpt, "-hide-list") == 0)
ret= Xorriso_genisofs_hide_list(xorriso, whom, argv[i], 1, 0);
else if(strcmp(argpt, "-hide-joliet") == 0)
ret= Xorriso_genisofs_hide(xorriso, whom, argv[i], 2, 0);
else if(strcmp(argpt, "-hide-joliet-list") == 0)
ret= Xorriso_genisofs_hide_list(xorriso, whom, argv[i], 2, 0);
else if(strcmp(argpt, "-hide-hfsplus") == 0)
ret= Xorriso_genisofs_hide(xorriso, whom, argv[i], 4, 0);
else if(strcmp(argpt, "-hide-hfsplus-list") == 0)
ret= Xorriso_genisofs_hide_list(xorriso, whom, argv[i], 4, 0);
if(ret <= 0)
goto problem_handler_1;
} else if(strcmp(argpt, "-root") == 0) {
if(i+1>=argc)
goto not_enough_args;
i++;
/* Always absolute */
strcpy(eff_path, "/");
if(Sfile_str(eff_path, argv[i], argv[i][0] != '/') <= 0)
{ret= -1; goto ex;}
strcpy(xorriso->wdi, eff_path);
root_seen= 1;
} else if(strcmp(argpt, "-old-root") == 0) {
if(i+1>=argc)
goto not_enough_args;
i++;
/* Always absolute */
strcpy(old_root, "/");
if(Sfile_str(old_root, argv[i], argv[i][0] != '/') <= 0)
{ret= -1; goto ex;}
} else if(strcmp(argpt, "--old-root-no-md5")==0) {
old_root_md5= 0;
} else if(strcmp(argpt, "--old-root-devno")==0) {
old_root_dev= 1;
} else if(strcmp(argpt, "--old-root-no-ino")==0) {
old_root_ino= 0;
} else if(strcmp(argpt, "-fat") == 0) {
xorriso->do_fat= 1;
} else if(strcmp(argpt, "-hfsplus") == 0) {
/* Already with -indev */
xorriso->do_hfsplus= 1;
} else if(strcmp(argpt, "--hardlinks")==0) {
Xorriso_option_hardlinks(xorriso, "on", 0);
} else if(strcmp(argpt, "--acl")==0) {
Xorriso_option_acl(xorriso, "on", 0);
} else if(strcmp(argpt, "--xattr")==0) {
Xorriso_option_xattr(xorriso, "on", 0);
} else if(strcmp(argpt, "--xattr-any")==0) {
Xorriso_option_xattr(xorriso, "any", 0);
} else if(strcmp(argpt, "--md5")==0) {
Xorriso_option_md5(xorriso, "on", 0);
} else if(strcmp(argpt, "--scdbackup_tag")==0) {
if(i + 2 >= argc)
goto not_enough_args;
i+= 2;
ret= Xorriso_option_scdbackup_tag(xorriso, argv[i-1], argv[i], 0);
if(ret <= 0)
goto problem_handler_1;
} else if(strcmp(argpt, "--for_backup")==0) {
Xorriso_option_hardlinks(xorriso, "on", 0);
Xorriso_option_acl(xorriso, "on", 0);
Xorriso_option_xattr(xorriso, "any", 0);
Xorriso_option_md5(xorriso, "on", 0);
} else if(strcmp(argpt, "-z")==0 ||
strcmp(argpt, "-transparent-compression")==0) {
ret= Xorriso_genisofs_fused_options(xorriso, whom, "z",
&option_d, &iso_level, &lower_r, ra_text, 2);
if(ret <= 0)
goto problem_handler_1;
Xorriso_option_zisofs(xorriso, "by_magic=on", 0);
} else if(strcmp(argpt, "--stdio_sync")==0) {
if(i+1>=argc)
goto not_enough_args;
i++;
Xorriso_option_stdio_sync(xorriso, argv[i], 0);
} else if(strcmp(argpt, "-disallow_dir_id_ext")==0) {
allow_dir_id_ext= 0;
} else if(strcmp(argpt, "--emul-toc")==0) {
with_emul_toc= 1;
xorriso->no_emul_toc&= ~1;
} else if(strcmp(argpt, "--no-emul-toc")==0) {
with_emul_toc= 0;
xorriso->no_emul_toc|= 1;
} else if(strcmp(argpt, "-log-file") == 0) {
/* already handled before this loop */;
i++;
} else if(strcmp(argpt, "-gui") == 0) {
xorriso->pacifier_interval= 0.25;
} else if(strcmp(argpt, "-file_name_limit") == 0) {
if(i+1>=argc)
goto not_enough_args;
i++;
Xorriso_option_file_name_limit(xorriso, argv[i], 0);
} else {
if(argv[i][0] == '-') {
ret= Xorriso_genisofs_fused_options(xorriso, whom, argv[i] + 1,
&option_d, &iso_level, &lower_r, ra_text, 1 | 2);
if(ret != 1)
was_other_option= 1;
} else {
ret= 0;
was_other_option= 1;
}
if(ret > 0) {
Xorriso_genisofs_fused_options(xorriso, whom, argv[i] + 1,
&option_d, &iso_level, &lower_r, ra_text, 2);
if(ret <= 0)
goto problem_handler_1;
} else {
hargv[0]= argpt;
ret= Xorriso_genisofs_count_args(xorriso, argc - i, hargv, &count, 0);
if(ret > 0)
i+= count; /* skip eventual arguments of known option */
}
}
continue; /* regular bottom of loop */
problem_handler_1:;
was_failure= 1;
fret= Xorriso_eval_problem_status(xorriso, ret, 1|2);
if(fret>=0)
continue;
goto ex;
}
Xorriso_option_report_about(xorriso, ra_text, 0);
if(adr[0]) {
if(strncmp(adr, "stdio:", 6)==0 && strncmp(adr, "stdio:/dev/fd/", 14)!=0) {
ret= Sfile_type(adr+6, 1);
if(ret==-1) {
/* ok */;
} else if(ret==2 || ret==3) {
sprintf(xorriso->info_text,
"-as %s: Cannot accept %s as target: -o %s",
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 overwritable as blank, truncate regular files on write start */
ret= Xorriso_option_dev(xorriso, adr, 2|8|16);
if(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)
goto ex;
}
if(msc[0]) {
cpt= strchr(msc, ',');
if(cpt==NULL) {
illegal_c:;
sprintf(xorriso->info_text,
"-as %s: unusable parameter with option -C: %s",
whom, Text_shellsafe(msc, sfe, 0));
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
{ret= 0; goto ex;}
} else if(cpt==msc || msc[1]==0)
goto illegal_c;
strncpy(sfe, msc, cpt-msc);
sfe[cpt-msc]= 0;
if(xorriso->in_drive_handle!=NULL && indev[0]) {
/* give up indev before setting the load address */
ret= Xorriso_option_dev(xorriso, "", 1);
if(ret<=0)
goto ex;
}
/* growisofs submits msc1+16 to avoid a theoretical bug in mkisofs.
Therefore this bug has to be emulated here. Sigh.
*/
ret= Xorriso_option_load(xorriso, "sbsector", sfe, 1);
if(ret<=0)
goto ex;
ret= Xorriso_option_grow_blindly(xorriso, cpt+1, 0);
if(ret<=0)
goto ex;
}
if(old_root[0] || root_seen) {
Xorriso_option_md5(xorriso, old_root_md5 ? "on" : "off", 0);
Xorriso_option_disk_dev_ino(xorriso,
old_root_dev && old_root_ino ? "on" :
old_root_ino ? "ino_only" : "off", 0);
if(!old_root_ino)
Xorriso_option_hardlinks(xorriso, "without_update", 0);
}
if(indev[0]) {
do_md5_mem= xorriso->do_md5;
if(xorriso->do_md5 & 1) /* MD5 loading is enabled */
xorriso->do_md5|= 32; /* Do not check tags of superblock,tree,session
because growisofs preserves the first sb tag.*/
ret= Xorriso_option_dev(xorriso, indev, 1);
xorriso->do_md5= do_md5_mem;
if(ret<=0)
goto ex;
}
if(!was_other_option)
{ret= 1; goto ex;}
if(old_root[0]) {
ret= Xorriso_iso_lstat(xorriso, old_root, &stbuf, 0);
if(ret >= 0) {
if(root_seen) {
ret= Xorriso_mkdir(xorriso, xorriso->wdi, 1 | 2);
if(ret < 0)
{ret= -(ret != -1); goto ex;}
} else {
strcpy(xorriso->wdi, "/");
}
if(strcmp(old_root, xorriso->wdi) != 0) {
ret= Xorriso_clone_under(xorriso, old_root, xorriso->wdi, 0);
if(ret <= 0)
goto ex;
}
}
}
xorriso->padding= 300*1024;
for(i= 0; i<argc; i++) {
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);
ret= Xorriso_genisofs_strip_dash(xorriso, argv[i], &argpt, 0);
if(ret <= 0)
goto ex;
ret= Xorriso_genisofs_ignore(xorriso, whom, argpt, &i, 0);
if(ret == 1)
continue;
if(strcmp(argpt, "-version")==0) {
/* was already handled in first argument scan */;
} else if(strcmp(argpt, "--norock")==0) {
xorriso->do_rockridge= 0;
lower_r= 0;
} else if(strcmp(argpt, "-R")==0 || strcmp(argpt, "-rock")==0) {
ret= Xorriso_genisofs_fused_options(xorriso, whom, "R",
&option_d, &iso_level, &lower_r, ra_text, 0);
if(ret <= 0)
goto problem_handler_2;
} else if(strcmp(argpt, "-r")==0 || strcmp(argpt, "-rational-rock")==0){
ret= Xorriso_genisofs_fused_options(xorriso, whom, "r",
&option_d, &iso_level, &lower_r, ra_text, 0);
if(ret <= 0)
goto problem_handler_2;
} else if(strcmp(argpt, "-J")==0 || strcmp(argpt, "-joliet")==0) {
ret= Xorriso_genisofs_fused_options(xorriso, whom, "J",
&option_d, &iso_level, &lower_r, ra_text, 0);
if(ret <= 0)
goto problem_handler_2;
} else if(strcmp(argpt, "-joliet-long")==0) {
Xorriso_relax_compliance(xorriso,
"joliet_long_paths:joliet_long_names", 0);
} else if(strcmp(argpt, "-joliet-utf16")==0) {
Xorriso_relax_compliance(xorriso, "joliet_utf16", 0);
} else if(strcmp(argpt, "-fat") == 0) {
/* was already handled in first argument scan */;
} else if(strcmp(argpt, "-hfs-bless") == 0 ||
strcmp(argpt, "-hfs-bless-by") == 0 ||
strcmp(argpt, "-hfsplus-file-creator-type") == 0) {
arg_count= 1;
if(strcmp(argpt, "-hfs-bless-by") == 0)
arg_count= 2;
else if(strcmp(argpt, "-hfsplus-file-creator-type") == 0)
arg_count= 3;
if(i + arg_count >= argc)
goto not_enough_args;
/* Memorize command until all pathspecs are processed */
delay_opt_list[delay_opt_count++]= i;
if(argv[i] != argpt)
delay_opt_list[delay_opt_count - 1]|= 1u<<31;
i+= arg_count;
} else if(strcmp(argpt, "-hfsplus") == 0) {
/* was already handled in first argument scan */;
} else if(strcmp(argpt, "-hfsplus-serial-no") == 0) {
if(i+1>=argc)
goto not_enough_args;
i++;
sprintf(pathspec, "hfsplus_serial=%.80s", argv[i]);
ret= Xorriso_option_boot_image(xorriso, "any", pathspec, 0);
if(ret <= 0)
goto problem_handler_2;
} else if(strcmp(argpt, "-hfsplus-block-size") == 0 ||
strcmp(argpt, "-apm-block-size") == 0) {
if(i+1>=argc)
goto not_enough_args;
i++;
ret= -1;
sscanf(argv[i], "%d", &ret);
if(argpt[1] == 'h')
sprintf(sfe, "hfsplus_block_size=%d", ret);
else
sprintf(sfe, "apm_block_size=%d", ret);
ret= Xorriso_option_boot_image(xorriso, "any", sfe, 0);
if(ret <= 0)
goto problem_handler_2;
} else if(strcmp(argpt, "-graft-points")==0) {
xorriso->allow_graft_points= 3;
} else if(strcmp(argpt, "-path-list")==0 ||
strcmp(argpt, "--quoted_path_list")==0) {
if(i+1>=argc) {
not_enough_args:;
sprintf(xorriso->info_text, "-as %s: Not enough arguments to option %s",
whom, argv[i]);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
ret= 0; goto ex;
}
i++;
xorriso->pacifier_style= 1;
ret= Xorriso_option_path_list(xorriso, argv[i],
(strcmp(argpt, "--quoted_path_list") == 0) | 2);
if(ret<=0)
goto problem_handler_2;
ret = Xorriso_genisofs_path_pecul(xorriso, &was_path, with_emul_toc,
&allow_dir_id_ext, &iso_level, 0);
if(ret <= 0)
goto ex;
} else if(strcmp(argpt, "-f")==0 || strcmp(argpt, "-follow-links")==0) {
/* was already handled in first argument scan */;
} else if(strcmp(argpt, "-pad")==0) {
xorriso->padding= 300*1024;
} else if(strcmp(argpt, "-no-pad")==0) {
xorriso->padding= 0;
} else if(strcmp(argpt, "-print-size")==0) {
do_print_size= 1;
} else if(strcmp(argpt, "-o")==0 || strcmp(argpt, "-output") == 0) {
i++;
/* was already handled in first argument scan */;
} else if(strcmp(argpt, "-M")==0 || strcmp(argpt, "-dev")==0 ||
strcmp(argpt, "-prev-session")==0) {
i++;
/* was already handled in first argument scan */;
} else if(strcmp(argpt, "-C")==0 ||
strcmp(argpt, "-cdrecord-params")==0) {
i++;
/* was already handled in first argument scan */;
} else if(strcmp(argpt, "-help")==0) {
/* was already handled in first argument scan */;
} else if(strcmp(argpt, "-V")==0 || strcmp(argpt, "-volid")==0 ||
strcmp(argpt, "-volset")==0 ||
strcmp(argpt, "-p")==0 || strcmp(argpt, "-preparer")==0 ||
strcmp(argpt, "-P")==0 || strcmp(argpt, "-publisher")==0 ||
strcmp(argpt, "-A")==0 || strcmp(argpt, "-appid")==0 ||
strcmp(argpt, "--application_use")==0 ||
strcmp(argpt, "-sysid")==0 ||
strcmp(argpt, "-biblio")==0 ||
strcmp(argpt, "-copyright")==0 ||
strcmp(argpt, "-abstract")==0 ) {
if(i+1>=argc)
goto not_enough_args;
i++;
ret= 1;
if(strcmp(argpt, "-V")==0 || strcmp(argpt, "-volid")==0)
ret= Xorriso_option_volid(xorriso, argv[i], 0);
else if(strcmp(argpt, "-volset")==0)
ret= Xorriso_option_volset_id(xorriso, argv[i], 0);
else if(strcmp(argpt, "-p")==0 ||
strcmp(argpt, "-preparer")==0)
ret= Xorriso_option_preparer_id(xorriso, argv[i], 0);
else if(strcmp(argpt, "-P")==0 ||
strcmp(argpt, "-publisher")==0)
ret= Xorriso_option_publisher(xorriso, argv[i], 0);
else if(strcmp(argpt, "-A")==0 || strcmp(argpt, "-appid")==0)
ret= Xorriso_option_application_id(xorriso, argv[i], 0);
else if(strcmp(argpt, "-sysid")==0)
ret= Xorriso_option_system_id(xorriso, argv[i], 0);
else if(strcmp(argpt, "-biblio")==0)
ret= Xorriso_option_biblio_file(xorriso, argv[i], 0);
else if(strcmp(argpt, "-copyright")==0)
ret= Xorriso_option_copyright_file(xorriso, argv[i], 0);
else if(strcmp(argpt, "-abstract")==0)
ret= Xorriso_option_abstract_file(xorriso, argv[i], 0);
else if(strcmp(argpt, "--application_use")==0)
ret= Xorriso_option_application_use(xorriso, argv[i], 0);
if(ret<=0)
goto problem_handler_2;
} else if(strcmp(argpt, "-m")==0 || strcmp(argpt, "-exclude")==0 ||
strcmp(argpt, "-x")==0 || strcmp(argpt, "-old-exclude")==0) {
if(i+1>=argc)
goto not_enough_args;
i++;
mem= xorriso->do_disk_pattern;
xorriso->do_disk_pattern= 1;
if(strchr(argv[i], '/')!=NULL) {
idx= i;
ret= Xorriso_option_not_paths(xorriso, i+1, argv, &idx, 0);
} else
ret= Xorriso_option_not_leaf(xorriso, argv[i], 0);
xorriso->do_disk_pattern= mem;
if(ret<=0)
goto problem_handler_2;
} else if(strcmp(argpt, "-exclude-list")==0) {
if(i+1>=argc)
goto not_enough_args;
i++;
mem= xorriso->do_disk_pattern;
xorriso->do_disk_pattern= 1;
ret= Xorriso_option_not_list(xorriso, argv[i], 0);
xorriso->do_disk_pattern= mem;
if(ret<=0)
goto problem_handler_2;
} else if(strcmp(argpt, "-v")==0 || strcmp(argpt, "-verbose")==0 ||
strcmp(argpt, "-quiet")==0) {
/* was already handled in first argument scan */;
} else if(strcmp(argpt, "-iso-level")==0) {
i++;
/* was already handled in first argument scan */;
} else if(strcmp(argpt, "-no-emul-boot")==0 ||
strcmp(argpt, "-hard-disk-boot")==0 ||
strcmp(argpt, "-boot-info-table")==0 ||
strcmp(argpt, "--grub2-boot-info") == 0 ||
strncmp(argpt, "isolinux_mbr=", 13)==0 ||
strcmp(argpt, "-eltorito-alt-boot")==0 ||
strcmp(argpt, "--protective-msdos-label")==0 ||
strcmp(argpt, "--mbr-force-bootable")==0 ||
strcmp(argpt, "--boot-catalog-hide")==0 ||
strcmp(argpt, "-isohybrid-gpt-basdat")==0 ||
strcmp(argpt, "-isohybrid-gpt-hfsplus")==0 ||
strcmp(argpt, "-isohybrid-apm-hfsplus")==0 ||
strcmp(argpt, "-part_like_isohybrid")==0) {
delay_opt_list[delay_opt_count++]= i;
if(argv[i] != argpt)
delay_opt_list[delay_opt_count - 1]|= 1u<<31;
} else if(strcmp(argpt, "-b") == 0 ||
strcmp(argpt, "-eltorito-boot") == 0 ||
strcmp(argpt, "-eltorito-platform") == 0 ||
strcmp(argpt, "--efi-boot") == 0 ||
strcmp(argpt, "-e") == 0 ||
strcmp(argpt, "-mips-boot") == 0 ||
strcmp(argpt, "-mipsel-boot") == 0 ||
strcmp(argpt, "-c") == 0 ||
strcmp(argpt, "-eltorito-catalog") == 0 ||
strcmp(argpt, "-boot-load-size") == 0 ||
strcmp(argpt, "-eltorito-id") == 0 ||
strcmp(argpt, "-eltorito-selcrit") == 0 ||
strcmp(argpt, "--embedded-boot")==0 ||
strcmp(argpt, "-generic-boot")==0 ||
strcmp(argpt, "-G") == 0 ||
strcmp(argpt, "-partition_offset") == 0 ||
strcmp(argpt, "-partition_hd_cyl") == 0 ||
strcmp(argpt, "-partition_sec_hd") == 0 ||
strcmp(argpt, "-partition_cyl_align") == 0 ||
strcmp(argpt, "-isohybrid-mbr") == 0 ||
strcmp(argpt, "--grub2-mbr") == 0 ||
strncmp(argpt, "-hppa-", 6) == 0 ||
strcmp(argpt, "-alpha-boot") == 0 ||
strcmp(argpt, "--gpt_disk_guid") == 0 ||
strcmp(argpt, "-iso_mbr_part_type") == 0) {
if(i+1>=argc)
goto not_enough_args;
delay_opt_list[delay_opt_count++]= i;
if(argv[i] != argpt)
delay_opt_list[delay_opt_count - 1]|= 1u<<31;
i++;
} else if(strncmp(argpt, "--modification-date=", 20)==0) {
ret= Xorriso_option_volume_date(xorriso, "uuid", argpt + 20, 0);
if(ret <= 0)
goto problem_handler_2;
} else if(strcmp(argpt, "--set_all_file_dates") == 0) {
if(i+1>=argc)
goto not_enough_args;
i++;
ret= Xorriso_option_volume_date(xorriso, "all_file_dates", argv[i], 0);
if(ret <= 0)
goto problem_handler_2;
} else if(strcmp(argpt, "-input-charset")==0) {
i++;
/* was already handled in first argument scan */;
} else if(strcmp(argpt, "-output-charset")==0) {
i++;
/* was already handled in first argument scan */;
} else if(strcmp(argpt, "--hardlinks")==0 ||
strcmp(argpt, "--acl")==0 ||
strcmp(argpt, "--xattr")==0 ||
strcmp(argpt, "--xattr-any")==0 ||
strcmp(argpt, "--md5")==0 ||
strcmp(argpt, "--for_backup")==0) {
/* was already handled in first argument scan */;
} else if(strcmp(argpt, "--scdbackup_tag")==0) {
/* was already handled in first argument scan */;
i+= 2;
} else if(strcmp(argpt, "--sort-weight")==0) {
if(i + 2 >= argc)
goto not_enough_args;
i+= 2;
/* memorize for find runs after pathspecs have been added */
weight_list[weight_count++]= i - 2;
} else if(strcmp(argpt, "--sort-weight-list") == 0 ||
strcmp(argpt, "--sort-weight-patterns") == 0) {
if(i + 1 >= argc)
goto not_enough_args;
i++;
if(Sfile_str(sort_file, argv[i], 0) <= 0)
{ret= -1; goto ex;}
sort_file_pattern= (strcmp(argpt, "--sort-weight-patterns") == 0);
} else if(strcmp(argpt, "-z")==0 ||
strcmp(argpt, "-transparent-compression")==0) {
/* was already handled in first argument scan */;
} else if(strcmp(argpt, "-U") == 0 ||
strcmp(argpt, "-untranslated-filenames") == 0) {
ret= Xorriso_genisofs_fused_options(xorriso, whom, "U",
&option_d, &iso_level, &lower_r, ra_text, 0);
if(ret <= 0)
goto problem_handler_2;
} else if(strcmp(argpt, "-untranslated_name_len") == 0) {
if(i+1>=argc)
goto not_enough_args;
i++;
sprintf(sfe, "untranslated_name_len=%s", argv[i]);
ret= Xorriso_relax_compliance(xorriso, sfe, 0);
if(ret <= 0)
goto problem_handler_2;
} else if(strcmp(argpt, "-N") == 0 ||
strcmp(argpt, "-omit-version-number") == 0) {
ret= Xorriso_genisofs_fused_options(xorriso, whom, "N",
&option_d, &iso_level, &lower_r, ra_text, 0);
if(ret <= 0)
goto problem_handler_2;
} else if(strcmp(argpt, "-l") == 0 ||
strcmp(argpt, "-full-iso9660-filenames") == 0) {
ret= Xorriso_genisofs_fused_options(xorriso, whom, "l",
&option_d, &iso_level, &lower_r, ra_text, 0);
if(ret <= 0)
goto problem_handler_2;
} else if(strcmp(argpt, "-max-iso9660-filenames") == 0) {
Xorriso_relax_compliance(xorriso, "long_names", 0);
} else if(strcmp(argpt, "-d") == 0 ||
strcmp(argpt, "-omit-period") == 0) {
ret= Xorriso_genisofs_fused_options(xorriso, whom, "d",
&option_d, &iso_level, &lower_r, ra_text, 0);
if(ret <= 0)
goto problem_handler_2;
} else if(strcmp(argpt, "-allow-lowercase") == 0) {
Xorriso_relax_compliance(xorriso, "lowercase", 0);
} else if(strcmp(argpt, "-relaxed-filenames") == 0) {
Xorriso_relax_compliance(xorriso, "7bit_ascii", 0);
} else if(strcmp(argpt, "-hide") == 0 ||
strcmp(argpt, "-hide-list") == 0 ||
strcmp(argpt, "-hide-joliet") == 0 ||
strcmp(argpt, "-hide-joliet-list") == 0 ||
strcmp(argpt, "-hide-hfsplus") == 0 ||
strcmp(argpt, "-hide-hfsplus-list") == 0) {
if(i+1>=argc)
goto not_enough_args;
i++;
/* was already handled in first argument scan */;
} else if(strcmp(argpt, "-root") == 0 ||
strcmp(argpt, "-old-root") == 0) {
if(i+1>=argc)
goto not_enough_args;
i++;
/* was already handled in first argument scan */;
} else if(strcmp(argpt, "--old-root-no-md5")==0 ||
strcmp(argpt, "--old-root-devno")==0 ||
strcmp(argpt, "--old-root-no-ino")==0) {
/* was already handled in first argument scan */;
} else if(strcmp(argpt, "-dir-mode") == 0) {
if(i+1>=argc)
goto not_enough_args;
i++;
ret= Xorriso_convert_modstring(xorriso, "-as mkisofs -dir-mode",
argv[i], &mode_and, &mode_or, 0);
if(ret<=0)
goto problem_handler_2;
dir_mode= mode_or;
} else if(strcmp(argpt, "-file-mode") == 0) {
if(i+1>=argc)
goto not_enough_args;
i++;
ret= Xorriso_convert_modstring(xorriso, "-as mkisofs -file-mode",
argv[i], &mode_and, &mode_or, 0);
if(ret<=0)
goto problem_handler_2;
file_mode= mode_or;
} else if(strcmp(argpt, "-jigdo-jigdo") == 0 ||
strcmp(argpt, "-jigdo-template") == 0 ||
strcmp(argpt, "-jigdo-min-file-size") == 0 ||
strcmp(argpt, "-jigdo-exclude") == 0 ||
strcmp(argpt, "-jigdo-force-md5") == 0 ||
strcmp(argpt, "-jigdo-force-checksum") == 0 ||
strcmp(argpt, "-jigdo-map") == 0 ||
strcmp(argpt, "-jigdo-checksum-algorithm") == 0 ||
strcmp(argpt, "-jigdo-template-compress") == 0 ||
strcmp(argpt, "-checksum_algorithm_iso") == 0 ||
strcmp(argpt, "-checksum_algorithm_template") == 0 ||
strcmp(argpt, "-md5-list") == 0 ||
strcmp(argpt, "-checksum-list") == 0) {
i++;
ret= Xorriso_option_jigdo(xorriso, argpt, argv[i], 0);
if(ret <= 0)
goto problem_handler_2;
} else if(strcmp(argpt, "-chrp-boot-part") == 0 ||
strcmp(argpt, "-chrp-boot") == 0) {
ret= Xorriso_option_boot_image(xorriso, "any", "chrp_boot_part=on", 0);
if(ret <= 0)
goto problem_handler_2;
} else if(strcmp(argpt, "-prep-boot-part") == 0) {
if(i + 1 >= argc)
goto not_enough_args;
i++;
ret= Sfile_str(xorriso->prep_partition, argv[i], 0);
if(ret <= 0)
goto ex;
} else if(strcmp(argpt, "-efi-boot-part") == 0) {
if(i + 1 >= argc)
goto not_enough_args;
i++;
ret= Sfile_str(xorriso->efi_boot_partition, argv[i], 0);
if(ret <= 0)
goto ex;
} else if(strcmp(argpt, "-append_partition") == 0) {
if(i + 3 >= argc)
goto not_enough_args;
i+= 3;
ret= Xorriso_option_append_partition(xorriso, argv[i - 2], argv[i - 1],
argv[i], 0);
if(ret <= 0)
goto problem_handler_2;
} else if(strcmp(argpt, "-appended_part_as_gpt") == 0) {
xorriso->appended_as_gpt= 1;
} else if(strcmp(argpt, "-appended_part_as_apm") == 0) {
xorriso->appended_as_apm= 1;
} else if(strcmp(argpt, "-B") == 0 ||
strcmp(argpt, "-sparc-boot") == 0) {
i++;
if(strlen(argv[i]) >= SfileadrL)
continue;
/* Switch system area type to: SUN Disk Label */
strcpy(pathspec, "sparc_label=");
strcat(pathspec, xorriso->ascii_disc_label);
ret= Xorriso_option_boot_image(xorriso, "any", pathspec, 0);
if(ret <= 0)
goto problem_handler_2;
/* Interpret list of boot partition images or "..." */;
cpt= ept= argv[i];
partition_number= 2;
while(ept != NULL) {
ept= strchr(cpt, ',');
if(ept != NULL) {
strncpy(pathspec, cpt, ept - cpt);
pathspec[ept - cpt]= 0;
cpt= ept + 1;
} else
strcpy(pathspec, cpt);
if(strcmp(pathspec, "...") == 0) {
for(; partition_number <= 8; partition_number++) {
sprintf(partno_text, "%d", partition_number);
ret= Xorriso_option_append_partition(xorriso, partno_text, "0x0",
".", 0);
if(ret <= 0)
goto problem_handler_2;
}
} else {
if(partition_number > 8) {
sprintf(xorriso->info_text,
"-as %s -sparc-boot %s : Too many boot images", whom, argv[i]);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE",0);
goto problem_handler_2;
}
sprintf(partno_text, "%d", partition_number);
ret= Xorriso_option_append_partition(xorriso, partno_text, "0x0",
pathspec, 0);
if(ret <= 0)
goto problem_handler_2;
partition_number++;
}
}
} else if(strcmp(argpt, "-sparc-label") == 0) {
if(i+1>=argc)
goto not_enough_args;
i++;
sprintf(sfe, "sparc_label=%s", argv[i]);
ret= Xorriso_option_boot_image(xorriso, "any", sfe, 0);
if(ret <= 0)
goto problem_handler_2;
} else if(strcmp(argpt, "--grub2-sparc-core") == 0) {
if(i+1>=argc)
goto not_enough_args;
i++;
sprintf(sfe, "grub2_sparc_core=%s", argv[i]);
ret= Xorriso_option_boot_image(xorriso, "any", sfe, 0);
if(ret <= 0)
goto problem_handler_2;
} else if(strcmp(argpt, "--stdio_sync")==0) {
if(i+1>=argc)
goto not_enough_args;
i++;
/* was already handled in first argument scan */;
} else if(strcmp(argpt, "--emul-toc")==0 ||
strcmp(argpt, "--no-emul-toc")==0) {
/* was already handled in first argument scan */;
} else if(strcmp(argpt, "--old-empty")==0) {
xorriso->do_old_empty= 1;
} else if(strcmp(argpt, "-disallow_dir_id_ext")==0) {
/* was already handled in first argument scan */;
} else if(strcmp(argpt, "--no_rc")==0) {
/* was already handled in Xorriso_prescan_args */;
} else if(strcmp(argpt, "-D") == 0 ||
strcmp(argpt, "-disable-deep-relocation") == 0) {
ret= Xorriso_genisofs_fused_options(xorriso, whom, "D",
&option_d, &iso_level, &lower_r, ra_text, 0);
if(ret <= 0)
goto problem_handler_2;
} else if(strcmp(argpt, "-hide-rr-moved") == 0) {
rr_reloc_dir_pt= ".rr_moved";
goto rr_reloc_dir;
} else if(strcmp(argpt, "-rr_reloc_dir") == 0) {
i++;
rr_reloc_dir_pt= argv[i];
rr_reloc_dir:;
if(rr_reloc_dir_pt[0] == '/')
rr_reloc_dir_pt++;
if(strchr(rr_reloc_dir_pt, '/') != NULL) {
sprintf(xorriso->info_text,
"-as %s -rr_reloc_dir %s : May only use directories in root directory",
whom, Text_shellsafe(argv[i], sfe, 0));
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE",0);
}
ret= Xorriso_option_rr_reloc_dir(xorriso, rr_reloc_dir_pt, 0);
if(ret <= 0)
goto problem_handler_2;
Xorriso_relax_compliance(xorriso, "deep_paths_off:long_paths_off", 0);
} else if(strcmp(argpt, "-log-file") == 0 ||
strcmp(argpt, "-file_name_limit") == 0) {
i+= 1;
/* was already handled before this loop */;
} else if(strcmp(argpt, "-gui") == 0) {
/* was already handled in first argument scan */;
} else if(strcmp(argpt, "-uid") == 0) {
if(i + 1 >= argc)
goto not_enough_args;
i++;
ret= Xorriso_option_uid(xorriso, argv[i], 0);
if(ret <= 0)
goto problem_handler_2;
} else if(strcmp(argpt, "-gid") == 0) {
if(i + 1 >= argc)
goto not_enough_args;
i++;
ret= Xorriso_option_gid(xorriso, argv[i], 0);
if(ret <= 0)
goto problem_handler_2;
} else if(argpt[0]=='-' && argpt[1]!=0) {
ret= Xorriso_genisofs_fused_options(xorriso, whom, argv[i] + 1,
&option_d, &iso_level, &lower_r, ra_text, 1);
if(ret == 1) {
ret= Xorriso_genisofs_fused_options(xorriso, whom, argv[i] + 1,
&option_d, &iso_level, &lower_r, ra_text, 0);
if(ret <= 0)
goto problem_handler_2;
} else {
hargv[0]= argpt;
ret= Xorriso_genisofs_count_args(xorriso, argc - i, hargv, &count, 1);
if(ret > 0) {
sprintf(xorriso->info_text, "-as %s: Unsupported option %s",
whom, Text_shellsafe(argv[i], sfe, 0));
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
i+= count;
goto problem_handler_2;
} else {
sprintf(xorriso->info_text, "-as %s: Unrecognized option %s",
whom, Text_shellsafe(argv[i], sfe, 0));
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
goto problem_handler_2;
}
}
} else {
ret= Xorriso_graftable_pathspec(xorriso, argv[i], pathspec, 0);
if(ret <= 0)
goto problem_handler_2;
add_pt= pathspec;
if(old_root[0]) {
/* Split pathspec */
ret= Fileliste__target_source_limit(add_pt, '=', &ept, 0);
if(ret > 0) {
*ept= 0;
iso_rr_pt= add_pt;
disk_pt= ept + 1;
} else {
iso_rr_pt= "/";
disk_pt= add_pt;
}
/* Unescape iso_rr_pt */
strcpy(eff_path, iso_rr_pt);
iso_rr_pt= eff_path;
for(wpt= rpt= iso_rr_pt; *rpt != 0; rpt++) {
if(*rpt == '\\') {
if(*(rpt + 1) == '\\')
rpt++;
else if(*(rpt + 1) == '=')
continue;
}
*(wpt++) = *rpt;
}
*wpt= 0;
if(root_seen) {
ret= Sfile_prepend_path(xorriso->wdi, iso_rr_pt, 0);
if(ret<=0) {
Xorriso_msgs_submit(xorriso, 0, "Effective path gets much too long",
0, "FAILURE", 0);
goto problem_handler_2;
}
}
/* update_merge */
ret= Xorriso_option_update(xorriso, disk_pt, iso_rr_pt, 1 | 8 | 32);
} else {
mem_graft_points= xorriso->allow_graft_points;
xorriso->allow_graft_points= 3;
zero= 0;
ret= Xorriso_option_add(xorriso, 1, &add_pt, &zero,
(was_path << 1) | (root_seen << 2));
xorriso->allow_graft_points= mem_graft_points;
}
if(ret<=0)
goto problem_handler_2;
/* Enforce odd mkisofs defaults on first pathspec */
ret = Xorriso_genisofs_path_pecul(xorriso, &was_path, with_emul_toc,
&allow_dir_id_ext, &iso_level, 0);
if(ret <= 0)
goto ex;
}
continue; /* regular bottom of loop */
problem_handler_2:;
was_failure= 1;
fret= Xorriso_eval_problem_status(xorriso, ret, 1|2);
if(fret>=0)
continue;
goto ex;
}
if(old_root[0]) {
/* Delete all visited nodes which were not found on disk */
if(root_seen)
rm_merge_args[0]= xorriso->wdi;
else
rm_merge_args[0]= "/";
rm_merge_args[1]= "-exec";
rm_merge_args[2]= "rm_merge";
zero= 0;
ret= Xorriso_option_find(xorriso, 3, rm_merge_args, &zero, 2);
if(ret<=0)
goto ex;
}
if(lower_r) {
static char *lower_r_args[3]= {"/", "-exec", "mkisofs_r"};
zero= 0;
ret= Xorriso_option_find(xorriso, 3, lower_r_args, &zero, 2);
if(ret<=0)
goto ex;
}
if(dir_mode >= 0) {
static char *dir_mode_args[6]= {"/", "-type", "d", "-exec", "chmod", ""};
zero= 0;
sprintf(sfe, "0%o", (unsigned int) dir_mode);
dir_mode_args[5]= sfe;
ret= Xorriso_option_find(xorriso, 6, dir_mode_args, &zero, 2);
if(ret<=0)
goto ex;
}
if(file_mode >= 0) {
static char *file_mode_args[6]= {"/", "-type", "f", "-exec", "chmod", ""};
zero= 0;
sprintf(sfe, "0%o", (unsigned int) file_mode);
file_mode_args[5]= sfe;
ret= Xorriso_option_find(xorriso, 6, file_mode_args, &zero, 2);
if(ret<=0)
goto ex;
}
if(sort_file[0]) {
ret= Xorriso_apply_sort_file(xorriso, sort_file, sort_file_pattern);
if(ret<=0)
goto ex;
}
for(j= 0; j < weight_count; j++) {
i= weight_list[j];
/* find argv[i+2] -exec sort_weight argv[i+1] */
zero= 0;
sort_weight_args[0]= argv[i + 2];
sort_weight_args[1]= "-exec";
sort_weight_args[2]= "sort_weight";
sort_weight_args[3]= argv[i + 1];
ret= Xorriso_option_find(xorriso, 4, sort_weight_args, &zero, 2);
if(ret > 0)
continue;
/* Problem handler */
was_failure= 1;
fret= Xorriso_eval_problem_status(xorriso, ret, 1|2);
if(fret>=0)
continue;
goto ex;
}
if(option_d)
Xorriso_relax_compliance(xorriso, "deep_paths:long_paths", 0);
/* After all pathspecs are added: perform delayed options, mostly boot related
*/
for(j= 0; j < delay_opt_count; j++) {
i= delay_opt_list[j] & ~(1u << 31);
if(delay_opt_list[j] & (1u << 31))
argpt= argv[i] + 1;
else
argpt= argv[i];
if(strcmp(argpt, "-no-emul-boot")==0) {
xorriso->boot_image_emul= 0;
xorriso->boot_emul_default= 0;
} else if(strcmp(argpt, "-hard-disk-boot")==0) {
xorriso->boot_image_emul= 1;
xorriso->boot_emul_default= 0;
} else if(strcmp(argpt, "-boot-info-table")==0) {
xorriso->patch_isolinux_image= (xorriso->patch_isolinux_image & ~2) | 1;
} else if(strcmp(argpt, "--grub2-boot-info") == 0) {
xorriso->patch_isolinux_image=
(xorriso->patch_isolinux_image & ~2) | 512;
} else if(strcmp(argpt, "-b") == 0 ||
strcmp(argpt, "-eltorito-boot") == 0 ||
strcmp(argpt, "--efi-boot") == 0 ||
strcmp(argpt, "-e") == 0) {
i++;
if(strcmp(argpt, "--efi-boot") == 0) {
if(xorriso->boot_image_bin_path[0]) {
ret= Xorriso_genisofs_add_boot(xorriso, 0);
if(ret <= 0)
goto problem_handler_boot;
}
boot_path= xorriso->boot_image_bin_path;
xorriso->boot_efi_default= 1;
xorriso->boot_image_emul= 0;
xorriso->boot_emul_default= 0;
} else {
boot_path= xorriso->boot_image_bin_path;
if(strcmp(argpt, "-e") == 0)
xorriso->boot_platform_id= 0xef;
else
xorriso->boot_platform_id= mkisofs_b_platform_id;
xorriso->boot_efi_default= 0;
if(xorriso->boot_emul_default)
xorriso->boot_image_emul= 2;
}
boot_path[0]= 0;
if(argv[i][0] != '/' && strncmp(argv[i], "--interval:", 11) != 0)
strcat(boot_path, "/");
ret= Sfile_str(boot_path + strlen(boot_path), argv[i], 0);
if(ret <= 0)
goto ex;
if(xorriso->boot_efi_default && xorriso->boot_image_bin_path[0]) {
ret= Xorriso_genisofs_add_boot(xorriso, 0);
if(ret <= 0)
goto problem_handler_boot;
}
xorriso->keep_boot_image= 0;
with_boot_image= 1;
} else if(strcmp(argpt, "-eltorito-platform") == 0) {
if(i + 1>=argc)
goto not_enough_args;
i++;
mem= mkisofs_b_platform_id;
mkisofs_b_platform_id= Xorriso_genisofs_platform(xorriso, argv[i], 0);
if(mkisofs_b_platform_id < 0) {
mkisofs_b_platform_id= 0;
goto problem_handler_boot;
}
if(mkisofs_b_platform_id != mem &&
xorriso->boot_image_bin_path[0] != 0) {
ret= Xorriso_genisofs_add_boot(xorriso, 0);
if(ret <= 0)
goto problem_handler_boot;
}
} else if(strcmp(argpt, "-c") == 0 ||
strcmp(argpt, "-eltorito-catalog") == 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;
if(with_cat_path == 0)
with_cat_path= 1;
} else if(strcmp(argpt, "-boot-load-size") == 0) {
if(i+1>=argc)
goto not_enough_args;
i++;
if(strcmp(argv[i], "full") == 0) {
xorriso->boot_img_full_size= 1;
} else {
sscanf(argv[i], "%d", &ret);
xorriso->boot_image_load_size= ret * 512;
}
xorriso->boot_img_size_default= 0;
} else if(strcmp(argpt, "-eltorito-id") == 0 ||
strcmp(argpt, "-eltorito-selcrit") == 0) {
if(i+1>=argc)
goto not_enough_args;
i++;
if(strcmp(argpt, "-eltorito-id") == 0)
sprintf(sfe, "id_string=%s", argv[i]);
else
sprintf(sfe, "sel_crit=%s", argv[i]);
ret= Xorriso_option_boot_image(xorriso, "any", sfe, 0);
if(ret <= 0)
goto problem_handler_boot;
} else if(strncmp(argpt, "isolinux_mbr=", 13)==0) {
sprintf(sfe, "isohybrid=%s", argpt + 13);
ret= Xorriso_option_boot_image(xorriso, "isolinux", sfe, 0);
if(ret <= 0)
goto problem_handler_boot;
} else if(strcmp(argpt, "-isohybrid-gpt-basdat") == 0) {
xorriso->patch_isolinux_image = (xorriso->patch_isolinux_image & ~0x0fc) |
(1 << 2);
} else if(strcmp(argpt, "-isohybrid-gpt-hfsplus") == 0) {
xorriso->patch_isolinux_image = (xorriso->patch_isolinux_image & ~0x0fc) |
(2 << 2);
} else if(strcmp(argpt, "-isohybrid-apm-hfsplus") == 0) {
xorriso->patch_isolinux_image = xorriso->patch_isolinux_image | (1 << 8);
} else if(strcmp(argpt, "-part_like_isohybrid") == 0) {
xorriso->part_like_isohybrid= 1;
} else if(strcmp(argpt, "-iso_mbr_part_type") == 0) {
if(i + 1 >= argc)
goto not_enough_args;
i++;
sprintf(sfe, "iso_mbr_part_type=%s", argv[i]);
ret= Xorriso_option_boot_image(xorriso, "any", sfe, 0);
if(ret <= 0)
goto problem_handler_boot;
} else if(strcmp(argpt, "--gpt_disk_guid") == 0) {
if(i + 1 >= argc)
goto not_enough_args;
i++;
ret= Xorriso_parse_gpt_guid(xorriso, argv[i], 0);
if(ret <= 0)
goto problem_handler_boot;
} else if(strcmp(argpt, "-eltorito-alt-boot")==0) {
ret= Xorriso_genisofs_add_boot(xorriso, 0);
if(ret <= 0)
goto problem_handler_boot;
} else if(strcmp(argpt, "--embedded-boot")==0 ||
strcmp(argpt, "-generic-boot")==0 ||
strcmp(argpt, "-G") == 0 ||
strcmp(argpt, "-isohybrid-mbr") == 0 ||
strcmp(argpt, "--grub2-mbr") == 0) {
if(i+1>=argc)
goto not_enough_args;
i++;
if(strcmp(argv[i], ".") == 0)
sa_path= "";
else
sa_path= argv[i];
ret= Xorriso_set_system_area_path(xorriso, sa_path, 0);
if(ret <= 0)
goto problem_handler_boot;
if(strcmp(argpt, "-isohybrid-mbr")==0)
xorriso->system_area_options=
(xorriso->system_area_options & ~4001) | 2;
else if(strcmp(argpt, "--grub2-mbr") == 0)
xorriso->system_area_options=
(xorriso->system_area_options & ~2) | 0x4000;
} else if(strcmp(argpt, "--protective-msdos-label")==0) {
xorriso->system_area_options= (xorriso->system_area_options & ~2) | 1;
} else if(strcmp(argpt, "--mbr-force-bootable") == 0) {
xorriso->system_area_options= xorriso->system_area_options | (1 << 15);
} else if(strcmp(argpt, "--boot-catalog-hide")==0) {
xorriso->boot_image_cat_hidden|= 3;
} else if(strcmp(argpt, "-partition_offset") == 0 ||
strcmp(argpt, "-partition_sec_hd") == 0 ||
strcmp(argpt, "-partition_hd_cyl") == 0 ||
strcmp(argpt, "-partition_cyl_align") == 0) {
if(i+1>=argc)
goto not_enough_args;
i++;
sprintf(sfe, "%s=%.16s", argpt + 1, argv[i]);
ret= Xorriso_option_boot_image(xorriso, "any", sfe, 0);
if(ret <= 0)
goto problem_handler_boot;
} else if(strcmp(argpt, "-mips-boot") == 0 ||
strcmp(argpt, "-mipsel-boot") == 0) {
if(i + 1 >= argc)
goto not_enough_args;
i++;
if(strcmp(argpt, "-mipsel-boot") == 0)
strcpy(sfe, "mipsel_path=");
else
strcpy(sfe, "mips_path=");
ret= Sfile_str(sfe, argv[i], 1);
if(ret <= 0)
goto ex;
ret= Xorriso_option_boot_image(xorriso, "any", sfe, 0);
if(ret <= 0)
goto problem_handler_boot;
} else if(strncmp(argpt, "-hppa-", 6) == 0) {
if(i + 1 >= argc)
goto not_enough_args;
i++;
sprintf(sfe, "-as mkisofs %s %s", argpt, argv[i]);
palohdrversion= (xorriso->system_area_options >> 2) & 0x3f;
if(palohdrversion != 4)
palohdrversion= 5;
ret= Xorriso_coordinate_system_area(xorriso, palohdrversion, 0, sfe, 0);
if(ret <= 0)
goto ex;
ret= Xorriso_set_hppa_boot_parm(xorriso, argv[i], argpt + 6, 0);
if(ret <= 0)
goto problem_handler_boot;
} else if(strcmp(argpt, "-alpha-boot") == 0) {
if(i + 1 >= argc)
goto not_enough_args;
i++;
sprintf(sfe, "-as mkisofs %s %s", argpt, argv[i]);
ret= Xorriso_coordinate_system_area(xorriso, 6, 0, sfe, 0);
if(ret <= 0)
goto ex;
ret= Xorriso_set_alpha_boot(xorriso, argv[i], 0);
} else if(strcmp(argpt, "-hfs-bless") == 0) {
static char *bless_arg_data[6]= {
"/", "-disk_path", "", "-exec", "set_hfs_bless", "p"};
for(j= 0; j < 6; j++)
bless_args[j]= bless_arg_data[j];
bless_args[2]= argv[i + 1];
zero= 0;
ret= Xorriso_option_find(xorriso, 6, bless_args, &zero, 2 | 16);
if(ret<=0)
goto ex;
if(ret < 2) {
sprintf(xorriso->info_text,
"-hfs-bless: Could not find a data file which stems from underneath disk directory ");
Text_shellsafe(argv[i + 1], xorriso->info_text, 1);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
Xorriso_msgs_submit(xorriso, 0,
"Consider to use: -hfs-bless-by p ISO_RR_PATH", 0, "HINT", 0);
goto problem_handler_boot;
}
} else if(strcmp(argpt, "-hfs-bless-by") == 0) {
ret= Xorriso_hfsplus_bless(xorriso, argv[i + 2], NULL, argv[i + 1], 0);
if(ret <= 0)
goto problem_handler_boot;
} else if(strcmp(argpt, "-hfsplus-file-creator-type") == 0) {
ret= Xorriso_hfsplus_file_creator_type(xorriso, argv[i + 3], NULL,
argv[i + 1], argv[i + 2], 0);
if(ret <= 0)
goto problem_handler_boot;
}
continue; /* regular bottom of loop */
problem_handler_boot:;
/* Problem handler */
was_failure= 1;
fret= Xorriso_eval_problem_status(xorriso, ret, 1|2);
if(fret>=0)
continue;
goto ex;
}
if(with_boot_image && with_cat_path == 0)
strcpy(xorriso->boot_image_cat_path, "/boot.catalog");
/* The boot catalog has to be hidden separately */
if(xorriso->boot_image_cat_path[0]) {
ret= Xorriso_path_is_hidden(xorriso, xorriso->boot_image_cat_path, 0);
if(ret > 0)
xorriso->boot_image_cat_hidden|= ret;
else if(ret < 0)
was_failure= 1;
}
/* Enforce the -boot-load-size default of mkisofs */
if(with_boot_image && xorriso->boot_img_size_default &&
xorriso->boot_image_emul == 0)
xorriso->boot_img_full_size= 1;
if(xorriso->no_emul_toc & 1)
xorriso->do_padding_by_libisofs= 1;
if(do_print_size) {
ret= Xorriso_option_print_size(xorriso, 1);
goto ex;
}
ret= !was_failure;
ex:;
if(was_path && (!do_print_size) && !old_root[0])
Xorriso_pacifier_callback(xorriso, "files added", xorriso->pacifier_count,
xorriso->pacifier_total, "", 1);
if(do_print_size && Xorriso_change_is_pending(xorriso, 1))
xorriso->volset_change_pending= 2;
if(weight_list != NULL)
free(weight_list);
if(delay_opt_list != NULL)
free(delay_opt_list);
Xorriso_free_meM(sort_file);
Xorriso_free_meM(sfe);
Xorriso_free_meM(adr);
Xorriso_free_meM(pathspec);
Xorriso_free_meM(eff_path);
Xorriso_free_meM(indev);
Xorriso_free_meM(old_root);
return(ret);
}
int Xorriso_as_genisofs(struct XorrisO *xorriso, int argc, char **argv,
int *idx, int flag)
{
int end_idx, ret, old_idx;
old_idx= *idx;
end_idx= Xorriso_end_idx(xorriso, argc, argv, *idx, 1);
(*idx)= end_idx;
if(end_idx<=0 || old_idx>=argc)
return(1);
ret= Xorriso_genisofs(xorriso, "genisofs", end_idx-old_idx, argv+old_idx, 0);
return(ret);
}
int Xorriso_as_cdrskin(struct XorrisO *xorriso, int argc, char **argv,
int *idx, int flag)
{
int end_idx, ret, old_idx;
old_idx= *idx;
end_idx= Xorriso_end_idx(xorriso, argc, argv, *idx, 1);
(*idx)= end_idx;
if(end_idx<=0 || old_idx>=argc)
return(1);
ret= Xorriso_cdrskin(xorriso, "cdrskin", end_idx-old_idx, argv+old_idx, 0);
return(ret);
}