16 struct upkg_name *names;
18 unsigned long name_offset, export_offset, import_offset;
19 unsigned char guid[16];
22 static long decode_index(unsigned char *bytes)
27 val += bytes[0] & 0x3f;
28 if (bytes[0] & 0x40) do {
29 val += bytes[i] & 0x7f;
30 } while (bytes[i] & 0x80 && i < 5);
32 return bytes[0] & 0x80 ? -val : val;
35 static struct upkg *init_upkg(unsigned char hdr[static UPKG_HDR_SIZE])
39 pkg = malloc(sizeof *pkg);
44 pkg->priv = malloc(sizeof *pkg->priv);
50 pkg->version = unpack_16_le(hdr+4);
51 pkg->license = unpack_16_le(hdr+6);
52 pkg->flags = unpack_32_le(hdr+8);
53 pkg->name_count = unpack_32_le(hdr+12);
54 pkg->export_count = unpack_32_le(hdr+20);
55 pkg->import_count = unpack_32_le(hdr+28);
57 pkg->priv->name_offset = unpack_32_le(hdr+16);
58 pkg->priv->export_offset = unpack_32_le(hdr+24);
59 pkg->priv->import_offset = unpack_32_le(hdr+32);
64 static int pkg_init_names(struct upkg *pkg)
66 size_t rc, len, nbuf = 0;
67 unsigned long index = 0;
70 if (fseek(pkg->priv->f, pkg->priv->name_offset, SEEK_SET) != 0)
73 pkg->priv->names = malloc(pkg->name_count * sizeof *pkg->priv->names);
74 if (!pkg->priv->names)
77 while (index < pkg->name_count) {
78 struct upkg_name *name = &pkg->priv->names[index];
80 /* Read some data into buffer. */
81 if (!feof(pkg->priv->f)) {
82 rc = fread(buf+nbuf, 1, sizeof buf-nbuf, pkg->priv->f);
88 if (pkg->version >= 64) {
90 if (nbuf <= len + 4 || buf[len])
92 name->name = malloc(len);
95 memcpy(name->name, buf+1, len);
96 name->flags = unpack_32_le(buf+len+1);
99 memmove(buf, buf+len+5, nbuf);
108 free(pkg->priv->names);
112 struct upkg *upkg_fopen(const char *path)
114 unsigned char hdr_buf[UPKG_HDR_SIZE];
118 if (!(f = fopen(path, "rb"))) {
121 if (fread(hdr_buf, sizeof hdr_buf, 1, f) != 1) {
124 if (unpack_32_le(hdr_buf) != UPKG_HDR_MAGIC) {
128 /* Initialize package structure. */
129 pkg = init_upkg(hdr_buf);
135 if (pkg_init_names(pkg) != 0) {
148 int upkg_close(struct upkg *pkg)
153 rc = fclose(pkg->priv->f);
155 for (unsigned i = 0; i < pkg->name_count; i++) {
156 free(pkg->priv->names[i].name);
158 free(pkg->priv->names);
169 const char *upkg_get_name(struct upkg *pkg, unsigned long idx)
171 if (idx >= pkg->name_count)
173 return pkg->priv->names[idx].name;