9 unsigned long index, flags;
16 struct upkg_name *names;
18 unsigned long name_offset, export_offset, import_offset;
19 unsigned char guid[16];
22 static int namecmp(const void *_a, const void *_b, void *_pkg)
24 const struct upkg_name *a = _a, *b = _b;
25 if (a->index < b->index)
27 if (a->index > b->index)
32 static long decode_index(unsigned char *bytes)
37 val += bytes[0] & 0x3f;
38 if (bytes[0] & 0x40) do {
39 val += bytes[i] & 0x7f;
40 } while (bytes[i] & 0x80 && i < 5);
42 return bytes[0] & 0x80 ? -val : val;
45 static struct upkg *init_upkg(unsigned char hdr[static UPKG_HDR_SIZE])
49 pkg = malloc(sizeof *pkg);
54 pkg->priv = malloc(sizeof *pkg->priv);
60 pkg->version = unpack_16_le(hdr+4);
61 pkg->license = unpack_16_le(hdr+6);
62 pkg->flags = unpack_32_le(hdr+8);
63 pkg->name_count = unpack_32_le(hdr+12);
64 pkg->export_count = unpack_32_le(hdr+20);
65 pkg->import_count = unpack_32_le(hdr+28);
67 pkg->priv->name_offset = unpack_32_le(hdr+16);
68 pkg->priv->export_offset = unpack_32_le(hdr+24);
69 pkg->priv->import_offset = unpack_32_le(hdr+32);
74 static int pkg_init_names(struct upkg *pkg)
76 size_t rc, nbuf = 0, len;
77 unsigned long index = 0;
80 if (fseek(pkg->priv->f, pkg->priv->name_offset, SEEK_SET) != 0)
83 pkg->priv->names = malloc(pkg->name_count * sizeof *pkg->priv->names);
84 if (!pkg->priv->names)
87 while (index < pkg->name_count) {
88 struct upkg_name *name = &pkg->priv->names[index];
91 /* Read some data into buffer. */
92 if (!feof(pkg->priv->f)) {
93 rc = fread(buf+nbuf, 1, sizeof buf-nbuf, pkg->priv->f);
99 if (pkg->version >= 64) {
101 if (nbuf <= len + 4 || buf[len])
103 name->name = malloc(len);
106 memcpy(name->name, buf+1, len);
107 name->flags = unpack_32_le(buf+len+1);
110 memmove(buf, buf+len+5, nbuf);
119 free(pkg->priv->names);
123 struct upkg *upkg_fopen(const char *path)
125 unsigned char hdr_buf[UPKG_HDR_SIZE];
129 if (!(f = fopen(path, "rb"))) {
132 if (fread(hdr_buf, sizeof hdr_buf, 1, f) != 1) {
135 if (unpack_32_le(hdr_buf) != UPKG_HDR_MAGIC) {
139 /* Initialize package structure. */
140 pkg = init_upkg(hdr_buf);
146 if (pkg_init_names(pkg) != 0) {
159 int upkg_close(struct upkg *pkg)
164 rc = fclose(pkg->priv->f);
166 for (unsigned i = 0; i < pkg->name_count; i++) {
167 free(pkg->priv->names[i].name);
169 free(pkg->priv->names);
180 const char *upkg_get_name(struct upkg *pkg, unsigned long idx)
182 if (idx >= pkg->name_count)
184 return pkg->priv->names[idx].name;