libisoburn/xorriso/emulators.c

1666 lines
61 KiB
C
Raw Normal View History

/* xorriso - creates, loads, manipulates and burns ISO 9660 filesystem images.
Copyright 2007-2010 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_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 xorriso",
"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",
"\t-v\t\tincrement verbose level by one",
"\t-checkdrive\tcheck if a driver for the drive is present",
"\t-inq\t\tdo an inquiry for the drive and exit emulation",
"\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-waiti\t\twait until input is available before opening SCSI",
"\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",
"\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",
"\tdvd_obs=default|32k|64k\t\tbytes per DVD/BD write operation",
"\tstdio_sync=on|off|number\twhether to fsync output to \"stdio:\"",
"\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 overwriteable media.",
"A much more elaborate cdrecord emulator is cdrskin from the same project.",
"@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;
double write_start_address= -1.0, tsize= -1.0;
char track_source[SfileadrL], sfe[5*SfileadrL], dev_adr[SfileadrL], *cpt;
char mem_report_about_text[80], *report_about= "SORRY", blank_mode[80];
char speed[80];
/* 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=", "minbuf=",
"assert_write_lba=", "fifo_start_at=", "dev_translation=",
"drive_scsi_dev_family=", "fallback_program=", "modesty_on_drive=",
"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", "-sao", "-dao", "-swab",
"-tao", "-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 media 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@"
};
strcpy(mem_report_about_text, xorriso->report_about_text);
mem_do_close= xorriso->do_close;
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)
return(ret);
}
/* Assess plan, make settings */
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);
for(k=0;ignored_partial_options[k][0]!=0;k++) {
if(argv[i][0]=='-')
if(strncmp(argv[i]+1,ignored_partial_options[k],
strlen(ignored_partial_options[k]))==0)
goto no_volunteer;
if(strncmp(argv[i],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(argv[i],ignored_full_options[k])==0)
goto no_volunteer;
if(0) {
no_volunteer:;
sprintf(xorriso->info_text, "-as %s: Ignored option %s",
whom, Text_shellsafe(argv[i], sfe, 0));
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
continue;
}
if(strcmp(argv[i], "-atip")==0) {
do_atip= 1;
} else if(strcmp(argv[i], "-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(argv[i], "-blank=", 7)==0 ||
strncmp(argv[i], "blank=", 6)==0) {
cpt= strchr(argv[i], '=')+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=%s not supported. See blank=help .",
whom, Text_shellsafe(argv[i], sfe, 0));
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
ret= 0; goto ex;
}
} else if(strcmp(argv[i], "-checkdrive")==0) {
do_checkdrive= 1;
} else if(strcmp(argv[i], "-data")==0) {
/* ok */;
} else if(strncmp(argv[i], "-dev=", 5)==0 ||
strncmp(argv[i], "dev=", 4)==0) {
cpt= strchr(argv[i], '=')+1;
strcpy(dev_adr, cpt);
} else if(strcmp(argv[i], "--devices")==0) {
do_scanbus= 2;
} else if(strncmp(argv[i],"driveropts=", 11)==0 ||
strncmp(argv[i],"-driveropts=", 12)==0) {
if(strcmp(argv[i]+11, "help")==0) {
fprintf(stderr,"Driver options:\n");
fprintf(stderr,
"burnfree\tPrepare writer to use BURN-Free technology\n");
}
} else if(strcmp(argv[i], "-dummy")==0) {
xorriso->do_dummy= 1;
} else if(strcmp(argv[i], "-eject")==0) {
do_eject= 1;
} else if(strncmp(argv[i], "-fs=", 4)==0 || strncmp(argv[i], "fs=", 3)==0) {
cpt= strchr(argv[i], '=')+1;
ret= Xorriso_option_fs(xorriso, cpt, 0);
if(ret<=0)
goto ex;
} else if(strcmp(argv[i], "--grow_overwriteable_iso")==0) {
do_grow= 1;
} else if(strcmp(argv[i], "-help")==0) {
do_help= 1;
} else if(strcmp(argv[i], "-isosize")==0) {
do_isosize= 1;
} else if(strcmp(argv[i], "-inq")==0) {
do_checkdrive= 2;
} else if(strcmp(argv[i], "-mode2")==0) {
Xorriso_msgs_submit(xorriso, 0,
"Defaulting option -mode2 to option -data", 0, "NOTE", 0);
} else if(strcmp(argv[i], "-msinfo")==0) {
do_msinfo= 1;
} else if(strcmp(argv[i], "-multi")==0) {
do_multi= 1;
} else if(strcmp(argv[i], "-nopad")==0) {
xorriso->padding= 0;
} else if(strcmp(argv[i], "-pad")==0) {
xorriso->padding= 15*2048;
} else if(strncmp(argv[i], "-padsize=", 9)==0 ||
strncmp(argv[i], "padsize=", 8)==0) {
cpt= strchr(argv[i], '=')+1;
ret= Xorriso_option_padding(xorriso, cpt, 0);
if(ret<=0)
goto ex;
} else if(strcmp(argv[i], "-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;
/* do_scanbus= 1; */
} else if(strncmp(argv[i], "-speed=", 7)==0 ||
strncmp(argv[i], "speed=", 6)==0) {
cpt= strchr(argv[i], '=')+1;
strncpy(speed, cpt, 79);
speed[79]= 0;
} else if(strncmp(argv[i], "-stream_recording=", 18)==0 ||
strncmp(argv[i], "stream_recording=", 17)==0) {
cpt= strchr(argv[i], '=')+1;
Xorriso_option_stream_recording(xorriso, cpt, 0);
} else if(strncmp(argv[i], "-dvd_obs=", 9)==0 ||
strncmp(argv[i], "dvd_obs=", 8)==0) {
cpt= strchr(argv[i], '=') + 1;
Xorriso_option_dvd_obs(xorriso, cpt, 0);
} else if(strncmp(argv[i], "-stdio_sync=", 12)==0 ||
strncmp(argv[i], "stdio_sync=", 11)==0) {
cpt= strchr(argv[i], '=') + 1;
Xorriso_option_stdio_sync(xorriso, cpt, 0);
} else if(strcmp(argv[i], "-toc")==0 || strcmp(argv[i], "--long_toc")==0) {
do_toc= 1;
} else if(strncmp(argv[i], "-tsize=", 7)==0 ||
strncmp(argv[i], "tsize=", 6)==0) {
cpt= strchr(argv[i], '=')+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, argv[i]);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
ret= 0; goto ex;
}
} else if(strcmp(argv[i], "-V")==0 || strcmp(argv[i],"-Verbose")==0) {
Xorriso_option_scsi_log(xorriso, "on", 0);
} else if(strcmp(argv[i], "-v")==0 || strcmp(argv[i],"-verbose")==0) {
do_verbous++;
} else if(strcmp(argv[i], "-vv")==0) {
do_verbous+= 2;
} else if(strcmp(argv[i], "-vvv")==0) {
do_verbous+= 3;
} else if(strcmp(argv[i], "-version")==0) {
do_version= 1;
} else if(strcmp(argv[i], "-waiti")==0) {
do_waiti= 1;
} else if(strncmp(argv[i], "write_start_address=", 20)==0) {
write_start_address= Scanf_io_size(argv[i]+20,0);
} else if(strcmp(argv[i], "-xa")==0) {
Xorriso_msgs_submit(xorriso, 0,
"Defaulting option -xa to option -data", 0, "NOTE", 0);
} else if(strcmp(argv[i], "-xa1")==0) {
if(do_xa1 == 0)
do_xa1= 1;
} else if(strcmp(argv[i], "--xa1-ignore")==0) {
do_xa1= -1;
} else if(strcmp(argv[i], "-xa2")==0) {
Xorriso_msgs_submit(xorriso, 0,
"Defaulting option -xa2 to option -data", 0, "NOTE", 0);
} else if(strcmp(argv[i], "-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(argv[i][0]=='-' && argv[i][1]!=0) {
sprintf(xorriso->info_text, "-as %s: Unknown option %s",
whom, Text_shellsafe(argv[i], sfe, 0));
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 %s",
whom, Text_shellsafe(argv[i], sfe, 0));
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
sprintf(xorriso->info_text, "First and only track source is %s",
Text_shellsafe(track_source, sfe, 0));
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) 2010 see libburnia-project.org xorriso\n");
Xorriso_result(xorriso, 1);
Xorriso_option_version(xorriso, 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 | 32 | 64;
if(!do_grow)
hflag|= 8; /* consider overwriteables as blank */
ret= Xorriso_option_dev(xorriso, dev_adr, hflag);
if(ret<=0)
goto ex;
}
if(do_help) {
Xorriso_cdrskin_help(xorriso, 0);
ret= 1; goto ex;
}
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(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);
}
ret= 1; goto ex;
}
if(!(do_checkdrive || do_atip || do_toc || blank_mode[0] || track_source[0] ||
do_eject || do_msinfo))
{ret= 1; 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_verbous<=0)
report_about= "SORRY";
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_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;
ret= Xorriso_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;
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", "--md5", "--for_backup",
"--protective-msdos-label", "--boot-catalog-hide", "--no-emul-toc",
""
};
static char arg1_options[][41]= {
"-abstract", "-A", "-appid", "-biblio", "-b", "-B", "-boot-load-seg",
"-boot-load-size", "-C", "-c", "-check-session", "-copyright",
"-dir-mode", "-file-mode", "-G", "-gid", "-hide", "-hide-list",
"-hidden", "-hidden-list", "-hide-joliet", "-hide-joliet-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-exclude", "-jigdo-map", "-md5-list",
"-jigdo-template-compress",
"-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",
""
};
static char arg2_options[][41]= {
"--scdbackup_tag", "--sort-weight",
""
};
static char arg3_options[][41]= {
"-append_partition",
""
};
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 **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-multidot",
"-cache-inodes", "-no-cache-inodes", "-check-oldnames", "-D",
2010-10-27 06:38:29 +00:00
"-L", "-max-iso9660-filenames", "-nobak",
"-no-bak", "-force-rr", "-relaxed-filenames", "-T",
"-no-iso-translate",
""
};
static char ignored_arg1_options[][41]= {
"-check-session", "-hide-hfs", "-hide-hfs-list", "-root",
"-old-root", "-table-name", "-volset-seqno", "-volset-size",
""
};
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);
}
int Xorriso_genisofs_add_boot(struct XorrisO *xorriso, char *whom,
int *option_b, int *emul_boot, int flag)
{
int ret;
if(*option_b)
xorriso->boot_image_emul= *emul_boot;
else
xorriso->boot_image_emul= 0;
ret= Xorriso_attach_boot_image(xorriso, 0);
if(ret <= 0)
xorriso->boot_image_bin_path[0]= 0;
*option_b= 0;
*emul_boot= 2;
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 xorriso",
"Options:",
" -f, -follow-links Follow symbolic links",
" -graft-points Allow to use graft points for filenames",
" -help Print option help",
" -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",
" -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)",
" -J, -joliet Generate Joliet directory information",
2010-10-27 06:38:29 +00:00
" -joliet-long Allow Joliet file names to be 103 Unicode characters",
" -U, -untranslated-filenames Allow Untranslated filenames (for HPUX & AIX - violates ISO9660).",
" -allow-lowercase Allow lower case characters in addition to the current character set (violates ISO9660)",
" -d, -omit-period Omit trailing periods from filenames (violates ISO9660)",
" -l, -full-iso9660-filenames Allow full 31 character filenames for ISO9660 names",
" -N, -omit-version-number Omit version number from ISO9660 filename (violates ISO9660)",
" -o FILE, -output FILE Set output file name",
" -m GLOBFILE, -exclude GLOBFILE",
" Exclude file name",
2010-06-25 09:59:20 +00:00
" -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",
2010-06-25 09:59:20 +00:00
" -dir-mode mode Make the mode of all directories this mode.",
2010-06-25 10:22:28 +00:00
" -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",
" -R, -rock Generate Rock Ridge directory information",
" -r, -rational-rock Generate rationalized Rock Ridge directory information",
" --hardlinks Record eventual hard link relations of files",
" --acl Record eventual ACLs of files",
" --xattr Record eventual user space xattr of files",
" --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",
" -abstract FILE Set Abstract filename",
" -biblio FILE Set Bibliographic filename",
" -copyright FILE Set Copyright filename",
" -p PREP, -preparer PREP Set Volume preparer",
" -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-md5 PATTERN Pattern(s) where files MUST match an externally-supplied MD5sum",
" -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)",
" -md5-list FILE File containing MD5 sums of the files that should be checked",
" -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"
" -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",
" -G FILE, -generic-boot FILE Set generic boot image name",
" --protective-msdos-label Patch System Area by partition table",
" -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",
" -mips-boot FILE Set mips boot image name (relative to image root)",
" -append_partition NUMBER TYPE FILE",
" Append FILE after image. TYPE is hex: 0x..",
" --modification-date=YYYYMMDDhhmmsscc",
" Override date of creation and modification",
" -isohybrid-mbr FILE Set SYSLINUX mbr/isohdp[fp]x*.bin for isohybrid",
#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",
" --stdio_sync on|off|number Control forced output to disk files",
" --no-emul-toc Save 64 kB size on random access output files",
" -z, -transparent-compression",
" Enable transparent compression of files",
" -v, -verbose Verbose",
" -version Print the current version",
"@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);
}
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.
*/
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 & 3) == 0)
return(2);
if(strchr(pattern, '/') != NULL) {
argv[0]= pattern;
ret= Xorriso_option_not_paths(xorriso, 1, argv, &zero,
4 | (hide_attrs & 3));
} else {
ret= Xorriso_option_not_leaf(xorriso, pattern, hide_attrs & 3);
}
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;
FILE *fp= NULL;
if(adr[0]==0) {
sprintf(xorriso->info_text,
"Empty file name given with -as %s -hide-%slist",
whom, hide_attrs == 1 ? "" : "joliet-");
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);
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:;
if(flag & 1)
Xorriso_read_lines(xorriso, fp, &linecount, &argc, &argv, 2);
if(fp != NULL && fp != stdin)
fclose(fp);
if(ret<=0)
return(ret);
return(!was_failure);
}
/* 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= 0, emul_boot= 2;
2010-06-25 10:22:28 +00:00
int option_b= 0, was_failure= 0, fret, lower_r= 0, zero= 0;
int dir_mode= -1, file_mode= -1, count;
2010-06-25 09:59:20 +00:00
mode_t mode_and, mode_or;
int with_boot_image= 0, with_cat_path= 0;
int *weight_list= NULL, weight_count= 0;
int *delay_opt_list= NULL, delay_opt_count= 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;
2010-09-29 15:28:57 +00:00
char *boot_path;
static char *sort_weight_args[4]= {"", "-exec", "sort_weight", ""};
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);
return(-1);
}
delay_opt_list= TSOB_FELD(int, argc + 1);
if(delay_opt_list == NULL) {
cpt= (char *) weight_list;
Xorriso_no_malloc_memory(xorriso, &cpt, 0);
return(-1);
}
if(xorriso->boot_image_cat_path[0])
with_cat_path= -1;
adr[0]= indev[0]= msc[0]= 0;
for(i= 0; i<argc; i++) {
ret= Xorriso_genisofs_ignore(xorriso, whom, argv, &i, 1);
if(ret == 1)
continue;
if(strcmp(argv[i], "-version")==0) {
sprintf(xorriso->result_line,
"mkisofs 2.01-Emulation Copyright (C) 2010 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(argv[i], "-o")==0 || strcmp(argv[i], "-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(argv[i], "-M")=</