]> git.draconx.ca Git - upkg.git/commitdiff
Implement import table parsing.
authorNick Bowler <nbowler@draconx.ca>
Sat, 6 Jun 2009 01:20:50 +0000 (21:20 -0400)
committerNick Bowler <nbowler@draconx.ca>
Sat, 6 Jun 2009 01:20:50 +0000 (21:20 -0400)
libupkg.c
upkg.c

index a269698247fbd9e721f7e39aa6549b0c33fabfe3..85767a2e4262e96be5984655c99f8d1a338dfbb4 100644 (file)
--- a/libupkg.c
+++ b/libupkg.c
@@ -13,16 +13,24 @@ struct upkg_name {
 };
 
 struct upkg_export {
-       long class, super, name;
-       unsigned long package, flags;
+       const char *name;
+
+       long package, class, super;
+       unsigned long flags;
        unsigned long size, offset;
 };
 
+struct upkg_import {
+       const char *class_package, *class_name, *object_name;
+       long package;
+};
+
 struct upkg_private {
        FILE *f;
 
        struct upkg_name   *names;
        struct upkg_export *exports;
+       struct upkg_import *imports;
 
        unsigned long name_offset, export_offset, import_offset;
        unsigned char guid[16];
@@ -159,6 +167,7 @@ static int pkg_init_exports(struct upkg *pkg)
 
        while (index < pkg->export_count) {
                struct upkg_export *export = &pkg->priv->exports[index];
+               long tmp;
 
                /* Read some data into buffer. */
                if (!feof(pkg->priv->f)) {
@@ -181,8 +190,9 @@ static int pkg_init_exports(struct upkg *pkg)
                export->package = unpack_32_le(buf+len);
                len += 4;
 
-               rc = decode_index(&export->name, buf+len, nbuf-len);
-               if (rc == 0) goto err;
+               rc = decode_index(&tmp, buf+len, nbuf-len);
+               if (rc == 0 || tmp < 0 || tmp >= pkg->name_count) goto err;
+               export->name = pkg->priv->names[tmp].name;
                len += rc;
 
                if (nbuf-len < 4) goto err;
@@ -210,6 +220,62 @@ err:
        return -1;
 }
 
+static int pkg_init_imports(struct upkg *pkg)
+{
+       size_t rc, len, nbuf = 0;
+       unsigned long index = 0;
+       char buf[512];
+
+       if (fseek(pkg->priv->f, pkg->priv->import_offset, SEEK_SET) != 0)
+               return -1;
+
+       pkg->priv->imports = malloc(pkg->import_count * sizeof *pkg->priv->imports);
+       if (!pkg->priv->imports)
+               return -1;
+
+       while (index < pkg->import_count) {
+               struct upkg_import *import = &pkg->priv->imports[index];
+               long tmp;
+
+               /* 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(&tmp, buf+len, nbuf-len);
+               if (rc == 0 || len < 0 || len >= pkg->name_count) goto err;
+               import->class_package = pkg->priv->names[tmp].name;
+               len += rc;
+
+               rc = decode_index(&tmp, buf+len, nbuf-len);
+               if (rc == 0 || len < 0 || len >= pkg->name_count) goto err;
+               import->class_name = pkg->priv->names[tmp].name;
+               len += rc;
+
+               if (nbuf-len < 4) goto err;
+               import->package = unpack_32_le(buf+len);
+               len += 4;
+
+               rc = decode_index(&tmp, buf+len, nbuf-len);
+               if (rc == 0 || len < 0 || len >= pkg->name_count) goto err;
+               import->object_name = pkg->priv->names[tmp].name;
+               len += rc;
+
+               nbuf -= len;
+               memmove(buf, buf+len, nbuf);
+               index++;
+       }
+
+       return 0;
+err:
+       free(pkg->priv->imports);
+       return -1;
+}
+
 struct upkg *upkg_fopen(const char *path)
 {
        unsigned char hdr_buf[UPKG_HDR_SIZE];
@@ -233,17 +299,25 @@ struct upkg *upkg_fopen(const char *path)
        }
        pkg->priv->f = f;
 
-       if (pkg_init_exports(pkg) != 0) {
+       if (pkg_init_names(pkg) != 0) {
                goto err2;
        }
 
-       if (pkg_init_names(pkg) != 0) {
+       if (pkg_init_exports(pkg) != 0) {
                goto err3;
        }
 
+       if (pkg_init_imports(pkg) != 0) {
+               goto err4;
+       }
+
        return pkg;
-err3:
+err4:
        free(pkg->priv->exports);
+err3:
+       for (unsigned i = 0; i < pkg->name_count; i++)
+               free(pkg->priv->names[i].name);
+       free(pkg->priv->names);
 err2:
        free(pkg->priv);
        free(pkg);
@@ -264,6 +338,7 @@ int upkg_close(struct upkg *pkg)
                }
        }
 
+       free(pkg->priv->imports);
        free(pkg->priv->exports);
        free(pkg->priv->names);
        free(pkg->priv);
diff --git a/upkg.c b/upkg.c
index 2694f5b20a2bb1ed33c61ea989013b7f404703bd..660819c53b6f54355c91ed30e0b667501afbe246 100644 (file)
--- a/upkg.c
+++ b/upkg.c
@@ -46,6 +46,7 @@ int main(int argc, char **argv)
        }
 
        printf("Exports: %lu\n", pkg->export_count);
+       printf("Imports: %lu\n", pkg->import_count);
 
        upkg_close(pkg);
        return 0;