From cc8ed39b240180b58810784f844e253263594ac3 Mon Sep 17 00:00:00 2001 From: Eric Andersen Date: Tue, 5 Oct 1999 16:24:54 +0000 Subject: Initial revision --- cp.c | 89 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 cp.c (limited to 'cp.c') diff --git a/cp.c b/cp.c new file mode 100644 index 000000000..078a57c56 --- /dev/null +++ b/cp.c @@ -0,0 +1,89 @@ +#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; +} -- cgit v1.2.3