]> git.draconx.ca Git - upkg.git/commitdiff
Initial commit
authorNick Bowler <nbowler@draconx.ca>
Fri, 5 Jun 2009 00:12:18 +0000 (20:12 -0400)
committerNick Bowler <nbowler@draconx.ca>
Fri, 5 Jun 2009 00:12:18 +0000 (20:12 -0400)
.gitignore [new file with mode: 0644]
Makefile.am [new file with mode: 0644]
autogen.sh [new file with mode: 0755]
configure.ac [new file with mode: 0644]
libupkg.c [new file with mode: 0644]
pack.c [new file with mode: 0644]
pack.h [new file with mode: 0644]
upkg.c [new file with mode: 0644]
upkg.h [new file with mode: 0644]

diff --git a/.gitignore b/.gitignore
new file mode 100644 (file)
index 0000000..56e731f
--- /dev/null
@@ -0,0 +1,20 @@
+*.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
diff --git a/Makefile.am b/Makefile.am
new file mode 100644 (file)
index 0000000..b89ed90
--- /dev/null
@@ -0,0 +1,11 @@
+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
diff --git a/autogen.sh b/autogen.sh
new file mode 100755 (executable)
index 0000000..9db4e70
--- /dev/null
@@ -0,0 +1,15 @@
+#!/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."
diff --git a/configure.ac b/configure.ac
new file mode 100644 (file)
index 0000000..58638b4
--- /dev/null
@@ -0,0 +1,16 @@
+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
diff --git a/libupkg.c b/libupkg.c
new file mode 100644 (file)
index 0000000..dfc8e0f
--- /dev/null
+++ b/libupkg.c
@@ -0,0 +1,83 @@
+#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;
+}
diff --git a/pack.c b/pack.c
new file mode 100644 (file)
index 0000000..49bacd9
--- /dev/null
+++ b/pack.c
@@ -0,0 +1,73 @@
+#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
diff --git a/pack.h b/pack.h
new file mode 100644 (file)
index 0000000..283f28c
--- /dev/null
+++ b/pack.h
@@ -0,0 +1,30 @@
+#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
diff --git a/upkg.c b/upkg.c
new file mode 100644 (file)
index 0000000..d0ba146
--- /dev/null
+++ b/upkg.c
@@ -0,0 +1,43 @@
+#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;
+}
diff --git a/upkg.h b/upkg.h
new file mode 100644 (file)
index 0000000..acd176b
--- /dev/null
+++ b/upkg.h
@@ -0,0 +1,24 @@
+#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