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/pack.c

125 lines
2.4 KiB

#include <stdio.h>
#include <time.h>
#include <getopt.h>
#include <file.h>
#include <image.h>
#include <macros.h>
#include <option.h>
#include <pack.h>
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;
}