1 /* 2 * Copyright (c) 2012, 2013 SRI International 3 * Copyright (c) 1987, 1993 4 * The Regents of the University of California. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 4. Neither the name of the University nor the names of its contributors 15 * may be used to endorse or promote products derived from this software 16 * without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * SUCH DAMAGE. 29 */ 30 31 #ifndef lint 32 static const char copyright[] = 33 "@(#) Copyright (c) 1987, 1993\n\ 34 The Regents of the University of California. All rights reserved.\n"; 35 #endif /* not lint */ 36 37 #if 0 38 #ifndef lint 39 static char sccsid[] = "@(#)xinstall.c 8.1 (Berkeley) 7/21/93"; 40 #endif /* not lint */ 41 #endif 42 43 #include <sys/cdefs.h> 44 __FBSDID("$FreeBSD$"); 45 46 #include <sys/param.h> 47 #include <sys/mman.h> 48 #include <sys/mount.h> 49 #include <sys/stat.h> 50 #include <sys/time.h> 51 #include <sys/wait.h> 52 53 #include <err.h> 54 #include <errno.h> 55 #include <fcntl.h> 56 #include <grp.h> 57 #include <libgen.h> 58 #include <md5.h> 59 #include <paths.h> 60 #include <pwd.h> 61 #include <ripemd.h> 62 #include <sha.h> 63 #include <sha256.h> 64 #include <sha512.h> 65 #include <stdint.h> 66 #include <stdio.h> 67 #include <stdlib.h> 68 #include <string.h> 69 #include <sysexits.h> 70 #include <unistd.h> 71 #include <vis.h> 72 73 #include "mtree.h" 74 75 #define MAX_CMP_SIZE (16 * 1024 * 1024) 76 77 #define LN_ABSOLUTE 0x01 78 #define LN_RELATIVE 0x02 79 #define LN_HARD 0x04 80 #define LN_SYMBOLIC 0x08 81 #define LN_MIXED 0x10 82 83 #define DIRECTORY 0x01 /* Tell install it's a directory. */ 84 #define SETFLAGS 0x02 /* Tell install to set flags. */ 85 #define NOCHANGEBITS (UF_IMMUTABLE | UF_APPEND | SF_IMMUTABLE | SF_APPEND) 86 #define BACKUP_SUFFIX ".old" 87 88 typedef union { 89 MD5_CTX MD5; 90 RIPEMD160_CTX RIPEMD160; 91 SHA1_CTX SHA1; 92 SHA256_CTX SHA256; 93 SHA512_CTX SHA512; 94 } DIGEST_CTX; 95 96 static enum { 97 DIGEST_NONE = 0, 98 DIGEST_MD5, 99 DIGEST_RIPEMD160, 100 DIGEST_SHA1, 101 DIGEST_SHA256, 102 DIGEST_SHA512, 103 } digesttype = DIGEST_NONE; 104 105 static gid_t gid; 106 static uid_t uid; 107 static int dobackup, docompare, dodir, dolink, dopreserve, dostrip, dounpriv, 108 safecopy, verbose; 109 static int haveopt_f, haveopt_g, haveopt_m, haveopt_o; 110 static mode_t mode = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH; 111 static FILE *metafp; 112 static const char *group, *owner; 113 static const char *suffix = BACKUP_SUFFIX; 114 static char *destdir, *digest, *fflags, *metafile, *tags; 115 116 static int compare(int, const char *, size_t, int, const char *, size_t, 117 char **); 118 static char *copy(int, const char *, int, const char *, off_t); 119 static int create_newfile(const char *, int, struct stat *); 120 static int create_tempfile(const char *, char *, size_t); 121 static char *quiet_mktemp(char *template); 122 static char *digest_file(const char *); 123 static void digest_init(DIGEST_CTX *); 124 static void digest_update(DIGEST_CTX *, const char *, size_t); 125 static char *digest_end(DIGEST_CTX *, char *); 126 static int do_link(const char *, const char *, const struct stat *); 127 static void do_symlink(const char *, const char *, const struct stat *); 128 static void makelink(const char *, const char *, const struct stat *); 129 static void install(const char *, const char *, u_long, u_int); 130 static void install_dir(char *); 131 static void metadata_log(const char *, const char *, struct timeval *, 132 const char *, const char *, off_t); 133 static int parseid(const char *, id_t *); 134 static void strip(const char *); 135 static int trymmap(int); 136 static void usage(void); 137 138 int 139 main(int argc, char *argv[]) 140 { 141 struct stat from_sb, to_sb; 142 mode_t *set; 143 u_long fset; 144 int ch, no_target; 145 u_int iflags; 146 char *p; 147 const char *to_name; 148 149 iflags = 0; 150 group = owner = NULL; 151 while ((ch = getopt(argc, argv, "B:bCcD:df:g:h:l:M:m:N:o:pSsT:Uv")) != 152 -1) 153 switch((char)ch) { 154 case 'B': 155 suffix = optarg; 156 /* FALLTHROUGH */ 157 case 'b': 158 dobackup = 1; 159 break; 160 case 'C': 161 docompare = 1; 162 break; 163 case 'c': 164 /* For backwards compatibility. */ 165 break; 166 case 'D': 167 destdir = optarg; 168 break; 169 case 'd': 170 dodir = 1; 171 break; 172 case 'f': 173 haveopt_f = 1; 174 fflags = optarg; 175 break; 176 case 'g': 177 haveopt_g = 1; 178 group = optarg; 179 break; 180 case 'h': 181 digest = optarg; 182 break; 183 case 'l': 184 for (p = optarg; *p != '\0'; p++) 185 switch (*p) { 186 case 's': 187 dolink &= ~(LN_HARD|LN_MIXED); 188 dolink |= LN_SYMBOLIC; 189 break; 190 case 'h': 191 dolink &= ~(LN_SYMBOLIC|LN_MIXED); 192 dolink |= LN_HARD; 193 break; 194 case 'm': 195 dolink &= ~(LN_SYMBOLIC|LN_HARD); 196 dolink |= LN_MIXED; 197 break; 198 case 'a': 199 dolink &= ~LN_RELATIVE; 200 dolink |= LN_ABSOLUTE; 201 break; 202 case 'r': 203 dolink &= ~LN_ABSOLUTE; 204 dolink |= LN_RELATIVE; 205 break; 206 default: 207 errx(1, "%c: invalid link type", *p); 208 /* NOTREACHED */ 209 } 210 break; 211 case 'M': 212 metafile = optarg; 213 break; 214 case 'm': 215 haveopt_m = 1; 216 if (!(set = setmode(optarg))) 217 errx(EX_USAGE, "invalid file mode: %s", 218 optarg); 219 mode = getmode(set, 0); 220 free(set); 221 break; 222 case 'N': 223 if (!setup_getid(optarg)) 224 err(EX_OSERR, "Unable to use user and group " 225 "databases in `%s'", optarg); 226 break; 227 case 'o': 228 haveopt_o = 1; 229 owner = optarg; 230 break; 231 case 'p': 232 docompare = dopreserve = 1; 233 break; 234 case 'S': 235 safecopy = 1; 236 break; 237 case 's': 238 dostrip = 1; 239 break; 240 case 'T': 241 tags = optarg; 242 break; 243 case 'U': 244 dounpriv = 1; 245 break; 246 case 'v': 247 verbose = 1; 248 break; 249 case '?': 250 default: 251 usage(); 252 } 253 argc -= optind; 254 argv += optind; 255 256 /* some options make no sense when creating directories */ 257 if (dostrip && dodir) { 258 warnx("-d and -s may not be specified together"); 259 usage(); 260 } 261 262 if (getenv("DONTSTRIP") != NULL) { 263 warnx("DONTSTRIP set - will not strip installed binaries"); 264 dostrip = 0; 265 } 266 267 /* must have at least two arguments, except when creating directories */ 268 if (argc == 0 || (argc == 1 && !dodir)) 269 usage(); 270 271 if (digest != NULL) { 272 if (strcmp(digest, "none") == 0) { 273 digesttype = DIGEST_NONE; 274 } else if (strcmp(digest, "md5") == 0) { 275 digesttype = DIGEST_MD5; 276 } else if (strcmp(digest, "rmd160") == 0) { 277 digesttype = DIGEST_RIPEMD160; 278 } else if (strcmp(digest, "sha1") == 0) { 279 digesttype = DIGEST_SHA1; 280 } else if (strcmp(digest, "sha256") == 0) { 281 digesttype = DIGEST_SHA256; 282 } else if (strcmp(digest, "sha512") == 0) { 283 digesttype = DIGEST_SHA512; 284 } else { 285 warnx("unknown digest `%s'", digest); 286 usage(); 287 } 288 } 289 290 /* need to make a temp copy so we can compare stripped version */ 291 if (docompare && dostrip) 292 safecopy = 1; 293 294 /* get group and owner id's */ 295 if (group != NULL && !dounpriv) { 296 if (gid_from_group(group, &gid) == -1) { 297 id_t id; 298 if (!parseid(group, &id)) 299 errx(1, "unknown group %s", group); 300 gid = id; 301 } 302 } else 303 gid = (gid_t)-1; 304 305 if (owner != NULL && !dounpriv) { 306 if (uid_from_user(owner, &uid) == -1) { 307 id_t id; 308 if (!parseid(owner, &id)) 309 errx(1, "unknown user %s", owner); 310 uid = id; 311 } 312 } else 313 uid = (uid_t)-1; 314 315 if (fflags != NULL && !dounpriv) { 316 if (strtofflags(&fflags, &fset, NULL)) 317 errx(EX_USAGE, "%s: invalid flag", fflags); 318 iflags |= SETFLAGS; 319 } 320 321 if (metafile != NULL) { 322 if ((metafp = fopen(metafile, "a")) == NULL) 323 warn("open %s", metafile); 324 } else 325 digesttype = DIGEST_NONE; 326 327 if (dodir) { 328 for (; *argv != NULL; ++argv) 329 install_dir(*argv); 330 exit(EX_OK); 331 /* NOTREACHED */ 332 } 333 334 to_name = argv[argc - 1]; 335 no_target = stat(to_name, &to_sb); 336 if (!no_target && S_ISDIR(to_sb.st_mode)) { 337 if (dolink & LN_SYMBOLIC) { 338 if (lstat(to_name, &to_sb) != 0) 339 err(EX_OSERR, "%s vanished", to_name); 340 if (S_ISLNK(to_sb.st_mode)) { 341 if (argc != 2) { 342 errno = ENOTDIR; 343 err(EX_USAGE, "%s", to_name); 344 } 345 install(*argv, to_name, fset, iflags); 346 exit(EX_OK); 347 } 348 } 349 for (; *argv != to_name; ++argv) 350 install(*argv, to_name, fset, iflags | DIRECTORY); 351 exit(EX_OK); 352 /* NOTREACHED */ 353 } 354 355 /* can't do file1 file2 directory/file */ 356 if (argc != 2) { 357 if (no_target) 358 warnx("target directory `%s' does not exist", 359 argv[argc - 1]); 360 else 361 warnx("target `%s' is not a directory", 362 argv[argc - 1]); 363 usage(); 364 } 365 366 if (!no_target && !dolink) { 367 if (stat(*argv, &from_sb)) 368 err(EX_OSERR, "%s", *argv); 369 if (!S_ISREG(to_sb.st_mode)) { 370 errno = EFTYPE; 371 err(EX_OSERR, "%s", to_name); 372 } 373 if (to_sb.st_dev == from_sb.st_dev && 374 to_sb.st_ino == from_sb.st_ino) 375 errx(EX_USAGE, 376 "%s and %s are the same file", *argv, to_name); 377 } 378 install(*argv, to_name, fset, iflags); 379 exit(EX_OK); 380 /* NOTREACHED */ 381 } 382 383 static char * 384 digest_file(const char *name) 385 { 386 387 switch (digesttype) { 388 case DIGEST_MD5: 389 return (MD5File(name, NULL)); 390 case DIGEST_RIPEMD160: 391 return (RIPEMD160_File(name, NULL)); 392 case DIGEST_SHA1: 393 return (SHA1_File(name, NULL)); 394 case DIGEST_SHA256: 395 return (SHA256_File(name, NULL)); 396 case DIGEST_SHA512: 397 return (SHA512_File(name, NULL)); 398 default: 399 return (NULL); 400 } 401 } 402 403 static void 404 digest_init(DIGEST_CTX *c) 405 { 406 407 switch (digesttype) { 408 case DIGEST_NONE: 409 break; 410 case DIGEST_MD5: 411 MD5Init(&(c->MD5)); 412 break; 413 case DIGEST_RIPEMD160: 414 RIPEMD160_Init(&(c->RIPEMD160)); 415 break; 416 case DIGEST_SHA1: 417 SHA1_Init(&(c->SHA1)); 418 break; 419 case DIGEST_SHA256: 420 SHA256_Init(&(c->SHA256)); 421 break; 422 case DIGEST_SHA512: 423 SHA512_Init(&(c->SHA512)); 424 break; 425 } 426 } 427 428 static void 429 digest_update(DIGEST_CTX *c, const char *data, size_t len) 430 { 431 432 switch (digesttype) { 433 case DIGEST_NONE: 434 break; 435 case DIGEST_MD5: 436 MD5Update(&(c->MD5), data, len); 437 break; 438 case DIGEST_RIPEMD160: 439 RIPEMD160_Update(&(c->RIPEMD160), data, len); 440 break; 441 case DIGEST_SHA1: 442 SHA1_Update(&(c->SHA1), data, len); 443 break; 444 case DIGEST_SHA256: 445 SHA256_Update(&(c->SHA256), data, len); 446 break; 447 case DIGEST_SHA512: 448 SHA512_Update(&(c->SHA512), data, len); 449 break; 450 } 451 } 452 453 static char * 454 digest_end(DIGEST_CTX *c, char *buf) 455 { 456 457 switch (digesttype) { 458 case DIGEST_MD5: 459 return (MD5End(&(c->MD5), buf)); 460 case DIGEST_RIPEMD160: 461 return (RIPEMD160_End(&(c->RIPEMD160), buf)); 462 case DIGEST_SHA1: 463 return (SHA1_End(&(c->SHA1), buf)); 464 case DIGEST_SHA256: 465 return (SHA256_End(&(c->SHA256), buf)); 466 case DIGEST_SHA512: 467 return (SHA512_End(&(c->SHA512), buf)); 468 default: 469 return (NULL); 470 } 471 } 472 473 /* 474 * parseid -- 475 * parse uid or gid from arg into id, returning non-zero if successful 476 */ 477 static int 478 parseid(const char *name, id_t *id) 479 { 480 char *ep; 481 errno = 0; 482 *id = (id_t)strtoul(name, &ep, 10); 483 if (errno || *ep != '\0') 484 return (0); 485 return (1); 486 } 487 488 /* 489 * quiet_mktemp -- 490 * mktemp implementation used mkstemp to avoid mktemp warnings. We 491 * really do need mktemp semantics here as we will be creating a link. 492 */ 493 static char * 494 quiet_mktemp(char *template) 495 { 496 int fd; 497 498 if ((fd = mkstemp(template)) == -1) 499 return (NULL); 500 close (fd); 501 if (unlink(template) == -1) 502 err(EX_OSERR, "unlink %s", template); 503 return (template); 504 } 505 506 /* 507 * do_link -- 508 * make a hard link, obeying dorename if set 509 * return -1 on failure 510 */ 511 static int 512 do_link(const char *from_name, const char *to_name, 513 const struct stat *target_sb) 514 { 515 char tmpl[MAXPATHLEN]; 516 int ret; 517 518 if (safecopy && target_sb != NULL) { 519 (void)snprintf(tmpl, sizeof(tmpl), "%s.inst.XXXXXX", to_name); 520 /* This usage is safe. */ 521 if (quiet_mktemp(tmpl) == NULL) 522 err(EX_OSERR, "%s: mktemp", tmpl); 523 ret = link(from_name, tmpl); 524 if (ret == 0) { 525 if (target_sb->st_mode & S_IFDIR && rmdir(to_name) == 526 -1) { 527 unlink(tmpl); 528 err(EX_OSERR, "%s", to_name); 529 } 530 if (target_sb->st_flags & NOCHANGEBITS) 531 (void)chflags(to_name, target_sb->st_flags & 532 ~NOCHANGEBITS); 533 unlink(to_name); 534 ret = rename(tmpl, to_name); 535 /* 536 * If rename has posix semantics, then the temporary 537 * file may still exist when from_name and to_name point 538 * to the same file, so unlink it unconditionally. 539 */ 540 (void)unlink(tmpl); 541 } 542 return (ret); 543 } else 544 return (link(from_name, to_name)); 545 } 546 547 /* 548 * do_symlink -- 549 * Make a symbolic link, obeying dorename if set. Exit on failure. 550 */ 551 static void 552 do_symlink(const char *from_name, const char *to_name, 553 const struct stat *target_sb) 554 { 555 char tmpl[MAXPATHLEN]; 556 557 if (safecopy && target_sb != NULL) { 558 (void)snprintf(tmpl, sizeof(tmpl), "%s.inst.XXXXXX", to_name); 559 /* This usage is safe. */ 560 if (quiet_mktemp(tmpl) == NULL) 561 err(EX_OSERR, "%s: mktemp", tmpl); 562 563 if (symlink(from_name, tmpl) == -1) 564 err(EX_OSERR, "symlink %s -> %s", from_name, tmpl); 565 566 if (target_sb->st_mode & S_IFDIR && rmdir(to_name) == -1) { 567 (void)unlink(tmpl); 568 err(EX_OSERR, "%s", to_name); 569 } 570 if (target_sb->st_flags & NOCHANGEBITS) 571 (void)chflags(to_name, target_sb->st_flags & 572 ~NOCHANGEBITS); 573 unlink(to_name); 574 575 if (rename(tmpl, to_name) == -1) { 576 /* Remove temporary link before exiting. */ 577 (void)unlink(tmpl); 578 err(EX_OSERR, "%s: rename", to_name); 579 } 580 } else { 581 if (symlink(from_name, to_name) == -1) 582 err(EX_OSERR, "symlink %s -> %s", from_name, to_name); 583 } 584 } 585 586 /* 587 * makelink -- 588 * make a link from source to destination 589 */ 590 static void 591 makelink(const char *from_name, const char *to_name, 592 const struct stat *target_sb) 593 { 594 char src[MAXPATHLEN], dst[MAXPATHLEN], lnk[MAXPATHLEN]; 595 struct stat to_sb; 596 597 /* Try hard links first. */ 598 if (dolink & (LN_HARD|LN_MIXED)) { 599 if (do_link(from_name, to_name, target_sb) == -1) { 600 if ((dolink & LN_HARD) || errno != EXDEV) 601 err(EX_OSERR, "link %s -> %s", from_name, to_name); 602 } else { 603 if (stat(to_name, &to_sb)) 604 err(EX_OSERR, "%s: stat", to_name); 605 if (S_ISREG(to_sb.st_mode)) { 606 /* 607 * XXX: hard links to anything other than 608 * plain files are not metalogged 609 */ 610 int omode; 611 const char *oowner, *ogroup; 612 char *offlags; 613 char *dres; 614 615 /* 616 * XXX: use underlying perms, unless 617 * overridden on command line. 618 */ 619 omode = mode; 620 if (!haveopt_m) 621 mode = (to_sb.st_mode & 0777); 622 oowner = owner; 623 if (!haveopt_o) 624 owner = NULL; 625 ogroup = group; 626 if (!haveopt_g) 627 group = NULL; 628 offlags = fflags; 629 if (!haveopt_f) 630 fflags = NULL; 631 dres = digest_file(from_name); 632 metadata_log(to_name, "file", NULL, NULL, 633 dres, to_sb.st_size); 634 free(dres); 635 mode = omode; 636 owner = oowner; 637 group = ogroup; 638 fflags = offlags; 639 } 640 return; 641 } 642 } 643 644 /* Symbolic links. */ 645 if (dolink & LN_ABSOLUTE) { 646 /* Convert source path to absolute. */ 647 if (realpath(from_name, src) == NULL) 648 err(EX_OSERR, "%s: realpath", from_name); 649 do_symlink(src, to_name, target_sb); 650 /* XXX: src may point outside of destdir */ 651 metadata_log(to_name, "link", NULL, src, NULL, 0); 652 return; 653 } 654 655 if (dolink & LN_RELATIVE) { 656 char *cp, *d, *s; 657 658 /* Resolve pathnames. */ 659 if (realpath(from_name, src) == NULL) 660 err(EX_OSERR, "%s: realpath", from_name); 661 662 /* 663 * The last component of to_name may be a symlink, 664 * so use realpath to resolve only the directory. 665 */ 666 cp = dirname(to_name); 667 if (realpath(cp, dst) == NULL) 668 err(EX_OSERR, "%s: realpath", cp); 669 /* .. and add the last component. */ 670 if (strcmp(dst, "/") != 0) { 671 if (strlcat(dst, "/", sizeof(dst)) > sizeof(dst)) 672 errx(1, "resolved pathname too long"); 673 } 674 cp = basename(to_name); 675 if (strlcat(dst, cp, sizeof(dst)) > sizeof(dst)) 676 errx(1, "resolved pathname too long"); 677 678 /* Trim common path components. */ 679 for (s = src, d = dst; *s == *d; s++, d++) 680 continue; 681 while (*s != '/') 682 s--, d--; 683 684 /* Count the number of directories we need to backtrack. */ 685 for (++d, lnk[0] = '\0'; *d; d++) 686 if (*d == '/') 687 (void)strlcat(lnk, "../", sizeof(lnk)); 688 689 (void)strlcat(lnk, ++s, sizeof(lnk)); 690 691 do_symlink(lnk, to_name, target_sb); 692 /* XXX: Link may point outside of destdir. */ 693 metadata_log(to_name, "link", NULL, lnk, NULL, 0); 694 return; 695 } 696 697 /* 698 * If absolute or relative was not specified, try the names the 699 * user provided. 700 */ 701 do_symlink(from_name, to_name, target_sb); 702 /* XXX: from_name may point outside of destdir. */ 703 metadata_log(to_name, "link", NULL, from_name, NULL, 0); 704 } 705 706 /* 707 * install -- 708 * build a path name and install the file 709 */ 710 static void 711 install(const char *from_name, const char *to_name, u_long fset, u_int flags) 712 { 713 struct stat from_sb, temp_sb, to_sb; 714 struct timeval tvb[2]; 715 int devnull, files_match, from_fd, serrno, target; 716 int tempcopy, temp_fd, to_fd; 717 char backup[MAXPATHLEN], *p, pathbuf[MAXPATHLEN], tempfile[MAXPATHLEN]; 718 char *digestresult; 719 720 files_match = 0; 721 from_fd = -1; 722 to_fd = -1; 723 724 /* If try to install NULL file to a directory, fails. */ 725 if (flags & DIRECTORY || strcmp(from_name, _PATH_DEVNULL)) { 726 if (!dolink) { 727 if (stat(from_name, &from_sb)) 728 err(EX_OSERR, "%s", from_name); 729 if (!S_ISREG(from_sb.st_mode)) { 730 errno = EFTYPE; 731 err(EX_OSERR, "%s", from_name); 732 } 733 } 734 /* Build the target path. */ 735 if (flags & DIRECTORY) { 736 (void)snprintf(pathbuf, sizeof(pathbuf), "%s/%s", 737 to_name, 738 (p = strrchr(from_name, '/')) ? ++p : from_name); 739 to_name = pathbuf; 740 } 741 devnull = 0; 742 } else { 743 devnull = 1; 744 } 745 746 if (!dolink) 747 target = (stat(to_name, &to_sb) == 0); 748 else 749 target = (lstat(to_name, &to_sb) == 0); 750 751 if (dolink) { 752 if (target && !safecopy) { 753 if (to_sb.st_mode & S_IFDIR && rmdir(to_name) == -1) 754 err(EX_OSERR, "%s", to_name); 755 if (to_sb.st_flags & NOCHANGEBITS) 756 (void)chflags(to_name, 757 to_sb.st_flags & ~NOCHANGEBITS); 758 unlink(to_name); 759 } 760 makelink(from_name, to_name, target ? &to_sb : NULL); 761 return; 762 } 763 764 /* Only install to regular files. */ 765 if (target && !S_ISREG(to_sb.st_mode)) { 766 errno = EFTYPE; 767 warn("%s", to_name); 768 return; 769 } 770 771 /* Only copy safe if the target exists. */ 772 tempcopy = safecopy && target; 773 774 if (!devnull && (from_fd = open(from_name, O_RDONLY, 0)) < 0) 775 err(EX_OSERR, "%s", from_name); 776 777 /* If we don't strip, we can compare first. */ 778 if (docompare && !dostrip && target) { 779 if ((to_fd = open(to_name, O_RDONLY, 0)) < 0) 780 err(EX_OSERR, "%s", to_name); 781 if (devnull) 782 files_match = to_sb.st_size == 0; 783 else 784 files_match = !(compare(from_fd, from_name, 785 (size_t)from_sb.st_size, to_fd, 786 to_name, (size_t)to_sb.st_size, &digestresult)); 787 788 /* Close "to" file unless we match. */ 789 if (!files_match) 790 (void)close(to_fd); 791 } 792 793 if (!files_match) { 794 if (tempcopy) { 795 to_fd = create_tempfile(to_name, tempfile, 796 sizeof(tempfile)); 797 if (to_fd < 0) 798 err(EX_OSERR, "%s", tempfile); 799 } else { 800 if ((to_fd = create_newfile(to_name, target, 801 &to_sb)) < 0) 802 err(EX_OSERR, "%s", to_name); 803 if (verbose) 804 (void)printf("install: %s -> %s\n", 805 from_name, to_name); 806 } 807 if (!devnull) 808 digestresult = copy(from_fd, from_name, to_fd, 809 tempcopy ? tempfile : to_name, from_sb.st_size); 810 else 811 digestresult = NULL; 812 } 813 814 if (dostrip) { 815 strip(tempcopy ? tempfile : to_name); 816 817 /* 818 * Re-open our fd on the target, in case we used a strip 819 * that does not work in-place -- like GNU binutils strip. 820 */ 821 close(to_fd); 822 to_fd = open(tempcopy ? tempfile : to_name, O_RDONLY, 0); 823 if (to_fd < 0) 824 err(EX_OSERR, "stripping %s", to_name); 825 } 826 827 /* 828 * Compare the stripped temp file with the target. 829 */ 830 if (docompare && dostrip && target) { 831 temp_fd = to_fd; 832 833 /* Re-open to_fd using the real target name. */ 834 if ((to_fd = open(to_name, O_RDONLY, 0)) < 0) 835 err(EX_OSERR, "%s", to_name); 836 837 if (fstat(temp_fd, &temp_sb)) { 838 serrno = errno; 839 (void)unlink(tempfile); 840 errno = serrno; 841 err(EX_OSERR, "%s", tempfile); 842 } 843 844 if (compare(temp_fd, tempfile, (size_t)temp_sb.st_size, to_fd, 845 to_name, (size_t)to_sb.st_size, &digestresult) 846 == 0) { 847 /* 848 * If target has more than one link we need to 849 * replace it in order to snap the extra links. 850 * Need to preserve target file times, though. 851 */ 852 if (to_sb.st_nlink != 1) { 853 tvb[0].tv_sec = to_sb.st_atime; 854 tvb[0].tv_usec = 0; 855 tvb[1].tv_sec = to_sb.st_mtime; 856 tvb[1].tv_usec = 0; 857 (void)utimes(tempfile, tvb); 858 } else { 859 files_match = 1; 860 (void)unlink(tempfile); 861 } 862 (void) close(temp_fd); 863 } 864 } 865 866 if (dostrip && (!docompare || !target)) 867 digestresult = digest_file(tempfile); 868 869 /* 870 * Move the new file into place if doing a safe copy 871 * and the files are different (or just not compared). 872 */ 873 if (tempcopy && !files_match) { 874 /* Try to turn off the immutable bits. */ 875 if (to_sb.st_flags & NOCHANGEBITS) 876 (void)chflags(to_name, to_sb.st_flags & ~NOCHANGEBITS); 877 if (dobackup) { 878 if ((size_t)snprintf(backup, MAXPATHLEN, "%s%s", to_name, 879 suffix) != strlen(to_name) + strlen(suffix)) { 880 unlink(tempfile); 881 errx(EX_OSERR, "%s: backup filename too long", 882 to_name); 883 } 884 if (verbose) 885 (void)printf("install: %s -> %s\n", to_name, backup); 886 if (rename(to_name, backup) < 0) { 887 serrno = errno; 888 unlink(tempfile); 889 errno = serrno; 890 err(EX_OSERR, "rename: %s to %s", to_name, 891 backup); 892 } 893 } 894 if (verbose) 895 (void)printf("install: %s -> %s\n", from_name, to_name); 896 if (rename(tempfile, to_name) < 0) { 897 serrno = errno; 898 unlink(tempfile); 899 errno = serrno; 900 err(EX_OSERR, "rename: %s to %s", 901 tempfile, to_name); 902 } 903 904 /* Re-open to_fd so we aren't hosed by the rename(2). */ 905 (void) close(to_fd); 906 if ((to_fd = open(to_name, O_RDONLY, 0)) < 0) 907 err(EX_OSERR, "%s", to_name); 908 } 909 910 /* 911 * Preserve the timestamp of the source file if necessary. 912 */ 913 if (dopreserve && !files_match && !devnull) { 914 tvb[0].tv_sec = from_sb.st_atime; 915 tvb[0].tv_usec = 0; 916 tvb[1].tv_sec = from_sb.st_mtime; 917 tvb[1].tv_usec = 0; 918 (void)utimes(to_name, tvb); 919 } 920 921 if (fstat(to_fd, &to_sb) == -1) { 922 serrno = errno; 923 (void)unlink(to_name); 924 errno = serrno; 925 err(EX_OSERR, "%s", to_name); 926 } 927 928 /* 929 * Set owner, group, mode for target; do the chown first, 930 * chown may lose the setuid bits. 931 */ 932 if (!dounpriv && ((gid != (gid_t)-1 && gid != to_sb.st_gid) || 933 (uid != (uid_t)-1 && uid != to_sb.st_uid) || 934 (mode != (to_sb.st_mode & ALLPERMS)))) { 935 /* Try to turn off the immutable bits. */ 936 if (to_sb.st_flags & NOCHANGEBITS) 937 (void)fchflags(to_fd, to_sb.st_flags & ~NOCHANGEBITS); 938 } 939 940 if (!dounpriv & 941 (gid != (gid_t)-1 && gid != to_sb.st_gid) || 942 (uid != (uid_t)-1 && uid != to_sb.st_uid)) 943 if (fchown(to_fd, uid, gid) == -1) { 944 serrno = errno; 945 (void)unlink(to_name); 946 errno = serrno; 947 err(EX_OSERR,"%s: chown/chgrp", to_name); 948 } 949 950 if (mode != (to_sb.st_mode & ALLPERMS)) { 951 if (fchmod(to_fd, 952 dounpriv ? mode & (S_IRWXU|S_IRWXG|S_IRWXO) : mode)) { 953 serrno = errno; 954 (void)unlink(to_name); 955 errno = serrno; 956 err(EX_OSERR, "%s: chmod", to_name); 957 } 958 } 959 960 /* 961 * If provided a set of flags, set them, otherwise, preserve the 962 * flags, except for the dump flag. 963 * NFS does not support flags. Ignore EOPNOTSUPP flags if we're just 964 * trying to turn off UF_NODUMP. If we're trying to set real flags, 965 * then warn if the fs doesn't support it, otherwise fail. 966 */ 967 if (!dounpriv & !devnull && (flags & SETFLAGS || 968 (from_sb.st_flags & ~UF_NODUMP) != to_sb.st_flags) && 969 fchflags(to_fd, 970 flags & SETFLAGS ? fset : from_sb.st_flags & ~UF_NODUMP)) { 971 if (flags & SETFLAGS) { 972 if (errno == EOPNOTSUPP) 973 warn("%s: chflags", to_name); 974 else { 975 serrno = errno; 976 (void)unlink(to_name); 977 errno = serrno; 978 err(EX_OSERR, "%s: chflags", to_name); 979 } 980 } 981 } 982 983 (void)close(to_fd); 984 if (!devnull) 985 (void)close(from_fd); 986 987 metadata_log(to_name, "file", tvb, NULL, digestresult, to_sb.st_size); 988 free(digestresult); 989 } 990 991 /* 992 * compare -- 993 * compare two files; non-zero means files differ 994 */ 995 static int 996 compare(int from_fd, const char *from_name __unused, size_t from_len, 997 int to_fd, const char *to_name __unused, size_t to_len, 998 char **dresp) 999 { 1000 char *p, *q; 1001 int rv; 1002 int done_compare; 1003 DIGEST_CTX ctx; 1004 1005 rv = 0; 1006 if (from_len != to_len) 1007 return 1; 1008 1009 if (from_len <= MAX_CMP_SIZE) { 1010 if (dresp != NULL) 1011 digest_init(&ctx); 1012 done_compare = 0; 1013 if (trymmap(from_fd) && trymmap(to_fd)) { 1014 p = mmap(NULL, from_len, PROT_READ, MAP_SHARED, 1015 from_fd, (off_t)0); 1016 if (p == MAP_FAILED) 1017 goto out; 1018 q = mmap(NULL, from_len, PROT_READ, MAP_SHARED, 1019 to_fd, (off_t)0); 1020 if (q == MAP_FAILED) { 1021 munmap(p, from_len); 1022 goto out; 1023 } 1024 1025 rv = memcmp(p, q, from_len); 1026 if (dresp != NULL) 1027 digest_update(&ctx, p, from_len); 1028 munmap(p, from_len); 1029 munmap(q, from_len); 1030 done_compare = 1; 1031 } 1032 out: 1033 if (!done_compare) { 1034 char buf1[MAXBSIZE]; 1035 char buf2[MAXBSIZE]; 1036 int n1, n2; 1037 1038 rv = 0; 1039 lseek(from_fd, 0, SEEK_SET); 1040 lseek(to_fd, 0, SEEK_SET); 1041 while (rv == 0) { 1042 n1 = read(from_fd, buf1, sizeof(buf1)); 1043 if (n1 == 0) 1044 break; /* EOF */ 1045 else if (n1 > 0) { 1046 n2 = read(to_fd, buf2, n1); 1047 if (n2 == n1) 1048 rv = memcmp(buf1, buf2, n1); 1049 else 1050 rv = 1; /* out of sync */ 1051 } else 1052 rv = 1; /* read failure */ 1053 digest_update(&ctx, buf1, n1); 1054 } 1055 lseek(from_fd, 0, SEEK_SET); 1056 lseek(to_fd, 0, SEEK_SET); 1057 } 1058 } else 1059 rv = 1; /* don't bother in this case */ 1060 1061 if (dresp != NULL) { 1062 if (rv == 0) 1063 *dresp = digest_end(&ctx, NULL); 1064 else 1065 (void)digest_end(&ctx, NULL); 1066 } 1067 1068 return rv; 1069 } 1070 1071 /* 1072 * create_tempfile -- 1073 * create a temporary file based on path and open it 1074 */ 1075 static int 1076 create_tempfile(const char *path, char *temp, size_t tsize) 1077 { 1078 char *p; 1079 1080 (void)strncpy(temp, path, tsize); 1081 temp[tsize - 1] = '\0'; 1082 if ((p = strrchr(temp, '/')) != NULL) 1083 p++; 1084 else 1085 p = temp; 1086 (void)strncpy(p, "INS@XXXX", &temp[tsize - 1] - p); 1087 temp[tsize - 1] = '\0'; 1088 return (mkstemp(temp)); 1089 } 1090 1091 /* 1092 * create_newfile -- 1093 * create a new file, overwriting an existing one if necessary 1094 */ 1095 static int 1096 create_newfile(const char *path, int target, struct stat *sbp) 1097 { 1098 char backup[MAXPATHLEN]; 1099 int saved_errno = 0; 1100 int newfd; 1101 1102 if (target) { 1103 /* 1104 * Unlink now... avoid ETXTBSY errors later. Try to turn 1105 * off the append/immutable bits -- if we fail, go ahead, 1106 * it might work. 1107 */ 1108 if (sbp->st_flags & NOCHANGEBITS) 1109 (void)chflags(path, sbp->st_flags & ~NOCHANGEBITS); 1110 1111 if (dobackup) { 1112 if ((size_t)snprintf(backup, MAXPATHLEN, "%s%s", 1113 path, suffix) != strlen(path) + strlen(suffix)) 1114 errx(EX_OSERR, "%s: backup filename too long", 1115 path); 1116 (void)snprintf(backup, MAXPATHLEN, "%s%s", 1117 path, suffix); 1118 if (verbose) 1119 (void)printf("install: %s -> %s\n", 1120 path, backup); 1121 if (rename(path, backup) < 0) 1122 err(EX_OSERR, "rename: %s to %s", path, backup); 1123 } else 1124 if (unlink(path) < 0) 1125 saved_errno = errno; 1126 } 1127 1128 newfd = open(path, O_CREAT | O_RDWR | O_TRUNC, S_IRUSR | S_IWUSR); 1129 if (newfd < 0 && saved_errno != 0) 1130 errno = saved_errno; 1131 return newfd; 1132 } 1133 1134 /* 1135 * copy -- 1136 * copy from one file to another 1137 */ 1138 static char * 1139 copy(int from_fd, const char *from_name, int to_fd, const char *to_name, 1140 off_t size) 1141 { 1142 int nr, nw; 1143 int serrno; 1144 char *p; 1145 char buf[MAXBSIZE]; 1146 int done_copy; 1147 DIGEST_CTX ctx; 1148 1149 /* Rewind file descriptors. */ 1150 if (lseek(from_fd, (off_t)0, SEEK_SET) == (off_t)-1) 1151 err(EX_OSERR, "lseek: %s", from_name); 1152 if (lseek(to_fd, (off_t)0, SEEK_SET) == (off_t)-1) 1153 err(EX_OSERR, "lseek: %s", to_name); 1154 1155 digest_init(&ctx); 1156 1157 /* 1158 * Mmap and write if less than 8M (the limit is so we don't totally 1159 * trash memory on big files. This is really a minor hack, but it 1160 * wins some CPU back. 1161 */ 1162 done_copy = 0; 1163 if (size <= 8 * 1048576 && trymmap(from_fd) && 1164 (p = mmap(NULL, (size_t)size, PROT_READ, MAP_SHARED, 1165 from_fd, (off_t)0)) != MAP_FAILED) { 1166 nw = write(to_fd, p, size); 1167 if (nw != size) { 1168 serrno = errno; 1169 (void)unlink(to_name); 1170 if (nw >= 0) { 1171 errx(EX_OSERR, 1172 "short write to %s: %jd bytes written, %jd bytes asked to write", 1173 to_name, (uintmax_t)nw, (uintmax_t)size); 1174 } else { 1175 errno = serrno; 1176 err(EX_OSERR, "%s", to_name); 1177 } 1178 } 1179 digest_update(&ctx, p, size); 1180 (void)munmap(p, size); 1181 done_copy = 1; 1182 } 1183 if (!done_copy) { 1184 while ((nr = read(from_fd, buf, sizeof(buf))) > 0) { 1185 if ((nw = write(to_fd, buf, nr)) != nr) { 1186 serrno = errno; 1187 (void)unlink(to_name); 1188 if (nw >= 0) { 1189 errx(EX_OSERR, 1190 "short write to %s: %jd bytes written, %jd bytes asked to write", 1191 to_name, (uintmax_t)nw, 1192 (uintmax_t)size); 1193 } else { 1194 errno = serrno; 1195 err(EX_OSERR, "%s", to_name); 1196 } 1197 } 1198 digest_update(&ctx, buf, nr); 1199 } 1200 if (nr != 0) { 1201 serrno = errno; 1202 (void)unlink(to_name); 1203 errno = serrno; 1204 err(EX_OSERR, "%s", from_name); 1205 } 1206 } 1207 return (digest_end(&ctx, NULL)); 1208 } 1209 1210 /* 1211 * strip -- 1212 * use strip(1) to strip the target file 1213 */ 1214 static void 1215 strip(const char *to_name) 1216 { 1217 const char *stripbin; 1218 int serrno, status; 1219 1220 switch (fork()) { 1221 case -1: 1222 serrno = errno; 1223 (void)unlink(to_name); 1224 errno = serrno; 1225 err(EX_TEMPFAIL, "fork"); 1226 case 0: 1227 stripbin = getenv("STRIPBIN"); 1228 if (stripbin == NULL) 1229 stripbin = "strip"; 1230 execlp(stripbin, stripbin, to_name, (char *)NULL); 1231 err(EX_OSERR, "exec(%s)", stripbin); 1232 default: 1233 if (wait(&status) == -1 || status) { 1234 serrno = errno; 1235 (void)unlink(to_name); 1236 errc(EX_SOFTWARE, serrno, "wait"); 1237 /* NOTREACHED */ 1238 } 1239 } 1240 } 1241 1242 /* 1243 * install_dir -- 1244 * build directory hierarchy 1245 */ 1246 static void 1247 install_dir(char *path) 1248 { 1249 char *p; 1250 struct stat sb; 1251 int ch; 1252 1253 for (p = path;; ++p) 1254 if (!*p || (p != path && *p == '/')) { 1255 ch = *p; 1256 *p = '\0'; 1257 if (stat(path, &sb)) { 1258 if (errno != ENOENT || mkdir(path, 0755) < 0) { 1259 err(EX_OSERR, "mkdir %s", path); 1260 /* NOTREACHED */ 1261 } else if (verbose) 1262 (void)printf("install: mkdir %s\n", 1263 path); 1264 } else if (!S_ISDIR(sb.st_mode)) 1265 errx(EX_OSERR, "%s exists but is not a directory", path); 1266 if (!(*p = ch)) 1267 break; 1268 } 1269 1270 if (!dounpriv) { 1271 if ((gid != (gid_t)-1 || uid != (uid_t)-1) && 1272 chown(path, uid, gid)) 1273 warn("chown %u:%u %s", uid, gid, path); 1274 /* XXXBED: should we do the chmod in the dounpriv case? */ 1275 if (chmod(path, mode)) 1276 warn("chmod %o %s", mode, path); 1277 } 1278 metadata_log(path, "dir", NULL, NULL, NULL, 0); 1279 } 1280 1281 /* 1282 * metadata_log -- 1283 * if metafp is not NULL, output mtree(8) full path name and settings to 1284 * metafp, to allow permissions to be set correctly by other tools, 1285 * or to allow integrity checks to be performed. 1286 */ 1287 static void 1288 metadata_log(const char *path, const char *type, struct timeval *tv, 1289 const char *slink, const char *digestresult, off_t size) 1290 { 1291 static const char extra[] = { ' ', '\t', '\n', '\\', '#', '\0' }; 1292 const char *p; 1293 char *buf; 1294 size_t destlen; 1295 struct flock metalog_lock; 1296 1297 if (!metafp) 1298 return; 1299 /* Buffer for strsvis(3). */ 1300 buf = (char *)malloc(4 * strlen(path) + 1); 1301 if (buf == NULL) { 1302 warnx("%s", strerror(ENOMEM)); 1303 return; 1304 } 1305 1306 /* Lock log file. */ 1307 metalog_lock.l_start = 0; 1308 metalog_lock.l_len = 0; 1309 metalog_lock.l_whence = SEEK_SET; 1310 metalog_lock.l_type = F_WRLCK; 1311 if (fcntl(fileno(metafp), F_SETLKW, &metalog_lock) == -1) { 1312 warn("can't lock %s", metafile); 1313 free(buf); 1314 return; 1315 } 1316 1317 /* Remove destdir. */ 1318 p = path; 1319 if (destdir) { 1320 destlen = strlen(destdir); 1321 if (strncmp(p, destdir, destlen) == 0 && 1322 (p[destlen] == '/' || p[destlen] == '\0')) 1323 p += destlen; 1324 } 1325 while (*p && *p == '/') 1326 p++; 1327 strsvis(buf, p, VIS_OCTAL, extra); 1328 p = buf; 1329 /* Print details. */ 1330 fprintf(metafp, ".%s%s type=%s", *p ? "/" : "", p, type); 1331 if (owner) 1332 fprintf(metafp, " uname=%s", owner); 1333 if (group) 1334 fprintf(metafp, " gname=%s", group); 1335 fprintf(metafp, " mode=%#o", mode); 1336 if (slink) { 1337 strsvis(buf, slink, VIS_CSTYLE, extra); /* encode link */ 1338 fprintf(metafp, " link=%s", buf); 1339 } 1340 if (*type == 'f') /* type=file */ 1341 fprintf(metafp, " size=%lld", (long long)size); 1342 if (tv != NULL && dopreserve) 1343 fprintf(metafp, " time=%lld.%ld", 1344 (long long)tv[1].tv_sec, (long)tv[1].tv_usec); 1345 if (digestresult && digest) 1346 fprintf(metafp, " %s=%s", digest, digestresult); 1347 if (fflags) 1348 fprintf(metafp, " flags=%s", fflags); 1349 if (tags) 1350 fprintf(metafp, " tags=%s", tags); 1351 fputc('\n', metafp); 1352 /* Flush line. */ 1353 fflush(metafp); 1354 1355 /* Unlock log file. */ 1356 metalog_lock.l_type = F_UNLCK; 1357 if (fcntl(fileno(metafp), F_SETLKW, &metalog_lock) == -1) 1358 warn("can't unlock %s", metafile); 1359 free(buf); 1360 } 1361 1362 /* 1363 * usage -- 1364 * print a usage message and die 1365 */ 1366 static void 1367 usage(void) 1368 { 1369 (void)fprintf(stderr, 1370 "usage: install [-bCcpSsUv] [-f flags] [-g group] [-m mode] [-o owner]\n" 1371 " [-M log] [-D dest] [-h hash] [-T tags]\n" 1372 " [-B suffix] [-l linkflags] [-N dbdir]\n" 1373 " file1 file2\n" 1374 " install [-bCcpSsUv] [-f flags] [-g group] [-m mode] [-o owner]\n" 1375 " [-M log] [-D dest] [-h hash] [-T tags]\n" 1376 " [-B suffix] [-l linkflags] [-N dbdir]\n" 1377 " file1 ... fileN directory\n" 1378 " install -dU [-vU] [-g group] [-m mode] [-N dbdir] [-o owner]\n" 1379 " [-M log] [-D dest] [-h hash] [-T tags]\n" 1380 " directory ...\n"); 1381 exit(EX_USAGE); 1382 /* NOTREACHED */ 1383 } 1384 1385 /* 1386 * trymmap -- 1387 * return true (1) if mmap should be tried, false (0) if not. 1388 */ 1389 static int 1390 trymmap(int fd) 1391 { 1392 /* 1393 * The ifdef is for bootstrapping - f_fstypename doesn't exist in 1394 * pre-Lite2-merge systems. 1395 */ 1396 #ifdef MFSNAMELEN 1397 struct statfs stfs; 1398 1399 if (fstatfs(fd, &stfs) != 0) 1400 return (0); 1401 if (strcmp(stfs.f_fstypename, "ufs") == 0 || 1402 strcmp(stfs.f_fstypename, "cd9660") == 0) 1403 return (1); 1404 #endif 1405 return (0); 1406 } 1407