progress
This commit is contained in:
		
							parent
							
								
									76b8da4685
								
							
						
					
					
						commit
						bf2249fa7b
					
				
							
								
								
									
										110
									
								
								src/main.c
									
									
									
									
									
								
							
							
						
						
									
										110
									
								
								src/main.c
									
									
									
									
									
								
							@ -20,7 +20,7 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#define MAX_LINE_LENGTH_BUF 2048
 | 
					#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 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 expand_memory_if_needed() genutzt, um den Speicher zu vergrößern
 | 
					#define GROWTH_FACTOR 2 // wird in mem_expand_dynamically() genutzt, um den Speicher zu vergrößern
 | 
				
			||||||
#define MAX_FILTERS 100
 | 
					#define MAX_FILTERS 100
 | 
				
			||||||
#define MAX_URL_PATH_LENGTH 512
 | 
					#define MAX_URL_PATH_LENGTH 512
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -89,12 +89,12 @@ int max_entries = 0;
 | 
				
			|||||||
int total_entries = 0;
 | 
					int total_entries = 0;
 | 
				
			||||||
struct filter_system filters = {0};
 | 
					struct filter_system filters = {0};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Helper für die Erkennung von Leerzeichen
 | 
					// Hilfsfunktion für die Erkennung von Leerzeichen
 | 
				
			||||||
