mirror of
https://github.com/openwrt/openwrt.git
synced 2024-12-23 23:42:43 +00:00
otrx: support for creating simple TRX files
Signed-off-by: Rafał Miłecki <zajec5@gmail.com> SVN-Revision: 45444
This commit is contained in:
parent
3cb8bf44e6
commit
8b1b857948
@ -220,6 +220,184 @@ out:
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**************************************************
|
||||||
|
* Create
|
||||||
|
**************************************************/
|
||||||
|
|
||||||
|
static void otrx_create_parse_options(int argc, char **argv) {
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t otrx_create_append_file(FILE *trx, const char *in_path) {
|
||||||
|
FILE *in;
|
||||||
|
size_t bytes;
|
||||||
|
ssize_t length = 0;
|
||||||
|
uint8_t buf[128];
|
||||||
|
|
||||||
|
in = fopen(in_path, "r");
|
||||||
|
if (!in) {
|
||||||
|
fprintf(stderr, "Couldn't open %s\n", in_path);
|
||||||
|
return -EACCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
while ((bytes = fread(buf, 1, sizeof(buf), in)) > 0) {
|
||||||
|
if (fwrite(buf, 1, bytes, trx) != bytes) {
|
||||||
|
fprintf(stderr, "Couldn't write %zu B to %s\n", bytes, trx_path);
|
||||||
|
length = -EIO;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
length += bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(in);
|
||||||
|
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t otrx_create_append_zeros(FILE *trx, size_t length) {
|
||||||
|
uint8_t *buf;
|
||||||
|
|
||||||
|
buf = malloc(length);
|
||||||
|
if (!buf)
|
||||||
|
return -ENOMEM;
|
||||||
|
memset(buf, 0, length);
|
||||||
|
|
||||||
|
if (fwrite(buf, 1, length, trx) != length) {
|
||||||
|
fprintf(stderr, "Couldn't write %zu B to %s\n", length, trx_path);
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t otrx_create_align(FILE *trx, size_t curr_offset, size_t alignment) {
|
||||||
|
if (curr_offset & (alignment - 1)) {
|
||||||
|
size_t length = alignment - (curr_offset % alignment);
|
||||||
|
return otrx_create_append_zeros(trx, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int otrx_create_write_hdr(FILE *trx, struct trx_header *hdr) {
|
||||||
|
size_t bytes, length;
|
||||||
|
uint8_t *buf;
|
||||||
|
uint32_t crc32;
|
||||||
|
|
||||||
|
hdr->magic = cpu_to_le32(TRX_MAGIC);
|
||||||
|
hdr->version = 1;
|
||||||
|
|
||||||
|
fseek(trx, 0, SEEK_SET);
|
||||||
|
bytes = fwrite(hdr, 1, sizeof(struct trx_header), trx);
|
||||||
|
if (bytes != sizeof(struct trx_header)) {
|
||||||
|
fprintf(stderr, "Couldn't write TRX header to %s\n", trx_path);
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
length = le32_to_cpu(hdr->length);
|
||||||
|
|
||||||
|
buf = malloc(length);
|
||||||
|
if (!buf) {
|
||||||
|
fprintf(stderr, "Couldn't alloc %zu B buffer\n", length);
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
fseek(trx, 0, SEEK_SET);
|
||||||
|
bytes = fread(buf, 1, length, trx);
|
||||||
|
if (bytes != length) {
|
||||||
|
fprintf(stderr, "Couldn't read %zu B of data from %s\n", length, trx_path);
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
crc32 = otrx_crc32(buf + TRX_FLAGS_OFFSET, length - TRX_FLAGS_OFFSET);
|
||||||
|
hdr->crc32 = cpu_to_le32(crc32);
|
||||||
|
|
||||||
|
fseek(trx, 0, SEEK_SET);
|
||||||
|
bytes = fwrite(hdr, 1, sizeof(struct trx_header), trx);
|
||||||
|
if (bytes != sizeof(struct trx_header)) {
|
||||||
|
fprintf(stderr, "Couldn't write TRX header to %s\n", trx_path);
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int otrx_create(int argc, char **argv) {
|
||||||
|
FILE *trx;
|
||||||
|
struct trx_header hdr = {};
|
||||||
|
ssize_t sbytes;
|
||||||
|
size_t curr_idx = 0;
|
||||||
|
size_t curr_offset = sizeof(hdr);
|
||||||
|
int c;
|
||||||
|
int err = 0;
|
||||||
|
|
||||||
|
if (argc < 3) {
|
||||||
|
fprintf(stderr, "No TRX file passed\n");
|
||||||
|
err = -EINVAL;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
trx_path = argv[2];
|
||||||
|
|
||||||
|
optind = 3;
|
||||||
|
otrx_create_parse_options(argc, argv);
|
||||||
|
|
||||||
|
trx = fopen(trx_path, "w+");
|
||||||
|
if (!trx) {
|
||||||
|
fprintf(stderr, "Couldn't open %s\n", trx_path);
|
||||||
|
err = -EACCES;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
fseek(trx, curr_offset, SEEK_SET);
|
||||||
|
|
||||||
|
optind = 3;
|
||||||
|
while ((c = getopt(argc, argv, "f:b:")) != -1) {
|
||||||
|
switch (c) {
|
||||||
|
case 'f':
|
||||||
|
if (curr_idx >= TRX_MAX_PARTS) {
|
||||||
|
err = -ENOSPC;
|
||||||
|
fprintf(stderr, "Reached TRX partitions limit, no place for %s\n", optarg);
|
||||||
|
goto err_close;
|
||||||
|
}
|
||||||
|
|
||||||
|
sbytes = otrx_create_append_file(trx, optarg);
|
||||||
|
if (sbytes < 0) {
|
||||||
|
fprintf(stderr, "Failed to append file %s\n", optarg);
|
||||||
|
} else {
|
||||||
|
hdr.offset[curr_idx++] = curr_offset;
|
||||||
|
curr_offset += sbytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
sbytes = otrx_create_align(trx, curr_offset, 4);
|
||||||
|
if (sbytes < 0)
|
||||||
|
fprintf(stderr, "Failed to append zeros\n");
|
||||||
|
else
|
||||||
|
curr_offset += sbytes;
|
||||||
|
|
||||||
|
break;
|
||||||
|
case 'b':
|
||||||
|
sbytes = strtol(optarg, NULL, 0) - curr_offset;
|
||||||
|
if (sbytes < 0) {
|
||||||
|
fprintf(stderr, "Current TRX length is 0x%zx, can't pad it with zeros to 0x%lx\n", curr_offset, strtol(optarg, NULL, 0));
|
||||||
|
} else {
|
||||||
|
sbytes = otrx_create_append_zeros(trx, sbytes);
|
||||||
|
if (sbytes < 0)
|
||||||
|
fprintf(stderr, "Failed to append zeros\n");
|
||||||
|
else
|
||||||
|
curr_offset += sbytes;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (err)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
hdr.length = curr_offset;
|
||||||
|
otrx_create_write_hdr(trx, &hdr);
|
||||||
|
err_close:
|
||||||
|
fclose(trx);
|
||||||
|
out:
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
/**************************************************
|
/**************************************************
|
||||||
* Extract
|
* Extract
|
||||||
**************************************************/
|
**************************************************/
|
||||||
@ -363,6 +541,11 @@ static void usage() {
|
|||||||
printf("\totrx check <file> [options]\tcheck if file is a valid TRX\n");
|
printf("\totrx check <file> [options]\tcheck if file is a valid TRX\n");
|
||||||
printf("\t-o offset\t\t\toffset of TRX data in file (default: 0)\n");
|
printf("\t-o offset\t\t\toffset of TRX data in file (default: 0)\n");
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
printf("Creating new TRX file:\n");
|
||||||
|
printf("\totrx create <file> [options] [partitions]\n");
|
||||||
|
printf("\t-f file\t\t\t\t[partition] start new partition with content copied from file\n");
|
||||||
|
printf("\t-b offset\t\t\t[partition] append zeros to partition till reaching absolute offset\n");
|
||||||
|
printf("\n");
|
||||||
printf("Extracting from TRX file:\n");
|
printf("Extracting from TRX file:\n");
|
||||||
printf("\totrx extract <file> [options]\textract partitions from TRX file\n");
|
printf("\totrx extract <file> [options]\textract partitions from TRX file\n");
|
||||||
printf("\t-o offset\t\t\toffset of TRX data in file (default: 0)\n");
|
printf("\t-o offset\t\t\toffset of TRX data in file (default: 0)\n");
|
||||||
@ -375,6 +558,8 @@ int main(int argc, char **argv) {
|
|||||||
if (argc > 1) {
|
if (argc > 1) {
|
||||||
if (!strcmp(argv[1], "check"))
|
if (!strcmp(argv[1], "check"))
|
||||||
return otrx_check(argc, argv);
|
return otrx_check(argc, argv);
|
||||||
|
else if (!strcmp(argv[1], "create"))
|
||||||
|
return otrx_create(argc, argv);
|
||||||
else if (!strcmp(argv[1], "extract"))
|
else if (!strcmp(argv[1], "extract"))
|
||||||
return otrx_extract(argc, argv);
|
return otrx_extract(argc, argv);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user