Warning: Undefined array key "view" in /var/www/html/wp-content/uploads/classes/so/1920/lab-homeworks/index.php on line 2
Warning: Cannot modify header information - headers already sent by (output started at /var/www/html/wp-content/uploads/classes/so/1920/lab-homeworks/index.php:2) in /var/www/html/wp-content/uploads/classes/so/1920/lab-homeworks/index.php on line 47
Warning: Cannot modify header information - headers already sent by (output started at /var/www/html/wp-content/uploads/classes/so/1920/lab-homeworks/index.php:2) in /var/www/html/wp-content/uploads/classes/so/1920/lab-homeworks/index.php on line 48
Warning: Cannot modify header information - headers already sent by (output started at /var/www/html/wp-content/uploads/classes/so/1920/lab-homeworks/index.php:2) in /var/www/html/wp-content/uploads/classes/so/1920/lab-homeworks/index.php on line 49
Warning: Cannot modify header information - headers already sent by (output started at /var/www/html/wp-content/uploads/classes/so/1920/lab-homeworks/index.php:2) in /var/www/html/wp-content/uploads/classes/so/1920/lab-homeworks/index.php on line 50
Warning: Cannot modify header information - headers already sent by (output started at /var/www/html/wp-content/uploads/classes/so/1920/lab-homeworks/index.php:2) in /var/www/html/wp-content/uploads/classes/so/1920/lab-homeworks/index.php on line 51
/*
Homework n.4
Estendere l'esercizio 'homework n.1' affinche' operi correttamente
anche nel caso in cui tra le sorgenti e' indicata una directory, copiandone
il contenuto ricorsivamente. Eventuali link simbolici incontrati dovranno
essere replicati come tali (dovrà essere creato un link e si dovranno
preservare tutti permessi di accesso originali dei file e directory).
Una ipotetica invocazione potrebbe essere la seguente:
$ homework-4 directory-di-esempio file-semplice.txt path/altra-dir/ "nome con spazi.pdf" directory-destinazione
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define BUFSIZE 2048
void copy_element(const char *pathname, const char *destination, int depth) {
int sd, dd, size, i;
char buffer[BUFSIZE], buffer2[BUFSIZE];
struct stat statbuf;
DIR *dp;
struct dirent *entry;
/* prepara in 'buffer' il nome del file di destinazione:
/ */
strncpy(buffer, destination, BUFSIZE);
strncat(buffer, "/", BUFSIZE-strlen(buffer));
strncpy(buffer2, pathname, BUFSIZE); // ne faccio una copia, basename puo' alterarla
strncat(buffer, basename(buffer2), BUFSIZE-strlen(buffer));
if (lstat(pathname, &statbuf) == -1) {
perror(pathname);
exit(1);
}
// determina il tipo di oggetto da copiare
switch (statbuf.st_mode & S_IFMT) {
case S_IFLNK: // e' un link simbolico
// legge il pathname del link simbolico
if ((size = readlink(pathname, buffer2, BUFSIZE)) == -1) {
perror(pathname);
exit(1);
}
buffer2[size] = '\0';
printf("%*s%s (l)--> %s [=> %s]\n", depth, " ", pathname, buffer, buffer2);
// crea un nuovo link simbolico con lo stesso pathname interno
if (symlink(buffer2, buffer) == -1) {
perror(buffer);
exit(1);
}
break;
case S_IFREG: // e' un file regolare
printf("%*s%s (f)--> %s\n", depth, " ", pathname, buffer);
// apre il file sorgente di turno in sola lettura
if ((sd = open(pathname, O_RDONLY)) == -1) {
perror(pathname);
exit(1);
}
// apre il file destinazione in sola scrittura, con troncamento e creazione
if ((dd = open(buffer, O_WRONLY|O_CREAT|O_TRUNC, statbuf.st_mode & 0777)) == -1) {
perror(buffer);
exit(1);
}
// copia i dati dalla sorgente alla destinazione
do {
// legge fino ad un massimo di BUFSIZE byte dalla sorgente
if ((size = read(sd, buffer, BUFSIZE)) == -1) {
perror(pathname);
exit(1);
}
// scrive i byte letti
if (write(dd, buffer, size) == -1) {
perror(destination);
exit(1);
}
} while (size == BUFSIZE);
// chiude i file attualmente aperti
close(sd);
close(dd);
break;
case S_IFDIR: // e' una directory (da copiare ricorsivamente)
printf("%*s%s/ (d)--> %s/\n", depth, " ", pathname, buffer);
if (mkdir(buffer, statbuf.st_mode & 0777) == -1) {
perror(buffer);
if (errno != EEXIST) exit(1);
}
// apre la directory
if ((dp = opendir(pathname)) == NULL) {
perror(pathname);
return;
}
// legge le varie voci
while ((entry=readdir(dp)) != NULL) {
if (strcmp(entry->d_name,".") == 0 || strcmp(entry->d_name,"..") == 0 )
continue;
/* ricostruisce in buffer2 il pathname dell'elemento
interno alla directory da copiare ricorsivamente */
strncpy(buffer2, pathname, BUFSIZE);
strncat(buffer2, "/", BUFSIZE-strlen(buffer2));
strncat(buffer2, entry->d_name, BUFSIZE-strlen(buffer2));
// copia ricorsivamente l'elemento della directory
copy_element(buffer2, buffer, depth+1);
}
closedir(dp);
break;
default:
fprintf(stderr, "tipo di oggetto non supportato!\n");
exit(1);
}
}
int main(int argc, char *argv[]) {
int i;
if (argc < 3) {
printf("utilizzo: %s [...] \n", argv[0]);
exit(1);
}
for (i = 1; i < argc-1; i++)
copy_element(argv[i], argv[argc-1], 0);
}