+static int pkg_init_exports(struct upkg *pkg)
+{
+ size_t rc, len, nbuf = 0;
+ unsigned long index = 0;
+ char buf[512];
+
+ if (fseek(pkg->priv->f, pkg->priv->export_offset, SEEK_SET) != 0)
+ return -1;
+
+ pkg->priv->exports = malloc(pkg->export_count * sizeof *pkg->priv->exports);
+ if (!pkg->priv->exports)
+ return -1;
+
+ while (index < pkg->export_count) {
+ struct upkg_export *export = &pkg->priv->exports[index];
+
+ /* Read some data into buffer. */
+ if (!feof(pkg->priv->f)) {
+ rc = fread(buf+nbuf, 1, sizeof buf-nbuf, pkg->priv->f);
+ if (rc == 0)
+ goto err;
+ nbuf += rc;
+ }
+
+ len = 0;
+ rc = decode_index(&export->class, buf+len, nbuf-len);
+ if (rc == 0) goto err;
+ len += rc;
+
+ rc = decode_index(&export->super, buf+len, nbuf-len);
+ if (rc == 0) goto err;
+ len += rc;
+
+ if (nbuf-len < 4) goto err;
+ export->package = unpack_32_le(buf+len);
+ len += 4;
+
+ rc = decode_index(&export->name, buf+len, nbuf-len);
+ if (rc == 0) goto err;
+ len += rc;
+
+ if (nbuf-len < 4) goto err;
+ export->flags = unpack_32_le(buf+len);
+ len += 4;
+
+ rc = decode_index(&export->size, buf+len, nbuf-len);
+ if (rc == 0) goto err;
+ len += rc;
+
+ if (export->size) {
+ rc = decode_index(&export->offset, buf+len, nbuf-len);
+ if (rc == 0) goto err;
+ len += rc;
+ }
+
+ nbuf -= len;
+ memmove(buf, buf+len, nbuf);
+ index++;
+ }
+
+ return 0;
+err:
+ free(pkg->priv->exports);
+ return -1;
+}
+