From d30a6525d237105ff77e0728fd7378cc674701a3 Mon Sep 17 00:00:00 2001 From: Bobby Bingham Date: Sat, 12 Sep 2015 13:51:55 -0500 Subject: rename bins --- Makefile | 4 +- src/satmkboot.c | 277 ---------------------------------------------------- src/satmkiso.c | 116 ---------------------- src/saturn-mkboot.c | 277 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/saturn-mkiso.c | 116 ++++++++++++++++++++++ 5 files changed, 395 insertions(+), 395 deletions(-) delete mode 100644 src/satmkboot.c delete mode 100644 src/satmkiso.c create mode 100644 src/saturn-mkboot.c create mode 100644 src/saturn-mkiso.c diff --git a/Makefile b/Makefile index 10bd278..9aeb8b7 100644 --- a/Makefile +++ b/Makefile @@ -22,7 +22,7 @@ BOOTBINS = $(patsubst boot/%.c,share/boot/%,$(BOOTSRCS)) SRCS = $(sort $(wildcard src/*.c)) DATA = $(sort $(wildcard src/*.bin)) OBJS = $(SRCS:.c=.o) $(DATA:.bin=.o) -BINS = bin/satmkboot bin/satmkiso +BINS = bin/saturn-mkboot bin/saturn-mkiso .PHONY: all clean install install-bins install-data @@ -33,7 +33,7 @@ install: install-bins install-data clean: rm -f $(BINS) $(OBJS) $(BOOTBINS) $(BOOTELFS) -bin/satmkboot: src/securitycode.o src/symbols.o +bin/saturn-mkboot: src/securitycode.o src/symbols.o bin/%: src/%.o $(CC) $(LDFLAGS) $^ -o $@ diff --git a/src/satmkboot.c b/src/satmkboot.c deleted file mode 100644 index 63e7bb6..0000000 --- a/src/satmkboot.c +++ /dev/null @@ -1,277 +0,0 @@ -#include -#include -#include -#include -#include -#include - -#include "bootinfo.h" -#include "symbols.h" - -static struct systemid sysid = { - .magic = "SEGA SEGASATURN ", - .maker = "SEGA TP T-000 ", - .product = "T-000000G ", - .version = "V0.001", - .reldate = "20000101", - .device = "CD-1/1 ", - .regions = "JTUBKAEL ", - .peripherals = "J ", - .padding1 = " ", - .title = "TEST TITLE ", - .bootsize = 0xe00, - .stack_master = 0, - .stack_slave = 0, - .load_addr = 0x06004000, - .load_size = 0, -}; - -static char ipbuf[0x7200]; -static char *ipfile, *outfile; - -static void serialize_region_code(char *out, const struct symbolname *region) -{ - static const char defcode[32] = "\xa0\x0e\x00\x09" "For "; - size_t namelen = region ? strlen(region->name) : 0; - - memcpy(out, defcode, sizeof defcode); - if (namelen) memcpy(out+8, region->name, namelen); - out[8+namelen] = '.'; -} - -#define WRITE(f,p,s) fwrite(p,s,1,f) -#define WRITE32(f,v) fwrite((char[]){(v)>>24,(v)>>16,(v)>>8,(v)},4,1,f) - -static int write_output(FILE *fp) -{ - extern const unsigned char securitycode[]; - extern const size_t securitycode_size; - - /* system id - 0x100 bytes */ - WRITE (fp, &sysid, offsetof(struct systemid, bootsize)); - WRITE32(fp, sysid.bootsize); - WRITE32(fp, 0); /* reserved bytes */ - WRITE32(fp, sysid.stack_master); - WRITE32(fp, sysid.stack_slave); - WRITE32(fp, sysid.load_addr); - WRITE32(fp, sysid.load_size); - WRITE32(fp, 0); /* reserved bytes */ - WRITE32(fp, 0); /* reserved bytes */ - - /* security code */ - WRITE(fp, securitycode, securitycode_size); - - /* initial program */ - WRITE(fp, ipbuf, sysid.bootsize - 0xe00); - return ferror(fp) ? -1 : 0; -} - -static size_t default_ip(char *out) -{ - size_t size = 0; - - out[size++] = 0xd0; /* mov.l addr, r0 */ - out[size++] = 0x01; - out[size++] = 0x40; /* jmp @r0 */ - out[size++] = 0x2b; - out[size++] = 0x00; /* nop */ - out[size++] = 0x09; - out[size++] = 0x00; /* nop */ - out[size++] = 0x09; - out[size++] = sysid.load_addr >> 24 & 0xff; /* addr: .long */ - out[size++] = sysid.load_addr >> 16 & 0xff; - out[size++] = sysid.load_addr >> 8 & 0xff; - out[size++] = sysid.load_addr >> 0 & 0xff; - - return size; -} - -static size_t load_ip(char *filename, char *out, size_t maxsize) -{ - FILE *fp; - size_t size; - const char *errprefix = "Error loading initial program"; - - if (!(fp = fopen(filename, "rb"))) { - goto fail_perror; - } - if ((size = fread(out, 1, maxsize, fp)) < maxsize) { - /* read fewer than requested amount. determine if we hit error or eof */ - if (ferror(fp)) { - goto fail_perror; - } - } else { - /* successfully read the requested amount. verify we reached eof */ - if (fgetc(fp) != EOF) { - fprintf(stderr, "%s: exceeds maximum size\n", errprefix); - goto fail; - } - } - - fclose(fp); - return size; - -fail_perror: - perror(errprefix); -fail: - if (fp) fclose(fp); - return -1; -} - -static void print_symbols(int width, const struct symbolname *symbols) -{ - for (; symbols->symbol; symbols++) { - printf("\t%*s%c: %s\n", width+4, "", symbols->symbol, symbols->name); - } -} - -static void usage(const char *progname) -{ - const int width = 20; - - printf("usage: %s -h\n", progname); - printf(" %s -o[iprms]\n\n", progname); - printf("\t%-*s%s\n", width, "-h", "Show this help text"); - printf("\t%-*s%s\n", width, "-o output", "Output file"); - printf("\t%-*s%s\n", width, "-i ip.bin", "Initial program code file"); - printf("\t%-*s%s\n", width, "-p peripherals", "Supported peripherals (default: control pad):"); - print_symbols(width, peripheraldefs); - printf("\t%-*s%s\n", width, "-r regions", "Geographical regions (default: all):"); - print_symbols(width, regiondefs); - printf("\t%-*s%s\n", width, "-m master_stack", "Master stack address (default 0x06002000)"); - printf("\t%-*s%s\n", width, "-s slave_stack", "Slave stack address (default 0x06001000)"); - - exit(0); -} - -static int process_symbols(const char *progname, char *list, size_t size, const char *arg) -{ - while (size-- && *arg) *list++ = *arg++; - while (size--) *list++ = ' '; - return *arg; -} - -static int process_address(const char *progname, uint32_t *addr, const char *arg) -{ - char *end; - errno = 0; - unsigned long val = strtoul(arg, &end, 16); - if (end == arg || *end || errno || val > (uint32_t)-1) return 1; - *addr = val; - return 0; -} - -#define FLAG_o (1U << 3) - -static int process_args(int argc, char **argv) -{ - uint32_t seen = 0; - int opt, fail = 0; - - extern char *optarg; - extern int optind, optopt; - static const char *optpat = "hi:o:p:r:m:s:"; - while ((opt = getopt(argc, argv, optpat)) != -1) { - uint32_t flag = opt == '?' ? 0 : 1U << strchr(optpat, opt) - optpat; - if (seen & flag) { - fprintf(stderr, "%s: Duplicate option -%c\n", argv[0], opt); - fail = 1; - continue; - } - seen |= flag; - - switch (opt) { - case 'h': - usage(argv[0]); - - case 'i': - ipfile = optarg; - break; - - case 'o': - outfile = optarg; - break; - - case 'm': - if (process_address(argv[0], &sysid.stack_master, optarg)) { - fprintf(stderr, "%s: Invalid master stack\n", argv[0]); - fail = 1; - } - break; - - case 's': - if (process_address(argv[0], &sysid.stack_slave, optarg)) { - fprintf(stderr, "%s: Invalid slave stack\n", argv[0]); - fail = 1; - } - break; - - case 'p': - if (process_symbols(argv[0], sysid.peripherals, sizeof sysid.peripherals, optarg)) { - fprintf(stderr, "%s: Too many peripherals specified (max 16)\n", argv[0]); - fail = 1; - } - break; - - case 'r': - if (process_symbols(argv[0], sysid.regions, sizeof sysid.regions, optarg)) { - fprintf(stderr, "%s: Too many regions specified (max 10)\n", argv[0]); - fail = 1; - } - break; - - default: - fail = 1; - } - } - - if (!(seen & FLAG_o)) { - fprintf(stderr, "%s: Missing required option -o\n", argv[0]); - fail = 1; - } - if (argv[optind]) { - fprintf(stderr, "%s: Unknown option '%s'\n", argv[0], argv[optind]); - fail = 1; - } - if (fail) fprintf(stderr, "\nUse -h option for help on correct usage.\n"); - - return fail; -} - -int main(int argc, char **argv) -{ - FILE *outfp = NULL; - char *ipout = ipbuf; - size_t ipsize; - - if (process_args(argc, argv)) return 1; - - for (int i = 0; i < 8; i++) { - serialize_region_code(ipout, find_symbol(regiondefs, sysid.regions[i])); - ipout += 32; - sysid.bootsize += 32; - } - - ipsize = ipfile - ? load_ip(ipfile, ipout, sizeof ipbuf - (ipout - ipbuf)) - : default_ip(ipout); - if (ipsize == -1) goto fail; - sysid.bootsize += ipsize; - - if (!(outfp = fopen(outfile, "wb"))) { - perror("Error opening output file"); - goto fail; - } - - if (write_output(outfp)) { - perror("Error writing output"); - goto fail; - } - - fclose(outfp); - return 0; - -fail: - if (outfp) fclose(outfp); - return 1; -} diff --git a/src/satmkiso.c b/src/satmkiso.c deleted file mode 100644 index 766d3ce..0000000 --- a/src/satmkiso.c +++ /dev/null @@ -1,116 +0,0 @@ -#include -#include -#include -#include -#include -#include - -static void usage(const char *progname) -{ - static const int width = 24; - - printf("usage: %s -h\n", progname); - printf(" %s -bo[ABC] [files...]\n\n", progname); - printf("\t%-*s%s\n", width, "-h", "Show this help text"); - printf("\t%-*s%s\n", width, "-b bootsector", "Bootsector image"); - printf("\t%-*s%s\n", width, "-o output", "Output isofs file"); - printf("\t%-*s%s\n", width, "-A abstract_path", "Path in isofs of abstract file"); - printf("\t%-*s%s\n", width, "-B bibliography_path", "Path in isofs of bibliography file"); - printf("\t%-*s%s\n", width, "-C copyright_path", "Path in isofs of copyright file"); - printf("\t%-*s%s\n", width, "files...", "Files to include in the isofs image"); - - printf("\nFor -A/B/C, the path must refer to a file which exists within the isofs image.\n"); -} - -#define FLAG_o (1U << 1) -#define FLAG_b (1U << 3) -#define FLAG_A (1U << 5) -#define FLAG_B (1U << 7) -#define FLAG_C (1U << 9) - -int main(int argc, char **argv) -{ - static const char *optpat = "ho:b:A:B:C:"; - static const char *fileopts = "boABC"; - char *specialfiles[5] = { - 0, 0, "DUMMY.TXT", "DUMMY.TXT", "DUMMY.TXT", - }; - -#define SPECIALFILE(c) specialfiles[strchr(fileopts, (c)) - fileopts] - - uint32_t seen = 0; - int opt, fail = 0; - -#define SEEN(flags) ((seen | (flags)) == seen) -#define FLAG(c) (1U << (strchr(optpat, (c)) - optpat)) - - extern char *optarg; - extern int optind, optopt; - while ((opt = getopt(argc, argv, optpat)) != -1) { - uint32_t flag = opt == '?' ? 0 : FLAG(opt); - if (SEEN(flag)) { - fprintf(stderr, "%s: Duplicate option -%c\n", argv[0], opt); - fail = 1; - continue; - } - seen |= flag; - - switch (opt) { - case 'h': - usage(argv[0]); - return 0; - - case 'b': - case 'o': - case 'A': - case 'B': - case 'C': - SPECIALFILE(opt) = optarg; - break; - - default: - fail = 1; - } - } - - for (const char *c = "bo"; *c; c++) { - if (!SEEN(FLAG(*c))) { - fprintf(stderr, "%s: Missing required option -%c\n", argv[0], *c); - fail = 1; - } - } - if (fail) { - fprintf(stderr, "\nUse -h option for help on correct usage.\n"); - return 1; - } - - char *argprefix[] = { - "mkisofs", "-graft-points", "-full-iso9660-filenames", - "-G", SPECIALFILE('b'), - "-o", SPECIALFILE('o'), - "-abstract", SPECIALFILE('A'), - "-biblio", SPECIALFILE('B'), - "-copyright", SPECIALFILE('C'), - }; - -#define ARRAYLEN(a) (sizeof(a) / sizeof *(a)) - - char **args = calloc(argc - optind + ARRAYLEN(argprefix) + 2, sizeof *args); - if (!args) { - perror("malloc"); - return 1; - } - - size_t argidx; - for (argidx = 0; argidx < ARRAYLEN(argprefix); argidx++) - args[argidx] = argprefix[argidx]; - while (argv[optind]) - args[argidx++] = argv[optind++]; - if (!SEEN(FLAG_A | FLAG_B | FLAG_C)) - args[argidx++] = "DUMMY.TXT=/dev/null"; - - execvp("mkisofs", args); - perror("exec"); - return 1; -} - diff --git a/src/saturn-mkboot.c b/src/saturn-mkboot.c new file mode 100644 index 0000000..63e7bb6 --- /dev/null +++ b/src/saturn-mkboot.c @@ -0,0 +1,277 @@ +#include +#include +#include +#include +#include +#include + +#include "bootinfo.h" +#include "symbols.h" + +static struct systemid sysid = { + .magic = "SEGA SEGASATURN ", + .maker = "SEGA TP T-000 ", + .product = "T-000000G ", + .version = "V0.001", + .reldate = "20000101", + .device = "CD-1/1 ", + .regions = "JTUBKAEL ", + .peripherals = "J ", + .padding1 = " ", + .title = "TEST TITLE ", + .bootsize = 0xe00, + .stack_master = 0, + .stack_slave = 0, + .load_addr = 0x06004000, + .load_size = 0, +}; + +static char ipbuf[0x7200]; +static char *ipfile, *outfile; + +static void serialize_region_code(char *out, const struct symbolname *region) +{ + static const char defcode[32] = "\xa0\x0e\x00\x09" "For "; + size_t namelen = region ? strlen(region->name) : 0; + + memcpy(out, defcode, sizeof defcode); + if (namelen) memcpy(out+8, region->name, namelen); + out[8+namelen] = '.'; +} + +#define WRITE(f,p,s) fwrite(p,s,1,f) +#define WRITE32(f,v) fwrite((char[]){(v)>>24,(v)>>16,(v)>>8,(v)},4,1,f) + +static int write_output(FILE *fp) +{ + extern const unsigned char securitycode[]; + extern const size_t securitycode_size; + + /* system id - 0x100 bytes */ + WRITE (fp, &sysid, offsetof(struct systemid, bootsize)); + WRITE32(fp, sysid.bootsize); + WRITE32(fp, 0); /* reserved bytes */ + WRITE32(fp, sysid.stack_master); + WRITE32(fp, sysid.stack_slave); + WRITE32(fp, sysid.load_addr); + WRITE32(fp, sysid.load_size); + WRITE32(fp, 0); /* reserved bytes */ + WRITE32(fp, 0); /* reserved bytes */ + + /* security code */ + WRITE(fp, securitycode, securitycode_size); + + /* initial program */ + WRITE(fp, ipbuf, sysid.bootsize - 0xe00); + return ferror(fp) ? -1 : 0; +} + +static size_t default_ip(char *out) +{ + size_t size = 0; + + out[size++] = 0xd0; /* mov.l addr, r0 */ + out[size++] = 0x01; + out[size++] = 0x40; /* jmp @r0 */ + out[size++] = 0x2b; + out[size++] = 0x00; /* nop */ + out[size++] = 0x09; + out[size++] = 0x00; /* nop */ + out[size++] = 0x09; + out[size++] = sysid.load_addr >> 24 & 0xff; /* addr: .long */ + out[size++] = sysid.load_addr >> 16 & 0xff; + out[size++] = sysid.load_addr >> 8 & 0xff; + out[size++] = sysid.load_addr >> 0 & 0xff; + + return size; +} + +static size_t load_ip(char *filename, char *out, size_t maxsize) +{ + FILE *fp; + size_t size; + const char *errprefix = "Error loading initial program"; + + if (!(fp = fopen(filename, "rb"))) { + goto fail_perror; + } + if ((size = fread(out, 1, maxsize, fp)) < maxsize) { + /* read fewer than requested amount. determine if we hit error or eof */ + if (ferror(fp)) { + goto fail_perror; + } + } else { + /* successfully read the requested amount. verify we reached eof */ + if (fgetc(fp) != EOF) { + fprintf(stderr, "%s: exceeds maximum size\n", errprefix); + goto fail; + } + } + + fclose(fp); + return size; + +fail_perror: + perror(errprefix); +fail: + if (fp) fclose(fp); + return -1; +} + +static void print_symbols(int width, const struct symbolname *symbols) +{ + for (; symbols->symbol; symbols++) { + printf("\t%*s%c: %s\n", width+4, "", symbols->symbol, symbols->name); + } +} + +static void usage(const char *progname) +{ + const int width = 20; + + printf("usage: %s -h\n", progname); + printf(" %s -o[iprms]\n\n", progname); + printf("\t%-*s%s\n", width, "-h", "Show this help text"); + printf("\t%-*s%s\n", width, "-o output", "Output file"); + printf("\t%-*s%s\n", width, "-i ip.bin", "Initial program code file"); + printf("\t%-*s%s\n", width, "-p peripherals", "Supported peripherals (default: control pad):"); + print_symbols(width, peripheraldefs); + printf("\t%-*s%s\n", width, "-r regions", "Geographical regions (default: all):"); + print_symbols(width, regiondefs); + printf("\t%-*s%s\n", width, "-m master_stack", "Master stack address (default 0x06002000)"); + printf("\t%-*s%s\n", width, "-s slave_stack", "Slave stack address (default 0x06001000)"); + + exit(0); +} + +static int process_symbols(const char *progname, char *list, size_t size, const char *arg) +{ + while (size-- && *arg) *list++ = *arg++; + while (size--) *list++ = ' '; + return *arg; +} + +static int process_address(const char *progname, uint32_t *addr, const char *arg) +{ + char *end; + errno = 0; + unsigned long val = strtoul(arg, &end, 16); + if (end == arg || *end || errno || val > (uint32_t)-1) return 1; + *addr = val; + return 0; +} + +#define FLAG_o (1U << 3) + +static int process_args(int argc, char **argv) +{ + uint32_t seen = 0; + int opt, fail = 0; + + extern char *optarg; + extern int optind, optopt; + static const char *optpat = "hi:o:p:r:m:s:"; + while ((opt = getopt(argc, argv, optpat)) != -1) { + uint32_t flag = opt == '?' ? 0 : 1U << strchr(optpat, opt) - optpat; + if (seen & flag) { + fprintf(stderr, "%s: Duplicate option -%c\n", argv[0], opt); + fail = 1; + continue; + } + seen |= flag; + + switch (opt) { + case 'h': + usage(argv[0]); + + case 'i': + ipfile = optarg; + break; + + case 'o': + outfile = optarg; + break; + + case 'm': + if (process_address(argv[0], &sysid.stack_master, optarg)) { + fprintf(stderr, "%s: Invalid master stack\n", argv[0]); + fail = 1; + } + break; + + case 's': + if (process_address(argv[0], &sysid.stack_slave, optarg)) { + fprintf(stderr, "%s: Invalid slave stack\n", argv[0]); + fail = 1; + } + break; + + case 'p': + if (process_symbols(argv[0], sysid.peripherals, sizeof sysid.peripherals, optarg)) { + fprintf(stderr, "%s: Too many peripherals specified (max 16)\n", argv[0]); + fail = 1; + } + break; + + case 'r': + if (process_symbols(argv[0], sysid.regions, sizeof sysid.regions, optarg)) { + fprintf(stderr, "%s: Too many regions specified (max 10)\n", argv[0]); + fail = 1; + } + break; + + default: + fail = 1; + } + } + + if (!(seen & FLAG_o)) { + fprintf(stderr, "%s: Missing required option -o\n", argv[0]); + fail = 1; + } + if (argv[optind]) { + fprintf(stderr, "%s: Unknown option '%s'\n", argv[0], argv[optind]); + fail = 1; + } + if (fail) fprintf(stderr, "\nUse -h option for help on correct usage.\n"); + + return fail; +} + +int main(int argc, char **argv) +{ + FILE *outfp = NULL; + char *ipout = ipbuf; + size_t ipsize; + + if (process_args(argc, argv)) return 1; + + for (int i = 0; i < 8; i++) { + serialize_region_code(ipout, find_symbol(regiondefs, sysid.regions[i])); + ipout += 32; + sysid.bootsize += 32; + } + + ipsize = ipfile + ? load_ip(ipfile, ipout, sizeof ipbuf - (ipout - ipbuf)) + : default_ip(ipout); + if (ipsize == -1) goto fail; + sysid.bootsize += ipsize; + + if (!(outfp = fopen(outfile, "wb"))) { + perror("Error opening output file"); + goto fail; + } + + if (write_output(outfp)) { + perror("Error writing output"); + goto fail; + } + + fclose(outfp); + return 0; + +fail: + if (outfp) fclose(outfp); + return 1; +} diff --git a/src/saturn-mkiso.c b/src/saturn-mkiso.c new file mode 100644 index 0000000..766d3ce --- /dev/null +++ b/src/saturn-mkiso.c @@ -0,0 +1,116 @@ +#include +#include +#include +#include +#include +#include + +static void usage(const char *progname) +{ + static const int width = 24; + + printf("usage: %s -h\n", progname); + printf(" %s -bo[ABC] [files...]\n\n", progname); + printf("\t%-*s%s\n", width, "-h", "Show this help text"); + printf("\t%-*s%s\n", width, "-b bootsector", "Bootsector image"); + printf("\t%-*s%s\n", width, "-o output", "Output isofs file"); + printf("\t%-*s%s\n", width, "-A abstract_path", "Path in isofs of abstract file"); + printf("\t%-*s%s\n", width, "-B bibliography_path", "Path in isofs of bibliography file"); + printf("\t%-*s%s\n", width, "-C copyright_path", "Path in isofs of copyright file"); + printf("\t%-*s%s\n", width, "files...", "Files to include in the isofs image"); + + printf("\nFor -A/B/C, the path must refer to a file which exists within the isofs image.\n"); +} + +#define FLAG_o (1U << 1) +#define FLAG_b (1U << 3) +#define FLAG_A (1U << 5) +#define FLAG_B (1U << 7) +#define FLAG_C (1U << 9) + +int main(int argc, char **argv) +{ + static const char *optpat = "ho:b:A:B:C:"; + static const char *fileopts = "boABC"; + char *specialfiles[5] = { + 0, 0, "DUMMY.TXT", "DUMMY.TXT", "DUMMY.TXT", + }; + +#define SPECIALFILE(c) specialfiles[strchr(fileopts, (c)) - fileopts] + + uint32_t seen = 0; + int opt, fail = 0; + +#define SEEN(flags) ((seen | (flags)) == seen) +#define FLAG(c) (1U << (strchr(optpat, (c)) - optpat)) + + extern char *optarg; + extern int optind, optopt; + while ((opt = getopt(argc, argv, optpat)) != -1) { + uint32_t flag = opt == '?' ? 0 : FLAG(opt); + if (SEEN(flag)) { + fprintf(stderr, "%s: Duplicate option -%c\n", argv[0], opt); + fail = 1; + continue; + } + seen |= flag; + + switch (opt) { + case 'h': + usage(argv[0]); + return 0; + + case 'b': + case 'o': + case 'A': + case 'B': + case 'C': + SPECIALFILE(opt) = optarg; + break; + + default: + fail = 1; + } + } + + for (const char *c = "bo"; *c; c++) { + if (!SEEN(FLAG(*c))) { + fprintf(stderr, "%s: Missing required option -%c\n", argv[0], *c); + fail = 1; + } + } + if (fail) { + fprintf(stderr, "\nUse -h option for help on correct usage.\n"); + return 1; + } + + char *argprefix[] = { + "mkisofs", "-graft-points", "-full-iso9660-filenames", + "-G", SPECIALFILE('b'), + "-o", SPECIALFILE('o'), + "-abstract", SPECIALFILE('A'), + "-biblio", SPECIALFILE('B'), + "-copyright", SPECIALFILE('C'), + }; + +#define ARRAYLEN(a) (sizeof(a) / sizeof *(a)) + + char **args = calloc(argc - optind + ARRAYLEN(argprefix) + 2, sizeof *args); + if (!args) { + perror("malloc"); + return 1; + } + + size_t argidx; + for (argidx = 0; argidx < ARRAYLEN(argprefix); argidx++) + args[argidx] = argprefix[argidx]; + while (argv[optind]) + args[argidx++] = argv[optind++]; + if (!SEEN(FLAG_A | FLAG_B | FLAG_C)) + args[argidx++] = "DUMMY.TXT=/dev/null"; + + execvp("mkisofs", args); + perror("exec"); + return 1; +} + -- cgit v1.2.3