1 /*- 2 * Copyright (c) 2003-2009 Tim Kientzle 3 * Copyright (c) 2010-2012 Michihiro NAKAJIMA 4 * Copyright (c) 2016 Martin Matuska 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28 #include "archive_platform.h" 29 __FBSDID("$FreeBSD"); 30 31 /* This is the tree-walking code for POSIX systems. */ 32 #if !defined(_WIN32) || defined(__CYGWIN__) 33 34 #ifdef HAVE_SYS_TYPES_H 35 #include <sys/types.h> 36 #endif 37 #ifdef HAVE_SYS_EXTATTR_H 38 #include <sys/extattr.h> 39 #endif 40 #ifdef HAVE_SYS_IOCTL_H 41 #include <sys/ioctl.h> 42 #endif 43 #ifdef HAVE_SYS_PARAM_H 44 #include <sys/param.h> 45 #endif 46 #ifdef HAVE_SYS_STAT_H 47 #include <sys/stat.h> 48 #endif 49 #if defined(HAVE_SYS_XATTR_H) 50 #include <sys/xattr.h> 51 #elif defined(HAVE_ATTR_XATTR_H) 52 #include <attr/xattr.h> 53 #endif 54 #ifdef HAVE_SYS_EA_H 55 #include <sys/ea.h> 56 #endif 57 #ifdef HAVE_COPYFILE_H 58 #include <copyfile.h> 59 #endif 60 #ifdef HAVE_ERRNO_H 61 #include <errno.h> 62 #endif 63 #ifdef HAVE_FCNTL_H 64 #include <fcntl.h> 65 #endif 66 #ifdef HAVE_LIMITS_H 67 #include <limits.h> 68 #endif 69 #ifdef HAVE_LINUX_TYPES_H 70 #include <linux/types.h> 71 #endif 72 #ifdef HAVE_LINUX_FIEMAP_H 73 #include <linux/fiemap.h> 74 #endif 75 #ifdef HAVE_LINUX_FS_H 76 #include <linux/fs.h> 77 #endif 78 /* 79 * Some Linux distributions have both linux/ext2_fs.h and ext2fs/ext2_fs.h. 80 * As the include guards don't agree, the order of include is important. 81 */ 82 #ifdef HAVE_LINUX_EXT2_FS_H 83 #include <linux/ext2_fs.h> /* for Linux file flags */ 84 #endif 85 #if defined(HAVE_EXT2FS_EXT2_FS_H) && !defined(__CYGWIN__) 86 #include <ext2fs/ext2_fs.h> /* Linux file flags, broken on Cygwin */ 87 #endif 88 #ifdef HAVE_PATHS_H 89 #include <paths.h> 90 #endif 91 #ifdef HAVE_UNISTD_H 92 #include <unistd.h> 93 #endif 94 95 #include "archive.h" 96 #include "archive_entry.h" 97 #include "archive_private.h" 98 #include "archive_read_disk_private.h" 99 100 #ifndef O_CLOEXEC 101 #define O_CLOEXEC 0 102 #endif 103 104 static int setup_mac_metadata(struct archive_read_disk *, 105 struct archive_entry *, int *fd); 106 #ifdef ARCHIVE_XATTR_FREEBSD 107 static int setup_xattrs_namespace(struct archive_read_disk *, 108 struct archive_entry *, int *, int); 109 #endif 110 static int setup_xattrs(struct archive_read_disk *, 111 struct archive_entry *, int *fd); 112 static int setup_sparse(struct archive_read_disk *, 113 struct archive_entry *, int *fd); 114 #if defined(HAVE_LINUX_FIEMAP_H) 115 static int setup_sparse_fiemap(struct archive_read_disk *, 116 struct archive_entry *, int *fd); 117 #endif 118 119 #if !ARCHIVE_ACL_SUPPORT 120 int 121 archive_read_disk_entry_setup_acls(struct archive_read_disk *a, 122 struct archive_entry *entry, int *fd) 123 { 124 (void)a; /* UNUSED */ 125 (void)entry; /* UNUSED */ 126 (void)fd; /* UNUSED */ 127 return (ARCHIVE_OK); 128 } 129 #endif 130 131 /* 132 * Enter working directory and return working pathname of archive_entry. 133 * If a pointer to an integer is provided and its value is below zero 134 * open a file descriptor on this pathname. 135 */ 136 const char * 137 archive_read_disk_entry_setup_path(struct archive_read_disk *a, 138 struct archive_entry *entry, int *fd) 139 { 140 const char *path; 141 142 path = archive_entry_sourcepath(entry); 143 144 if (path == NULL || (a->tree != NULL && 145 a->tree_enter_working_dir(a->tree) != 0)) 146 path = archive_entry_pathname(entry); 147 if (path == NULL) { 148 archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, 149 "Couldn't determine path"); 150 } else if (fd != NULL && *fd < 0 && a->tree != NULL && 151 (a->follow_symlinks || archive_entry_filetype(entry) != AE_IFLNK)) { 152 *fd = a->open_on_current_dir(a->tree, path, 153 O_RDONLY | O_NONBLOCK); 154 } 155 return (path); 156 } 157 158 int 159 archive_read_disk_entry_from_file(struct archive *_a, 160 struct archive_entry *entry, 161 int fd, 162 const struct stat *st) 163 { 164 struct archive_read_disk *a = (struct archive_read_disk *)_a; 165 const char *path, *name; 166 struct stat s; 167 int initial_fd = fd; 168 int r, r1; 169 170 archive_check_magic(_a, ARCHIVE_READ_DISK_MAGIC, ARCHIVE_STATE_ANY, 171 "archive_read_disk_entry_from_file"); 172 173 archive_clear_error(_a); 174 path = archive_entry_sourcepath(entry); 175 if (path == NULL) 176 path = archive_entry_pathname(entry); 177 178 if (a->tree == NULL) { 179 if (st == NULL) { 180 #if HAVE_FSTAT 181 if (fd >= 0) { 182 if (fstat(fd, &s) != 0) { 183 archive_set_error(&a->archive, errno, 184 "Can't fstat"); 185 return (ARCHIVE_FAILED); 186 } 187 } else 188 #endif 189 #if HAVE_LSTAT 190 if (!a->follow_symlinks) { 191 if (lstat(path, &s) != 0) { 192 archive_set_error(&a->archive, errno, 193 "Can't lstat %s", path); 194 return (ARCHIVE_FAILED); 195 } 196 } else 197 #endif 198 if (la_stat(path, &s) != 0) { 199 archive_set_error(&a->archive, errno, 200 "Can't stat %s", path); 201 return (ARCHIVE_FAILED); 202 } 203 st = &s; 204 } 205 archive_entry_copy_stat(entry, st); 206 } 207 208 /* Lookup uname/gname */ 209 name = archive_read_disk_uname(_a, archive_entry_uid(entry)); 210 if (name != NULL) 211 archive_entry_copy_uname(entry, name); 212 name = archive_read_disk_gname(_a, archive_entry_gid(entry)); 213 if (name != NULL) 214 archive_entry_copy_gname(entry, name); 215 216 #ifdef HAVE_STRUCT_STAT_ST_FLAGS 217 /* On FreeBSD, we get flags for free with the stat. */ 218 /* TODO: Does this belong in copy_stat()? */ 219 if ((a->flags & ARCHIVE_READDISK_NO_FFLAGS) == 0 && st->st_flags != 0) 220 archive_entry_set_fflags(entry, st->st_flags, 0); 221 #endif 222 223 #if (defined(FS_IOC_GETFLAGS) && defined(HAVE_WORKING_FS_IOC_GETFLAGS)) || \ 224 (defined(EXT2_IOC_GETFLAGS) && defined(HAVE_WORKING_EXT2_IOC_GETFLAGS)) 225 /* Linux requires an extra ioctl to pull the flags. Although 226 * this is an extra step, it has a nice side-effect: We get an 227 * open file descriptor which we can use in the subsequent lookups. */ 228 if ((a->flags & ARCHIVE_READDISK_NO_FFLAGS) == 0 && 229 (S_ISREG(st->st_mode) || S_ISDIR(st->st_mode))) { 230 if (fd < 0) { 231 if (a->tree != NULL) 232 fd = a->open_on_current_dir(a->tree, path, 233 O_RDONLY | O_NONBLOCK | O_CLOEXEC); 234 else 235 fd = open(path, O_RDONLY | O_NONBLOCK | 236 O_CLOEXEC); 237 __archive_ensure_cloexec_flag(fd); 238 } 239 if (fd >= 0) { 240 int stflags; 241 r = ioctl(fd, 242 #if defined(FS_IOC_GETFLAGS) 243 FS_IOC_GETFLAGS, 244 #else 245 EXT2_IOC_GETFLAGS, 246 #endif 247 &stflags); 248 if (r == 0 && stflags != 0) 249 archive_entry_set_fflags(entry, stflags, 0); 250 } 251 } 252 #endif 253 254 #if defined(HAVE_READLINK) || defined(HAVE_READLINKAT) 255 if (S_ISLNK(st->st_mode)) { 256 size_t linkbuffer_len = st->st_size; 257 char *linkbuffer; 258 int lnklen; 259 260 linkbuffer = malloc(linkbuffer_len + 1); 261 if (linkbuffer == NULL) { 262 archive_set_error(&a->archive, ENOMEM, 263 "Couldn't read link data"); 264 return (ARCHIVE_FAILED); 265 } 266 if (a->tree != NULL) { 267 #ifdef HAVE_READLINKAT 268 lnklen = readlinkat(a->tree_current_dir_fd(a->tree), 269 path, linkbuffer, linkbuffer_len); 270 #else 271 if (a->tree_enter_working_dir(a->tree) != 0) { 272 archive_set_error(&a->archive, errno, 273 "Couldn't read link data"); 274 free(linkbuffer); 275 return (ARCHIVE_FAILED); 276 } 277 lnklen = readlink(path, linkbuffer, linkbuffer_len); 278 #endif /* HAVE_READLINKAT */ 279 } else 280 lnklen = readlink(path, linkbuffer, linkbuffer_len); 281 if (lnklen < 0) { 282 archive_set_error(&a->archive, errno, 283 "Couldn't read link data"); 284 free(linkbuffer); 285 return (ARCHIVE_FAILED); 286 } 287 linkbuffer[lnklen] = '\0'; 288 archive_entry_set_symlink(entry, linkbuffer); 289 free(linkbuffer); 290 } 291 #endif /* HAVE_READLINK || HAVE_READLINKAT */ 292 293 r = 0; 294 if ((a->flags & ARCHIVE_READDISK_NO_ACL) == 0) 295 r = archive_read_disk_entry_setup_acls(a, entry, &fd); 296 if ((a->flags & ARCHIVE_READDISK_NO_XATTR) == 0) { 297 r1 = setup_xattrs(a, entry, &fd); 298 if (r1 < r) 299 r = r1; 300 } 301 if (a->flags & ARCHIVE_READDISK_MAC_COPYFILE) { 302 r1 = setup_mac_metadata(a, entry, &fd); 303 if (r1 < r) 304 r = r1; 305 } 306 if ((a->flags & ARCHIVE_READDISK_NO_SPARSE) == 0) { 307 r1 = setup_sparse(a, entry, &fd); 308 if (r1 < r) 309 r = r1; 310 } 311 312 /* If we opened the file earlier in this function, close it. */ 313 if (initial_fd != fd) 314 close(fd); 315 return (r); 316 } 317 318 #if defined(__APPLE__) && defined(HAVE_COPYFILE_H) 319 /* 320 * The Mac OS "copyfile()" API copies the extended metadata for a 321 * file into a separate file in AppleDouble format (see RFC 1740). 322 * 323 * Mac OS tar and cpio implementations store this extended 324 * metadata as a separate entry just before the regular entry 325 * with a "._" prefix added to the filename. 326 * 327 * Note that this is currently done unconditionally; the tar program has 328 * an option to discard this information before the archive is written. 329 * 330 * TODO: If there's a failure, report it and return ARCHIVE_WARN. 331 */ 332 static int 333 setup_mac_metadata(struct archive_read_disk *a, 334 struct archive_entry *entry, int *fd) 335 { 336 int tempfd = -1; 337 int copyfile_flags = COPYFILE_NOFOLLOW | COPYFILE_ACL | COPYFILE_XATTR; 338 struct stat copyfile_stat; 339 int ret = ARCHIVE_OK; 340 void *buff = NULL; 341 int have_attrs; 342 const char *name, *tempdir; 343 struct archive_string tempfile; 344 345 (void)fd; /* UNUSED */ 346 347 name = archive_read_disk_entry_setup_path(a, entry, NULL); 348 if (name == NULL) 349 return (ARCHIVE_WARN); 350 351 /* Short-circuit if there's nothing to do. */ 352 have_attrs = copyfile(name, NULL, 0, copyfile_flags | COPYFILE_CHECK); 353 if (have_attrs == -1) { 354 archive_set_error(&a->archive, errno, 355 "Could not check extended attributes"); 356 return (ARCHIVE_WARN); 357 } 358 if (have_attrs == 0) 359 return (ARCHIVE_OK); 360 361 tempdir = NULL; 362 if (issetugid() == 0) 363 tempdir = getenv("TMPDIR"); 364 if (tempdir == NULL) 365 tempdir = _PATH_TMP; 366 archive_string_init(&tempfile); 367 archive_strcpy(&tempfile, tempdir); 368 archive_strcat(&tempfile, "tar.md.XXXXXX"); 369 tempfd = mkstemp(tempfile.s); 370 if (tempfd < 0) { 371 archive_set_error(&a->archive, errno, 372 "Could not open extended attribute file"); 373 ret = ARCHIVE_WARN; 374 goto cleanup; 375 } 376 __archive_ensure_cloexec_flag(tempfd); 377 378 /* XXX I wish copyfile() could pack directly to a memory 379 * buffer; that would avoid the temp file here. For that 380 * matter, it would be nice if fcopyfile() actually worked, 381 * that would reduce the many open/close races here. */ 382 if (copyfile(name, tempfile.s, 0, copyfile_flags | COPYFILE_PACK)) { 383 archive_set_error(&a->archive, errno, 384 "Could not pack extended attributes"); 385 ret = ARCHIVE_WARN; 386 goto cleanup; 387 } 388 if (fstat(tempfd, ©file_stat)) { 389 archive_set_error(&a->archive, errno, 390 "Could not check size of extended attributes"); 391 ret = ARCHIVE_WARN; 392 goto cleanup; 393 } 394 buff = malloc(copyfile_stat.st_size); 395 if (buff == NULL) { 396 archive_set_error(&a->archive, errno, 397 "Could not allocate memory for extended attributes"); 398 ret = ARCHIVE_WARN; 399 goto cleanup; 400 } 401 if (copyfile_stat.st_size != read(tempfd, buff, copyfile_stat.st_size)) { 402 archive_set_error(&a->archive, errno, 403 "Could not read extended attributes into memory"); 404 ret = ARCHIVE_WARN; 405 goto cleanup; 406 } 407 archive_entry_copy_mac_metadata(entry, buff, copyfile_stat.st_size); 408 409 cleanup: 410 if (tempfd >= 0) { 411 close(tempfd); 412 unlink(tempfile.s); 413 } 414 archive_string_free(&tempfile); 415 free(buff); 416 return (ret); 417 } 418 419 #else 420 421 /* 422 * Stub implementation for non-Mac systems. 423 */ 424 static int 425 setup_mac_metadata(struct archive_read_disk *a, 426 struct archive_entry *entry, int *fd) 427 { 428 (void)a; /* UNUSED */ 429 (void)entry; /* UNUSED */ 430 (void)fd; /* UNUSED */ 431 return (ARCHIVE_OK); 432 } 433 #endif 434 435 #if ARCHIVE_XATTR_LINUX || ARCHIVE_XATTR_DARWIN || ARCHIVE_XATTR_AIX 436 437 /* 438 * Linux, Darwin and AIX extended attribute support. 439 * 440 * TODO: By using a stack-allocated buffer for the first 441 * call to getxattr(), we might be able to avoid the second 442 * call entirely. We only need the second call if the 443 * stack-allocated buffer is too small. But a modest buffer 444 * of 1024 bytes or so will often be big enough. Same applies 445 * to listxattr(). 446 */ 447 448 449 static int 450 setup_xattr(struct archive_read_disk *a, 451 struct archive_entry *entry, const char *name, int fd, const char *accpath) 452 { 453 ssize_t size; 454 void *value = NULL; 455 456 457 if (fd >= 0) { 458 #if ARCHIVE_XATTR_LINUX 459 size = fgetxattr(fd, name, NULL, 0); 460 #elif ARCHIVE_XATTR_DARWIN 461 size = fgetxattr(fd, name, NULL, 0, 0, 0); 462 #elif ARCHIVE_XATTR_AIX 463 size = fgetea(fd, name, NULL, 0); 464 #endif 465 } else if (!a->follow_symlinks) { 466 #if ARCHIVE_XATTR_LINUX 467 size = lgetxattr(accpath, name, NULL, 0); 468 #elif ARCHIVE_XATTR_DARWIN 469 size = getxattr(accpath, name, NULL, 0, 0, XATTR_NOFOLLOW); 470 #elif ARCHIVE_XATTR_AIX 471 size = lgetea(accpath, name, NULL, 0); 472 #endif 473 } else { 474 #if ARCHIVE_XATTR_LINUX 475 size = getxattr(accpath, name, NULL, 0); 476 #elif ARCHIVE_XATTR_DARWIN 477 size = getxattr(accpath, name, NULL, 0, 0, 0); 478 #elif ARCHIVE_XATTR_AIX 479 size = getea(accpath, name, NULL, 0); 480 #endif 481 } 482 483 if (size == -1) { 484 archive_set_error(&a->archive, errno, 485 "Couldn't query extended attribute"); 486 return (ARCHIVE_WARN); 487 } 488 489 if (size > 0 && (value = malloc(size)) == NULL) { 490 archive_set_error(&a->archive, errno, "Out of memory"); 491 return (ARCHIVE_FATAL); 492 } 493 494 495 if (fd >= 0) { 496 #if ARCHIVE_XATTR_LINUX 497 size = fgetxattr(fd, name, value, size); 498 #elif ARCHIVE_XATTR_DARWIN 499 size = fgetxattr(fd, name, value, size, 0, 0); 500 #elif ARCHIVE_XATTR_AIX 501 size = fgetea(fd, name, value, size); 502 #endif 503 } else if (!a->follow_symlinks) { 504 #if ARCHIVE_XATTR_LINUX 505 size = lgetxattr(accpath, name, value, size); 506 #elif ARCHIVE_XATTR_DARWIN 507 size = getxattr(accpath, name, value, size, 0, XATTR_NOFOLLOW); 508 #elif ARCHIVE_XATTR_AIX 509 size = lgetea(accpath, name, value, size); 510 #endif 511 } else { 512 #if ARCHIVE_XATTR_LINUX 513 size = getxattr(accpath, name, value, size); 514 #elif ARCHIVE_XATTR_DARWIN 515 size = getxattr(accpath, name, value, size, 0, 0); 516 #elif ARCHIVE_XATTR_AIX 517 size = getea(accpath, name, value, size); 518 #endif 519 } 520 521 if (size == -1) { 522 archive_set_error(&a->archive, errno, 523 "Couldn't read extended attribute"); 524 return (ARCHIVE_WARN); 525 } 526 527 archive_entry_xattr_add_entry(entry, name, value, size); 528 529 free(value); 530 return (ARCHIVE_OK); 531 } 532 533 static int 534 setup_xattrs(struct archive_read_disk *a, 535 struct archive_entry *entry, int *fd) 536 { 537 char *list, *p; 538 const char *path; 539 ssize_t list_size; 540 541 path = NULL; 542 543 if (*fd < 0) { 544 path = archive_read_disk_entry_setup_path(a, entry, fd); 545 if (path == NULL) 546 return (ARCHIVE_WARN); 547 } 548 549 if (*fd >= 0) { 550 #if ARCHIVE_XATTR_LINUX 551 list_size = flistxattr(*fd, NULL, 0); 552 #elif ARCHIVE_XATTR_DARWIN 553 list_size = flistxattr(*fd, NULL, 0, 0); 554 #elif ARCHIVE_XATTR_AIX 555 list_size = flistea(*fd, NULL, 0); 556 #endif 557 } else if (!a->follow_symlinks) { 558 #if ARCHIVE_XATTR_LINUX 559 list_size = llistxattr(path, NULL, 0); 560 #elif ARCHIVE_XATTR_DARWIN 561 list_size = listxattr(path, NULL, 0, XATTR_NOFOLLOW); 562 #elif ARCHIVE_XATTR_AIX 563 list_size = llistea(path, NULL, 0); 564 #endif 565 } else { 566 #if ARCHIVE_XATTR_LINUX 567 list_size = listxattr(path, NULL, 0); 568 #elif ARCHIVE_XATTR_DARWIN 569 list_size = listxattr(path, NULL, 0, 0); 570 #elif ARCHIVE_XATTR_AIX 571 list_size = listea(path, NULL, 0); 572 #endif 573 } 574 575 if (list_size == -1) { 576 if (errno == ENOTSUP || errno == ENOSYS) 577 return (ARCHIVE_OK); 578 archive_set_error(&a->archive, errno, 579 "Couldn't list extended attributes"); 580 return (ARCHIVE_WARN); 581 } 582 583 if (list_size == 0) 584 return (ARCHIVE_OK); 585 586 if ((list = malloc(list_size)) == NULL) { 587 archive_set_error(&a->archive, errno, "Out of memory"); 588 return (ARCHIVE_FATAL); 589 } 590 591 if (*fd >= 0) { 592 #if ARCHIVE_XATTR_LINUX 593 list_size = flistxattr(*fd, list, list_size); 594 #elif ARCHIVE_XATTR_DARWIN 595 list_size = flistxattr(*fd, list, list_size, 0); 596 #elif ARCHIVE_XATTR_AIX 597 list_size = flistea(*fd, list, list_size); 598 #endif 599 } else if (!a->follow_symlinks) { 600 #if ARCHIVE_XATTR_LINUX 601 list_size = llistxattr(path, list, list_size); 602 #elif ARCHIVE_XATTR_DARWIN 603 list_size = listxattr(path, list, list_size, XATTR_NOFOLLOW); 604 #elif ARCHIVE_XATTR_AIX 605 list_size = llistea(path, list, list_size); 606 #endif 607 } else { 608 #if ARCHIVE_XATTR_LINUX 609 list_size = listxattr(path, list, list_size); 610 #elif ARCHIVE_XATTR_DARWIN 611 list_size = listxattr(path, list, list_size, 0); 612 #elif ARCHIVE_XATTR_AIX 613 list_size = listea(path, list, list_size); 614 #endif 615 } 616 617 if (list_size == -1) { 618 archive_set_error(&a->archive, errno, 619 "Couldn't retrieve extended attributes"); 620 free(list); 621 return (ARCHIVE_WARN); 622 } 623 624 for (p = list; (p - list) < list_size; p += strlen(p) + 1) { 625 #if ARCHIVE_XATTR_LINUX 626 /* Linux: skip POSIX.1e ACL extended attributes */ 627 if (strncmp(p, "system.", 7) == 0 && 628 (strcmp(p + 7, "posix_acl_access") == 0 || 629 strcmp(p + 7, "posix_acl_default") == 0)) 630 continue; 631 if (strncmp(p, "trusted.SGI_", 12) == 0 && 632 (strcmp(p + 12, "ACL_DEFAULT") == 0 || 633 strcmp(p + 12, "ACL_FILE") == 0)) 634 continue; 635 636 /* Linux: xfsroot namespace is obsolete and unsupported */ 637 if (strncmp(p, "xfsroot.", 8) == 0) 638 continue; 639 #endif 640 setup_xattr(a, entry, p, *fd, path); 641 } 642 643 free(list); 644 return (ARCHIVE_OK); 645 } 646 647 #elif ARCHIVE_XATTR_FREEBSD 648 649 /* 650 * FreeBSD extattr interface. 651 */ 652 653 /* TODO: Implement this. Follow the Linux model above, but 654 * with FreeBSD-specific system calls, of course. Be careful 655 * to not include the system extattrs that hold ACLs; we handle 656 * those separately. 657 */ 658 static int 659 setup_xattr(struct archive_read_disk *a, struct archive_entry *entry, 660 int namespace, const char *name, const char *fullname, int fd, 661 const char *path); 662 663 static int 664 setup_xattr(struct archive_read_disk *a, struct archive_entry *entry, 665 int namespace, const char *name, const char *fullname, int fd, 666 const char *accpath) 667 { 668 ssize_t size; 669 void *value = NULL; 670 671 if (fd >= 0) 672 size = extattr_get_fd(fd, namespace, name, NULL, 0); 673 else if (!a->follow_symlinks) 674 size = extattr_get_link(accpath, namespace, name, NULL, 0); 675 else 676 size = extattr_get_file(accpath, namespace, name, NULL, 0); 677 678 if (size == -1) { 679 archive_set_error(&a->archive, errno, 680 "Couldn't query extended attribute"); 681 return (ARCHIVE_WARN); 682 } 683 684 if (size > 0 && (value = malloc(size)) == NULL) { 685 archive_set_error(&a->archive, errno, "Out of memory"); 686 return (ARCHIVE_FATAL); 687 } 688 689 if (fd >= 0) 690 size = extattr_get_fd(fd, namespace, name, value, size); 691 else if (!a->follow_symlinks) 692 size = extattr_get_link(accpath, namespace, name, value, size); 693 else 694 size = extattr_get_file(accpath, namespace, name, value, size); 695 696 if (size == -1) { 697 free(value); 698 archive_set_error(&a->archive, errno, 699 "Couldn't read extended attribute"); 700 return (ARCHIVE_WARN); 701 } 702 703 archive_entry_xattr_add_entry(entry, fullname, value, size); 704 705 free(value); 706 return (ARCHIVE_OK); 707 } 708 709 static int 710 setup_xattrs_namespace(struct archive_read_disk *a, 711 struct archive_entry *entry, int *fd, int namespace) 712 { 713 char buff[512]; 714 char *list, *p; 715 ssize_t list_size; 716 const char *path; 717 718 path = NULL; 719 720 if (*fd < 0) { 721 path = archive_read_disk_entry_setup_path(a, entry, fd); 722 if (path == NULL) 723 return (ARCHIVE_WARN); 724 } 725 726 if (*fd >= 0) 727 list_size = extattr_list_fd(*fd, namespace, NULL, 0); 728 else if (!a->follow_symlinks) 729 list_size = extattr_list_link(path, namespace, NULL, 0); 730 else 731 list_size = extattr_list_file(path, namespace, NULL, 0); 732 733 if (list_size == -1 && errno == EOPNOTSUPP) 734 return (ARCHIVE_OK); 735 if (list_size == -1 && errno == EPERM) 736 return (ARCHIVE_OK); 737 if (list_size == -1) { 738 archive_set_error(&a->archive, errno, 739 "Couldn't list extended attributes"); 740 return (ARCHIVE_WARN); 741 } 742 743 if (list_size == 0) 744 return (ARCHIVE_OK); 745 746 if ((list = malloc(list_size)) == NULL) { 747 archive_set_error(&a->archive, errno, "Out of memory"); 748 return (ARCHIVE_FATAL); 749 } 750 751 if (*fd >= 0) 752 list_size = extattr_list_fd(*fd, namespace, list, list_size); 753 else if (!a->follow_symlinks) 754 list_size = extattr_list_link(path, namespace, list, list_size); 755 else 756 list_size = extattr_list_file(path, namespace, list, list_size); 757 758 if (list_size == -1) { 759 archive_set_error(&a->archive, errno, 760 "Couldn't retrieve extended attributes"); 761 free(list); 762 return (ARCHIVE_WARN); 763 } 764 765 p = list; 766 while ((p - list) < list_size) { 767 size_t len = 255 & (int)*p; 768 char *name; 769 770 if (namespace == EXTATTR_NAMESPACE_SYSTEM) { 771 if (!strcmp(p + 1, "nfs4.acl") || 772 !strcmp(p + 1, "posix1e.acl_access") || 773 !strcmp(p + 1, "posix1e.acl_default")) { 774 p += 1 + len; 775 continue; 776 } 777 strcpy(buff, "system."); 778 } else { 779 strcpy(buff, "user."); 780 } 781 name = buff + strlen(buff); 782 memcpy(name, p + 1, len); 783 name[len] = '\0'; 784 setup_xattr(a, entry, namespace, name, buff, *fd, path); 785 p += 1 + len; 786 } 787 788 free(list); 789 return (ARCHIVE_OK); 790 } 791 792 static int 793 setup_xattrs(struct archive_read_disk *a, 794 struct archive_entry *entry, int *fd) 795 { 796 int namespaces[2]; 797 int i, res; 798 799 namespaces[0] = EXTATTR_NAMESPACE_USER; 800 namespaces[1] = EXTATTR_NAMESPACE_SYSTEM; 801 802 for (i = 0; i < 2; i++) { 803 res = setup_xattrs_namespace(a, entry, fd, 804 namespaces[i]); 805 switch (res) { 806 case (ARCHIVE_OK): 807 case (ARCHIVE_WARN): 808 break; 809 default: 810 return (res); 811 } 812 } 813 814 return (ARCHIVE_OK); 815 } 816 817 #else 818 819 /* 820 * Generic (stub) extended attribute support. 821 */ 822 static int 823 setup_xattrs(struct archive_read_disk *a, 824 struct archive_entry *entry, int *fd) 825 { 826 (void)a; /* UNUSED */ 827 (void)entry; /* UNUSED */ 828 (void)fd; /* UNUSED */ 829 return (ARCHIVE_OK); 830 } 831 832 #endif 833 834 #if defined(HAVE_LINUX_FIEMAP_H) 835 836 /* 837 * Linux FIEMAP sparse interface. 838 * 839 * The FIEMAP ioctl returns an "extent" for each physical allocation 840 * on disk. We need to process those to generate a more compact list 841 * of logical file blocks. We also need to be very careful to use 842 * FIEMAP_FLAG_SYNC here, since there are reports that Linux sometimes 843 * does not report allocations for newly-written data that hasn't 844 * been synced to disk. 845 * 846 * It's important to return a minimal sparse file list because we want 847 * to not trigger sparse file extensions if we don't have to, since 848 * not all readers support them. 849 */ 850 851 static int 852 setup_sparse_fiemap(struct archive_read_disk *a, 853 struct archive_entry *entry, int *fd) 854 { 855 char buff[4096]; 856 struct fiemap *fm; 857 struct fiemap_extent *fe; 858 int64_t size; 859 int count, do_fiemap, iters; 860 int exit_sts = ARCHIVE_OK; 861 const char *path; 862 863 if (archive_entry_filetype(entry) != AE_IFREG 864 || archive_entry_size(entry) <= 0 865 || archive_entry_hardlink(entry) != NULL) 866 return (ARCHIVE_OK); 867 868 if (*fd < 0) { 869 path = archive_read_disk_entry_setup_path(a, entry, NULL); 870 if (path == NULL) 871 return (ARCHIVE_FAILED); 872 873 if (a->tree != NULL) 874 *fd = a->open_on_current_dir(a->tree, path, 875 O_RDONLY | O_NONBLOCK | O_CLOEXEC); 876 else 877 *fd = open(path, O_RDONLY | O_NONBLOCK | O_CLOEXEC); 878 if (*fd < 0) { 879 archive_set_error(&a->archive, errno, 880 "Can't open `%s'", path); 881 return (ARCHIVE_FAILED); 882 } 883 __archive_ensure_cloexec_flag(*fd); 884 } 885 886 /* Initialize buffer to avoid the error valgrind complains about. */ 887 memset(buff, 0, sizeof(buff)); 888 count = (sizeof(buff) - sizeof(*fm))/sizeof(*fe); 889 fm = (struct fiemap *)buff; 890 fm->fm_start = 0; 891 fm->fm_length = ~0ULL;; 892 fm->fm_flags = FIEMAP_FLAG_SYNC; 893 fm->fm_extent_count = count; 894 do_fiemap = 1; 895 size = archive_entry_size(entry); 896 for (iters = 0; ; ++iters) { 897 int i, r; 898 899 r = ioctl(*fd, FS_IOC_FIEMAP, fm); 900 if (r < 0) { 901 /* When something error happens, it is better we 902 * should return ARCHIVE_OK because an earlier 903 * version(<2.6.28) cannot perform FS_IOC_FIEMAP. */ 904 goto exit_setup_sparse_fiemap; 905 } 906 if (fm->fm_mapped_extents == 0) { 907 if (iters == 0) { 908 /* Fully sparse file; insert a zero-length "data" entry */ 909 archive_entry_sparse_add_entry(entry, 0, 0); 910 } 911 break; 912 } 913 fe = fm->fm_extents; 914 for (i = 0; i < (int)fm->fm_mapped_extents; i++, fe++) { 915 if (!(fe->fe_flags & FIEMAP_EXTENT_UNWRITTEN)) { 916 /* The fe_length of the last block does not 917 * adjust itself to its size files. */ 918 int64_t length = fe->fe_length; 919 if (fe->fe_logical + length > (uint64_t)size) 920 length -= fe->fe_logical + length - size; 921 if (fe->fe_logical == 0 && length == size) { 922 /* This is not sparse. */ 923 do_fiemap = 0; 924 break; 925 } 926 if (length > 0) 927 archive_entry_sparse_add_entry(entry, 928 fe->fe_logical, length); 929 } 930 if (fe->fe_flags & FIEMAP_EXTENT_LAST) 931 do_fiemap = 0; 932 } 933 if (do_fiemap) { 934 fe = fm->fm_extents + fm->fm_mapped_extents -1; 935 fm->fm_start = fe->fe_logical + fe->fe_length; 936 } else 937 break; 938 } 939 exit_setup_sparse_fiemap: 940 return (exit_sts); 941 } 942 943 #if !defined(SEEK_HOLE) || !defined(SEEK_DATA) 944 static int 945 setup_sparse(struct archive_read_disk *a, 946 struct archive_entry *entry, int *fd) 947 { 948 return setup_sparse_fiemap(a, entry, fd); 949 } 950 #endif 951 #endif /* defined(HAVE_LINUX_FIEMAP_H) */ 952 953 #if defined(SEEK_HOLE) && defined(SEEK_DATA) 954 955 /* 956 * SEEK_HOLE sparse interface (FreeBSD, Linux, Solaris) 957 */ 958 959 static int 960 setup_sparse(struct archive_read_disk *a, 961 struct archive_entry *entry, int *fd) 962 { 963 int64_t size; 964 off_t initial_off; 965 off_t off_s, off_e; 966 int exit_sts = ARCHIVE_OK; 967 int check_fully_sparse = 0; 968 const char *path; 969 970 if (archive_entry_filetype(entry) != AE_IFREG 971 || archive_entry_size(entry) <= 0 972 || archive_entry_hardlink(entry) != NULL) 973 return (ARCHIVE_OK); 974 975 /* Does filesystem support the reporting of hole ? */ 976 if (*fd < 0) 977 path = archive_read_disk_entry_setup_path(a, entry, fd); 978 else 979 path = NULL; 980 981 if (*fd >= 0) { 982 #ifdef _PC_MIN_HOLE_SIZE 983 if (fpathconf(*fd, _PC_MIN_HOLE_SIZE) <= 0) 984 return (ARCHIVE_OK); 985 #endif 986 initial_off = lseek(*fd, 0, SEEK_CUR); 987 if (initial_off != 0) 988 lseek(*fd, 0, SEEK_SET); 989 } else { 990 if (path == NULL) 991 return (ARCHIVE_FAILED); 992 #ifdef _PC_MIN_HOLE_SIZE 993 if (pathconf(path, _PC_MIN_HOLE_SIZE) <= 0) 994 return (ARCHIVE_OK); 995 #endif 996 *fd = open(path, O_RDONLY | O_NONBLOCK | O_CLOEXEC); 997 if (*fd < 0) { 998 archive_set_error(&a->archive, errno, 999 "Can't open `%s'", path); 1000 return (ARCHIVE_FAILED); 1001 } 1002 __archive_ensure_cloexec_flag(*fd); 1003 initial_off = 0; 1004 } 1005 1006 #ifndef _PC_MIN_HOLE_SIZE 1007 /* Check if the underlying filesystem supports seek hole */ 1008 off_s = lseek(*fd, 0, SEEK_HOLE); 1009 if (off_s < 0) 1010 #if defined(HAVE_LINUX_FIEMAP_H) 1011 return setup_sparse_fiemap(a, entry, fd); 1012 #else 1013 goto exit_setup_sparse; 1014 #endif 1015 else if (off_s > 0) 1016 lseek(*fd, 0, SEEK_SET); 1017 #endif 1018 1019 off_s = 0; 1020 size = archive_entry_size(entry); 1021 while (off_s < size) { 1022 off_s = lseek(*fd, off_s, SEEK_DATA); 1023 if (off_s == (off_t)-1) { 1024 if (errno == ENXIO) { 1025 /* no more hole */ 1026 if (archive_entry_sparse_count(entry) == 0) { 1027 /* Potentially a fully-sparse file. */ 1028 check_fully_sparse = 1; 1029 } 1030 break; 1031 } 1032 archive_set_error(&a->archive, errno, 1033 "lseek(SEEK_HOLE) failed"); 1034 exit_sts = ARCHIVE_FAILED; 1035 goto exit_setup_sparse; 1036 } 1037 off_e = lseek(*fd, off_s, SEEK_HOLE); 1038 if (off_e == (off_t)-1) { 1039 if (errno == ENXIO) { 1040 off_e = lseek(*fd, 0, SEEK_END); 1041 if (off_e != (off_t)-1) 1042 break;/* no more data */ 1043 } 1044 archive_set_error(&a->archive, errno, 1045 "lseek(SEEK_DATA) failed"); 1046 exit_sts = ARCHIVE_FAILED; 1047 goto exit_setup_sparse; 1048 } 1049 if (off_s == 0 && off_e == size) 1050 break;/* This is not sparse. */ 1051 archive_entry_sparse_add_entry(entry, off_s, 1052 off_e - off_s); 1053 off_s = off_e; 1054 } 1055 1056 if (check_fully_sparse) { 1057 if (lseek(*fd, 0, SEEK_HOLE) == 0 && 1058 lseek(*fd, 0, SEEK_END) == size) { 1059 /* Fully sparse file; insert a zero-length "data" entry */ 1060 archive_entry_sparse_add_entry(entry, 0, 0); 1061 } 1062 } 1063 exit_setup_sparse: 1064 lseek(*fd, initial_off, SEEK_SET); 1065 return (exit_sts); 1066 } 1067 1068 #elif !defined(HAVE_LINUX_FIEMAP_H) 1069 1070 /* 1071 * Generic (stub) sparse support. 1072 */ 1073 static int 1074 setup_sparse(struct archive_read_disk *a, 1075 struct archive_entry *entry, int *fd) 1076 { 1077 (void)a; /* UNUSED */ 1078 (void)entry; /* UNUSED */ 1079 (void)fd; /* UNUSED */ 1080 return (ARCHIVE_OK); 1081 } 1082 1083 #endif 1084 1085 #endif /* !defined(_WIN32) || defined(__CYGWIN__) */ 1086 1087