diff options
| author | Mosder <xmosder12@gmail.com> | 2026-07-28 16:38:04 +0200 |
|---|---|---|
| committer | Mosder <xmosder12@gmail.com> | 2026-07-28 16:38:04 +0200 |
| commit | 9e874301350a70a1ba40b5508878d559f68f8f4a (patch) | |
| tree | 89f561b31bdda9bed936961dd7ef0268228a5b69 | |
| parent | 95763527e73c0d06d3887e4a2da22f627f13bfaa (diff) | |
refactor: generalized dynamic arrays with structures/array.h
| -rw-r--r-- | Makefile | 1 | ||||
| -rw-r--r-- | analyzer/analyzer.c | 29 | ||||
| -rw-r--r-- | analyzer/capture.c | 5 | ||||
| -rw-r--r-- | analyzer/parser/fight_results/fight_results.c | 77 | ||||
| -rw-r--r-- | analyzer/parser/fight_results/fight_results.h | 11 | ||||
| -rw-r--r-- | analyzer/parser/parser.c | 37 | ||||
| -rw-r--r-- | analyzer/parser/parser.h | 14 | ||||
| -rw-r--r-- | analyzer/parser/parser_defs.h | 6 | ||||
| -rw-r--r-- | analyzer/render.c | 26 | ||||
| -rw-r--r-- | analyzer/structures/array.c | 110 | ||||
| -rw-r--r-- | analyzer/structures/array.h | 80 | ||||
| -rw-r--r-- | analyzer/structures/hashmap.c | 28 | ||||
| -rw-r--r-- | analyzer/structures/hashmap.h | 22 | ||||
| -rw-r--r-- | analyzer/structures/heap.c | 73 | ||||
| -rw-r--r-- | analyzer/structures/heap.h | 30 | ||||
| -rw-r--r-- | analyzer/utils/fs.c | 9 | ||||
| -rw-r--r-- | analyzer/utils/memory.c | 24 | ||||
| -rw-r--r-- | analyzer/utils/memory.h | 26 | ||||
| -rw-r--r-- | analyzer/utils/tcp.c | 26 | ||||
| -rw-r--r-- | analyzer/utils/tcp.h | 5 | ||||
| -rw-r--r-- | csv_table_gen.c | 7 |
21 files changed, 384 insertions, 262 deletions
@@ -29,6 +29,7 @@ main_files: structures: $(CC) $(CFLAGS) -c analyzer/structures/hashmap.c $(CC) $(CFLAGS) -c analyzer/structures/heap.c + $(CC) $(CFLAGS) -c analyzer/structures/array.c utils: $(CC) $(CFLAGS) -c analyzer/utils/fs.c diff --git a/analyzer/analyzer.c b/analyzer/analyzer.c index 088e6d4..7b80328 100644 --- a/analyzer/analyzer.c +++ b/analyzer/analyzer.c @@ -1,7 +1,6 @@ #include "analyzer.h" -#include <stdlib.h> -#include <string.h> +#include <stdio.h> #include "parser/parser.h" #include "render.h" @@ -9,11 +8,7 @@ // loop through packets received from pcap_handle and analyze the TCP streams void analyzer_loop( - TCPStream *server_stream, - TCPStream *client_stream, - pcap_t *pcap_handle, - void *state, - void (*parsed_data_handler)(void *state, ParsedData *parsed_data, size_t n_parsed_data) + TCPStream *server_stream, TCPStream *client_stream, pcap_t *pcap_handle, void *state, void (*parsed_data_handler)(void *state, DynArray parsed_data) ) { // read packets from handle struct pcap_pkthdr *packet_data; @@ -30,31 +25,31 @@ void analyzer_loop( if (handle_segment(stream, segment)) { // if it was added to the stream - parse it size_t parsed_len; - size_t n_parsed_data; - ParsedData *parsed_data = parse_stream(stream, &parsed_len, &n_parsed_data); + DynArray parsed_data = parse_stream(stream, &parsed_len); // if some bytes were parsed - remove them from the stream if (parsed_len > 0) remove_parsed_data(stream, parsed_len); // if there's parsed data - call the parsed data handler - if (n_parsed_data > 0) - parsed_data_handler(state, parsed_data, n_parsed_data); + if (parsed_data.count > 0) + parsed_data_handler(state, parsed_data); - // free the entire parsed data memory - free_parsed_data(parsed_data, n_parsed_data); + // destroy parsed data + array_destroy(parsed_data); } } } // file analyzer parsed data handler -void file_parsed_data_handler(void *state, ParsedData *parsed_data, size_t n_parsed_data) { +void file_parsed_data_handler(void *state, DynArray parsed_data) { int *fights_count = state; - for (size_t i = 0; i < n_parsed_data; i++) { - switch (parsed_data[i].data_type) { + ParsedData *data = NULL; + while ((data = array_next(parsed_data, data))) { + switch (data->data_type) { case TYPE_FIGHT_RESULTS: printf("\nFIGHT %d:\n", ++*fights_count); - render_fight_results(*(FightResults *)parsed_data[i].data); + render_fight_results(*(FightResults *)data->data); break; } } diff --git a/analyzer/capture.c b/analyzer/capture.c index 0a75e09..9c27850 100644 --- a/analyzer/capture.c +++ b/analyzer/capture.c @@ -1,5 +1,6 @@ #include "capture.h" +#include <limits.h> #include <stdio.h> #include <stdlib.h> @@ -10,7 +11,7 @@ void capture_to_file(char *path) { char command[128]; - sprintf(command, "tshark -i %s -f \"src host %s\" -w %s", INTERFACE, SERVER_IP, path); + sprintf(command, "tshark -i %s -f \"host %s\" -w %s", INTERFACE, SERVER_IP, path); system(command); } @@ -20,7 +21,7 @@ void capturing_mode(char *path) { return; } - char capture_dir[256], new_path[256], date_time[128]; + char capture_dir[PATH_MAX], new_path[PATH_MAX], date_time[128]; get_capture_dir(capture_dir); get_date_time_string(date_time); sprintf(new_path, "%s/capture-%s.pcap", capture_dir, date_time); diff --git a/analyzer/parser/fight_results/fight_results.c b/analyzer/parser/fight_results/fight_results.c index 3adf67b..942d9b4 100644 --- a/analyzer/parser/fight_results/fight_results.c +++ b/analyzer/parser/fight_results/fight_results.c @@ -13,32 +13,40 @@ #include "parser/fight_results/gear.h" #include "parser/fight_results/gear_info.h" #include "parser/fight_results/orb.h" -#include "parser/structs.h" #include "utils/memory.h" #include "utils/roman.h" // function to cleanup fight results to be used in ParsedData struct void cleanup_fight_results(void *data) { FightResults *fight_results = data; - for (size_t i = 0; i < fight_results->num_friendly; i++) { - FriendlyResults friendly = fight_results->friendly_results[i]; - free(friendly.name); - for (size_t j = 0; j < friendly.num_items; j++) - free(friendly.items[j].data); - free(friendly.items); - } - for (size_t i = 0; i < fight_results->num_enemy; i++) { - free(fight_results->enemy_results[i].name); - } - free(fight_results->friendly_results); - free(fight_results->enemy_results); + array_destroy(fight_results->friendly_results); + array_destroy(fight_results->enemy_results); } -byte_t *find_fight_results(TCPStream *stream, int offset, int *length) { - byte_t *start = memmem(stream->data + offset, stream->len - offset, FIGHT_RESULTS_START, strlen(FIGHT_RESULTS_START)); +// function to cleanup FriendlyResults in DynArray +void cleanup_friendly_results(void *results) { + FriendlyResults *friendly = results; + free(friendly->name); + array_destroy(friendly->items); +} + +// function to cleanup EnemyResults in DynArray +void cleanup_enemy_results(void *results) { + EnemyResults *enemy = results; + free(enemy->name); +} + +// function to cleanup Item in DynArray +void cleanup_item(void *item) { + Item *it = item; + free(it->data); +} + +byte_t *find_fight_results(byte_t *bytes, size_t bytes_count, int *length) { + byte_t *start = memmem(bytes, bytes_count, FIGHT_RESULTS_START, strlen(FIGHT_RESULTS_START)); byte_t *end = NULL; if (start) - end = memmem(start, stream->len - (start - stream->data), FIGHT_RESULTS_END, strlen(FIGHT_RESULTS_END)); + end = memmem(start, bytes_count - (start - bytes), FIGHT_RESULTS_END, strlen(FIGHT_RESULTS_END)); *length = end ? (int)(end - start + strlen(FIGHT_RESULTS_END)) : -1; return start; } @@ -48,7 +56,7 @@ void get_stars(char *buffer, int incr_above_b1) { sprintf(buffer, " (%c%d)", star_types[incr_above_b1 / 3], incr_above_b1 % 3 + 1); } -void add_gear(FriendlyResults *results, size_t *items_capacity, char *gears_str) { +void add_gear(DynArray *items, char *gears_str) { if (strlen(gears_str) == 0) return; @@ -106,7 +114,7 @@ void add_gear(FriendlyResults *results, size_t *items_capacity, char *gears_str) item.type = EPIC; break; } - results->items = array_append(results->items, sizeof(Item), &results->num_items, items_capacity, &item); + array_append(items, &item); cleanup_struct(&gear_info, gear_info_fields, ARR_LEN(gear_info_fields)); @@ -119,7 +127,7 @@ void add_gear(FriendlyResults *results, size_t *items_capacity, char *gears_str) sprintf(buffer, "%sorb %s", get_artifact_size_from_id(orb.size), get_orb_name_from_id(orb.id)); Item item = {.data = strdup(buffer), .type = ORB}; - results->items = array_append(results->items, sizeof(Item), &results->num_items, items_capacity, &item); + array_append(items, &item); cleanup_struct(&orb, orb_fields, ARR_LEN(orb_fields)); } @@ -128,7 +136,7 @@ void add_gear(FriendlyResults *results, size_t *items_capacity, char *gears_str) } while (gears_separator); } -void add_drifs(FriendlyResults *results, size_t *items_capacity, char *drifs_str) { +void add_drifs(DynArray *items, char *drifs_str) { if (strlen(drifs_str) == 0) return; @@ -144,13 +152,13 @@ void add_drifs(FriendlyResults *results, size_t *items_capacity, char *drifs_str drifs_str = drifs_separator + strlen(SEPARATOR_DRIF); Item item = {.data = strdup(drif.name), .type = DRIF}; - results->items = array_append(results->items, sizeof(Item), &results->num_items, items_capacity, &item); + array_append(items, &item); cleanup_struct(&drif, drif_fields, ARR_LEN(drif_fields)); } while (drifs_separator); } -void add_items(FriendlyResults *results, size_t *items_capacity, char *items_str) { +void add_items(DynArray *items, char *items_str) { if (strlen(items_str) == 0) return; @@ -168,7 +176,7 @@ void add_items(FriendlyResults *results, size_t *items_capacity, char *items_str items_str = items_separator + strlen(SEPARATOR_ITEMS); Item item = {.data = strdup(buffer), .type = NORMAL}; - results->items = array_append(results->items, sizeof(Item), &results->num_items, items_capacity, &item); + array_append(items, &item); } while (items_separator); } @@ -181,16 +189,14 @@ FriendlyResults parse_to_friendly(EntityResults entity_results) { .level = entity_results.level, .psycho = entity_results.psycho, .splinters = entity_results.splinters, - .num_items = 0, .saturation = 0 }; // create items array and add to it gear, drifs and items - results.items = safe_malloc(INIT_ITEMS_CAPACITY * sizeof(Item)); - size_t items_cap = INIT_ITEMS_CAPACITY; - add_gear(&results, &items_cap, entity_results.gear); - add_drifs(&results, &items_cap, entity_results.drifs); - add_items(&results, &items_cap, entity_results.items); + results.items = array_new(sizeof(Item), INIT_ITEMS_CAPACITY, cleanup_item); + add_gear(&results.items, entity_results.gear); + add_drifs(&results.items, entity_results.drifs); + add_items(&results.items, entity_results.items); if (strlen(entity_results.saturation) > 0) { int saturation_id; @@ -216,13 +222,8 @@ ParsedData parse_fight_results(byte_t *data, size_t length) { FightResults *results = safe_malloc(sizeof(FightResults)); - results->friendly_results = safe_malloc(INIT_ENTITIES_PER_SIDE * sizeof(FriendlyResults)); - results->num_friendly = 0; - size_t friendly_cap = INIT_ENTITIES_PER_SIDE; - - results->enemy_results = safe_malloc(INIT_ENTITIES_PER_SIDE * sizeof(EnemyResults)); - results->num_enemy = 0; - size_t enemy_cap = INIT_ENTITIES_PER_SIDE; + results->friendly_results = array_new(sizeof(FriendlyResults), INIT_ENTITIES_PER_SIDE, cleanup_friendly_results); + results->enemy_results = array_new(sizeof(EnemyResults), INIT_ENTITIES_PER_SIDE, cleanup_enemy_results); byte_t *entity_separator; do { @@ -236,12 +237,12 @@ ParsedData parse_fight_results(byte_t *data, size_t length) { switch (entity_results.team) { case TEAM_FRIEND: { FriendlyResults res = parse_to_friendly(entity_results); - results->friendly_results = array_append(results->friendly_results, sizeof(FriendlyResults), &results->num_friendly, &friendly_cap, &res); + array_append(&results->friendly_results, &res); break; } case TEAM_ENEMY: { EnemyResults res = parse_to_enemy(entity_results); - results->enemy_results = array_append(results->enemy_results, sizeof(EnemyResults), &results->num_enemy, &enemy_cap, &res); + array_append(&results->enemy_results, &res); break; } } diff --git a/analyzer/parser/fight_results/fight_results.h b/analyzer/parser/fight_results/fight_results.h index ec90394..03b3e7b 100644 --- a/analyzer/parser/fight_results/fight_results.h +++ b/analyzer/parser/fight_results/fight_results.h @@ -2,7 +2,7 @@ // utilities for parsing the fight results data #include "parser/parser_defs.h" -#include "utils/tcp.h" +#include "structures/array.h" #ifndef FIGHT_RESULTS_H #define FIGHT_RESULTS_H @@ -29,8 +29,7 @@ typedef struct { char *name; int exp; int gold; - Item *items; - size_t num_items; + DynArray items; int level; int psycho; int splinters; @@ -48,10 +47,8 @@ typedef struct { // entire fight resutls typedef struct { - size_t num_friendly; - FriendlyResults *friendly_results; - size_t num_enemy; - EnemyResults *enemy_results; + DynArray friendly_results; + DynArray enemy_results; } FightResults; extern find_function_t find_fight_results; diff --git a/analyzer/parser/parser.c b/analyzer/parser/parser.c index 07980e5..9265153 100644 --- a/analyzer/parser/parser.c +++ b/analyzer/parser/parser.c @@ -5,8 +5,16 @@ #include "parser/find_parse_functions.h" #include "utils/memory.h" +// function to cleanup ParsedData in DynArray +void cleanup_parsed_data(void *parsed_data) { + ParsedData *data = parsed_data; + if (data->data_cleanup) + data->data_cleanup(data->data); + free(data->data); +} + // find earliest data to parse in stream -byte_t *find_earliest_data(TCPStream *stream, int stream_offset, int *earliest_length, parse_function_t **earliest_parse_fun) { +byte_t *find_earliest_data(TCPStream *stream, size_t stream_offset, int *earliest_length, parse_function_t **earliest_parse_fun) { byte_t *earliest_data = NULL; for (size_t i = 0; i < ARR_LEN(all_find_parse_functions); i++) { // ignore if not correct stream @@ -14,7 +22,7 @@ byte_t *find_earliest_data(TCPStream *stream, int stream_offset, int *earliest_l continue; int length; - byte_t *data = all_find_parse_functions[i].find_fn(stream, stream_offset, &length); + byte_t *data = all_find_parse_functions[i].find_fn(stream->bytes.data + stream_offset, stream->bytes.count - stream_offset, &length); // if it's the first found or earlier than earliest - save it if (data && (!earliest_data || data < earliest_data)) { earliest_data = data; @@ -25,12 +33,10 @@ byte_t *find_earliest_data(TCPStream *stream, int stream_offset, int *earliest_l return earliest_data; } -ParsedData *parse_stream(TCPStream *stream, size_t *parsed_len, size_t *n_parsed_data) { - size_t parsed_data_capacity = INIT_PARSED_DATA_CAPACITY; - ParsedData *parsed_data = safe_malloc(parsed_data_capacity * sizeof(ParsedData)); - *n_parsed_data = 0; +DynArray parse_stream(TCPStream *stream, size_t *parsed_len) { + DynArray parsed_data = array_new(sizeof(ParsedData), INIT_PARSED_DATA_CAPACITY, cleanup_parsed_data); - int stream_offset = 0; + size_t stream_offset = 0; byte_t *earliest_data; do { // find earliest data to parse @@ -41,28 +47,19 @@ ParsedData *parse_stream(TCPStream *stream, size_t *parsed_len, size_t *n_parsed // if start of data to parse was found, but not the end, then finish here // set parsed_len, so that the beginning of that data is at the beginning of the stream if (earliest_data && earliest_length == -1) { - *parsed_len = earliest_data - stream->data; + *parsed_len = earliest_data - (byte_t *)stream->bytes.data; return parsed_data; } // if data to parse was found, parse it and update the offset if (earliest_data) { ParsedData new_parsed = earliest_parse_fun(earliest_data, earliest_length); - parsed_data = array_append(parsed_data, sizeof(ParsedData), n_parsed_data, &parsed_data_capacity, &new_parsed); - stream_offset = earliest_data - stream->data + earliest_length; + array_append(&parsed_data, &new_parsed); + stream_offset = earliest_data - (byte_t *)stream->bytes.data + earliest_length; } } while (earliest_data); // if all was parsed - set parsed_len to stream_len and return the data - *parsed_len = stream->len; + *parsed_len = stream->bytes.count; return parsed_data; } - -void free_parsed_data(ParsedData *parsed_data, size_t n_parsed_data) { - for (size_t i = 0; i < n_parsed_data; i++) { - if (parsed_data[i].data_cleanup) - parsed_data[i].data_cleanup(parsed_data[i].data); - free(parsed_data[i].data); - } - free(parsed_data); -} diff --git a/analyzer/parser/parser.h b/analyzer/parser/parser.h index e7c46e8..221d3bd 100644 --- a/analyzer/parser/parser.h +++ b/analyzer/parser/parser.h @@ -1,8 +1,7 @@ // parser/parser.h // main parser file -#include "parser/fight_results/fight_results.h" -#include "parser/parser_defs.h" +#include "structures/array.h" #include "utils/tcp.h" #define INIT_PARSED_DATA_CAPACITY 4 @@ -11,13 +10,6 @@ // params: // - stream - the stream to parse // - parsed_len - pointer to inform how much of the stream was parsed (not all if e.g. start of data is there, but the end isn't yet) -// - n_parsed_data - pointer to the count of parsed data that was retrieved from the stream // returns: -// pointer to the array of parsed data -extern ParsedData *parse_stream(TCPStream *stream, size_t *parsed_len, size_t *n_parsed_data); - -// free the entire parsed data array from parse_stream function -// params: -// - parsed_data - parsed data to free -// - n_parsed_data - count of parsed data -extern void free_parsed_data(ParsedData *parsed_data, size_t n_parsed_data); +// array of parsed data +extern DynArray parse_stream(TCPStream *stream, size_t *parsed_len); diff --git a/analyzer/parser/parser_defs.h b/analyzer/parser/parser_defs.h index c64e138..5c03a09 100644 --- a/analyzer/parser/parser_defs.h +++ b/analyzer/parser/parser_defs.h @@ -18,12 +18,12 @@ typedef struct { // find the first results data of specific type in stream // params: -// - stream - stream to find the data in -// - offset - offset to start finding data from +// - bytes - stream bytes to find the data in +// - bytes_count - count of bytes in the stream // - length - length of the data or -1 if there's no end yet // returns: // pointer to the beginning of data or NULL if there's none -typedef byte_t *find_function_t(TCPStream *stream, int offset, int *length); +typedef byte_t *find_function_t(byte_t *bytes, size_t bytes_count, int *length); // parse given data of specifc type // params: diff --git a/analyzer/render.c b/analyzer/render.c index 5c4b2d0..fbaa72e 100644 --- a/analyzer/render.c +++ b/analyzer/render.c @@ -39,14 +39,14 @@ void print_center(char *text, int color, size_t width, char padding_char) { printf("%c", padding_char); } -void print_enemy_list(EnemyResults *results, size_t n_enemies) { +void print_enemy_list(DynArray enemies) { printf(TABLE_LINE_START); size_t line_length = TABLE_LINE_START_WIDTH; - for (size_t i = 0; i < n_enemies; i++) { - EnemyResults enemy = results[i]; + EnemyResults *enemy = NULL; + while ((enemy = array_next(enemies, enemy))) { char enemy_buffer[TABLE_LINE_WIDTH + 1]; - sprintf(enemy_buffer, "%s (%d)%s", enemy.name, enemy.level, i < n_enemies - 1 ? ", " : ""); + sprintf(enemy_buffer, "%s (%d)%s", enemy->name, enemy->level, array_next(enemies, enemy) ? ", " : ""); // break line if length would be too big if (line_length + utf8_strlen(enemy_buffer) > TABLE_LINE_WIDTH - TABLE_LINE_END_WIDTH) { @@ -122,20 +122,21 @@ void print_player_rewards(FriendlyResults results) { } printf("\n"); - if (results.num_items > 0) { + if (results.items.count > 0) { printf(TABLE_LINE_START); print_center("ITEMS", COLOR_WHITE, TABLE_ITEMS_WIDTH, ' '); printf(TABLE_LINE_END "\n" TABLE_LINE_START); size_t line_len = 0; - for (size_t i = 0; i < results.num_items; i++) { - char *sep = i < results.num_items - 1 ? ", " : ""; - size_t item_len = utf8_strlen(results.items[i].data) + strlen(sep); + Item *item = NULL; + while ((item = array_next(results.items, item))) { + char *sep = array_next(results.items, item) ? ", " : ""; + size_t item_len = utf8_strlen(item->data) + strlen(sep); if (line_len + item_len > TABLE_ITEMS_WIDTH) { printf("%*s" TABLE_LINE_END "\n" TABLE_LINE_START, (int)(TABLE_ITEMS_WIDTH - line_len), ""); line_len = 0; } - print_color(results.items[i].data, item_type_to_color(results.items[i].type)); + print_color(item->data, item_type_to_color(item->type)); printf("%s", sep); line_len += item_len; } @@ -147,7 +148,7 @@ void render_fight_results(FightResults results) { print_center("ENEMIES", COLOR_RED, TABLE_LINE_WIDTH, TABLE_ROW_SEPARATOR_CHAR); printf("\n"); - print_enemy_list(results.enemy_results, results.num_enemy); + print_enemy_list(results.enemy_results); print_center("PLAYER REWARDS", COLOR_GREEN, TABLE_LINE_WIDTH, TABLE_ROW_SEPARATOR_CHAR); printf("\n"); @@ -155,8 +156,9 @@ void render_fight_results(FightResults results) { print_column_names(); print_row_separator(); - for (size_t i = 0; i < results.num_friendly; i++) { - print_player_rewards(results.friendly_results[i]); + FriendlyResults *friendly = NULL; + while ((friendly = array_next(results.friendly_results, friendly))) { + print_player_rewards(*friendly); print_row_separator(); } } diff --git a/analyzer/structures/array.c b/analyzer/structures/array.c new file mode 100644 index 0000000..ecdc0df --- /dev/null +++ b/analyzer/structures/array.c @@ -0,0 +1,110 @@ +#include "structures/array.h" + +#include <stdlib.h> +#include <string.h> + +#include "utils/memory.h" + +DynArray array_new(size_t el_size, size_t capacity, void (*el_cleanup)(void *el)) { + // clang-format off + DynArray array = { + .data = safe_malloc(capacity * el_size), + .el_size = el_size, + .count = 0, + .capacity = capacity, + .el_cleanup = el_cleanup + }; + // clang-format on + return array; +} + +void *array_get(DynArray array, size_t index) { + if (index >= array.count) + return NULL; + return (char *)array.data + index * array.el_size; +} + +void *array_next(DynArray array, void *prev) { + // if NULL - return first or NULL if count is 0 + if (!prev) + return array.count == 0 ? NULL : array.data; + + ptrdiff_t byte_diff = (char *)prev - (char *)array.data; + + // if outside of range / prev was last - return NULL + if (byte_diff < 0 || (size_t)byte_diff >= (array.count - 1) * array.el_size) + return NULL; + + return (char *)prev + array.el_size; +} + +// expand an array +void array_expand(DynArray *array, size_t to_fit) { + while (array->capacity < to_fit) + array->capacity *= 2; + array->data = safe_realloc(array->data, array->capacity * array->el_size); +} + +void array_put(DynArray *array, size_t index, void *val) { + if (index >= array->capacity) + array_expand(array, index + 1); + + if (index < array->count && array->el_cleanup) + array->el_cleanup(array_get(*array, index)); + + memcpy((char *)array->data + index * array->el_size, val, array->el_size); + + if (index >= array->count) + array->count = index + 1; +} + +void array_append(DynArray *array, void *val) { + if (array->count >= array->capacity) + array_expand(array, array->count + 1); + memcpy((char *)array->data + array->count++ * array->el_size, val, array->el_size); +} + +void array_concat(DynArray *array, void *arr2, size_t len2) { + if (array->count + len2 > array->capacity) + array_expand(array, array->count + len2); + memcpy((char *)array->data + array->count * array->el_size, arr2, len2 * array->el_size); + array->count += len2; +} + +void array_remove_front(DynArray *array, size_t to_remove) { + if (to_remove >= array->count) { + array->count = 0; + return; + } + + if (array->el_cleanup) { + for (size_t i = 0; i < to_remove; i++) + array->el_cleanup(array_get(*array, i)); + } + + array->count -= to_remove; + memmove(array->data, (char *)array->data + to_remove * array->el_size, array->count * array->el_size); +} + +void array_remove_back(DynArray *array, size_t to_remove) { + if (to_remove >= array->count) { + array->count = 0; + return; + } + + if (array->el_cleanup) { + for (size_t i = 0; i < to_remove; i++) + array->el_cleanup(array_get(*array, array->count - i - 1)); + } + + array->count -= to_remove; +} + +void array_destroy(DynArray array) { + if (array.el_cleanup) { + void *el = NULL; + while ((el = array_next(array, el))) + array.el_cleanup(el); + } + free(array.data); +} diff --git a/analyzer/structures/array.h b/analyzer/structures/array.h new file mode 100644 index 0000000..5f65bc3 --- /dev/null +++ b/analyzer/structures/array.h @@ -0,0 +1,80 @@ +// structures/array.h +// implementation of dynamic array + +#include <stddef.h> + +#ifndef ARRAY_H +#define ARRAY_H + +typedef struct { + void *data; // array elements + size_t el_size; // element size + size_t count; // element count + size_t capacity; // array capacity + void (*el_cleanup)(void *el); // element cleanup function +} DynArray; + +// create new dynamic array of given el_size and capacity +// params: +// - el_size - size of the element to be in array +// - capacity - initial capacity of the array +// - cleanup - element cleanup function (if there are any internal allocations) +// if no internal allocations - should be NULL +// returns: +// newly created DynArray +extern DynArray array_new(size_t el_size, size_t capacity, void (*el_cleanup)(void *el)); + +// get (the pointer to) an element in the array +// params: +// - array - array to get from +// - index - index of the elment to get +// returns: +// pointer to the element to get or NULL if it doesn't exist +extern void *array_get(DynArray array, size_t index); + +// get the next element in the array +// params: +// - array - array to get next element from +// - prev - previous element of the array, if NULL gets first +// returns: +// pointer to the next element or NULL prev was the last one +extern void *array_next(DynArray array, void *prev); + +// put an element into the array +// params: +// - array - array to put to +// - index - index to put to +// - val - pointer to the value to put +extern void array_put(DynArray *array, size_t index, void *val); + +// append to array, expand if necessary +// params: +// - array - array to append to +// - val - pointer to the value to append to the array +extern void array_append(DynArray *array, void *val); + +// concatenate 2 arrays, expand if necessary +// params: +// - array - first array (destination) +// - arr2 - second array (doesn't have to be dynamic) +// - len2 - length of arr2 +extern void array_concat(DynArray *array, void *arr2, size_t len2); + +// remove given count of elements from the front of the array +// params: +// - array - array to remove from +// - to_remove - count of elements to remove +extern void array_remove_front(DynArray *array, size_t to_remove); + +// remove given count of elements from the back of the array +// params: +// - array - array to remove from +// - to_remove - count of elements to remove +extern void array_remove_back(DynArray *array, size_t to_remove); + +// destroy the array +// params: +// - array - array to destroy +extern void array_destroy(DynArray array); + +#endif diff --git a/analyzer/structures/hashmap.c b/analyzer/structures/hashmap.c index 5eb27ae..53fd5fc 100644 --- a/analyzer/structures/hashmap.c +++ b/analyzer/structures/hashmap.c @@ -7,25 +7,25 @@ HashMap *hashmap_new( size_t key_size, - size_t value_size, + size_t val_size, size_t (*hash)(void *key), int (*compare)(void *key1, void *key2), void (*key_cleanup)(void *key), - void (*value_cleanup)(void *key) + void (*val_cleanup)(void *val) ) { HashMap *map = safe_malloc(sizeof(HashMap)); // initialize NULLs memset(map->table, 0, HASHMAP_TABLE_SIZE * sizeof(HashMapNode *)); map->key_size = key_size; - map->value_size = value_size; + map->val_size = val_size; map->hash = hash; map->compare = compare; map->key_cleanup = key_cleanup; - map->value_cleanup = value_cleanup; + map->val_cleanup = val_cleanup; return map; } -void hashmap_put(HashMap *map, void *key, void *value) { +void hashmap_put(HashMap *map, void *key, void *val) { size_t key_hash = map->hash(key); HashMapNode *node = map->table[key_hash]; @@ -34,10 +34,10 @@ void hashmap_put(HashMap *map, void *key, void *value) { // if it exists - update node if (map->compare(key, node->key)) { // ensure no hanging memory allocation - if (map->value_cleanup) { - map->value_cleanup(node->value); + if (map->val_cleanup) { + map->val_cleanup(node->val); } - memcpy(node->value, value, map->value_size); + memcpy(node->val, val, map->val_size); return; } node = node->next; @@ -46,9 +46,9 @@ void hashmap_put(HashMap *map, void *key, void *value) { // if it doesn't exist - create new node HashMapNode *new_node = safe_malloc(sizeof(HashMapNode)); new_node->key = safe_malloc(map->key_size); - new_node->value = safe_malloc(map->value_size); + new_node->val = safe_malloc(map->val_size); memcpy(new_node->key, key, map->key_size); - memcpy(new_node->value, value, map->value_size); + memcpy(new_node->val, val, map->val_size); // put in front of the linked list new_node->next = map->table[key_hash]; @@ -63,7 +63,7 @@ void *hashmap_get(HashMap *map, void *key) { while (node) { // if it exists - return the value pointer if (map->compare(key, node->key)) { - return node->value; + return node->val; } node = node->next; } @@ -76,11 +76,11 @@ void free_node_without_next(HashMap *map, HashMapNode *node) { if (map->key_cleanup) { map->key_cleanup(node->key); } - if (map->value_cleanup) { - map->value_cleanup(node->value); + if (map->val_cleanup) { + map->val_cleanup(node->val); } free(node->key); - free(node->value); + free(node->val); free(node); } diff --git a/analyzer/structures/hashmap.h b/analyzer/structures/hashmap.h index 528f24a..10637f1 100644 --- a/analyzer/structures/hashmap.h +++ b/analyzer/structures/hashmap.h @@ -7,24 +7,24 @@ typedef struct HashMapNode { void *key; - void *value; + void *val; struct HashMapNode *next; } HashMapNode; typedef struct { HashMapNode *table[HASHMAP_TABLE_SIZE]; size_t key_size; - size_t value_size; + size_t val_size; size_t (*hash)(void *key); int (*compare)(void *key1, void *key2); void (*key_cleanup)(void *key); - void (*value_cleanup)(void *value); + void (*val_cleanup)(void *val); } HashMap; // create a new hash map // params: // - key_size - size of the key type -// - value_size - size of the value type +// - val_size - size of the value type // - hash - function for hashing keys // params: // - key - pointer to the key to hash @@ -40,27 +40,27 @@ typedef struct { // if it has no heap allocations, this should be NULL // params: // - key - pointer to the key to cleanup -// - value_cleanup - function for cleaning up any internal allocations inside node->value (not the value itself) -// if it has no heap allocations, this should be NULL +// - val_cleanup - function for cleaning up any internal allocations inside node->val (not the value itself) +// if it has no heap allocations, this should be NULL // params: -// - value - pointer to the value to cleanup +// - val - pointer to the value to cleanup // returns: // pointer to the new hash map extern HashMap *hashmap_new( size_t key_size, - size_t value_size, + size_t val_size, size_t (*hash)(void *key), int (*compare)(void *key1, void *key2), void (*key_cleanup)(void *key), - void (*value_cleanup)(void *value) + void (*val_cleanup)(void *val) ); // create/update an entry in a hash map // params: // - map - hash map to insert to // - key - pointer to the key -// - value - pointer to the value -extern void hashmap_put(HashMap *map, void *key, void *value); +// - val - pointer to the value +extern void hashmap_put(HashMap *map, void *key, void *val); // get the value of given key from a hash map // params: diff --git a/analyzer/structures/heap.c b/analyzer/structures/heap.c index 1267668..8f34ef2 100644 --- a/analyzer/structures/heap.c +++ b/analyzer/structures/heap.c @@ -5,14 +5,14 @@ #include "utils/memory.h" -Heap *heap_new(size_t element_size, int (*compare)(void *element1, void *element2), void (*element_cleanup)(void *element)) { +Heap *heap_new(size_t el_size, int (*compare)(void *el1, void *el2), void (*el_cleanup)(void *el)) { Heap *heap = safe_malloc(sizeof(Heap)); - heap->data = safe_malloc(INIT_HEAP_CAPACITY * sizeof(void *)); - heap->n_elements = 0; - heap->element_size = element_size; + heap->data = safe_malloc(INIT_HEAP_CAPACITY * el_size); + heap->count = 0; + heap->el_size = el_size; heap->capacity = INIT_HEAP_CAPACITY; heap->compare = compare; - heap->element_cleanup = element_cleanup; + heap->el_cleanup = el_cleanup; return heap; } @@ -31,56 +31,50 @@ size_t right(size_t i) { return 2 * i + 2; } -// swap two elements -void swap(void **p_el1, void **p_el2) { - void *tmp = *p_el1; - *p_el1 = *p_el2; - *p_el2 = tmp; +// swap two elements in heap +void swap(Heap *heap, size_t i1, size_t i2) { + char tmp[heap->el_size]; + memcpy(tmp, heap->data + i1, heap->el_size); + memcpy(heap->data + i1, heap->data + i2, heap->el_size); + memcpy(heap->data + i2, tmp, heap->el_size); } // expand heap exponentially to fit el_count elements void expand_heap(Heap *heap, size_t el_count) { while (heap->capacity < el_count) heap->capacity = (heap->capacity << 1) | 1; - heap->data = safe_realloc(heap->data, heap->capacity * sizeof(void *)); + heap->data = safe_realloc(heap->data, heap->capacity * heap->el_size); } void heap_insert(Heap *heap, void *element) { // expand heap if capacity is too small - if (heap->n_elements >= heap->capacity) - expand_heap(heap, heap->n_elements + 1); + if (heap->count >= heap->capacity) + expand_heap(heap, heap->count + 1); // insert into the last position - size_t i = heap->n_elements; - heap->data[i] = safe_malloc(heap->element_size); - memcpy(heap->data[i], element, heap->element_size); - heap->n_elements++; + size_t i = heap->count++; + memcpy(heap->data + i, element, heap->count); // heapify up - while (i > 0 && heap->compare(heap->data[i], heap->data[parent(i)])) { - swap(&heap->data[i], &heap->data[parent(i)]); + while (i > 0 && heap->compare(heap->data + i, heap->data + parent(i))) { + swap(heap, i, parent(i)); i = parent(i); } } void *heap_top_get(Heap *heap) { - return heap->n_elements <= 0 ? NULL : heap->data[0]; -} - -void free_heap_element(Heap *heap, size_t index) { - if (heap->element_cleanup) - heap->element_cleanup(heap->data[index]); - free(heap->data[index]); + return heap->count <= 0 ? NULL : heap->data; } void heap_top_remove(Heap *heap) { - if (heap->n_elements <= 0) + if (heap->count <= 0) return; - free_heap_element(heap, 0); + if (heap->el_cleanup) + heap->el_cleanup(heap->data); // move last element to root - heap->data[0] = heap->data[--heap->n_elements]; + memcpy(heap->data, heap->data + --heap->count, heap->el_size); // heapify down size_t i = 0; @@ -88,16 +82,16 @@ void heap_top_remove(Heap *heap) { do { size_t l = left(i); size_t r = right(i); - size_t to_be_parent = i; + size_t new_par = i; - if (l < heap->n_elements && heap->compare(heap->data[l], heap->data[to_be_parent])) - to_be_parent = l; - if (r < heap->n_elements && heap->compare(heap->data[r], heap->data[to_be_parent])) - to_be_parent = r; + if (l < heap->count && heap->compare(heap->data + l, heap->data + new_par)) + new_par = l; + if (r < heap->count && heap->compare(heap->data + r, heap->data + new_par)) + new_par = r; - if ((changed = to_be_parent != i)) { - swap(&heap->data[to_be_parent], &heap->data[i]); - i = to_be_parent; + if ((changed = new_par != i)) { + swap(heap, new_par, i); + i = new_par; } } while (changed); } @@ -105,8 +99,9 @@ void heap_top_remove(Heap *heap) { void heap_free(Heap *heap) { if (!heap) return; - for (size_t i = 0; i < heap->n_elements; i++) { - free_heap_element(heap, i); + if (heap->el_cleanup) { + for (size_t i = 0; i < heap->count; i++) + heap->el_cleanup(heap->data + i); } free(heap->data); free(heap); diff --git a/analyzer/structures/heap.h b/analyzer/structures/heap.h index 1ae72c0..a2d7333 100644 --- a/analyzer/structures/heap.h +++ b/analyzer/structures/heap.h @@ -10,36 +10,36 @@ #define INIT_HEAP_CAPACITY (1 << INIT_HEAP_DEPTH) - 1 typedef struct { - void **data; - size_t n_elements; - size_t element_size; + void *data; + size_t count; + size_t el_size; size_t capacity; - int (*compare)(void *element1, void *element2); - void (*element_cleanup)(void *element); + int (*compare)(void *el1, void *el2); + void (*el_cleanup)(void *el); } Heap; // create a new heap // params: -// - element_size - size of the heap element +// - el_size - size of the heap element // - compare - function for comparing elements // params: -// - element1 - pointer to the first of the elements to compare -// - element2 - pointer to the second of the elements to compare +// - el1 - pointer to the first of the elements to compare +// - el2 - pointer to the second of the elements to compare // returns: -// truthy if element1 should be element2's parent (e.g. element1 > element2 for max heap), falsy otherwise -// - element_cleanup - function for cleaning up any internal allocations inside element (not the element itself) -// if it has no heap allocations, this should be NULL +// truthy if el1 should be el2's parent (e.g. el1 > el2 for max heap), falsy otherwise +// - el_cleanup - function for cleaning up any internal allocations inside element (not the element itself) +// if it has no heap allocations, this should be NULL // params: -// - element - pointer to the element to cleanup +// - el - pointer to the element to cleanup // returns: // pointer to the new heap -extern Heap *heap_new(size_t element_size, int (*compare)(void *element1, void *element2), void (*element_cleanup)(void *element)); +extern Heap *heap_new(size_t el_size, int (*compare)(void *el1, void *el2), void (*el_cleanup)(void *el)); // insert new element into the heap // params: // - heap - heap to insert to -// - element - pointer to the element to insert -extern void heap_insert(Heap *heap, void *element); +// - el - pointer to the element to insert +extern void heap_insert(Heap *heap, void *el); // get the top element from the heap // params: diff --git a/analyzer/utils/fs.c b/analyzer/utils/fs.c index 5e3eb1c..e6d3256 100644 --- a/analyzer/utils/fs.c +++ b/analyzer/utils/fs.c @@ -1,5 +1,6 @@ #include "utils/fs.h" +#include <limits.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -10,25 +11,25 @@ void get_home_dir(char *home_dir) { } void get_main_dir(char *main_dir) { - char home_dir[256]; + char home_dir[PATH_MAX]; get_home_dir(home_dir); sprintf(main_dir, "%s/.local/share/branal", home_dir); } void get_capture_dir(char *capture_dir) { - char main_dir[256]; + char main_dir[PATH_MAX]; get_main_dir(main_dir); sprintf(capture_dir, "%s/captures", main_dir); } void get_saves_dir(char *saves_dir) { - char main_dir[256]; + char main_dir[PATH_MAX]; get_main_dir(main_dir); sprintf(saves_dir, "%s/saves", main_dir); } void create_necessary_directories() { - char main_dir[256], capture_dir[256], saves_dir[256]; + char main_dir[PATH_MAX], capture_dir[PATH_MAX], saves_dir[PATH_MAX]; get_main_dir(main_dir); get_capture_dir(capture_dir); get_saves_dir(saves_dir); diff --git a/analyzer/utils/memory.c b/analyzer/utils/memory.c index 91c5f18..3e29671 100644 --- a/analyzer/utils/memory.c +++ b/analyzer/utils/memory.c @@ -2,7 +2,6 @@ #include <stdio.h> #include <stdlib.h> -#include <string.h> #include <unistd.h> void *safe_malloc(size_t size) { @@ -37,26 +36,3 @@ void *safe_realloc(void *ptr, size_t size) { fprintf(stderr, "FATAL: Failed realloc %d times. Exiting...", MAX_ALLOC_ATTEMPTS); exit(EXIT_FAILURE); } - -// expand an array -// returns pointer to the expanded array -void *array_expand(void *arr, size_t el_size, size_t *cap, size_t to_fit) { - while (*cap < to_fit) - *cap *= 2; - return safe_realloc(arr, *cap * el_size); -} - -void *array_append(void *arr, size_t el_size, size_t *len, size_t *cap, void *val) { - if (*len >= *cap) - arr = array_expand(arr, el_size, cap, *len + 1); - memcpy((char *)arr + (*len)++ * el_size, val, el_size); - return arr; -} - -void *array_concat(void *arr1, size_t el_size, size_t *len1, size_t *cap, void *arr2, size_t len2) { - if (*len1 + len2 > *cap) - arr1 = array_expand(arr1, el_size, cap, *len1 + len2); - memcpy((char *)arr1 + *len1 * el_size, arr2, len2 * el_size); - *len1 += len2; - return arr1; -} diff --git a/analyzer/utils/memory.h b/analyzer/utils/memory.h index 0973623..8f01ba4 100644 --- a/analyzer/utils/memory.h +++ b/analyzer/utils/memory.h @@ -3,6 +3,9 @@ #include <stddef.h> +#ifndef MEMORY_H +#define MEMORY_H + #define ARR_LEN(arr) (sizeof(arr) / sizeof(arr[0])) #define MAX_ALLOC_ATTEMPTS 3 @@ -22,25 +25,4 @@ extern void *safe_malloc(size_t size); // pointer to the reallocated memory extern void *safe_realloc(void *ptr, size_t size); -// append to array, expand if necessary -// params: -// - arr - array to append to -// - el_size - size of an array element -// - len - pointer to the length of the array -// - cap - pointer to the capacity of the array -// - val - pointer to the value to append to the array -// returns: -// new pointer to the array (different if it was realloced) -extern void *array_append(void *arr, size_t el_size, size_t *len, size_t *cap, void *val); - -// concatenate 2 arrays, expand if necessary -// params: -// - arr1 - first array (destination) -// - el_size - size of an array element -// - len1 - pointer to the length of arr1 -// - cap - pointer to the capacity of arr1 -// - arr2 - second array -// - len2 - length of arr2 -// returns: -// new pointer to the array (different if it was realloced) -extern void *array_concat(void *arr1, size_t el_size, size_t *len1, size_t *cap, void *arr2, size_t len2); +#endif diff --git a/analyzer/utils/tcp.c b/analyzer/utils/tcp.c index 7a79c67..add2a76 100644 --- a/analyzer/utils/tcp.c +++ b/analyzer/utils/tcp.c @@ -77,9 +77,7 @@ TCPSegment get_segment_from_packet(const byte_t *packet, const struct pcap_pkthd TCPStream new_stream(ConnectionSource src) { // clang-format off TCPStream stream = { - .data = safe_malloc(INIT_STREAM_CAPACITY), - .len = 0, - .capacity = INIT_STREAM_CAPACITY, + .bytes = array_new(1, INIT_STREAM_CAPACITY, NULL), .seq = 0, .port = 0, .src = src, @@ -90,13 +88,12 @@ TCPStream new_stream(ConnectionSource src) { } void destroy_stream(TCPStream stream) { - free(stream.data); + array_destroy(stream.bytes); heap_free(stream.pending); } void remove_parsed_data(TCPStream *stream, size_t parsed_len) { - memmove(stream->data, stream->data + parsed_len, stream->len - parsed_len); - stream->len -= parsed_len; + array_remove_front(&stream->bytes, parsed_len); stream->seq += parsed_len; } @@ -104,7 +101,7 @@ void remove_parsed_data(TCPStream *stream, size_t parsed_len) { // return the index of the first relevant byte in payload or -1 if segment isn't directly connected to stream int get_first_relevant_byte_index(TCPStream stream, TCPSegment segment) { // expected tcp sequence numbers for stream and segment - uint32_t stream_expected = stream.seq + stream.len; + uint32_t stream_expected = stream.seq + stream.bytes.count; uint32_t segment_expected = segment.seq + segment.len; if (seq_in_range_ie(stream_expected, segment.seq, segment_expected)) return stream_expected - segment.seq; @@ -114,16 +111,11 @@ int get_first_relevant_byte_index(TCPStream stream, TCPSegment segment) { // check if the segment is in acceptable range to the stream int in_acceptable_range(TCPStream stream, TCPSegment segment) { // expected tcp sequence number for stream and max acceptable sequence number for segment - uint32_t stream_expected = stream.seq + stream.len; + uint32_t stream_expected = stream.seq + stream.bytes.count; uint32_t max_acceptable_seq = stream_expected + MAX_SEQ_OFFSET; return seq_in_range_ei(segment.seq, stream_expected, max_acceptable_seq); } -// add segment directly to stream -void add_segment(TCPStream *stream, TCPSegment segment, size_t data_start) { - stream->data = array_concat(stream->data, 1, &stream->len, &stream->capacity, segment.payload + data_start, segment.len - data_start); -} - // add pending segments to the stream void add_pending_segments(TCPStream *stream) { int top_changed = 1; @@ -134,7 +126,7 @@ void add_pending_segments(TCPStream *stream) { // add pending segment it it became directly connected int data_start = get_first_relevant_byte_index(*stream, *top); if (data_start != -1) { - add_segment(stream, *top, data_start); + array_concat(&stream->bytes, top->payload + data_start, top->len - data_start); top_changed = 1; } @@ -152,11 +144,11 @@ int handle_segment(TCPStream *stream, TCPSegment segment) { heap_free(stream->pending); stream->pending = heap_new(sizeof(TCPSegment), segments_compare, segment_cleanup); - stream->len = 0; + array_remove_front(&stream->bytes, stream->bytes.count); stream->seq = segment.seq; stream->port = segment.port; - add_segment(stream, segment, 0); + array_concat(&stream->bytes, segment.payload, segment.len); free(segment.payload); return 1; } @@ -164,7 +156,7 @@ int handle_segment(TCPStream *stream, TCPSegment segment) { // add segment directly to the stream if it's directly connected int data_start = get_first_relevant_byte_index(*stream, segment); if (data_start != -1) { - add_segment(stream, segment, data_start); + array_concat(&stream->bytes, segment.payload + data_start, segment.len - data_start); free(segment.payload); add_pending_segments(stream); return 1; diff --git a/analyzer/utils/tcp.h b/analyzer/utils/tcp.h index 382c585..55cbf3e 100644 --- a/analyzer/utils/tcp.h +++ b/analyzer/utils/tcp.h @@ -4,6 +4,7 @@ #include <pcap.h> #include "structures/heap.h" +#include "structures/array.h" #ifndef TCP_H #define TCP_H @@ -32,9 +33,7 @@ extern TCPSegment get_segment_from_packet(const byte_t *packet, const struct pca // struct that stores all the information about stream typedef struct { - byte_t *data; // bytes in the stream - size_t len; // length of the stream - size_t capacity; // capacity of the data buffer + DynArray bytes; // bytes in the stream uint32_t seq; // TCP sequence number of the first byte in the stream uint16_t port; // client port of currently analyzed connection ConnectionSource src; // stream's source diff --git a/csv_table_gen.c b/csv_table_gen.c index ae80b78..49ebe77 100644 --- a/csv_table_gen.c +++ b/csv_table_gen.c @@ -1,4 +1,5 @@ #include <dirent.h> +#include <limits.h> #include <stdio.h> #include <string.h> #include <sys/stat.h> @@ -89,19 +90,19 @@ void create_c(char *path, char *h_path, char *from, char *to, char from_to_array void create_table(char *file_name) { // read from input file - char input_path[BUFFER_SIZE]; + char input_path[PATH_MAX]; sprintf(input_path, "%s/%s", CSV_PATH, file_name); char from[BUFFER_SIZE], to[BUFFER_SIZE]; char from_to_array[MAX_ARR_SIZE][BUFFER_SIZE] = {0}; size_t max_index = read_csv(input_path, from, to, from_to_array); // create output .h file - char h_path[BUFFER_SIZE]; + char h_path[PATH_MAX]; sprintf(h_path, "%s/%s_to_%s.h", OUT_PATH, from, to); create_h(h_path, from, to); // create output .c file - char c_path[BUFFER_SIZE]; + char c_path[PATH_MAX]; sprintf(c_path, "%s/%s_to_%s.c", OUT_PATH, from, to); create_c(c_path, h_path, from, to, from_to_array, max_index); } |
