From: Nick Bowler Date: Fri, 5 Jun 2009 00:12:18 +0000 (-0400) Subject: Initial commit X-Git-Url: https://git.draconx.ca/gitweb/upkg.git/commitdiff_plain/21b765a5e880c966a965fc40922ca6257bc465c6 Initial commit --- 21b765a5e880c966a965fc40922ca6257bc465c6 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..56e731f --- /dev/null +++ b/.gitignore @@ -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 index 0000000..b89ed90 --- /dev/null +++ b/Makefile.am @@ -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 index 0000000..9db4e70 --- /dev/null +++ b/autogen.sh @@ -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 index 0000000..58638b4 --- /dev/null +++ b/configure.ac @@ -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 index 0000000..dfc8e0f --- /dev/null +++ b/libupkg.c @@ -0,0 +1,83 @@ +#include +#include + +#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 index 0000000..49bacd9 --- /dev/null +++ b/pack.c @@ -0,0 +1,73 @@ +#include +#include + +#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 index 0000000..283f28c --- /dev/null +++ b/pack.h @@ -0,0 +1,30 @@ +#ifndef PACK_H_ +#define PACK_H_ + +#include + +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 index 0000000..d0ba146 --- /dev/null +++ b/upkg.c @@ -0,0 +1,43 @@ +#include +#include +#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 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