blob: d613e5416fd6fc05a2ef590b54f2c9b7d8190ab6 [file] [log] [blame]
#include "hf/cpio.h"
#include <stdint.h>
#include "hf/std.h"
#pragma pack(push, 1)
struct cpio_header {
uint16_t magic;
uint16_t dev;
uint16_t ino;
uint16_t mode;
uint16_t uid;
uint16_t gid;
uint16_t nlink;
uint16_t rdev;
uint16_t mtime[2];
uint16_t namesize;
uint16_t filesize[2];
};
#pragma pack(pop)
/**
* Retrieves the next file stored in the cpio archive stored in the cpio, and
* advances the iterator such that another call to this function would return
* the following file.
*/
bool cpio_next(struct memiter *iter, const char **name, const void **contents,
size_t *size)
{
size_t len;
struct memiter lit = *iter;
const struct cpio_header *h = (const struct cpio_header *)lit.next;
if (!memiter_advance(&lit, sizeof(struct cpio_header))) {
return false;
}
*name = lit.next;
/* TODO: Check magic. */
len = (h->namesize + 1) & ~1;
if (!memiter_advance(&lit, len)) {
return false;
}
*contents = lit.next;
len = (size_t)h->filesize[0] << 16 | h->filesize[1];
if (!memiter_advance(&lit, (len + 1) & ~1)) {
return false;
}
/* TODO: Check that string is null-terminated. */
/* Stop enumerating files when we hit the end marker. */
if (!strcmp(*name, "TRAILER!!!")) {
return false;
}
*size = len;
*iter = lit;
return true;
}