This commit is contained in:
overcuriousity 2025-09-01 16:29:43 +02:00
parent 3d11d2f0f2
commit e567bdbc65

View File

@ -625,114 +625,162 @@ int search_in_string(const char* raw_string, const char* search_string) {
// Filterfunktion für den User-Agent. Nimmt den Datensatz entgegen und prüft gegen die gesetzten Filter, gibt dann 0 oder 1 zurück // Filterfunktion für den User-Agent. Nimmt den Datensatz entgegen und prüft gegen die gesetzten Filter, gibt dann 0 oder 1 zurück
int user_agent_matches(char* user_agent) { int user_agent_matches(char* user_agent) {
if (filters.user_agent_count == 0) return 1; if (filters.user_agent_count == 0) return 1;
// Ausschluss-Filter geht vor
int has_include_filters = 0; for (int i = 0; i < filters.user_agent_count; i++) {
int include_match = 0; if (filters.user_agent_filters[i].mode == FILTER_EXCLUDE) {
int pattern_found = search_in_string(user_agent, filters.user_agent_filters[i].pattern);
if (pattern_found) {
return 0; // früheres Verlassen der Schleife, sobald Ausschlussfilter zutrifft
}
}
}
// Prüfung im entsprechenden Modus
int include_count = 0;
int include_matches = 0;
for (int i = 0; i < filters.user_agent_count; i++) { for (int i = 0; i < filters.user_agent_count; i++) {
int pattern_found = search_in_string(user_agent, filters.user_agent_filters[i].pattern);
if (filters.user_agent_filters[i].mode == FILTER_INCLUDE) { if (filters.user_agent_filters[i].mode == FILTER_INCLUDE) {
has_include_filters = 1; include_count++;
int pattern_found = search_in_string(user_agent, filters.user_agent_filters[i].pattern);
if (pattern_found) { if (pattern_found) {
include_match = 1; include_matches++;
if (filters.combination_mode == 1) { // OR-Modus
return 1; // Früheres Verlassen der Schleife bei erstem zutreffendem Einschlussfilter im OR-Modus
} }
} else { // ausschließen-Filter
if (pattern_found) {
return 0;
} }
} }
} }
if (has_include_filters) { // Diese Prüfung wird ausgeführt, wenn Einschlussfilter vorhanden sind
return include_match; if (include_count > 0) {
if (filters.combination_mode == 0) { // AND-Modus
return include_matches == include_count; // Alle Einschlussfilter müssen zutreffen, die Treffer müssen Anzahl der Filter entsprechen
} else { // OR-Modus
return include_matches > 0; // Ausschlussfilter im ODER-Modus - wenn ein beliebiger Eintrag zum Ausschlussfilter passt, wird 0=negativ zurückgegeben
}
} }
return 1; return 1; // Keine Einschlussfilter, keine zutreffenden Ausschlussfilter, positiver Rückgabewert =1
} }
int status_code_matches(int status_code) { int status_code_matches(int status_code) {
if (filters.status_count == 0) return 1; if (filters.status_count == 0) return 1;
// Ausschluss-Filter prüfen: immer übergeordnet gültig
int has_include_filters = 0;
int include_match = 0;
for (int i = 0; i < filters.status_count; i++) { for (int i = 0; i < filters.status_count; i++) {
if (filters.status_filters[i].mode == FILTER_INCLUDE) { if (filters.status_filters[i].mode == FILTER_EXCLUDE) {
has_include_filters = 1;
if (filters.status_filters[i].code == status_code) {
include_match = 1;
}
} else {
if (filters.status_filters[i].code == status_code) { if (filters.status_filters[i].code == status_code) {
return 0; return 0;
} }
} }
} }
if (has_include_filters) { // Filter prüfen in entsprechendem Modus
return include_match; int include_count = 0;
int include_matches = 0;
for (int i = 0; i < filters.status_count; i++) {
if (filters.status_filters[i].mode == FILTER_INCLUDE) {
include_count++;
if (filters.status_filters[i].code == status_code) {
include_matches++;
if (filters.combination_mode == 1) { // OR-Modus
return 1; // positiver Rückgabewert, Schleife wird verlassen sobald erster Treffer im OR-Modus
}
}
}
} }
return 1; // Diese Prüfung wird ausgeführt, wenn Einschlussfilter vorhanden sind
if (include_count > 0) {
if (filters.combination_mode == 0) { // UND-Modus
return include_matches == include_count; // Filter-Treffer müssen der Anzahl der Statuscode-Filter entsprechen
} else { // OR-Modus
return include_matches > 0; // Ausschlussfilter im ODER-Modus - wenn ein beliebiger Eintrag zum Ausschlussfilter passt, wird 0=negativ zurückgegeben
}
}
return 1; // Keine Einschlussfilter, keine Treffer in den Ausschlussfiltern, positiver Rückgabewert = 1
} }
int ip_address_matches(char* ip_address) { int ip_address_matches(char* ip_address) {
if (filters.ip_count == 0) return 1; if (filters.ip_count == 0) return 1;
int has_include_filters = 0; // Prüfen der Ausschlussfilter, sind dem Rest vorgelagert
int include_match = 0; for (int i = 0; i < filters.ip_count; i++) {
if (filters.ip_filters[i].mode == FILTER_EXCLUDE) {
if (strcmp(filters.ip_filters[i].ip_address, ip_address) == 0) {
return 0; // zutreffender Ausschlussfilter führt zu negativem Rückgabewert
}
}
}
// Prüfung im AND oder im OR-Modus
int include_count = 0;
int include_matches = 0;
for (int i = 0; i < filters.ip_count; i++) { for (int i = 0; i < filters.ip_count; i++) {
if (filters.ip_filters[i].mode == FILTER_INCLUDE) { if (filters.ip_filters[i].mode == FILTER_INCLUDE) {
has_include_filters = 1; include_count++;
if (strcmp(filters.ip_filters[i].ip_address, ip_address) == 0) { if (strcmp(filters.ip_filters[i].ip_address, ip_address) == 0) {
include_match = 1; include_matches++;
if (filters.combination_mode == 1) { // OR-Modus
return 1; // Früheres Verlassen der Schleife, sofern erster Filter im OR-Modus zutrifft
} }
} else {
if (strcmp(filters.ip_filters[i].ip_address, ip_address) == 0) {
return 0;
} }
} }
} }
if (has_include_filters) { // Diese Prüfung wird ausgeführt, wenn Einschlussfilter vorhanden sind
return include_match; if (include_count > 0) {
if (filters.combination_mode == 0) { // UND-Modus
return include_matches == include_count; // Filter-Treffer müssen der Anzahl der IP-Adressen-Filter entsprechen
} else { // OR-Modus
return include_matches > 0; // zutreffender Ausschlussfilter führt zu negativem Rückgabewert
} }
}
return 1; return 1; // Keine Einschlussfilter, keine Treffer in den Ausschlussfiltern, positiver Rückgabewert = 1
} }
// Vergleicht einen übergebenen Prüfwert für einen Zeitstempel mit dem aktuell gesetzten Filter. Wenn der Prüfwert im Filterbereich ist,wird 1 zurückgegeben. // Vergleicht einen übergebenen Prüfwert für einen Zeitstempel mit dem aktuell gesetzten Filter. Wenn der Prüfwert im Filterbereich ist,wird 1 zurückgegeben.
int time_matches(struct simple_time entry_time) { int time_matches(struct simple_time entry_time) {
// gibt 1 zurück, wenn kein Filter gesetzt wird -> der komplette Log-Datensatz wird ausgegeben
if (filters.time_count == 0) return 1; if (filters.time_count == 0) return 1;
int has_include_filters = 0; // Übergeordneter Ausschlussfilter
int include_match = 0;
// es können mehrere Filter gleichzeitig gesetzt sein, diese werden alle nacheinander in einer Schleife geprüft
for (int i = 0; i < filters.time_count; i++) { for (int i = 0; i < filters.time_count; i++) {
if (filters.time_filters[i].mode == FILTER_EXCLUDE) {
int in_range = (compare_times(entry_time, filters.time_filters[i].start_time) >= 0 && int in_range = (compare_times(entry_time, filters.time_filters[i].start_time) >= 0 &&
compare_times(entry_time, filters.time_filters[i].end_time) <= 0); // gibt 0=false zurück, wenn der Prüfwert nicht im Filterbereich ist compare_times(entry_time, filters.time_filters[i].end_time) <= 0);
if (in_range) {
return 0; // zutreffender Ausschlussfilter führt zu negativem Rückgabewert, ist den Einschlussfiltern übergeordnet
}
}
}
// Prüfung im entsprechenden Modus
int include_count = 0;
int include_matches = 0;
for (int i = 0; i < filters.time_count; i++) {
if (filters.time_filters[i].mode == FILTER_INCLUDE) { if (filters.time_filters[i].mode == FILTER_INCLUDE) {
has_include_filters = 1; // Flag für inlusive Filter include_count++;
int in_range = (compare_times(entry_time, filters.time_filters[i].start_time) >= 0 &&
compare_times(entry_time, filters.time_filters[i].end_time) <= 0);
if (in_range) { if (in_range) {
include_match = 1; // gibt 1=true aus, wenn der Prüfwert in den geprüften inklusiven Filter passt include_matches++;
if (filters.combination_mode == 1) { // OR-Modus
return 1; // Sobald der erste Zeitraum im OR-Modus zutrifft, wird die Schleife verlassen
} }
// ausschließen-Filter
} else {
if (in_range) {
return 0; // gibt 0=false aus, wenn der geprüfte Filter exklusiv ist, und der Prüfwert in den Filterbereich passt
} }
} }
} }
if (has_include_filters) { // Diese Prüfung wird ausgeführt, wenn Einschlussfilter vorhanden sind
return include_match; // gibt 0=false aus, wenn es inklusive Filter gibt (has_include_filters =1), aber kein Zeitstempel in den Filterbereich passt if (include_count > 0) {
if (filters.combination_mode == 0) { // AND-Modus
return include_matches == include_count; // Filter-Treffer müssen der Anzahl der Zeitraum-Filter entsprechen
} else { // OR-Modus
return include_matches > 0; // zutreffender Ausschlussfilter führt zu negativem Rückgabewert
} }
}
return 1; return 1; // keine Einschlussfilter und keine zutreffenden Ausschlussfilter - positiver Rückgabewert
} }
// Prüfen aller Filter im AND-Modus oder OR-Modus (combination_mode) pro Log-Eintrag // Prüfen aller Filter im AND-Modus oder OR-Modus (combination_mode) pro Log-Eintrag
@ -772,64 +820,142 @@ void show_status() {
printf("❌ Keine Log-Daten geladen\n"); printf("❌ Keine Log-Daten geladen\n");
} }
printf("\n🔍 Aktive Filter:\n"); printf("\n🔍 Aktive Filter-Logik:\n");
int total_filters = filters.status_count + filters.ip_count + filters.time_count + filters.user_agent_count; // UPDATE THIS LINE int total_filters = filters.status_count + filters.ip_count + filters.time_count + filters.user_agent_count;
if (total_filters == 0) { if (total_filters == 0) {
printf(" Keine Filter gesetzt\n"); printf(" Keine Filter gesetzt → alle Einträge werden angezeigt\n");
printf(" Filter-Modus: %s\n", filters.combination_mode == 0 ? "AND" : "OR");
} else { } else {
printf(" Filter-Modus: %s\n", filters.combination_mode == 0 ? "AND" : "OR"); 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) { if (filters.status_count > 0) {
printf(" Status-Codes (%d): ", filters.status_count); printf(" Status: ");
int excludes = 0, includes = 0;
for (int i = 0; i < filters.status_count; i++) { for (int i = 0; i < filters.status_count; i++) {
char mode_char = (filters.status_filters[i].mode == FILTER_EXCLUDE) ? '!' : ' '; if (filters.status_filters[i].mode == FILTER_EXCLUDE) excludes++;
printf("%c%d", mode_char, filters.status_filters[i].code); else includes++;
if (i < filters.status_count - 1) printf(", "); }
// 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"); printf("\n");
} }
if (filters.ip_count > 0) { if (filters.ip_count > 0) {
printf(" IP-Adressen (%d): ", filters.ip_count); printf(" IP: ");
int excludes = 0, includes = 0;
for (int i = 0; i < filters.ip_count; i++) { for (int i = 0; i < filters.ip_count; i++) {
char mode_char = (filters.ip_filters[i].mode == FILTER_EXCLUDE) ? '!' : ' '; if (filters.ip_filters[i].mode == FILTER_EXCLUDE) excludes++;
printf("%c%s", mode_char, filters.ip_filters[i].ip_address); else includes++;
if (i < filters.ip_count - 1) printf(", "); }
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"); printf("\n");
} }
if (filters.user_agent_count > 0) { if (filters.user_agent_count > 0) {
printf(" User-Agent Pattern (%d): ", filters.user_agent_count); printf(" UserAgent: ");
int excludes = 0, includes = 0;
for (int i = 0; i < filters.user_agent_count; i++) { for (int i = 0; i < filters.user_agent_count; i++) {
char mode_char = (filters.user_agent_filters[i].mode == FILTER_EXCLUDE) ? '!' : ' '; if (filters.user_agent_filters[i].mode == FILTER_EXCLUDE) excludes++;
printf("%c\"%s\"", mode_char, filters.user_agent_filters[i].pattern); else includes++;
if (i < filters.user_agent_count - 1) printf(", "); }
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"); printf("\n");
} }
if (filters.time_count > 0) { if (filters.time_count > 0) {
printf(" Zeiträume (%d):\n", filters.time_count); printf(" Time: %d Filter(s) gesetzt\n", filters.time_count);
for (int i = 0; i < filters.time_count; i++) {
char mode_char = (filters.time_filters[i].mode == FILTER_EXCLUDE) ? '!' : ' ';
printf(" %c%02d.%02d.%d %02d:%02d:%02d - %02d.%02d.%d %02d:%02d:%02d\n",
mode_char,
filters.time_filters[i].start_time.day,
filters.time_filters[i].start_time.month,
filters.time_filters[i].start_time.year,
filters.time_filters[i].start_time.hour,
filters.time_filters[i].start_time.minute,
filters.time_filters[i].start_time.second,
filters.time_filters[i].end_time.day,
filters.time_filters[i].end_time.month,
filters.time_filters[i].end_time.year,
filters.time_filters[i].end_time.hour,
filters.time_filters[i].end_time.minute,
filters.time_filters[i].end_time.second);
} }
// Zeigt aktuellen Modus
int active_types = (filters.status_count > 0) + (filters.ip_count > 0) +
(filters.user_agent_count > 0) + (filters.time_count > 0);
if (active_types > 1) {
printf("\n %s-Verknüpfung - Ausschlussfilter vorrangig\n",
filters.combination_mode == 0 ? "UND" : "ODER");
} }
} }
@ -1054,7 +1180,7 @@ void show_filtered_entries() {
for (int i = 0; i < total_entries; i++) { for (int i = 0; i < total_entries; i++) {
if (passes_filter(i)) { if (passes_filter(i)) {
printf("%-16s | %-7s | %-22s | %-6d | %-5d | %02d.%02d.%d %02d:%02d:%02d\n", printf("%-16s | %-7s | %-22s | %-6d | %-5d | %-36s | %02d.%02d.%d %02d:%02d:%02d\n",
all_entries[i].ip_address, all_entries[i].ip_address,
all_entries[i].request_method, all_entries[i].request_method,
all_entries[i].url_path, all_entries[i].url_path,
@ -1327,7 +1453,7 @@ void menu_set_filters() {
} }
void menu_delete_filters() { void menu_delete_filters() {
int total_filters = filters.status_count + filters.ip_count + filters.time_count + filters.user_agent_count; // UPDATE THIS LINE int total_filters = filters.status_count + filters.ip_count + filters.time_count + filters.user_agent_count;
if (total_filters == 0) { if (total_filters == 0) {
printf("Keine Filter gesetzt zum Löschen.\n"); printf("Keine Filter gesetzt zum Löschen.\n");
@ -1437,10 +1563,14 @@ void menu_delete_filters() {
} }
void menu_filter_mode() { void menu_filter_mode() {
printf("\n=== FILTER-MODUS ===\n"); printf("=== FILTER-MODUS ===\n");
printf("Aktueller Modus: %s\n", filters.combination_mode == 0 ? "AND (alle müssen zutreffen)" : "OR (einer muss zutreffen)"); printf("Aktueller Modus: %s\n", filters.combination_mode == 0 ? "AND" : "OR");
printf("1. AND-Modus (alle Filter müssen zutreffen)\n"); printf("\nDieser Modus bestimmt:\n");
printf("2. OR-Modus (mindestens ein Filter muss zutreffen)\n"); printf("1. Wie mehrere Filter desselben Typs kombiniert werden\n");
printf("2. Wie verschiedene Filter-Typen kombiniert werden\n");
printf("\nBeispiele:\n");
printf("AND: IP=1.2.3.4 UND User-Agent=mozilla (beide müssen zutreffen)\n");
printf("OR: IP=1.2.3.4 ODER User-Agent=mozilla (einer muss zutreffen)\n");
printf("Auswahl: "); printf("Auswahl: ");
int choice = read_safe_integer(); int choice = read_safe_integer();
@ -1514,7 +1644,7 @@ void menu_show_entries() {
if (choice == 1) { if (choice == 1) {
if (filtered_count > 1000) { if (filtered_count > 1000) {
printf("WARNUNG: %d Einträge sind sehr viele für die Anzeige!\n", filtered_count); printf("WARNUNG: Die Anzeige von %d Einträgen ist in der Kommandozeile nur schlecht darstellbar.\n", filtered_count);
printf("Möchten Sie trotzdem fortfahren? (1=Ja, 0=Nein): "); printf("Möchten Sie trotzdem fortfahren? (1=Ja, 0=Nein): ");
int confirm = read_safe_integer(); int confirm = read_safe_integer();
if (confirm != 1) { if (confirm != 1) {