*/
#include <byteswap.h>
+#include <endian.h>
#include <errno.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
+#if !defined(__BYTE_ORDER)
+#error "Unknown byte order"
+#endif
+
#if __BYTE_ORDER == __BIG_ENDIAN
#define cpu_to_le32(x) bswap_32(x)
#define le32_to_cpu(x) bswap_32(x)
size_t trx_offset = 0;
char *partition[TRX_MAX_PARTS] = {};
+static inline size_t otrx_min(size_t x, size_t y) {
+ return x < y ? x : y;
+}
+
/**************************************************
* CRC32
**************************************************/
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d,
};
-uint32_t otrx_crc32(uint8_t *buf, size_t len) {
- uint32_t crc = 0xffffffff;
-
+uint32_t otrx_crc32(uint32_t crc, uint8_t *buf, size_t len) {
while (len) {
crc = crc32_tbl[(crc ^ *buf) & 0xff] ^ (crc >> 8);
buf++;
FILE *trx;
struct trx_header hdr;
size_t bytes, length;
- uint8_t *buf;
+ uint8_t buf[1024];
uint32_t crc32;
int err = 0;
goto err_close;
}
- buf = malloc(length);
- if (!buf) {
- fprintf(stderr, "Couldn't alloc %zd B buffer\n", length);
- err = -ENOMEM;
- goto err_close;
+ crc32 = 0xffffffff;
+ fseek(trx, trx_offset + TRX_FLAGS_OFFSET, SEEK_SET);
+ length -= TRX_FLAGS_OFFSET;
+ while ((bytes = fread(buf, 1, otrx_min(sizeof(buf), length), trx)) > 0) {
+ crc32 = otrx_crc32(crc32, buf, bytes);
+ length -= bytes;
}
- fseek(trx, trx_offset, SEEK_SET);
- bytes = fread(buf, 1, length, trx);
- if (bytes != length) {
- fprintf(stderr, "Couldn't read %zd B of data from %s\n", length, trx_path);
- err = -ENOMEM;
- goto err_free_buf;
+ if (length) {
+ fprintf(stderr, "Couldn't read last %zd B of data from %s\n", length, trx_path);
+ err = -EIO;
+ goto err_close;
}
- crc32 = otrx_crc32(buf + TRX_FLAGS_OFFSET, length - TRX_FLAGS_OFFSET);
if (crc32 != le32_to_cpu(hdr.crc32)) {
fprintf(stderr, "Invalid data crc32: 0x%08x instead of 0x%08x\n", crc32, le32_to_cpu(hdr.crc32));
err = -EINVAL;
- goto err_free_buf;
+ goto err_close;
}
printf("Found a valid TRX version %d\n", le32_to_cpu(hdr.version));
-err_free_buf:
- free(buf);
err_close:
fclose(trx);
out:
static int otrx_create_write_hdr(FILE *trx, struct trx_header *hdr) {
size_t bytes, length;
- uint8_t *buf;
+ uint8_t buf[1024];
uint32_t crc32;
hdr->magic = cpu_to_le32(TRX_MAGIC);
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 = 0xffffffff;
+ fseek(trx, TRX_FLAGS_OFFSET, SEEK_SET);
+ length -= TRX_FLAGS_OFFSET;
+ while ((bytes = fread(buf, 1, otrx_min(sizeof(buf), length), trx)) > 0) {
+ crc32 = otrx_crc32(crc32, buf, bytes);
+ length -= bytes;
}
-
- crc32 = otrx_crc32(buf + TRX_FLAGS_OFFSET, length - TRX_FLAGS_OFFSET);
hdr->crc32 = cpu_to_le32(crc32);
fseek(trx, 0, SEEK_SET);