Durch das ganze Unix System bestimmte Dateiart suchen

Dieses Thema im Forum "C/C++" wurde erstellt von sniper, 23.11.2006.

  1. sniper

    sniper Jungspund

    Dabei seit:
    23.11.2006
    Beiträge:
    12
    Zustimmungen:
    0
    Hallo,
    ich will ein C Programm schreiben welches das ganze Unix System nach einer bestimmten Dateiart sucht. Am ende sollen alle Pfade ausgeben werden wo sich die Dateien befinden. Ein Teil hab ich schon geschrieben der funktioniert, nur nicht mit der gewünschten Funktion weil es nur ein Ordner durchsuchen kann. Ich muss aber das ganze System durchsuchen und ich komm nicht weiter… Hat jemand eine Idee wie es funktionieren könnte? :think:

    Hier ist mein Programm:

    Code:
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <errno.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <dirent.h>
    #include <unistd.h>
    
    // die Dateiart die gesucht wird
    #define STR_EXTENSION ".xxx"
    #define LENGTH_OF_STRING(x) (sizeof(x)-1)
    
    
    int main () {
    
      struct stat FileInfo;
      struct dirent *CurrentFile;
      DIR *Directory;
      char chl_Path[256];
    
      int inl_ordnerZaehler = 0;
      int inl_xxxZaehler = 0;
      // von diesen Punkt fängt das Programm mit der Suche an
      char chl_anfangsPath[] = { "/" };
    
      /// Öffnet das Verzeichnis
      if ( (Directory = opendir(chl_anfangsPath)) == NULL) {
          perror("opendir()");
          return EXIT_FAILURE;
      }
      else {
    
        /// bis das Programm alle Dateien durchgelaufen hat
        while ( (CurrentFile = readdir(Directory)) != NULL) {
            int inl_slaenge = 0;
    
            if (strcmp(CurrentFile->d_name,".") && strcmp(CurrentFile->d_name,"..")) {
                // kopiert den String in chl_Path
                strcpy(chl_Path,chl_anfangsPath);
                // hängt das zweite an das erste an
                strcat(chl_Path,CurrentFile->d_name);
                // brauchen wir um die Attribute der Datei ausgelesen zu können
                if (stat(chl_Path,&FileInfo) == -1) {
                    perror("stat()");
                    closedir(Directory);
                    return EXIT_FAILURE;
                }
    
                /// wenn die Datei lesbar ist
                if(access(chl_Path, R_OK) == 0){
    
                    /// wenn es sich um ein Ordner handelt
                    if (S_ISDIR(FileInfo.st_mode)) {
    
                        // erzeugt ein array welcher alle adressen von den verschiedenen Ordner speichert
                        long il_pos[inl_ordnerZaehler];
                        // zuweisung der Adressen
                        il_pos[inl_ordnerZaehler] = telldir(Directory);
                        // erzeugt ein array welcher alle Namen von Ordner aus dem aktuellen Verzeichnis speichert
                        char chl_Ordner[inl_ordnerZaehler][128];
                        strcpy(chl_Ordner[inl_ordnerZaehler],CurrentFile->d_name);
                        printf("%d.\t",inl_ordnerZaehler+1);
                        printf("%s \t\t",chl_Path);
                        printf("pos.: %ld\n",il_pos[inl_ordnerZaehler]);
                        inl_ordnerZaehler++;
                    }
    
                    /// wenn es sich um eine Datei handelt
                    else if (S_ISREG(FileInfo.st_mode)) {
                        inl_slaenge = strlen(CurrentFile->d_name);
    
                        char *str_rueckgabe;
                        int im_c = '.';
                        str_rueckgabe = strchr ( CurrentFile->d_name, im_c );
    
                           /// wenn er die ".xxx" Datei gefunden hat
                           if                      ((strcmp(STR_EXTENSION,CurrentFile->d_name+inl_slaenge-LENGTH_OF_STRING(STR_EXTENSION))) == 0){
                               char chl_xxx[inl_xxxZaehler][256];
                               strcpy(chl_xxx[inl_xxxZaehler],chl_Path);
                               printf("XXX Path: %s \n",chl_xxx[inl_xxxZaehler]);
                               inl_xxxZaehler++;
                           }
                     } // end of else if
                } // end of if (wenn die Datei lesbar ist)
            }
        } //end while
        closedir(Directory);
      } // end of else
      return EXIT_SUCCESS;
    } //end main
    
    

    Und so sieht die Augabe bis jetzt (sie wurde nur zur Testzwecken gemacht) wenn das Programm keine Datei gefunden hat. Wenn er die Datei findet dann steht noch der ganzer Pfad von der Datei in der Ausgabe.

    Code:
    
    1.      /bin            pos.: 2354688
    2.	/dev            pos.: 2401792
    3.	/etc            pos.: 2529152
    4.	/lib            pos.: 2563328
    5.	/mnt            pos.: 2609920
    6.	/opt            pos.: 2700672
    7.	/srv            pos.: 2711168
    8.	/tmp            pos.: 2713728
    9.	/sys            pos.: 2730880
    10.	/var            pos.: 2744576
    11.	/usr            pos.: 25652864
    12.	/boot           pos.: 27051904
    13.	/home           pos.: 29009280
    14.	/proc           pos.: 29360256
    15.	/sbin           pos.: 29415552
    16.	/data1          pos.: 284135552
    17.	/data2          pos.: 307945600
    18.	/media          pos.: 1091284480
    19.	/freebsd                pos.: 1383414400
    
     
  2. Anzeige

    Schau dir mal diese Kategorie an. Dort findest du bestimmt etwas.
    Registrieren bzw. einloggen, um diese und auch andere Anzeigen zu deaktivieren
  3. #2 Lord Kefir, 23.11.2006
    Lord Kefir

    Lord Kefir König

    Dabei seit:
    10.06.2004
    Beiträge:
    944
    Zustimmungen:
    0
    Du musst alle directory-entries durchlaufen und prüfen, ob ein entry ein Ordner ist. Falls dies der Fall ist, muss sie die Funktion selbst aufrufen (Stichwort: Rekursion).

    Mfg, Lord Kefir
     
  4. sniper

    sniper Jungspund

    Dabei seit:
    23.11.2006
    Beiträge:
    12
    Zustimmungen:
    0
    Danke für die Antwort..
    .. aber was sind genau directory-entries? Und wieso muss ich sie überprüfen wenn ich die Ordner schon herausgesucht hab mit „S_ISDIR(FileInfo.st_mode)“?

    Muss ich dann mit der Funktion „getdents()“ und den Katalogen arbeiten? Ist mein Programm für irgendwas zu gebrauchen oder komplett neu schreiben?

    Ich hab nicht wirklich viel Ahnung von C und Unix Systeme. Beschäftige mich jetzt erst seit paar Wochen damit.
     
  5. #4 Lord Kefir, 23.11.2006
    Lord Kefir

    Lord Kefir König

    Dabei seit:
    10.06.2004
    Beiträge:
    944
    Zustimmungen:
    0
    Hatte ich noch auf der Platte herumfliegen:

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <sys/stat.h>
    #include <sys/types.h>
    #include <dirent.h>
    #include <string.h>
    
    void show_files (const char *dirname) {
    	DIR *dir;
    	struct dirent *dir_info;
    	char filename[5120];
    	struct stat attr;
    	
    	if ((dir = opendir (dirname)) != NULL) {
    		while ((dir_info = readdir (dir)) != NULL) {
    			if (strcmp (dir_info->d_name, ".") != 0 && strcmp (dir_info->d_name, "..") != 0) {
    				if (dirname[strlen (dirname) - 1] == '/') {
    					sprintf (filename, "%s%s", dirname, dir_info->d_name);
    				}
    				else {
    					sprintf (filename, "%s/%s", dirname, dir_info->d_name);
    				}
    
    				if (stat (filename, &attr) == 0) {
    					fprintf (stdout, "%s\n", filename);
    					switch (attr.st_mode & S_IFMT) {
    						case S_IFDIR:
    							show_files (filename);
    							break;
    						default:
    							fprintf (stdout, "%s\n", filename);
    					}
    				}
    				else {
    					fprintf (stderr, "Could not stat file: %s\n", dir_info->d_name);
    				}
    			}
    		}		
    		closedir (dir);
    	}
    	else {
    		fprintf (stderr, "Could not open dir: %s\n", dirname);
    	}
    }
    
    int main (int argc, char *argv[]) {
    	show_files ("/home");
    
    	return EXIT_SUCCESS;
    }
    
    Einziger Nachteil bei dem Code ist es, dass es eventuell zu Bufferoverflows kommen kann (Pfad + Dateiname dürfen höchstens 5120 Zeichen lang sein). Entweder Du arbeitest mit 'nem dynamischen Array oder baust 'ne Überprüfung ein, bevor Du den Dateinamen zusammensetzt.

    Mfg, Lord Kefir
     
  6. sniper

    sniper Jungspund

    Dabei seit:
    23.11.2006
    Beiträge:
    12
    Zustimmungen:
    0
    Danke!!
    Das Programm wird mit bestimmt sehr helfen. ;)
     
  7. #6 schorsch312, 23.11.2006
    schorsch312

    schorsch312 Routinier

    Dabei seit:
    18.07.2006
    Beiträge:
    372
    Zustimmungen:
    0
    HI,
    Kann man nicht auf die Datenbank von locate zurückgreifen? Wenn das geht sollte es schneller gehn, da die DB ja schon vorhandnen ist.
    Gruß, Georg
     
  8. #7 Lord Kefir, 23.11.2006
    Lord Kefir

    Lord Kefir König

    Dabei seit:
    10.06.2004
    Beiträge:
    944
    Zustimmungen:
    0
    Dann muss slocate aber installiert und aktuell sein.

    Mfg, Lord Kefir
     
  9. sniper

    sniper Jungspund

    Dabei seit:
    23.11.2006
    Beiträge:
    12
    Zustimmungen:
    0
    Ein Tipp noch:

    Man sollte besser die Funktion lstat() statt stat() verwenden weil wenn das Programm an einen Symbolischen Link oder eine rekursive Verknüpfung stoßt dann kommt man in eine endlose Schleife.
     
  10. Anzeige

    Vielleicht findest du HIER Antworten.
    Registrieren bzw. einloggen, um diese und auch andere Anzeigen zu deaktivieren
  11. #9 Lord Kefir, 27.11.2006
    Lord Kefir

    Lord Kefir König

    Dabei seit:
    10.06.2004
    Beiträge:
    944
    Zustimmungen:
    0
    Mit 'stat' gibt es auch keine Probleme, da aufgrund des 'switch (attr.st_mode & S_IFMT)' im obigen Codebeispiel nur rekursive Aufrufe stattfinden, wenn auch wirklich ein directory gefunden wird.

    Mfg, Lord Kefir
     
  12. #10 sniper, 28.11.2006
    Zuletzt bearbeitet: 21.06.2007
    sniper

    sniper Jungspund

    Dabei seit:
    23.11.2006
    Beiträge:
    12
    Zustimmungen:
    0
    Ich hab "switch (attr.st_mode & S_IFMT)" auch in meinen Programm und ich hatte Probleme wenn ich ab den root Verzeichnis gesucht habe. Es war nicht unbedingt eine Endlosschleife aber es war auch nicht schon wenn mit das Programm mehrere male so was ausgibt /ordner1/ordner2/ordner3/ordner1/ordner2/ordner3/ordner1/ordner2/ordner3/ordner1/ordner2/ordner3/ ordner1/ordner2/ordner3/ordner1/ordner2/ordner3/ordner1/ordner2/ordner3/ordner1/ordner2/ordner3/ ordner1/ordner2/ordner3/ordner1/ordner2/ordner3/ordner1/ordner2/ordner3/ordner1/ordner2/ordner3/ ordner1/ordner2/ordner3/ordner1/ordner2/ordner3/meineDatei.xxx
    Und das Programm hat über 10 Minuten nach den Dateien gesucht.. Ich weis nicht ob es je zum Ende gekommen ist weil ich keine Geduld hatte so lange zu warten.
    Dann hab ich diese eine Funktion geändert und ich hätte meine gesuchte Dateien sauber auf dem Bildschirm stehen und das schon nach 3-4 Minuten auf einen 500MHz Rechner.
     
