Assignment Chef icon Assignment Chef
All German tutorials

Programming lesson

Anleitung zur Auswertung von Login-Statistiken mit C: logdata-Programm unter Linux

Lerne, wie du mit C und der wtmp-Datei Login-Statistiken auswertest. Schritt-für-Schritt-Anleitung für das logdata-Programm – inklusive Optionen, Zeitberechnung und Fehlerbehandlung.

Login-Statistiken C wtmp Datei auslesen logdata Programm C Programmierung Linux Systemprogrammierung Tutorial Login-Zeiten berechnen C getopt Beispiel utmp.h verwenden Zeitberechnung in C Linux Logdateien auswerten Studium Informatik C Aufgabe Csci493.66 wtmp Struktur Login-Statistiken erstellen C Praxisprojekt

Einleitung: Warum Login-Statistiken in der Praxis wichtig sind

In der heutigen digitalen Welt, in der Systemadministratoren täglich mit Benutzerkonten und Zugriffszeiten jonglieren, ist die Fähigkeit, Login-Daten auszuwerten, eine grundlegende Kompetenz. Ob in der IT-Sicherheit, beim Monitoring von Serverzugriffen oder einfach zur Optimierung von Arbeitsabläufen – das Verständnis von Systemprotokollen wie der wtmp-Datei öffnet Türen zu tiefergehenden Einblicken. Dieses Tutorial führt dich durch die Erstellung eines C-Programms namens logdata, das genau solche Statistiken liefert. Es ist ideal für Studierende der Informatik, die sich mit Systemprogrammierung, Datei-I/O und Zeitverarbeitung vertraut machen möchten.

Stell dir vor, du verwaltest einen Server für eine beliebte Online-Gaming-Plattform. Täglich loggen sich tausende Spieler ein, um an Turnieren teilzunehmen. Mit einem Tool wie logdata könntest du schnell herausfinden, welcher Spieler die meiste Zeit im Spiel verbringt – und das ohne manuelles Durchforsten von Logdateien. Die Technik dahinter ist dieselbe, die auch in großen Unternehmen für das User-Auditing eingesetzt wird.

Grundlagen: Die wtmp-Datei und ihre Struktur

Die wtmp-Datei („who tmp“) ist eine binäre Protokolldatei unter Linux, die alle Login- und Logout-Ereignisse speichert. Sie befindet sich standardmäßig unter /var/log/wtmp. Jeder Eintrag ist eine Struktur vom Typ struct utmp, die unter anderem folgende Felder enthält:

  • ut_type: Der Typ des Eintrags (z. B. USER_PROCESS für einen angemeldeten Benutzer).
  • ut_user: Der Benutzername.
  • ut_line: Das Terminal oder die Verbindung.
  • ut_tv: Ein timeval-Struktur mit Sekunden und Mikrosekunden des Ereignisses.

Um Login-Statistiken zu berechnen, musst du die Datei öffnen, jeden Datensatz lesen und die Zeiten für Login/Logout-Paare verarbeiten. Ein besonderer Fall sind sogenannte „offene“ Sessions, die noch kein Logout haben – diese werden in der Statistik nicht berücksichtigt, es sei denn, sie endeten durch einen Systemneustart.

Schritt 1: Aufsetzen des C-Programmgerüsts

Beginne mit einem leeren C-Programm, das die notwendigen Header einbindet:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <utmp.h>
#include <unistd.h>

Die Funktion main() sollte die Kommandozeilenargumente parsen. Verwende getopt(), um die Optionen -a, -s und -f zu erkennen. Der Rest der Argumente sind Benutzernamen. Wenn keine Benutzernamen angegeben sind und -a nicht gesetzt ist, wird der aktuelle Benutzer (getlogin()) verwendet.

Beispiel für das Parsen:

int opt;
int show_all = 0;
int show_summary = 0;
char *wtmp_path = "/var/log/wtmp";
while ((opt = getopt(argc, argv, "asf:")) != -1) {
switch (opt) {
case 'a': show_all = 1; break;
case 's': show_summary = 1; break;
case 'f': wtmp_path = optarg; break;
default: fprintf(stderr, "Usage: %s [-a] [-s] [-f file] [username ...]\n", argv[0]); return 1;
}
}

Schritt 2: Lesen der wtmp-Datei

Öffne die wtmp-Datei mit fopen() im Binärmodus ("rb"). Wenn die Datei nicht existiert, gib eine Fehlermeldung auf stderr aus. Lese dann Datensätze mit fread() in eine struct utmp ein.

FILE *wtmp = fopen(wtmp_path, "rb");
if (!wtmp) {
fprintf(stderr, "Keine Aufzeichnungen vorhanden: %s\n", wtmp_path);
return 1;
}
struct utmp entry;
while (fread(&entry, sizeof(entry), 1, wtmp) == 1) {
// Verarbeite Eintrag
}

Beachte: Die wtmp-Datei kann sehr groß sein. Für dieses Tutorial nehmen wir an, dass sie vollständig in den Speicher passt. In der Praxis solltest du effizientere Methoden wie mmap() in Betracht ziehen.

