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

217 lines
3.7 KiB

#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <image.h>
size_t read_u8(FILE *fp, uint8_t *val)
{
int byte;
size_t shift = 8, nbytes;
*val = 0;
for (nbytes = 0; nbytes < sizeof *val; ++nbytes) {
if ((byte = fgetc(fp)) == EOF)
return nbytes;
shift -= 8;
*val |= (byte & 0xff) << shift;
}
return nbytes;
}
size_t read_u32(FILE *fp, uint32_t *val)
{
int byte;
size_t shift = 32, nbytes;
*val = 0;
for (nbytes = 0; nbytes < sizeof *val; ++nbytes) {
if ((byte = fgetc(fp)) == EOF)
return nbytes;
shift -= 8;
*val |= (byte & 0xff) << shift;
}
return nbytes;
}
size_t read_u64(FILE *fp, uint64_t *val)
{
int byte;
size_t shift = 64, nbytes;
*val = 0;
for (nbytes = 0; nbytes < sizeof *val; ++nbytes) {
if ((byte = fgetc(fp)) == EOF)
return nbytes;
shift -= 8;
*val |= (byte & 0xff) << shift;
}
return nbytes;
}
size_t write_u8(FILE *fp, uint8_t val)
{
size_t shift = 8, nbytes;
for (nbytes = 0; nbytes < sizeof val; ++nbytes) {
shift -= 8;
if (fputc((val >> shift) & 0xff, fp) == EOF)
return nbytes;
}
return nbytes;
}
size_t write_u32(FILE *fp, uint32_t val)
{
size_t shift = 32, nbytes;
for (nbytes = 0; nbytes < sizeof val; ++nbytes) {
shift -= 8;
if (fputc((val >> shift) & 0xff, fp) == EOF)
return nbytes;
}
return nbytes;
}
size_t write_u64(FILE *fp, uint64_t val)
{
size_t shift = 64, nbytes;
for (nbytes = 0; nbytes < sizeof val; ++nbytes) {
shift -= 8;
if (fputc((val >> shift) & 0xff, fp) == EOF)
return nbytes;
}
return nbytes;
}
int rots_read_hdr(FILE *fp, struct rots_hdr *hdr)
{
char magic[8];
if (fread(magic, sizeof *magic, sizeof magic, fp) < sizeof magic)
return -1;
if (memcmp(magic, ROTS_MAGIC, 8) != 0)
return -1;
if (read_u64(fp, &hdr->timestamp) < sizeof hdr->timestamp)
return -1;
if (read_u64(fp, &hdr->size) < sizeof hdr->size)
return -1;
return 0;
}
int rots_write_hdr(FILE *fp, struct rots_hdr *hdr)
{
if (fwrite(ROTS_MAGIC, sizeof(char), 8, fp) < 8)
return -1;
if (write_u64(fp, hdr->timestamp) < sizeof hdr->timestamp)
return -1;
if (write_u64(fp, hdr->size) < sizeof hdr->size)
return -1;
return 0;
}
int rots_read_sig_hdr(FILE *fp, struct rots_sig_hdr *sig_hdr)
{
uint8_t len;
if (read_u8(fp, &len) < 1)
return -1;
if (!(sig_hdr->name = calloc(len + 1, sizeof *sig_hdr->name)))
return -1;
if (fread(sig_hdr->name, sizeof *sig_hdr->name, len, fp) < len)
goto err_free_name;
if (read_u8(fp, &len) < 1)
goto err_free_name;
if (!(sig_hdr->digest = calloc(len + 1, sizeof *sig_hdr->digest)))
goto err_free_name;
if (fread(sig_hdr->digest, sizeof *sig_hdr->digest, len, fp) < len)
goto err_free_digest;
if (read_u64(fp, &sig_hdr->timestamp) < sizeof sig_hdr->timestamp)
goto err_free_digest;
if (read_u32(fp, &sig_hdr->size) < sizeof sig_hdr->size)
goto err_free_digest;
return 0;
err_free_digest:
free(sig_hdr->digest);
err_free_name:
free(sig_hdr->name);
return -1;
}
int rots_write_sig_hdr(FILE *fp, struct rots_sig_hdr *sig_hdr)
{
size_t len;
len = strlen(sig_hdr->name);
if (write_u8(fp, len) < 1)
return -1;
if (fwrite(sig_hdr->name, sizeof *sig_hdr->name, len, fp) < len)
return -1;
len = strlen(sig_hdr->digest);
if (write_u8(fp, len) < 1)
return -1;
if (fwrite(sig_hdr->digest, sizeof *sig_hdr->digest, len, fp) < len)
return -1;
if (write_u64(fp, sig_hdr->timestamp) < sizeof sig_hdr->timestamp)
return -1;
if (write_u32(fp, sig_hdr->size) < sizeof sig_hdr->size)
return -1;
return 0;
}
void rots_cleanup_sig_hdr(struct rots_sig_hdr *sig_hdr)
{
if (!sig_hdr)
return;
if (sig_hdr->name) {
free(sig_hdr->name);
sig_hdr->name = NULL;
}
if (sig_hdr->digest) {
free(sig_hdr->digest);
sig_hdr->digest = NULL;
}
}