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 r1 = setup_sparse(a, entry, &fd); 307 if (r1 < r) 308 r = r1; 309 310 /* If we opened the file earlier in this function, close it. */ 311 if (initial_fd != fd) 312 close(fd); 313 return (r); 314 } 315 316 #if defined(__APPLE__) && defined(HAVE_COPYFILE_H) 317 /* 318 * The Mac OS "copyfile()" API copies the extended metadata for a 319 * file into a separate file in AppleDouble format (see RFC 1740). 320 * 321 * Mac OS tar and cpio implementations store this extended 322 * metadata as a separate entry just before the regular entry 323 * with a "._" prefix added to the filename. 324 * 325 * Note that this is currently done unconditionally; the tar program has 326 * an option to discard this information before the archive is written. 327 * 328 * TODO: If there's a failure, report it and return ARCHIVE_WARN. 329 */ 330 static int 331 setup_mac_metadata(struct archive_read_disk *a, 332 struct archive_entry *entry, int *fd) 333 { 334 int tempfd = -1; 335 int copyfile_flags = COPYFILE_NOFOLLOW | COPYFILE_ACL | COPYFILE_XATTR; 336 struct stat copyfile_stat; 337 int ret = ARCHIVE_OK; 338 void *buff = NULL; 339 int have_attrs; 340 const char *name, *tempdir; 341 struct archive_string tempfile; 342 343 (void)fd; /* UNUSED */ 344 345 name = archive_read_disk_entry_setup_path(a, entry, NULL); 346 if (name == NULL) 347 return (ARCHIVE_WARN); 348 349 /* Short-circuit if there's nothing to do. */ 350 have_attrs = copyfile(name, NULL, 0, copyfile_flags | COPYFILE_CHECK); 351 if (have_attrs == -1) { 352 archive_set_error(&a->archive, errno, 353 "Could not check extended attributes"); 354 return (ARCHIVE_WARN); 355 } 356 if (have_attrs == 0) 357 return (ARCHIVE_OK); 358 359 tempdir = NULL; 360 if (issetugid() == 0) 361 tempdir = getenv("TMPDIR"); 362 if (tempdir == NULL) 363 tempdir = _PATH_TMP; 364 archive_string_init(&tempfile); 365 archive_strcpy(&tempfile, tempdir); 366 archive_strcat(&tempfile, "tar.md.XXXXXX"); 367 tempfd = mkstemp(tempfile.s); 368 if (tempfd < 0) { 369 archive_set_error(&a->archive, errno, 370 "Could not open extended attribute file"); 371 ret = ARCHIVE_WARN; 372 goto cleanup; 373 } 374 __archive_ensure_cloexec_flag(tempfd); 375 376 /* XXX I wish copyfile() could pack directly to a memory 377 * buffer; that would avoid the temp file here. For that 378 * matter, it would be nice if fcopyfile() actually worked, 379 * that would reduce the many open/close races here. */ 380 if (copyfile(name, tempfile.s, 0, copyfile_flags | COPYFILE_PACK)) { 381 archive_set_error(&a->archive, errno, 382 "Could not pack extended attributes"); 383 ret = ARCHIVE_WARN; 384 goto cleanup; 385 } 386 if (fstat(tempfd, ©file_stat)) { 387 archive_set_error(&a->archive, errno, 388 "Could not check size of extended attributes"); 389 ret = ARCHIVE_WARN; 390 goto cleanup; 391 } 392 buff = malloc(copyfile_stat.st_size); 393 if (buff == NULL) { 394 archive_set_error(&a->archive, errno, 395 "Could not allocate memory for extended attributes"); 396 ret = ARCHIVE_WARN; 397 goto cleanup; 398 } 399 if (copyfile_stat.st_size != read(tempfd, buff, copyfile_stat.st_size)) { 400 archive_set_error(&a->archive, errno, 401 "Could not read extended attributes into memory"); 402 ret = ARCHIVE_WARN; 403 goto cleanup; 404 } 405 archive_entry_copy_mac_metadata(entry, buff, copyfile_stat.st_size); 406 407 cleanup: 408 if (tempfd >= 0) { 409 close(tempfd); 410 unlink(tempfile.s); 411 } 412 archive_string_free(&tempfile); 413 free(buff); 414 return (ret); 415 } 416 417 #else 418 419 /* 420 * Stub implementation for non-Mac systems. 421 */ 422 static int 423 setup_mac_metadata(struct archive_read_disk *a, 424 struct archive_entry *entry, int *fd) 425 { 426 (void)a; /* UNUSED */ 427 (void)entry; /* UNUSED */ 428 (void)fd; /* UNUSED */ 429 return (ARCHIVE_OK); 430 } 431 #endif 432 433 #if ARCHIVE_XATTR_LINUX || ARCHIVE_XATTR_DARWIN || ARCHIVE_XATTR_AIX 434 435 /* 436 * Linux, Darwin and AIX extended attribute support. 437 * 438 * TODO: By using a stack-allocated buffer for the first 439 * call to getxattr(), we might be able to avoid the second 440 * call entirely. We only need the second call if the 441 * stack-allocated buffer is too small. But a modest buffer 442 * of 1024 bytes or so will often be big enough. Same applies 443 * to listxattr(). 444 */ 445 446 447 static int 448 setup_xattr(struct archive_read_disk *a, 449 struct archive_entry *entry, const char *name, int fd, const char *accpath) 450 { 451 ssize_t size; 452 void *value = NULL; 453 454 455 if (fd >= 0) { 456 #if ARCHIVE_XATTR_LINUX 457 size = fgetxattr(fd, name, NULL, 0); 458 #elif ARCHIVE_XATTR_DARWIN 459 size = fgetxattr(fd, name, NULL, 0, 0, 0); 460 #elif ARCHIVE_XATTR_AIX 461 size = fgetea(fd, name, NULL, 0); 462 #endif 463 } else if (!a->follow_symlinks) { 464 #if ARCHIVE_XATTR_LINUX 465 size = lgetxattr(accpath, name, NULL, 0); 466 #elif ARCHIVE_XATTR_DARWIN 467 size = getxattr(accpath, name, NULL, 0, 0, XATTR_NOFOLLOW); 468 #elif ARCHIVE_XATTR_AIX 469 size = lgetea(accpath, name, NULL, 0); 470 #endif 471 } else { 472 #if ARCHIVE_XATTR_LINUX 473 size = getxattr(accpath, name, NULL, 0); 474 #elif ARCHIVE_XATTR_DARWIN 475 size = getxattr(accpath, name, NULL, 0, 0, 0); 476 #elif ARCHIVE_XATTR_AIX 477 size = getea(accpath, name, NULL, 0); 478 #endif 479 } 480 481 if (size == -1) { 482 archive_set_error(&a->archive, errno, 483 "Couldn't query extended attribute"); 484 return (ARCHIVE_WARN); 485 } 486 487 if (size > 0 && (value = malloc(size)) == NULL) { 488 archive_set_error(&a->archive, errno, "Out of memory"); 489 return (ARCHIVE_FATAL); 490 } 491 492 493 if (fd >= 0) { 494 #if ARCHIVE_XATTR_LINUX 495 size = fgetxattr(fd, name, value, size); 496 #elif ARCHIVE_XATTR_DARWIN 497 size = fgetxattr(fd, name, value, size, 0, 0); 498 #elif ARCHIVE_XATTR_AIX 499 size = fgetea(fd, name, value, size); 500 #endif 501 } else if (!a->follow_symlinks) { 502 #if ARCHIVE_XATTR_LINUX 503 size = lgetxattr(accpath, name, value, size); 504 #elif ARCHIVE_XATTR_DARWIN 505 size = getxattr(accpath, name, value, size, 0, XATTR_NOFOLLOW); 506 #elif ARCHIVE_XATTR_AIX 507 size = lgetea(accpath, name, value, size); 508 #endif 509 } else { 510 #if ARCHIVE_XATTR_LINUX 511 size = getxattr(accpath, name, value, size); 512 #elif ARCHIVE_XATTR_DARWIN 513 size = getxattr(accpath, name, value, size, 0, 0); 514 #elif ARCHIVE_XATTR_AIX 515 size = getea(accpath, name, value, size); 516 #endif 517 } 518 519 if (size == -1) { 520 archive_set_error(&a->archive, errno, 521 "Couldn't read extended attribute"); 522 return (ARCHIVE_WARN); 523 } 524 525 archive_entry_xattr_add_entry(entry, name, value, size); 526 527 free(value); 528 return (ARCHIVE_OK); 529 } 530 531 static int 532 setup_xattrs(struct archive_read_disk *a, 533 struct archive_entry *entry, int *fd) 534 { 535 char *list, *p; 536 const char *path; 537 ssize_t list_size; 538 539 path = NULL; 540 541 if (*fd < 0) { 542 path = archive_read_disk_entry_setup_path(a, entry, fd); 543 if (path == NULL) 544 return (ARCHIVE_WARN); 545 } 546 547 if (*fd >= 0) { 548 #if ARCHIVE_XATTR_LINUX 549 list_size = flistxattr(*fd, NULL, 0); 550 #elif ARCHIVE_XATTR_DARWIN 551 list_size = flistxattr(*fd, NULL, 0, 0); 552 #elif ARCHIVE_XATTR_AIX 553 list_size = flistea(*fd, NULL, 0); 554 #endif 555 } else if (!a->follow_symlinks) { 556 #if ARCHIVE_XATTR_LINUX 557 list_size = llistxattr(path, NULL, 0); 558 #elif ARCHIVE_XATTR_DARWIN 559 list_size = listxattr(path, NULL, 0, XATTR_NOFOLLOW); 560 #elif ARCHIVE_XATTR_AIX 561 list_size = llistea(path, NULL, 0); 562 #endif 563 } else { 564 #if ARCHIVE_XATTR_LINUX 565 list_size = listxattr(path, NULL, 0); 566 #elif ARCHIVE_XATTR_DARWIN 567 list_size = listxattr(path, NULL, 0, 0); 568 #elif ARCHIVE_XATTR_AIX 569 list_size = listea(path, NULL, 0); 570 #endif 571 } 572 573 if (list_size == -1) { 574 if (errno == ENOTSUP || errno == ENOSYS) 575 return (ARCHIVE_OK); 576 archive_set_error(&a->archive, errno, 577 "Couldn't list extended attributes"); 578 return (ARCHIVE_WARN); 579 } 580 581 if (list_size == 0) 582 return (ARCHIVE_OK); 583 584 if ((list = malloc(list_size)) == NULL) { 585 archive_set_error(&a->archive, errno, "Out of memory"); 586 return (ARCHIVE_FATAL); 587 } 588 589 if (*fd >= 0) { 590 #if ARCHIVE_XATTR_LINUX 591 list_size = flistxattr(*fd, list, list_size); 592 #elif ARCHIVE_XATTR_DARWIN 593 list_size = flistxattr(*fd, list, list_size, 0); 594 #elif ARCHIVE_XATTR_AIX 595 list_size = flistea(*fd, list, list_size); 596 #endif 597 } else if (!a->follow_symlinks) { 598 #if ARCHIVE_XATTR_LINUX 599 list_size = llistxattr(path, list, list_size); 600 #elif ARCHIVE_XATTR_DARWIN 601 list_size = listxattr(path, list, list_size, XATTR_NOFOLLOW); 602 #elif ARCHIVE_XATTR_AIX 603 list_size = llistea(path, list, list_size); 604 #endif 605 } else { 606 #if ARCHIVE_XATTR_LINUX 607 list_size = listxattr(path, list, list_size); 608 #elif ARCHIVE_XATTR_DARWIN 609 list_size = listxattr(path, list, list_size, 0); 610 #elif ARCHIVE_XATTR_AIX 611 list_size = listea(path, list, list_size); 612 #endif 613 } 614 615 if (list_size == -1) { 616 archive_set_error(&a->archive, errno, 617 "Couldn't retrieve extended attributes"); 618 free(list); 619 return (ARCHIVE_WARN); 620 } 621 622 for (p = list; (p - list) < list_size; p += strlen(p) + 1) { 623 #if ARCHIVE_XATTR_LINUX 624 /* Linux: skip POSIX.1e ACL extended attributes */ 625 if (strncmp(p, "system.", 7) == 0 && 626 (strcmp(p + 7, "posix_acl_access") == 0 || 627 strcmp(p + 7, "posix_acl_default") == 0)) 628 continue; 629 if (strncmp(p, "trusted.SGI_", 12) == 0 && 630 (strcmp(p + 12, "ACL_DEFAULT") == 0 || 631 strcmp(p + 12, "ACL_FILE") == 0)) 632 continue; 633 634 /* Linux: xfsroot namespace is obsolete and unsupported */ 635 if (strncmp(p, "xfsroot.", 8) == 0) 636 continue; 637 #endif 638 setup_xattr(a, entry, p, *fd, path); 639 } 640 641 free(list); 642 return (ARCHIVE_OK); 643 } 644 645 #elif ARCHIVE_XATTR_FREEBSD 646 647 /* 648 * FreeBSD extattr interface. 649 */ 650 651 /* TODO: Implement this. Follow the Linux model above, but 652 * with FreeBSD-specific system calls, of course. Be careful 653 * to not include the system extattrs that hold ACLs; we handle 654 * those separately. 655 */ 656 static int 657 setup_xattr(struct archive_read_disk *a, struct archive_entry *entry, 658 int namespace, const char *name, const char *fullname, int fd, 659 const char *path); 660 661 static int 662 setup_xattr(struct archive_read_disk *a, struct archive_entry *entry, 663 int namespace, const char *name, const char *fullname, int fd, 664 const char *accpath) 665 { 666 ssize_t size; 667 void *value = NULL; 668 669 if (fd >= 0) 670 size = extattr_get_fd(fd, namespace, name, NULL, 0); 671 else if (!a->follow_symlinks) 672 size = extattr_get_link(accpath, namespace, name, NULL, 0); 673 else 674 size = extattr_get_file(accpath, namespace, name, NULL, 0); 675 676 if (size == -1) { 677 archive_set_error(&a->archive, errno, 678 "Couldn't query extended attribute"); 679 return (ARCHIVE_WARN); 680 } 681 682 if (size > 0 && (value = malloc(size)) == NULL) { 683 archive_set_error(&a->archive, errno, "Out of memory"); 684 return (ARCHIVE_FATAL); 685 } 686 687 if (fd >= 0) 688 size = extattr_get_fd(fd, namespace, name, value, size); 689 else if (!a->follow_symlinks) 690 size = extattr_get_link(accpath, namespace, name, value, size); 691 else 692 size = extattr_get_file(accpath, namespace, name, value, size); 693 694 if (size == -1) { 695 free(value); 696 archive_set_error(&a->archive, errno, 697 "Couldn't read extended attribute"); 698 return (ARCHIVE_WARN); 699 } 700 701 archive_entry_xattr_add_entry(entry, fullname, value, size); 702 703 free(value); 704 return (ARCHIVE_OK); 705 } 706 707 static int 708 setup_xattrs_namespace(struct archive_read_disk *a, 709 struct archive_entry *entry, int *fd, int namespace) 710 { 711 char buff[512]; 712 char *list, *p; 713 ssize_t list_size; 714 const char *path; 715 716 path = NULL; 717 718 if (*fd < 0) { 719 path = archive_read_disk_entry_setup_path(a, entry, fd); 720 if (path == NULL) 721 return (ARCHIVE_WARN); 722 } 723 724 if (*fd >= 0) 725 list_size = extattr_list_fd(*fd, namespace, NULL, 0); 726 else if (!a->follow_symlinks) 727 list_size = extattr_list_link(path, namespace, NULL, 0); 728 else 729 list_size = extattr_list_file(path, namespace, NULL, 0); 730 731 if (list_size == -1 && errno == EOPNOTSUPP) 732 return (ARCHIVE_OK); 733 if (list_size == -1 && errno == EPERM) 734 return (ARCHIVE_OK); 735 if (list_size == -1) { 736 archive_set_error(&a->archive, errno, 737 "Couldn't list extended attributes"); 738 return (ARCHIVE_WARN); 739 } 740 741 if (list_size == 0) 742 return (ARCHIVE_OK); 743 744 if ((list = malloc(list_size)) == NULL) { 745 archive_set_error(&a->archive, errno, "Out of memory"); 746 return (ARCHIVE_FATAL); 747 } 748 749 if (*fd >= 0) 750 list_size = extattr_list_fd(*fd, namespace, list, list_size); 751 else if (!a->follow_symlinks) 752 list_size = extattr_list_link(path, namespace, list, list_size); 753 else 754 list_size = extattr_list_file(path, namespace, list, list_size); 755 756 if (list_size == -1) { 757 archive_set_error(&a->archive, errno, 758 "Couldn't retrieve extended attributes"); 759 free(list); 760 return (ARCHIVE_WARN); 761 } 762 763 p = list; 764 while ((p - list) < list_size) { 765 size_t len = 255 & (int)*p; 766 char *name; 767 768 if (namespace == EXTATTR_NAMESPACE_SYSTEM) { 769 if (!strcmp(p + 1, "nfs4.acl") || 770 !strcmp(p + 1, "posix1e.acl_access") || 771 !strcmp(p + 1, "posix1e.acl_default")) { 772 p += 1 + len; 773 continue; 774 } 775 strcpy(buff, "system."); 776 } else { 777 strcpy(buff, "user."); 778 } 779 name = buff + strlen(buff); 780 memcpy(name, p + 1, len); 781 name[len] = '\0'; 782 setup_xattr(a, entry, namespace, name, buff, *fd, path); 783 p += 1 + len; 784 } 785 786 free(list); 787 return (ARCHIVE_OK); 788 } 789 790 static int 791 setup_xattrs(struct archive_read_disk *a, 792 struct archive_entry *entry, int *fd) 793 { 794 int namespaces[2]; 795 int i, res; 796 797 namespaces[0] = EXTATTR_NAMESPACE_USER; 798 namespaces[1] = EXTATTR_NAMESPACE_SYSTEM; 799 800 for (i = 0; i < 2; i++) { 801 res = setup_xattrs_namespace(a, entry, fd, 802 namespaces[i]); 803 switch (res) { 804 case (ARCHIVE_OK): 805 case (ARCHIVE_WARN): 806 break; 807 default: 808 return (res); 809 } 810 } 811 812 return (ARCHIVE_OK); 813 } 814 815 #else 816 817 /* 818 * Generic (stub) extended attribute support. 819 */ 820 static int 821 setup_xattrs(struct archive_read_disk *a, 822 struct archive_entry *entry, int *fd) 823 { 824 (void)a; /* UNUSED */ 825 (void)entry; /* UNUSED */ 826 (void)fd; /* UNUSED */ 827 return (ARCHIVE_OK); 828 } 829 830 #endif 831 832 #if defined(HAVE_LINUX_FIEMAP_H) 833 834 /* 835 * Linux FIEMAP sparse interface. 836 * 837 * The FIEMAP ioctl returns an "extent" for each physical allocation 838 * on disk. We need to process those to generate a more compact list 839 * of logical file blocks. We also need to be very careful to use 840 * FIEMAP_FLAG_SYNC here, since there are reports that Linux sometimes 841 * does not report allocations for newly-written data that hasn't 842 * been synced to disk. 843 * 844 * It's important to return a minimal sparse file list because we want 845 * to not trigger sparse file extensions if we don't have to, since 846 * not all readers support them. 847 */ 848 849 static int 850 setup_sparse_fiemap(struct archive_read_disk *a, 851 struct archive_entry *entry, int *fd) 852 { 853 char buff[4096]; 854 struct fiemap *fm; 855 struct fiemap_extent *fe; 856 int64_t size; 857 int count, do_fiemap, iters; 858 int exit_sts = ARCHIVE_OK; 859 const char *path; 860 861 if (archive_entry_filetype(entry) != AE_IFREG 862 || archive_entry_size(entry) <= 0 863 || archive_entry_hardlink(entry) != NULL) 864 return (ARCHIVE_OK); 865 866 if (*fd < 0) { 867 path = archive_read_disk_entry_setup_path(a, entry, NULL); 868 if (path == NULL) 869 return (ARCHIVE_FAILED); 870 871 if (a->tree != NULL) 872 *fd = a->open_on_current_dir(a->tree, path, 873 O_RDONLY | O_NONBLOCK | O_CLOEXEC); 874 else 875 *fd = open(path, O_RDONLY | O_NONBLOCK | O_CLOEXEC); 876 if (*fd < 0) { 877 archive_set_error(&a->archive, errno, 878 "Can't open `%s'", path); 879 return (ARCHIVE_FAILED); 880 } 881 __archive_ensure_cloexec_flag(*fd); 882 } 883 884 /* Initialize buffer to avoid the error valgrind complains about. */ 885 memset(buff, 0, sizeof(buff)); 886 count = (sizeof(buff) - sizeof(*fm))/sizeof(*fe); 887 fm = (struct fiemap *)buff; 888 fm->fm_start = 0; 889 fm->fm_length = ~0ULL;; 890 fm->fm_flags = FIEMAP_FLAG_SYNC; 891 fm->fm_extent_count = count; 892 do_fiemap = 1; 893 size = archive_entry_size(entry); 894 for (iters = 0; ; ++iters) { 895 int i, r; 896 897 r = ioctl(*fd, FS_IOC_FIEMAP, fm); 898 if (r < 0) { 899 /* When something error happens, it is better we 900 * should return ARCHIVE_OK because an earlier 901 * version(<2.6.28) cannot perform FS_IOC_FIEMAP. */ 902 goto exit_setup_sparse_fiemap; 903 } 904 if (fm->fm_mapped_extents == 0) { 905 if (iters == 0) { 906 /* Fully sparse file; insert a zero-length "data" entry */ 907 archive_entry_sparse_add_entry(entry, 0, 0); 908 } 909 break; 910 } 911 fe = fm->fm_extents; 912 for (i = 0; i < (int)fm->fm_mapped_extents; i++, fe++) { 913 if (!(fe->fe_flags & FIEMAP_EXTENT_UNWRITTEN)) { 914 /* The fe_length of the last block does not 915 * adjust itself to its size files. */ 916 int64_t length = fe->fe_length; 917 if (fe->fe_logical + length > (uint64_t)size) 918 length -= fe->fe_logical + length - size; 919 if (fe->fe_logical == 0 && length == size) { 920 /* This is not sparse. */ 921 do_fiemap = 0; 922 break; 923 } 924 if (length > 0) 925 archive_entry_sparse_add_entry(entry, 926 fe->fe_logical, length); 927 } 928 if (fe->fe_flags & FIEMAP_EXTENT_LAST) 929 do_fiemap = 0; 930 } 931 if (do_fiemap) { 932 fe = fm->fm_extents + fm->fm_mapped_extents -1; 933 fm->fm_start = fe->fe_logical + fe->fe_length; 934 } else 935 break; 936 } 937 exit_setup_sparse_fiemap: 938 return (exit_sts); 939 } 940 941 #if !defined(SEEK_HOLE) || !defined(SEEK_DATA) 942 static int 943 setup_sparse(struct archive_read_disk *a, 944 struct archive_entry *entry, int *fd) 945 { 946 return setup_sparse_fiemap(a, entry, fd); 947 } 948 #endif 949 #endif /* defined(HAVE_LINUX_FIEMAP_H) */ 950 951 #if defined(SEEK_HOLE) && defined(SEEK_DATA) 952 953 /* 954 * SEEK_HOLE sparse interface (FreeBSD, Linux, Solaris) 955 */ 956 957 static int 958 setup_sparse(struct archive_read_disk *a, 959 struct archive_entry *entry, int *fd) 960 { 961 int64_t size; 962 off_t initial_off; 963 off_t off_s, off_e; 964 int exit_sts = ARCHIVE_OK; 965 int check_fully_sparse = 0; 966 const char *path; 967 968 if (archive_entry_filetype(entry) != AE_IFREG 969 || archive_entry_size(entry) <= 0 970 || archive_entry_hardlink(entry) != NULL) 971 return (ARCHIVE_OK); 972 973 /* Does filesystem support the reporting of hole ? */ 974 if (*fd < 0) 975 path = archive_read_disk_entry_setup_path(a, entry, fd); 976 else 977 path = NULL; 978 979 if (*fd >= 0) { 980 #ifdef _PC_MIN_HOLE_SIZE 981 if (fpathconf(*fd, _PC_MIN_HOLE_SIZE) <= 0) 982 return (ARCHIVE_OK); 983 #endif 984 initial_off = lseek(*fd, 0, SEEK_CUR); 985 if (initial_off != 0) 986 lseek(*fd, 0, SEEK_SET); 987 } else { 988 if (path == NULL) 989 return (ARCHIVE_FAILED); 990 #ifdef _PC_MIN_HOLE_SIZE 991 if (pathconf(path, _PC_MIN_HOLE_SIZE) <= 0) 992 return (ARCHIVE_OK); 993 #endif 994 *fd = open(path, O_RDONLY | O_NONBLOCK | O_CLOEXEC); 995 if (*fd < 0) { 996 archive_set_error(&a->archive, errno, 997 "Can't open `%s'", path); 998 return (ARCHIVE_FAILED); 999 } 1000 __archive_ensure_cloexec_flag(*fd); 1001 initial_off = 0; 1002 } 1003 1004 #ifndef _PC_MIN_HOLE_SIZE 1005 /* Check if the underlying filesystem supports seek hole */ 1006 off_s = lseek(*fd, 0, SEEK_HOLE); 1007 if (off_s < 0) 1008 #if defined(HAVE_LINUX_FIEMAP_H) 1009 return setup_sparse_fiemap(a, entry, fd); 1010 #else 1011 goto exit_setup_sparse; 1012 #endif 1013 else if (off_s > 0) 1014 lseek(*fd, 0, SEEK_SET); 1015 #endif 1016 1017 off_s = 0; 1018 size = archive_entry_size(entry); 1019 while (off_s < size) { 1020 off_s = lseek(*fd, off_s, SEEK_DATA); 1021 if (off_s == (off_t)-1) { 1022 if (errno == ENXIO) { 1023 /* no more hole */ 1024 if (archive_entry_sparse_count(entry) == 0) { 1025 /* Potentially a fully-sparse file. */ 1026 check_fully_sparse = 1; 1027 } 1028 break; 1029 } 1030 archive_set_error(&a->archive, errno, 1031 "lseek(SEEK_HOLE) failed"); 1032 exit_sts = ARCHIVE_FAILED; 1033 goto exit_setup_sparse; 1034 } 1035 off_e = lseek(*fd, off_s, SEEK_HOLE); 1036 if (off_e == (off_t)-1) { 1037 if (errno == ENXIO) { 1038 off_e = lseek(*fd, 0, SEEK_END); 1039 if (off_e != (off_t)-1) 1040 break;/* no more data */ 1041 } 1042 archive_set_error(&a->archive, errno, 1043 "lseek(SEEK_DATA) failed"); 1044 exit_sts = ARCHIVE_FAILED; 1045 goto exit_setup_sparse; 1046 } 1047 if (off_s == 0 && off_e == size) 1048 break;/* This is not sparse. */ 1049 archive_entry_sparse_add_entry(entry, off_s, 1050 off_e - off_s); 1051 off_s = off_e; 1052 } 1053 1054 if (check_fully_sparse) { 1055 if (lseek(*fd, 0, SEEK_HOLE) == 0 && 1056 lseek(*fd, 0, SEEK_END) == size) { 1057 /* Fully sparse file; insert a zero-length "data" entry */ 1058 archive_entry_sparse_add_entry(entry, 0, 0); 1059 } 1060 } 1061 exit_setup_sparse: 1062 lseek(*fd, initial_off, SEEK_SET); 1063 return (exit_sts); 1064 } 1065 1066 #elif !defined(HAVE_LINUX_FIEMAP_H) 1067 1068 /* 1069 * Generic (stub) sparse support. 1070 */ 1071 static int 1072 setup_sparse(struct archive_read_disk *a, 1073 struct archive_entry *entry, int *fd) 1074 { 1075 (void)a; /* UNUSED */ 1076 (void)entry; /* UNUSED */ 1077 (void)fd; /* UNUSED */ 1078 return (ARCHIVE_OK); 1079 } 1080 1081 #endif 1082 1083 #endif /* !defined(_WIN32) || defined(__CYGWIN__) */ 1084 1085