/************************************************************************ ** ** FILE : scandir.c ** ** ZWECK : Enthaelt die Funktion ScanDir der Dir-Funktionen ** Liest den Inhalt des Verzeichnisses DirInh.Pfad ** ** AUTOR : Michael C. Ancutici ** Universitaet Stuttgart, Fakultaet Informatik ** ** DATUM : 14.03.93 ** *************************************************************************/ #include #include "dir.H" #include "misc.h" #define F_TAB_FULL "*** ScanDir: Einttragstabelle voll. Mehr als %d Dateien.\n" #define F_BUFF_FULL "*** ScanDir: Namenspuffer fuer Dateien voll. Mehr als %d Zeichen.\n" /************************************************************************* ** FUNKTION: CompareFiles ** ZWECK: Lexikographische Ordnungsrelation fuer Filenamen ** wird von Quicksort aufgerufen ** ANMERK: Habe das handelsuebliche strcmp ersetzt, weil dort zwischen ** Gross- und Kleinbuchstaben unterschieden wird, was mir nicht ** gefaellt, denn ich moechte mein "Makefile" direkt unter ** meinem "makefile" sehen und nicht seitenweise getrennt. ** Wer glaubt, das es mit strcmp schneller geht (habe aber ** nichts gemerkt), kann es ja wieder ersetzen. ** INPUT: zwei Filenamen ** RETURN: negativ fuer a < b ** null fuer a = b ** positiv fuer a > b *************************************************************************/ static int CompareFiles( a, b) char **a,**b; { register char *ha = *a; register char *hb = *b; for (ha, hb; *ha!=EOL && *hb!=EOL; ha++, hb++) if (toupper(*ha) < toupper(*hb)) return (-1); else if (toupper(*ha) > toupper(*hb)) return (+1); if (*ha=EOL) return (-1); else if(*ha=EOL) return (+1); else return (0); /* return (strcmp( *a, *b)); einfacher, schneller (?) */ } /************************************************************************* ** FUNKTION: CompareDirs ** ZWECK: Lexikographische Ordnungsrelation fuer Unterverzeichnisse ** ueberspringt Praefix, vielleicht geht deshalb alles so schnell ** wird von Quicksort aufgerufen ** ANMERK: Habe das handelsuebliche strcmp ersetzt, weil dort zwischen ** Gross- und Kleinbuchstaben unterschieden wird, was mir nicht ** gefaellt, denn ich moechte mein "Random" direkt unter ** meinem "random" sehen und nicht seitenweise getrennt. ** Wer glaubt, das es mit strcmp schneller geht (habe aber ** nichts gemerkt), kann es ja wieder ersetzen. ** INPUT: zwei Verzeichnisnamen mit Praefix FillSpace ** RETURN: negativ fuer a < b ** null fuer a = b ** positiv fuer a > b *************************************************************************/ static int CompareDirs( a, b) char **a,**b; { register char *ha = *a+FillLen; register char *hb = *b+FillLen; for (ha, hb; *ha!=EOL && *hb!=EOL; ha++, hb++) if (toupper(*ha) < toupper(*hb)) return (-1); else if (toupper(*ha) > toupper(*hb)) return (+1); if (*ha=EOL) return (-1); else if(*ha=EOL) return (+1); else return (0); /* return (strcmp( *a+FillLen, *b+FillLen)); */ } /************************************************************************* ** FUNKTION: ScanDir ** ZWECK: ** EINGABE: ** AUSGABE: ** RETURN: ** ANMERK: *************************************************************************/ void ScanDir( DirInh) DIRECTORY *DirInh; { DIR *dir; struct dirent *eintrag; struct stat statbuffer; char fullname[ MAXPATHLEN]; int i; int nFiles = DirInh->nPfad; int nSubDir = DirInh->nPfad; register char *p = DirInh->nextBuffer; char *h; register int pcount = (DirInh->nextBuffer)-(DirInh->Buffer); if (!(dir = opendir( DirInh->Pfad))) /* Fehler: Pfad nicht lesbar */ return; strcpy( fullname, DirInh->Pfad); h = fullname + strlen( fullname); for (eintrag = readdir(dir); eintrag != NULL; eintrag = readdir( dir)) if (eintrag->d_name[0] != '.') { strcpy( h, eintrag->d_name); if (!stat( fullname, &statbuffer) && S_ISDIR( statbuffer.st_mode)) { if (pcount + (i=1+strlen(FillSpace)+strlen(eintrag->d_name)) >= DI_BUFFER_SIZE) { fprintf( stderr, F_BUFF_FULL, DI_BUFFER_SIZE); break; /* Fehler: Buffer voll */ } strcpy( p, FillSpace); strcat( p, eintrag->d_name); pcount += i; if (nFiles >= DI_MAX_NAMEN) { fprintf( stderr, F_TAB_FULL, DI_MAX_NAMEN); break; /* Fehler: Eintragstabelle voll */ } DirInh->Name[nFiles++] = DirInh->Name[nSubDir]; DirInh->Name[nSubDir++] = p; p+=i; } else { /* File */ if (pcount + (i=1+strlen(eintrag->d_name)) >= DI_BUFFER_SIZE) { fprintf( stderr, F_BUFF_FULL, DI_BUFFER_SIZE); break; /* Fehler: Buffer voll */ } strcpy( p, eintrag->d_name); pcount += i; if (nFiles >= DI_MAX_NAMEN) { fprintf( stderr, F_TAB_FULL, DI_MAX_NAMEN); break; /* Fehler: Eintragstabelle voll */ } DirInh->Name[nFiles++] = p; p+=i; } } closedir(dir); DirInh->nFiles = nFiles; DirInh->nSubDir = nSubDir; if (nFiles == nSubDir) DirInh->Name[nFiles]=NULL; FillLen=strlen(FillSpace); qsort( DirInh->Name+nSubDir, nFiles-nSubDir, sizeof(char *), CompareFiles); qsort( DirInh->Name+DirInh->nPfad, nSubDir-DirInh->nPfad, sizeof(char *), CompareDirs); }