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