#include #include #include #include #include #include #include enum { OPTION_HELP = 'h', OPTION_IMAGE = 'i', OPTION_OUTPUT = 'o', }; struct args { const char *image, *output; }; static int parse_args(struct args *args, int argc, char *argv[]) { struct option options[] = { { "help", no_argument, NULL, OPTION_HELP }, { "image", required_argument, NULL, OPTION_IMAGE }, { "output", required_argument, NULL, OPTION_OUTPUT }, { NULL, 0, 0, 0 }, }; int ret; while ((ret = getopt_long(argc, (char * const *)argv, "hi:o:", options, NULL)) >= 0) { switch (ret) { case OPTION_HELP: return -1; case OPTION_IMAGE: args->image = optarg; break; case OPTION_OUTPUT: args->output = optarg; break; default: break; } } return 0; } int do_unpack(int argc, char *argv[]) { char data[512]; struct rots_hdr hdr; FILE *in, *out; struct args args; size_t nbytes, size; if (parse_args(&args, argc, argv) < 0) { fprintf(stderr, "invalid\n"); return -1; } if (!(in = fopen(args.image, "rb"))) { fprintf(stderr, "error: file '%s' not found.\n", args.image); return -1; } if (!(out = fopen(args.output, "wb"))) { fprintf(stderr, "error: cannot open '%s' for writing.\n", args.output); goto err_close_in; } if (rots_read_hdr(in, &hdr) < 0) { fprintf(stderr, "error: file '%s' is not a ROTS-image.\n", args.image); goto err_close_out; } size = hdr.size; while (size) { nbytes = fread(data, sizeof *data, min(size, sizeof data), in); if (nbytes == 0) { fprintf(stderr, "error: cannot read the next chunk.\n"); goto err_close_out; } if (fwrite(data, sizeof *data, nbytes, out) < nbytes) { fprintf(stderr, "error: cannot write the current chunk.\n"); goto err_close_out; } size -= nbytes; } fclose(out); fclose(in); return 0; err_close_out: fclose(out); err_close_in: fclose(in); return -1; }