cp.c (78469) | cp.c (87655) |
---|---|
1/* 2 * Copyright (c) 1988, 1993, 1994 3 * The Regents of the University of California. All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * David Hitz of Auspex Systems Inc. 7 * 8 * Redistribution and use in source and binary forms, with or without --- 31 unchanged lines hidden (view full) --- 40 The Regents of the University of California. All rights reserved.\n"; 41#endif /* not lint */ 42 43#ifndef lint 44#if 0 45static char sccsid[] = "@(#)cp.c 8.2 (Berkeley) 4/1/94"; 46#endif 47static const char rcsid[] = | 1/* 2 * Copyright (c) 1988, 1993, 1994 3 * The Regents of the University of California. All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * David Hitz of Auspex Systems Inc. 7 * 8 * Redistribution and use in source and binary forms, with or without --- 31 unchanged lines hidden (view full) --- 40 The Regents of the University of California. All rights reserved.\n"; 41#endif /* not lint */ 42 43#ifndef lint 44#if 0 45static char sccsid[] = "@(#)cp.c 8.2 (Berkeley) 4/1/94"; 46#endif 47static const char rcsid[] = |
48 "$FreeBSD: head/bin/cp/cp.c 78469 2001-06-19 15:41:57Z des $"; | 48 "$FreeBSD: head/bin/cp/cp.c 87655 2001-12-11 13:18:10Z mckay $"; |
49#endif /* not lint */ 50 51/* 52 * Cp copies source files to target files. 53 * 54 * The global PATH_T structure "to" always contains the path to the 55 * current target file. Since fts(3) does not change directories, 56 * this path can be either absolute or dot-relative. --- 186 unchanged lines hidden (view full) --- 243 enum op type; 244 int fts_options; 245{ 246 struct stat to_stat; 247 FTS *ftsp; 248 FTSENT *curr; 249 int base = 0, dne, badcp, nlen, rval; 250 char *p, *target_mid; | 49#endif /* not lint */ 50 51/* 52 * Cp copies source files to target files. 53 * 54 * The global PATH_T structure "to" always contains the path to the 55 * current target file. Since fts(3) does not change directories, 56 * this path can be either absolute or dot-relative. --- 186 unchanged lines hidden (view full) --- 243 enum op type; 244 int fts_options; 245{ 246 struct stat to_stat; 247 FTS *ftsp; 248 FTSENT *curr; 249 int base = 0, dne, badcp, nlen, rval; 250 char *p, *target_mid; |
251 mode_t mask; |
|
251 | 252 |
253 /* 254 * Keep an inverted copy of the umask, for use in correcting 255 * permissions on created directories when not using -p. 256 */ 257 mask = ~umask(0777); 258 umask(~mask); 259 |
|
252 if ((ftsp = fts_open(argv, fts_options, mastercmp)) == NULL) 253 err(1, NULL); 254 for (badcp = rval = 0; (curr = fts_read(ftsp)) != NULL; badcp = 0) { 255 switch (curr->fts_info) { 256 case FTS_NS: 257 case FTS_DNR: 258 case FTS_ERR: 259 warnx("%s: %s", 260 curr->fts_path, strerror(curr->fts_errno)); 261 badcp = rval = 1; 262 continue; 263 case FTS_DC: /* Warn, continue. */ 264 warnx("%s: directory causes a cycle", curr->fts_path); 265 badcp = rval = 1; 266 continue; | 260 if ((ftsp = fts_open(argv, fts_options, mastercmp)) == NULL) 261 err(1, NULL); 262 for (badcp = rval = 0; (curr = fts_read(ftsp)) != NULL; badcp = 0) { 263 switch (curr->fts_info) { 264 case FTS_NS: 265 case FTS_DNR: 266 case FTS_ERR: 267 warnx("%s: %s", 268 curr->fts_path, strerror(curr->fts_errno)); 269 badcp = rval = 1; 270 continue; 271 case FTS_DC: /* Warn, continue. */ 272 warnx("%s: directory causes a cycle", curr->fts_path); 273 badcp = rval = 1; 274 continue; |
267 case FTS_DP: /* Ignore, continue. */ 268 continue; | |
269 } 270 271 /* 272 * If we are in case (2) or (3) above, we need to append the 273 * source name to the target name. 274 */ 275 if (type != FILE_TO_FILE) { 276 /* --- 41 unchanged lines hidden (view full) --- 318 continue; 319 } 320 (void)strncat(target_mid, p, nlen); 321 to.p_end = target_mid + nlen; 322 *to.p_end = 0; 323 STRIP_TRAILING_SLASH(to); 324 } 325 | 275 } 276 277 /* 278 * If we are in case (2) or (3) above, we need to append the 279 * source name to the target name. 280 */ 281 if (type != FILE_TO_FILE) { 282 /* --- 41 unchanged lines hidden (view full) --- 324 continue; 325 } 326 (void)strncat(target_mid, p, nlen); 327 to.p_end = target_mid + nlen; 328 *to.p_end = 0; 329 STRIP_TRAILING_SLASH(to); 330 } 331 |
332 if (curr->fts_info == FTS_DP) { 333 /* 334 * We are finished copying to this directory. If 335 * -p is in effect, set permissions and timestamps. 336 * Otherwise, if we created this directory, set the 337 * correct permissions, limited by the umask. 338 */ 339 if (pflag) 340 rval = setfile(curr->fts_statp, 0); 341 else if (curr->fts_number) { 342 mode_t perm = curr->fts_statp->st_mode & mask; 343 if (chmod(to.p_path, perm)) { 344 warn("chmod: %s", to.p_path); 345 rval = 1; 346 } 347 } 348 continue; 349 } 350 |
|
326 /* Not an error but need to remember it happened */ 327 if (stat(to.p_path, &to_stat) == -1) 328 dne = 1; 329 else { 330 if (to_stat.st_dev == curr->fts_statp->st_dev && 331 to_stat.st_ino == curr->fts_statp->st_ino) { 332 warnx("%s and %s are identical (not copied).", 333 to.p_path, curr->fts_path); --- 37 unchanged lines hidden (view full) --- 371 if (mkdir(to.p_path, 372 curr->fts_statp->st_mode | S_IRWXU) < 0) 373 err(1, "%s", to.p_path); 374 } else if (!S_ISDIR(to_stat.st_mode)) { 375 errno = ENOTDIR; 376 err(1, "%s", to.p_path); 377 } 378 /* | 351 /* Not an error but need to remember it happened */ 352 if (stat(to.p_path, &to_stat) == -1) 353 dne = 1; 354 else { 355 if (to_stat.st_dev == curr->fts_statp->st_dev && 356 to_stat.st_ino == curr->fts_statp->st_ino) { 357 warnx("%s and %s are identical (not copied).", 358 to.p_path, curr->fts_path); --- 37 unchanged lines hidden (view full) --- 396 if (mkdir(to.p_path, 397 curr->fts_statp->st_mode | S_IRWXU) < 0) 398 err(1, "%s", to.p_path); 399 } else if (!S_ISDIR(to_stat.st_mode)) { 400 errno = ENOTDIR; 401 err(1, "%s", to.p_path); 402 } 403 /* |
379 * If not -p and directory didn't exist, set it to be 380 * the same as the from directory, umodified by the 381 * umask; arguably wrong, but it's been that way 382 * forever. | 404 * Arrange to correct directory permissions later 405 * (in the post-order phase) if this is a new 406 * directory and the permissions aren't the final 407 * ones we want yet. Note that mkdir() does not 408 * honour setuid, setgid nor sticky bits, but we 409 * normally want to preserve them on directories. |
383 */ | 410 */ |
384 if (pflag && setfile(curr->fts_statp, 0)) 385 badcp = rval = 1; 386 else if (dne) 387 (void)chmod(to.p_path, 388 curr->fts_statp->st_mode); | 411 { 412 mode_t mode = curr->fts_statp->st_mode; 413 curr->fts_number = dne && 414 ((mode & (S_ISUID|S_ISGID|S_ISTXT)) || 415 ((mode | S_IRWXU) & mask) != (mode & mask)); 416 } |
389 break; 390 case S_IFBLK: 391 case S_IFCHR: 392 if (Rflag) { 393 if (copy_special(curr->fts_statp, !dne)) 394 badcp = rval = 1; 395 } else { 396 if (copy_file(curr, dne)) --- 51 unchanged lines hidden --- | 417 break; 418 case S_IFBLK: 419 case S_IFCHR: 420 if (Rflag) { 421 if (copy_special(curr->fts_statp, !dne)) 422 badcp = rval = 1; 423 } else { 424 if (copy_file(curr, dne)) --- 51 unchanged lines hidden --- |