/** Esercizio 2 * Scrivere cpsymlink: che ha come parametro il pathname di una directory. * Il programma deve cercare tutti i link simbolici presenti nella directory * e sostituire ogni link simbolico che punta ad un file regolare con la copia * del file puntato. * * link testo: https://dynamik.vercel.app/sistemi-operativi/prove/pratica/scritto-2021-01-18-testo.pdf */ #include <stdio.h> #include <stdlib.h> #include <sys/types.h> // stat, lstat #include <sys/stat.h> // stat, lstat #include <unistd.h> // stat, lstat #include <fcntl.h> // stat, lstat #include <sys/sendfile.h> // sendfile #include <dirent.h> // opendir, readdir // copiare un file da una directory all'altra int copyfile(const char *directory, const char *name){ int fd = open(directory, O_RDONLY); if (fd == -1) { perror("open"); return -1; } int fd_copy = open(name, O_WRONLY | O_CREAT, 0666); // 0666 = mode_t mode = e` il set of permission struct stat stat_buf; lstat(directory, &stat_buf); sendfile(fd_copy, fd, 0, stat_buf.st_size); close(fd_copy); close(fd); return 0; } int main(int argc, char* argv){ if (argc != 2){ printf("Numero parametri errato!"); exit(EXIT_FAILURE); } char pathname = argv[1]; struct stat s; // statistiche di symlink lstat(pathname, &s); // controllo se il pathname ha sym link if (S_ISDIR(s.st_mode)){ DIR *directory = opendir(pathname); struct dirent *entry; // directory entry while ((entry = readdir(directory))!= NULL){ int fd = open(entry->d_name, O_RDONLY); // file descriptor if (fd != -1){ struct stat filestat; lstat(entry->d_name, &filestat); if (S_ISLNK(filestat.st_mode)){ // il file e` davvero un link //sostituisco il file con la copia char real_path[1024]; // 1024 caratteri max realpath(entry->d_name, real_path); close(fd); char real_name[1024]; strcpy(real_name, entry->d_name); // salvo il nome del file unlink(entry->d_name); copyfile(real_path, real_name); } else // il file non e` un link close(fd); } } } else exit(EXIT_FAILURE); return 0; }