X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=coreutils%2Fcp.c;h=1e10f286839035b0ced254c0df02895d47b7b802;hb=2fe08c7afb3ddef42f304e78cb6edfa28e0741ef;hp=078a57c565b799ca8496f738a80c7b5df0f70295;hpb=cc8ed39b240180b58810784f844e253263594ac3;p=oweals%2Fbusybox.git diff --git a/coreutils/cp.c b/coreutils/cp.c index 078a57c56..1e10f2868 100644 --- a/coreutils/cp.c +++ b/coreutils/cp.c @@ -1,89 +1,129 @@ +/* + * Mini cp implementation for busybox + * + * + * Copyright (C) 1999 by Lineo, inc. + * Written by Erik Andersen , + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + #include "internal.h" #include -#include -#include -#include -#include +#include +#include +#include + +static const char cp_usage[] = "cp [OPTION]... SOURCE DEST\n" + " or: cp [OPTION]... SOURCE... DIRECTORY\n\n" + "Copy SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY.\n" + "\n" + "\t-a\tsame as -dpR\n" + "\t-d\tpreserve links\n" + "\t-p\tpreserve file attributes if possable\n" + "\t-R\tcopy directories recursively\n"; + -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."; +static int recursiveFlag = FALSE; +static int followLinks = FALSE; +static int preserveFlag = FALSE; +static const char *srcName; +static const char *destName; +static int destDirFlag = FALSE; +static int destExistsFlag = FALSE; +static int srcDirFlag = FALSE; -extern int -cp_fn(const struct FileInfo * i) +static int fileAction(const char *fileName, struct stat* statbuf) { - int sourceFd; - int destinationFd; - const char * destination = i->destination; - struct stat destination_stat; - int status; - char buf[8192]; - char d[PATH_MAX]; + char newdestName[NAME_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; + strcpy(newdestName, destName); + if ( srcDirFlag == TRUE ) { + if (recursiveFlag!=TRUE ) { + fprintf(stderr, "cp: %s: omitting directory\n", srcName); + return( TRUE); + } + strcat(newdestName, strstr(fileName, srcName) + strlen(srcName)); + } + + if (destDirFlag==TRUE && srcDirFlag == FALSE) { + if (newdestName[strlen(newdestName)-1] != '/' ) { + strcat(newdestName, "/"); + } + strcat(newdestName, srcName); } - 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; - } + + return (copyFile(fileName, newdestName, preserveFlag, followLinks)); +} + +extern int cp_main(int argc, char **argv) +{ + struct stat statBuf; + + if (argc < 3) { + usage (cp_usage); } - /* - * 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]); + argc--; + argv++; - 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; - } - } + /* Parse any options */ + while (**argv == '-') { + while (*++(*argv)) + switch (**argv) { + case 'a': + followLinks = TRUE; + preserveFlag = TRUE; + recursiveFlag = TRUE; + break; + case 'd': + followLinks = TRUE; + break; + case 'p': + preserveFlag = TRUE; + break; + case 'R': + recursiveFlag = TRUE; + break; + default: + usage (cp_usage); + } + argc--; + argv++; } - 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; - } + destName = argv[argc - 1]; + if (stat(destName, &statBuf) >= 0) { + destExistsFlag = TRUE; + if (S_ISDIR(statBuf.st_mode)) + destDirFlag = TRUE; } - close(sourceFd); - close(destinationFd); - if ( status < 0 ) { - name_and_error(i->source); - return 1; + + if ((argc > 3) && destDirFlag==FALSE) { + fprintf(stderr, "%s: not a directory\n", destName); + exit (FALSE); + } + + while (argc-- > 1) { + srcName = *(argv++); + srcDirFlag = isDirectory(srcName); + if (recursiveAction(srcName, recursiveFlag, followLinks, FALSE, + fileAction, fileAction) == FALSE) { + exit( FALSE); + } } - return 0; + exit( TRUE); }