archive_entry.c revision 337352
1/*- 2 * Copyright (c) 2003-2007 Tim Kientzle 3 * Copyright (c) 2016 Martin Matuska 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR 16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, 19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 */ 26 27#include "archive_platform.h" 28__FBSDID("$FreeBSD: stable/10/contrib/libarchive/libarchive/archive_entry.c 337352 2018-08-05 14:36:12Z mm $"); 29 30#ifdef HAVE_SYS_STAT_H 31#include <sys/stat.h> 32#endif 33#ifdef HAVE_SYS_TYPES_H 34#include <sys/types.h> 35#endif 36#if MAJOR_IN_MKDEV 37#include <sys/mkdev.h> 38#define HAVE_MAJOR 39#elif MAJOR_IN_SYSMACROS 40#include <sys/sysmacros.h> 41#define HAVE_MAJOR 42#endif 43#ifdef HAVE_ERRNO_H 44#include <errno.h> 45#endif 46#ifdef HAVE_LIMITS_H 47#include <limits.h> 48#endif 49#ifdef HAVE_LINUX_FS_H 50#include <linux/fs.h> /* for Linux file flags */ 51#endif 52/* 53 * Some Linux distributions have both linux/ext2_fs.h and ext2fs/ext2_fs.h. 54 * As the include guards don't agree, the order of include is important. 55 */ 56#ifdef HAVE_LINUX_EXT2_FS_H 57#include <linux/ext2_fs.h> /* for Linux file flags */ 58#endif 59#if defined(HAVE_EXT2FS_EXT2_FS_H) && !defined(__CYGWIN__) 60#include <ext2fs/ext2_fs.h> /* for Linux file flags */ 61#endif 62#include <stddef.h> 63#include <stdio.h> 64#ifdef HAVE_STDLIB_H 65#include <stdlib.h> 66#endif 67#ifdef HAVE_STRING_H 68#include <string.h> 69#endif 70#ifdef HAVE_WCHAR_H 71#include <wchar.h> 72#endif 73 74#include "archive.h" 75#include "archive_acl_private.h" 76#include "archive_entry.h" 77#include "archive_entry_locale.h" 78#include "archive_private.h" 79#include "archive_entry_private.h" 80 81#if !defined(HAVE_MAJOR) && !defined(major) 82/* Replacement for major/minor/makedev. */ 83#define major(x) ((int)(0x00ff & ((x) >> 8))) 84#define minor(x) ((int)(0xffff00ff & (x))) 85#define makedev(maj,min) ((0xff00 & ((maj)<<8)) | (0xffff00ff & (min))) 86#endif 87 88/* Play games to come up with a suitable makedev() definition. */ 89#ifdef __QNXNTO__ 90/* QNX. <sigh> */ 91#include <sys/netmgr.h> 92#define ae_makedev(maj, min) makedev(ND_LOCAL_NODE, (maj), (min)) 93#elif defined makedev 94/* There's a "makedev" macro. */ 95#define ae_makedev(maj, min) makedev((maj), (min)) 96#elif defined mkdev || ((defined _WIN32 || defined __WIN32__) && !defined(__CYGWIN__)) 97/* Windows. <sigh> */ 98#define ae_makedev(maj, min) mkdev((maj), (min)) 99#else 100/* There's a "makedev" function. */ 101#define ae_makedev(maj, min) makedev((maj), (min)) 102#endif 103 104/* 105 * This adjustment is needed to support the following idiom for adding 106 * 1000ns to the stored time: 107 * archive_entry_set_atime(archive_entry_atime(), 108 * archive_entry_atime_nsec() + 1000) 109 * The additional if() here compensates for ambiguity in the C standard, 110 * which permits two possible interpretations of a % b when a is negative. 111 */ 112#define FIX_NS(t,ns) \ 113 do { \ 114 t += ns / 1000000000; \ 115 ns %= 1000000000; \ 116 if (ns < 0) { --t; ns += 1000000000; } \ 117 } while (0) 118 119static char * ae_fflagstostr(unsigned long bitset, unsigned long bitclear); 120static const wchar_t *ae_wcstofflags(const wchar_t *stringp, 121 unsigned long *setp, unsigned long *clrp); 122static const char *ae_strtofflags(const char *stringp, 123 unsigned long *setp, unsigned long *clrp); 124 125#ifndef HAVE_WCSCPY 126static wchar_t * wcscpy(wchar_t *s1, const wchar_t *s2) 127{ 128 wchar_t *dest = s1; 129 while ((*s1 = *s2) != L'\0') 130 ++s1, ++s2; 131 return dest; 132} 133#endif 134#ifndef HAVE_WCSLEN 135static size_t wcslen(const wchar_t *s) 136{ 137 const wchar_t *p = s; 138 while (*p != L'\0') 139 ++p; 140 return p - s; 141} 142#endif 143#ifndef HAVE_WMEMCMP 144/* Good enough for simple equality testing, but not for sorting. */ 145#define wmemcmp(a,b,i) memcmp((a), (b), (i) * sizeof(wchar_t)) 146#endif 147 148/**************************************************************************** 149 * 150 * Public Interface 151 * 152 ****************************************************************************/ 153 154struct archive_entry * 155archive_entry_clear(struct archive_entry *entry) 156{ 157 if (entry == NULL) 158 return (NULL); 159 archive_mstring_clean(&entry->ae_fflags_text); 160 archive_mstring_clean(&entry->ae_gname); 161 archive_mstring_clean(&entry->ae_hardlink); 162 archive_mstring_clean(&entry->ae_pathname); 163 archive_mstring_clean(&entry->ae_sourcepath); 164 archive_mstring_clean(&entry->ae_symlink); 165 archive_mstring_clean(&entry->ae_uname); 166 archive_entry_copy_mac_metadata(entry, NULL, 0); 167 archive_acl_clear(&entry->acl); 168 archive_entry_xattr_clear(entry); 169 archive_entry_sparse_clear(entry); 170 free(entry->stat); 171 memset(entry, 0, sizeof(*entry)); 172 return entry; 173} 174 175struct archive_entry * 176archive_entry_clone(struct archive_entry *entry) 177{ 178 struct archive_entry *entry2; 179 struct ae_xattr *xp; 180 struct ae_sparse *sp; 181 size_t s; 182 const void *p; 183 184 /* Allocate new structure and copy over all of the fields. */ 185 /* TODO: Should we copy the archive over? Or require a new archive 186 * as an argument? */ 187 entry2 = archive_entry_new2(entry->archive); 188 if (entry2 == NULL) 189 return (NULL); 190 entry2->ae_stat = entry->ae_stat; 191 entry2->ae_fflags_set = entry->ae_fflags_set; 192 entry2->ae_fflags_clear = entry->ae_fflags_clear; 193 194 /* TODO: XXX If clone can have a different archive, what do we do here if 195 * character sets are different? XXX */ 196 archive_mstring_copy(&entry2->ae_fflags_text, &entry->ae_fflags_text); 197 archive_mstring_copy(&entry2->ae_gname, &entry->ae_gname); 198 archive_mstring_copy(&entry2->ae_hardlink, &entry->ae_hardlink); 199 archive_mstring_copy(&entry2->ae_pathname, &entry->ae_pathname); 200 archive_mstring_copy(&entry2->ae_sourcepath, &entry->ae_sourcepath); 201 archive_mstring_copy(&entry2->ae_symlink, &entry->ae_symlink); 202 entry2->ae_set = entry->ae_set; 203 archive_mstring_copy(&entry2->ae_uname, &entry->ae_uname); 204 205 /* Copy encryption status */ 206 entry2->encryption = entry->encryption; 207 208 /* Copy ACL data over. */ 209 archive_acl_copy(&entry2->acl, &entry->acl); 210 211 /* Copy Mac OS metadata. */ 212 p = archive_entry_mac_metadata(entry, &s); 213 archive_entry_copy_mac_metadata(entry2, p, s); 214 215 /* Copy xattr data over. */ 216 xp = entry->xattr_head; 217 while (xp != NULL) { 218 archive_entry_xattr_add_entry(entry2, 219 xp->name, xp->value, xp->size); 220 xp = xp->next; 221 } 222 223 /* Copy sparse data over. */ 224 sp = entry->sparse_head; 225 while (sp != NULL) { 226 archive_entry_sparse_add_entry(entry2, 227 sp->offset, sp->length); 228 sp = sp->next; 229 } 230 231 return (entry2); 232} 233 234void 235archive_entry_free(struct archive_entry *entry) 236{ 237 archive_entry_clear(entry); 238 free(entry); 239} 240 241struct archive_entry * 242archive_entry_new(void) 243{ 244 return archive_entry_new2(NULL); 245} 246 247struct archive_entry * 248archive_entry_new2(struct archive *a) 249{ 250 struct archive_entry *entry; 251 252 entry = (struct archive_entry *)calloc(1, sizeof(*entry)); 253 if (entry == NULL) 254 return (NULL); 255 entry->archive = a; 256 return (entry); 257} 258 259/* 260 * Functions for reading fields from an archive_entry. 261 */ 262 263time_t 264archive_entry_atime(struct archive_entry *entry) 265{ 266 return (entry->ae_stat.aest_atime); 267} 268 269long 270archive_entry_atime_nsec(struct archive_entry *entry) 271{ 272 return (entry->ae_stat.aest_atime_nsec); 273} 274 275int 276archive_entry_atime_is_set(struct archive_entry *entry) 277{ 278 return (entry->ae_set & AE_SET_ATIME); 279} 280 281time_t 282archive_entry_birthtime(struct archive_entry *entry) 283{ 284 return (entry->ae_stat.aest_birthtime); 285} 286 287long 288archive_entry_birthtime_nsec(struct archive_entry *entry) 289{ 290 return (entry->ae_stat.aest_birthtime_nsec); 291} 292 293int 294archive_entry_birthtime_is_set(struct archive_entry *entry) 295{ 296 return (entry->ae_set & AE_SET_BIRTHTIME); 297} 298 299time_t 300archive_entry_ctime(struct archive_entry *entry) 301{ 302 return (entry->ae_stat.aest_ctime); 303} 304 305int 306archive_entry_ctime_is_set(struct archive_entry *entry) 307{ 308 return (entry->ae_set & AE_SET_CTIME); 309} 310 311long 312archive_entry_ctime_nsec(struct archive_entry *entry) 313{ 314 return (entry->ae_stat.aest_ctime_nsec); 315} 316 317dev_t 318archive_entry_dev(struct archive_entry *entry) 319{ 320 if (entry->ae_stat.aest_dev_is_broken_down) 321 return ae_makedev(entry->ae_stat.aest_devmajor, 322 entry->ae_stat.aest_devminor); 323 else 324 return (entry->ae_stat.aest_dev); 325} 326 327int 328archive_entry_dev_is_set(struct archive_entry *entry) 329{ 330 return (entry->ae_set & AE_SET_DEV); 331} 332 333dev_t 334archive_entry_devmajor(struct archive_entry *entry) 335{ 336 if (entry->ae_stat.aest_dev_is_broken_down) 337 return (entry->ae_stat.aest_devmajor); 338 else 339 return major(entry->ae_stat.aest_dev); 340} 341 342dev_t 343archive_entry_devminor(struct archive_entry *entry) 344{ 345 if (entry->ae_stat.aest_dev_is_broken_down) 346 return (entry->ae_stat.aest_devminor); 347 else 348 return minor(entry->ae_stat.aest_dev); 349} 350 351mode_t 352archive_entry_filetype(struct archive_entry *entry) 353{ 354 return (AE_IFMT & entry->acl.mode); 355} 356 357void 358archive_entry_fflags(struct archive_entry *entry, 359 unsigned long *set, unsigned long *clear) 360{ 361 *set = entry->ae_fflags_set; 362 *clear = entry->ae_fflags_clear; 363} 364 365/* 366 * Note: if text was provided, this just returns that text. If you 367 * really need the text to be rebuilt in a canonical form, set the 368 * text, ask for the bitmaps, then set the bitmaps. (Setting the 369 * bitmaps clears any stored text.) This design is deliberate: if 370 * we're editing archives, we don't want to discard flags just because 371 * they aren't supported on the current system. The bitmap<->text 372 * conversions are platform-specific (see below). 373 */ 374const char * 375archive_entry_fflags_text(struct archive_entry *entry) 376{ 377 const char *f; 378 char *p; 379 380 if (archive_mstring_get_mbs(entry->archive, 381 &entry->ae_fflags_text, &f) == 0) { 382 if (f != NULL) 383 return (f); 384 } else if (errno == ENOMEM) 385 __archive_errx(1, "No memory"); 386 387 if (entry->ae_fflags_set == 0 && entry->ae_fflags_clear == 0) 388 return (NULL); 389 390 p = ae_fflagstostr(entry->ae_fflags_set, entry->ae_fflags_clear); 391 if (p == NULL) 392 return (NULL); 393 394 archive_mstring_copy_mbs(&entry->ae_fflags_text, p); 395 free(p); 396 if (archive_mstring_get_mbs(entry->archive, 397 &entry->ae_fflags_text, &f) == 0) 398 return (f); 399 if (errno == ENOMEM) 400 __archive_errx(1, "No memory"); 401 return (NULL); 402} 403 404la_int64_t 405archive_entry_gid(struct archive_entry *entry) 406{ 407 return (entry->ae_stat.aest_gid); 408} 409 410const char * 411archive_entry_gname(struct archive_entry *entry) 412{ 413 const char *p; 414 if (archive_mstring_get_mbs(entry->archive, &entry->ae_gname, &p) == 0) 415 return (p); 416 if (errno == ENOMEM) 417 __archive_errx(1, "No memory"); 418 return (NULL); 419} 420 421const char * 422archive_entry_gname_utf8(struct archive_entry *entry) 423{ 424 const char *p; 425 if (archive_mstring_get_utf8(entry->archive, &entry->ae_gname, &p) == 0) 426 return (p); 427 if (errno == ENOMEM) 428 __archive_errx(1, "No memory"); 429 return (NULL); 430} 431 432 433const wchar_t * 434archive_entry_gname_w(struct archive_entry *entry) 435{ 436 const wchar_t *p; 437 if (archive_mstring_get_wcs(entry->archive, &entry->ae_gname, &p) == 0) 438 return (p); 439 if (errno == ENOMEM) 440 __archive_errx(1, "No memory"); 441 return (NULL); 442} 443 444int 445_archive_entry_gname_l(struct archive_entry *entry, 446 const char **p, size_t *len, struct archive_string_conv *sc) 447{ 448 return (archive_mstring_get_mbs_l(&entry->ae_gname, p, len, sc)); 449} 450 451const char * 452archive_entry_hardlink(struct archive_entry *entry) 453{ 454 const char *p; 455 if ((entry->ae_set & AE_SET_HARDLINK) == 0) 456 return (NULL); 457 if (archive_mstring_get_mbs( 458 entry->archive, &entry->ae_hardlink, &p) == 0) 459 return (p); 460 if (errno == ENOMEM) 461 __archive_errx(1, "No memory"); 462 return (NULL); 463} 464 465const char * 466archive_entry_hardlink_utf8(struct archive_entry *entry) 467{ 468 const char *p; 469 if ((entry->ae_set & AE_SET_HARDLINK) == 0) 470 return (NULL); 471 if (archive_mstring_get_utf8( 472 entry->archive, &entry->ae_hardlink, &p) == 0) 473 return (p); 474 if (errno == ENOMEM) 475 __archive_errx(1, "No memory"); 476 return (NULL); 477} 478 479const wchar_t * 480archive_entry_hardlink_w(struct archive_entry *entry) 481{ 482 const wchar_t *p; 483 if ((entry->ae_set & AE_SET_HARDLINK) == 0) 484 return (NULL); 485 if (archive_mstring_get_wcs( 486 entry->archive, &entry->ae_hardlink, &p) == 0) 487 return (p); 488 if (errno == ENOMEM) 489 __archive_errx(1, "No memory"); 490 return (NULL); 491} 492 493int 494_archive_entry_hardlink_l(struct archive_entry *entry, 495 const char **p, size_t *len, struct archive_string_conv *sc) 496{ 497 if ((entry->ae_set & AE_SET_HARDLINK) == 0) { 498 *p = NULL; 499 *len = 0; 500 return (0); 501 } 502 return (archive_mstring_get_mbs_l(&entry->ae_hardlink, p, len, sc)); 503} 504 505la_int64_t 506archive_entry_ino(struct archive_entry *entry) 507{ 508 return (entry->ae_stat.aest_ino); 509} 510 511int 512archive_entry_ino_is_set(struct archive_entry *entry) 513{ 514 return (entry->ae_set & AE_SET_INO); 515} 516 517la_int64_t 518archive_entry_ino64(struct archive_entry *entry) 519{ 520 return (entry->ae_stat.aest_ino); 521} 522 523mode_t 524archive_entry_mode(struct archive_entry *entry) 525{ 526 return (entry->acl.mode); 527} 528 529time_t 530archive_entry_mtime(struct archive_entry *entry) 531{ 532 return (entry->ae_stat.aest_mtime); 533} 534 535long 536archive_entry_mtime_nsec(struct archive_entry *entry) 537{ 538 return (entry->ae_stat.aest_mtime_nsec); 539} 540 541int 542archive_entry_mtime_is_set(struct archive_entry *entry) 543{ 544 return (entry->ae_set & AE_SET_MTIME); 545} 546 547unsigned int 548archive_entry_nlink(struct archive_entry *entry) 549{ 550 return (entry->ae_stat.aest_nlink); 551} 552 553const char * 554archive_entry_pathname(struct archive_entry *entry) 555{ 556 const char *p; 557 if (archive_mstring_get_mbs( 558 entry->archive, &entry->ae_pathname, &p) == 0) 559 return (p); 560 if (errno == ENOMEM) 561 __archive_errx(1, "No memory"); 562 return (NULL); 563} 564 565const char * 566archive_entry_pathname_utf8(struct archive_entry *entry) 567{ 568 const char *p; 569 if (archive_mstring_get_utf8( 570 entry->archive, &entry->ae_pathname, &p) == 0) 571 return (p); 572 if (errno == ENOMEM) 573 __archive_errx(1, "No memory"); 574 return (NULL); 575} 576 577const wchar_t * 578archive_entry_pathname_w(struct archive_entry *entry) 579{ 580 const wchar_t *p; 581 if (archive_mstring_get_wcs( 582 entry->archive, &entry->ae_pathname, &p) == 0) 583 return (p); 584 if (errno == ENOMEM) 585 __archive_errx(1, "No memory"); 586 return (NULL); 587} 588 589int 590_archive_entry_pathname_l(struct archive_entry *entry, 591 const char **p, size_t *len, struct archive_string_conv *sc) 592{ 593 return (archive_mstring_get_mbs_l(&entry->ae_pathname, p, len, sc)); 594} 595 596mode_t 597archive_entry_perm(struct archive_entry *entry) 598{ 599 return (~AE_IFMT & entry->acl.mode); 600} 601 602dev_t 603archive_entry_rdev(struct archive_entry *entry) 604{ 605 if (entry->ae_stat.aest_rdev_is_broken_down) 606 return ae_makedev(entry->ae_stat.aest_rdevmajor, 607 entry->ae_stat.aest_rdevminor); 608 else 609 return (entry->ae_stat.aest_rdev); 610} 611 612dev_t 613archive_entry_rdevmajor(struct archive_entry *entry) 614{ 615 if (entry->ae_stat.aest_rdev_is_broken_down) 616 return (entry->ae_stat.aest_rdevmajor); 617 else 618 return major(entry->ae_stat.aest_rdev); 619} 620 621dev_t 622archive_entry_rdevminor(struct archive_entry *entry) 623{ 624 if (entry->ae_stat.aest_rdev_is_broken_down) 625 return (entry->ae_stat.aest_rdevminor); 626 else 627 return minor(entry->ae_stat.aest_rdev); 628} 629 630la_int64_t 631archive_entry_size(struct archive_entry *entry) 632{ 633 return (entry->ae_stat.aest_size); 634} 635 636int 637archive_entry_size_is_set(struct archive_entry *entry) 638{ 639 return (entry->ae_set & AE_SET_SIZE); 640} 641 642const char * 643archive_entry_sourcepath(struct archive_entry *entry) 644{ 645 const char *p; 646 if (archive_mstring_get_mbs( 647 entry->archive, &entry->ae_sourcepath, &p) == 0) 648 return (p); 649 if (errno == ENOMEM) 650 __archive_errx(1, "No memory"); 651 return (NULL); 652} 653 654const wchar_t * 655archive_entry_sourcepath_w(struct archive_entry *entry) 656{ 657 const wchar_t *p; 658 if (archive_mstring_get_wcs( 659 entry->archive, &entry->ae_sourcepath, &p) == 0) 660 return (p); 661 return (NULL); 662} 663 664const char * 665archive_entry_symlink(struct archive_entry *entry) 666{ 667 const char *p; 668 if ((entry->ae_set & AE_SET_SYMLINK) == 0) 669 return (NULL); 670 if (archive_mstring_get_mbs( 671 entry->archive, &entry->ae_symlink, &p) == 0) 672 return (p); 673 if (errno == ENOMEM) 674 __archive_errx(1, "No memory"); 675 return (NULL); 676} 677 678const char * 679archive_entry_symlink_utf8(struct archive_entry *entry) 680{ 681 const char *p; 682 if ((entry->ae_set & AE_SET_SYMLINK) == 0) 683 return (NULL); 684 if (archive_mstring_get_utf8( 685 entry->archive, &entry->ae_symlink, &p) == 0) 686 return (p); 687 if (errno == ENOMEM) 688 __archive_errx(1, "No memory"); 689 return (NULL); 690} 691 692const wchar_t * 693archive_entry_symlink_w(struct archive_entry *entry) 694{ 695 const wchar_t *p; 696 if ((entry->ae_set & AE_SET_SYMLINK) == 0) 697 return (NULL); 698 if (archive_mstring_get_wcs( 699 entry->archive, &entry->ae_symlink, &p) == 0) 700 return (p); 701 if (errno == ENOMEM) 702 __archive_errx(1, "No memory"); 703 return (NULL); 704} 705 706int 707_archive_entry_symlink_l(struct archive_entry *entry, 708 const char **p, size_t *len, struct archive_string_conv *sc) 709{ 710 if ((entry->ae_set & AE_SET_SYMLINK) == 0) { 711 *p = NULL; 712 *len = 0; 713 return (0); 714 } 715 return (archive_mstring_get_mbs_l( &entry->ae_symlink, p, len, sc)); 716} 717 718la_int64_t 719archive_entry_uid(struct archive_entry *entry) 720{ 721 return (entry->ae_stat.aest_uid); 722} 723 724const char * 725archive_entry_uname(struct archive_entry *entry) 726{ 727 const char *p; 728 if (archive_mstring_get_mbs(entry->archive, &entry->ae_uname, &p) == 0) 729 return (p); 730 if (errno == ENOMEM) 731 __archive_errx(1, "No memory"); 732 return (NULL); 733} 734 735const char * 736archive_entry_uname_utf8(struct archive_entry *entry) 737{ 738 const char *p; 739 if (archive_mstring_get_utf8(entry->archive, &entry->ae_uname, &p) == 0) 740 return (p); 741 if (errno == ENOMEM) 742 __archive_errx(1, "No memory"); 743 return (NULL); 744} 745 746const wchar_t * 747archive_entry_uname_w(struct archive_entry *entry) 748{ 749 const wchar_t *p; 750 if (archive_mstring_get_wcs(entry->archive, &entry->ae_uname, &p) == 0) 751 return (p); 752 if (errno == ENOMEM) 753 __archive_errx(1, "No memory"); 754 return (NULL); 755} 756 757int 758_archive_entry_uname_l(struct archive_entry *entry, 759 const char **p, size_t *len, struct archive_string_conv *sc) 760{ 761 return (archive_mstring_get_mbs_l(&entry->ae_uname, p, len, sc)); 762} 763 764int 765archive_entry_is_data_encrypted(struct archive_entry *entry) 766{ 767 return ((entry->encryption & AE_ENCRYPTION_DATA) == AE_ENCRYPTION_DATA); 768} 769 770int 771archive_entry_is_metadata_encrypted(struct archive_entry *entry) 772{ 773 return ((entry->encryption & AE_ENCRYPTION_METADATA) == AE_ENCRYPTION_METADATA); 774} 775 776int 777archive_entry_is_encrypted(struct archive_entry *entry) 778{ 779 return (entry->encryption & (AE_ENCRYPTION_DATA|AE_ENCRYPTION_METADATA)); 780} 781 782/* 783 * Functions to set archive_entry properties. 784 */ 785 786void 787archive_entry_set_filetype(struct archive_entry *entry, unsigned int type) 788{ 789 entry->stat_valid = 0; 790 entry->acl.mode &= ~AE_IFMT; 791 entry->acl.mode |= AE_IFMT & type; 792} 793 794void 795archive_entry_set_fflags(struct archive_entry *entry, 796 unsigned long set, unsigned long clear) 797{ 798 archive_mstring_clean(&entry->ae_fflags_text); 799 entry->ae_fflags_set = set; 800 entry->ae_fflags_clear = clear; 801} 802 803const char * 804archive_entry_copy_fflags_text(struct archive_entry *entry, 805 const char *flags) 806{ 807 archive_mstring_copy_mbs(&entry->ae_fflags_text, flags); 808 return (ae_strtofflags(flags, 809 &entry->ae_fflags_set, &entry->ae_fflags_clear)); 810} 811 812const wchar_t * 813archive_entry_copy_fflags_text_w(struct archive_entry *entry, 814 const wchar_t *flags) 815{ 816 archive_mstring_copy_wcs(&entry->ae_fflags_text, flags); 817 return (ae_wcstofflags(flags, 818 &entry->ae_fflags_set, &entry->ae_fflags_clear)); 819} 820 821void 822archive_entry_set_gid(struct archive_entry *entry, la_int64_t g) 823{ 824 entry->stat_valid = 0; 825 entry->ae_stat.aest_gid = g; 826} 827 828void 829archive_entry_set_gname(struct archive_entry *entry, const char *name) 830{ 831 archive_mstring_copy_mbs(&entry->ae_gname, name); 832} 833 834void 835archive_entry_set_gname_utf8(struct archive_entry *entry, const char *name) 836{ 837 archive_mstring_copy_utf8(&entry->ae_gname, name); 838} 839 840void 841archive_entry_copy_gname(struct archive_entry *entry, const char *name) 842{ 843 archive_mstring_copy_mbs(&entry->ae_gname, name); 844} 845 846void 847archive_entry_copy_gname_w(struct archive_entry *entry, const wchar_t *name) 848{ 849 archive_mstring_copy_wcs(&entry->ae_gname, name); 850} 851 852int 853archive_entry_update_gname_utf8(struct archive_entry *entry, const char *name) 854{ 855 if (archive_mstring_update_utf8(entry->archive, 856 &entry->ae_gname, name) == 0) 857 return (1); 858 if (errno == ENOMEM) 859 __archive_errx(1, "No memory"); 860 return (0); 861} 862 863int 864_archive_entry_copy_gname_l(struct archive_entry *entry, 865 const char *name, size_t len, struct archive_string_conv *sc) 866{ 867 return (archive_mstring_copy_mbs_len_l(&entry->ae_gname, name, len, sc)); 868} 869 870void 871archive_entry_set_ino(struct archive_entry *entry, la_int64_t ino) 872{ 873 entry->stat_valid = 0; 874 entry->ae_set |= AE_SET_INO; 875 entry->ae_stat.aest_ino = ino; 876} 877 878void 879archive_entry_set_ino64(struct archive_entry *entry, la_int64_t ino) 880{ 881 entry->stat_valid = 0; 882 entry->ae_set |= AE_SET_INO; 883 entry->ae_stat.aest_ino = ino; 884} 885 886void 887archive_entry_set_hardlink(struct archive_entry *entry, const char *target) 888{ 889 archive_mstring_copy_mbs(&entry->ae_hardlink, target); 890 if (target != NULL) 891 entry->ae_set |= AE_SET_HARDLINK; 892 else 893 entry->ae_set &= ~AE_SET_HARDLINK; 894} 895 896void 897archive_entry_set_hardlink_utf8(struct archive_entry *entry, const char *target) 898{ 899 archive_mstring_copy_utf8(&entry->ae_hardlink, target); 900 if (target != NULL) 901 entry->ae_set |= AE_SET_HARDLINK; 902 else 903 entry->ae_set &= ~AE_SET_HARDLINK; 904} 905 906void 907archive_entry_copy_hardlink(struct archive_entry *entry, const char *target) 908{ 909 archive_mstring_copy_mbs(&entry->ae_hardlink, target); 910 if (target != NULL) 911 entry->ae_set |= AE_SET_HARDLINK; 912 else 913 entry->ae_set &= ~AE_SET_HARDLINK; 914} 915 916void 917archive_entry_copy_hardlink_w(struct archive_entry *entry, const wchar_t *target) 918{ 919 archive_mstring_copy_wcs(&entry->ae_hardlink, target); 920 if (target != NULL) 921 entry->ae_set |= AE_SET_HARDLINK; 922 else 923 entry->ae_set &= ~AE_SET_HARDLINK; 924} 925 926int 927archive_entry_update_hardlink_utf8(struct archive_entry *entry, const char *target) 928{ 929 if (target != NULL) 930 entry->ae_set |= AE_SET_HARDLINK; 931 else 932 entry->ae_set &= ~AE_SET_HARDLINK; 933 if (archive_mstring_update_utf8(entry->archive, 934 &entry->ae_hardlink, target) == 0) 935 return (1); 936 if (errno == ENOMEM) 937 __archive_errx(1, "No memory"); 938 return (0); 939} 940 941int 942_archive_entry_copy_hardlink_l(struct archive_entry *entry, 943 const char *target, size_t len, struct archive_string_conv *sc) 944{ 945 int r; 946 947 r = archive_mstring_copy_mbs_len_l(&entry->ae_hardlink, 948 target, len, sc); 949 if (target != NULL && r == 0) 950 entry->ae_set |= AE_SET_HARDLINK; 951 else 952 entry->ae_set &= ~AE_SET_HARDLINK; 953 return (r); 954} 955 956void 957archive_entry_set_atime(struct archive_entry *entry, time_t t, long ns) 958{ 959 FIX_NS(t, ns); 960 entry->stat_valid = 0; 961 entry->ae_set |= AE_SET_ATIME; 962 entry->ae_stat.aest_atime = t; 963 entry->ae_stat.aest_atime_nsec = ns; 964} 965 966void 967archive_entry_unset_atime(struct archive_entry *entry) 968{ 969 archive_entry_set_atime(entry, 0, 0); 970 entry->ae_set &= ~AE_SET_ATIME; 971} 972 973void 974archive_entry_set_birthtime(struct archive_entry *entry, time_t t, long ns) 975{ 976 FIX_NS(t, ns); 977 entry->stat_valid = 0; 978 entry->ae_set |= AE_SET_BIRTHTIME; 979 entry->ae_stat.aest_birthtime = t; 980 entry->ae_stat.aest_birthtime_nsec = ns; 981} 982 983void 984archive_entry_unset_birthtime(struct archive_entry *entry) 985{ 986 archive_entry_set_birthtime(entry, 0, 0); 987 entry->ae_set &= ~AE_SET_BIRTHTIME; 988} 989 990void 991archive_entry_set_ctime(struct archive_entry *entry, time_t t, long ns) 992{ 993 FIX_NS(t, ns); 994 entry->stat_valid = 0; 995 entry->ae_set |= AE_SET_CTIME; 996 entry->ae_stat.aest_ctime = t; 997 entry->ae_stat.aest_ctime_nsec = ns; 998} 999 1000void 1001archive_entry_unset_ctime(struct archive_entry *entry) 1002{ 1003 archive_entry_set_ctime(entry, 0, 0); 1004 entry->ae_set &= ~AE_SET_CTIME; 1005} 1006 1007void 1008archive_entry_set_dev(struct archive_entry *entry, dev_t d) 1009{ 1010 entry->stat_valid = 0; 1011 entry->ae_set |= AE_SET_DEV; 1012 entry->ae_stat.aest_dev_is_broken_down = 0; 1013 entry->ae_stat.aest_dev = d; 1014} 1015 1016void 1017archive_entry_set_devmajor(struct archive_entry *entry, dev_t m) 1018{ 1019 entry->stat_valid = 0; 1020 entry->ae_set |= AE_SET_DEV; 1021 entry->ae_stat.aest_dev_is_broken_down = 1; 1022 entry->ae_stat.aest_devmajor = m; 1023} 1024 1025void 1026archive_entry_set_devminor(struct archive_entry *entry, dev_t m) 1027{ 1028 entry->stat_valid = 0; 1029 entry->ae_set |= AE_SET_DEV; 1030 entry->ae_stat.aest_dev_is_broken_down = 1; 1031 entry->ae_stat.aest_devminor = m; 1032} 1033 1034/* Set symlink if symlink is already set, else set hardlink. */ 1035void 1036archive_entry_set_link(struct archive_entry *entry, const char *target) 1037{ 1038 if (entry->ae_set & AE_SET_SYMLINK) 1039 archive_mstring_copy_mbs(&entry->ae_symlink, target); 1040 else 1041 archive_mstring_copy_mbs(&entry->ae_hardlink, target); 1042} 1043 1044void 1045archive_entry_set_link_utf8(struct archive_entry *entry, const char *target) 1046{ 1047 if (entry->ae_set & AE_SET_SYMLINK) 1048 archive_mstring_copy_utf8(&entry->ae_symlink, target); 1049 else 1050 archive_mstring_copy_utf8(&entry->ae_hardlink, target); 1051} 1052 1053/* Set symlink if symlink is already set, else set hardlink. */ 1054void 1055archive_entry_copy_link(struct archive_entry *entry, const char *target) 1056{ 1057 if (entry->ae_set & AE_SET_SYMLINK) 1058 archive_mstring_copy_mbs(&entry->ae_symlink, target); 1059 else 1060 archive_mstring_copy_mbs(&entry->ae_hardlink, target); 1061} 1062 1063/* Set symlink if symlink is already set, else set hardlink. */ 1064void 1065archive_entry_copy_link_w(struct archive_entry *entry, const wchar_t *target) 1066{ 1067 if (entry->ae_set & AE_SET_SYMLINK) 1068 archive_mstring_copy_wcs(&entry->ae_symlink, target); 1069 else 1070 archive_mstring_copy_wcs(&entry->ae_hardlink, target); 1071} 1072 1073int 1074archive_entry_update_link_utf8(struct archive_entry *entry, const char *target) 1075{ 1076 int r; 1077 if (entry->ae_set & AE_SET_SYMLINK) 1078 r = archive_mstring_update_utf8(entry->archive, 1079 &entry->ae_symlink, target); 1080 else 1081 r = archive_mstring_update_utf8(entry->archive, 1082 &entry->ae_hardlink, target); 1083 if (r == 0) 1084 return (1); 1085 if (errno == ENOMEM) 1086 __archive_errx(1, "No memory"); 1087 return (0); 1088} 1089 1090int 1091_archive_entry_copy_link_l(struct archive_entry *entry, 1092 const char *target, size_t len, struct archive_string_conv *sc) 1093{ 1094 int r; 1095 1096 if (entry->ae_set & AE_SET_SYMLINK) 1097 r = archive_mstring_copy_mbs_len_l(&entry->ae_symlink, 1098 target, len, sc); 1099 else 1100 r = archive_mstring_copy_mbs_len_l(&entry->ae_hardlink, 1101 target, len, sc); 1102 return (r); 1103} 1104 1105void 1106archive_entry_set_mode(struct archive_entry *entry, mode_t m) 1107{ 1108 entry->stat_valid = 0; 1109 entry->acl.mode = m; 1110} 1111 1112void 1113archive_entry_set_mtime(struct archive_entry *entry, time_t t, long ns) 1114{ 1115 FIX_NS(t, ns); 1116 entry->stat_valid = 0; 1117 entry->ae_set |= AE_SET_MTIME; 1118 entry->ae_stat.aest_mtime = t; 1119 entry->ae_stat.aest_mtime_nsec = ns; 1120} 1121 1122void 1123archive_entry_unset_mtime(struct archive_entry *entry) 1124{ 1125 archive_entry_set_mtime(entry, 0, 0); 1126 entry->ae_set &= ~AE_SET_MTIME; 1127} 1128 1129void 1130archive_entry_set_nlink(struct archive_entry *entry, unsigned int nlink) 1131{ 1132 entry->stat_valid = 0; 1133 entry->ae_stat.aest_nlink = nlink; 1134} 1135 1136void 1137archive_entry_set_pathname(struct archive_entry *entry, const char *name) 1138{ 1139 archive_mstring_copy_mbs(&entry->ae_pathname, name); 1140} 1141 1142void 1143archive_entry_set_pathname_utf8(struct archive_entry *entry, const char *name) 1144{ 1145 archive_mstring_copy_utf8(&entry->ae_pathname, name); 1146} 1147 1148void 1149archive_entry_copy_pathname(struct archive_entry *entry, const char *name) 1150{ 1151 archive_mstring_copy_mbs(&entry->ae_pathname, name); 1152} 1153 1154void 1155archive_entry_copy_pathname_w(struct archive_entry *entry, const wchar_t *name) 1156{ 1157 archive_mstring_copy_wcs(&entry->ae_pathname, name); 1158} 1159 1160int 1161archive_entry_update_pathname_utf8(struct archive_entry *entry, const char *name) 1162{ 1163 if (archive_mstring_update_utf8(entry->archive, 1164 &entry->ae_pathname, name) == 0) 1165 return (1); 1166 if (errno == ENOMEM) 1167 __archive_errx(1, "No memory"); 1168 return (0); 1169} 1170 1171int 1172_archive_entry_copy_pathname_l(struct archive_entry *entry, 1173 const char *name, size_t len, struct archive_string_conv *sc) 1174{ 1175 return (archive_mstring_copy_mbs_len_l(&entry->ae_pathname, 1176 name, len, sc)); 1177} 1178 1179void 1180archive_entry_set_perm(struct archive_entry *entry, mode_t p) 1181{ 1182 entry->stat_valid = 0; 1183 entry->acl.mode &= AE_IFMT; 1184 entry->acl.mode |= ~AE_IFMT & p; 1185} 1186 1187void 1188archive_entry_set_rdev(struct archive_entry *entry, dev_t m) 1189{ 1190 entry->stat_valid = 0; 1191 entry->ae_stat.aest_rdev = m; 1192 entry->ae_stat.aest_rdev_is_broken_down = 0; 1193} 1194 1195void 1196archive_entry_set_rdevmajor(struct archive_entry *entry, dev_t m) 1197{ 1198 entry->stat_valid = 0; 1199 entry->ae_stat.aest_rdev_is_broken_down = 1; 1200 entry->ae_stat.aest_rdevmajor = m; 1201} 1202 1203void 1204archive_entry_set_rdevminor(struct archive_entry *entry, dev_t m) 1205{ 1206 entry->stat_valid = 0; 1207 entry->ae_stat.aest_rdev_is_broken_down = 1; 1208 entry->ae_stat.aest_rdevminor = m; 1209} 1210 1211void 1212archive_entry_set_size(struct archive_entry *entry, la_int64_t s) 1213{ 1214 entry->stat_valid = 0; 1215 entry->ae_stat.aest_size = s; 1216 entry->ae_set |= AE_SET_SIZE; 1217} 1218 1219void 1220archive_entry_unset_size(struct archive_entry *entry) 1221{ 1222 archive_entry_set_size(entry, 0); 1223 entry->ae_set &= ~AE_SET_SIZE; 1224} 1225 1226void 1227archive_entry_copy_sourcepath(struct archive_entry *entry, const char *path) 1228{ 1229 archive_mstring_copy_mbs(&entry->ae_sourcepath, path); 1230} 1231 1232void 1233archive_entry_copy_sourcepath_w(struct archive_entry *entry, const wchar_t *path) 1234{ 1235 archive_mstring_copy_wcs(&entry->ae_sourcepath, path); 1236} 1237 1238void 1239archive_entry_set_symlink(struct archive_entry *entry, const char *linkname) 1240{ 1241 archive_mstring_copy_mbs(&entry->ae_symlink, linkname); 1242 if (linkname != NULL) 1243 entry->ae_set |= AE_SET_SYMLINK; 1244 else 1245 entry->ae_set &= ~AE_SET_SYMLINK; 1246} 1247 1248void 1249archive_entry_set_symlink_utf8(struct archive_entry *entry, const char *linkname) 1250{ 1251 archive_mstring_copy_utf8(&entry->ae_symlink, linkname); 1252 if (linkname != NULL) 1253 entry->ae_set |= AE_SET_SYMLINK; 1254 else 1255 entry->ae_set &= ~AE_SET_SYMLINK; 1256} 1257 1258void 1259archive_entry_copy_symlink(struct archive_entry *entry, const char *linkname) 1260{ 1261 archive_mstring_copy_mbs(&entry->ae_symlink, linkname); 1262 if (linkname != NULL) 1263 entry->ae_set |= AE_SET_SYMLINK; 1264 else 1265 entry->ae_set &= ~AE_SET_SYMLINK; 1266} 1267 1268void 1269archive_entry_copy_symlink_w(struct archive_entry *entry, const wchar_t *linkname) 1270{ 1271 archive_mstring_copy_wcs(&entry->ae_symlink, linkname); 1272 if (linkname != NULL) 1273 entry->ae_set |= AE_SET_SYMLINK; 1274 else 1275 entry->ae_set &= ~AE_SET_SYMLINK; 1276} 1277 1278int 1279archive_entry_update_symlink_utf8(struct archive_entry *entry, const char *linkname) 1280{ 1281 if (linkname != NULL) 1282 entry->ae_set |= AE_SET_SYMLINK; 1283 else 1284 entry->ae_set &= ~AE_SET_SYMLINK; 1285 if (archive_mstring_update_utf8(entry->archive, 1286 &entry->ae_symlink, linkname) == 0) 1287 return (1); 1288 if (errno == ENOMEM) 1289 __archive_errx(1, "No memory"); 1290 return (0); 1291} 1292 1293int 1294_archive_entry_copy_symlink_l(struct archive_entry *entry, 1295 const char *linkname, size_t len, struct archive_string_conv *sc) 1296{ 1297 int r; 1298 1299 r = archive_mstring_copy_mbs_len_l(&entry->ae_symlink, 1300 linkname, len, sc); 1301 if (linkname != NULL && r == 0) 1302 entry->ae_set |= AE_SET_SYMLINK; 1303 else 1304 entry->ae_set &= ~AE_SET_SYMLINK; 1305 return (r); 1306} 1307 1308void 1309archive_entry_set_uid(struct archive_entry *entry, la_int64_t u) 1310{ 1311 entry->stat_valid = 0; 1312 entry->ae_stat.aest_uid = u; 1313} 1314 1315void 1316archive_entry_set_uname(struct archive_entry *entry, const char *name) 1317{ 1318 archive_mstring_copy_mbs(&entry->ae_uname, name); 1319} 1320 1321void 1322archive_entry_set_uname_utf8(struct archive_entry *entry, const char *name) 1323{ 1324 archive_mstring_copy_utf8(&entry->ae_uname, name); 1325} 1326 1327void 1328archive_entry_copy_uname(struct archive_entry *entry, const char *name) 1329{ 1330 archive_mstring_copy_mbs(&entry->ae_uname, name); 1331} 1332 1333void 1334archive_entry_copy_uname_w(struct archive_entry *entry, const wchar_t *name) 1335{ 1336 archive_mstring_copy_wcs(&entry->ae_uname, name); 1337} 1338 1339int 1340archive_entry_update_uname_utf8(struct archive_entry *entry, const char *name) 1341{ 1342 if (archive_mstring_update_utf8(entry->archive, 1343 &entry->ae_uname, name) == 0) 1344 return (1); 1345 if (errno == ENOMEM) 1346 __archive_errx(1, "No memory"); 1347 return (0); 1348} 1349 1350void 1351archive_entry_set_is_data_encrypted(struct archive_entry *entry, char is_encrypted) 1352{ 1353 if (is_encrypted) { 1354 entry->encryption |= AE_ENCRYPTION_DATA; 1355 } else { 1356 entry->encryption &= ~AE_ENCRYPTION_DATA; 1357 } 1358} 1359 1360void 1361archive_entry_set_is_metadata_encrypted(struct archive_entry *entry, char is_encrypted) 1362{ 1363 if (is_encrypted) { 1364 entry->encryption |= AE_ENCRYPTION_METADATA; 1365 } else { 1366 entry->encryption &= ~AE_ENCRYPTION_METADATA; 1367 } 1368} 1369 1370int 1371_archive_entry_copy_uname_l(struct archive_entry *entry, 1372 const char *name, size_t len, struct archive_string_conv *sc) 1373{ 1374 return (archive_mstring_copy_mbs_len_l(&entry->ae_uname, 1375 name, len, sc)); 1376} 1377 1378const void * 1379archive_entry_mac_metadata(struct archive_entry *entry, size_t *s) 1380{ 1381 *s = entry->mac_metadata_size; 1382 return entry->mac_metadata; 1383} 1384 1385void 1386archive_entry_copy_mac_metadata(struct archive_entry *entry, 1387 const void *p, size_t s) 1388{ 1389 free(entry->mac_metadata); 1390 if (p == NULL || s == 0) { 1391 entry->mac_metadata = NULL; 1392 entry->mac_metadata_size = 0; 1393 } else { 1394 entry->mac_metadata_size = s; 1395 entry->mac_metadata = malloc(s); 1396 if (entry->mac_metadata == NULL) 1397 abort(); 1398 memcpy(entry->mac_metadata, p, s); 1399 } 1400} 1401 1402/* 1403 * ACL management. The following would, of course, be a lot simpler 1404 * if: 1) the last draft of POSIX.1e were a really thorough and 1405 * complete standard that addressed the needs of ACL archiving and 2) 1406 * everyone followed it faithfully. Alas, neither is true, so the 1407 * following is a lot more complex than might seem necessary to the 1408 * uninitiated. 1409 */ 1410 1411struct archive_acl * 1412archive_entry_acl(struct archive_entry *entry) 1413{ 1414 return &entry->acl; 1415} 1416 1417void 1418archive_entry_acl_clear(struct archive_entry *entry) 1419{ 1420 archive_acl_clear(&entry->acl); 1421} 1422 1423/* 1424 * Add a single ACL entry to the internal list of ACL data. 1425 */ 1426int 1427archive_entry_acl_add_entry(struct archive_entry *entry, 1428 int type, int permset, int tag, int id, const char *name) 1429{ 1430 return archive_acl_add_entry(&entry->acl, type, permset, tag, id, name); 1431} 1432 1433/* 1434 * As above, but with a wide-character name. 1435 */ 1436int 1437archive_entry_acl_add_entry_w(struct archive_entry *entry, 1438 int type, int permset, int tag, int id, const wchar_t *name) 1439{ 1440 return archive_acl_add_entry_w_len(&entry->acl, 1441 type, permset, tag, id, name, wcslen(name)); 1442} 1443 1444/* 1445 * Return a bitmask of ACL types in an archive entry ACL list 1446 */ 1447int 1448archive_entry_acl_types(struct archive_entry *entry) 1449{ 1450 return (archive_acl_types(&entry->acl)); 1451} 1452 1453/* 1454 * Return a count of entries matching "want_type". 1455 */ 1456int 1457archive_entry_acl_count(struct archive_entry *entry, int want_type) 1458{ 1459 return archive_acl_count(&entry->acl, want_type); 1460} 1461 1462/* 1463 * Prepare for reading entries from the ACL data. Returns a count 1464 * of entries matching "want_type", or zero if there are no 1465 * non-extended ACL entries of that type. 1466 */ 1467int 1468archive_entry_acl_reset(struct archive_entry *entry, int want_type) 1469{ 1470 return archive_acl_reset(&entry->acl, want_type); 1471} 1472 1473/* 1474 * Return the next ACL entry in the list. Fake entries for the 1475 * standard permissions and include them in the returned list. 1476 */ 1477int 1478archive_entry_acl_next(struct archive_entry *entry, int want_type, int *type, 1479 int *permset, int *tag, int *id, const char **name) 1480{ 1481 int r; 1482 r = archive_acl_next(entry->archive, &entry->acl, want_type, type, 1483 permset, tag, id, name); 1484 if (r == ARCHIVE_FATAL && errno == ENOMEM) 1485 __archive_errx(1, "No memory"); 1486 return (r); 1487} 1488 1489/* 1490 * Generate a text version of the ACL. The flags parameter controls 1491 * the style of the generated ACL. 1492 */ 1493wchar_t * 1494archive_entry_acl_to_text_w(struct archive_entry *entry, la_ssize_t *len, 1495 int flags) 1496{ 1497 return (archive_acl_to_text_w(&entry->acl, len, flags, 1498 entry->archive)); 1499} 1500 1501char * 1502archive_entry_acl_to_text(struct archive_entry *entry, la_ssize_t *len, 1503 int flags) 1504{ 1505 return (archive_acl_to_text_l(&entry->acl, len, flags, NULL)); 1506} 1507 1508char * 1509_archive_entry_acl_to_text_l(struct archive_entry *entry, ssize_t *len, 1510 int flags, struct archive_string_conv *sc) 1511{ 1512 return (archive_acl_to_text_l(&entry->acl, len, flags, sc)); 1513} 1514 1515/* 1516 * ACL text parser. 1517 */ 1518int 1519archive_entry_acl_from_text_w(struct archive_entry *entry, 1520 const wchar_t *wtext, int type) 1521{ 1522 return (archive_acl_from_text_w(&entry->acl, wtext, type)); 1523} 1524 1525int 1526archive_entry_acl_from_text(struct archive_entry *entry, 1527 const char *text, int type) 1528{ 1529 return (archive_acl_from_text_l(&entry->acl, text, type, NULL)); 1530} 1531 1532int 1533_archive_entry_acl_from_text_l(struct archive_entry *entry, const char *text, 1534 int type, struct archive_string_conv *sc) 1535{ 1536 return (archive_acl_from_text_l(&entry->acl, text, type, sc)); 1537} 1538 1539/* Deprecated */ 1540static int 1541archive_entry_acl_text_compat(int *flags) 1542{ 1543 if ((*flags & ARCHIVE_ENTRY_ACL_TYPE_POSIX1E) == 0) 1544 return (1); 1545 1546 /* ABI compat with old ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID */ 1547 if ((*flags & OLD_ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID) != 0) 1548 *flags |= ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID; 1549 1550 /* ABI compat with old ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT */ 1551 if ((*flags & OLD_ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT) != 0) 1552 *flags |= ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT; 1553 1554 *flags |= ARCHIVE_ENTRY_ACL_STYLE_SEPARATOR_COMMA; 1555 1556 return (0); 1557} 1558 1559/* Deprecated */ 1560const wchar_t * 1561archive_entry_acl_text_w(struct archive_entry *entry, int flags) 1562{ 1563 if (entry->acl.acl_text_w != NULL) { 1564 free(entry->acl.acl_text_w); 1565 entry->acl.acl_text_w = NULL; 1566 } 1567 if (archive_entry_acl_text_compat(&flags) == 0) 1568 entry->acl.acl_text_w = archive_acl_to_text_w(&entry->acl, 1569 NULL, flags, entry->archive); 1570 return (entry->acl.acl_text_w); 1571} 1572 1573/* Deprecated */ 1574const char * 1575archive_entry_acl_text(struct archive_entry *entry, int flags) 1576{ 1577 if (entry->acl.acl_text != NULL) { 1578 free(entry->acl.acl_text); 1579 entry->acl.acl_text = NULL; 1580 } 1581 if (archive_entry_acl_text_compat(&flags) == 0) 1582 entry->acl.acl_text = archive_acl_to_text_l(&entry->acl, NULL, 1583 flags, NULL); 1584 1585 return (entry->acl.acl_text); 1586} 1587 1588/* Deprecated */ 1589int 1590_archive_entry_acl_text_l(struct archive_entry *entry, int flags, 1591 const char **acl_text, size_t *len, struct archive_string_conv *sc) 1592{ 1593 if (entry->acl.acl_text != NULL) { 1594 free(entry->acl.acl_text); 1595 entry->acl.acl_text = NULL; 1596 } 1597 1598 if (archive_entry_acl_text_compat(&flags) == 0) 1599 entry->acl.acl_text = archive_acl_to_text_l(&entry->acl, 1600 (ssize_t *)len, flags, sc); 1601 1602 *acl_text = entry->acl.acl_text; 1603 1604 return (0); 1605} 1606 1607/* 1608 * Following code is modified from UC Berkeley sources, and 1609 * is subject to the following copyright notice. 1610 */ 1611 1612/*- 1613 * Copyright (c) 1993 1614 * The Regents of the University of California. All rights reserved. 1615 * 1616 * Redistribution and use in source and binary forms, with or without 1617 * modification, are permitted provided that the following conditions 1618 * are met: 1619 * 1. Redistributions of source code must retain the above copyright 1620 * notice, this list of conditions and the following disclaimer. 1621 * 2. Redistributions in binary form must reproduce the above copyright 1622 * notice, this list of conditions and the following disclaimer in the 1623 * documentation and/or other materials provided with the distribution. 1624 * 4. Neither the name of the University nor the names of its contributors 1625 * may be used to endorse or promote products derived from this software 1626 * without specific prior written permission. 1627 * 1628 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 1629 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1630 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1631 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 1632 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1633 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 1634 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 1635 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 1636 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 1637 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 1638 * SUCH DAMAGE. 1639 */ 1640 1641static const struct flag { 1642 const char *name; 1643 const wchar_t *wname; 1644 unsigned long set; 1645 unsigned long clear; 1646} flags[] = { 1647 /* Preferred (shorter) names per flag first, all prefixed by "no" */ 1648#ifdef SF_APPEND 1649 { "nosappnd", L"nosappnd", SF_APPEND, 0 }, 1650 { "nosappend", L"nosappend", SF_APPEND, 0 }, 1651#endif 1652#if defined(FS_APPEND_FL) /* 'a' */ 1653 { "nosappnd", L"nosappnd", FS_APPEND_FL, 0 }, 1654 { "nosappend", L"nosappend", FS_APPEND_FL, 0 }, 1655#elif defined(EXT2_APPEND_FL) /* 'a' */ 1656 { "nosappnd", L"nosappnd", EXT2_APPEND_FL, 0 }, 1657 { "nosappend", L"nosappend", EXT2_APPEND_FL, 0 }, 1658#endif 1659#ifdef SF_ARCHIVED 1660 { "noarch", L"noarch", SF_ARCHIVED, 0 }, 1661 { "noarchived", L"noarchived", SF_ARCHIVED, 0 }, 1662#endif 1663#ifdef SF_IMMUTABLE 1664 { "noschg", L"noschg", SF_IMMUTABLE, 0 }, 1665 { "noschange", L"noschange", SF_IMMUTABLE, 0 }, 1666 { "nosimmutable", L"nosimmutable", SF_IMMUTABLE, 0 }, 1667#endif 1668#if defined(FS_IMMUTABLE_FL) /* 'i' */ 1669 { "noschg", L"noschg", FS_IMMUTABLE_FL, 0 }, 1670 { "noschange", L"noschange", FS_IMMUTABLE_FL, 0 }, 1671 { "nosimmutable", L"nosimmutable", FS_IMMUTABLE_FL, 0 }, 1672#elif defined(EXT2_IMMUTABLE_FL) /* 'i' */ 1673 { "noschg", L"noschg", EXT2_IMMUTABLE_FL, 0 }, 1674 { "noschange", L"noschange", EXT2_IMMUTABLE_FL, 0 }, 1675 { "nosimmutable", L"nosimmutable", EXT2_IMMUTABLE_FL, 0 }, 1676#endif 1677#ifdef SF_NOUNLINK 1678 { "nosunlnk", L"nosunlnk", SF_NOUNLINK, 0 }, 1679 { "nosunlink", L"nosunlink", SF_NOUNLINK, 0 }, 1680#endif 1681#ifdef SF_SNAPSHOT 1682 { "nosnapshot", L"nosnapshot", SF_SNAPSHOT, 0 }, 1683#endif 1684#ifdef UF_APPEND 1685 { "nouappnd", L"nouappnd", UF_APPEND, 0 }, 1686 { "nouappend", L"nouappend", UF_APPEND, 0 }, 1687#endif 1688#ifdef UF_IMMUTABLE 1689 { "nouchg", L"nouchg", UF_IMMUTABLE, 0 }, 1690 { "nouchange", L"nouchange", UF_IMMUTABLE, 0 }, 1691 { "nouimmutable", L"nouimmutable", UF_IMMUTABLE, 0 }, 1692#endif 1693#ifdef UF_NODUMP 1694 { "nodump", L"nodump", 0, UF_NODUMP}, 1695#endif 1696#if defined(FS_NODUMP_FL) /* 'd' */ 1697 { "nodump", L"nodump", 0, FS_NODUMP_FL}, 1698#elif defined(EXT2_NODUMP_FL) /* 'd' */ 1699 { "nodump", L"nodump", 0, EXT2_NODUMP_FL}, 1700#endif 1701#ifdef UF_OPAQUE 1702 { "noopaque", L"noopaque", UF_OPAQUE, 0 }, 1703#endif 1704#ifdef UF_NOUNLINK 1705 { "nouunlnk", L"nouunlnk", UF_NOUNLINK, 0 }, 1706 { "nouunlink", L"nouunlink", UF_NOUNLINK, 0 }, 1707#endif 1708#ifdef UF_COMPRESSED 1709 { "nocompressed",L"nocompressed", UF_COMPRESSED, 0 }, 1710#endif 1711#ifdef UF_HIDDEN 1712 { "nohidden", L"nohidden", UF_HIDDEN, 0 }, 1713#endif 1714#if defined(FS_UNRM_FL) 1715 { "nouunlink", L"nouunlink", FS_UNRM_FL, 0}, 1716#elif defined(EXT2_UNRM_FL) 1717 { "nouunlink", L"nouunlink", EXT2_UNRM_FL, 0}, 1718#endif 1719 1720#if defined(FS_BTREE_FL) 1721 { "nobtree", L"nobtree", FS_BTREE_FL, 0 }, 1722#elif defined(EXT2_BTREE_FL) 1723 { "nobtree", L"nobtree", EXT2_BTREE_FL, 0 }, 1724#endif 1725 1726#if defined(FS_ECOMPR_FL) 1727 { "nocomperr", L"nocomperr", FS_ECOMPR_FL, 0 }, 1728#elif defined(EXT2_ECOMPR_FL) 1729 { "nocomperr", L"nocomperr", EXT2_ECOMPR_FL, 0 }, 1730#endif 1731 1732#if defined(FS_COMPR_FL) /* 'c' */ 1733 { "nocompress", L"nocompress", FS_COMPR_FL, 0 }, 1734#elif defined(EXT2_COMPR_FL) /* 'c' */ 1735 { "nocompress", L"nocompress", EXT2_COMPR_FL, 0 }, 1736#endif 1737 1738#if defined(FS_NOATIME_FL) /* 'A' */ 1739 { "noatime", L"noatime", 0, FS_NOATIME_FL}, 1740#elif defined(EXT2_NOATIME_FL) /* 'A' */ 1741 { "noatime", L"noatime", 0, EXT2_NOATIME_FL}, 1742#endif 1743 1744#if defined(FS_DIRTY_FL) 1745 { "nocompdirty",L"nocompdirty", FS_DIRTY_FL, 0}, 1746#elif defined(EXT2_DIRTY_FL) 1747 { "nocompdirty",L"nocompdirty", EXT2_DIRTY_FL, 0}, 1748#endif 1749 1750#if defined(FS_COMPRBLK_FL) 1751#if defined(FS_NOCOMPR_FL) 1752 { "nocomprblk", L"nocomprblk", FS_COMPRBLK_FL, FS_NOCOMPR_FL}, 1753#else 1754 { "nocomprblk", L"nocomprblk", FS_COMPRBLK_FL, 0}, 1755#endif 1756#elif defined(EXT2_COMPRBLK_FL) 1757#if defined(EXT2_NOCOMPR_FL) 1758 { "nocomprblk", L"nocomprblk", EXT2_COMPRBLK_FL, EXT2_NOCOMPR_FL}, 1759#else 1760 { "nocomprblk", L"nocomprblk", EXT2_COMPRBLK_FL, 0}, 1761#endif 1762#endif 1763#if defined(FS_DIRSYNC_FL) 1764 { "nodirsync", L"nodirsync", FS_DIRSYNC_FL, 0}, 1765#elif defined(EXT2_DIRSYNC_FL) 1766 { "nodirsync", L"nodirsync", EXT2_DIRSYNC_FL, 0}, 1767#endif 1768#if defined(FS_INDEX_FL) 1769 { "nohashidx", L"nohashidx", FS_INDEX_FL, 0}, 1770#elif defined(EXT2_INDEX_FL) 1771 { "nohashidx", L"nohashidx", EXT2_INDEX_FL, 0}, 1772#endif 1773#if defined(FS_IMAGIC_FL) 1774 { "noimagic", L"noimagic", FS_IMAGIC_FL, 0}, 1775#elif defined(EXT2_IMAGIC_FL) 1776 { "noimagic", L"noimagic", EXT2_IMAGIC_FL, 0}, 1777#endif 1778#if defined(FS_JOURNAL_DATA_FL) 1779 { "nojournal", L"nojournal", FS_JOURNAL_DATA_FL, 0}, 1780#elif defined(EXT3_JOURNAL_DATA_FL) 1781 { "nojournal", L"nojournal", EXT3_JOURNAL_DATA_FL, 0}, 1782#endif 1783#if defined(FS_SECRM_FL) 1784 { "nosecuredeletion",L"nosecuredeletion",FS_SECRM_FL, 0}, 1785#elif defined(EXT2_SECRM_FL) 1786 { "nosecuredeletion",L"nosecuredeletion",EXT2_SECRM_FL, 0}, 1787#endif 1788#if defined(FS_SYNC_FL) 1789 { "nosync", L"nosync", FS_SYNC_FL, 0}, 1790#elif defined(EXT2_SYNC_FL) 1791 { "nosync", L"nosync", EXT2_SYNC_FL, 0}, 1792#endif 1793#if defined(FS_NOTAIL_FL) 1794 { "notail", L"notail", 0, FS_NOTAIL_FL}, 1795#elif defined(EXT2_NOTAIL_FL) 1796 { "notail", L"notail", 0, EXT2_NOTAIL_FL}, 1797#endif 1798#if defined(FS_TOPDIR_FL) 1799 { "notopdir", L"notopdir", FS_TOPDIR_FL, 0}, 1800#elif defined(EXT2_TOPDIR_FL) 1801 { "notopdir", L"notopdir", EXT2_TOPDIR_FL, 0}, 1802#endif 1803#ifdef FS_ENCRYPT_FL 1804 { "noencrypt", L"noencrypt", FS_ENCRYPT_FL, 0}, 1805#endif 1806#ifdef FS_HUGE_FILE_FL 1807 { "nohugefile", L"nohugefile", FS_HUGE_FILE_FL, 0}, 1808#endif 1809#ifdef FS_EXTENT_FL 1810 { "noextent", L"noextent", FS_EXTENT_FL, 0}, 1811#endif 1812#ifdef FS_EA_INODE_FL 1813 { "noeainode", L"noeainode", FS_EA_INODE_FL, 0}, 1814#endif 1815#ifdef FS_EOFBLOCKS_FL 1816 { "noeofblocks",L"noeofblocks", FS_EOFBLOCKS_FL, 0}, 1817#endif 1818#ifdef FS_NOCOW_FL 1819 { "nocow", L"nocow", FS_NOCOW_FL, 0}, 1820#endif 1821#ifdef FS_INLINE_DATA_FL 1822 { "noinlinedata",L"noinlinedata", FS_INLINE_DATA_FL, 0}, 1823#endif 1824#ifdef FS_PROJINHERIT_FL 1825 { "noprojinherit",L"noprojinherit", FS_PROJINHERIT_FL, 0}, 1826#endif 1827#if defined(FS_RESERVED_FL) 1828 { "noreserved", L"noreserved", FS_RESERVED_FL, 0}, 1829#elif defined(EXT2_RESERVED_FL) 1830 { "noreserved", L"noreserved", EXT2_RESERVED_FL, 0}, 1831#endif 1832 { NULL, NULL, 0, 0 } 1833}; 1834 1835/* 1836 * fflagstostr -- 1837 * Convert file flags to a comma-separated string. If no flags 1838 * are set, return the empty string. 1839 */ 1840static char * 1841ae_fflagstostr(unsigned long bitset, unsigned long bitclear) 1842{ 1843 char *string, *dp; 1844 const char *sp; 1845 unsigned long bits; 1846 const struct flag *flag; 1847 size_t length; 1848 1849 bits = bitset | bitclear; 1850 length = 0; 1851 for (flag = flags; flag->name != NULL; flag++) 1852 if (bits & (flag->set | flag->clear)) { 1853 length += strlen(flag->name) + 1; 1854 bits &= ~(flag->set | flag->clear); 1855 } 1856 1857 if (length == 0) 1858 return (NULL); 1859 string = (char *)malloc(length); 1860 if (string == NULL) 1861 return (NULL); 1862 1863 dp = string; 1864 for (flag = flags; flag->name != NULL; flag++) { 1865 if (bitset & flag->set || bitclear & flag->clear) { 1866 sp = flag->name + 2; 1867 } else if (bitset & flag->clear || bitclear & flag->set) { 1868 sp = flag->name; 1869 } else 1870 continue; 1871 bitset &= ~(flag->set | flag->clear); 1872 bitclear &= ~(flag->set | flag->clear); 1873 if (dp > string) 1874 *dp++ = ','; 1875 while ((*dp++ = *sp++) != '\0') 1876 ; 1877 dp--; 1878 } 1879 1880 *dp = '\0'; 1881 return (string); 1882} 1883 1884/* 1885 * strtofflags -- 1886 * Take string of arguments and return file flags. This 1887 * version works a little differently than strtofflags(3). 1888 * In particular, it always tests every token, skipping any 1889 * unrecognized tokens. It returns a pointer to the first 1890 * unrecognized token, or NULL if every token was recognized. 1891 * This version is also const-correct and does not modify the 1892 * provided string. 1893 */ 1894static const char * 1895ae_strtofflags(const char *s, unsigned long *setp, unsigned long *clrp) 1896{ 1897 const char *start, *end; 1898 const struct flag *flag; 1899 unsigned long set, clear; 1900 const char *failed; 1901 1902 set = clear = 0; 1903 start = s; 1904 failed = NULL; 1905 /* Find start of first token. */ 1906 while (*start == '\t' || *start == ' ' || *start == ',') 1907 start++; 1908 while (*start != '\0') { 1909 size_t length; 1910 /* Locate end of token. */ 1911 end = start; 1912 while (*end != '\0' && *end != '\t' && 1913 *end != ' ' && *end != ',') 1914 end++; 1915 length = end - start; 1916 for (flag = flags; flag->name != NULL; flag++) { 1917 size_t flag_length = strlen(flag->name); 1918 if (length == flag_length 1919 && memcmp(start, flag->name, length) == 0) { 1920 /* Matched "noXXXX", so reverse the sense. */ 1921 clear |= flag->set; 1922 set |= flag->clear; 1923 break; 1924 } else if (length == flag_length - 2 1925 && memcmp(start, flag->name + 2, length) == 0) { 1926 /* Matched "XXXX", so don't reverse. */ 1927 set |= flag->set; 1928 clear |= flag->clear; 1929 break; 1930 } 1931 } 1932 /* Ignore unknown flag names. */ 1933 if (flag->name == NULL && failed == NULL) 1934 failed = start; 1935 1936 /* Find start of next token. */ 1937 start = end; 1938 while (*start == '\t' || *start == ' ' || *start == ',') 1939 start++; 1940 1941 } 1942 1943 if (setp) 1944 *setp = set; 1945 if (clrp) 1946 *clrp = clear; 1947 1948 /* Return location of first failure. */ 1949 return (failed); 1950} 1951 1952/* 1953 * wcstofflags -- 1954 * Take string of arguments and return file flags. This 1955 * version works a little differently than strtofflags(3). 1956 * In particular, it always tests every token, skipping any 1957 * unrecognized tokens. It returns a pointer to the first 1958 * unrecognized token, or NULL if every token was recognized. 1959 * This version is also const-correct and does not modify the 1960 * provided string. 1961 */ 1962static const wchar_t * 1963ae_wcstofflags(const wchar_t *s, unsigned long *setp, unsigned long *clrp) 1964{ 1965 const wchar_t *start, *end; 1966 const struct flag *flag; 1967 unsigned long set, clear; 1968 const wchar_t *failed; 1969 1970 set = clear = 0; 1971 start = s; 1972 failed = NULL; 1973 /* Find start of first token. */ 1974 while (*start == L'\t' || *start == L' ' || *start == L',') 1975 start++; 1976 while (*start != L'\0') { 1977 size_t length; 1978 /* Locate end of token. */ 1979 end = start; 1980 while (*end != L'\0' && *end != L'\t' && 1981 *end != L' ' && *end != L',') 1982 end++; 1983 length = end - start; 1984 for (flag = flags; flag->wname != NULL; flag++) { 1985 size_t flag_length = wcslen(flag->wname); 1986 if (length == flag_length 1987 && wmemcmp(start, flag->wname, length) == 0) { 1988 /* Matched "noXXXX", so reverse the sense. */ 1989 clear |= flag->set; 1990 set |= flag->clear; 1991 break; 1992 } else if (length == flag_length - 2 1993 && wmemcmp(start, flag->wname + 2, length) == 0) { 1994 /* Matched "XXXX", so don't reverse. */ 1995 set |= flag->set; 1996 clear |= flag->clear; 1997 break; 1998 } 1999 } 2000 /* Ignore unknown flag names. */ 2001 if (flag->wname == NULL && failed == NULL) 2002 failed = start; 2003 2004 /* Find start of next token. */ 2005 start = end; 2006 while (*start == L'\t' || *start == L' ' || *start == L',') 2007 start++; 2008 2009 } 2010 2011 if (setp) 2012 *setp = set; 2013 if (clrp) 2014 *clrp = clear; 2015 2016 /* Return location of first failure. */ 2017 return (failed); 2018} 2019 2020 2021#ifdef TEST 2022#include <stdio.h> 2023int 2024main(int argc, char **argv) 2025{ 2026 struct archive_entry *entry = archive_entry_new(); 2027 unsigned long set, clear; 2028 const wchar_t *remainder; 2029 2030 remainder = archive_entry_copy_fflags_text_w(entry, L"nosappnd dump archive,,,,,,,"); 2031 archive_entry_fflags(entry, &set, &clear); 2032 2033 wprintf(L"set=0x%lX clear=0x%lX remainder='%ls'\n", set, clear, remainder); 2034 2035 wprintf(L"new flags='%s'\n", archive_entry_fflags_text(entry)); 2036 return (0); 2037} 2038#endif 2039