src/main.c aktualisiert
This commit is contained in:
222
src/main.c
222
src/main.c
@@ -30,9 +30,10 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
#define GROWTH_FACTOR 1.1 // wird in mem_expand_dynamically() genutzt, um den Speicher zu vergrößern
|
||||
#define MAX_FILTERS 100
|
||||
#define MAX_REQUEST_LENGTH 8192 // das hohe Limit ist erforderlich, da teilweise ausufernde JSON-Requests in nginx auflaufen können.
|
||||
#define MAX_PREVIEW 10000
|
||||
|
||||
// struct für die Darstellung von Timestamps. Die granulare Trennung in verschiedene int-Werte macht die spätere Verarbeitung modular anpassbar/erweiterbar und erleichtert die Verarbeitung.
|
||||
struct simple_time {
|
||||
struct simple_time_t {
|
||||
int day;
|
||||
int month;
|
||||
int year;
|
||||
@@ -42,13 +43,13 @@ struct simple_time {
|
||||
};
|
||||
|
||||
// Struktur für die Darstellung eines Standard-NGINX-Logeintrags.
|
||||
struct log_entry {
|
||||
struct log_entry_t {
|
||||
char ip_address[50]; // ausreichende Längenbegrenzung für IP-Adressen. Könnte theoretisch auch ipv6 (ungetestet)
|
||||
char request_method[10]; // GET, POST, PUT, DELETE, PROPFIND ...
|
||||
char url_path[MAX_REQUEST_LENGTH]; // Pfade können lang werden, insbesodere bei base64-Strings wie oft in Malware verwendet
|
||||
int status_code;
|
||||
int bytes_sent;
|
||||
struct simple_time time;
|
||||
struct simple_time_t time;
|
||||
char referrer[128];
|
||||
char user_agent[256];
|
||||
char source_file[256];
|
||||
@@ -56,57 +57,57 @@ struct log_entry {
|
||||
};
|
||||
|
||||
// Struktur für einen Status-Filtereintrag mit Inhalt & Modus
|
||||
struct status_filter {
|
||||
struct status_filter_t {
|
||||
int code;
|
||||
int filter_exclude_flag;
|
||||
};
|
||||
|
||||
struct method_filter {
|
||||
struct method_filter_t {
|
||||
char pattern[10];
|
||||
int filter_exclude_flag;
|
||||
};
|
||||
|
||||
// für IP-Adressen
|
||||
struct ip_filter {
|
||||
struct ip_filter_t {
|
||||
char ip_address[50];
|
||||
int filter_exclude_flag;
|
||||
};
|
||||
|
||||
// Filter für User-Agent
|
||||
struct user_agent_filter {
|
||||
struct user_agent_filter_t {
|
||||
char pattern[256];
|
||||
int filter_exclude_flag;
|
||||
};
|
||||
|
||||
// Filter für URL-Pfad/Request
|
||||
struct url_filter {
|
||||
struct url_filter_t {
|
||||
char pattern[MAX_REQUEST_LENGTH];
|
||||
int filter_exclude_flag;
|
||||
};
|
||||
|
||||
// Struktur zum erhalten aller Filtereinträge, kann im Dialogbetrieb bearbeitet werden. Mit Zähler.
|
||||
struct filter_system {
|
||||
struct status_filter status_filters[MAX_FILTERS];
|
||||
struct filter_system_t {
|
||||
struct status_filter_t status_filters[MAX_FILTERS];
|
||||
int status_count;
|
||||
|
||||
struct method_filter method_filters[MAX_FILTERS];
|
||||
struct method_filter_t method_filters[MAX_FILTERS];
|
||||
int method_count;
|
||||
|
||||
struct ip_filter ip_filters[MAX_FILTERS];
|
||||
struct ip_filter_t ip_filters[MAX_FILTERS];
|
||||
int ip_count;
|
||||
|
||||
struct user_agent_filter user_agent_filters[MAX_FILTERS];
|
||||
struct user_agent_filter_t user_agent_filters[MAX_FILTERS];
|
||||
int user_agent_count;
|
||||
|
||||
struct url_filter url_filters[MAX_FILTERS];
|
||||
struct url_filter_t url_filters[MAX_FILTERS];
|
||||
int url_count;
|
||||
};
|
||||
|
||||
// Initialisierung eines Arrays für die Logeinträge und weiterer Startvariablen
|
||||
struct log_entry *all_entries = NULL;
|
||||
struct log_entry_t *all_entries = NULL;
|
||||
int max_entries = 0;
|
||||
int total_entries = 0;
|
||||
struct filter_system filters = {0};
|
||||
struct filter_system_t filters = {0};
|
||||
// für -v option
|
||||
int flag_verbose = 0;
|
||||
|
||||
@@ -160,7 +161,7 @@ int month_name_to_number(char* month_name) {
|
||||
// Speicher freigeben und mit 0 überschreiben (Prävention von use-after-free-Schwachstelle)
|
||||
void cleanup_memory(){
|
||||
if (all_entries != NULL){
|
||||
printf("\nDEBUG: %lu Bytes Speicher werden freigegeben\n", (unsigned long)(max_entries * sizeof(struct log_entry)));
|
||||
printf("\nDEBUG: %lu Bytes Speicher werden freigegeben\n", (unsigned long)(max_entries * sizeof(struct log_entry_t)));
|
||||
free(all_entries);
|
||||
all_entries = NULL;
|
||||
}
|
||||
@@ -191,47 +192,49 @@ void mem_expand_dynamically(){
|
||||
|
||||
if (flag_verbose) printf("DEBUG: Dynamische Speichererweiterung von %d auf %d Einträge um Faktor %f\n", old_max, max_entries, GROWTH_FACTOR);
|
||||
|
||||
struct log_entry *new_ptr = realloc(all_entries, max_entries * sizeof(struct log_entry));
|
||||
struct log_entry_t *new_ptr = realloc(all_entries, max_entries * sizeof(struct log_entry_t));
|
||||
|
||||
if (new_ptr == NULL){
|
||||
printf("ERROR: Speicher konnte nicht auf %d Einträge erweitert werden, ..\n", max_entries);
|
||||
printf("ERROR: Benötigter Speicher: %lu Bytes\n", (unsigned long)(max_entries * sizeof(struct log_entry)));
|
||||
printf("ERROR: Benötigter Speicher: %lu Bytes\n", (unsigned long)(max_entries * sizeof(struct log_entry_t)));
|
||||
cleanup_and_exit();
|
||||
}
|
||||
|
||||
all_entries = new_ptr;
|
||||
if (flag_verbose) printf("DEBUG: Speicher erfolgreich erweitert auf %lu Bytes\n", (unsigned long)(max_entries * sizeof(struct log_entry)));
|
||||
if (flag_verbose) printf("DEBUG: Speicher erfolgreich erweitert auf %lu Bytes\n", (unsigned long)(max_entries * sizeof(struct log_entry_t)));
|
||||
}
|
||||
}
|
||||
|
||||
void allocate_initial_memory(){
|
||||
max_entries = INITIAL_ENTRIES; // Startwert 1000, globale Variable
|
||||
all_entries = malloc(max_entries * sizeof(struct log_entry));
|
||||
all_entries = malloc(max_entries * sizeof(struct log_entry_t));
|
||||
|
||||
if (all_entries == NULL){
|
||||
printf("ERROR: Konnte %d Einträge nicht allozieren, ..\n", max_entries);
|
||||
printf("ERROR: %lu Bytes\n", (unsigned long)(max_entries * sizeof(struct log_entry)));
|
||||
printf("ERROR: %lu Bytes\n", (unsigned long)(max_entries * sizeof(struct log_entry_t)));
|
||||
exit(1); // cleanup_and_exit() nicht nötig, da der Speicherbereich nicht beschrieben wurde - use-after-free unproblematisch
|
||||
}
|
||||
|
||||
if (flag_verbose) printf("DEBUG: Speicher erfolgreich alloziert für %d Log-Einträge (%lu Bytes)\n", max_entries, (unsigned long)(max_entries * sizeof(struct log_entry)));
|
||||
if (flag_verbose) printf("DEBUG: Speicher erfolgreich alloziert für %d Log-Einträge (%lu Bytes)\n", max_entries, (unsigned long)(max_entries * sizeof(struct log_entry_t)));
|
||||
}
|
||||
|
||||
void get_current_timestamp(char* buffer, int buffer_size) {
|
||||
// aktuelle Timestamp erfassen
|
||||
void get_current_timestamp(char* buffer){
|
||||
time_t raw_time;
|
||||
struct tm *time_info;
|
||||
|
||||
int timestamp_buffer_size =32;
|
||||
time(&raw_time);
|
||||
time_info = localtime(&raw_time);
|
||||
|
||||
if (time_info != NULL){
|
||||
strftime(buffer, buffer_size, "%Y-%m-%d %H:%M:%S", time_info);
|
||||
strftime(buffer, timestamp_buffer_size, "%Y-%m-%d %H:%M:%S", time_info);
|
||||
} else {
|
||||
snprintf(buffer, buffer_size, "UNKNOWN");
|
||||
sprintf(buffer, "UNKNOWN");
|
||||
}
|
||||
}
|
||||
|
||||
// Hilfsfunktion zum Prüfen, ob es sich beim Pfad um ein Directory handelt - für rekursives Parsen
|
||||
// https://stackoverflow.com/questions/4553012/checking-if-a-file-is-a-directory-or-just-a-file
|
||||
int is_directory(char* path){
|
||||
struct stat path_stat;
|
||||
if (stat(path, &path_stat) != 0){
|
||||
@@ -438,7 +441,7 @@ int parse_simple_log_line(char* line, int entry_index, char* source_file) { // N
|
||||
|
||||
if (is_valid_method){
|
||||
// Normal parsen: HTTP-Methode bis zum nächsten Leerzeichen einlesen und speichern
|
||||
strcpy(all_entries[entry_index].request_method, temp_method);
|
||||
strncpy(all_entries[entry_index].request_method, temp_method,sizeof(all_entries[entry_index].request_method));
|
||||
while (*current_pos != ' ' && *current_pos != '\0'){
|
||||
current_pos++;
|
||||
}
|
||||
@@ -461,15 +464,17 @@ int parse_simple_log_line(char* line, int entry_index, char* source_file) { // N
|
||||
} else {
|
||||
// in NGINX treten gelegentlich fehlerhafte Requests auf, die binäre Daten übersenden, sodass normales parsen nicht möglich ist.
|
||||
// der entsprechende Eintrag wird daher mit dem String "ATYPICAL" repräsentiert
|
||||
// strcpy reicht hier aus, da der Wert "ATYPICAL" hard-gecoded und somit deterministisch ist"
|
||||
strcpy(all_entries[entry_index].request_method, "ATYPICAL");
|
||||
|
||||
// Read entire quoted content into url_path for forensic analysis
|
||||
// Kompletten Inhalt zwischen "" einlesen
|
||||
int i = 0;
|
||||
while (*current_pos != '"' && *current_pos != '\0' && i < sizeof(all_entries[entry_index].url_path) - 1){
|
||||
all_entries[entry_index].url_path[i] = *current_pos;
|
||||
i++;
|
||||
current_pos++;
|
||||
}
|
||||
// Nullterminator anfügen
|
||||
all_entries[entry_index].url_path[i] = '\0';
|
||||
|
||||
// zum Ende des request-strings vorarbeiten, wenn der String zu lang war.
|
||||
@@ -507,19 +512,23 @@ int parse_simple_log_line(char* line, int entry_index, char* source_file) { // N
|
||||
}
|
||||
current_pos = skip_spaces(current_pos);
|
||||
|
||||
// Parsen des Referrer-Feldes innerhalb "", wird übersprungen da nicht gespeichert
|
||||
// Parsen des Referrer-Feldes innerhalb ""
|
||||
if (*current_pos == '"'){
|
||||
current_pos++; // öffnendes Anführungszeichen überspringen
|
||||
// Referrer-Inhalt bis zum schließenden Anführungszeichen überspringen
|
||||
while (*current_pos != '"' && *current_pos != '\0') {
|
||||
// Referrer-Inhalt zwischen "" einlesen
|
||||
int i = 0;
|
||||
while (*current_pos != '"' && *current_pos != '\0' && i < sizeof(all_entries[entry_index].referrer) - 1){
|
||||
all_entries[entry_index].referrer[i] = *current_pos;
|
||||
i++;
|
||||
current_pos++;
|
||||
}
|
||||
all_entries[entry_index].referrer[i] = '\0';
|
||||
|
||||
if (*current_pos == '"') current_pos++; // schließendes Anführungszeichen überspringen
|
||||
} else {
|
||||
printf("ERROR: Unerwartetes Log-Format. Lediglich mit standard-nginx-accesslog kompatibel.\nDer Fehler ist beim Prüfen des Referrer-Feldes aufgetreten.\nLogeintrag: %s\n", line);
|
||||
cleanup_and_exit();
|
||||
}
|
||||
|
||||
current_pos = skip_spaces(current_pos);
|
||||
// parsen des user agents innerhalb ""
|
||||
if (*current_pos == '"'){
|
||||
@@ -536,7 +545,7 @@ int parse_simple_log_line(char* line, int entry_index, char* source_file) { // N
|
||||
printf("ERROR: Unerwartetes Log-Format. Lediglich mit standard-nginx-accesslog kompatibel.\nDer Fehler ist beim Prüfen des User-Agent aufgetreten. Dieser steht innerhalb eines Strings:\n\"Mozilla/5.0; Keydrop.io/1.0(onlyscans.com/about);\"\nLogeintrag: %s\n", line);
|
||||
cleanup_and_exit();
|
||||
}
|
||||
get_current_timestamp(all_entries[entry_index].parsing_timestamp, sizeof(all_entries[entry_index].parsing_timestamp));
|
||||
get_current_timestamp(all_entries[entry_index].parsing_timestamp);
|
||||
// Dateinamen in das Feld schreiben - strncpy um Buffer overflow zu verhindern
|
||||
strncpy(all_entries[entry_index].source_file, source_file, sizeof(all_entries[entry_index].source_file) - 1);
|
||||
// strncpy setzt keinen Nullterminator, dieser muss am Ende eingefügt werden
|
||||
@@ -637,11 +646,11 @@ void load_log_file(char* path) {
|
||||
int needs_slash = (path_len > 0 && path[path_len - 1] != '/');
|
||||
|
||||
if (is_log_file(filename)){
|
||||
(needs_slash) ? snprintf(full_path, sizeof(full_path), "%s/%s", path, filename) : snprintf(full_path, sizeof(full_path), "%s%s", path, filename);
|
||||
(needs_slash) ? sprintf(full_path, "%s/%s", path, filename) : sprintf(full_path, "%s%s", path, filename);
|
||||
load_regular_file(full_path);
|
||||
files_found++;
|
||||
} else if (strstr(filename, ".gz") != NULL){
|
||||
(needs_slash) ? snprintf(full_path, sizeof(full_path), "%s/%s", path, filename) : snprintf(full_path, sizeof(full_path), "%s%s", path, filename);
|
||||
(needs_slash) ? sprintf(full_path, "%s/%s", path, filename) : sprintf(full_path, "%s%s", path, filename);
|
||||
load_gz_file(full_path);
|
||||
files_found++;
|
||||
}
|
||||
@@ -665,7 +674,7 @@ void load_log_file(char* path) {
|
||||
|
||||
printf("INFO: Erfolgreich %d Einträge insgesamt geladen.\n", total_entries);
|
||||
if (flag_verbose) printf("DEBUG: Aktueller Speicherverbrauch: %lu Bytes für %d Einträge\n",
|
||||
(unsigned long)(max_entries * sizeof(struct log_entry)), max_entries);
|
||||
(unsigned long)(max_entries * sizeof(struct log_entry_t)), max_entries);
|
||||
}
|
||||
|
||||
// Filterfunktion für den User-Agent. Nimmt den Datensatz entgegen und prüft gegen die gesetzten Filter, gibt dann 0 oder 1 zurück
|
||||
@@ -822,10 +831,34 @@ int count_filtered_entries(){
|
||||
}
|
||||
|
||||
// notwendig, um konformes Timestamp-Format aus simple_time struct zu generieren. Unterstützt derzeit nur UTC
|
||||
void format_iso8601_time(struct simple_time time, char* buffer, int buffer_size) {
|
||||
snprintf(buffer, buffer_size, "%04d-%02d-%02dT%02d:%02d:%02d+00:00", time.year, time.month, time.day, time.hour, time.minute, time.second);
|
||||
void format_datetime(struct simple_time_t time, char* buffer){
|
||||
sprintf(buffer, "%04d-%02d-%02dT%02d:%02d:%02d+00:00", time.year, time.month, time.day, time.hour, time.minute, time.second);
|
||||
}
|
||||
|
||||
void show_preview(){
|
||||
char datetime[32];
|
||||
int lines_shown = 0;
|
||||
int count_filtered =0;
|
||||
printf("\n");
|
||||
printf("| TIMESTAMP | IP-Adresse | HTTP-METHODE | PFAD/PAYLOAD | USERAGENT | STATUSCODE | BYTES | REFERRER |\n");
|
||||
printf("|---------------------|-----------------|--------------|--------------------------------|----------------------|------------|----------|----------------------|\n");
|
||||
|
||||
for (int i = 0; i < MAX_PREVIEW; i++){
|
||||
if (passes_filter(i)){
|
||||
format_datetime(all_entries[i].time, datetime);
|
||||
printf("| %-19.19s | %-15.15s | %-12.12s | %-30.30s | %-20.20s | %-10d | %-8d | %-20.20s |\n", datetime, all_entries[i].ip_address, all_entries[i].request_method, all_entries[i].url_path, all_entries[i].user_agent, all_entries[i].status_code, all_entries[i].bytes_sent, all_entries[i].referrer);
|
||||
lines_shown++;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < total_entries; i++){
|
||||
if (passes_filter(i)){
|
||||
count_filtered++;
|
||||
}
|
||||
}
|
||||
printf("\n%d Zeilen von insgesamt %d Einträgen(gefiltert) angezeigt.\nInsgesamt %d Einträge im Datensatz.\n", lines_shown, total_entries, count_filtered);
|
||||
}
|
||||
|
||||
|
||||
void export_filtered_entries(char *filepath){
|
||||
// 90 chars +delimiter
|
||||
char filename[91];
|
||||
@@ -836,6 +869,7 @@ void export_filtered_entries(char *filepath) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
// buffer overflow verhindern
|
||||
strncpy(filename, filepath, sizeof(filename) - 1);
|
||||
filename[sizeof(filename) - 1] = '\0';
|
||||
}
|
||||
@@ -851,12 +885,12 @@ void export_filtered_entries(char *filepath) {
|
||||
// CSV-Kopfzeile für Timesketch-Kompatibilität
|
||||
fprintf(file, "datetime,message,timestamp_desc,ip_address,method,url_path,status_code,bytes_sent,user_agent,parsing_timestamp\n");
|
||||
|
||||
char iso_datetime[32];
|
||||
char datetime[32];
|
||||
|
||||
for (int i = 0; i < total_entries; i++){
|
||||
if (passes_filter(i)){
|
||||
format_iso8601_time(all_entries[i].time, iso_datetime, sizeof(iso_datetime));
|
||||
fprintf(file, "%s,%s,\"NGINX Log\",%s,%s,%s,%d,%d,%s,%s\n", iso_datetime, all_entries[i].source_file, all_entries[i].ip_address, all_entries[i].request_method, all_entries[i].url_path, all_entries[i].status_code, all_entries[i].bytes_sent, all_entries[i].user_agent, all_entries[i].parsing_timestamp);
|
||||
format_datetime(all_entries[i].time, datetime);
|
||||
fprintf(file, "%s,%s,\"NGINX Log\",%s,%s,%s,%d,%d,%s,%s,%s\n", datetime, all_entries[i].source_file, all_entries[i].ip_address, all_entries[i].request_method, all_entries[i].url_path, all_entries[i].status_code, all_entries[i].bytes_sent, all_entries[i].user_agent, all_entries[i].referrer,all_entries[i].parsing_timestamp);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -902,7 +936,7 @@ void apply_ip_filter(char* value, int filter_exclude_flag) {
|
||||
}
|
||||
|
||||
// setzen des Filters
|
||||
strcpy(filters.ip_filters[filters.ip_count].ip_address, value);
|
||||
strncpy(filters.ip_filters[filters.ip_count].ip_address, value,sizeof(filters.ip_filters[filters.ip_count].ip_address));
|
||||
filters.ip_filters[filters.ip_count].filter_exclude_flag = filter_exclude_flag;
|
||||
filters.ip_count++;
|
||||
|
||||
@@ -921,7 +955,7 @@ void apply_method_filter(char* value, int filter_exclude_flag) {
|
||||
return;
|
||||
}
|
||||
|
||||
strcpy(filters.method_filters[filters.method_count].pattern, value);
|
||||
strncpy(filters.method_filters[filters.method_count].pattern,value, sizeof(filters.method_filters[filters.method_count].pattern));
|
||||
filters.method_filters[filters.method_count].filter_exclude_flag = filter_exclude_flag;
|
||||
filters.method_count++;
|
||||
|
||||
@@ -940,7 +974,7 @@ void apply_useragent_filter(char* value, int filter_exclude_flag) {
|
||||
return;
|
||||
}
|
||||
|
||||
strcpy(filters.user_agent_filters[filters.user_agent_count].pattern, value);
|
||||
strncpy(filters.user_agent_filters[filters.user_agent_count].pattern, value,sizeof(filters.user_agent_filters[filters.user_agent_count].pattern));
|
||||
filters.user_agent_filters[filters.user_agent_count].filter_exclude_flag = filter_exclude_flag;
|
||||
filters.user_agent_count++;
|
||||
|
||||
@@ -959,7 +993,7 @@ void apply_url_filter(char* value, int filter_exclude_flag) {
|
||||
return;
|
||||
}
|
||||
|
||||
strcpy(filters.url_filters[filters.url_count].pattern, value);
|
||||
strncpy(filters.url_filters[filters.url_count].pattern, value,sizeof(filters.url_filters[filters.url_count].pattern));
|
||||
filters.url_filters[filters.url_count].filter_exclude_flag = filter_exclude_flag;
|
||||
filters.url_count++;
|
||||
|
||||
@@ -1054,6 +1088,7 @@ void print_help(char* binary) {
|
||||
printf("NGINX-Auditor (Beleg)\n");
|
||||
printf("Nutzung: %s <LOGFILE|VERZEICHNIS> [Flags]\n\n", binary);
|
||||
printf("Flags:\n");
|
||||
printf(" -i [Logfile|Verzeichnis] Optional Eingabe definieren - Datei oder Verzeichnis; Standard /var/log/nginx\n");
|
||||
printf(" -e [Dateiname ohne Endung] Export zu Timestamp-kompatiblem CSV\n");
|
||||
printf(" -f --[Filterobjekt] Filtern mit den folgenden Optionen:\n");
|
||||
printf(" --status=[HTTP-Statuscode],[Weiterer],[...] HTTP Status Codes, z.B. 200, 404,301,...\n");
|
||||
@@ -1068,82 +1103,65 @@ void print_help(char* binary) {
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]){
|
||||
if (argc < 2) {
|
||||
print_help(argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("\nNGINX EXAMINATOR\n");
|
||||
|
||||
// Dateipfad: wenn nicht angegeben, wird /var/log/nginx (Standardpfad) untersucht
|
||||
char* input_path;
|
||||
int arg_offset = 1; // Offset für die args
|
||||
|
||||
// Prüfen des ersten Zeichens des ersten Arguments - Pfad oder Flag?
|
||||
if (argv[1][0] == '-') {
|
||||
// Ist ein Flag - Standardpfad, Offset bleibt bei 1
|
||||
input_path = "/var/log/nginx/";
|
||||
arg_offset = 1;
|
||||
} else {
|
||||
input_path = argv[1];
|
||||
arg_offset = 2; // Offset inkrementieren, Dateipfad schiebt die args nach hinten
|
||||
}
|
||||
char* input_path = "/var/log/nginx"; // Standardpfad
|
||||
char export_filename[50];
|
||||
int flag_export = 0;
|
||||
int flag_help = 0;
|
||||
// int flag_verbose = 0; - global definiert
|
||||
|
||||
char export_filename[90];
|
||||
int flag_has_filename = 0;
|
||||
|
||||
int flag_filter =0;
|
||||
int flag_has_export_filename = 0;
|
||||
int flag_showpreview =0;
|
||||
allocate_initial_memory();
|
||||
|
||||
if (argc >= 2){
|
||||
// hier wird das offset angewendet
|
||||
for (int i=arg_offset; i<argc; i++) {
|
||||
if (strcmp(argv[i], "-e")==0) {
|
||||
for (int i=1; i<argc; i++){
|
||||
if (i==0){
|
||||
continue;
|
||||
}
|
||||
if (starts_with(argv[i], "-i")){
|
||||
if (!starts_with(argv[i+1], "-")&& i+1<argc){
|
||||
input_path = argv[i+1];
|
||||
}
|
||||
}
|
||||
if (starts_with(argv[i], "-e")){
|
||||
flag_export =1;
|
||||
if (i+1<argc && argv[i+1][0]!='-'){
|
||||
if (!starts_with(argv[i+1], "-")&& i+1<argc){
|
||||
strncpy(export_filename, argv[i + 1], sizeof(export_filename) - 1);
|
||||
flag_has_filename = 1;
|
||||
i++; // Schleife weiter iterieren
|
||||
}
|
||||
} else if (strcmp(argv[i], "-f")==0) {
|
||||
// parsen der nachfolgenden Argumente --ip= usw.
|
||||
for (int j = i + 1; j < argc; j++) {
|
||||
if (starts_with(argv[j], "--")) {
|
||||
parse_filter_argument(argv[j]);
|
||||
}else{
|
||||
break;
|
||||
flag_has_export_filename =1;
|
||||
}
|
||||
}
|
||||
|
||||
} else if (strcmp(argv[i], "-h")==0) {
|
||||
flag_help = 1;
|
||||
} else if (strcmp(argv[i], "-v")==0) {
|
||||
flag_verbose = 1;
|
||||
if (starts_with(argv[i], "-f")){
|
||||
flag_filter = 1;
|
||||
}
|
||||
if (starts_with(argv[i], "--")){
|
||||
parse_filter_argument(argv[i]);
|
||||
}
|
||||
if (starts_with(argv[i], "-v")){
|
||||
flag_verbose =1; // globale Variable oben definiert
|
||||
}
|
||||
|
||||
// Aktionen basierend auf gesetzten flags ausführen
|
||||
if (flag_help == 1){
|
||||
if (starts_with(argv[i], "-s")){
|
||||
flag_showpreview =1;
|
||||
printf("Flag for show prewview set\n");
|
||||
}
|
||||
if (starts_with(argv[i], "-h")){
|
||||
print_help(argv[0]);
|
||||
return 1;
|
||||
} else if (flag_export == 1) {
|
||||
}
|
||||
}
|
||||
|
||||
load_log_file(input_path);
|
||||
if (flag_has_filename == 1) {
|
||||
if (flag_export ==1){
|
||||
if (flag_has_export_filename){
|
||||
export_filtered_entries(export_filename);
|
||||
} else {
|
||||
export_filtered_entries(NULL);
|
||||
}
|
||||
} else {
|
||||
// Standard-Verhalten: Logs laden und Zusammenfassung anzeigen
|
||||
load_log_file(input_path);
|
||||
int filtered_count = count_filtered_entries();
|
||||
printf("Geladen: %d Einträge, %d entsprechen den Filtern. Nutzen Sie -e zum Exportieren.\n",
|
||||
total_entries, filtered_count);
|
||||
printf("Geladen: %d Einträge, %d entsprechen den Filtern. Nutzen Sie -e zum Exportieren.\n", total_entries, filtered_count);
|
||||
}
|
||||
if (flag_showpreview==1){
|
||||
printf("should show preview here\n");
|
||||
show_preview();
|
||||
}
|
||||
|
||||
cleanup_memory();
|
||||
printf("INFO: Ausführung beendet.\n");
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user