summaryrefslogtreecommitdiff
path: root/src/main/perk.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/perk.c')
-rw-r--r--src/main/perk.c116
1 files changed, 116 insertions, 0 deletions
diff --git a/src/main/perk.c b/src/main/perk.c
new file mode 100644
index 0000000..5fe8f17
--- /dev/null
+++ b/src/main/perk.c
@@ -0,0 +1,116 @@
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <malloc.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <errno.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <perk/perk.h>
+#include "perk_impl.h"
+
+static int perk_parse_opts(struct perk_ctx * ctx)
+{
+ int i;
+ char * ch;
+ const char ** popt;
+
+ for (i=1; i<ctx->argc; i++) {
+ ch = ctx->argv[i];
+
+ if (*ch == '-') {
+ switch (*++ch) {
+ case 'i':
+ popt = &ctx->fname;
+ break;
+ case 'h':
+ ctx->flags = PERK_HELP;
+ return 0;
+ default:
+ ctx->status = PERK_BAD_OPT;
+ return ctx->status;
+ }
+
+ while ((*++ch == '\t') || (*ch == ' '));
+
+ if (!*ch) {
+ if (++i < ctx->argc)
+ *popt = ctx->argv[i];
+ else
+ ctx->status = PERK_BAD_OPT_VAL;
+ } else
+ *popt = ch;
+ } else if (!ctx->fname)
+ ctx->fname = ch;
+ else
+ ctx->status = PERK_BAD_OPT;
+
+ }
+
+ return ctx->status;
+}
+
+
+static int perk_map_input(struct perk_ctx * ctx)
+{
+ ctx->fd = open(ctx->fname,O_RDONLY | O_CLOEXEC);
+
+ if (ctx->fd < 0) {
+ ctx->status = PERK_IO_ERROR;
+ return ctx->status;
+ }
+
+ ctx->status = pe_map_raw_image(ctx->fd,0,&ctx->map);
+
+ return ctx->status;
+}
+
+
+static int perk_exit(struct perk_ctx * ctx)
+{
+ if (ctx->map.addr)
+ pe_unmap_raw_image(&ctx->map);
+
+ return ctx->status;
+}
+
+
+static int perk_run(struct perk_ctx * ctx)
+{
+ struct pe_image_meta * meta;
+
+ if (perk_map_input(ctx))
+ return perk_exit(ctx);
+
+ if ((ctx->status = pe_get_image_meta(&ctx->map,&meta)))
+ return perk_exit(ctx);
+
+ /* pre-alpha default output */
+ pe_output_export_symbols(
+ meta,
+ PERK_OUTPUT_FORMAT_LIST | PERK_OUTPUT_FIELD_NAME,
+ stdout);
+
+ ctx->status = pe_free_image_meta(meta);
+
+ return perk_exit(ctx);
+}
+
+static int perk_main(int argc, char * argv[], char * envp[])
+{
+ struct perk_ctx ctx = {argc,argv,envp};
+
+ if (perk_parse_opts(&ctx))
+ return ctx.status;
+ else
+ return perk_run(&ctx);
+}
+
+#ifdef PERK_APP
+extern __typeof(perk_main) main __attribute__((alias("perk_main")));
+#endif