progress
This commit is contained in:
parent
c0984b242e
commit
3e990ff05e
677
src/main.c
677
src/main.c
@ -17,10 +17,11 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
#include <stdlib.h>
|
||||
#include <dirent.h> // library für Interaktion mit Ordnerstrukturen
|
||||
#include <sys/stat.h> // library für is_directory: Unterscheidung zwischen Dateien und Ordnern
|
||||
#include <time.h> // um aktuelle Zeit zu generieren
|
||||
|
||||
#define MAX_LINE_LENGTH_BUF 2048
|
||||
#define INITIAL_ENTRIES 1000 // globale Variable zur initialen Speicherallokation in allocate_initial_memory(). Wird falls nötig um GROWTH_FACTOR erweitert
|
||||
#define GROWTH_FACTOR 2 // wird in mem_expand_dynamically() genutzt, um den Speicher zu vergrößern
|
||||
#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 1024 // das hohe Limit ist erforderlich, da teilweise ausufernde JSON-Requests in nginx auflaufen können.
|
||||
#define TOP_X 20 // definiert die Anzahl der Einträge, die in den Top-Listen angezeigt werden sollen
|
||||
@ -51,6 +52,8 @@ struct log_entry {
|
||||
struct simple_time time;
|
||||
char referrer[128];
|
||||
char user_agent[256];
|
||||
char source_file[256];
|
||||
char parsing_timestamp[32];
|
||||
};
|
||||
|
||||
// Struktur für einen Status-Filtereintrag mit Inhalt & Modus
|
||||
@ -222,7 +225,7 @@ void mem_expand_dynamically() {
|
||||
int old_max = max_entries;
|
||||
max_entries = max_entries * GROWTH_FACTOR;
|
||||
|
||||
printf("Dynamische Speichererweiterung von %d auf %d Einträge um Faktor %d\n", old_max, max_entries, GROWTH_FACTOR);
|
||||
printf("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));
|
||||
|
||||
@ -250,6 +253,20 @@ void allocate_initial_memory() {
|
||||
printf("Speicher erfolgreich alloziert für %d Log-Einträge (%lu Bytes)\n", max_entries, (unsigned long)(max_entries * sizeof(struct log_entry)));
|
||||
}
|
||||
|
||||
void get_current_timestamp(char* buffer, int buffer_size) {
|
||||
time_t raw_time;
|
||||
struct tm *time_info;
|
||||
|
||||
time(&raw_time);
|
||||
time_info = localtime(&raw_time);
|
||||
|
||||
if (time_info != NULL) {
|
||||
strftime(buffer, buffer_size, "%Y-%m-%d %H:%M:%S", time_info);
|
||||
} else {
|
||||
snprintf(buffer, buffer_size, "UNKNOWN");
|
||||
}
|
||||
}
|
||||
|
||||
// Hilfsfunktion zum Prüfen, ob es sich beim Pfad um ein Directory handelt - für rekursives Parsen
|
||||
int is_directory(char* path) {
|
||||
struct stat path_stat;
|
||||
@ -293,7 +310,7 @@ Fehleranfällig, wenn das Logformat nicht dem Standard entspricht - das gilt abe
|
||||
'"$http_user_agent" "$http_x_forwarded_for"';
|
||||
*/
|
||||
// 107.170.27.248 - - [31/Aug/2025:00:11:42 +0000] "GET /.git/config HTTP/1.1" 400 255 "-" "Mozilla/5.0; Keydrop.io/1.0(onlyscans.com/about);" "-"
|
||||
int parse_simple_log_line(char* line, int entry_index) { // Nimmt den Pointer auf die Zeile und einen Index entgegen - dieser ist anfangs 0 (globale Variable) und wird pro Eintrag inkrementiert
|
||||
int parse_simple_log_line(char* line, int entry_index, char* source_file) { // Nimmt den Pointer auf die Zeile und einen Index entgegen - dieser ist anfangs 0 (globale Variable) und wird pro Eintrag inkrementiert
|
||||
char* current_pos = line;
|
||||
// leere Zeichen am Anfang überspringen
|
||||
current_pos = skip_spaces(current_pos);
|
||||
@ -386,7 +403,6 @@ int parse_simple_log_line(char* line, int entry_index) { // Nimmt den Pointer au
|
||||
|
||||
current_pos = skip_spaces(current_pos);
|
||||
// Weiter mit dem String innerhalb "", aus dem die HTTP-Methode und der URL-Pfad zu entnehmen ist
|
||||
// Enhanced parsing to handle malformed binary requests gracefully
|
||||
if (*current_pos == '"') {
|
||||
current_pos++;
|
||||
// 107.170.27.248 - - [31/Aug/2025:00:11:42 +0000] "GET /.git/config HTTP/1.1" 400 255 "-" "Mozilla/5.0; Keydrop.io/1.0(onlyscans.com/about);" "-"
|
||||
@ -433,8 +449,8 @@ int parse_simple_log_line(char* line, int entry_index) { // Nimmt den Pointer au
|
||||
}
|
||||
} 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 "MALFORMED" repräsentiert
|
||||
strcpy(all_entries[entry_index].request_method, "MALFORMED");
|
||||
// der entsprechende Eintrag wird daher mit dem String "ATYPICAL" repräsentiert
|
||||
strcpy(all_entries[entry_index].request_method, "ATYPICAL");
|
||||
|
||||
// Read entire quoted content into url_path for forensic analysis
|
||||
int i = 0;
|
||||
@ -452,8 +468,6 @@ int parse_simple_log_line(char* line, int entry_index) { // Nimmt den Pointer au
|
||||
}
|
||||
|
||||
if (*current_pos == '"') current_pos++;
|
||||
|
||||
printf("INFO: Fehlerhaften Logeintrag entdeckt, speichere mit MALFORMED-Eintrag.\n");
|
||||
}
|
||||
// 107.170.27.248 - - [31/Aug/2025:00:11:42 +0000] "GET /.git/config HTTP/1.1" 400 255 "-" "Mozilla/5.0; Keydrop.io/1.0(onlyscans.com/about);" "-"
|
||||
// ^
|
||||
@ -512,30 +526,29 @@ int parse_simple_log_line(char* line, int entry_index) { // Nimmt den Pointer au
|
||||
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);\"\n\n");
|
||||
cleanup_and_exit();
|
||||
}
|
||||
return 1;
|
||||
get_current_timestamp(all_entries[entry_index].parsing_timestamp, sizeof(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
|
||||
all_entries[entry_index].source_file[sizeof(all_entries[entry_index].source_file) - 1] = '\0';
|
||||
}
|
||||
|
||||
// TODO
|
||||
void load_regular_file(char* filename) {
|
||||
FILE* file = fopen(filename, "r");
|
||||
if (file == NULL) {
|
||||
printf("ERROR: Kann Datei '%s' nicht öffnen!\n", filename);
|
||||
return;
|
||||
}
|
||||
|
||||
printf("Lade Datei: %s\n", filename);
|
||||
char line[MAX_LINE_LENGTH_BUF];
|
||||
int loaded_from_this_file = 0;
|
||||
|
||||
while (fgets(line, sizeof(line), file) != NULL) {
|
||||
mem_expand_dynamically();
|
||||
|
||||
if (parse_simple_log_line(line, total_entries)) {
|
||||
if (parse_simple_log_line(line, total_entries, filename)) {
|
||||
total_entries++;
|
||||
loaded_from_this_file++;
|
||||
}
|
||||
}
|
||||
|
||||
fclose(file);
|
||||
printf(" -> %d Einträge aus dieser Datei geladen.\n", loaded_from_this_file);
|
||||
}
|
||||
@ -960,276 +973,24 @@ int count_filtered_entries() {
|
||||
return count;
|
||||
}
|
||||
|
||||
void show_status() {
|
||||
printf("\n========== SYSTEM STATUS ==========\n");
|
||||
|
||||
if (total_entries > 0) {
|
||||
printf("✅ Log-Daten: %d Einträge geladen\n", total_entries);
|
||||
printf(" Speicherverbrauch: %lu Bytes (%d Einträge Kapazität)\n", (unsigned long)(max_entries * sizeof(struct log_entry)), max_entries);
|
||||
} else {
|
||||
printf("❌ Keine Log-Daten geladen\n");
|
||||
}
|
||||
|
||||
printf("\n🔍 Aktive Filter-Logik:\n");
|
||||
int total_filters = filters.status_count + filters.method_count + filters.ip_count + filters.time_count + filters.user_agent_count + filters.url_count;
|
||||
|
||||
if (total_filters == 0) {
|
||||
printf(" Keine Filter gesetzt → alle Einträge werden angezeigt\n");
|
||||
} else {
|
||||
printf(" Modus: %s\n", filters.combination_mode == 0 ? "AND" : "OR");
|
||||
printf(" Regel: Ausschlussfilter (!) haben Vorrang, dann Einschlussfilter\n");
|
||||
printf("\n Filter-Ausdruck:\n");
|
||||
|
||||
if (filters.status_count > 0) {
|
||||
printf(" Status: ");
|
||||
|
||||
int excludes = 0, includes = 0;
|
||||
for (int i = 0; i < filters.status_count; i++) {
|
||||
if (filters.status_filters[i].mode == FILTER_EXCLUDE) excludes++;
|
||||
else includes++;
|
||||
}
|
||||
|
||||
// Ausschlussfilter (immer im ODER-Modus)
|
||||
if (excludes > 0) {
|
||||
printf("!(");
|
||||
int first = 1;
|
||||
for (int i = 0; i < filters.status_count; i++) {
|
||||
if (filters.status_filters[i].mode == FILTER_EXCLUDE) {
|
||||
if (!first) printf(" OR ");
|
||||
printf("%d", filters.status_filters[i].code);
|
||||
first = 0;
|
||||
}
|
||||
}
|
||||
printf(")");
|
||||
if (includes > 0) printf(" AND ");
|
||||
}
|
||||
|
||||
// Einschlussfilter (folgen dem gesetzten Modus)
|
||||
if (includes > 0) {
|
||||
if (includes > 1) printf("(");
|
||||
int first = 1;
|
||||
for (int i = 0; i < filters.status_count; i++) {
|
||||
if (filters.status_filters[i].mode == FILTER_INCLUDE) {
|
||||
if (!first) printf(" %s ", filters.combination_mode == 0 ? "AND" : "OR");
|
||||
printf("%d", filters.status_filters[i].code);
|
||||
first = 0;
|
||||
}
|
||||
}
|
||||
if (includes > 1) printf(")");
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
if (filters.method_count > 0) {
|
||||
printf(" Method: ");
|
||||
|
||||
int excludes = 0, includes = 0;
|
||||
for (int i = 0; i < filters.method_count; i++) {
|
||||
if (filters.method_filters[i].mode == FILTER_EXCLUDE) excludes++;
|
||||
else includes++;
|
||||
}
|
||||
|
||||
if (excludes > 0) {
|
||||
printf("!(");
|
||||
int first = 1;
|
||||
for (int i = 0; i < filters.method_count; i++) {
|
||||
if (filters.method_filters[i].mode == FILTER_EXCLUDE) {
|
||||
if (!first) printf(" OR ");
|
||||
printf("%s", filters.method_filters[i].pattern);
|
||||
first = 0;
|
||||
}
|
||||
}
|
||||
printf(")");
|
||||
if (includes > 0) printf(" AND ");
|
||||
}
|
||||
|
||||
if (includes > 0) {
|
||||
if (includes > 1) printf("(");
|
||||
int first = 1;
|
||||
for (int i = 0; i < filters.method_count; i++) {
|
||||
if (filters.method_filters[i].mode == FILTER_INCLUDE) {
|
||||
if (!first) printf(" %s ", filters.combination_mode == 0 ? "AND" : "OR");
|
||||
printf("%s", filters.method_filters[i].pattern);
|
||||
first = 0;
|
||||
}
|
||||
}
|
||||
if (includes > 1) printf(")");
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
if (filters.ip_count > 0) {
|
||||
printf(" IP: ");
|
||||
|
||||
int excludes = 0, includes = 0;
|
||||
for (int i = 0; i < filters.ip_count; i++) {
|
||||
if (filters.ip_filters[i].mode == FILTER_EXCLUDE) excludes++;
|
||||
else includes++;
|
||||
}
|
||||
|
||||
if (excludes > 0) {
|
||||
printf("!(");
|
||||
int first = 1;
|
||||
for (int i = 0; i < filters.ip_count; i++) {
|
||||
if (filters.ip_filters[i].mode == FILTER_EXCLUDE) {
|
||||
if (!first) printf(" OR ");
|
||||
printf("%s", filters.ip_filters[i].ip_address);
|
||||
first = 0;
|
||||
}
|
||||
}
|
||||
printf(")");
|
||||
if (includes > 0) printf(" AND ");
|
||||
}
|
||||
|
||||
if (includes > 0) {
|
||||
if (includes > 1) printf("(");
|
||||
int first = 1;
|
||||
for (int i = 0; i < filters.ip_count; i++) {
|
||||
if (filters.ip_filters[i].mode == FILTER_INCLUDE) {
|
||||
if (!first) printf(" %s ", filters.combination_mode == 0 ? "AND" : "OR");
|
||||
printf("%s", filters.ip_filters[i].ip_address);
|
||||
first = 0;
|
||||
}
|
||||
}
|
||||
if (includes > 1) printf(")");
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
if (filters.user_agent_count > 0) {
|
||||
printf(" UserAgent: ");
|
||||
|
||||
int excludes = 0, includes = 0;
|
||||
for (int i = 0; i < filters.user_agent_count; i++) {
|
||||
if (filters.user_agent_filters[i].mode == FILTER_EXCLUDE) excludes++;
|
||||
else includes++;
|
||||
}
|
||||
|
||||
if (excludes > 0) {
|
||||
printf("!(");
|
||||
int first = 1;
|
||||
for (int i = 0; i < filters.user_agent_count; i++) {
|
||||
if (filters.user_agent_filters[i].mode == FILTER_EXCLUDE) {
|
||||
if (!first) printf(" OR ");
|
||||
printf("\"%s\"", filters.user_agent_filters[i].pattern);
|
||||
first = 0;
|
||||
}
|
||||
}
|
||||
printf(")");
|
||||
if (includes > 0) printf(" AND ");
|
||||
}
|
||||
|
||||
if (includes > 0) {
|
||||
if (includes > 1) printf("(");
|
||||
int first = 1;
|
||||
for (int i = 0; i < filters.user_agent_count; i++) {
|
||||
if (filters.user_agent_filters[i].mode == FILTER_INCLUDE) {
|
||||
if (!first) printf(" %s ", filters.combination_mode == 0 ? "AND" : "OR");
|
||||
printf("\"%s\"", filters.user_agent_filters[i].pattern);
|
||||
first = 0;
|
||||
}
|
||||
}
|
||||
if (includes > 1) printf(")");
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
if (filters.url_count > 0) {
|
||||
printf(" URL: ");
|
||||
|
||||
int excludes = 0, includes = 0;
|
||||
for (int i = 0; i < filters.url_count; i++) {
|
||||
if (filters.url_filters[i].mode == FILTER_EXCLUDE) excludes++;
|
||||
else includes++;
|
||||
}
|
||||
|
||||
if (excludes > 0) {
|
||||
printf("!(");
|
||||
int first = 1;
|
||||
for (int i = 0; i < filters.url_count; i++) {
|
||||
if (filters.url_filters[i].mode == FILTER_EXCLUDE) {
|
||||
if (!first) printf(" OR ");
|
||||
printf("\"%s\"", filters.url_filters[i].pattern);
|
||||
first = 0;
|
||||
}
|
||||
}
|
||||
printf(")");
|
||||
if (includes > 0) printf(" AND ");
|
||||
}
|
||||
|
||||
if (includes > 0) {
|
||||
if (includes > 1) printf("(");
|
||||
int first = 1;
|
||||
for (int i = 0; i < filters.url_count; i++) {
|
||||
if (filters.url_filters[i].mode == FILTER_INCLUDE) {
|
||||
if (!first) printf(" %s ", filters.combination_mode == 0 ? "AND" : "OR");
|
||||
printf("\"%s\"", filters.url_filters[i].pattern);
|
||||
first = 0;
|
||||
}
|
||||
}
|
||||
if (includes > 1) printf(")");
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
if (filters.time_count > 0) {
|
||||
printf(" Time: %d Filter(s) gesetzt\n", filters.time_count);
|
||||
}
|
||||
|
||||
// Zeigt aktuellen Modus
|
||||
int active_types = (filters.status_count > 0) + (filters.method_count > 0 ) + (filters.ip_count > 0) +
|
||||
(filters.user_agent_count > 0) + (filters.time_count > 0) + (filters.url_count > 0);
|
||||
if (active_types > 1) {
|
||||
printf("\n %s-Verknüpfung - Ausschlussfilter vorrangig\n",
|
||||
filters.combination_mode == 0 ? "UND" : "ODER");
|
||||
}
|
||||
}
|
||||
|
||||
if (total_entries > 0) {
|
||||
int filtered_count = count_filtered_entries();
|
||||
printf("\n📊 Ergebnis: %d von %d Einträgen entsprechen den Filtern\n", filtered_count, total_entries);
|
||||
}
|
||||
|
||||
printf("===================================\n");
|
||||
}
|
||||
|
||||
long long time_to_unix_microseconds(struct simple_time time) {
|
||||
int days_since_1970 = (time.year - 1970) * 365 + (time.year - 1970) / 4;
|
||||
|
||||
int days_in_months[] = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};
|
||||
if (time.month >= 1 && time.month <= 12) {
|
||||
days_since_1970 += days_in_months[time.month - 1];
|
||||
}
|
||||
|
||||
if (time.month > 2 && ((time.year % 4 == 0 && time.year % 100 != 0) || time.year % 400 == 0)) {
|
||||
days_since_1970 += 1;
|
||||
}
|
||||
|
||||
days_since_1970 += time.day - 1;
|
||||
|
||||
long long seconds = (long long)days_since_1970 * 24 * 60 * 60;
|
||||
seconds += time.hour * 60 * 60;
|
||||
seconds += time.minute * 60;
|
||||
seconds += time.second;
|
||||
|
||||
return seconds * 1000000LL;
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
//Export in Timesketch-kompatiblem Format
|
||||
void export_filtered_entries() {
|
||||
printf("Dateiname für Timesketch Export eingeben (ohne .csv): ");
|
||||
char filename[95];
|
||||
if (scanf("%94s", filename) != 1) {
|
||||
printf("Dateiname für Timesketch-Export eingeben (ohne .csv): ");
|
||||
//90 chars + delimiter
|
||||
char filename[91];
|
||||
if (scanf("%90s", filename) != 1) {
|
||||
printf("FEHLER: Ungültiger Dateiname!\n");
|
||||
clear_input_buffer();
|
||||
return;
|
||||
}
|
||||
clear_input_buffer();
|
||||
|
||||
// Dateiendung
|
||||
strcat(filename, ".csv");
|
||||
|
||||
FILE* file = fopen(filename, "w");
|
||||
@ -1238,7 +999,8 @@ void export_filtered_entries() {
|
||||
return;
|
||||
}
|
||||
|
||||
fprintf(file, "message,datetime,timestamp_desc,timestamp,ip_address,method,url_path,status_code,bytes_sent,user_agent\n");
|
||||
// CSV-Kopfzeile für Timesketch-Kompatibilität
|
||||
fprintf(file, "datetime,timestamp_desc,ip_address,method,url_path,status_code,bytes_sent,user_agent,source_file,parsing_timestamp\n");
|
||||
|
||||
int exported_count = 0;
|
||||
char iso_datetime[32];
|
||||
@ -1248,27 +1010,17 @@ void export_filtered_entries() {
|
||||
if (passes_filter(i)) {
|
||||
format_iso8601_time(all_entries[i].time, iso_datetime, sizeof(iso_datetime));
|
||||
|
||||
long long unix_timestamp = time_to_unix_microseconds(all_entries[i].time);
|
||||
|
||||
snprintf(message_text, sizeof(message_text),
|
||||
"%s %s %s - Status: %d, Bytes: %d",
|
||||
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);
|
||||
|
||||
fprintf(file, "\"%s\",\"%s\",\"HTTP Access Log\",%lld,\"%s\",\"%s\",\"%s\",%d,%d\n",
|
||||
message_text,
|
||||
fprintf(file, "\"%s\",\"HTTP Access Log\",\"%s\",\"%s\",\"%s\",%d,%d,\"%s\",\"%s\",\"%s\"\n",
|
||||
iso_datetime,
|
||||
unix_timestamp,
|
||||
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].user_agent,
|
||||
all_entries[i].source_file,
|
||||
all_entries[i].parsing_timestamp);
|
||||
|
||||
exported_count++;
|
||||
}
|
||||
@ -1397,13 +1149,34 @@ void show_top_user_agents() {
|
||||
}
|
||||
}
|
||||
|
||||
void show_filtered_entries() {
|
||||
void show_filtered_entries(int num_shown) {
|
||||
int shown_count = 0;
|
||||
|
||||
printf("\n=== GEFILTERTE LOG-EINTRÄGE ===\n");
|
||||
printf("\nLOGDATEN:\n");
|
||||
printf("IP-Adresse | Methode | URL | Status | Bytes | User Agent | Zeit\n");
|
||||
printf("-----------------|---------|------------------------|--------|-------|--------------------------------------|------------------\n");
|
||||
|
||||
if (num_shown != 0) {
|
||||
for (int i = 0; i < num_shown; i++) {
|
||||
if (passes_filter(i)) {
|
||||
printf("%-16s | %-7s | %-22s | %-6d | %-5d | %-36s | %02d.%02d.%d %02d:%02d:%02d\n",
|
||||
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].time.day,
|
||||
all_entries[i].time.month,
|
||||
all_entries[i].time.year,
|
||||
all_entries[i].time.hour,
|
||||
all_entries[i].time.minute,
|
||||
all_entries[i].time.second);
|
||||
|
||||
shown_count++;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < total_entries; i++) {
|
||||
if (passes_filter(i)) {
|
||||
printf("%-16s | %-7s | %-22s | %-6d | %-5d | %-36s | %02d.%02d.%d %02d:%02d:%02d\n",
|
||||
@ -1423,6 +1196,7 @@ void show_filtered_entries() {
|
||||
shown_count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
printf("\nInsgesamt %d Einträge gefunden.\n", shown_count);
|
||||
|
||||
@ -1431,6 +1205,241 @@ void show_filtered_entries() {
|
||||
}
|
||||
}
|
||||
|
||||
// Statusanzeige
|
||||
void show_status() {
|
||||
printf("PREVIEW:\n");
|
||||
show_filtered_entries(10);
|
||||
printf("\nSTATUS\n");
|
||||
|
||||
if (total_entries > 0) {
|
||||
printf(" %d Logzeilen in Datenstruktur\n", total_entries);
|
||||
printf(" Speicherbelegung: %lu Bytes\n", (unsigned long)(max_entries * sizeof(struct log_entry)));
|
||||
} else {
|
||||
printf(" ERROR: Keine Einträge in Datenstruktur!\n");
|
||||
}
|
||||
|
||||
printf("\n Aktive Filter:\n");
|
||||
int total_filters = filters.status_count + filters.method_count + filters.ip_count + filters.time_count + filters.user_agent_count + filters.url_count;
|
||||
|
||||
if (total_filters == 0) {
|
||||
printf(" -> keine Filter gesetzt\n");
|
||||
} else {
|
||||
printf(" Modus: %s\n", filters.combination_mode == 0 ? "AND" : "OR");
|
||||
printf(" Ausschlussfilter (!) haben Vorrang, dann Einschlussfilter\n");
|
||||
printf("\n Gesetzt:\n");
|
||||
|
||||
if (filters.status_count > 0) {
|
||||
printf(" -> Status: ");
|
||||
|
||||
int excludes = 0, includes = 0;
|
||||
for (int i = 0; i < filters.status_count; i++) {
|
||||
if (filters.status_filters[i].mode == FILTER_EXCLUDE) excludes++;
|
||||
else includes++;
|
||||
}
|
||||
|
||||
// Ausschlussfilter (immer im ODER-Modus)
|
||||
if (excludes > 0) {
|
||||
printf("!(");
|
||||
int first = 1;
|
||||
for (int i = 0; i < filters.status_count; i++) {
|
||||
if (filters.status_filters[i].mode == FILTER_EXCLUDE) {
|
||||
if (!first) printf(" OR ");
|
||||
printf("%d", filters.status_filters[i].code);
|
||||
first = 0;
|
||||
}
|
||||
}
|
||||
printf(")");
|
||||
if (includes > 0) printf(" AND ");
|
||||
}
|
||||
|
||||
// Einschlussfilter (folgen dem gesetzten Modus)
|
||||
if (includes > 0) {
|
||||
if (includes > 1) printf("(");
|
||||
int first = 1;
|
||||
for (int i = 0; i < filters.status_count; i++) {
|
||||
if (filters.status_filters[i].mode == FILTER_INCLUDE) {
|
||||
if (!first) printf(" %s ", filters.combination_mode == 0 ? "AND" : "OR");
|
||||
printf("%d", filters.status_filters[i].code);
|
||||
first = 0;
|
||||
}
|
||||
}
|
||||
if (includes > 1) printf(")");
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
if (filters.method_count > 0) {
|
||||
printf("Request-Method: ");
|
||||
|
||||
int excludes = 0, includes = 0;
|
||||
for (int i = 0; i < filters.method_count; i++) {
|
||||
if (filters.method_filters[i].mode == FILTER_EXCLUDE) excludes++;
|
||||
else includes++;
|
||||
}
|
||||
|
||||
if (excludes > 0) {
|
||||
printf("!(");
|
||||
int first = 1;
|
||||
for (int i = 0; i < filters.method_count; i++) {
|
||||
if (filters.method_filters[i].mode == FILTER_EXCLUDE) {
|
||||
if (!first) printf(" OR ");
|
||||
printf("%s", filters.method_filters[i].pattern);
|
||||
first = 0;
|
||||
}
|
||||
}
|
||||
printf(")");
|
||||
if (includes > 0) printf(" AND ");
|
||||
}
|
||||
|
||||
if (includes > 0) {
|
||||
if (includes > 1) printf("(");
|
||||
int first = 1;
|
||||
for (int i = 0; i < filters.method_count; i++) {
|
||||
if (filters.method_filters[i].mode == FILTER_INCLUDE) {
|
||||
if (!first) printf(" %s ", filters.combination_mode == 0 ? "AND" : "OR");
|
||||
printf("%s", filters.method_filters[i].pattern);
|
||||
first = 0;
|
||||
}
|
||||
}
|
||||
if (includes > 1) printf(")");
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
if (filters.ip_count > 0) {
|
||||
printf("IP-Adresse: ");
|
||||
|
||||
int excludes = 0, includes = 0;
|
||||
for (int i = 0; i < filters.ip_count; i++) {
|
||||
if (filters.ip_filters[i].mode == FILTER_EXCLUDE) excludes++;
|
||||
else includes++;
|
||||
}
|
||||
|
||||
if (excludes > 0) {
|
||||
printf("!(");
|
||||
int first = 1;
|
||||
for (int i = 0; i < filters.ip_count; i++) {
|
||||
if (filters.ip_filters[i].mode == FILTER_EXCLUDE) {
|
||||
if (!first) printf(" OR ");
|
||||
printf("%s", filters.ip_filters[i].ip_address);
|
||||
first = 0;
|
||||
}
|
||||
}
|
||||
printf(")");
|
||||
if (includes > 0) printf(" AND ");
|
||||
}
|
||||
|
||||
if (includes > 0) {
|
||||
if (includes > 1) printf("(");
|
||||
int first = 1;
|
||||
for (int i = 0; i < filters.ip_count; i++) {
|
||||
if (filters.ip_filters[i].mode == FILTER_INCLUDE) {
|
||||
if (!first) printf(" %s ", filters.combination_mode == 0 ? "AND" : "OR");
|
||||
printf("%s", filters.ip_filters[i].ip_address);
|
||||
first = 0;
|
||||
}
|
||||
}
|
||||
if (includes > 1) printf(")");
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
if (filters.user_agent_count > 0) {
|
||||
printf("UserAgent: ");
|
||||
|
||||
int excludes = 0, includes = 0;
|
||||
for (int i = 0; i < filters.user_agent_count; i++) {
|
||||
if (filters.user_agent_filters[i].mode == FILTER_EXCLUDE) excludes++;
|
||||
else includes++;
|
||||
}
|
||||
|
||||
if (excludes > 0) {
|
||||
printf("!(");
|
||||
int first = 1;
|
||||
for (int i = 0; i < filters.user_agent_count; i++) {
|
||||
if (filters.user_agent_filters[i].mode == FILTER_EXCLUDE) {
|
||||
if (!first) printf(" OR ");
|
||||
printf("\"%s\"", filters.user_agent_filters[i].pattern);
|
||||
first = 0;
|
||||
}
|
||||
}
|
||||
printf(")");
|
||||
if (includes > 0) printf(" AND ");
|
||||
}
|
||||
|
||||
if (includes > 0) {
|
||||
if (includes > 1) printf("(");
|
||||
int first = 1;
|
||||
for (int i = 0; i < filters.user_agent_count; i++) {
|
||||
if (filters.user_agent_filters[i].mode == FILTER_INCLUDE) {
|
||||
if (!first) printf(" %s ", filters.combination_mode == 0 ? "AND" : "OR");
|
||||
printf("\"%s\"", filters.user_agent_filters[i].pattern);
|
||||
first = 0;
|
||||
}
|
||||
}
|
||||
if (includes > 1) printf(")");
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
if (filters.url_count > 0) {
|
||||
printf("Payload/Pfad: ");
|
||||
|
||||
int excludes = 0, includes = 0;
|
||||
for (int i = 0; i < filters.url_count; i++) {
|
||||
if (filters.url_filters[i].mode == FILTER_EXCLUDE) excludes++;
|
||||
else includes++;
|
||||
}
|
||||
|
||||
if (excludes > 0) {
|
||||
printf("!(");
|
||||
int first = 1;
|
||||
for (int i = 0; i < filters.url_count; i++) {
|
||||
if (filters.url_filters[i].mode == FILTER_EXCLUDE) {
|
||||
if (!first) printf(" OR ");
|
||||
printf("\"%s\"", filters.url_filters[i].pattern);
|
||||
first = 0;
|
||||
}
|
||||
}
|
||||
printf(")");
|
||||
if (includes > 0) printf(" AND ");
|
||||
}
|
||||
|
||||
if (includes > 0) {
|
||||
if (includes > 1) printf("(");
|
||||
int first = 1;
|
||||
for (int i = 0; i < filters.url_count; i++) {
|
||||
if (filters.url_filters[i].mode == FILTER_INCLUDE) {
|
||||
if (!first) printf(" %s ", filters.combination_mode == 0 ? "AND" : "OR");
|
||||
printf("\"%s\"", filters.url_filters[i].pattern);
|
||||
first = 0;
|
||||
}
|
||||
}
|
||||
if (includes > 1) printf(")");
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
if (filters.time_count > 0) {
|
||||
printf("Zeitraum: %d Filter gesetzt\n", filters.time_count);
|
||||
}
|
||||
|
||||
// Zeigt aktuellen Modus
|
||||
int active_types = (filters.status_count > 0) + (filters.method_count > 0 ) + (filters.ip_count > 0) +
|
||||
(filters.user_agent_count > 0) + (filters.time_count > 0) + (filters.url_count > 0);
|
||||
if (active_types > 1) {
|
||||
printf("\n%s-Verknüpfung (nur Einschlussfilter)\n",
|
||||
filters.combination_mode == 0 ? "UND" : "ODER");
|
||||
}
|
||||
}
|
||||
|
||||
if (total_entries > 0) {
|
||||
int filtered_count = count_filtered_entries();
|
||||
printf("\n ERGEBNIS: \n %d von %d Einträgen entsprechen den Filtern\n", filtered_count, total_entries);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void show_statistics() {
|
||||
int count_200 = 0;
|
||||
int count_404 = 0;
|
||||
@ -1438,7 +1447,7 @@ void show_statistics() {
|
||||
int total_bytes = 0;
|
||||
int filtered_count = 0;
|
||||
|
||||
printf("\n=== STATISTIKEN ===\n");
|
||||
printf("\nSTATISTIKEN\n");
|
||||
|
||||
for (int i = 0; i < total_entries; i++) {
|
||||
if (passes_filter(i)) {
|
||||
@ -1465,52 +1474,52 @@ void show_statistics() {
|
||||
void print_filter_examples() {
|
||||
printf("\nFILTER-DOKUMENTATION\n");
|
||||
|
||||
printf("\n🔴 EXKLUSIONS-FILTER (immer OR-Logik, unabhängig vom Modus):\n");
|
||||
printf("\nEXKLUSIONS-FILTER (immer OR-Logik, unabhängig vom Modus):\n");
|
||||
printf("Beispiel: !('uptime' OR 'scanner')\n");
|
||||
printf("→ Schließt ALLE Einträge aus, die 'uptime' ODER 'scanner' enthalten\n\n");
|
||||
printf("> Schließt ALLE Einträge aus, die 'uptime' ODER 'scanner' enthalten\n\n");
|
||||
|
||||
printf("🟢 INKLUSIONS-FILTER im AND-Modus:\n");
|
||||
printf("INKLUSIONS-FILTER im AND-Modus:\n");
|
||||
printf("Beispiel: ('bot' AND 'crawl')\n");
|
||||
printf("→ Zeigt nur Einträge mit BEIDEN Begriffen\n\n");
|
||||
printf("> Zeigt nur Einträge mit BEIDEN Begriffen\n\n");
|
||||
|
||||
printf("🟡 INKLUSIONS-FILTER im OR-Modus:\n");
|
||||
printf("INKLUSIONS-FILTER im OR-Modus:\n");
|
||||
printf("Beispiel: ('bot' OR 'crawl')\n");
|
||||
printf("→ Zeigt Einträge mit 'bot' ODER 'crawl'\n\n");
|
||||
printf("> Zeigt Einträge mit 'bot' ODER 'crawl'\n\n");
|
||||
|
||||
printf("⚡ KOMBINATION: Exklusion + Inklusion:\n");
|
||||
printf("KOMBINATION: Exklusion + Inklusion:\n");
|
||||
printf("AND-Modus: !('uptime') AND ('bot' AND 'crawl')\n");
|
||||
printf("OR-Modus: !('uptime') AND ('bot' OR 'crawl')\n\n");
|
||||
|
||||
printf("🎯 PRAKTISCHE ANWENDUNGSFÄLLE:\n");
|
||||
printf("PRAKTISCHE ANWENDUNGSFÄLLE:\n");
|
||||
printf("Malware-Erkennung:\n");
|
||||
printf(" '.git' OR '.env' OR '/admin'\n");
|
||||
printf(" → Verdächtige Pfad-Zugriffe\n\n");
|
||||
printf(" > Verdächtige Pfad-Zugriffe\n\n");
|
||||
|
||||
printf("Bot-Traffic bereinigen:\n");
|
||||
printf(" !('bot') AND Status=200 AND Method='GET'\n");
|
||||
printf(" → Nur menschliche, erfolgreiche GET-Anfragen\n\n");
|
||||
printf(" > Nur menschliche, erfolgreiche GET-Anfragen\n\n");
|
||||
|
||||
printf("Zeitraum-Analyse:\n");
|
||||
printf(" Time='08:00-18:00' AND Status=500\n");
|
||||
printf(" → Server-Fehler nur während Geschäftszeiten\n\n");
|
||||
printf(" > Server-Fehler nur während Geschäftszeiten\n\n");
|
||||
|
||||
printf("DDoS-Verdacht:\n");
|
||||
printf(" Status=429 OR Status=503 OR Status=500\n");
|
||||
printf(" → Alle Überlastungs- und Fehler-Codes\n");
|
||||
printf(" > Alle Überlastungs- und Fehler-Codes\n");
|
||||
}
|
||||
|
||||
void menu_set_filters() {
|
||||
int choice = 0;
|
||||
while (choice != 7) {
|
||||
show_status();
|
||||
printf("\n=== FILTER SETZEN ===\n");
|
||||
printf("1. Status-Code Filter hinzufügen (exakte Suche)\n");
|
||||
printf("2. IP-Adresse Filter hinzufügen (exakte Suche)\n");
|
||||
printf("3. Zeitraum Filter hinzufügen (interaktiv)\n");
|
||||
printf("4. User-Agent-Filter setzen (Freitext)\n");
|
||||
printf("5. HTTP-Methode Filter hinzufügen (Freitext)\n");
|
||||
printf("6. URL-Pfad Filter hinzufügen (Freitext)\n");
|
||||
printf("7. Zurück zum Filter-Menü\n");
|
||||
printf("\nFILTER SETZEN\n");
|
||||
printf("1. Status-Code (exakte Suche)\n");
|
||||
printf("2. IP-Adresse (exakte Suche)\n");
|
||||
printf("3. Zeitraum (interaktiv)\n");
|
||||
printf("4. User-Agent (Freitext)\n");
|
||||
printf("5. HTTP-Methode (Freitext)\n");
|
||||
printf("6. URL-Pfad (Freitext)\n");
|
||||
printf("7. Zurück\n");
|
||||
printf("Auswahl: ");
|
||||
|
||||
choice = read_safe_integer();
|
||||
@ -1536,7 +1545,7 @@ void menu_set_filters() {
|
||||
filters.status_filters[filters.status_count].code = status;
|
||||
filters.status_filters[filters.status_count].mode = (filter_type == 2) ? FILTER_EXCLUDE : FILTER_INCLUDE;
|
||||
filters.status_count++;
|
||||
printf("✅ Status-Code Filter hinzugefügt. Total: %d\n", filters.status_count);
|
||||
printf(">Status-Code Filter hinzugefügt. Total: %d\n", filters.status_count);
|
||||
} else {
|
||||
printf("FEHLER: Ungültiger Filter-Typ!\n");
|
||||
}
|
||||
@ -1561,7 +1570,7 @@ void menu_set_filters() {
|
||||
strcpy(filters.ip_filters[filters.ip_count].ip_address, ip);
|
||||
filters.ip_filters[filters.ip_count].mode = (filter_type == 2) ? FILTER_EXCLUDE : FILTER_INCLUDE;
|
||||
filters.ip_count++;
|
||||
printf("✅ IP-Filter hinzugefügt. Total: %d\n", filters.ip_count);
|
||||
printf(">IP-Filter hinzugefügt. Total: %d\n", filters.ip_count);
|
||||
} else {
|
||||
printf("FEHLER: Ungültiger Filter-Typ!\n");
|
||||
}
|
||||
@ -1679,7 +1688,7 @@ void menu_set_filters() {
|
||||
filters.time_filters[filters.time_count] = new_time_filter;
|
||||
filters.time_count++;
|
||||
|
||||
printf("✅ Zeitraum-Filter hinzugefügt. Total: %d\n", filters.time_count);
|
||||
printf(">Zeitraum-Filter hinzugefügt. Total: %d\n", filters.time_count);
|
||||
|
||||
} else if (choice == 4) {
|
||||
if (filters.user_agent_count >= MAX_FILTERS) {
|
||||
@ -1700,7 +1709,7 @@ void menu_set_filters() {
|
||||
strcpy(filters.user_agent_filters[filters.user_agent_count].pattern, pattern);
|
||||
filters.user_agent_filters[filters.user_agent_count].mode = (filter_type == 2) ? FILTER_EXCLUDE : FILTER_INCLUDE;
|
||||
filters.user_agent_count++;
|
||||
printf("✅ User-Agent Filter hinzugefügt. Total: %d\n", filters.user_agent_count);
|
||||
printf(">User-Agent Filter hinzugefügt. Total: %d\n", filters.user_agent_count);
|
||||
} else {
|
||||
printf("FEHLER: Ungültiger Filter-Typ!\n");
|
||||
}
|
||||
@ -1715,7 +1724,7 @@ void menu_set_filters() {
|
||||
continue;
|
||||
}
|
||||
|
||||
printf("HTTP-Methode eingeben (z.B. 'GET', 'POST', 'PUT', ... Sonderwert 'MALFORMED'): ");
|
||||
printf("HTTP-Methode eingeben (z.B. 'GET', 'POST', 'PUT', ... Sonderwert 'ATYPICAL'): ");
|
||||
char pattern[10];
|
||||
if (scanf("%9s", pattern) == 1) {
|
||||
printf("Filter-Typ wählen:\n");
|
||||
@ -1728,7 +1737,7 @@ void menu_set_filters() {
|
||||
strcpy(filters.method_filters[filters.method_count].pattern, pattern);
|
||||
filters.method_filters[filters.method_count].mode = (filter_type == 2) ? FILTER_EXCLUDE : FILTER_INCLUDE;
|
||||
filters.method_count++;
|
||||
printf("✅ Method-Filter hinzugefügt. Total: %d\n", filters.method_count);
|
||||
printf(">Method-Filter hinzugefügt. Total: %d\n", filters.method_count);
|
||||
} else {
|
||||
printf("FEHLER: Ungültiger Filter-Typ!\n");
|
||||
}
|
||||
@ -1756,7 +1765,7 @@ void menu_set_filters() {
|
||||
strcpy(filters.url_filters[filters.url_count].pattern, pattern);
|
||||
filters.url_filters[filters.url_count].mode = (filter_type == 2) ? FILTER_EXCLUDE : FILTER_INCLUDE;
|
||||
filters.url_count++;
|
||||
printf("✅ URL-Filter hinzugefügt. Total: %d\n", filters.url_count);
|
||||
printf(">URL-Filter hinzugefügt. Total: %d\n", filters.url_count);
|
||||
} else {
|
||||
printf("FEHLER: Ungültiger Filter-Typ!\n");
|
||||
}
|
||||
@ -1781,7 +1790,7 @@ void menu_delete_filters() {
|
||||
return;
|
||||
}
|
||||
|
||||
printf("\n=== FILTER LÖSCHEN ===\n");
|
||||
printf("\nFILTER LÖSCHEN\n");
|
||||
printf("Aktuell gesetzte Filter:\n");
|
||||
|
||||
int filter_index = 1;
|
||||
@ -1830,7 +1839,7 @@ void menu_delete_filters() {
|
||||
mode_str);
|
||||
}
|
||||
|
||||
printf("Welchen Filter möchten Sie löschen (1-%d) oder 0 für Abbrechen: ", total_filters);
|
||||
printf("Auswahl: (1-%d) oder 0 für Abbrechen: ", total_filters);
|
||||
int choice = read_safe_integer();
|
||||
|
||||
if (choice == 0) {
|
||||
@ -1850,7 +1859,7 @@ void menu_delete_filters() {
|
||||
filters.status_filters[j] = filters.status_filters[j + 1];
|
||||
}
|
||||
filters.status_count--;
|
||||
printf("✅ Status-Code Filter gelöscht.\n");
|
||||
printf(">Status-Code Filter gelöscht.\n");
|
||||
return;
|
||||
}
|
||||
current_index++;
|
||||
@ -1862,7 +1871,7 @@ void menu_delete_filters() {
|
||||
filters.method_filters[j] = filters.method_filters[j + 1];
|
||||
}
|
||||
filters.method_count--;
|
||||
printf("✅ Method-Filter gelöscht.\n");
|
||||
printf(">Method-Filter gelöscht.\n");
|
||||
return;
|
||||
}
|
||||
current_index++;
|
||||
@ -1874,7 +1883,7 @@ void menu_delete_filters() {
|
||||
filters.ip_filters[j] = filters.ip_filters[j + 1];
|
||||
}
|
||||
filters.ip_count--;
|
||||
printf("✅ IP-Filter gelöscht.\n");
|
||||
printf(">IP-Filter gelöscht.\n");
|
||||
return;
|
||||
}
|
||||
current_index++;
|
||||
@ -1886,7 +1895,7 @@ void menu_delete_filters() {
|
||||
filters.user_agent_filters[j] = filters.user_agent_filters[j + 1];
|
||||
}
|
||||
filters.user_agent_count--;
|
||||
printf("✅ User-Agent Filter gelöscht.\n");
|
||||
printf(">User-Agent Filter gelöscht.\n");
|
||||
return;
|
||||
}
|
||||
current_index++;
|
||||
@ -1898,7 +1907,7 @@ void menu_delete_filters() {
|
||||
filters.url_filters[j] = filters.url_filters[j + 1];
|
||||
}
|
||||
filters.url_count--;
|
||||
printf("✅ URL-Filter gelöscht.\n");
|
||||
printf(">URL-Filter gelöscht.\n");
|
||||
return;
|
||||
}
|
||||
current_index++;
|
||||
@ -1910,7 +1919,7 @@ void menu_delete_filters() {
|
||||
filters.time_filters[j] = filters.time_filters[j + 1];
|
||||
}
|
||||
filters.time_count--;
|
||||
printf("✅ Zeitraum-Filter gelöscht.\n");
|
||||
printf(">Zeitraum-Filter gelöscht.\n");
|
||||
return;
|
||||
}
|
||||
current_index++;
|
||||
@ -1918,7 +1927,7 @@ void menu_delete_filters() {
|
||||
}
|
||||
|
||||
void menu_filter_mode() {
|
||||
printf("=== FILTER-MODUS ===\n");
|
||||
printf("FILTER-MODUS\n");
|
||||
printf("Aktueller Modus: %s\n", filters.combination_mode == 0 ? "AND" : "OR");
|
||||
printf("\nACHTUNG:\n");
|
||||
printf("Der Modus wirkt sich nur auf inklusive Filter aus.\n");
|
||||
@ -1932,10 +1941,10 @@ void menu_filter_mode() {
|
||||
|
||||
if (choice == 1) {
|
||||
filters.combination_mode = 0;
|
||||
printf("✅ Filter-Modus auf AND gesetzt.\n");
|
||||
printf(">Filter-Modus auf AND gesetzt.\n");
|
||||
} else if (choice == 2) {
|
||||
filters.combination_mode = 1;
|
||||
printf("✅ Filter-Modus auf OR gesetzt.\n");
|
||||
printf(">Filter-Modus auf OR gesetzt.\n");
|
||||
} else if (choice == 3) {
|
||||
print_filter_examples();
|
||||
} else if (choice != -1) {
|
||||
@ -1952,7 +1961,7 @@ void menu_reset_filters() {
|
||||
filters.url_count = 0;
|
||||
filters.combination_mode = 0;
|
||||
|
||||
printf("✅ Alle Filter zurückgesetzt.\n");
|
||||
printf(">Alle Filter zurückgesetzt.\n");
|
||||
}
|
||||
|
||||
void menu_filter_management() {
|
||||
@ -2014,7 +2023,7 @@ void menu_show_entries() {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
show_filtered_entries();
|
||||
show_filtered_entries(0);
|
||||
} else if (choice == 2) {
|
||||
export_filtered_entries();
|
||||
} else if (choice == 3) {
|
||||
@ -2051,7 +2060,7 @@ int main(int argc, char* argv[]) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("=== NGINX LOG PARSER - VEREINFACHTE VERSION ===\n");
|
||||
printf("NGINX EXAMINATOR\n");
|
||||
allocate_initial_memory();
|
||||
|
||||
load_log_file(argv[1]);
|
||||
@ -2080,7 +2089,7 @@ int main(int argc, char* argv[]) {
|
||||
} else if (choice == 3) {
|
||||
show_statistics();
|
||||
} else if (choice == 4) {
|
||||
printf("Auf Wiedersehen!\n");
|
||||
printf("Programmende\n");
|
||||
} else {
|
||||
printf("Ungültige Auswahl! Bitte wählen Sie 1-4.\n");
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user