Intanto ecco il codice:
Codice: Seleziona tutto
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#define N 100
#define BUFFSIZE 4096
void recursiveCopyDirectoryTree(char* source, char* dest);
int main(int argc, char** argv)
{
DIR* destDP;
if(mkdir(argv[2], S_IRUSR | S_IWUSR | S_IXUSR)==-1)
{
printf("\nmkdir error!");
exit(1);
}
if((destDP=opendir(argv[2]))==NULL)
{
printf("\nopendir error!");
exit(1);
}
recursiveCopyDirectoryTree(argv[1], argv[2]);
if(closedir(destDP)==-1)
{
printf("\nclosedir error!");
exit(1);
}
return 0;
}
void recursiveCopyDirectoryTree(char* source, char* dest)
{
int nR, nW, sourceFD, destFD;
struct stat statBuf;
struct dirent* entry;
char sourceFullName[N], destFullName[N], buf[BUFFSIZE];
DIR* sourceDP;
DIR* destDP;
if(lstat(source, &statBuf)==-1)
{
printf("\nlstat error!");
exit(1);
}
if(S_ISDIR(statBuf.st_mode)==0)
{
printf("\nsource is not a directory!");
exit(1);
}
if((sourceDP=opendir(source))==NULL)
{
printf("\nopendir error!");
exit(1);
}
while((entry=readdir(sourceDP))!=NULL)
{
if(strcmp(entry->d_name, ".")!=0 && strcmp(entry->d_name, "..")!=0)
{
sprintf(sourceFullName, "%s/%s", source, entry->d_name);
sprintf(destFullName, "%s/%s", dest, entry->d_name);
if(lstat(sourceFullName, &statBuf)==-1)
{
printf("\nlstat error!");
exit(1);
}
if(S_ISREG(statBuf.st_mode))
{
sourceFD=open(sourceFullName, O_RDONLY);
destFD=open(destFullName, O_WRONLY | O_CREAT | O_TRUNC | O_EXCL, S_IWUSR | S_IRUSR | S_IXUSR);
if(sourceFD==-1 || destFD==-1)
{
printf("\nerror opening a file!");
exit(1);
}
while((nR=read(sourceFD, buf, sizeof(buf)))>0)
{
nW=write(destFD, buf, nR);
if(nW!=nR)
{
printf("\nerror: read %d, wrote %d", nR, nW);
exit(1);
}
if(nR<0)
{
printf("\nwrite error!");
exit(1);
}
close(sourceFD);
close(destFD);
}
}
else
{
if(mkdir(destFullName, S_IRUSR | S_IWUSR | S_IXUSR)==-1)
{
printf("\nmkdir error!");
exit(1);
}
if((destDP=opendir(destFullName))==NULL)
{
printf("\nopendir error!");
exit(1);
}
recursiveCopyDirectoryTree(sourceFullName, destFullName);
closedir(sourceDP);
closedir(destDP);
}
}
}
}
Cosa ho sbagliato?
Inoltre avrei un po' di domande su alcuni particolari che mi potrebbero aiutare in futuro:
1) la mkdir iniziale nel main che crea la cartella di destinazione provoca l'uscita dal programma se la cartella è già presente.. come evito ciò?
2) il pezzo di codice che legge dai file "source" e scrive nei file "dest" l'ho preso da alcune slide ma non capisco il controllo che viene subito dopo il while (che nella slide viene spiegato con "controllo sull'ultima lettura").
3) nel caso volessi copiare dei file binari il buf di che tipo sarà? in questo caso sono dei file di testo quindi mi sembra scontato che bisogna allocare dei buf di tipo char.
4) ieri, non so per quale motivo, mi dava problemi la opendir fatta nel main e provando ad eliminarla il programma funzionava comunque alla stessa maniera. Quindi l'opendir ha senso dopo aver creato una nuova cartella o no?
5) per il terzo argomento della open si può scrivere (nel caso in cui volessi dare tutti i permessi allo user) soltanto S_IRWXUSR al posto di separarli con l'or bit a bit?
Grazie per l'aiuto!!