#include #include #include #include #include #include #include #include enum { OPTION_HELP = 'h', OPTION_OUTPUT = 'o', }; 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[] = { { "help", no_argument, NULL, OPTION_HELP }, { "output", required_argument, 0, OPTION_OUTPUT }, { NULL, 0, 0, 0 }, }; int ret; while ((ret = getopt_long(argc, (char * const *)argv, "ho:", options, NULL)) >= 0) { switch (ret) { case OPTION_HELP: return -1; case OPTION_OUTPUT: args->output = optarg; break; default: return -1; } } if (!args->output) return -1; if (optind >= argc) return -1; ++optind; if (optind >= argc) return -1; args->input = argv[optind]; 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]; struct rots_hdr hdr; struct args args; FILE *input, *output; size_t nbytes, size; if (parse_args(&args, argc, argv) < 0) { show_pack_usage(argv[0], argv[1]); return -1; } if (!(input = fopen(args.input, "rb"))) { fprintf(stderr, "unable to open '%s' for reading.\n", args.input); return -1; } if (!(output = fopen(args.output, "wb"))) { fprintf(stderr, "unable to open '%s' for writing.\n", args.output); goto err_close_input; } get_file_size(&size, args.input); hdr.timestamp = (uint64_t)time(NULL); hdr.size = size; printf("%zu\n", hdr.size); if (rots_write_hdr(output, &hdr) < 0) goto err_close_output; while (size) { nbytes = fread(data, sizeof *data, min(sizeof data, size), input); if (nbytes == 0) { fprintf(stderr, "unable to read the next chunk\n"); goto err_close_output; } if (fwrite(data, sizeof *data, nbytes, output) < nbytes) { fprintf(stderr, "unable to write the current chunk\n"); goto err_close_output; } size -= nbytes; } fclose(output); fclose(input); return 0; err_close_output: fclose(output); err_close_input: fclose(input); return -1; }