diff options
Diffstat (limited to 'coreutils')
| -rw-r--r-- | coreutils/cp.c | 206 | ||||
| -rw-r--r-- | coreutils/mv.c | 6 |
2 files changed, 132 insertions, 80 deletions
diff --git a/coreutils/cp.c b/coreutils/cp.c index 078a57c56..797663d2b 100644 --- a/coreutils/cp.c +++ b/coreutils/cp.c | |||
| @@ -1,89 +1,141 @@ | |||
| 1 | /* | ||
| 2 | * Mini cp implementation for busybox | ||
| 3 | * | ||
| 4 | * Copyright (C) 1998 by Erik Andersen <andersee@debian.org> | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License as published by | ||
| 8 | * the Free Software Foundation; either version 2 of the License, or | ||
| 9 | * (at your option) any later version. | ||
| 10 | * | ||
| 11 | * This program is distributed in the hope that it will be useful, | ||
| 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 14 | * General Public License for more details. | ||
| 15 | * | ||
| 16 | * You should have received a copy of the GNU General Public License | ||
| 17 | * along with this program; if not, write to the Free Software | ||
| 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
| 19 | * | ||
| 20 | */ | ||
| 21 | |||
| 1 | #include "internal.h" | 22 | #include "internal.h" |
| 2 | #include <stdio.h> | 23 | #include <stdio.h> |
| 3 | #include <sys/stat.h> | 24 | #include <time.h> |
| 4 | #include <sys/fcntl.h> | 25 | #include <utime.h> |
| 5 | #include <sys/param.h> | 26 | #include <dirent.h> |
| 6 | #include <errno.h> | 27 | |
| 7 | 28 | const char cp_usage[] = "cp [OPTION]... SOURCE DEST\n" | |
| 8 | const char cp_usage[] = "cp [-r] source-file destination-file\n" | 29 | " or: cp [OPTION]... SOURCE... DIRECTORY\n" |
| 9 | "\t\tcp [-r] source-file [source-file ...] destination-directory\n" | 30 | "Copy SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY.\n" |
| 10 | "\n" | 31 | "\n" |
| 11 | "\tCopy the source files to the destination.\n" | 32 | "\t-a\tsame as -dpR\n" |
| 12 | "\n" | 33 | "\t-d\tpreserve links\n" |
| 13 | "\t-r:\tRecursively copy all files and directories\n" | 34 | "\t-p\tpreserve file attributes if possable\n" |
| 14 | "\t\tunder the argument directory."; | 35 | "\t-R\tcopy directories recursively\n"; |
| 15 | 36 | ||
| 16 | extern int | 37 | |
| 17 | cp_fn(const struct FileInfo * i) | 38 | static int recursiveFlag = FALSE; |
| 39 | static int followLinks = FALSE; | ||
| 40 | static int preserveFlag = FALSE; | ||
| 41 | static const char *srcName; | ||
| 42 | static const char *destName; | ||
| 43 | |||
| 44 | |||
| 45 | static int fileAction(const char *fileName) | ||
| 18 | { | 46 | { |
| 19 | int sourceFd; | 47 | char newdestName[NAME_MAX]; |
| 20 | int destinationFd; | 48 | strcpy(newdestName, destName); |
| 21 | const char * destination = i->destination; | 49 | strcat(newdestName, fileName+(strlen(srcName))); |
| 22 | struct stat destination_stat; | 50 | fprintf(stderr, "A: copying %s to %s\n", fileName, newdestName); |
| 23 | int status; | 51 | return (copyFile(fileName, newdestName, preserveFlag, followLinks)); |
| 24 | char buf[8192]; | 52 | } |
| 25 | char d[PATH_MAX]; | 53 | |
| 26 | 54 | static int dirAction(const char *fileName) | |
| 27 | if ( (i->stat.st_mode & S_IFMT) == S_IFDIR ) { | 55 | { |
| 28 | if ( mkdir(destination, i->stat.st_mode & ~S_IFMT) | 56 | char newdestName[NAME_MAX]; |
| 29 | != 0 && errno != EEXIST ) { | 57 | struct stat statBuf; |
| 30 | name_and_error(destination); | 58 | struct utimbuf times; |
| 31 | return 1; | 59 | |
| 32 | } | 60 | strcpy(newdestName, destName); |
| 33 | return 0; | 61 | strcat(newdestName, fileName+(strlen(srcName))); |
| 62 | if (stat(newdestName, &statBuf)) { | ||
| 63 | if (mkdir( newdestName, 0777777 ^ umask (0))) { | ||
| 64 | perror(newdestName); | ||
| 65 | return( FALSE); | ||
| 66 | } | ||
| 34 | } | 67 | } |
| 35 | if ( (sourceFd = open(i->source, O_RDONLY)) < 0 ) { | 68 | else if (!S_ISDIR (statBuf.st_mode)) { |
| 36 | name_and_error(i->source); | 69 | fprintf(stderr, "`%s' exists but is not a directory", newdestName); |
| 37 | return 1; | 70 | return( FALSE); |
| 38 | } | 71 | } |
| 39 | if ( stat(destination, &destination_stat) == 0 ) { | 72 | if (preserveFlag==TRUE) { |
| 40 | if ( i->stat.st_ino == destination_stat.st_ino | 73 | /* Try to preserve premissions, but don't whine on failure */ |
| 41 | && i->stat.st_dev == destination_stat.st_dev ) { | 74 | if (stat(newdestName, &statBuf)) { |
| 42 | fprintf(stderr | 75 | perror(newdestName); |
| 43 | ,"copy of %s to %s would copy file to itself.\n" | 76 | return( FALSE); |
| 44 | ,i->source | 77 | } |
| 45 | ,destination); | 78 | chmod(newdestName, statBuf.st_mode); |
| 46 | close(sourceFd); | 79 | chown(newdestName, statBuf.st_uid, statBuf.st_gid); |
| 47 | return 1; | 80 | times.actime = statBuf.st_atime; |
| 48 | } | 81 | times.modtime = statBuf.st_mtime; |
| 82 | utime(newdestName, ×); | ||
| 49 | } | 83 | } |
| 50 | /* | 84 | return TRUE; |
| 51 | * If the destination is a directory, create a file within it. | 85 | } |
| 52 | */ | 86 | |
| 53 | if ( (destination_stat.st_mode & S_IFMT) == S_IFDIR ) { | 87 | extern int cp_main(int argc, char **argv) |
| 54 | destination = join_paths( | 88 | { |
| 55 | d | 89 | |
| 56 | ,i->destination | 90 | int dirFlag; |
| 57 | ,&i->source[i->directoryLength]); | 91 | |
| 58 | 92 | if (argc < 3) { | |
| 59 | if ( stat(destination, &destination_stat) == 0 ) { | 93 | fprintf(stderr, "Usage: %s", cp_usage); |
| 60 | if ( i->stat.st_ino == destination_stat.st_ino | 94 | return (FALSE); |
| 61 | && i->stat.st_dev == destination_stat.st_dev ) { | ||
| 62 | fprintf(stderr | ||
| 63 | ,"copy of %s to %s would copy file to itself.\n" | ||
| 64 | ,i->source | ||
| 65 | ,destination); | ||
| 66 | close(sourceFd); | ||
| 67 | return 1; | ||
| 68 | } | ||
| 69 | } | ||
| 70 | } | 95 | } |
| 96 | argc--; | ||
| 97 | argv++; | ||
| 71 | 98 | ||
| 72 | destinationFd = creat(destination, i->stat.st_mode & 07777); | 99 | /* Parse any options */ |
| 100 | while (**argv == '-') { | ||
| 101 | while (*++(*argv)) | ||
| 102 | switch (**argv) { | ||
| 103 | case 'a': | ||
| 104 | followLinks = TRUE; | ||
| 105 | preserveFlag = TRUE; | ||
| 106 | recursiveFlag = TRUE; | ||
| 107 | break; | ||
| 108 | case 'd': | ||
| 109 | followLinks = TRUE; | ||
| 110 | break; | ||
| 111 | case 'p': | ||
| 112 | preserveFlag = TRUE; | ||
| 113 | break; | ||
| 114 | case 'R': | ||
| 115 | recursiveFlag = TRUE; | ||
| 116 | break; | ||
| 117 | default: | ||
| 118 | fprintf(stderr, "Usage: %s\n", cp_usage); | ||
| 119 | exit(FALSE); | ||
| 120 | } | ||
| 121 | argc--; | ||
| 122 | argv++; | ||
| 123 | } | ||
| 124 | |||
| 125 | |||
| 126 | destName = argv[argc - 1]; | ||
| 73 | 127 | ||
| 74 | while ( (status = read(sourceFd, buf, sizeof(buf))) > 0 ) { | 128 | dirFlag = isDirectory(destName); |
| 75 | if ( write(destinationFd, buf, status) != status ) { | 129 | |
| 76 | name_and_error(destination); | 130 | if ((argc > 3) && !dirFlag) { |
| 77 | close(sourceFd); | 131 | fprintf(stderr, "%s: not a directory\n", destName); |
| 78 | close(destinationFd); | 132 | return (FALSE); |
| 79 | return 1; | ||
| 80 | } | ||
| 81 | } | 133 | } |
| 82 | close(sourceFd); | 134 | |
| 83 | close(destinationFd); | 135 | while (argc-- >= 2) { |
| 84 | if ( status < 0 ) { | 136 | srcName = *(argv++); |
| 85 | name_and_error(i->source); | 137 | return recursiveAction(srcName, recursiveFlag, followLinks, |
| 86 | return 1; | 138 | fileAction, fileAction); |
| 87 | } | 139 | } |
| 88 | return 0; | 140 | return( TRUE); |
| 89 | } | 141 | } |
diff --git a/coreutils/mv.c b/coreutils/mv.c index 610040d92..df56206a3 100644 --- a/coreutils/mv.c +++ b/coreutils/mv.c | |||
| @@ -37,7 +37,7 @@ extern int mv_main (int argc, char **argv) | |||
| 37 | const char *srcName; | 37 | const char *srcName; |
| 38 | const char *destName; | 38 | const char *destName; |
| 39 | const char *lastArg; | 39 | const char *lastArg; |
| 40 | BOOL dirFlag; | 40 | int dirFlag; |
| 41 | 41 | ||
| 42 | if (argc < 3) { | 42 | if (argc < 3) { |
| 43 | fprintf (stderr, "Usage: %s %s", *argv, mv_usage); | 43 | fprintf (stderr, "Usage: %s %s", *argv, mv_usage); |
| @@ -63,7 +63,7 @@ extern int mv_main (int argc, char **argv) | |||
| 63 | 63 | ||
| 64 | destName = lastArg; | 64 | destName = lastArg; |
| 65 | 65 | ||
| 66 | if (dirFlag) | 66 | if (dirFlag==TRUE) |
| 67 | destName = buildName (destName, srcName); | 67 | destName = buildName (destName, srcName); |
| 68 | 68 | ||
| 69 | if (rename (srcName, destName) >= 0) | 69 | if (rename (srcName, destName) >= 0) |
| @@ -74,7 +74,7 @@ extern int mv_main (int argc, char **argv) | |||
| 74 | continue; | 74 | continue; |
| 75 | } | 75 | } |
| 76 | 76 | ||
| 77 | if (!copyFile (srcName, destName, TRUE)) | 77 | if (!copyFile (srcName, destName, TRUE, FALSE)) |
| 78 | continue; | 78 | continue; |
| 79 | 79 | ||
| 80 | if (unlink (srcName) < 0) | 80 | if (unlink (srcName) < 0) |
