#include "internal.h" #include #include #include #include #include const char cp_usage[] = "cp [-r] source-file destination-file\n" "\t\tcp [-r] source-file [source-file ...] destination-directory\n" "\n" "\tCopy the source files to the destination.\n" "\n" "\t-r:\tRecursively copy all files and directories\n" "\t\tunder the argument directory."; extern int cp_fn(const struct FileInfo * i) { int sourceFd; int destinationFd; const char * destination = i->destination; struct stat destination_stat; int status; char buf[8192]; char d[PATH_MAX]; if ( (i->stat.st_mode & S_IFMT) == S_IFDIR ) { if ( mkdir(destination, i->stat.st_mode & ~S_IFMT) != 0 && errno != EEXIST ) { name_and_error(destination); return 1; } return 0; } if ( (sourceFd = open(i->source, O_RDONLY)) < 0 ) { name_and_error(i->source); return 1; } if ( stat(destination, &destination_stat) == 0 ) { if ( i->stat.st_ino == destination_stat.st_ino && i->stat.st_dev == destination_stat.st_dev ) { fprintf(stderr ,"copy of %s to %s would copy file to itself.\n" ,i->source ,destination); close(sourceFd); return 1; } } /* * If the destination is a directory, create a file within it. */ if ( (destination_stat.st_mode & S_IFMT) == S_IFDIR ) { destination = join_paths( d ,i->destination ,&i->source[i->directoryLength]); if ( stat(destination, &destination_stat) == 0 ) { if ( i->stat.st_ino == destination_stat.st_ino && i->stat.st_dev == destination_stat.st_dev ) { fprintf(stderr ,"copy of %s to %s would copy file to itself.\n" ,i->source ,destination); close(sourceFd); return 1; } } } destinationFd = creat(destination, i->stat.st_mode & 07777); while ( (status = read(sourceFd, buf, sizeof(buf))) > 0 ) { if ( write(destinationFd, buf, status) != status ) { name_and_error(destination); close(sourceFd); close(destinationFd); return 1; } } close(sourceFd); close(destinationFd); if ( status < 0 ) { name_and_error(i->source); return 1; } return 0; }