int is_space(char c) {
 | 
					int is_space(char c) {
 | 
				
			||||||
    return (c == ' ' || c == '\t');
 | 
					    return (c == ' ' || c == '\t');
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Helper zum Überspringen von Leerzeichen, gibt den Pointer für das nächste nicht-Leerzeichen zurück. Nötig für strtok-Parser.
 | 
					// Hilfsfunktion zum Überspringen von Leerzeichen, gibt den Pointer für das nächste nicht-Leerzeichen zurück. Nötig für Parser.
 | 
				
			||||||
char* skip_spaces(char* str) {
 | 
					char* skip_spaces(char* str) {
 | 
				
			||||||
    while (is_space(*str)) {
 | 
					    while (is_space(*str)) {
 | 
				
			||||||
        str++;
 | 
					        str++;
 | 
				
			||||||
@ -102,7 +102,7 @@ char* skip_spaces(char* str) {
 | 
				
			|||||||
    return str;
 | 
					    return str;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// TODO
 | 
					// Kopiert einen Eingabestring von einem Quellbereich zu einem Zielbereich, bis ein Leerzeichen (oder Nullterminator) erreicht wird
 | 
				
			||||||
void copy_until_space(char* destination, char* source, int max_length) {
 | 
					void copy_until_space(char* destination, char* source, int max_length) {
 | 
				
			||||||
    int i = 0;
 | 
					    int i = 0;
 | 
				
			||||||
    while (source[i] != ' ' && source[i] != '\0' && i < max_length - 1) {
 | 
					    while (source[i] != ' ' && source[i] != '\0' && i < max_length - 1) {
 | 
				
			||||||
@ -129,38 +129,49 @@ int month_name_to_number(char* month_name) {
 | 
				
			|||||||
    return 1;
 | 
					    return 1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int compare_times(struct simple_time time1, struct simple_time time2) {
 | 
					// Vergleich von Zeitstempel-Strukturen - time_checkvalue ist der Prüfwert, time_filtervalue ist der Vergleichswert (Filter) - Funktion wird in time_matches() aufgerufen
 | 
				
			||||||
    if (time1.year != time2.year) return (time1.year < time2.year) ? -1 : 1;
 | 
					int compare_times(struct simple_time time_checkvalue, struct simple_time time_filtervalue) {
 | 
				
			||||||
    if (time1.month != time2.month) return (time1.month < time2.month) ? -1 : 1;
 | 
					    /* 
 | 
				
			||||||
    if (time1.day != time2.day) return (time1.day < time2.day) ? -1 : 1;
 | 
					    Rückgabewert 1 -> Prüfwert ist NACH dem Vergleichswert
 | 
				
			||||||
    if (time1.hour != time2.hour) return (time1.hour < time2.hour) ? -1 : 1;
 | 
					    Es wird erst das Jahr geprüft, dann der Monat u.s.w. 
 | 
				
			||||||
    if (time1.minute != time2.minute) return (time1.minute < time2.minute) ? -1 : 1;
 | 
					    Ist ein Wert gleich, wird der nächstfeinere Wert geprüft. 
 | 
				
			||||||
    if (time1.second != time2.second) return (time1.second < time2.second) ? -1 : 1;
 | 
					    Sobald die Werte sich unterscheiden, findet die Prüfung statt und ein Rückgabewert wird ausgegeben.
 | 
				
			||||||
 | 
					    Gibt 0 zurück, wenn der Wert dem Filter exakt gleicht
 | 
				
			||||||
 | 
					    */
 | 
				
			||||||
 | 
					    if (time_checkvalue.year != time_filtervalue.year) return (time_checkvalue.year < time_filtervalue.year) ? -1 : 1;
 | 
				
			||||||
 | 
					    if (time_checkvalue.month != time_filtervalue.month) return (time_checkvalue.month < time_filtervalue.month) ? -1 : 1;
 | 
				
			||||||
 | 
					    if (time_checkvalue.day != time_filtervalue.day) return (time_checkvalue.day < time_filtervalue.day) ? -1 : 1;
 | 
				
			||||||
 | 
					    if (time_checkvalue.hour != time_filtervalue.hour) return (time_checkvalue.hour < time_filtervalue.hour) ? -1 : 1;
 | 
				
			||||||
 | 
					    if (time_checkvalue.minute != time_filtervalue.minute) return (time_checkvalue.minute < time_filtervalue.minute) ? -1 : 1;
 | 
				
			||||||
 | 
					    if (time_checkvalue.second != time_filtervalue.second) return (time_checkvalue.second < time_filtervalue.second) ? -1 : 1;
 | 
				
			||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Standardfunktion zum Leeren des Input-Buffers
 | 
				
			||||||
void clear_input_buffer() {
 | 
					void clear_input_buffer() {
 | 
				
			||||||
    int c;
 | 
					    int c;
 | 
				
			||||||
    while ((c = getchar()) != '\n' && c != EOF) {
 | 
					    while ((c = getchar()) != '\n' && c != EOF) {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Hilfsfunktion zum Prüfen, ob die Zahl eine Dezimalzahl ist. Wird im Menu verwendet, um die Nutzereingabe zu prüfen
 | 
				
			||||||
int read_safe_integer() {
 | 
					int read_safe_integer() {
 | 
				
			||||||
    int number;
 | 
					    int number;
 | 
				
			||||||
    int result = scanf("%d", &number);
 | 
					    int result = scanf("%d", &number);
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    if (result != 1) {
 | 
					    if (result != 1) {
 | 
				
			||||||
        clear_input_buffer();
 | 
					        clear_input_buffer();
 | 
				
			||||||
        return -1;
 | 
					        return -1; // Fehler, wenn die Nutzereingabe kein Integer ist
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    clear_input_buffer();
 | 
					    clear_input_buffer();
 | 
				
			||||||
    return number;
 | 
					    return number;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Speicher freigeben und mit 0 überschreiben (Prävention von use-after-free-Schwachstelle)
 | 
				
			||||||
void cleanup_memory() {
 | 
					void cleanup_memory() {
 | 
				
			||||||
    if (all_entries != NULL) {
 | 
					    if (all_entries != NULL) {
 | 
				
			||||||
        printf("Gebe %zu Bytes Speicher frei...\n", max_entries * sizeof(struct log_entry));
 | 
					        printf("%lu Bytes Speicher werden freigegeben\n", (unsigned long)(max_entries * sizeof(struct log_entry)));
 | 
				
			||||||
        free(all_entries);
 | 
					        free(all_entries);
 | 
				
			||||||
        all_entries = NULL;
 | 
					        all_entries = NULL;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -168,47 +179,49 @@ void cleanup_memory() {
 | 
				
			|||||||
    total_entries = 0;
 | 
					    total_entries = 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// sauberes Schließen und bereinigen bei Fehlerstatus, sofern Speicher nicht alloziert werden kann
 | 
				
			||||||
void cleanup_and_exit() {
 | 
					void cleanup_and_exit() {
 | 
				
			||||||
    printf("Programm wird wegen Speicherfehler beendet...\n");
 | 
					    printf("Speicherfehler, Programmende\n");
 | 
				
			||||||
    cleanup_memory();
 | 
					    cleanup_memory();
 | 
				
			||||||
    exit(1);
 | 
					    exit(1);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void expand_memory_if_needed() {
 | 
					// Erweiterung des Speichers für dynamische Speicherallokation
 | 
				
			||||||
 | 
					void mem_expand_dynamically() {
 | 
				
			||||||
 | 
					    // total_entries werden beim parsen am Anfang gezählt (load_regular_file()), max_entries werden initial festgelegt
 | 
				
			||||||
    if (total_entries >= max_entries) {
 | 
					    if (total_entries >= max_entries) {
 | 
				
			||||||
        int old_max = max_entries;
 | 
					        int old_max = max_entries;
 | 
				
			||||||
        max_entries = max_entries * GROWTH_FACTOR;
 | 
					        max_entries = max_entries * GROWTH_FACTOR;
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        printf("Speicher wird erweitert: %d -> %d Einträge\n", old_max, max_entries);
 | 
					        printf("Dynamische Speichererweiterung von %d auf %d Einträge um Faktor %d\n", old_max, max_entries, GROWTH_FACTOR);
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        struct log_entry *new_ptr = realloc(all_entries, max_entries * sizeof(struct log_entry));
 | 
					        struct log_entry *new_ptr = realloc(all_entries, max_entries * sizeof(struct log_entry));
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        if (new_ptr == NULL) {
 | 
					        if (new_ptr == NULL) {
 | 
				
			||||||
            printf("KRITISCHER FEHLER: Speicher konnte nicht auf %d Einträge erweitert werden!\n", max_entries);
 | 
					            printf("ERROR: Speicher konnte nicht auf %d Einträge erweitert werden, Programm wird beendet...\n", max_entries);
 | 
				
			||||||
            printf("Benötigter Speicher: %zu Bytes\n", max_entries * sizeof(struct log_entry));
 | 
					            printf("ERROR: Benötigter Speicher: %lu Bytes\n", (unsigned long)(max_entries * sizeof(struct log_entry)));
 | 
				
			||||||
            cleanup_and_exit();
 | 
					            cleanup_and_exit();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        all_entries = new_ptr;
 | 
					        all_entries = new_ptr;
 | 
				
			||||||
        printf("Speicher erfolgreich erweitert auf %zu Bytes\n", 
 | 
					        printf("Speicher erfolgreich erweitert auf %lu Bytes\n", (unsigned long)(max_entries * sizeof(struct log_entry)));
 | 
				
			||||||
               max_entries * sizeof(struct log_entry));
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void allocate_initial_memory() {
 | 
					void allocate_initial_memory() {
 | 
				
			||||||
    max_entries = INITIAL_ENTRIES;
 | 
					    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));
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    if (all_entries == NULL) {
 | 
					    if (all_entries == NULL) {
 | 
				
			||||||
        printf("KRITISCHER FEHLER: Konnte %d Einträge nicht allokieren!\n", max_entries);
 | 
					        printf("ERROR: Konnte %d Einträge nicht allozieren, Programm wird beendet...\n", max_entries);
 | 
				
			||||||
        printf("Benötigter Speicher: %zu Bytes\n", max_entries * sizeof(struct log_entry));
 | 
					        printf("ERROR: %lu Bytes\n", (unsigned long)(max_entries * sizeof(struct log_entry)));
 | 
				
			||||||
        exit(1);
 | 
					        exit(1); // cleanup_and_exit() nicht nötig, da der Speicherbereich nicht beschrieben wurde - use-after-free unproblematisch
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    printf("Speicher allokiert für %d Log-Einträge (%zu Bytes)\n", 
 | 
					    printf("Speicher erfolgreich alloziert für %d Log-Einträge (%lu Bytes)\n", max_entries, (unsigned long)(max_entries * sizeof(struct log_entry)));
 | 
				
			||||||
           max_entries, max_entries * sizeof(struct log_entry));
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Hilfsfunktion zum Prüfen, ob es sich beim Pfad um ein Directory handelt - für rekursives Parsen
 | 
				
			||||||
int is_directory(char* path) {
 | 
					int is_directory(char* path) {
 | 
				
			||||||
    struct stat path_stat;
 | 
					    struct stat path_stat;
 | 
				
			||||||
    if (stat(path, &path_stat) != 0) {
 | 
					    if (stat(path, &path_stat) != 0) {
 | 
				
			||||||
@ -217,28 +230,34 @@ int is_directory(char* path) {
 | 
				
			|||||||
    return S_ISDIR(path_stat.st_mode);
 | 
					    return S_ISDIR(path_stat.st_mode);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Hilfsfunktion zum prüfen, ob es sich um eine plausible nginx-Logdatei handelt (Metrik: Dateiname - BESSER: Regex oder Magic Bytes?)
 | 
				
			||||||
int is_log_file(char* filename) {
 | 
					int is_log_file(char* filename) {
 | 
				
			||||||
    char* log_pos = strstr(filename, ".log");
 | 
					    char* log_pos = strstr(filename, ".log"); // Sucht und findet den Pointer auf die Startposition des Suchstrings
 | 
				
			||||||
    if (log_pos == NULL) return 0;
 | 
					    if (log_pos == NULL) return 0;
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    char* after_log = log_pos + 4;
 | 
					    char* after_log = log_pos + 4;
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    if (*after_log == '\0') return 1;
 | 
					    if (*after_log == '\0') return 1; // true, wenn die Datei mit .log endet
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    if (*after_log == '.') {
 | 
					    if (*after_log == '.') {
 | 
				
			||||||
        after_log++;
 | 
					        after_log++;
 | 
				
			||||||
        if (*after_log == '\0') return 0;
 | 
					        if (*after_log == '\0') return 0; // false, wenn die Datei mit einem Punkt nach .log endet
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        while (*after_log != '\0') {
 | 
					        while (*after_log != '\0') {
 | 
				
			||||||
            if (*after_log < '0' || *after_log > '9') return 0;
 | 
					            if (*after_log < '0' || *after_log > '9') return 0; // wenn was anderes als Zahlen nach dem . kommen, gib False zurück
 | 
				
			||||||
            after_log++;
 | 
					            after_log++;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        return 1;
 | 
					        return 1; // true, wenn nach .log. noch Zahlen vorhanden sind, wie typisch bei NGINX-Logrotation
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return 0;
 | 
					    return 0; // false, wenn nichts zutrifft
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int parse_simple_log_line(char* line, int entry_index) {
 | 
					/*
 | 
				
			||||||
 | 
					Parser. Regex Parser und strtok haben sich als schwieriger herausgestellt, da nginx Leerzeichen-getrennte Werte in den Logs hat, aber auch Leerzeichen innerhalb der Werte vorkommen.
 | 
				
			||||||
 | 
					Daher ist das Parsing am einfachsten, wenn ein Pointer-basierter Algorithmus die Zeile Stück für Stück einliest und die Erwartungswerte in die struct schreibt.
 | 
				
			||||||
 | 
					Fehleranfällig, wenn das Logformat nicht dem Standard entspricht - das gilt aber auch für andere Parser.
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					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
 | 
				
			||||||
    char* current_pos = line;
 | 
					    char* current_pos = line;
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    current_pos = skip_spaces(current_pos);
 | 
					    current_pos = skip_spaces(current_pos);
 | 
				
			||||||
@ -360,7 +379,7 @@ void load_regular_file(char* filename) {
 | 
				
			|||||||
    int loaded_from_this_file = 0;
 | 
					    int loaded_from_this_file = 0;
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    while (fgets(line, sizeof(line), file) != NULL) {
 | 
					    while (fgets(line, sizeof(line), file) != NULL) {
 | 
				
			||||||
        expand_memory_if_needed();
 | 
					        mem_expand_dynamically();
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        if (parse_simple_log_line(line, total_entries)) {
 | 
					        if (parse_simple_log_line(line, total_entries)) {
 | 
				
			||||||
            total_entries++;
 | 
					            total_entries++;
 | 
				
			||||||
@ -431,8 +450,7 @@ void load_log_file(char* path) {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    printf("Erfolgreich %d Einträge insgesamt geladen.\n", total_entries);
 | 
					    printf("Erfolgreich %d Einträge insgesamt geladen.\n", total_entries);
 | 
				
			||||||
    printf("Aktueller Speicherverbrauch: %zu Bytes für %d Einträge\n", 
 | 
					    printf("Aktueller Speicherverbrauch: %lu Bytes für %d Einträge\n", (unsigned long)(max_entries * sizeof(struct log_entry)), max_entries);
 | 
				
			||||||
           max_entries * sizeof(struct log_entry), max_entries);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int status_code_matches(int status_code) {
 | 
					int status_code_matches(int status_code) {
 | 
				
			||||||
@ -487,35 +505,39 @@ int ip_address_matches(char* ip_address) {
 | 
				
			|||||||
    return 1;
 | 
					    return 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.
 | 
				
			||||||
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;
 | 
					    int has_include_filters = 0;
 | 
				
			||||||
    int include_match = 0;
 | 
					    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++) {
 | 
				
			||||||
        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);
 | 
					                       compare_times(entry_time, filters.time_filters[i].end_time) <= 0); // gibt 0=false zurück, wenn der Prüfwert nicht im Filterbereich ist
 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        if (filters.time_filters[i].mode == FILTER_INCLUDE) {
 | 
					        if (filters.time_filters[i].mode == FILTER_INCLUDE) {
 | 
				
			||||||
            has_include_filters = 1;
 | 
					            has_include_filters = 1; // Flag für inlusive Filter
 | 
				
			||||||
            if (in_range) {
 | 
					            if (in_range) {
 | 
				
			||||||
                include_match = 1;
 | 
					                include_match = 1; // gibt 1=true aus, wenn der Prüfwert in den geprüften inklusiven Filter passt
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					        // ausschließen-Filter
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            if (in_range) {
 | 
					            if (in_range) {
 | 
				
			||||||
                return 0;
 | 
					                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) {
 | 
					    if (has_include_filters) {
 | 
				
			||||||
        return include_match;
 | 
					        return include_match; // gibt 0=false aus, wenn es inklusive Filter gibt (has_include_filters =1), aber kein Zeitstempel in den Filterbereich passt
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    return 1;
 | 
					    return 1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Prüfen aller Filter im AND-Modus oder OR-Modus (combination_mode) pro Log-Eintrag
 | 
				
			||||||
int passes_filter(int entry_index) {
 | 
					int passes_filter(int entry_index) {
 | 
				
			||||||
    int status_match = status_code_matches(all_entries[entry_index].status_code);
 | 
					    int status_match = status_code_matches(all_entries[entry_index].status_code);
 | 
				
			||||||
    int ip_match = ip_address_matches(all_entries[entry_index].ip_address);
 | 
					    int ip_match = ip_address_matches(all_entries[entry_index].ip_address);
 | 
				
			||||||
@ -531,6 +553,7 @@ int passes_filter(int entry_index) {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Einfacher Zähler für alle Einträge, die die Filterfunktionen bestehen
 | 
				
			||||||
int count_filtered_entries() {
 | 
					int count_filtered_entries() {
 | 
				
			||||||
    int count = 0;
 | 
					    int count = 0;
 | 
				
			||||||
    for (int i = 0; i < total_entries; i++) {
 | 
					    for (int i = 0; i < total_entries; i++) {
 | 
				
			||||||
@ -546,8 +569,7 @@ void show_status() {
 | 
				
			|||||||
    
 | 
					    
 | 
				
			||||||
    if (total_entries > 0) {
 | 
					    if (total_entries > 0) {
 | 
				
			||||||
        printf("✅ Log-Daten: %d Einträge geladen\n", total_entries);
 | 
					        printf("✅ Log-Daten: %d Einträge geladen\n", total_entries);
 | 
				
			||||||
        printf("   Speicherverbrauch: %zu Bytes (%d Einträge Kapazität)\n", 
 | 
					        printf("   Speicherverbrauch: %lu Bytes (%d Einträge Kapazität)\n", (unsigned long)(max_entries * sizeof(struct log_entry)), max_entries);
 | 
				
			||||||
               max_entries * sizeof(struct log_entry), max_entries);
 | 
					 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
        printf("❌ Keine Log-Daten geladen\n");
 | 
					        printf("❌ Keine Log-Daten geladen\n");
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user