Salve, ho fatto quest'esercizio in C che dovrebbe girare su sistemi di tipo unix, la traccia è nel codice.
All'apparenza da i risultati richiesti, ma vi è un bug che non riesco a capire.

Nella parte della funzione cerca_ext, che è una funzione che cerca i file che terminano con .ext in tutte le sottodirectory della directory passata da linea di comando, se è presente un file in una sottodirectory terminante per .ext da segmentation fault, altrimenti se non è presente le cartelle sono analizzate corretemente e l'esercizio da i risultati corretti.

Ora esaminando l'output delle printf, sembra che venga vista come cartella un file terminante con .ext se presente nelle sottodirectory, e non capisco perchè, essendoci un if che controlla SE il file in analisi è una directory.
Qualcuno nella ricorsione non va insomma.

Qualcuno ha qualche idea? Grazie 1000

codice:
/* Scrivere un programma Trovafile.c che quando invocato con Trovafile ext directory trovi
* tutti i file a partire dalla directory di nome directory che hanno come estensione ext
* e ne verifichi i diritti di lettura per altri e le dimensioni. Individuato il file di
* dimensione minima, il programma deve creare un file con lo stesso nome e con estensione
* txt nella directory corrente in cui scrivere i nome dei file. */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <errno.h>
#include <dirent.h>
#include <sys/stat.h>
#include <string.h>
#include <fcntl.h>
#include <limits.h>


/* Struttura contenente le informazione da raccogliere */
struct info_da_salvare {
  char *nome_file;
  off_t size;
  int permesso;
} array_file_ext[100];  
int contatore = 0;

/* Prototipi funzioni */
void cerca_ext (char *path);
int main(int argc, char *argv[])
{
  /* Dichiarazione delle variabili */
  int i, len_da_copiare;
  off_t size_minimo= INT_MAX;
  char *file_minimo;
  char new_path[256];
  int fd;
  
  /* Controllo input */
  if (argc != 3) {
    printf("Usage %s ext <path>\n", argv[0]);
    exit(1);  
  }
  
  /* Chiamata funzione su directory passata */
  cerca_ext(argv[2]);
  
  /* Ora ho tutti i dati che mi servono nell'array della struttura, stampo i dati e
  faccio la ricerca del size minimo */
  for (i=0; i<contatore; i++){
    printf("File %s, peso %d, permesso %d\n", array_file_ext[i].nome_file, array_file_ext[i].size, array_file_ext[i].permesso); 
    if (array_file_ext[i].size < size_minimo)
      size_minimo = array_file_ext[i].size;
    file_minimo = array_file_ext[i].nome_file;
  } 
  printf("Ho trovato %d file terminanti per exc\n", contatore);
  printf("Quello che pesa meno e' %s, che pesa %d\n", file_minimo, size_minimo);
  
  /* Creo il nome del nuovo file txt che conterra' i nome dei file .ext tramite
  manipolazioni sulle stringhe */
  len_da_copiare = strlen(file_minimo)-4;
  strncpy(new_path, file_minimo, len_da_copiare);
  new_path[len_da_copiare]='\0';
  strcat(new_path, ".txt");
  
  /* Creo un nuovo file */
  fd = creat (new_path, 0744);
  
  /* Scrittura nel file */
  for (i=0; i<contatore; i++){
    write (fd, array_file_ext[i].nome_file, sizeof(char)*strlen(array_file_ext[i].nome_file));
    write (fd, &"\n", sizeof(char));
  }
  
  /* Chiusura descrittore e uscita */
  close(fd);
  exit(0);
} 

void cerca_ext (char *path) { 
  /* Dichiarazione delle variabili */
  DIR *directory;
  struct dirent *file;
  struct stat info_file;
  char newpath[256], *ptr;
  char cwd[256];
  int mask=4;          //Permessi in lettura altri
  
  /* Apro directory e me la salvo in newpath*/
  directory = opendir (path);
  strcpy (newpath, path);
  
  /* Finche' la directory ha file, li scorro per vedere se terminano con .ext */
  while (((file = readdir (directory))) != NULL){
    stat (file -> d_name, &info_file);    //Cerco informazioni stat
    
    /* Se e' una directory, devo aprirla e cercare all'interno, uso ricorsione */
    if (S_ISDIR(info_file.st_mode)) {
      if ((strncmp(file -> d_name, ".", 1))!=0) {
	/* Creo il nome del nuovo percorso sui cui fare la ricorsione */
	strcat (newpath, "/");
	strcat (newpath, file -> d_name);
	printf("new cartella: %s\n", newpath);
	cerca_ext(newpath);
      }
    }
    /* Se sono qui non è una directory il file che sto esaminando */
    else {
      if ((ptr = strstr(file->d_name, ".ext")) != NULL) {  //Impreciso, trova prima occ
	/* Stampo percorso del file e salvo i dati di mio interesse */ 
	getcwd(cwd, sizeof(cwd));
	printf("Ho trovato 1 file, %s/%s\n", cwd, file->d_name);
	array_file_ext[contatore].nome_file = file->d_name;
	array_file_ext[contatore].size = info_file.st_size;
	/* Confronto sui bit, se il permesso c'è salvera' 1, altrimenti 0 */
	if ((info_file.st_mode & S_IROTH) == mask)
	  array_file_ext[contatore].permesso = 1;
	else
	  array_file_ext[contatore].permesso = 0;
	contatore++;
      }     
    }  
  }
  closedir(directory);
}