diff options
Diffstat (limited to 'src/main/perk.c')
-rw-r--r-- | src/main/perk.c | 116 |
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 |