--- /dev/null
+*.o
+*.lo
+*.la
+Makefile
+Makefile.in
+.libs
+.deps
+config.*
+aclocal.m4
+autom4te.cache
+configure
+libtool
+ltmain.sh
+install-sh
+depcomp
+missing
+stamp-h1
+compile
+upkg
+m4
--- /dev/null
+ACLOCAL_AMFLAGS = -I m4
+
+lib_LTLIBRARIES = libupkg.la
+bin_PROGRAMS = upkg
+
+libupkg_la_SOURCES = libupkg.c pack.c
+include_HEADERS = upkg.h
+noinst_HEADERS = pack.h
+
+upkg_SOURCES = upkg.c
+upkg_LDADD = libupkg.la
--- /dev/null
+#!/bin/sh
+
+die()
+{
+ echo $@ 1>&2
+ exit 1
+}
+
+test -d m4 || mkdir m4
+
+aclocal -I m4 || die "Failed to run aclocal."
+autoheader || die "Failed to run autoheader."
+libtoolize --copy || die "Failed to run libtoolize."
+automake --add-missing || die "Failed to run automake."
+autoconf || die "Failed to run autoconf."
--- /dev/null
+AC_PREREQ(2.62)
+AC_INIT([upkg],[0.1],[nbowler@draconx.ca])
+AC_CONFIG_SRCDIR([pack.c])
+AC_CONFIG_HEADER([config.h])
+AC_CONFIG_MACRO_DIR([m4])
+
+AM_INIT_AUTOMAKE([-Wall -Werror foreign])
+
+AC_PROG_CC_C99
+
+LT_INIT
+
+AC_CONFIG_FILES([
+ Makefile
+])
+AC_OUTPUT
--- /dev/null
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "upkg.h"
+#include "pack.h"
+
+struct upkg_table {
+ size_t offset;
+ size_t count;
+};
+
+struct upkg_private {
+ FILE *f;
+
+ struct upkg_table names, exports, imports;
+ unsigned char guid[16];
+};
+
+static struct upkg *init_upkg(unsigned char hdr[static UPKG_HDR_SIZE])
+{
+ struct upkg *pkg;
+
+ pkg = malloc(sizeof *pkg);
+ if (!pkg) {
+ return NULL;
+ }
+
+ pkg->priv = malloc(sizeof *pkg->priv);
+ if (!pkg->priv) {
+ free(pkg);
+ return NULL;
+ }
+
+ pkg->version = unpack_16_le(hdr+4);
+ pkg->license = unpack_16_le(hdr+6);
+ pkg->flags = unpack_32_le(hdr+8);
+
+ pkg->priv->names = (struct upkg_table) {
+ .count = unpack_32_le(hdr+12),
+ .offset = unpack_32_le(hdr+16),
+ };
+ pkg->priv->exports = (struct upkg_table) {
+ .count = unpack_32_le(hdr+20),
+ .offset = unpack_32_le(hdr+24),
+ };
+ pkg->priv->imports = (struct upkg_table) {
+ .count = unpack_32_le(hdr+28),
+ .offset = unpack_32_le(hdr+32),
+ };
+
+ return pkg;
+}
+
+struct upkg *upkg_fopen(const char *path)
+{
+ unsigned char hdr_buf[UPKG_HDR_SIZE];
+ struct upkg *pkg;
+ FILE *f;
+
+ f = fopen(path, "rb");
+ if (!f) {
+ return NULL;
+ }
+
+ if (fread(hdr_buf, sizeof hdr_buf, 1, f) != 1) {
+ goto err;
+ }
+
+ if (unpack_32_le(hdr_buf) != UPKG_HDR_MAGIC) {
+ goto err;
+ }
+
+ pkg = init_upkg(hdr_buf);
+ if (!pkg) {
+ goto err;
+ }
+
+ pkg->priv->f = f;
+ return pkg;
+err:
+ fclose(f);
+ return NULL;
+}
--- /dev/null
+#include <stdio.h>
+#include <limits.h>
+
+#include "pack.h"
+
+/* Integer packing. */
+#define DEFPACK_BE(bits, type) void pack_ ## bits ## _be ( \
+ unsigned char *out, type v \
+) { \
+ unsigned i; \
+ for (i = 1; i <= bits/8; i++) { \
+ out[bits/8 - i] = v % 256; \
+ v /= 256; \
+ } \
+}
+
+#define DEFPACK_LE(bits, type) void pack_ ## bits ## _le ( \
+ unsigned char *out, type v \
+) { \
+ unsigned i; \
+ for (i = 0; i < bits/8; i++) { \
+ out[i] = v % 256; \
+ v /= 256; \
+ } \
+}
+
+DEFPACK_BE(16, unsigned short)
+DEFPACK_BE(32, unsigned long)
+#ifdef ULLONG_MAX
+DEFPACK_BE(64, unsigned long long)
+#endif
+
+DEFPACK_LE(16, unsigned short)
+DEFPACK_LE(32, unsigned long)
+#ifdef ULLONG_MAX
+DEFPACK_LE(64, unsigned long long)
+#endif
+
+#define DEFUNPACK_BE(bits, type) type unpack_ ## bits ## _be ( \
+ unsigned char *in \
+) { \
+ type v = 0; \
+ unsigned i; \
+ for (i = 0; i < bits/8; i++) { \
+ v *= 256; \
+ v += in[i]; \
+ } \
+ return v; \
+}
+
+#define DEFUNPACK_LE(bits, type) type unpack_ ## bits ## _le ( \
+ unsigned char *in \
+) { \
+ type v = 0; \
+ unsigned i; \
+ for (i = 1; i <= bits/8; i++) { \
+ v *= 256; \
+ v += in[bits/8 - i]; \
+ } \
+ return v; \
+}
+
+DEFUNPACK_BE(16, unsigned short)
+DEFUNPACK_BE(32, unsigned long)
+#ifdef ULLONG_MAX
+DEFUNPACK_BE(64, unsigned long long)
+#endif
+
+DEFUNPACK_LE(16, unsigned short)
+DEFUNPACK_LE(32, unsigned long)
+#ifdef ULLONG_MAX
+DEFUNPACK_LE(64, unsigned long long)
+#endif
--- /dev/null
+#ifndef PACK_H_
+#define PACK_H_
+
+#include <limits.h>
+
+void pack_16_be(unsigned char *, unsigned short);
+void pack_32_be(unsigned char *, unsigned long);
+#ifdef ULLONG_MAX
+void pack_64_be(unsigned char *, unsigned long long);
+#endif
+
+void pack_16_le(unsigned char *, unsigned short);
+void pack_32_le(unsigned char *, unsigned long);
+#ifdef ULLONG_MAX
+void pack_64_le(unsigned char *, unsigned long long);
+#endif
+
+unsigned short unpack_16_be(unsigned char *);
+unsigned long unpack_32_be(unsigned char *);
+#ifdef ULLONG_MAX
+unsigned long long unpack_64_be(unsigned char *);
+#endif
+
+unsigned short unpack_16_le(unsigned char *);
+unsigned long unpack_32_le(unsigned char *);
+#ifdef ULLONG_MAX
+unsigned long long unpack_64_le(unsigned char *);
+#endif
+
+#endif
--- /dev/null
+#include <stdio.h>
+#include <stdlib.h>
+#include "upkg.h"
+
+void print_upkg_flags(const char *prefix, unsigned long flags)
+{
+ if (flags & UPKG_FLAG_ALLOW_DOWNLOAD)
+ printf("%sAllowDownload\n", prefix);
+ if (flags & UPKG_FLAG_CLIENT_OPTIONAL)
+ printf("%sClientOptional\n", prefix);
+ if (flags & UPKG_FLAG_SERVER_ONLY)
+ printf("%sServerOnly\n", prefix);
+ if (flags & UPKG_FLAG_BROKEN_LINKS)
+ printf("%sBrokenLinks\n", prefix);
+ if (flags & UPKG_FLAG_INSECURE)
+ printf("%sInsecure\n", prefix);
+ if (flags & UPKG_FLAG_REQUIRED)
+ printf("%sRequired\n", prefix);
+}
+
+
+int main(int argc, char **argv)
+{
+ struct upkg *pkg;
+
+ if (argc < 2) {
+ fprintf(stderr, "usage: upkg file\n");
+ return EXIT_FAILURE;
+ }
+
+ pkg = upkg_fopen(argv[1]);
+ if (!pkg) {
+ fprintf(stderr, "failed to open package!\n");
+ return EXIT_FAILURE;
+ }
+
+ printf("Version: %u\n", pkg->version);
+ printf("License: %u\n", pkg->license);
+ printf("Flags: %lx\n", pkg->flags);
+ print_upkg_flags("\t", pkg->flags);
+
+ return 0;
+}
--- /dev/null
+#ifndef UPKG_H_
+#define UPKG_H_
+
+#define UPKG_FLAG_ALLOW_DOWNLOAD 0x0001
+#define UPKG_FLAG_CLIENT_OPTIONAL 0x0002
+#define UPKG_FLAG_SERVER_ONLY 0x0004
+#define UPKG_FLAG_BROKEN_LINKS 0x0008
+#define UPKG_FLAG_INSECURE 0x0010
+#define UPKG_FLAG_REQUIRED 0x8000
+
+#define UPKG_HDR_MAGIC 0x9e2a83c1
+#define UPKG_HDR_SIZE 36
+
+struct upkg {
+ unsigned version, license;
+ unsigned long flags;
+
+ struct upkg_private *priv;
+};
+
+struct upkg *upkg_fopen(const char *path);
+int upkg_close(struct upkg *pkg);
+
+#endif