View | Details | Raw Unified | Return to bug 127532 | Differences between
and this patch

Collapse All | Expand All

(-)head/usr.bin/xinstall/xinstall.c (-45 / +67 lines)
Lines 93-98 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 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 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 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 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 441-450 Link Here
441
449
442
		/* Re-open to_fd so we aren't hosed by the rename(2). */
450
		/* Re-open to_fd so we aren't hosed by the rename(2). */
443
		(void) close(to_fd);
451
		(void) close(to_fd);
444
		if ((to_fd = open(to_name, O_RDONLY, 0)) < 0)
452
		to_fd = temp_fd;
445
			err(EX_OSERR, "%s", to_name);
453
		temp_fd = -1;
446
	}
454
	} else
455
		set_attributes(to_fd, to_name);
447
456
457
	if (temp_fd != to_fd)
458
		(void)close(temp_fd);
459
448
	/*
460
	/*
449
	 * Preserve the timestamp of the source file if necessary.
461
	 * Preserve the timestamp of the source file if necessary.
450
	 */
462
	 */
Lines 456-498 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
	/*
471
	/*
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
	/*
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.
498
	 * NFS does not support flags.  Ignore EOPNOTSUPP flags if we're just
474
	 * NFS does not support flags.  Ignore EOPNOTSUPP flags if we're just
Lines 508-514 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 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 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
 */

Return to bug 127532