aboutsummaryrefslogtreecommitdiff
path: root/analyzer/commands.c
blob: 676c78d78f94a1b1530c0896cb90cdaf3e3be36f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
#include "commands.h"

#include <stdio.h>
#include <string.h>

#include "analyzer.h"
#include "capture.h"
#include "utils/memory.h"

#define PROGRAM_NAME "branal"
#define INDENT "  "
#define MAX_COMMAND_LENGTH 100

// calculate the longest command length to align explenations
int longest_command_length() {
    int longest_len = 0;
    for (size_t i = 0; i < commands_count; i++) {
        Command cmd = commands[i];
        int len = strlen(PROGRAM_NAME);
        len += strlen(" ( | ) ");
        len += strlen(cmd.short_name) + strlen(cmd.name);
        len += strlen(cmd.args_str) == 0 ? 0 : strlen(cmd.args_str) + 1;
        if (len > longest_len)
            longest_len = len;
    }
    return longest_len;
}

// help command handler
int print_help(int argc, char *argv[]) {
    (void)argc;
    (void)argv;

    int len = longest_command_length();

    printf("A bare-bones analyzer for the game Broken Ranks\n");
    printf("\nUsage:\n");
    printf(INDENT "%-*s- same as below\n", len, PROGRAM_NAME);

    for (size_t i = 0; i < commands_count; i++) {
        Command cmd = commands[i];

        char buffer[MAX_COMMAND_LENGTH];
        sprintf(buffer, PROGRAM_NAME " (%s | %s) ", cmd.short_name, cmd.name);
        if (strlen(cmd.args_str))
            strcat(buffer, cmd.args_str);

        printf(INDENT "%-*s- %s\n", len, buffer, cmd.explanation[0]);
        for (size_t j = 1; j < cmd.explanation_lines; j++)
            printf(INDENT "%*s%s\n", len + 2, "", cmd.explanation[j]);
    }

    return 0;
}

// live analyzer command handler
int live_anal(int argc, char *argv[]) {
    (void)argc;
    (void)argv;

    // TODO: implement
    printf("Not implemented\n");
    return 1;
}

// capturing mode command handler
int capture(int argc, char *argv[]) {
    capturing_mode(argc >= 3 ? argv[2] : NULL);
    return 0;
}

// file analysis command handler
int file_anal(int argc, char *argv[]) {
    if (argc < 3) {
        printf("You need to provide a file (or files) to analyze");
        return 1;
    }

    for (size_t i = 2; i < (size_t)argc; i++) {
        printf("FILE: %s\n", argv[i]);
        analyze_file(argv[i]);
        printf("\n");
    }

    return 0;
}

const Command help_command = {"help", "h", "", {"display this help"}, 1, print_help};
const Command commands[] = {
    {"live", "l", "", {"start live analysis"}, 1, live_anal},
    {"capture", "c", "[file]", {"start capturing packers to file", "If file isn't provided - captures to: $HOME/.local/share/branal/captures"}, 2, capture},
    {"file", "f", "<file...>", {"analyze the specified file(s)"}, 1, file_anal},
    help_command
};
const size_t commands_count = ARR_LEN(commands);

int is_command(Command command, char *str) {
    return !strcmp(command.short_name, str) || !strcmp(command.name, str);
}

void command_not_recognized() {
    printf("Command not recognized\n");
    printf("Use \"%s (%s | %s)\" for help\n", PROGRAM_NAME, help_command.short_name, help_command.name);
}