Newsgroup: it.comp.lang.c
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 ---

 Come posso fare?
Non penso di aver capito bene il tuo problema, cmq nel caso possano 
esserti utili ci sono diverse system call che restituiscono il path 
corrente.
Guarda 'man getcwd' (stai lavorando sotto *nix, no?)
Maldoror.
-- 
"L'Italia sta marcendo in un benessere che e' egoismo, stupidita', 
incultura, pettegolezzo,
moralismo, coazione, conformismo: prestarsi in qualche modo a 
contribuire a questa marcescenza
e', ora, il fascismo."
Pier Paolo Pasolini, 1972


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