Lines 93-98
int create_tempfile(const char *, char *
Link Here
|
93 |
void install(const char *, const char *, u_long, u_int); |
93 |
void install(const char *, const char *, u_long, u_int); |
94 |
void install_dir(char *); |
94 |
void install_dir(char *); |
95 |
u_long numeric_id(const char *, const char *); |
95 |
u_long numeric_id(const char *, const char *); |
|
|
96 |
void set_attributes(int, const char *); |
96 |
void strip(const char *); |
97 |
void strip(const char *); |
97 |
int trymmap(int); |
98 |
int trymmap(int); |
98 |
void usage(void); |
99 |
void usage(void); |
Lines 353-358
install(const char *from_name, const cha
Link Here
|
353 |
tempcopy ? tempfile : to_name, from_sb.st_size); |
354 |
tempcopy ? tempfile : to_name, from_sb.st_size); |
354 |
} |
355 |
} |
355 |
|
356 |
|
|
|
357 |
if (!devnull) |
358 |
(void)close(from_fd); |
359 |
|
356 |
if (dostrip) { |
360 |
if (dostrip) { |
357 |
strip(tempcopy ? tempfile : to_name); |
361 |
strip(tempcopy ? tempfile : to_name); |
358 |
|
362 |
|
Lines 369-377
install(const char *from_name, const cha
Link Here
|
369 |
/* |
373 |
/* |
370 |
* Compare the stripped temp file with the target. |
374 |
* Compare the stripped temp file with the target. |
371 |
*/ |
375 |
*/ |
|
|
376 |
temp_fd = to_fd; |
372 |
if (docompare && dostrip && target) { |
377 |
if (docompare && dostrip && target) { |
373 |
temp_fd = to_fd; |
|
|
374 |
|
375 |
/* Re-open to_fd using the real target name. */ |
378 |
/* Re-open to_fd using the real target name. */ |
376 |
if ((to_fd = open(to_name, O_RDONLY, 0)) < 0) |
379 |
if ((to_fd = open(to_name, O_RDONLY, 0)) < 0) |
377 |
err(EX_OSERR, "%s", to_name); |
380 |
err(EX_OSERR, "%s", to_name); |
Lines 400-406
install(const char *from_name, const cha
Link Here
|
400 |
files_match = 1; |
403 |
files_match = 1; |
401 |
(void)unlink(tempfile); |
404 |
(void)unlink(tempfile); |
402 |
} |
405 |
} |
403 |
(void) close(temp_fd); |
|
|
404 |
} |
406 |
} |
405 |
} |
407 |
} |
406 |
|
408 |
|
Lines 409-414
install(const char *from_name, const cha
Link Here
|
409 |
* and the files are different (or just not compared). |
411 |
* and the files are different (or just not compared). |
410 |
*/ |
412 |
*/ |
411 |
if (tempcopy && !files_match) { |
413 |
if (tempcopy && !files_match) { |
|
|
414 |
/* |
415 |
* Set attributes before rename so we can safely abort |
416 |
* on failure and leave the target untouched. |
417 |
*/ |
418 |
set_attributes(temp_fd, tempfile); |
419 |
|
412 |
/* Try to turn off the immutable bits. */ |
420 |
/* Try to turn off the immutable bits. */ |
413 |
if (to_sb.st_flags & NOCHANGEBITS) |
421 |
if (to_sb.st_flags & NOCHANGEBITS) |
414 |
(void)chflags(to_name, to_sb.st_flags & ~NOCHANGEBITS); |
422 |
(void)chflags(to_name, to_sb.st_flags & ~NOCHANGEBITS); |
Lines 443-449
install(const char *from_name, const cha
Link Here
|
443 |
(void) close(to_fd); |
451 |
(void) close(to_fd); |
444 |
if ((to_fd = open(to_name, O_RDONLY, 0)) < 0) |
452 |
if ((to_fd = open(to_name, O_RDONLY, 0)) < 0) |
445 |
err(EX_OSERR, "%s", to_name); |
453 |
err(EX_OSERR, "%s", to_name); |
446 |
} |
454 |
} else |
|
|
455 |
set_attributes(to_fd, to_name); |
456 |
|
457 |
if (docompare && dostrip && target) |
458 |
(void)close(temp_fd); |
447 |
|
459 |
|
448 |
/* |
460 |
/* |
449 |
* Preserve the timestamp of the source file if necessary. |
461 |
* Preserve the timestamp of the source file if necessary. |
Lines 456-497
install(const char *from_name, const cha
Link Here
|
456 |
(void)utimes(to_name, tvb); |
468 |
(void)utimes(to_name, tvb); |
457 |
} |
469 |
} |
458 |
|
470 |
|
459 |
if (fstat(to_fd, &to_sb) == -1) { |
|
|
460 |
serrno = errno; |
461 |
(void)unlink(to_name); |
462 |
errno = serrno; |
463 |
err(EX_OSERR, "%s", to_name); |
464 |
} |
465 |
|
466 |
/* |
467 |
* Set owner, group, mode for target; do the chown first, |
468 |
* chown may lose the setuid bits. |
469 |
*/ |
470 |
if ((gid != (gid_t)-1 && gid != to_sb.st_gid) || |
471 |
(uid != (uid_t)-1 && uid != to_sb.st_uid) || |
472 |
(mode != (to_sb.st_mode & ALLPERMS))) { |
473 |
/* Try to turn off the immutable bits. */ |
474 |
if (to_sb.st_flags & NOCHANGEBITS) |
475 |
(void)fchflags(to_fd, to_sb.st_flags & ~NOCHANGEBITS); |
476 |
} |
477 |
|
478 |
if ((gid != (gid_t)-1 && gid != to_sb.st_gid) || |
479 |
(uid != (uid_t)-1 && uid != to_sb.st_uid)) |
480 |
if (fchown(to_fd, uid, gid) == -1) { |
481 |
serrno = errno; |
482 |
(void)unlink(to_name); |
483 |
errno = serrno; |
484 |
err(EX_OSERR,"%s: chown/chgrp", to_name); |
485 |
} |
486 |
|
487 |
if (mode != (to_sb.st_mode & ALLPERMS)) |
488 |
if (fchmod(to_fd, mode)) { |
489 |
serrno = errno; |
490 |
(void)unlink(to_name); |
491 |
errno = serrno; |
492 |
err(EX_OSERR, "%s: chmod", to_name); |
493 |
} |
494 |
|
495 |
/* |
471 |
/* |
496 |
* If provided a set of flags, set them, otherwise, preserve the |
472 |
* If provided a set of flags, set them, otherwise, preserve the |
497 |
* flags, except for the dump flag. |
473 |
* flags, except for the dump flag. |
Lines 508-514
install(const char *from_name, const cha
Link Here
|
508 |
warn("%s: chflags", to_name); |
484 |
warn("%s: chflags", to_name); |
509 |
else { |
485 |
else { |
510 |
serrno = errno; |
486 |
serrno = errno; |
511 |
(void)unlink(to_name); |
487 |
(void)close(to_fd); |
512 |
errno = serrno; |
488 |
errno = serrno; |
513 |
err(EX_OSERR, "%s: chflags", to_name); |
489 |
err(EX_OSERR, "%s: chflags", to_name); |
514 |
} |
490 |
} |
Lines 516-523
install(const char *from_name, const cha
Link Here
|
516 |
} |
492 |
} |
517 |
|
493 |
|
518 |
(void)close(to_fd); |
494 |
(void)close(to_fd); |
519 |
if (!devnull) |
|
|
520 |
(void)close(from_fd); |
521 |
} |
495 |
} |
522 |
|
496 |
|
523 |
/* |
497 |
/* |
Lines 701-706
copy(int from_fd, const char *from_name,
Link Here
|
701 |
} |
675 |
} |
702 |
|
676 |
|
703 |
/* |
677 |
/* |
|
|
678 |
* set_attributes -- |
679 |
* set file mode, uid and gid |
680 |
*/ |
681 |
void |
682 |
set_attributes(int fd, const char *filename) |
683 |
{ |
684 |
struct stat sb; |
685 |
int serrno; |
686 |
|
687 |
if (fstat(fd, &sb) == -1) { |
688 |
serrno = errno; |
689 |
(void)unlink(filename); |
690 |
errno = serrno; |
691 |
err(EX_OSERR, "%s", filename); |
692 |
} |
693 |
|
694 |
/* |
695 |
* Set owner, group, mode for target; do the chown first, |
696 |
* chown may lose the setuid bits. |
697 |
*/ |
698 |
if ((gid != (gid_t)-1 && gid != sb.st_gid) || |
699 |
(uid != (uid_t)-1 && uid != sb.st_uid) || |
700 |
(mode != (sb.st_mode & ALLPERMS))) { |
701 |
/* Try to turn off the immutable bits. */ |
702 |
if (sb.st_flags & NOCHANGEBITS) |
703 |
(void)fchflags(fd, sb.st_flags & ~NOCHANGEBITS); |
704 |
} |
705 |
|
706 |
if ((gid != (gid_t)-1 && gid != sb.st_gid) || |
707 |
(uid != (uid_t)-1 && uid != sb.st_uid)) |
708 |
if (fchown(fd, uid, gid) == -1) { |
709 |
serrno = errno; |
710 |
(void)unlink(filename); |
711 |
errno = serrno; |
712 |
err(EX_OSERR,"%s: chown/chgrp", filename); |
713 |
} |
714 |
|
715 |
|
716 |
if (mode != (sb.st_mode & ALLPERMS)) |
717 |
if (fchmod(fd, mode)) { |
718 |
serrno = errno; |
719 |
(void)unlink(filename); |
720 |
errno = serrno; |
721 |
err(EX_OSERR, "%s: chmod", filename); |
722 |
} |
723 |
} |
724 |
|
725 |
/* |
704 |
* strip -- |
726 |
* strip -- |
705 |
* use strip(1) to strip the target file |
727 |
* use strip(1) to strip the target file |
706 |
*/ |
728 |
*/ |