From 21b765a5e880c966a965fc40922ca6257bc465c6 Mon Sep 17 00:00:00 2001 From: Nick Bowler Date: Thu, 4 Jun 2009 20:12:18 -0400 Subject: [PATCH] Initial commit --- .gitignore | 20 +++++++++++++ Makefile.am | 11 +++++++ autogen.sh | 15 ++++++++++ configure.ac | 16 ++++++++++ libupkg.c | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++++ pack.c | 73 +++++++++++++++++++++++++++++++++++++++++++++ pack.h | 30 +++++++++++++++++++ upkg.c | 43 +++++++++++++++++++++++++++ upkg.h | 24 +++++++++++++++ 9 files changed, 315 insertions(+) create mode 100644 .gitignore create mode 100644 Makefile.am create mode 100755 autogen.sh create mode 100644 configure.ac create mode 100644 libupkg.c create mode 100644 pack.c create mode 100644 pack.h create mode 100644 upkg.c create mode 100644 upkg.h 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 -- 2.43.0