#include #include #include "upkg.h" #include "pack.h" struct upkg_table { size_t offset; size_t count; }; struct upkg_private { FILE *f; struct upkg_table names, exports, imports; unsigned char guid[16]; }; static struct upkg *init_upkg(unsigned char hdr[static UPKG_HDR_SIZE]) { struct upkg *pkg; pkg = malloc(sizeof *pkg); if (!pkg) { return NULL; } pkg->priv = malloc(sizeof *pkg->priv); if (!pkg->priv) { free(pkg); return NULL; } pkg->version = unpack_16_le(hdr+4); pkg->license = unpack_16_le(hdr+6); pkg->flags = unpack_32_le(hdr+8); pkg->priv->names = (struct upkg_table) { .count = unpack_32_le(hdr+12), .offset = unpack_32_le(hdr+16), }; pkg->priv->exports = (struct upkg_table) { .count = unpack_32_le(hdr+20), .offset = unpack_32_le(hdr+24), }; pkg->priv->imports = (struct upkg_table) { .count = unpack_32_le(hdr+28), .offset = unpack_32_le(hdr+32), }; return pkg; } struct upkg *upkg_fopen(const char *path) { unsigned char hdr_buf[UPKG_HDR_SIZE]; struct upkg *pkg; FILE *f; f = fopen(path, "rb"); if (!f) { return NULL; } if (fread(hdr_buf, sizeof hdr_buf, 1, f) != 1) { goto err; } if (unpack_32_le(hdr_buf) != UPKG_HDR_MAGIC) { goto err; } pkg = init_upkg(hdr_buf); if (!pkg) { goto err; } pkg->priv->f = f; return pkg; err: fclose(f); return NULL; }