1 /* 2 * Copyright (c) 1988 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * David Hitz of Auspex Systems Inc. 7 * 8 * %sccs.include.redist.c% 9 */ 10 11 #ifndef lint 12 char copyright[] = 13 "@(#) Copyright (c) 1988 The Regents of the University of California.\n\ 14 All rights reserved.\n"; 15 #endif /* not lint */ 16 17 #ifndef lint 18 static char sccsid[] = "@(#)cp.c 5.26 (Berkeley) 10/27/91"; 19 #endif /* not lint */ 20 21 /* 22 * cp copies source files to target files. 23 * 24 * The global PATH_T structures "to" and "from" always contain paths to the 25 * current source and target files, respectively. Since cp does not change 26 * directories, these paths can be either absolute or dot-realative. 27 * 28 * The basic algorithm is to initialize "to" and "from", and then call the 29 * recursive copy() function to do the actual work. If "from" is a file, 30 * copy copies the data. If "from" is a directory, copy creates the 31 * corresponding "to" directory, and calls itself recursively on all of 32 * the entries in the "from" directory. 33 */ 34 35 #include <sys/param.h> 36 #include <sys/stat.h> 37 #include <sys/mman.h> 38 #include <sys/time.h> 39 #include <dirent.h> 40 #include <fcntl.h> 41 #include <errno.h> 42 #include <unistd.h> 43 #include <stdio.h> 44 #include <stdlib.h> 45 #include <string.h> 46 #include "extern.h" 47 48 static void copy __P((void)); 49 static void copy_dir __P((void)); 50 static void copy_fifo __P((struct stat *, int)); 51 static void copy_file __P((struct stat *, int)); 52 static void copy_link __P((int)); 53 static void copy_special __P((struct stat *, int)); 54 static void setfile __P((struct stat *, int)); 55 static void usage __P((void)); 56 57 PATH_T from = { from.p_path, "" }; 58 PATH_T to = { to.p_path, "" }; 59 60 uid_t myuid; 61 int exit_val, myumask; 62 int iflag, pflag, orflag, rflag; 63 int (*statfcn)(); 64 char *progname; 65 66 main(argc, argv) 67 int argc; 68 char **argv; 69 { 70 extern int optind; 71 struct stat to_stat; 72 register int c, r; 73 int symfollow, lstat(), stat(); 74 char *old_to, *p; 75 76 /* 77 * The utility cp(1) is used by mv(1) -- except for usage statements, 78 * print the "called as" program name. 79 */ 80 progname = (p = rindex(*argv,'/')) ? ++p : *argv; 81 82 symfollow = 0; 83 while ((c = getopt(argc, argv, "Rfhipr")) != EOF) { 84 switch ((char)c) { 85 case 'f': 86 iflag = 0; 87 break; 88 case 'h': 89 symfollow = 1; 90 break; 91 case 'i': 92 iflag = isatty(fileno(stdin)); 93 break; 94 case 'p': 95 pflag = 1; 96 break; 97 case 'R': 98 rflag = 1; 99 break; 100 case 'r': 101 orflag = 1; 102 break; 103 case '?': 104 default: 105 usage(); 106 break; 107 } 108 } 109 argc -= optind; 110 argv += optind; 111 112 if (argc < 2) 113 usage(); 114 115 if (rflag && orflag) { 116 (void)fprintf(stderr, 117 "cp: the -R and -r options are mutually exclusive.\n"); 118 exit(1); 119 } 120 121 myuid = getuid(); 122 123 /* copy the umask for explicit mode setting */ 124 myumask = umask(0); 125 (void)umask(myumask); 126 127 /* consume last argument first. */ 128 if (!path_set(&to, argv[--argc])) 129 exit(1); 130 131 statfcn = symfollow || !rflag ? stat : lstat; 132 133 /* 134 * Cp has two distinct cases: 135 * 136 * % cp [-rip] source target 137 * % cp [-rip] source1 ... directory 138 * 139 * In both cases, source can be either a file or a directory. 140 * 141 * In (1), the target becomes a copy of the source. That is, if the 142 * source is a file, the target will be a file, and likewise for 143 * directories. 144 * 145 * In (2), the real target is not directory, but "directory/source". 146 */ 147 148 r = stat(to.p_path, &to_stat); 149 if (r == -1 && errno != ENOENT) { 150 err("%s: %s", to.p_path, strerror(errno)); 151 exit(1); 152 } 153 if (r == -1 || !S_ISDIR(to_stat.st_mode)) { 154 /* 155 * Case (1). Target is not a directory. 156 */ 157 if (argc > 1) { 158 usage(); 159 exit(1); 160 } 161 if (!path_set(&from, *argv)) 162 exit(1); 163 copy(); 164 } 165 else { 166 /* 167 * Case (2). Target is a directory. 168 */ 169 for (;; ++argv) { 170 if (!path_set(&from, *argv)) 171 continue; 172 if (!(old_to = 173 path_append(&to, path_basename(&from), -1))) 174 continue; 175 copy(); 176 if (!--argc) 177 break; 178 path_restore(&to, old_to); 179 } 180 } 181 exit(exit_val); 182 } 183 184 /* copy file or directory at "from" to "to". */ 185 static void 186 copy() 187 { 188 struct stat from_stat, to_stat; 189 int dne, statval; 190 191 statval = statfcn(from.p_path, &from_stat); 192 if (statval == -1) { 193 err("%s: %s", from.p_path, strerror(errno)); 194 return; 195 } 196 197 /* not an error, but need to remember it happened */ 198 if (stat(to.p_path, &to_stat) == -1) 199 dne = 1; 200 else { 201 if (to_stat.st_dev == from_stat.st_dev && 202 to_stat.st_ino == from_stat.st_ino) { 203 (void)fprintf(stderr, 204 "%s: %s and %s are identical (not copied).\n", 205 progname, to.p_path, from.p_path); 206 exit_val = 1; 207 return; 208 } 209 dne = 0; 210 } 211 212 switch(from_stat.st_mode & S_IFMT) { 213 case S_IFLNK: 214 copy_link(!dne); 215 return; 216 case S_IFDIR: 217 if (!rflag && !orflag) { 218 (void)fprintf(stderr, 219 "%s: %s is a directory (not copied).\n", 220 progname, from.p_path); 221 exit_val = 1; 222 return; 223 } 224 if (dne) { 225 /* 226 * If the directory doesn't exist, create the new 227 * one with the from file mode plus owner RWX bits, 228 * modified by the umask. Trade-off between being 229 * able to write the directory (if from directory is 230 * 555) and not causing a permissions race. If the 231 * umask blocks owner writes cp fails. 232 */ 233 if (mkdir(to.p_path, from_stat.st_mode|S_IRWXU) < 0) { 234 err("%s: %s", to.p_path, strerror(errno)); 235 return; 236 } 237 } 238 else if (!S_ISDIR(to_stat.st_mode)) { 239 (void)fprintf(stderr, "%s: %s: not a directory.\n", 240 progname, to.p_path); 241 return; 242 } 243 copy_dir(); 244 /* 245 * If not -p and directory didn't exist, set it to be the 246 * same as the from directory, umodified by the umask; 247 * arguably wrong, but it's been that way forever. 248 */ 249 if (pflag) 250 setfile(&from_stat, 0); 251 else if (dne) 252 (void)chmod(to.p_path, from_stat.st_mode); 253 return; 254 case S_IFCHR: 255 case S_IFBLK: 256 if (rflag) { 257 copy_special(&from_stat, !dne); 258 return; 259 } 260 break; 261 case S_IFIFO: 262 if (rflag) { 263 copy_fifo(&from_stat, !dne); 264 return; 265 } 266 break; 267 } 268 copy_file(&from_stat, dne); 269 } 270 271 static void 272 copy_file(fs, dne) 273 struct stat *fs; 274 int dne; 275 { 276 static char buf[MAXBSIZE]; 277 register int from_fd, to_fd, rcount, wcount; 278 struct stat to_stat; 279 char *p; 280 281 if ((from_fd = open(from.p_path, O_RDONLY, 0)) == -1) { 282 err("%s: %s", from.p_path, strerror(errno)); 283 return; 284 } 285 286 /* 287 * If the file exists and we're interactive, verify with the user. 288 * If the file DNE, set the mode to be the from file, minus setuid 289 * bits, modified by the umask; arguably wrong, but it makes copying 290 * executables work right and it's been that way forever. (The 291 * other choice is 666 or'ed with the execute bits on the from file 292 * modified by the umask.) 293 */ 294 if (!dne) { 295 if (iflag) { 296 int checkch, ch; 297 298 (void)fprintf(stderr, "overwrite %s? ", to.p_path); 299 checkch = ch = getchar(); 300 while (ch != '\n' && ch != EOF) 301 ch = getchar(); 302 if (checkch != 'y') { 303 (void)close(from_fd); 304 return; 305 } 306 } 307 to_fd = open(to.p_path, O_WRONLY|O_TRUNC, 0); 308 } else 309 to_fd = open(to.p_path, O_WRONLY|O_CREAT|O_TRUNC, 310 fs->st_mode & ~(S_ISUID|S_ISGID)); 311 312 if (to_fd == -1) { 313 err("%s: %s", to.p_path, strerror(errno)); 314 (void)close(from_fd); 315 return; 316 } 317 318 /* 319 * Mmap and write if less than 8M (the limit is so we don't totally 320 * trash memory on big files. This is really a minor hack, but it 321 * wins some CPU back. 322 */ 323 if (fs->st_size <= 8 * 1048576) { 324 if ((p = mmap(NULL, fs->st_size, PROT_READ, 325 MAP_FILE, from_fd, (off_t)0)) == (char *)-1) 326 err("%s: %s", from.p_path, strerror(errno)); 327 if (write(to_fd, p, fs->st_size) != fs->st_size) 328 err("%s: %s", to.p_path, strerror(errno)); 329 } else { 330 while ((rcount = read(from_fd, buf, MAXBSIZE)) > 0) { 331 wcount = write(to_fd, buf, rcount); 332 if (rcount != wcount || wcount == -1) { 333 err("%s: %s", to.p_path, strerror(errno)); 334 break; 335 } 336 } 337 if (rcount < 0) 338 err("%s: %s", from.p_path, strerror(errno)); 339 } 340 if (pflag) 341 setfile(fs, to_fd); 342 /* 343 * If the source was setuid or setgid, lose the bits unless the 344 * copy is owned by the same user and group. 345 */ 346 else if (fs->st_mode & (S_ISUID|S_ISGID) && fs->st_uid == myuid) 347 if (fstat(to_fd, &to_stat)) 348 err("%s: %s", to.p_path, strerror(errno)); 349 #define RETAINBITS (S_ISUID|S_ISGID|S_ISVTX|S_IRWXU|S_IRWXG|S_IRWXO) 350 else if (fs->st_gid == to_stat.st_gid && fchmod(to_fd, 351 fs->st_mode & RETAINBITS & ~myumask)) 352 err("%s: %s", to.p_path, strerror(errno)); 353 (void)close(from_fd); 354 if (close(to_fd)) 355 err("%s: %s", to.p_path, strerror(errno)); 356 } 357 358 static void 359 copy_dir() 360 { 361 struct stat from_stat; 362 struct dirent *dp, **dir_list; 363 register int dir_cnt, i; 364 char *old_from, *old_to; 365 366 dir_cnt = scandir(from.p_path, &dir_list, NULL, NULL); 367 if (dir_cnt == -1) { 368 (void)fprintf(stderr, "%s: can't read directory %s.\n", 369 progname, from.p_path); 370 exit_val = 1; 371 } 372 373 /* 374 * Instead of handling directory entries in the order they appear 375 * on disk, do non-directory files before directory files. 376 * There are two reasons to do directories last. The first is 377 * efficiency. Files tend to be in the same cylinder group as 378 * their parent, whereas directories tend not to be. Copying files 379 * all at once reduces seeking. Second, deeply nested tree's 380 * could use up all the file descriptors if we didn't close one 381 * directory before recursivly starting on the next. 382 */ 383 /* copy files */ 384 for (i = 0; i < dir_cnt; ++i) { 385 dp = dir_list[i]; 386 if (dp->d_namlen <= 2 && dp->d_name[0] == '.' 387 && (dp->d_name[1] == NULL || dp->d_name[1] == '.')) 388 goto done; 389 if (!(old_from = 390 path_append(&from, dp->d_name, (int)dp->d_namlen))) 391 goto done; 392 393 if (statfcn(from.p_path, &from_stat) < 0) { 394 err("%s: %s", dp->d_name, strerror(errno)); 395 path_restore(&from, old_from); 396 goto done; 397 } 398 if (S_ISDIR(from_stat.st_mode)) { 399 path_restore(&from, old_from); 400 continue; 401 } 402 if (old_to = path_append(&to, dp->d_name, (int)dp->d_namlen)) { 403 copy(); 404 path_restore(&to, old_to); 405 } 406 path_restore(&from, old_from); 407 done: dir_list[i] = NULL; 408 free(dp); 409 } 410 411 /* copy directories */ 412 for (i = 0; i < dir_cnt; ++i) { 413 dp = dir_list[i]; 414 if (!dp) 415 continue; 416 if (!(old_from = 417 path_append(&from, dp->d_name, (int)dp->d_namlen))) { 418 free(dp); 419 continue; 420 } 421 if (!(old_to = 422 path_append(&to, dp->d_name, (int)dp->d_namlen))) { 423 free(dp); 424 path_restore(&from, old_from); 425 continue; 426 } 427 copy(); 428 free(dp); 429 path_restore(&from, old_from); 430 path_restore(&to, old_to); 431 } 432 free(dir_list); 433 } 434 435 static void 436 copy_link(exists) 437 int exists; 438 { 439 int len; 440 char link[MAXPATHLEN]; 441 442 if ((len = readlink(from.p_path, link, sizeof(link))) == -1) { 443 err("readlink: %s: %s", from.p_path, strerror(errno)); 444 return; 445 } 446 link[len] = '\0'; 447 if (exists && unlink(to.p_path)) { 448 err("unlink: %s: %s", to.p_path, strerror(errno)); 449 return; 450 } 451 if (symlink(link, to.p_path)) { 452 err("symlink: %s: %s", link, strerror(errno)); 453 return; 454 } 455 } 456 457 static void 458 copy_fifo(from_stat, exists) 459 struct stat *from_stat; 460 int exists; 461 { 462 if (exists && unlink(to.p_path)) { 463 err("unlink: %s: %s", to.p_path, strerror(errno)); 464 return; 465 } 466 if (mkfifo(to.p_path, from_stat->st_mode)) { 467 err("mkfifo: %s: %s", to.p_path, strerror(errno)); 468 return; 469 } 470 if (pflag) 471 setfile(from_stat, 0); 472 } 473 474 static void 475 copy_special(from_stat, exists) 476 struct stat *from_stat; 477 int exists; 478 { 479 if (exists && unlink(to.p_path)) { 480 err("unlink: %s: %s", to.p_path, strerror(errno)); 481 return; 482 } 483 if (mknod(to.p_path, from_stat->st_mode, from_stat->st_rdev)) { 484 err("mknod: %s: %s", to.p_path, strerror(errno)); 485 return; 486 } 487 if (pflag) 488 setfile(from_stat, 0); 489 } 490 491 static void 492 setfile(fs, fd) 493 register struct stat *fs; 494 int fd; 495 { 496 static struct timeval tv[2]; 497 498 fs->st_mode &= S_ISUID|S_ISGID|S_IRWXU|S_IRWXG|S_IRWXO; 499 500 tv[0].tv_sec = fs->st_atime; 501 tv[1].tv_sec = fs->st_mtime; 502 if (utimes(to.p_path, tv)) 503 err("utimes: %s: %s", to.p_path, strerror(errno)); 504 /* 505 * Changing the ownership probably won't succeed, unless we're root 506 * or POSIX_CHOWN_RESTRICTED is not set. Set uid/gid before setting 507 * the mode; current BSD behavior is to remove all setuid bits on 508 * chown. If chown fails, lose setuid/setgid bits. 509 */ 510 if (fd ? fchown(fd, fs->st_uid, fs->st_gid) : 511 chown(to.p_path, fs->st_uid, fs->st_gid)) { 512 if (errno != EPERM) 513 err("chown: %s: %s", to.p_path, strerror(errno)); 514 fs->st_mode &= ~(S_ISUID|S_ISGID); 515 } 516 if (fd ? fchmod(fd, fs->st_mode) : chmod(to.p_path, fs->st_mode)) 517 err("chown: %s: %s", to.p_path, strerror(errno)); 518 } 519 520 static void 521 usage() 522 { 523 (void)fprintf(stderr, 524 "usage: cp [-Rfhip] src target;\n cp [-Rfhip] src1 ... srcN directory\n"); 525 exit(1); 526 } 527 528 #if __STDC__ 529 #include <stdarg.h> 530 #else 531 #include <varargs.h> 532 #endif 533 534 void 535 #if __STDC__ 536 err(const char *fmt, ...) 537 #else 538 err(fmt, va_alist) 539 char *fmt; 540 va_dcl 541 #endif 542 { 543 va_list ap; 544 #if __STDC__ 545 va_start(ap, fmt); 546 #else 547 va_start(ap); 548 #endif 549 (void)fprintf(stderr, "%s: ", progname); 550 (void)vfprintf(stderr, fmt, ap); 551 va_end(ap); 552 (void)fprintf(stderr, "\n"); 553 exit_val = 1; 554 } 555