Schritt 3: Zuordnung von Logins zu Logouts

Um die Gesamtloginzeit zu berechnen, musst du für jeden Benutzer eine Liste von Login-Ereignissen (Typ USER_PROCESS) und die dazugehörigen Logouts finden. Ein Logout wird durch einen Eintrag vom Typ DEAD_PROCESS oder durch einen nachfolgenden Login desselben Benutzers auf derselben Leitung repräsentiert. Ein einfacher Ansatz ist, die Einträge chronologisch zu durchlaufen und für jeden Benutzer eine Liste offener Sessions zu führen.

Hier ein Beispiel für eine Datenstruktur:

typedef struct {
char user[32];
char line[32];
time_t login_time;
int active; // 1 = noch kein Logout
} Session;

Beim Durchlaufen der wtmp-Datei:

  • Wenn ein USER_PROCESS auftritt: Füge eine neue Session hinzu.
  • Wenn ein DEAD_PROCESS auftritt: Suche die passende Session (gleicher Benutzer, gleiche Leitung) und berechne die Differenz. Markiere die Session als inaktiv.
  • Wenn ein BOOT_TIME oder SHUTDOWN_TIME auftritt: Alle aktiven Sessions gelten als beendet (Systemneustart).

Schritt 4: Zeitberechnung und Formatierung

Die Gesamtzeit pro Benutzer wird in Sekunden gespeichert. Am Ende konvertierst du diese Sekunden in Tage, Stunden, Minuten und Sekunden. Die Ausgabe soll nur die notwendigen Einheiten anzeigen (z. B. bei weniger als einer Stunde nur Minuten und Sekunden).

void print_time(long total_sec) {
int days = total_sec / 86400;
int hours = (total_sec % 86400) / 3600;
int mins = (total_sec % 3600) / 60;
int secs = total_sec % 60;
if (days > 0) printf("%d Tag%s ", days, days == 1 ? "" : "e");
if (hours > 0) printf("%d Stunde%s ", hours, hours == 1 ? "" : "n");
if (mins > 0) printf("%d Minute%s ", mins, mins == 1 ? "" : "n");
if (secs > 0 || total_sec == 0) printf("%d Sekunde%s", secs, secs == 1 ? "" : "n");
printf("\n");
}

Achtung: Die Pluralbildung im Deutschen ist etwas knifflig. In der Aufgabenstellung wird Englisch verlangt („day(s)“, „hour(s)“ etc.), aber für dieses Tutorial verwenden wir Deutsch. Passe dies entsprechend an.

Schritt 5: Integration der Optionen

Die Option -a zeigt alle Benutzer an, die jemals in der wtmp-Datei vorkommen. Dazu musst du während des Lesens eine Liste aller eindeutigen Benutzernamen erstellen. Die Option -s fügt am Ende eine Zusammenfassungszeile mit der Gesamtzeit aller abgefragten Benutzer hinzu.

Beispiel für die Ausgabe mit -a:

alice 2 Tage 5 Stunden 10 Minuten 30 Sekunden
bob 0 Sekunden
charlie 1 Tag 3 Stunden 45 Minuten

Wenn -s gesetzt ist, kommt eine Zeile wie:

Gesamt: 3 Tage 8 Stunden 55 Minuten 30 Sekunden

Fehlerbehandlung und Edge Cases

Dein Programm sollte robust sein:

  • Wenn ein Benutzername nicht existiert, gib „0 Sekunden“ aus.
  • Wenn die wtmp-Datei nicht geöffnet werden kann, gib eine Fehlermeldung auf stderr aus und beende mit Exit-Status 1.
  • Behandle leere Argumente: Zeige die Usage-Nachricht an.
  • Achte darauf, dass Speicher nicht überläuft – insbesondere bei der Liste der Sessions.

Ein typischer Fehler ist, dass man vergisst, dass ut_tv.tv_sec ein time_t ist, aber in Sekunden vorliegt. Die Differenz zweier solcher Werte ergibt die verstrichene Zeit in Sekunden.

Zusammenfassung und Ausblick

Mit diesem Tutorial hast du die Grundlagen für ein voll funktionsfähiges logdata-Programm gelernt. Du kannst nun Login-Statistiken aus der wtmp-Datei extrahieren, Zeitberechnungen durchführen und die Ausgabe formatieren. Diese Fähigkeiten sind nicht nur für die Uni-Aufgabe nützlich, sondern auch für reale Systemadministration und Sicherheitsanalysen.

In der nächsten Erweiterung könntest du zum Beispiel:

  • Die Ausgabe nach Benutzern sortieren.
  • Die Option -p hinzufügen, um nur aktive Sessions anzuzeigen.
  • Die Statistik in eine CSV-Datei exportieren.

Denke daran: Übung macht den Meister. Probiere das Programm mit verschiedenen Optionen und wtmp-Dateien aus. Viel Erfolg bei deiner Abgabe!