Allora, non ho ancora capito su quale tipo di file/dir viene generato l'errore.
Comunque ho messo tutto in unico file, tralasciando l'uso delle pipe ma stampando soltanto a video i file trovati. Il file e' compilabile digitando soltanto "gcc -o fileL fileL.c" ed eseguibile con "fileL nomeDir".
Ancora segmentation fault in alcune directory.
L'errore, credo, si verifichi trattando "particolari" tipi di file (Ma non so quali).
Mi aiutate ?
Eccolo qua:
codice:
#include <dirent.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h> /* serve per la perror */
#include <string.h> /* serve per strlen */
#include <errno.h> /* serve per errno */
#include <stdlib.h>
#include <dirent.h>
#include <unistd.h>
#define IFERROR(s,m) if((s)==-1) {perror(m); exit(errno);}
#define IFERROR3(s,m,c) if((s)==-1) {perror(m); c;}
#define WRITE(m) IFERROR(write(STDOUT,m,strlen(m)), m);
#define WRITELN(m) WRITE(m);WRITE("\n");
#define STDIN 0
#define STDOUT 1
#define STDERR 2
#define FALSE 0
#define TRUE 1
#define SUCCESS -5
#define ERROR -10
#define FAILURE -15
static int sendFiles(DIR *, int);
static int fileL_1(char*);
static int checkTxt(char*);
int main(int argc, char*argv[])
{
if (argc < 2)
{
printf("Usage: fileL dirName");
exit(-1);
}
int returnValue;
if ((returnValue=fileL_1(argv[1])) == SUCCESS)
printf("fileList_1: SUCCESS\n");
else
printf("fileList_1: ERROR\n");
return(0);
}
int checkTxt(char* fileName)
{
if (fileName == NULL)
return FALSE;
int length = strlen(fileName);/*Lunghezza del nome del file*/
char*ext = fileName + (length - 4);/*Puntatore agli ultimi 4 caratteri */
if (strcmp(ext,".txt") == 0)
return TRUE;/*Per "terminare" la ricorsione*/
else return FALSE;
}
int fileL_1 (char * dirName)
{
DIR * dir;
/*Apro la directory*/
if ((dir = opendir(dirName)) == NULL)
return FAILURE;
int returnValue;
if (chdir(dirName)== -1)
{
perror("Error on chdir");
exit(errno);
}
returnValue = sendFiles(dir, SUCCESS);
if (returnValue == FAILURE)
{WRITELN("fileList_1: error searching the files");}
else/*Mando il messaggio di fine operazione*/
{WRITELN("fileList_1: operation terminated");}
if (closedir(dir) == -1)/*Chiusura directory*/
perror("fileList_1: error closeing directory");
return returnValue;/*Per far capire alla call1 se l'operazione e' andata a buon fine oppure no*/
}
static int sendFiles(DIR * dir, int result)
{
/*Effects:
invia ricorsivamente sulla pipe fd
tutti i file contenuti nella directory; dir e nelle sue sottodirectory
*/
int res = result;
/*Finche' err vale SUCCESS non ci sono stati errori
Quando error varra' FAILURE le chiamate ricorsive termineranno*/
struct dirent * infoDirent;
struct stat infoStat;
char * superdir = getcwd(NULL, 0);//?
while(((infoDirent = readdir(dir)) != NULL) && (res == SUCCESS))
{
if ((lstat(infoDirent->d_name, &infoStat)) == -1)
/*Non voglio avere problemi con i link simbolici*/
{
res = FAILURE;
return res;
}
if (S_ISDIR(infoStat.st_mode))
{/*Se e' una directory ed e' permesso a chiunque l'accesso in lettura */
if(strcmp(infoDirent->d_name, "..") && strcmp(infoDirent->d_name, ".") && ((infoStat.st_mode & (S_IROTH|S_IXOTH|S_IRGRP|S_IXGRP|S_IRUSR|S_IXUSR)) == (S_IROTH|S_IXOTH|S_IRGRP|S_IXGRP|S_IRUSR|S_IXUSR)))
{/*...e non e' ne' "." ne' ".."*/
DIR * sottodir;
if ((sottodir = opendir(infoDirent->d_name)) == NULL)
{
res = FAILURE;
return res;
}
/*La rendo directory corrente*/
if (chdir(infoDirent->d_name) == -1)
{
res = FAILURE;
return res;
}
/*Applico ricorsivamente la funzione*/
res = sendFiles(sottodir, res);
if (closedir(sottodir) == -1)
perror("fileList_1: error on closedir");
/*Al termine della chiamata ricorsiva chiudo la directory
e torno in quella DA CUI ERO VENUTO (Solitamente quella padre...
ma non necessariamente...) per poter fare correttamente le rimanenti stat*/
if (chdir(superdir) == -1)
{
res = FAILURE;
return res;
}
}
}
/*E' un file: lo devo inviare !*/
else
{
if (S_ISREG(infoStat.st_mode) && ((infoStat.st_mode & (S_IROTH|S_IRGRP|S_IRUSR)) == (S_IROTH|S_IRGRP|S_IRUSR)))
/*Considero solo i file che chiunque puo' leggere*/
{
if (checkTxt(infoDirent->d_name) == TRUE)
{
char * pathName;
pathName = getcwd(NULL, 0);
char * completeName = (char*) malloc(strlen(pathName) + 1 + strlen(infoDirent->d_name));
sprintf(completeName,"%s/%s",pathName, infoDirent->d_name);
//printf("DataServer: invio %s lungo %d caratteri\n", completeName, strlen(completeName));
printf("File: %s\n", completeName);
free(pathName);
free(completeName);
}
}
}
}
return res;
}