Newsgroup: it.comp.os.linux.development
Titolo: scan di una directory

Salve,
il codice qui sotto fa lo scan di una directory (mypath) in modo ricorsivo e
stampa il nome di ciascuna directory.
Es:
dir1
dir2
dir3
dir4
dir5
...
vorrei pero' stampare il path delle directory nello stesso modo nel quale
sono definite nel filesystem. Non il path assoluto, ma quello relativo a
mypath.
Es:
dir1
dir2/dir3
dir4
dir5/dir6/dir7
dir/8
....
Come posso fare?
Grazie in anticipo.
Enrico
--- inizio codice ---
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <string.h>
void scan(char * path);
int main(void) {
   char * mypath = "/home/erik/programmi/";
   scan(mypath);
   return(0);
}
void scan(char * path) {
   DIR* fd;
   struct dirent* file;
   struct stat stat_buffer;
   if((fd = opendir(path)) == NULL) perror("Error");
   chdir(path);
   while((file = readdir(fd)) != NULL) {
 lstat(file->d_name, &stat_buffer);
 if( S_ISDIR(stat_buffer.st_mode)) {
 if(strcmp(".",file->d_name)==0 || strcmp("..",file->d_name)==0)
 continue;
 printf("%s\n",file->d_name);
 scan(file->d_name);
        }
   }
   chdir("..");
closedir(fd);
}
--- fine codice ---


portati dietro il path
Ad esempio:
void scan(char * path) {
   DIR* fd;
   struct dirent* file;
   struct stat stat_buffer;
   char new_path[MAX_PATH];
   if((fd = opendir(path)) == NULL) perror("Error");
/*   chdir(path);  NON PIU' */
   while((file = readdir(fd)) != NULL) {
 lstat(file->d_name, &stat_buffer);
 if( S_ISDIR(stat_buffer.st_mode)) {
 if(strcmp(".",file->d_name)==0 || strcmp("..",file->d_name)==0)
 continue;
/* costruisco il nuovo path */
sprintf(new_path,"%s/%s",path,file->d_name);
/* modifico la stampa anche col path */
 printf("%s\n",new_path);
/* lancio lo scan col nuovo path */
 scan(new_path);
        }
   }
/*   chdir(".."); NON PIU' */
closedir(fd);
}
Occhio, non l'ho provato, sono andato ad occhio, quindi puo' darsi che ci
siano errori e soprattutto stai attento se costruisco il nuovo path
correttamente, ovvero se effettivamente va aggiunto lo slash tra "path" e
"file->d_name".
Comunque l'idea e' quella li':
rimanere nella directory corrente ma portarsi dietro il percorso completo a
partire dalla prima chiamata.
Ciao,
Ema

mi spiego meglio,
ad esempio, se ho il filesystem cosě
/home/erik/paperino
/home/erik/paperina
/home/erik/cane/pluto
/home/erik/nipote/qui
/home/erik/nipote/quo
/home/erik/nipote/qua
/home/erik/alfa/beta/gamma
e passo scandir ("/home/erik/")
vorrei ottenere
/paperino
/paperina
/cane/pluto
/nipote/qui
/nipote/quo
/nipote/qua
/alfa/beta/gamma
Ciao

 ha scritto nel messaggio
news:GNGHa.103013$pR3.2...@news1.tin.it...

Beh, se hai il file system come sopra otterrai qualcosa tipo:
/paperino
/paperina
/cane
/cane/pluto
/nipote
/nipote/qui
/nipote/quo
/nipote/qua
/alfa
/alfa/beta
/alfa/beta/gamma
Hai gia' provato quello che ti ho detto?
Ciao,
Ema


Se non vuoi stare ad estrarre il path relativo da quello assoluto puoi
sempre:
- cambiare directory prima di lanciare la funzione ricorsiva per la prima
volta
- usare quindi dei path relativi
- ripristinare la directory dove ti trovati all'inizio (che quindi ti eri
diligentemente salvato)
quindi qualcosa tipo
void scandir_main(char * dir) {
    char comando[1000];
    char initial_dir[1000];
    /* directory corrente */
    get_current_dir(initial_dir);
    /* directory da visitare*/
    sprintf(comando,"cd %s",dir);
    esegui(comando);
    /* visita ricorsiva */
    scandir(".")
    /* ripristino directory iniziale */
    sprintf(comando,"cd %s",initial_dir);
    esegui(comando);
}
Ovviamente questo e' pseudo-codice, ma l'idea c'e'.
Ciao,
Ema