Thema:

Durch das ganze Unix System bestimmte Dateiart suchen

Die Seite wird geladen...

Durch das ganze Unix System bestimmte Dateiart suchen - Ähnliche Themen

  1. Grep - Ganze Festplatte durchsuchen

    Grep - Ganze Festplatte durchsuchen: ich hab ne Frage zu grep. Bin absoluter Neuling und krieg das nicht gebacken und bin irgendwie am verzweifeln.Ich will aus ner Festplatte alle...
  2. Verzeichnisnamen durch Variable ergänzen

    Verzeichnisnamen durch Variable ergänzen: Guten abend, folgendes ich möchte einen Benutzer anlegen und dabei den Verzeichnisnamen durch Benutzereingabe bestimmen. Der Teil xxxxxx ist...
  3. PATH wird nicht richtig durchsucht

    PATH wird nicht richtig durchsucht: Hi zusammen, ich nutze das Forum schon seit längerem , allerdings hat mir bis jetzt immer die Suchfunktion weitergeholfen. Bei meinem aktuellen...
  4. Kunden-Skript ausgelöst durch Linux-Cluster Pacemaker

    Kunden-Skript ausgelöst durch Linux-Cluster Pacemaker: Hallo! Ich komme aus der AIX-Welt wo es im HACMP-Cluster die Möglichkeit der Ausführung eines Start- bzw. Stop-Skriptes im Zuge einer...
  5. Forscher analysieren Durchsatzprobleme im Linux-Scheduler

    Forscher analysieren Durchsatzprobleme im Linux-Scheduler: Eine Gruppe von Forschern hat Fälle identifiziert, in denen der Scheduler im Linux-Kernel falsche Entscheidungen trifft und die CPUs nicht so gut...