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, *ptr;
char cwd[256];
int mask=4; //Permessi in lettura altri
int rimanenza = 1;
char elenco_directory_da_leggere[256][256]; //Il primo 256 sono le massime cartelle, il secondo il numero di caratteri
int contatore_directory_da_leggere = 0;
int prossimo_da_leggere = 0;
strcpy (elenco_directory_da_leggere[0], path);
do {
// Apro directory e me la salvo in newpath
directory = opendir (elenco_directory_da_leggere[prossimo_da_leggere]);
printf("\nSto leggendo in: %s\n", elenco_directory_da_leggere[prossimo_da_leggere]);
rimanenza--;
// 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
printf("%s %d\n", file ->d_name, info_file.st_mode);
// 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) { //Elimina . e ..
// Creo il nome del nuovo percorso sui cui fare la ricorsione
newpath = (char *) malloc (256*sizeof(char));
strcpy (newpath, getcwd(cwd, sizeof(cwd)));
strcat (newpath, "/");
strcat (newpath, file -> d_name);
printf("Trovata dire: %s\n", newpath);
contatore_directory_da_leggere++;
rimanenza++;
strcpy (elenco_directory_da_leggere[contatore_directory_da_leggere], 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
if (strlen(file -> d_name) >= 4) {
if (strncmp(file -> d_name + strlen(file -> d_name) - 4, ".ext", 4) == 0) {
// Stampo percorso del file e salvo i dati di mio interesse
getcwd(cwd, sizeof(cwd));
printf("Trovato 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++;
}
}
}
// Pulizia info_file e chiusura directory
memset((void *) &info_file, 0, sizeof(info_file));
}
// Qui ci arrivo quando ho letto tutti i file contenuti in una directory
prossimo_da_leggere++;
closedir(directory);
printf("Rimanenza %d\n", rimanenza);
}
while (rimanenza > 0);
newpath = NULL;
free(newpath);
}