diff --git a/include/info.h b/include/info.h index d2964e6..306cbbb 100644 --- a/include/info.h +++ b/include/info.h @@ -1,4 +1,6 @@ #pragma once +void show_get_offset_usage(const char *prog_name, const char *cmd); +void show_get_size_usage(const char *prog_name, const char *cmd); int do_get_offset(int argc, char *argv[]); int do_get_size(int argc, char *argv[]); diff --git a/include/pack.h b/include/pack.h index e8df87d..157002e 100644 --- a/include/pack.h +++ b/include/pack.h @@ -1,3 +1,4 @@ #pragma once +void show_pack_usage(const char *prog_name, const char *cmd); int do_pack(int argc, char *argv[]); diff --git a/include/sign.h b/include/sign.h index 25c2ccb..a0c08d8 100644 --- a/include/sign.h +++ b/include/sign.h @@ -1,3 +1,4 @@ #pragma once +void show_sign_usage(const char *prog_name, const char *cmd); int do_sign(int argc, char *argv[]); diff --git a/include/unpack.h b/include/unpack.h index b67750c..a7aac95 100644 --- a/include/unpack.h +++ b/include/unpack.h @@ -1,3 +1,4 @@ #pragma once +void show_unpack_usage(const char *prog_name, const char *cmd); int do_unpack(int argc, char *argv[]); diff --git a/include/verify.h b/include/verify.h index a59eb11..bc0730a 100644 --- a/include/verify.h +++ b/include/verify.h @@ -1,3 +1,4 @@ #pragma once +void show_verify_usage(const char *prog_name, const char *cmd); int do_verify(int argc, char *argv[]); diff --git a/source/info.c b/source/info.c index 3c73071..5da1793 100644 --- a/source/info.c +++ b/source/info.c @@ -8,6 +8,7 @@ #include #include #include +#include #include enum { @@ -19,6 +20,12 @@ struct args { const char *image; }; +static struct opt_desc opt_descs[] = { + { "-i", "--image=PATH", "the image in ROTS format" }, + { "-h", "--help", "display this help and exit" }, + { NULL, NULL, NULL }, +}; + static int parse_args(struct args *args, int argc, char *argv[]) { struct option options[] = { @@ -40,6 +47,20 @@ static int parse_args(struct args *args, int argc, char *argv[]) return 0; } +void show_get_offset_usage(const char *prog_name, const char *cmd) +{ + fprintf(stderr, "usage: %s %s [option]...\n\n" + "print the offset of the payload within an image\n\n", prog_name, cmd); + format_options(opt_descs); +} + +void show_get_size_usage(const char *prog_name, const char *cmd) +{ + fprintf(stderr, "usage: %s %s [option]...\n\n" + "print the size of the payload within an image\n\n", prog_name, cmd); + format_options(opt_descs); +} + int do_get_offset(int argc, char *argv[]) { struct args args; @@ -47,7 +68,7 @@ int do_get_offset(int argc, char *argv[]) FILE *fp; if (parse_args(&args, argc, argv) < 0) { - fprintf(stderr, "invalid\n"); + show_get_offset_usage(argv[0], argv[1]); return -1; } @@ -78,7 +99,7 @@ int do_get_size(int argc, char *argv[]) FILE *fp; if (parse_args(&args, argc, argv) < 0) { - fprintf(stderr, "invalid\n"); + show_get_size_usage(argv[0], argv[1]); return -1; } diff --git a/source/main.c b/source/main.c index b44d6f7..cef6585 100644 --- a/source/main.c +++ b/source/main.c @@ -11,23 +11,24 @@ struct entry { const char *cmd; int (* main)(int argc, char *argv[]); + void (* show_usage)(const char *prog_name, const char *cmd); char *desc; }; struct entry entries[] = { - { "get-offset", do_get_offset, + { "get-offset", do_get_offset, show_get_offset_usage, "print the offset of the payload within an image" }, - { "get-size", do_get_size, + { "get-size", do_get_size, show_get_size_usage, "print the size of the payload within an image" }, - { "pack", do_pack, + { "pack", do_pack, show_pack_usage, "pack the payload within an image" }, - { "sign", do_sign, + { "sign", do_sign, show_sign_usage, "sign an image" }, - { "unpack", do_unpack, + { "unpack", do_unpack, show_unpack_usage, "unpack the payload of an image" }, - { "verify", do_verify, + { "verify", do_verify, show_verify_usage, "verify the signatures of an image" }, - { NULL, NULL, NULL }, + { NULL, NULL, NULL, NULL }, }; static void show_usage(const char *prog_name) @@ -39,10 +40,28 @@ static void show_usage(const char *prog_name) "Available commands:\n", prog_name); for (entry = entries; entry->cmd; ++entry) { - fprintf(stderr, "\t%-16s %-80s\n", entry->cmd, entry->desc); + fprintf(stderr, "\t%-16s %s\n", entry->cmd, entry->desc); } } +static void show_cmd_usage(char *prog_name, char *cmd) +{ + struct entry *entry; + + for (entry = entries; entry->cmd; ++entry) { + if (strcmp(entry->cmd, cmd) != 0) + continue; + + if (!entry->show_usage) + break; + + entry->show_usage(prog_name, cmd); + return; + } + + show_usage(prog_name); +} + int main(int argc, char *argv[]) { struct entry *entry; @@ -52,6 +71,15 @@ int main(int argc, char *argv[]) return -1; } + if (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0) { + if (argc < 3) + show_usage(argv[0]); + else + show_cmd_usage(argv[0], argv[2]); + + return -1; + } + for (entry = entries; entry->cmd; ++entry) { if (strcmp(entry->cmd, argv[1]) == 0) return entry->main(argc, argv); diff --git a/source/pack.c b/source/pack.c index c14466d..8071908 100644 --- a/source/pack.c +++ b/source/pack.c @@ -6,6 +6,7 @@ #include #include #include +#include #include enum { @@ -17,6 +18,12 @@ struct args { const char *input, *output; }; +static struct opt_desc opt_descs[] = { + { "-o", "--output", "the file to contain the image in ROTS format" }, + { "-h", "--help", "display this help and exit" }, + { NULL, NULL, NULL }, +}; + static int parse_args(struct args *args, int argc, char *argv[]) { struct option options[] = { @@ -31,10 +38,13 @@ static int parse_args(struct args *args, int argc, char *argv[]) switch (ret) { case OPTION_HELP: return -1; case OPTION_OUTPUT: args->output = optarg; break; - default: break; + default: return -1; } } + if (!args->output) + return -1; + if (optind >= argc) return -1; @@ -48,6 +58,13 @@ static int parse_args(struct args *args, int argc, char *argv[]) return 0; } +void show_pack_usage(const char *prog_name, const char *cmd) +{ + fprintf(stderr, "usage: %s %s [option]...\n\n" + "pack the payload within an image\n\n", prog_name, cmd); + format_options(opt_descs); +} + int do_pack(int argc, char *argv[]) { char data[4096]; @@ -57,7 +74,7 @@ int do_pack(int argc, char *argv[]) size_t nbytes, size; if (parse_args(&args, argc, argv) < 0) { - fprintf(stderr, "invalid\n"); + show_pack_usage(argv[0], argv[1]); return -1; } diff --git a/source/sign.c b/source/sign.c index 55098e5..63e58b5 100644 --- a/source/sign.c +++ b/source/sign.c @@ -14,6 +14,7 @@ #include #include +#include #include #include @@ -29,6 +30,16 @@ struct args { const char *image, *digest, *key, *cert; }; +static struct opt_desc opt_descs[] = { + { "-i", "--image=PATH","the image in ROTS format to sign" }, + { "-d", "--digest={ripemd160,sha224,sha256,sha384,sha512,whirlpool}\n", + "\t\tthe digest algorithm to use for signing" }, + { "-k", "--key=PATH", "the private key" }, + { "-c", "--cert=PATH", "the certificate containing the public key" }, + { "-h", "--help", "display this help and exit" }, + { NULL, NULL, NULL }, +}; + static int parse_args(struct args *args, int argc, char *argv[]) { struct option options[] = { @@ -53,6 +64,9 @@ static int parse_args(struct args *args, int argc, char *argv[]) } } + if (!args->image || !args->digest || !args->key || !args->cert) + return -1; + return 0; } @@ -158,6 +172,13 @@ err_close_image: return -1; } +void show_sign_usage(const char *prog_name, const char *cmd) +{ + fprintf(stderr, "usage: %s %s [option]...\n\n" + "sign an image\n\n", prog_name, cmd); + format_options(opt_descs); +} + int do_sign(int argc, char *argv[]) { struct args args; @@ -166,7 +187,7 @@ int do_sign(int argc, char *argv[]) char *cn; if (parse_args(&args, argc, argv) < 0) { - fprintf(stderr, "invalid\n"); + show_sign_usage(argv[0], argv[1]); return -1; } diff --git a/source/unpack.c b/source/unpack.c index 9331161..bf7fbdc 100644 --- a/source/unpack.c +++ b/source/unpack.c @@ -6,6 +6,7 @@ #include #include +#include #include enum { @@ -18,6 +19,13 @@ struct args { const char *image, *output; }; +static struct opt_desc opt_descs[] = { + { "-i", "--image=PATH", "the image in ROTS format to unpack" }, + { "-o", "--output=PATH", "the file to contain the payload" }, + { "-h", "--help", "display this help and exit" }, + { NULL, NULL, NULL }, +}; + static int parse_args(struct args *args, int argc, char *argv[]) { struct option options[] = { @@ -34,13 +42,23 @@ static int parse_args(struct args *args, int argc, char *argv[]) case OPTION_HELP: return -1; case OPTION_IMAGE: args->image = optarg; break; case OPTION_OUTPUT: args->output = optarg; break; - default: break; + default: return -1; } } + if (!args->image || !args->output) + return -1; + return 0; } +void show_unpack_usage(const char *prog_name, const char *cmd) +{ + fprintf(stderr, "usage: %s %s [option]...\n\n" + "unpack the payload of an image\n\n", prog_name, cmd); + format_options(opt_descs); +} + int do_unpack(int argc, char *argv[]) { char data[512]; @@ -49,8 +67,10 @@ int do_unpack(int argc, char *argv[]) struct args args; size_t nbytes, size; + memset(&args, 0, sizeof args); + if (parse_args(&args, argc, argv) < 0) { - fprintf(stderr, "invalid\n"); + show_unpack_usage(argv[0], argv[1]); return -1; } diff --git a/source/verify.c b/source/verify.c index 4d750df..939d0bd 100644 --- a/source/verify.c +++ b/source/verify.c @@ -15,6 +15,7 @@ #include #include +#include #include #include @@ -28,6 +29,13 @@ struct args { const char *image, *digest, *certs; }; +static struct opt_desc opt_descs[] = { + { "-i", "--image=PATH", "the image in ROTS format to verify" }, + { "-c", "--certs=PATH", "the directory containing the certificates" }, + { "-h", "--help", "display this help and exit" }, + { NULL, NULL, NULL }, +}; + static int parse_args(struct args *args, int argc, char *argv[]) { struct option options[] = { @@ -38,7 +46,7 @@ static int parse_args(struct args *args, int argc, char *argv[]) }; int ret; - while ((ret = getopt_long(argc, (char * const *)argv, "hi:d:c:", options, + while ((ret = getopt_long(argc, (char * const *)argv, "hi:c:", options, NULL)) >= 0) { switch (ret) { case OPTION_HELP: return -1; @@ -48,6 +56,9 @@ static int parse_args(struct args *args, int argc, char *argv[]) } } + if (!args->image || !args->certs) + return -1; + return 0; } @@ -220,13 +231,20 @@ err_close_image: return -1; } +void show_verify_usage(const char *prog_name, const char *cmd) +{ + fprintf(stderr, "usage: %s %s [option]...\n\n" + "verify the signature of an image\n\n", prog_name, cmd); + format_options(opt_descs); +} + int do_verify(int argc, char *argv[]) { struct args args; size_t count, total; if (parse_args(&args, argc, argv) < 0) { - fprintf(stderr, "invalid\n"); + show_verify_usage(argv[0], argv[1]); return -1; }