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.2
    Estendere l'esempio 'move.c' visto a lezione per supportare i 2 casi speciali:
    - spostamento cross-filesystem: individuato tale caso, il file deve essere
      spostato utilizzando la strategia "copia & cancella";
    - spostamento di un link simbolico: individuato tale caso, il link simbolico
      deve essere ricreato a destinazione con lo stesso contenuto (ovvero il percorso
      che denota l'oggetto referenziato); notate come tale spostamento potrebbe
      rendere il nuovo link simbolico non effettivamente valido.
    La sintassi da supportare e' la seguente:
     $ homework-2  
*/
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#define BUFSIZE 2048
int main(int argc, char *argv[]) {
    struct stat src_statbuf, dst_statbuf;
    int src_d, dst_d, size;
    char buffer[BUFSIZE];
    char *dst_dir;
    if (argc != 3) {
        fprintf(stderr, "utilizzo: %s  \n", argv[0]);
        exit(1);
    }
    if (lstat(argv[1], &src_statbuf) == -1) {
        perror(argv[1]);
        exit(1);
    }
    /* determina il tipo di oggetto da spostare */
    switch (src_statbuf.st_mode & S_IFMT) {
    case S_IFLNK:
        /* legge il pathname del link simbolico */
        if ((size = readlink(argv[1], buffer, BUFSIZE)) == -1) {
            perror(argv[1]);
            exit(1);
        }
        buffer[size] = '\0';
        /* crea un nuovo link simbolico con lo stesso pathname
           quest'ultimo potrebbe non essere piu' corretto...   */
        if (symlink(buffer, argv[2]) == -1) {
            perror(argv[2]);
            exit(1);
        }
        break;
    case S_IFREG:
        /* estrae dalla destinazione la directory padre: ne crea
           una copia perche' dirname potrebbe modificare la stringa */
        strncpy(buffer, argv[2], BUFSIZE);
        dst_dir = dirname(buffer);
        if (stat(dst_dir, &dst_statbuf) == -1) {
            perror(dst_dir);
            exit(1);
        }
        /* controlla che si tratti effettivamente di una directory */
        if (!S_ISDIR(dst_statbuf.st_mode)) {
            fprintf(stderr, "il percorso '%s' non sembra essere una directory!\n", dst_dir);
            exit(1);
        }
        /* cerca di capire se la sorgente e la directory di destinazione risiedono sullo stesso file-system;
           in alternativa si poteva tentare la creazione dell'hard-link e verificare la condizione
           (errno==EXDEV) in caso di errore                                                         */
        if (src_statbuf.st_dev == dst_statbuf.st_dev) {     // si trovano sullo stesso file-system
            printf("stesso fs\n");
            /* crea un hard-link a partire dal file esistente */
            if (link(argv[1], argv[2]) == -1) {
                perror(argv[2]);
                exit(1);
            }
        } else {    // si trovano su due file-system diversi: non posso usare gli hard-link
            printf("diverso fs\n");
            /* effettua una copia standard del file sorgente sulla destinazione */
            if ((src_d = open(argv[1], O_RDONLY)) == -1) {
                perror(argv[1]);
                exit(1);
            }
            if ((dst_d = open(argv[2], O_WRONLY|O_CREAT|O_TRUNC, (src_statbuf.st_mode & 0777))) == -1) {
                perror(argv[2]);
                exit(1);
            }
            do {
                if ((size = read(src_d, buffer, BUFSIZE)) == -1) {
                    perror(argv[1]);
                    exit(1);
                }
                if (write(dst_d, buffer, size) == -1) {
                    perror(argv[2]);
                    exit(1);
                }
            } while (size == BUFSIZE);
            close(src_d);
            close(dst_d);
        }
        break;
    default:
        fprintf(stderr, "tipo di oggetto non supportato!\n");
        exit(1);
    }
    /* rimuove l'oggetto sorgente */
    if (unlink(argv[1]) == -1) {
        perror(argv[1]);
        exit(1);
    }
}