summaryrefslogtreecommitdiff
path: root/src/satmkiso.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/satmkiso.c')
-rw-r--r--src/satmkiso.c116
1 files changed, 116 insertions, 0 deletions
diff --git a/src/satmkiso.c b/src/satmkiso.c
new file mode 100644
index 0000000..766d3ce
--- /dev/null
+++ b/src/satmkiso.c
@@ -0,0 +1,116 @@
+#include <getopt.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+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;
+}
+