Implement mInsertBefore, for pre-.interp injection
[centaur.git] / src / options.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <unistd.h>
4 #include <getopt.h>
5
6 #include "options.h"
7
8
9 static void printUsage(char *progname)
10 {
11   printf("Usage: %s [OPTIONS] <elf-file>\n", progname);
12   printf("\n"
13           "Options:\n"
14           "  -h, --help                     Print this help message\n"
15           "  -o, --output                   Where to write the modified ELF file to\n"
16           "\n"
17           "      --print-header             Print ELF header\n"
18           "      --print-segments           Print program headers\n"
19           "      --print-sections           Print sections\n"
20           "\n"
21           "      --insert-before off,sz     Insert spacing at given offset\n"
22           "\n");
23 }
24
25
26
27 void parseOptions(CLIOpts *opts, int argc, char **argv)
28 {
29   char *progname = argv[0];
30   int c;
31   int option_index = 0;
32   char *endptr;
33
34   static struct option long_options[] = {
35     {"help", 0, 0, 'h'},
36     {"output", 1, 0, 'o'},
37     {"print-header", 0, 0, 10001},
38     {"print-segments", 0, 0, 10002},
39     {"print-sections", 0, 0, 10003},
40     {"insert-before", 1, 0, 10004},
41     {NULL, 0, NULL, 0}
42   };
43
44   while ((c = getopt_long(argc, argv, "e:ho:",
45                           long_options, &option_index)) != -1) {
46     switch (c) {
47       case 'h':
48         printUsage(progname);
49         exit(EXIT_SUCCESS);
50       case 'o':
51         opts->fnOutput = optarg;
52         break;
53       case 10001:
54         opts->printHeader = 1;
55         break;
56       case 10002:
57         opts->printSegments = 1;
58         break;
59       case 10003:
60         opts->printSections = 1;
61         break;
62       case 10004:
63         opts->insertBeforeOffs = strtoul(optarg, &endptr, 0);
64         if (endptr[0] != ',') {
65           goto USAGE;
66         }
67         opts->insertBeforeSz = strtoul(endptr + 1, &endptr, 0);
68         if (endptr[0] != '\0' || opts->insertBeforeSz == 0) {
69           goto USAGE;
70         }
71         break;
72       case '?':
73       default:
74         goto USAGE;
75     }
76   }
77
78   while (optind < argc) {
79     if (!opts->fnInput) {
80       opts->fnInput = argv[optind];
81     }
82     optind++;
83   }
84
85   if (!opts->fnInput) {
86     fprintf(stderr, "Error: No input file specified.\n\n");
87     goto USAGE;
88   }
89
90   return;
91
92 USAGE:
93   printUsage(progname);
94   exit(1);
95 }