#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; }