You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
tbm-utils/source/unpack.c

100 lines
1.9 KiB

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <getopt.h>
#include <image.h>
#include <macros.h>
#include <unpack.h>
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;
}