Ho messo insieme un po' le idee, ripassato un po' la ricorsione e studiato i vari listati proposti, e ho messo in codice ciò che ho capito e a modo mio (nel senso di provare a scrivere
e non fare copia incolla).
Il listato non è completo, con i test sugli errori, e magari in alcuni punti esco senza curarmi se un descrittore è aperto o meno.
comunque per il momento l'importante è capire come copiare directory, sottodirectory e file nell'ordine preciso della cartella d'origine.
Ho apportato una modifica, non so se buona o meno. In termini di velocità credo sia penalizzante, ma risparmio l'allocazione dinamica delle liste o un vettore bidimensionale.
In poche parole al posto di salvare i nomi dei files da copiare in una lista, li leggo e uno ad uno vado nella cartelle destinazione e li copio.
Dopo averli copiati ripristino il percorso (tolgo il nome del file) es:
mia_cartella/file.txt ritorno a mia_cartella/
con un semplice puntatore che inizialmente punta alla fine della stringa, poi rimette il '\0' e il nome del file viene "troncato".
Insomma vi posto il codice...certo non è raffinatissimo, ci devo ancora lavorare
Comunque mi avete davvero aiutato, non credevo fosse così un casino copiare cartelle
Codice: Seleziona tutto
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <dirent.h>
#include <stdbool.h>
#define SIZE_BUF 1024
struct dirent *info;
struct stat info_stat;
int DirWalk(const char *origin, int *cont, int *contDir, char *dest);
void crea_dir(char *copy_dest);
int test_origin(const char *origin);
void copia_files(char *copy_path,char *copy_dest);
void copia_files(char *copy_path,char *copy_dest)
{
FILE *fpin, *fpout;
char static_buf[SIZE_BUF];
int len,n;
char *p;
len=strlen(copy_dest);
p=©_dest[len];
strncat(copy_dest,info->d_name,PATH_MAX);
fpin = fopen(copy_path,"rb");
if(fpin==NULL)
{
puts("errore apertura file");
exit (1);
}
fpout = fopen(copy_dest, "wb");
if(fpin==NULL)
{
puts("errore apertura file");
exit (1);
}
for(;;)
{
n = fread(static_buf, 1, SIZE_BUF, fpin);
if( n == 0 )
{
break;
}
fwrite(static_buf, 1, n, fpout);
}
fclose(fpin);
fclose(fpout);
// ripristino percorso: cartella/sotto_cart/file.txt-->>cartella/sotto_cart/
*p='\0';
}
int test_origin(const char *origin)
{
DIR *dir;
if ((dir = opendir(origin)) == NULL)
{
printf ("Impossibile aprire la directory %s\n", origin);
return 0;
}
else
{
closedir(dir);
return 1;
}
}
void crea_dir(char *copy_dest)
{
int res;
int len;
res= mkdir(copy_dest, S_IRWXU);
if (res!=0)
{
printf ("errore nella creazione della cartella %s\n", copy_dest);
exit (EXIT_FAILURE);
}
len=strlen(copy_dest);
copy_dest[len]='/';
len++;
copy_dest[len]='\0';
}
int DirWalk(const char *origin, int *cont, int *contDir, char *dest)
{
DIR *dir;
char temp[PATH_MAX+1];
char path[PATH_MAX + 1];
strncpy(temp,dest,PATH_MAX);
/* Apro il descrittore della directory */
if ((dir = opendir(origin)) == NULL)
{
printf ("Impossibile aprire la directory %s\n", origin);
exit (EXIT_FAILURE);
}
/* Finché ci sono file all'interno della directory... */
while ((info = readdir(dir)) != NULL)
{
if ((strncmp(info->d_name, ".", PATH_MAX) == 0) || (strncmp(info->d_name, "..", PATH_MAX) == 0 ))
{
continue;
}
strncpy(path, origin, PATH_MAX);
strncat(path, "/", PATH_MAX);
strncat(path, info->d_name, PATH_MAX);
stat(path, &info_stat);
if(S_ISREG(info_stat.st_mode) == true)
{
(*cont)++;
copia_files(path,dest);
}
else if(S_ISDIR(info_stat.st_mode) == true)
{
(*contDir)++;
strncat (dest,info->d_name,PATH_MAX);
crea_dir(dest);
DirWalk(path, cont, contDir,dest);
}
strncpy(dest,temp,PATH_MAX);
}
closedir(dir);
return 0;
}
int main(void)
{
char origin[PATH_MAX + 1];
char dest [PATH_MAX + 1];
int len;
int cont = 0;
int contDir = 0;
printf ("immetti cartella origine: ");
fgets (origin, PATH_MAX, stdin);
len = strnlen(origin, PATH_MAX);
len--;
origin[len] = '\0';
printf ("immetti cartella dest: ");
fgets (dest, PATH_MAX, stdin);
len = strnlen(dest, PATH_MAX);
len--;
dest[len] = '\0';
if ( (test_origin(origin))==1)
crea_dir(dest);
else
{
printf ("la cartella [%s] non esiste\n",origin);
return 0;
}
DirWalk(origin, &cont, &contDir,dest);
printf ("numero regular files : %d\n", cont);
printf ("numero directory : %d\n", contDir);
return 0;
}Dategli un occhio se avete voglia. A me sembra (sembra) esente da bugs e copia correttamente
