#include #include #include #include #include #include #include /* Liefert den Plattenplatzverbrauch aller regulaeren Dateien im * aktuellen Verzeichnis und dessen Unterverzeichnissen. */ unsigned int disk () { DIR * d = opendir ("."); struct dirent * dent; struct stat stat; unsigned int sum = 0; /* Nachsehen, ob wir das aktuelle Verzeichnis oeffnen konnten. */ if (!d) return 0; /* Alle Eintraege im aktuellen Verzeichnis durchgehen. */ while ((dent = readdir (d))) { /* "." ist das aktuelle Verzeichnis und wird ignoriert, */ if (strcmp (dent->d_name, ".") == 0) continue; /* genauso wie ".." */ if (strcmp (dent->d_name, "..") == 0) continue; /* Groesse und Dateityp bestimmen. Wir verwenden lstat * und nicht stat, um symbolische Links zu erkennen und * ignorieren zu koennen. */ if (lstat (dent->d_name, &stat) < 0) { perror ("lstat"); continue; } /* Unterscheiden nach Dateityp */ switch (stat.st_mode & S_IFMT) { case S_IFDIR: /* Ein Verzeichnis, also rekursiv ... */ /* Wechseln ins das Unterverzeichnis. */ if (chdir (dent->d_name) < 0) break; /* Rekursiver Aufruf um die Groesse des * Unterverzeichnisses zu bestimmen. Diese Groesse * wird zur Groesse des aktuellen Verzichnisses * hinzu addiert. */ sum += disk (); /* Zurueck aus dem Unterverzeichnis ins "aktuelle" * Verzeichnis wechseln. */ if (chdir ("..") < 0) { perror ("chdir"); exit (1); } break; case S_IFREG: /* Eine regulaere Datei */ /* In diesem Fall wird nur die Groesse der Datei * zur Groesse des aktuellen Verzeichnisses * hinzuaddiert. */ sum += stat.st_size; break; } } /* Fertig, berechnete Groesse zurueckgeben. */ return sum; } /* Hauptprogramm, kurz und knapp. */ int main () { printf ("Platzverbrauch: %d Bytes\n", disk ()); return 0; }