// "dir"-Befehl, nur Filenamen im aktuellen Verzeichnis
// 
// Aufruf: mydir1
// 
// Klaus Kusche, 2012

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <dirent.h>

const char *progName;  // für Fehlermeldungen

// Fehlermeldung nach missglückter Dir-Operationen ausgeben 
// (mit errno als Fehler-Grund)
void errMsg(const char *operation, const char *fileName)
{
  fprintf(stderr, "%s: error %s %s: %s\n",
          progName, operation, fileName, strerror(errno));
  exit(EXIT_FAILURE);
}

int main(int argc, const char *argv[])
{
  // Verzeichnis das angezeigt werden soll: Aktuelles Verzeichnis
  const char dirName[] = ".";
  
  progName = argv[0];  
  if (argc > 1) {
    fprintf(stderr, "Aufruf: %s\n", argv[0]);
    exit(EXIT_FAILURE);
  }

  // Analog zu FILE *: Das Ergebnis von opendir, geht ins readdir
  // Was da drin ist, ist uns egal
  DIR *d = opendir(dirName);
  if (d == NULL) {
    errMsg("opening directory", dirName);
  }

  for (;;) {  // ein Schleifenumlauf pro File im Verzeichnis d
    // bei readdir kann man "Ende des Directories" und "Fehler"
    // nur durch Auswertung von "errno" unterscheiden,
    // dazu muss man errno vor jedem readdir-Aufruf explizit auf 0 setzen
    errno = 0;
    // Das Ergebnis von readdir zeigt auf die interne statische struct,
    // in die readdir den Filenamen gespeichert hat
    struct dirent *entry = readdir(d);
    if (entry == NULL) break;  // Fehler oder Ende des Verzeichnisses
    // entry ist ein Pointer auf eine struct
    // ==> Zugriff auf deren Member mit "->"
    printf("%s\n", entry->d_name);  // Filenamen ausgeben
  }
  
  if (errno != 0) {
    errMsg("reading directory", dirName);
  }

  if (closedir(d) == -1) {
    errMsg("closing directory", dirName);
  }
  
  exit(EXIT_SUCCESS);
}
