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