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