]> git.draconx.ca Git - upkg.git/blob - libupkg.c
Initial commit
[upkg.git] / libupkg.c
1 #include <stdio.h>
2 #include <stdlib.h>
3
4 #include "upkg.h"
5 #include "pack.h"
6
7 struct upkg_table {
8         size_t offset;
9         size_t count;
10 };
11
12 struct upkg_private {
13         FILE *f;
14
15         struct upkg_table names, exports, imports;
16         unsigned char guid[16];
17 };
18
19 static struct upkg *init_upkg(unsigned char hdr[static UPKG_HDR_SIZE])
20 {
21         struct upkg *pkg;
22
23         pkg = malloc(sizeof *pkg);
24         if (!pkg) {
25                 return NULL;
26         }
27
28         pkg->priv = malloc(sizeof *pkg->priv);
29         if (!pkg->priv) {
30                 free(pkg);
31                 return NULL;
32         }
33
34         pkg->version = unpack_16_le(hdr+4);
35         pkg->license = unpack_16_le(hdr+6);
36         pkg->flags   = unpack_32_le(hdr+8);
37
38         pkg->priv->names = (struct upkg_table) {
39                 .count  = unpack_32_le(hdr+12),
40                 .offset = unpack_32_le(hdr+16),
41         };
42         pkg->priv->exports = (struct upkg_table) {
43                 .count  = unpack_32_le(hdr+20),
44                 .offset = unpack_32_le(hdr+24),
45         };
46         pkg->priv->imports = (struct upkg_table) {
47                 .count  = unpack_32_le(hdr+28),
48                 .offset = unpack_32_le(hdr+32),
49         };
50
51         return pkg;
52 }
53
54 struct upkg *upkg_fopen(const char *path)
55 {
56         unsigned char hdr_buf[UPKG_HDR_SIZE];
57         struct upkg *pkg;
58         FILE *f;
59         
60         f = fopen(path, "rb");
61         if (!f) {
62                 return NULL;
63         }
64
65         if (fread(hdr_buf, sizeof hdr_buf, 1, f) != 1) {
66                 goto err;
67         }
68
69         if (unpack_32_le(hdr_buf) != UPKG_HDR_MAGIC) {
70                 goto err;
71         }
72
73         pkg = init_upkg(hdr_buf);
74         if (!pkg) {
75                 goto err;
76         }
77
78         pkg->priv->f = f;
79         return pkg;
80 err:
81         fclose(f);
82         return NULL;
83 }