archive_entry.c revision 316337
160484Sobrien/*- 2218822Sdim * Copyright (c) 2003-2007 Tim Kientzle 3218822Sdim * Copyright (c) 2016 Martin Matuska 460484Sobrien * All rights reserved. 560484Sobrien * 660484Sobrien * Redistribution and use in source and binary forms, with or without 7130561Sobrien * modification, are permitted provided that the following conditions 860484Sobrien * are met: 9130561Sobrien * 1. Redistributions of source code must retain the above copyright 10130561Sobrien * notice, this list of conditions and the following disclaimer. 11130561Sobrien * 2. Redistributions in binary form must reproduce the above copyright 12130561Sobrien * notice, this list of conditions and the following disclaimer in the 1360484Sobrien * documentation and/or other materials provided with the distribution. 14130561Sobrien * 15130561Sobrien * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR 16130561Sobrien * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17130561Sobrien * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 1860484Sobrien * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, 19130561Sobrien * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20130561Sobrien * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21218822Sdim * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2260484Sobrien * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2360484Sobrien * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24218822Sdim * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2560484Sobrien */ 26218822Sdim 2760484Sobrien#include "archive_platform.h" 28130561Sobrien__FBSDID("$FreeBSD: stable/11/contrib/libarchive/libarchive/archive_entry.c 316337 2017-03-31 20:16:24Z mm $"); 29218822Sdim 3060484Sobrien#ifdef HAVE_SYS_STAT_H 31104834Sobrien#include <sys/stat.h> 32218822Sdim#endif 33218822Sdim#ifdef HAVE_SYS_TYPES_H 3460484Sobrien#include <sys/types.h> 3560484Sobrien#endif 3660484Sobrien#if MAJOR_IN_MKDEV 3760484Sobrien#include <sys/mkdev.h> 38218822Sdim#define HAVE_MAJOR 3960484Sobrien#elif MAJOR_IN_SYSMACROS 4060484Sobrien#include <sys/sysmacros.h> 4160484Sobrien#define HAVE_MAJOR 4260484Sobrien#endif 4360484Sobrien#ifdef HAVE_ERRNO_H 4460484Sobrien#include <errno.h> 4560484Sobrien#endif 4660484Sobrien#ifdef HAVE_LIMITS_H 47218822Sdim#include <limits.h> 48218822Sdim#endif 49218822Sdim#ifdef HAVE_LINUX_FS_H 50218822Sdim#include <linux/fs.h> /* for Linux file flags */ 51218822Sdim#endif 52218822Sdim/* 53218822Sdim * Some Linux distributions have both linux/ext2_fs.h and ext2fs/ext2_fs.h. 54218822Sdim * As the include guards don't agree, the order of include is important. 55218822Sdim */ 56218822Sdim#ifdef HAVE_LINUX_EXT2_FS_H 57218822Sdim#include <linux/ext2_fs.h> /* for Linux file flags */ 58218822Sdim#endif 59218822Sdim#if defined(HAVE_EXT2FS_EXT2_FS_H) && !defined(__CYGWIN__) 60218822Sdim#include <ext2fs/ext2_fs.h> /* for Linux file flags */ 61218822Sdim#endif 62218822Sdim#include <stddef.h> 63218822Sdim#include <stdio.h> 64218822Sdim#ifdef HAVE_STDLIB_H 65218822Sdim#include <stdlib.h> 66218822Sdim#endif 67218822Sdim#ifdef HAVE_STRING_H 68218822Sdim#include <string.h> 69218822Sdim#endif 70218822Sdim#ifdef HAVE_WCHAR_H 71218822Sdim#include <wchar.h> 72218822Sdim#endif 73218822Sdim 74218822Sdim#include "archive.h" 75218822Sdim#include "archive_acl_private.h" 76218822Sdim#include "archive_entry.h" 77218822Sdim#include "archive_entry_locale.h" 78218822Sdim#include "archive_private.h" 79218822Sdim#include "archive_entry_private.h" 80218822Sdim 81218822Sdim#if !defined(HAVE_MAJOR) && !defined(major) 82218822Sdim/* Replacement for major/minor/makedev. */ 83218822Sdim#define major(x) ((int)(0x00ff & ((x) >> 8))) 84218822Sdim#define minor(x) ((int)(0xffff00ff & (x))) 85218822Sdim#define makedev(maj,min) ((0xff00 & ((maj)<<8)) | (0xffff00ff & (min))) 86218822Sdim#endif 87218822Sdim 88218822Sdim/* Play games to come up with a suitable makedev() definition. */ 89218822Sdim#ifdef __QNXNTO__ 90218822Sdim/* QNX. <sigh> */ 91218822Sdim#include <sys/netmgr.h> 92218822Sdim#define ae_makedev(maj, min) makedev(ND_LOCAL_NODE, (maj), (min)) 93218822Sdim#elif defined makedev 94218822Sdim/* There's a "makedev" macro. */ 95218822Sdim#define ae_makedev(maj, min) makedev((maj), (min)) 96218822Sdim#elif defined mkdev || ((defined _WIN32 || defined __WIN32__) && !defined(__CYGWIN__)) 97218822Sdim/* Windows. <sigh> */ 98218822Sdim#define ae_makedev(maj, min) mkdev((maj), (min)) 99218822Sdim#else 100218822Sdim/* There's a "makedev" function. */ 101218822Sdim#define ae_makedev(maj, min) makedev((maj), (min)) 102218822Sdim#endif 103218822Sdim 104218822Sdim/* 105218822Sdim * This adjustment is needed to support the following idiom for adding 106218822Sdim * 1000ns to the stored time: 107218822Sdim * archive_entry_set_atime(archive_entry_atime(), 108218822Sdim * archive_entry_atime_nsec() + 1000) 109218822Sdim * The additional if() here compensates for ambiguity in the C standard, 110218822Sdim * which permits two possible interpretations of a % b when a is negative. 111218822Sdim */ 112218822Sdim#define FIX_NS(t,ns) \ 113218822Sdim do { \ 114218822Sdim t += ns / 1000000000; \ 115218822Sdim ns %= 1000000000; \ 116218822Sdim if (ns < 0) { --t; ns += 1000000000; } \ 117218822Sdim } while (0) 118218822Sdim 119218822Sdimstatic char * ae_fflagstostr(unsigned long bitset, unsigned long bitclear); 120218822Sdimstatic const wchar_t *ae_wcstofflags(const wchar_t *stringp, 121218822Sdim unsigned long *setp, unsigned long *clrp); 122218822Sdimstatic const char *ae_strtofflags(const char *stringp, 123218822Sdim unsigned long *setp, unsigned long *clrp); 124218822Sdim 125218822Sdim#ifndef HAVE_WCSCPY 126218822Sdimstatic wchar_t * wcscpy(wchar_t *s1, const wchar_t *s2) 127218822Sdim{ 128218822Sdim wchar_t *dest = s1; 129218822Sdim while ((*s1 = *s2) != L'\0') 130218822Sdim ++s1, ++s2; 131218822Sdim return dest; 132218822Sdim} 133218822Sdim#endif 134218822Sdim#ifndef HAVE_WCSLEN 135218822Sdimstatic size_t wcslen(const wchar_t *s) 136218822Sdim{ 137218822Sdim const wchar_t *p = s; 138218822Sdim while (*p != L'\0') 139218822Sdim ++p; 140218822Sdim return p - s; 141218822Sdim} 142218822Sdim#endif 143218822Sdim#ifndef HAVE_WMEMCMP 144218822Sdim/* Good enough for simple equality testing, but not for sorting. */ 145218822Sdim#define wmemcmp(a,b,i) memcmp((a), (b), (i) * sizeof(wchar_t)) 146218822Sdim#endif 147218822Sdim 148218822Sdim/**************************************************************************** 149218822Sdim * 150218822Sdim * Public Interface 151218822Sdim * 152218822Sdim ****************************************************************************/ 153218822Sdim 154218822Sdimstruct archive_entry * 155218822Sdimarchive_entry_clear(struct archive_entry *entry) 156218822Sdim{ 157218822Sdim if (entry == NULL) 158218822Sdim return (NULL); 159218822Sdim archive_mstring_clean(&entry->ae_fflags_text); 160218822Sdim archive_mstring_clean(&entry->ae_gname); 161218822Sdim archive_mstring_clean(&entry->ae_hardlink); 162218822Sdim archive_mstring_clean(&entry->ae_pathname); 163218822Sdim archive_mstring_clean(&entry->ae_sourcepath); 164218822Sdim archive_mstring_clean(&entry->ae_symlink); 165218822Sdim archive_mstring_clean(&entry->ae_uname); 166218822Sdim archive_entry_copy_mac_metadata(entry, NULL, 0); 167218822Sdim archive_acl_clear(&entry->acl); 168218822Sdim archive_entry_xattr_clear(entry); 169218822Sdim archive_entry_sparse_clear(entry); 170218822Sdim free(entry->stat); 171218822Sdim memset(entry, 0, sizeof(*entry)); 172218822Sdim return entry; 173218822Sdim} 174218822Sdim 175218822Sdimstruct archive_entry * 176218822Sdimarchive_entry_clone(struct archive_entry *entry) 177218822Sdim{ 178218822Sdim struct archive_entry *entry2; 179218822Sdim struct ae_xattr *xp; 180218822Sdim struct ae_sparse *sp; 181218822Sdim size_t s; 182218822Sdim const void *p; 183218822Sdim 184218822Sdim /* Allocate new structure and copy over all of the fields. */ 185218822Sdim /* TODO: Should we copy the archive over? Or require a new archive 186218822Sdim * as an argument? */ 187218822Sdim entry2 = archive_entry_new2(entry->archive); 188218822Sdim if (entry2 == NULL) 189218822Sdim return (NULL); 190218822Sdim entry2->ae_stat = entry->ae_stat; 191218822Sdim entry2->ae_fflags_set = entry->ae_fflags_set; 192218822Sdim entry2->ae_fflags_clear = entry->ae_fflags_clear; 193218822Sdim 194218822Sdim /* TODO: XXX If clone can have a different archive, what do we do here if 195218822Sdim * character sets are different? XXX */ 196218822Sdim archive_mstring_copy(&entry2->ae_fflags_text, &entry->ae_fflags_text); 197218822Sdim archive_mstring_copy(&entry2->ae_gname, &entry->ae_gname); 198218822Sdim archive_mstring_copy(&entry2->ae_hardlink, &entry->ae_hardlink); 199218822Sdim archive_mstring_copy(&entry2->ae_pathname, &entry->ae_pathname); 200218822Sdim archive_mstring_copy(&entry2->ae_sourcepath, &entry->ae_sourcepath); 201218822Sdim archive_mstring_copy(&entry2->ae_symlink, &entry->ae_symlink); 202218822Sdim entry2->ae_set = entry->ae_set; 203218822Sdim archive_mstring_copy(&entry2->ae_uname, &entry->ae_uname); 204218822Sdim 205218822Sdim /* Copy encryption status */ 206218822Sdim entry2->encryption = entry->encryption; 207218822Sdim 208218822Sdim /* Copy ACL data over. */ 209218822Sdim archive_acl_copy(&entry2->acl, &entry->acl); 210218822Sdim 211218822Sdim /* Copy Mac OS metadata. */ 212218822Sdim p = archive_entry_mac_metadata(entry, &s); 213218822Sdim archive_entry_copy_mac_metadata(entry2, p, s); 214218822Sdim 215218822Sdim /* Copy xattr data over. */ 216218822Sdim xp = entry->xattr_head; 217218822Sdim while (xp != NULL) { 218218822Sdim archive_entry_xattr_add_entry(entry2, 219218822Sdim xp->name, xp->value, xp->size); 220218822Sdim xp = xp->next; 221218822Sdim } 222218822Sdim 223218822Sdim /* Copy sparse data over. */ 224218822Sdim sp = entry->sparse_head; 225218822Sdim while (sp != NULL) { 226218822Sdim archive_entry_sparse_add_entry(entry2, 227218822Sdim sp->offset, sp->length); 228218822Sdim sp = sp->next; 229218822Sdim } 230218822Sdim 231218822Sdim return (entry2); 232218822Sdim} 233218822Sdim 234218822Sdimvoid 235218822Sdimarchive_entry_free(struct archive_entry *entry) 236218822Sdim{ 237218822Sdim archive_entry_clear(entry); 238218822Sdim free(entry); 239218822Sdim} 240218822Sdim 241218822Sdimstruct archive_entry * 242218822Sdimarchive_entry_new(void) 243218822Sdim{ 244218822Sdim return archive_entry_new2(NULL); 245218822Sdim} 246218822Sdim 247218822Sdimstruct archive_entry * 248218822Sdimarchive_entry_new2(struct archive *a) 249218822Sdim{ 250218822Sdim struct archive_entry *entry; 251218822Sdim 252218822Sdim entry = (struct archive_entry *)calloc(1, sizeof(*entry)); 253218822Sdim if (entry == NULL) 254218822Sdim return (NULL); 255218822Sdim entry->archive = a; 256218822Sdim return (entry); 257218822Sdim} 258218822Sdim 259218822Sdim/* 260218822Sdim * Functions for reading fields from an archive_entry. 261218822Sdim */ 262218822Sdim 263218822Sdimtime_t 264218822Sdimarchive_entry_atime(struct archive_entry *entry) 265218822Sdim{ 266218822Sdim return (entry->ae_stat.aest_atime); 267218822Sdim} 268218822Sdim 269218822Sdimlong 270218822Sdimarchive_entry_atime_nsec(struct archive_entry *entry) 271218822Sdim{ 272218822Sdim return (entry->ae_stat.aest_atime_nsec); 273218822Sdim} 274218822Sdim 275218822Sdimint 276218822Sdimarchive_entry_atime_is_set(struct archive_entry *entry) 277218822Sdim{ 278218822Sdim return (entry->ae_set & AE_SET_ATIME); 279218822Sdim} 280218822Sdim 281218822Sdimtime_t 282218822Sdimarchive_entry_birthtime(struct archive_entry *entry) 283218822Sdim{ 284218822Sdim return (entry->ae_stat.aest_birthtime); 285218822Sdim} 286218822Sdim 287218822Sdimlong 288218822Sdimarchive_entry_birthtime_nsec(struct archive_entry *entry) 289218822Sdim{ 290218822Sdim return (entry->ae_stat.aest_birthtime_nsec); 291218822Sdim} 292218822Sdim 293218822Sdimint 294218822Sdimarchive_entry_birthtime_is_set(struct archive_entry *entry) 295218822Sdim{ 296218822Sdim return (entry->ae_set & AE_SET_BIRTHTIME); 297218822Sdim} 298218822Sdim 299218822Sdimtime_t 300218822Sdimarchive_entry_ctime(struct archive_entry *entry) 301218822Sdim{ 302218822Sdim return (entry->ae_stat.aest_ctime); 303218822Sdim} 304218822Sdim 305218822Sdimint 306218822Sdimarchive_entry_ctime_is_set(struct archive_entry *entry) 307218822Sdim{ 308218822Sdim return (entry->ae_set & AE_SET_CTIME); 309218822Sdim} 310218822Sdim 311218822Sdimlong 312218822Sdimarchive_entry_ctime_nsec(struct archive_entry *entry) 313218822Sdim{ 314218822Sdim return (entry->ae_stat.aest_ctime_nsec); 315218822Sdim} 316218822Sdim 317218822Sdimdev_t 318218822Sdimarchive_entry_dev(struct archive_entry *entry) 319218822Sdim{ 320218822Sdim if (entry->ae_stat.aest_dev_is_broken_down) 321218822Sdim return ae_makedev(entry->ae_stat.aest_devmajor, 322218822Sdim entry->ae_stat.aest_devminor); 323218822Sdim else 324218822Sdim return (entry->ae_stat.aest_dev); 325218822Sdim} 326218822Sdim 327218822Sdimint 328218822Sdimarchive_entry_dev_is_set(struct archive_entry *entry) 329218822Sdim{ 330218822Sdim return (entry->ae_set & AE_SET_DEV); 331218822Sdim} 332218822Sdim 333218822Sdimdev_t 334218822Sdimarchive_entry_devmajor(struct archive_entry *entry) 335218822Sdim{ 336218822Sdim if (entry->ae_stat.aest_dev_is_broken_down) 337218822Sdim return (entry->ae_stat.aest_devmajor); 338218822Sdim else 339218822Sdim return major(entry->ae_stat.aest_dev); 340218822Sdim} 341218822Sdim 342218822Sdimdev_t 343218822Sdimarchive_entry_devminor(struct archive_entry *entry) 344218822Sdim{ 345218822Sdim if (entry->ae_stat.aest_dev_is_broken_down) 346218822Sdim return (entry->ae_stat.aest_devminor); 347218822Sdim else 348218822Sdim return minor(entry->ae_stat.aest_dev); 349218822Sdim} 350218822Sdim 351218822Sdimmode_t 352218822Sdimarchive_entry_filetype(struct archive_entry *entry) 353218822Sdim{ 354218822Sdim return (AE_IFMT & entry->acl.mode); 355218822Sdim} 356218822Sdim 357218822Sdimvoid 358218822Sdimarchive_entry_fflags(struct archive_entry *entry, 359218822Sdim unsigned long *set, unsigned long *clear) 360218822Sdim{ 361218822Sdim *set = entry->ae_fflags_set; 362218822Sdim *clear = entry->ae_fflags_clear; 363218822Sdim} 364218822Sdim 365218822Sdim/* 366218822Sdim * Note: if text was provided, this just returns that text. If you 367218822Sdim * really need the text to be rebuilt in a canonical form, set the 368218822Sdim * text, ask for the bitmaps, then set the bitmaps. (Setting the 369218822Sdim * bitmaps clears any stored text.) This design is deliberate: if 370218822Sdim * we're editing archives, we don't want to discard flags just because 371218822Sdim * they aren't supported on the current system. The bitmap<->text 372218822Sdim * conversions are platform-specific (see below). 373218822Sdim */ 374218822Sdimconst char * 375218822Sdimarchive_entry_fflags_text(struct archive_entry *entry) 376218822Sdim{ 377218822Sdim const char *f; 378218822Sdim char *p; 379218822Sdim 380218822Sdim if (archive_mstring_get_mbs(entry->archive, 381218822Sdim &entry->ae_fflags_text, &f) == 0) { 382218822Sdim if (f != NULL) 383218822Sdim return (f); 384218822Sdim } else if (errno == ENOMEM) 385218822Sdim __archive_errx(1, "No memory"); 386218822Sdim 387218822Sdim if (entry->ae_fflags_set == 0 && entry->ae_fflags_clear == 0) 388218822Sdim return (NULL); 389218822Sdim 390218822Sdim p = ae_fflagstostr(entry->ae_fflags_set, entry->ae_fflags_clear); 391218822Sdim if (p == NULL) 392218822Sdim return (NULL); 393218822Sdim 394218822Sdim archive_mstring_copy_mbs(&entry->ae_fflags_text, p); 395218822Sdim free(p); 396218822Sdim if (archive_mstring_get_mbs(entry->archive, 397218822Sdim &entry->ae_fflags_text, &f) == 0) 398218822Sdim return (f); 399218822Sdim if (errno == ENOMEM) 400218822Sdim __archive_errx(1, "No memory"); 401218822Sdim return (NULL); 402218822Sdim} 403218822Sdim 404218822Sdimla_int64_t 405218822Sdimarchive_entry_gid(struct archive_entry *entry) 406218822Sdim{ 407218822Sdim return (entry->ae_stat.aest_gid); 408218822Sdim} 409218822Sdim 410218822Sdimconst char * 411218822Sdimarchive_entry_gname(struct archive_entry *entry) 412218822Sdim{ 413218822Sdim const char *p; 414218822Sdim if (archive_mstring_get_mbs(entry->archive, &entry->ae_gname, &p) == 0) 415218822Sdim return (p); 416218822Sdim if (errno == ENOMEM) 417218822Sdim __archive_errx(1, "No memory"); 418218822Sdim return (NULL); 419218822Sdim} 420218822Sdim 421218822Sdimconst char * 422218822Sdimarchive_entry_gname_utf8(struct archive_entry *entry) 423218822Sdim{ 424218822Sdim const char *p; 425218822Sdim if (archive_mstring_get_utf8(entry->archive, &entry->ae_gname, &p) == 0) 426218822Sdim return (p); 427218822Sdim if (errno == ENOMEM) 428218822Sdim __archive_errx(1, "No memory"); 429218822Sdim return (NULL); 430218822Sdim} 431218822Sdim 432218822Sdim 433218822Sdimconst wchar_t * 434218822Sdimarchive_entry_gname_w(struct archive_entry *entry) 435218822Sdim{ 436218822Sdim const wchar_t *p; 437218822Sdim if (archive_mstring_get_wcs(entry->archive, &entry->ae_gname, &p) == 0) 438218822Sdim return (p); 439218822Sdim if (errno == ENOMEM) 440218822Sdim __archive_errx(1, "No memory"); 441218822Sdim return (NULL); 442218822Sdim} 443218822Sdim 444218822Sdimint 445218822Sdim_archive_entry_gname_l(struct archive_entry *entry, 446218822Sdim const char **p, size_t *len, struct archive_string_conv *sc) 447218822Sdim{ 448218822Sdim return (archive_mstring_get_mbs_l(&entry->ae_gname, p, len, sc)); 449218822Sdim} 450218822Sdim 451218822Sdimconst char * 452218822Sdimarchive_entry_hardlink(struct archive_entry *entry) 453218822Sdim{ 454218822Sdim const char *p; 455218822Sdim if ((entry->ae_set & AE_SET_HARDLINK) == 0) 456218822Sdim return (NULL); 457218822Sdim if (archive_mstring_get_mbs( 458218822Sdim entry->archive, &entry->ae_hardlink, &p) == 0) 459218822Sdim return (p); 460218822Sdim if (errno == ENOMEM) 461218822Sdim __archive_errx(1, "No memory"); 462218822Sdim return (NULL); 463218822Sdim} 464218822Sdim 465218822Sdimconst char * 466218822Sdimarchive_entry_hardlink_utf8(struct archive_entry *entry) 467218822Sdim{ 468218822Sdim const char *p; 469218822Sdim if ((entry->ae_set & AE_SET_HARDLINK) == 0) 470218822Sdim return (NULL); 471218822Sdim if (archive_mstring_get_utf8( 472218822Sdim entry->archive, &entry->ae_hardlink, &p) == 0) 473218822Sdim return (p); 474218822Sdim if (errno == ENOMEM) 475218822Sdim __archive_errx(1, "No memory"); 476218822Sdim return (NULL); 477218822Sdim} 478218822Sdim 479218822Sdimconst wchar_t * 480218822Sdimarchive_entry_hardlink_w(struct archive_entry *entry) 481218822Sdim{ 482218822Sdim const wchar_t *p; 483218822Sdim if ((entry->ae_set & AE_SET_HARDLINK) == 0) 484218822Sdim return (NULL); 485218822Sdim if (archive_mstring_get_wcs( 486218822Sdim entry->archive, &entry->ae_hardlink, &p) == 0) 487218822Sdim return (p); 488218822Sdim if (errno == ENOMEM) 489218822Sdim __archive_errx(1, "No memory"); 490218822Sdim return (NULL); 491218822Sdim} 492218822Sdim 493218822Sdimint 494218822Sdim_archive_entry_hardlink_l(struct archive_entry *entry, 495218822Sdim const char **p, size_t *len, struct archive_string_conv *sc) 496218822Sdim{ 497218822Sdim if ((entry->ae_set & AE_SET_HARDLINK) == 0) { 498218822Sdim *p = NULL; 499218822Sdim *len = 0; 500218822Sdim return (0); 501218822Sdim } 502218822Sdim return (archive_mstring_get_mbs_l(&entry->ae_hardlink, p, len, sc)); 503218822Sdim} 504218822Sdim 505218822Sdimla_int64_t 506218822Sdimarchive_entry_ino(struct archive_entry *entry) 507218822Sdim{ 508218822Sdim return (entry->ae_stat.aest_ino); 509218822Sdim} 510218822Sdim 511218822Sdimint 512218822Sdimarchive_entry_ino_is_set(struct archive_entry *entry) 513218822Sdim{ 514218822Sdim return (entry->ae_set & AE_SET_INO); 515218822Sdim} 516218822Sdim 517218822Sdimla_int64_t 518218822Sdimarchive_entry_ino64(struct archive_entry *entry) 519218822Sdim{ 520218822Sdim return (entry->ae_stat.aest_ino); 521218822Sdim} 522218822Sdim 523218822Sdimmode_t 524218822Sdimarchive_entry_mode(struct archive_entry *entry) 525218822Sdim{ 526218822Sdim return (entry->acl.mode); 527218822Sdim} 528218822Sdim 529218822Sdimtime_t 530218822Sdimarchive_entry_mtime(struct archive_entry *entry) 531218822Sdim{ 532218822Sdim return (entry->ae_stat.aest_mtime); 533218822Sdim} 534218822Sdim 535218822Sdimlong 536218822Sdimarchive_entry_mtime_nsec(struct archive_entry *entry) 537218822Sdim{ 538218822Sdim return (entry->ae_stat.aest_mtime_nsec); 539218822Sdim} 540218822Sdim 541218822Sdimint 542218822Sdimarchive_entry_mtime_is_set(struct archive_entry *entry) 543218822Sdim{ 544218822Sdim return (entry->ae_set & AE_SET_MTIME); 545218822Sdim} 546218822Sdim 547218822Sdimunsigned int 548218822Sdimarchive_entry_nlink(struct archive_entry *entry) 549218822Sdim{ 550218822Sdim return (entry->ae_stat.aest_nlink); 551218822Sdim} 552218822Sdim 553218822Sdimconst char * 554218822Sdimarchive_entry_pathname(struct archive_entry *entry) 555218822Sdim{ 556218822Sdim const char *p; 557218822Sdim if (archive_mstring_get_mbs( 558218822Sdim entry->archive, &entry->ae_pathname, &p) == 0) 559218822Sdim return (p); 560218822Sdim if (errno == ENOMEM) 561218822Sdim __archive_errx(1, "No memory"); 562218822Sdim return (NULL); 563218822Sdim} 564218822Sdim 565218822Sdimconst char * 566218822Sdimarchive_entry_pathname_utf8(struct archive_entry *entry) 567218822Sdim{ 568218822Sdim const char *p; 569218822Sdim if (archive_mstring_get_utf8( 570218822Sdim entry->archive, &entry->ae_pathname, &p) == 0) 571218822Sdim return (p); 572218822Sdim if (errno == ENOMEM) 573218822Sdim __archive_errx(1, "No memory"); 574218822Sdim return (NULL); 575218822Sdim} 576218822Sdim 577218822Sdimconst wchar_t * 578218822Sdimarchive_entry_pathname_w(struct archive_entry *entry) 579218822Sdim{ 580218822Sdim const wchar_t *p; 581218822Sdim if (archive_mstring_get_wcs( 582218822Sdim entry->archive, &entry->ae_pathname, &p) == 0) 583218822Sdim return (p); 584218822Sdim if (errno == ENOMEM) 585218822Sdim __archive_errx(1, "No memory"); 586218822Sdim return (NULL); 587218822Sdim} 588218822Sdim 589218822Sdimint 590218822Sdim_archive_entry_pathname_l(struct archive_entry *entry, 591218822Sdim const char **p, size_t *len, struct archive_string_conv *sc) 592218822Sdim{ 593218822Sdim return (archive_mstring_get_mbs_l(&entry->ae_pathname, p, len, sc)); 594218822Sdim} 595218822Sdim 596218822Sdimmode_t 597218822Sdimarchive_entry_perm(struct archive_entry *entry) 598218822Sdim{ 599218822Sdim return (~AE_IFMT & entry->acl.mode); 600218822Sdim} 601218822Sdim 602218822Sdimdev_t 603218822Sdimarchive_entry_rdev(struct archive_entry *entry) 604218822Sdim{ 605218822Sdim if (entry->ae_stat.aest_rdev_is_broken_down) 606218822Sdim return ae_makedev(entry->ae_stat.aest_rdevmajor, 607218822Sdim entry->ae_stat.aest_rdevminor); 608218822Sdim else 609218822Sdim return (entry->ae_stat.aest_rdev); 610218822Sdim} 611218822Sdim 612218822Sdimdev_t 613218822Sdimarchive_entry_rdevmajor(struct archive_entry *entry) 614218822Sdim{ 615218822Sdim if (entry->ae_stat.aest_rdev_is_broken_down) 616218822Sdim return (entry->ae_stat.aest_rdevmajor); 617218822Sdim else 618218822Sdim return major(entry->ae_stat.aest_rdev); 619218822Sdim} 620218822Sdim 621218822Sdimdev_t 622218822Sdimarchive_entry_rdevminor(struct archive_entry *entry) 623218822Sdim{ 624218822Sdim if (entry->ae_stat.aest_rdev_is_broken_down) 625218822Sdim return (entry->ae_stat.aest_rdevminor); 626218822Sdim else 627218822Sdim return minor(entry->ae_stat.aest_rdev); 628218822Sdim} 629218822Sdim 630218822Sdimla_int64_t 631218822Sdimarchive_entry_size(struct archive_entry *entry) 632218822Sdim{ 633218822Sdim return (entry->ae_stat.aest_size); 634218822Sdim} 635218822Sdim 636218822Sdimint 637218822Sdimarchive_entry_size_is_set(struct archive_entry *entry) 638218822Sdim{ 639218822Sdim return (entry->ae_set & AE_SET_SIZE); 640218822Sdim} 641218822Sdim 642218822Sdimconst char * 643218822Sdimarchive_entry_sourcepath(struct archive_entry *entry) 644218822Sdim{ 645218822Sdim const char *p; 646218822Sdim if (archive_mstring_get_mbs( 647218822Sdim entry->archive, &entry->ae_sourcepath, &p) == 0) 648218822Sdim return (p); 649218822Sdim if (errno == ENOMEM) 650218822Sdim __archive_errx(1, "No memory"); 651218822Sdim return (NULL); 652218822Sdim} 653218822Sdim 654218822Sdimconst wchar_t * 655218822Sdimarchive_entry_sourcepath_w(struct archive_entry *entry) 656218822Sdim{ 657218822Sdim const wchar_t *p; 658218822Sdim if (archive_mstring_get_wcs( 659218822Sdim entry->archive, &entry->ae_sourcepath, &p) == 0) 660218822Sdim return (p); 661218822Sdim return (NULL); 662218822Sdim} 663218822Sdim 664218822Sdimconst char * 665218822Sdimarchive_entry_symlink(struct archive_entry *entry) 666218822Sdim{ 667218822Sdim const char *p; 668218822Sdim if ((entry->ae_set & AE_SET_SYMLINK) == 0) 669218822Sdim return (NULL); 670218822Sdim if (archive_mstring_get_mbs( 671218822Sdim entry->archive, &entry->ae_symlink, &p) == 0) 672218822Sdim return (p); 673218822Sdim if (errno == ENOMEM) 674218822Sdim __archive_errx(1, "No memory"); 675218822Sdim return (NULL); 676218822Sdim} 677218822Sdim 678218822Sdimconst char * 679218822Sdimarchive_entry_symlink_utf8(struct archive_entry *entry) 680218822Sdim{ 681218822Sdim const char *p; 682218822Sdim if ((entry->ae_set & AE_SET_SYMLINK) == 0) 683218822Sdim return (NULL); 684218822Sdim if (archive_mstring_get_utf8( 685218822Sdim entry->archive, &entry->ae_symlink, &p) == 0) 686218822Sdim return (p); 687218822Sdim if (errno == ENOMEM) 688218822Sdim __archive_errx(1, "No memory"); 689218822Sdim return (NULL); 690218822Sdim} 691218822Sdim 692218822Sdimconst wchar_t * 693218822Sdimarchive_entry_symlink_w(struct archive_entry *entry) 694218822Sdim{ 695218822Sdim const wchar_t *p; 696218822Sdim if ((entry->ae_set & AE_SET_SYMLINK) == 0) 697218822Sdim return (NULL); 698218822Sdim if (archive_mstring_get_wcs( 699218822Sdim entry->archive, &entry->ae_symlink, &p) == 0) 700218822Sdim return (p); 701218822Sdim if (errno == ENOMEM) 702218822Sdim __archive_errx(1, "No memory"); 703218822Sdim return (NULL); 704218822Sdim} 705218822Sdim 706218822Sdimint 707218822Sdim_archive_entry_symlink_l(struct archive_entry *entry, 708218822Sdim const char **p, size_t *len, struct archive_string_conv *sc) 709218822Sdim{ 710218822Sdim if ((entry->ae_set & AE_SET_SYMLINK) == 0) { 711218822Sdim *p = NULL; 712218822Sdim *len = 0; 713218822Sdim return (0); 714218822Sdim } 715218822Sdim return (archive_mstring_get_mbs_l( &entry->ae_symlink, p, len, sc)); 716218822Sdim} 717218822Sdim 718218822Sdimla_int64_t 719218822Sdimarchive_entry_uid(struct archive_entry *entry) 720218822Sdim{ 721218822Sdim return (entry->ae_stat.aest_uid); 722218822Sdim} 723218822Sdim 724218822Sdimconst char * 725218822Sdimarchive_entry_uname(struct archive_entry *entry) 726218822Sdim{ 727218822Sdim const char *p; 728218822Sdim if (archive_mstring_get_mbs(entry->archive, &entry->ae_uname, &p) == 0) 729218822Sdim return (p); 730218822Sdim if (errno == ENOMEM) 731218822Sdim __archive_errx(1, "No memory"); 732218822Sdim return (NULL); 733218822Sdim} 734218822Sdim 735218822Sdimconst char * 736218822Sdimarchive_entry_uname_utf8(struct archive_entry *entry) 737218822Sdim{ 738218822Sdim const char *p; 739218822Sdim if (archive_mstring_get_utf8(entry->archive, &entry->ae_uname, &p) == 0) 740218822Sdim return (p); 741218822Sdim if (errno == ENOMEM) 742218822Sdim __archive_errx(1, "No memory"); 743218822Sdim return (NULL); 744218822Sdim} 745218822Sdim 746218822Sdimconst wchar_t * 747218822Sdimarchive_entry_uname_w(struct archive_entry *entry) 748218822Sdim{ 749218822Sdim const wchar_t *p; 750218822Sdim if (archive_mstring_get_wcs(entry->archive, &entry->ae_uname, &p) == 0) 751218822Sdim return (p); 752218822Sdim if (errno == ENOMEM) 753218822Sdim __archive_errx(1, "No memory"); 754218822Sdim return (NULL); 755218822Sdim} 756218822Sdim 757218822Sdimint 758218822Sdim_archive_entry_uname_l(struct archive_entry *entry, 759218822Sdim const char **p, size_t *len, struct archive_string_conv *sc) 760218822Sdim{ 761218822Sdim return (archive_mstring_get_mbs_l(&entry->ae_uname, p, len, sc)); 762218822Sdim} 763218822Sdim 764218822Sdimint 765218822Sdimarchive_entry_is_data_encrypted(struct archive_entry *entry) 766218822Sdim{ 767218822Sdim return ((entry->encryption & AE_ENCRYPTION_DATA) == AE_ENCRYPTION_DATA); 768218822Sdim} 769218822Sdim 770218822Sdimint 771218822Sdimarchive_entry_is_metadata_encrypted(struct archive_entry *entry) 772218822Sdim{ 773218822Sdim return ((entry->encryption & AE_ENCRYPTION_METADATA) == AE_ENCRYPTION_METADATA); 774218822Sdim} 775218822Sdim 776218822Sdimint 777218822Sdimarchive_entry_is_encrypted(struct archive_entry *entry) 778218822Sdim{ 779218822Sdim return (entry->encryption & (AE_ENCRYPTION_DATA|AE_ENCRYPTION_METADATA)); 780218822Sdim} 781218822Sdim 782218822Sdim/* 783218822Sdim * Functions to set archive_entry properties. 784218822Sdim */ 785218822Sdim 786218822Sdimvoid 787218822Sdimarchive_entry_set_filetype(struct archive_entry *entry, unsigned int type) 788218822Sdim{ 789218822Sdim entry->stat_valid = 0; 790218822Sdim entry->acl.mode &= ~AE_IFMT; 791218822Sdim entry->acl.mode |= AE_IFMT & type; 792218822Sdim} 793218822Sdim 794218822Sdimvoid 795218822Sdimarchive_entry_set_fflags(struct archive_entry *entry, 796218822Sdim unsigned long set, unsigned long clear) 797218822Sdim{ 798218822Sdim archive_mstring_clean(&entry->ae_fflags_text); 799218822Sdim entry->ae_fflags_set = set; 800218822Sdim entry->ae_fflags_clear = clear; 801218822Sdim} 802218822Sdim 803218822Sdimconst char * 804218822Sdimarchive_entry_copy_fflags_text(struct archive_entry *entry, 805218822Sdim const char *flags) 806218822Sdim{ 807218822Sdim archive_mstring_copy_mbs(&entry->ae_fflags_text, flags); 808218822Sdim return (ae_strtofflags(flags, 809218822Sdim &entry->ae_fflags_set, &entry->ae_fflags_clear)); 810218822Sdim} 811218822Sdim 812218822Sdimconst wchar_t * 813218822Sdimarchive_entry_copy_fflags_text_w(struct archive_entry *entry, 814218822Sdim const wchar_t *flags) 815218822Sdim{ 816218822Sdim archive_mstring_copy_wcs(&entry->ae_fflags_text, flags); 817218822Sdim return (ae_wcstofflags(flags, 818218822Sdim &entry->ae_fflags_set, &entry->ae_fflags_clear)); 819218822Sdim} 820218822Sdim 821218822Sdimvoid 822218822Sdimarchive_entry_set_gid(struct archive_entry *entry, la_int64_t g) 823218822Sdim{ 824218822Sdim entry->stat_valid = 0; 825218822Sdim entry->ae_stat.aest_gid = g; 826218822Sdim} 827218822Sdim 828218822Sdimvoid 829218822Sdimarchive_entry_set_gname(struct archive_entry *entry, const char *name) 830218822Sdim{ 831218822Sdim archive_mstring_copy_mbs(&entry->ae_gname, name); 832218822Sdim} 833218822Sdim 834218822Sdimvoid 835218822Sdimarchive_entry_set_gname_utf8(struct archive_entry *entry, const char *name) 836218822Sdim{ 837218822Sdim archive_mstring_copy_utf8(&entry->ae_gname, name); 838218822Sdim} 839218822Sdim 840218822Sdimvoid 841218822Sdimarchive_entry_copy_gname(struct archive_entry *entry, const char *name) 842218822Sdim{ 843218822Sdim archive_mstring_copy_mbs(&entry->ae_gname, name); 844218822Sdim} 845218822Sdim 846218822Sdimvoid 847218822Sdimarchive_entry_copy_gname_w(struct archive_entry *entry, const wchar_t *name) 848218822Sdim{ 849218822Sdim archive_mstring_copy_wcs(&entry->ae_gname, name); 850218822Sdim} 851218822Sdim 852218822Sdimint 853218822Sdimarchive_entry_update_gname_utf8(struct archive_entry *entry, const char *name) 854218822Sdim{ 855218822Sdim if (archive_mstring_update_utf8(entry->archive, 856218822Sdim &entry->ae_gname, name) == 0) 857218822Sdim return (1); 858218822Sdim if (errno == ENOMEM) 859218822Sdim __archive_errx(1, "No memory"); 860218822Sdim return (0); 861218822Sdim} 862218822Sdim 863218822Sdimint 864218822Sdim_archive_entry_copy_gname_l(struct archive_entry *entry, 865218822Sdim const char *name, size_t len, struct archive_string_conv *sc) 866218822Sdim{ 867218822Sdim return (archive_mstring_copy_mbs_len_l(&entry->ae_gname, name, len, sc)); 868218822Sdim} 869218822Sdim 870218822Sdimvoid 871218822Sdimarchive_entry_set_ino(struct archive_entry *entry, la_int64_t ino) 872218822Sdim{ 873218822Sdim entry->stat_valid = 0; 874218822Sdim entry->ae_set |= AE_SET_INO; 875218822Sdim entry->ae_stat.aest_ino = ino; 876218822Sdim} 877218822Sdim 878218822Sdimvoid 879218822Sdimarchive_entry_set_ino64(struct archive_entry *entry, la_int64_t ino) 880218822Sdim{ 881218822Sdim entry->stat_valid = 0; 882218822Sdim entry->ae_set |= AE_SET_INO; 883218822Sdim entry->ae_stat.aest_ino = ino; 884218822Sdim} 885218822Sdim 886218822Sdimvoid 887218822Sdimarchive_entry_set_hardlink(struct archive_entry *entry, const char *target) 888218822Sdim{ 889218822Sdim archive_mstring_copy_mbs(&entry->ae_hardlink, target); 890218822Sdim if (target != NULL) 891218822Sdim entry->ae_set |= AE_SET_HARDLINK; 892218822Sdim else 893218822Sdim entry->ae_set &= ~AE_SET_HARDLINK; 894218822Sdim} 895218822Sdim 896218822Sdimvoid 897218822Sdimarchive_entry_set_hardlink_utf8(struct archive_entry *entry, const char *target) 898218822Sdim{ 899218822Sdim archive_mstring_copy_utf8(&entry->ae_hardlink, target); 900218822Sdim if (target != NULL) 901218822Sdim entry->ae_set |= AE_SET_HARDLINK; 902218822Sdim else 903218822Sdim entry->ae_set &= ~AE_SET_HARDLINK; 904218822Sdim} 905218822Sdim 906218822Sdimvoid 907218822Sdimarchive_entry_copy_hardlink(struct archive_entry *entry, const char *target) 908218822Sdim{ 909218822Sdim archive_mstring_copy_mbs(&entry->ae_hardlink, target); 910218822Sdim if (target != NULL) 911218822Sdim entry->ae_set |= AE_SET_HARDLINK; 912218822Sdim else 913218822Sdim entry->ae_set &= ~AE_SET_HARDLINK; 914218822Sdim} 915218822Sdim 916218822Sdimvoid 917218822Sdimarchive_entry_copy_hardlink_w(struct archive_entry *entry, const wchar_t *target) 918218822Sdim{ 919218822Sdim archive_mstring_copy_wcs(&entry->ae_hardlink, target); 920218822Sdim if (target != NULL) 921218822Sdim entry->ae_set |= AE_SET_HARDLINK; 922218822Sdim else 923218822Sdim entry->ae_set &= ~AE_SET_HARDLINK; 924218822Sdim} 925218822Sdim 926218822Sdimint 927218822Sdimarchive_entry_update_hardlink_utf8(struct archive_entry *entry, const char *target) 928218822Sdim{ 929218822Sdim if (target != NULL) 930218822Sdim entry->ae_set |= AE_SET_HARDLINK; 931218822Sdim else 932218822Sdim entry->ae_set &= ~AE_SET_HARDLINK; 933218822Sdim if (archive_mstring_update_utf8(entry->archive, 934218822Sdim &entry->ae_hardlink, target) == 0) 935218822Sdim return (1); 936218822Sdim if (errno == ENOMEM) 937218822Sdim __archive_errx(1, "No memory"); 938218822Sdim return (0); 939218822Sdim} 940218822Sdim 941218822Sdimint 942218822Sdim_archive_entry_copy_hardlink_l(struct archive_entry *entry, 943218822Sdim const char *target, size_t len, struct archive_string_conv *sc) 944218822Sdim{ 945218822Sdim int r; 946218822Sdim 947218822Sdim r = archive_mstring_copy_mbs_len_l(&entry->ae_hardlink, 948218822Sdim target, len, sc); 949218822Sdim if (target != NULL && r == 0) 950218822Sdim entry->ae_set |= AE_SET_HARDLINK; 951218822Sdim else 952218822Sdim entry->ae_set &= ~AE_SET_HARDLINK; 953218822Sdim return (r); 954218822Sdim} 955218822Sdim 956218822Sdimvoid 957218822Sdimarchive_entry_set_atime(struct archive_entry *entry, time_t t, long ns) 958218822Sdim{ 959218822Sdim FIX_NS(t, ns); 960218822Sdim entry->stat_valid = 0; 961218822Sdim entry->ae_set |= AE_SET_ATIME; 962218822Sdim entry->ae_stat.aest_atime = t; 963218822Sdim entry->ae_stat.aest_atime_nsec = ns; 964218822Sdim} 965218822Sdim 966218822Sdimvoid 967218822Sdimarchive_entry_unset_atime(struct archive_entry *entry) 968218822Sdim{ 969218822Sdim archive_entry_set_atime(entry, 0, 0); 970218822Sdim entry->ae_set &= ~AE_SET_ATIME; 971218822Sdim} 972218822Sdim 973218822Sdimvoid 974218822Sdimarchive_entry_set_birthtime(struct archive_entry *entry, time_t t, long ns) 975218822Sdim{ 976218822Sdim FIX_NS(t, ns); 977218822Sdim entry->stat_valid = 0; 978218822Sdim entry->ae_set |= AE_SET_BIRTHTIME; 979218822Sdim entry->ae_stat.aest_birthtime = t; 980218822Sdim entry->ae_stat.aest_birthtime_nsec = ns; 981218822Sdim} 982218822Sdim 983218822Sdimvoid 984218822Sdimarchive_entry_unset_birthtime(struct archive_entry *entry) 985218822Sdim{ 986218822Sdim archive_entry_set_birthtime(entry, 0, 0); 987218822Sdim entry->ae_set &= ~AE_SET_BIRTHTIME; 988218822Sdim} 989218822Sdim 990218822Sdimvoid 991218822Sdimarchive_entry_set_ctime(struct archive_entry *entry, time_t t, long ns) 992218822Sdim{ 993218822Sdim FIX_NS(t, ns); 994218822Sdim entry->stat_valid = 0; 995218822Sdim entry->ae_set |= AE_SET_CTIME; 996218822Sdim entry->ae_stat.aest_ctime = t; 997218822Sdim entry->ae_stat.aest_ctime_nsec = ns; 998218822Sdim} 999218822Sdim 1000218822Sdimvoid 1001218822Sdimarchive_entry_unset_ctime(struct archive_entry *entry) 1002218822Sdim{ 1003218822Sdim archive_entry_set_ctime(entry, 0, 0); 1004218822Sdim entry->ae_set &= ~AE_SET_CTIME; 1005218822Sdim} 1006218822Sdim 1007218822Sdimvoid 1008218822Sdimarchive_entry_set_dev(struct archive_entry *entry, dev_t d) 1009218822Sdim{ 1010218822Sdim entry->stat_valid = 0; 1011218822Sdim entry->ae_set |= AE_SET_DEV; 1012218822Sdim entry->ae_stat.aest_dev_is_broken_down = 0; 1013218822Sdim entry->ae_stat.aest_dev = d; 1014218822Sdim} 1015218822Sdim 1016218822Sdimvoid 1017218822Sdimarchive_entry_set_devmajor(struct archive_entry *entry, dev_t m) 1018218822Sdim{ 1019218822Sdim entry->stat_valid = 0; 1020218822Sdim entry->ae_set |= AE_SET_DEV; 1021218822Sdim entry->ae_stat.aest_dev_is_broken_down = 1; 1022218822Sdim entry->ae_stat.aest_devmajor = m; 1023218822Sdim} 1024218822Sdim 1025218822Sdimvoid 1026218822Sdimarchive_entry_set_devminor(struct archive_entry *entry, dev_t m) 1027218822Sdim{ 1028218822Sdim entry->stat_valid = 0; 1029218822Sdim entry->ae_set |= AE_SET_DEV; 1030218822Sdim entry->ae_stat.aest_dev_is_broken_down = 1; 1031218822Sdim entry->ae_stat.aest_devminor = m; 1032218822Sdim} 1033218822Sdim 1034218822Sdim/* Set symlink if symlink is already set, else set hardlink. */ 1035218822Sdimvoid 1036218822Sdimarchive_entry_set_link(struct archive_entry *entry, const char *target) 1037218822Sdim{ 1038218822Sdim if (entry->ae_set & AE_SET_SYMLINK) 1039218822Sdim archive_mstring_copy_mbs(&entry->ae_symlink, target); 1040218822Sdim else 1041218822Sdim archive_mstring_copy_mbs(&entry->ae_hardlink, target); 1042218822Sdim} 1043218822Sdim 1044218822Sdimvoid 1045218822Sdimarchive_entry_set_link_utf8(struct archive_entry *entry, const char *target) 1046218822Sdim{ 1047218822Sdim if (entry->ae_set & AE_SET_SYMLINK) 1048218822Sdim archive_mstring_copy_utf8(&entry->ae_symlink, target); 1049218822Sdim else 1050218822Sdim archive_mstring_copy_utf8(&entry->ae_hardlink, target); 1051218822Sdim} 1052218822Sdim 1053218822Sdim/* Set symlink if symlink is already set, else set hardlink. */ 1054218822Sdimvoid 1055218822Sdimarchive_entry_copy_link(struct archive_entry *entry, const char *target) 1056218822Sdim{ 1057218822Sdim if (entry->ae_set & AE_SET_SYMLINK) 1058218822Sdim archive_mstring_copy_mbs(&entry->ae_symlink, target); 1059218822Sdim else 1060218822Sdim archive_mstring_copy_mbs(&entry->ae_hardlink, target); 1061218822Sdim} 1062218822Sdim 1063218822Sdim/* Set symlink if symlink is already set, else set hardlink. */ 1064218822Sdimvoid 1065218822Sdimarchive_entry_copy_link_w(struct archive_entry *entry, const wchar_t *target) 1066218822Sdim{ 1067218822Sdim if (entry->ae_set & AE_SET_SYMLINK) 1068218822Sdim archive_mstring_copy_wcs(&entry->ae_symlink, target); 1069218822Sdim else 1070218822Sdim archive_mstring_copy_wcs(&entry->ae_hardlink, target); 1071218822Sdim} 1072218822Sdim 1073218822Sdimint 1074218822Sdimarchive_entry_update_link_utf8(struct archive_entry *entry, const char *target) 1075218822Sdim{ 1076218822Sdim int r; 1077218822Sdim if (entry->ae_set & AE_SET_SYMLINK) 1078218822Sdim r = archive_mstring_update_utf8(entry->archive, 1079218822Sdim &entry->ae_symlink, target); 1080218822Sdim else 1081218822Sdim r = archive_mstring_update_utf8(entry->archive, 1082218822Sdim &entry->ae_hardlink, target); 1083218822Sdim if (r == 0) 1084218822Sdim return (1); 1085218822Sdim if (errno == ENOMEM) 1086218822Sdim __archive_errx(1, "No memory"); 1087218822Sdim return (0); 1088218822Sdim} 1089218822Sdim 1090218822Sdimint 1091218822Sdim_archive_entry_copy_link_l(struct archive_entry *entry, 1092218822Sdim const char *target, size_t len, struct archive_string_conv *sc) 1093218822Sdim{ 1094218822Sdim int r; 1095218822Sdim 1096218822Sdim if (entry->ae_set & AE_SET_SYMLINK) 1097218822Sdim r = archive_mstring_copy_mbs_len_l(&entry->ae_symlink, 1098218822Sdim target, len, sc); 1099218822Sdim else 1100218822Sdim r = archive_mstring_copy_mbs_len_l(&entry->ae_hardlink, 1101218822Sdim target, len, sc); 1102218822Sdim return (r); 1103218822Sdim} 1104218822Sdim 1105218822Sdimvoid 1106218822Sdimarchive_entry_set_mode(struct archive_entry *entry, mode_t m) 1107218822Sdim{ 1108218822Sdim entry->stat_valid = 0; 1109218822Sdim entry->acl.mode = m; 1110218822Sdim} 1111218822Sdim 1112218822Sdimvoid 1113218822Sdimarchive_entry_set_mtime(struct archive_entry *entry, time_t t, long ns) 1114218822Sdim{ 1115218822Sdim FIX_NS(t, ns); 1116218822Sdim entry->stat_valid = 0; 1117218822Sdim entry->ae_set |= AE_SET_MTIME; 1118218822Sdim entry->ae_stat.aest_mtime = t; 1119218822Sdim entry->ae_stat.aest_mtime_nsec = ns; 1120218822Sdim} 1121218822Sdim 1122218822Sdimvoid 1123218822Sdimarchive_entry_unset_mtime(struct archive_entry *entry) 1124218822Sdim{ 1125218822Sdim archive_entry_set_mtime(entry, 0, 0); 1126218822Sdim entry->ae_set &= ~AE_SET_MTIME; 1127218822Sdim} 1128218822Sdim 1129218822Sdimvoid 1130218822Sdimarchive_entry_set_nlink(struct archive_entry *entry, unsigned int nlink) 1131218822Sdim{ 1132218822Sdim entry->stat_valid = 0; 1133218822Sdim entry->ae_stat.aest_nlink = nlink; 1134218822Sdim} 1135218822Sdim 1136218822Sdimvoid 1137218822Sdimarchive_entry_set_pathname(struct archive_entry *entry, const char *name) 1138218822Sdim{ 1139218822Sdim archive_mstring_copy_mbs(&entry->ae_pathname, name); 1140218822Sdim} 1141218822Sdim 1142218822Sdimvoid 1143218822Sdimarchive_entry_set_pathname_utf8(struct archive_entry *entry, const char *name) 1144218822Sdim{ 1145218822Sdim archive_mstring_copy_utf8(&entry->ae_pathname, name); 1146218822Sdim} 1147218822Sdim 1148218822Sdimvoid 1149218822Sdimarchive_entry_copy_pathname(struct archive_entry *entry, const char *name) 1150218822Sdim{ 1151218822Sdim archive_mstring_copy_mbs(&entry->ae_pathname, name); 1152218822Sdim} 1153218822Sdim 1154218822Sdimvoid 1155218822Sdimarchive_entry_copy_pathname_w(struct archive_entry *entry, const wchar_t *name) 1156218822Sdim{ 1157218822Sdim archive_mstring_copy_wcs(&entry->ae_pathname, name); 1158218822Sdim} 1159218822Sdim 1160218822Sdimint 1161218822Sdimarchive_entry_update_pathname_utf8(struct archive_entry *entry, const char *name) 1162218822Sdim{ 1163218822Sdim if (archive_mstring_update_utf8(entry->archive, 1164218822Sdim &entry->ae_pathname, name) == 0) 1165218822Sdim return (1); 1166218822Sdim if (errno == ENOMEM) 1167218822Sdim __archive_errx(1, "No memory"); 1168218822Sdim return (0); 1169218822Sdim} 1170218822Sdim 1171218822Sdimint 1172218822Sdim_archive_entry_copy_pathname_l(struct archive_entry *entry, 1173218822Sdim const char *name, size_t len, struct archive_string_conv *sc) 1174218822Sdim{ 1175218822Sdim return (archive_mstring_copy_mbs_len_l(&entry->ae_pathname, 1176218822Sdim name, len, sc)); 1177218822Sdim} 1178218822Sdim 1179218822Sdimvoid 1180218822Sdimarchive_entry_set_perm(struct archive_entry *entry, mode_t p) 1181218822Sdim{ 1182218822Sdim entry->stat_valid = 0; 1183218822Sdim entry->acl.mode &= AE_IFMT; 1184218822Sdim entry->acl.mode |= ~AE_IFMT & p; 1185218822Sdim} 1186218822Sdim 1187218822Sdimvoid 1188218822Sdimarchive_entry_set_rdev(struct archive_entry *entry, dev_t m) 1189218822Sdim{ 1190218822Sdim entry->stat_valid = 0; 1191218822Sdim entry->ae_stat.aest_rdev = m; 1192218822Sdim entry->ae_stat.aest_rdev_is_broken_down = 0; 1193218822Sdim} 1194218822Sdim 1195218822Sdimvoid 1196218822Sdimarchive_entry_set_rdevmajor(struct archive_entry *entry, dev_t m) 1197218822Sdim{ 1198218822Sdim entry->stat_valid = 0; 1199218822Sdim entry->ae_stat.aest_rdev_is_broken_down = 1; 1200218822Sdim entry->ae_stat.aest_rdevmajor = m; 1201218822Sdim} 1202218822Sdim 1203218822Sdimvoid 1204218822Sdimarchive_entry_set_rdevminor(struct archive_entry *entry, dev_t m) 1205218822Sdim{ 1206218822Sdim entry->stat_valid = 0; 1207218822Sdim entry->ae_stat.aest_rdev_is_broken_down = 1; 1208218822Sdim entry->ae_stat.aest_rdevminor = m; 1209218822Sdim} 1210218822Sdim 1211218822Sdimvoid 1212218822Sdimarchive_entry_set_size(struct archive_entry *entry, la_int64_t s) 1213218822Sdim{ 1214218822Sdim entry->stat_valid = 0; 1215218822Sdim entry->ae_stat.aest_size = s; 1216218822Sdim entry->ae_set |= AE_SET_SIZE; 1217218822Sdim} 1218218822Sdim 1219218822Sdimvoid 1220218822Sdimarchive_entry_unset_size(struct archive_entry *entry) 1221218822Sdim{ 1222218822Sdim archive_entry_set_size(entry, 0); 1223218822Sdim entry->ae_set &= ~AE_SET_SIZE; 1224218822Sdim} 1225218822Sdim 1226218822Sdimvoid 1227218822Sdimarchive_entry_copy_sourcepath(struct archive_entry *entry, const char *path) 1228218822Sdim{ 1229218822Sdim archive_mstring_copy_mbs(&entry->ae_sourcepath, path); 1230218822Sdim} 1231218822Sdim 1232218822Sdimvoid 1233218822Sdimarchive_entry_copy_sourcepath_w(struct archive_entry *entry, const wchar_t *path) 1234218822Sdim{ 1235218822Sdim archive_mstring_copy_wcs(&entry->ae_sourcepath, path); 1236218822Sdim} 1237218822Sdim 1238218822Sdimvoid 1239218822Sdimarchive_entry_set_symlink(struct archive_entry *entry, const char *linkname) 1240218822Sdim{ 1241218822Sdim archive_mstring_copy_mbs(&entry->ae_symlink, linkname); 1242218822Sdim if (linkname != NULL) 1243218822Sdim entry->ae_set |= AE_SET_SYMLINK; 1244218822Sdim else 1245218822Sdim entry->ae_set &= ~AE_SET_SYMLINK; 1246218822Sdim} 1247218822Sdim 1248218822Sdimvoid 1249218822Sdimarchive_entry_set_symlink_utf8(struct archive_entry *entry, const char *linkname) 1250218822Sdim{ 1251218822Sdim archive_mstring_copy_utf8(&entry->ae_symlink, linkname); 1252218822Sdim if (linkname != NULL) 1253218822Sdim entry->ae_set |= AE_SET_SYMLINK; 1254218822Sdim else 1255218822Sdim entry->ae_set &= ~AE_SET_SYMLINK; 1256218822Sdim} 1257218822Sdim 1258218822Sdimvoid 1259218822Sdimarchive_entry_copy_symlink(struct archive_entry *entry, const char *linkname) 1260218822Sdim{ 1261218822Sdim archive_mstring_copy_mbs(&entry->ae_symlink, linkname); 1262218822Sdim if (linkname != NULL) 1263218822Sdim entry->ae_set |= AE_SET_SYMLINK; 1264218822Sdim else 1265218822Sdim entry->ae_set &= ~AE_SET_SYMLINK; 1266218822Sdim} 1267218822Sdim 1268218822Sdimvoid 1269218822Sdimarchive_entry_copy_symlink_w(struct archive_entry *entry, const wchar_t *linkname) 1270218822Sdim{ 1271218822Sdim archive_mstring_copy_wcs(&entry->ae_symlink, linkname); 1272218822Sdim if (linkname != NULL) 1273218822Sdim entry->ae_set |= AE_SET_SYMLINK; 1274218822Sdim else 1275218822Sdim entry->ae_set &= ~AE_SET_SYMLINK; 1276218822Sdim} 1277218822Sdim 1278218822Sdimint 1279218822Sdimarchive_entry_update_symlink_utf8(struct archive_entry *entry, const char *linkname) 1280218822Sdim{ 1281218822Sdim if (linkname != NULL) 1282218822Sdim entry->ae_set |= AE_SET_SYMLINK; 1283218822Sdim else 1284218822Sdim entry->ae_set &= ~AE_SET_SYMLINK; 1285218822Sdim if (archive_mstring_update_utf8(entry->archive, 1286218822Sdim &entry->ae_symlink, linkname) == 0) 1287218822Sdim return (1); 1288218822Sdim if (errno == ENOMEM) 1289218822Sdim __archive_errx(1, "No memory"); 1290218822Sdim return (0); 1291218822Sdim} 1292218822Sdim 1293218822Sdimint 1294218822Sdim_archive_entry_copy_symlink_l(struct archive_entry *entry, 1295218822Sdim const char *linkname, size_t len, struct archive_string_conv *sc) 1296218822Sdim{ 1297218822Sdim int r; 1298218822Sdim 1299218822Sdim r = archive_mstring_copy_mbs_len_l(&entry->ae_symlink, 1300218822Sdim linkname, len, sc); 1301218822Sdim if (linkname != NULL && r == 0) 1302218822Sdim entry->ae_set |= AE_SET_SYMLINK; 1303218822Sdim else 1304218822Sdim entry->ae_set &= ~AE_SET_SYMLINK; 1305218822Sdim return (r); 1306218822Sdim} 1307218822Sdim 1308218822Sdimvoid 1309218822Sdimarchive_entry_set_uid(struct archive_entry *entry, la_int64_t u) 1310218822Sdim{ 1311218822Sdim entry->stat_valid = 0; 1312218822Sdim entry->ae_stat.aest_uid = u; 1313218822Sdim} 1314218822Sdim 1315218822Sdimvoid 1316218822Sdimarchive_entry_set_uname(struct archive_entry *entry, const char *name) 1317218822Sdim{ 1318218822Sdim archive_mstring_copy_mbs(&entry->ae_uname, name); 1319218822Sdim} 1320218822Sdim 1321218822Sdimvoid 1322218822Sdimarchive_entry_set_uname_utf8(struct archive_entry *entry, const char *name) 1323218822Sdim{ 1324218822Sdim archive_mstring_copy_utf8(&entry->ae_uname, name); 1325218822Sdim} 1326218822Sdim 1327218822Sdimvoid 1328218822Sdimarchive_entry_copy_uname(struct archive_entry *entry, const char *name) 1329218822Sdim{ 1330218822Sdim archive_mstring_copy_mbs(&entry->ae_uname, name); 1331218822Sdim} 1332218822Sdim 1333218822Sdimvoid 1334218822Sdimarchive_entry_copy_uname_w(struct archive_entry *entry, const wchar_t *name) 1335218822Sdim{ 1336218822Sdim archive_mstring_copy_wcs(&entry->ae_uname, name); 1337218822Sdim} 1338218822Sdim 1339218822Sdimint 1340218822Sdimarchive_entry_update_uname_utf8(struct archive_entry *entry, const char *name) 1341218822Sdim{ 1342218822Sdim if (archive_mstring_update_utf8(entry->archive, 1343218822Sdim &entry->ae_uname, name) == 0) 1344218822Sdim return (1); 1345218822Sdim if (errno == ENOMEM) 1346218822Sdim __archive_errx(1, "No memory"); 1347218822Sdim return (0); 1348218822Sdim} 1349218822Sdim 1350218822Sdimvoid 1351218822Sdimarchive_entry_set_is_data_encrypted(struct archive_entry *entry, char is_encrypted) 1352218822Sdim{ 1353218822Sdim if (is_encrypted) { 1354218822Sdim entry->encryption |= AE_ENCRYPTION_DATA; 1355218822Sdim } else { 1356218822Sdim entry->encryption &= ~AE_ENCRYPTION_DATA; 1357218822Sdim } 1358218822Sdim} 1359218822Sdim 1360218822Sdimvoid 1361218822Sdimarchive_entry_set_is_metadata_encrypted(struct archive_entry *entry, char is_encrypted) 1362218822Sdim{ 1363218822Sdim if (is_encrypted) { 1364218822Sdim entry->encryption |= AE_ENCRYPTION_METADATA; 1365218822Sdim } else { 1366218822Sdim entry->encryption &= ~AE_ENCRYPTION_METADATA; 1367218822Sdim } 1368218822Sdim} 1369218822Sdim 1370218822Sdimint 1371218822Sdim_archive_entry_copy_uname_l(struct archive_entry *entry, 1372218822Sdim const char *name, size_t len, struct archive_string_conv *sc) 1373218822Sdim{ 1374218822Sdim return (archive_mstring_copy_mbs_len_l(&entry->ae_uname, 1375218822Sdim name, len, sc)); 1376218822Sdim} 1377218822Sdim 1378218822Sdimconst void * 1379218822Sdimarchive_entry_mac_metadata(struct archive_entry *entry, size_t *s) 1380218822Sdim{ 1381218822Sdim *s = entry->mac_metadata_size; 1382218822Sdim return entry->mac_metadata; 1383218822Sdim} 1384218822Sdim 1385218822Sdimvoid 1386218822Sdimarchive_entry_copy_mac_metadata(struct archive_entry *entry, 1387218822Sdim const void *p, size_t s) 1388218822Sdim{ 1389218822Sdim free(entry->mac_metadata); 1390218822Sdim if (p == NULL || s == 0) { 1391218822Sdim entry->mac_metadata = NULL; 1392218822Sdim entry->mac_metadata_size = 0; 1393218822Sdim } else { 1394218822Sdim entry->mac_metadata_size = s; 1395218822Sdim entry->mac_metadata = malloc(s); 1396218822Sdim if (entry->mac_metadata == NULL) 1397218822Sdim abort(); 1398218822Sdim memcpy(entry->mac_metadata, p, s); 1399218822Sdim } 1400218822Sdim} 1401218822Sdim 1402218822Sdim/* 1403218822Sdim * ACL management. The following would, of course, be a lot simpler 1404218822Sdim * if: 1) the last draft of POSIX.1e were a really thorough and 1405218822Sdim * complete standard that addressed the needs of ACL archiving and 2) 1406218822Sdim * everyone followed it faithfully. Alas, neither is true, so the 1407218822Sdim * following is a lot more complex than might seem necessary to the 1408218822Sdim * uninitiated. 1409218822Sdim */ 1410218822Sdim 1411218822Sdimstruct archive_acl * 1412218822Sdimarchive_entry_acl(struct archive_entry *entry) 1413218822Sdim{ 1414218822Sdim return &entry->acl; 1415218822Sdim} 1416218822Sdim 1417218822Sdimvoid 1418218822Sdimarchive_entry_acl_clear(struct archive_entry *entry) 1419218822Sdim{ 1420218822Sdim archive_acl_clear(&entry->acl); 1421218822Sdim} 1422218822Sdim 1423218822Sdim/* 1424218822Sdim * Add a single ACL entry to the internal list of ACL data. 1425218822Sdim */ 1426218822Sdimint 1427218822Sdimarchive_entry_acl_add_entry(struct archive_entry *entry, 1428218822Sdim int type, int permset, int tag, int id, const char *name) 1429218822Sdim{ 1430218822Sdim return archive_acl_add_entry(&entry->acl, type, permset, tag, id, name); 1431218822Sdim} 1432218822Sdim 143360484Sobrien/* 1434218822Sdim * As above, but with a wide-character name. 143560484Sobrien */ 1436218822Sdimint 1437218822Sdimarchive_entry_acl_add_entry_w(struct archive_entry *entry, 1438218822Sdim int type, int permset, int tag, int id, const wchar_t *name) 1439218822Sdim{ 1440218822Sdim return archive_acl_add_entry_w_len(&entry->acl, 1441218822Sdim type, permset, tag, id, name, wcslen(name)); 144260484Sobrien} 144360484Sobrien 1444218822Sdim/* 1445218822Sdim * Return a bitmask of ACL types in an archive entry ACL list 1446218822Sdim */ 144760484Sobrienint 144860484Sobrienarchive_entry_acl_types(struct archive_entry *entry) 144960484Sobrien{ 1450218822Sdim return (archive_acl_types(&entry->acl)); 145160484Sobrien} 145260484Sobrien 145360484Sobrien/* 145477298Sobrien * Return a count of entries matching "want_type". 145577298Sobrien */ 145660484Sobrienint 145760484Sobrienarchive_entry_acl_count(struct archive_entry *entry, int want_type) 145860484Sobrien{ 145960484Sobrien return archive_acl_count(&entry->acl, want_type); 146060484Sobrien} 146160484Sobrien 146260484Sobrien/* 1463130561Sobrien * Prepare for reading entries from the ACL data. Returns a count 146460484Sobrien * of entries matching "want_type", or zero if there are no 146560484Sobrien * non-extended ACL entries of that type. 1466218822Sdim */ 1467130561Sobrienint 1468130561Sobrienarchive_entry_acl_reset(struct archive_entry *entry, int want_type) 1469218822Sdim{ 1470218822Sdim return archive_acl_reset(&entry->acl, want_type); 1471218822Sdim} 1472218822Sdim 1473218822Sdim/* 1474130561Sobrien * Return the next ACL entry in the list. Fake entries for the 1475130561Sobrien * standard permissions and include them in the returned list. 1476218822Sdim */ 1477218822Sdimint 1478218822Sdimarchive_entry_acl_next(struct archive_entry *entry, int want_type, int *type, 1479218822Sdim int *permset, int *tag, int *id, const char **name) 1480218822Sdim{ 1481218822Sdim int r; 1482218822Sdim r = archive_acl_next(entry->archive, &entry->acl, want_type, type, 1483218822Sdim permset, tag, id, name); 1484218822Sdim if (r == ARCHIVE_FATAL && errno == ENOMEM) 1485218822Sdim __archive_errx(1, "No memory"); 148677298Sobrien return (r); 148760484Sobrien} 148860484Sobrien 148960484Sobrien/* 149060484Sobrien * Generate a text version of the ACL. The flags parameter controls 149160484Sobrien * the style of the generated ACL. 1492130561Sobrien */ 149360484Sobrienwchar_t * 1494218822Sdimarchive_entry_acl_to_text_w(struct archive_entry *entry, ssize_t *len, 1495218822Sdim int flags) 1496218822Sdim{ 1497218822Sdim return (archive_acl_to_text_w(&entry->acl, len, flags, 1498218822Sdim entry->archive)); 1499218822Sdim} 1500218822Sdim 1501218822Sdimchar * 150260484Sobrienarchive_entry_acl_to_text(struct archive_entry *entry, ssize_t *len, 1503218822Sdim int flags) 1504218822Sdim{ 1505218822Sdim return (archive_acl_to_text_l(&entry->acl, len, flags, NULL)); 1506218822Sdim} 1507218822Sdim 1508218822Sdimchar * 1509130561Sobrien_archive_entry_acl_to_text_l(struct archive_entry *entry, ssize_t *len, 1510218822Sdim int flags, struct archive_string_conv *sc) 1511218822Sdim{ 1512218822Sdim return (archive_acl_to_text_l(&entry->acl, len, flags, sc)); 1513218822Sdim} 151460484Sobrien 1515104834Sobrien/* 151660484Sobrien * ACL text parser. 1517218822Sdim */ 151860484Sobrienint 151960484Sobrienarchive_entry_acl_from_text_w(struct archive_entry *entry, 152060484Sobrien const wchar_t *wtext, int type) 152160484Sobrien{ 152260484Sobrien return (archive_acl_from_text_w(&entry->acl, wtext, type)); 1523218822Sdim} 152460484Sobrien 152560484Sobrienint 152660484Sobrienarchive_entry_acl_from_text(struct archive_entry *entry, 152760484Sobrien const char *text, int type) 152860484Sobrien{ 152960484Sobrien return (archive_acl_from_text_l(&entry->acl, text, type, NULL)); 153060484Sobrien} 1531218822Sdim 1532218822Sdimint 153360484Sobrien_archive_entry_acl_from_text_l(struct archive_entry *entry, const char *text, 153460484Sobrien int type, struct archive_string_conv *sc) 153560484Sobrien{ 153660484Sobrien return (archive_acl_from_text_l(&entry->acl, text, type, sc)); 153760484Sobrien} 153860484Sobrien 153960484Sobrien/* Deprecated */ 1540218822Sdimstatic int 1541218822Sdimarchive_entry_acl_text_compat(int *flags) 1542218822Sdim{ 1543218822Sdim if ((*flags & ARCHIVE_ENTRY_ACL_TYPE_POSIX1E) == 0) 1544218822Sdim return (1); 1545218822Sdim 1546218822Sdim /* ABI compat with old ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID */ 1547218822Sdim if ((*flags & OLD_ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID) != 0) 1548218822Sdim *flags |= ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID; 1549218822Sdim 1550218822Sdim /* ABI compat with old ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT */ 1551218822Sdim if ((*flags & OLD_ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT) != 0) 1552218822Sdim *flags |= ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT; 1553218822Sdim 1554218822Sdim *flags |= ARCHIVE_ENTRY_ACL_STYLE_SEPARATOR_COMMA; 1555218822Sdim 1556218822Sdim return (0); 1557218822Sdim} 1558218822Sdim 1559218822Sdim/* Deprecated */ 1560218822Sdimconst wchar_t * 1561218822Sdimarchive_entry_acl_text_w(struct archive_entry *entry, int flags) 1562218822Sdim{ 1563218822Sdim if (entry->acl.acl_text_w != NULL) { 1564218822Sdim free(entry->acl.acl_text_w); 1565218822Sdim entry->acl.acl_text_w = NULL; 1566218822Sdim } 1567218822Sdim if (archive_entry_acl_text_compat(&flags) == 0) 1568218822Sdim entry->acl.acl_text_w = archive_acl_to_text_w(&entry->acl, 1569218822Sdim NULL, flags, entry->archive); 1570218822Sdim return (entry->acl.acl_text_w); 1571218822Sdim} 1572218822Sdim 1573218822Sdim/* Deprecated */ 1574218822Sdimconst char * 1575218822Sdimarchive_entry_acl_text(struct archive_entry *entry, int flags) 1576218822Sdim{ 157760484Sobrien if (entry->acl.acl_text != NULL) { 1578218822Sdim free(entry->acl.acl_text); 1579218822Sdim entry->acl.acl_text = NULL; 158060484Sobrien } 158160484Sobrien if (archive_entry_acl_text_compat(&flags) == 0) 1582130561Sobrien entry->acl.acl_text = archive_acl_to_text_l(&entry->acl, NULL, 158360484Sobrien flags, NULL); 158460484Sobrien 158560484Sobrien return (entry->acl.acl_text); 158660484Sobrien} 158760484Sobrien 158860484Sobrien/* Deprecated */ 1589130561Sobrienint 159060484Sobrien_archive_entry_acl_text_l(struct archive_entry *entry, int flags, 159160484Sobrien const char **acl_text, size_t *len, struct archive_string_conv *sc) 159260484Sobrien{ 159360484Sobrien if (entry->acl.acl_text != NULL) { 159460484Sobrien free(entry->acl.acl_text); 159560484Sobrien entry->acl.acl_text = NULL; 159660484Sobrien } 1597130561Sobrien 159860484Sobrien if (archive_entry_acl_text_compat(&flags) == 0) 159960484Sobrien entry->acl.acl_text = archive_acl_to_text_l(&entry->acl, 1600130561Sobrien (ssize_t *)len, flags, sc); 1601218822Sdim 1602218822Sdim *acl_text = entry->acl.acl_text; 1603218822Sdim 1604218822Sdim return (0); 160560484Sobrien} 1606218822Sdim 160760484Sobrien/* 160860484Sobrien * Following code is modified from UC Berkeley sources, and 1609218822Sdim * is subject to the following copyright notice. 1610218822Sdim */ 161160484Sobrien 161260484Sobrien/*- 161360484Sobrien * Copyright (c) 1993 1614218822Sdim * The Regents of the University of California. All rights reserved. 1615218822Sdim * 1616218822Sdim * Redistribution and use in source and binary forms, with or without 1617130561Sobrien * modification, are permitted provided that the following conditions 1618218822Sdim * are met: 1619218822Sdim * 1. Redistributions of source code must retain the above copyright 1620218822Sdim * notice, this list of conditions and the following disclaimer. 162160484Sobrien * 2. Redistributions in binary form must reproduce the above copyright 1622218822Sdim * notice, this list of conditions and the following disclaimer in the 1623130561Sobrien * documentation and/or other materials provided with the distribution. 1624218822Sdim * 4. Neither the name of the University nor the names of its contributors 1625218822Sdim * may be used to endorse or promote products derived from this software 1626218822Sdim * without specific prior written permission. 1627218822Sdim * 162860484Sobrien * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 1629218822Sdim * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 163060484Sobrien * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1631130561Sobrien * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 1632130561Sobrien * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1633218822Sdim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 1634218822Sdim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 1635130561Sobrien * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 1636130561Sobrien * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 1637218822Sdim * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 1638218822Sdim * SUCH DAMAGE. 1639218822Sdim */ 164060484Sobrien 1641218822Sdimstatic const struct flag { 1642218822Sdim const char *name; 1643218822Sdim const wchar_t *wname; 1644218822Sdim unsigned long set; 1645218822Sdim unsigned long clear; 1646218822Sdim} flags[] = { 1647218822Sdim /* Preferred (shorter) names per flag first, all prefixed by "no" */ 1648218822Sdim#ifdef SF_APPEND 1649218822Sdim { "nosappnd", L"nosappnd", SF_APPEND, 0 }, 1650218822Sdim { "nosappend", L"nosappend", SF_APPEND, 0 }, 1651218822Sdim#endif 1652218822Sdim#if defined(FS_APPEND_FL) /* 'a' */ 1653218822Sdim { "nosappnd", L"nosappnd", FS_APPEND_FL, 0 }, 1654218822Sdim { "nosappend", L"nosappend", FS_APPEND_FL, 0 }, 1655218822Sdim#elif defined(EXT2_APPEND_FL) /* 'a' */ 1656218822Sdim { "nosappnd", L"nosappnd", EXT2_APPEND_FL, 0 }, 1657218822Sdim { "nosappend", L"nosappend", EXT2_APPEND_FL, 0 }, 1658218822Sdim#endif 1659218822Sdim#ifdef SF_ARCHIVED 1660218822Sdim { "noarch", L"noarch", SF_ARCHIVED, 0 }, 1661218822Sdim { "noarchived", L"noarchived", SF_ARCHIVED, 0 }, 1662218822Sdim#endif 1663218822Sdim#ifdef SF_IMMUTABLE 1664218822Sdim { "noschg", L"noschg", SF_IMMUTABLE, 0 }, 1665218822Sdim { "noschange", L"noschange", SF_IMMUTABLE, 0 }, 1666218822Sdim { "nosimmutable", L"nosimmutable", SF_IMMUTABLE, 0 }, 1667218822Sdim#endif 1668218822Sdim#if defined(FS_IMMUTABLE_FL) /* 'i' */ 1669218822Sdim { "noschg", L"noschg", FS_IMMUTABLE_FL, 0 }, 1670130561Sobrien { "noschange", L"noschange", FS_IMMUTABLE_FL, 0 }, 167160484Sobrien { "nosimmutable", L"nosimmutable", FS_IMMUTABLE_FL, 0 }, 167260484Sobrien#elif defined(EXT2_IMMUTABLE_FL) /* 'i' */ 167360484Sobrien { "noschg", L"noschg", EXT2_IMMUTABLE_FL, 0 }, 167460484Sobrien { "noschange", L"noschange", EXT2_IMMUTABLE_FL, 0 }, 167560484Sobrien { "nosimmutable", L"nosimmutable", EXT2_IMMUTABLE_FL, 0 }, 167660484Sobrien#endif 167760484Sobrien#ifdef SF_NOUNLINK 167860484Sobrien { "nosunlnk", L"nosunlnk", SF_NOUNLINK, 0 }, 167960484Sobrien { "nosunlink", L"nosunlink", SF_NOUNLINK, 0 }, 168060484Sobrien#endif 1681218822Sdim#ifdef SF_SNAPSHOT 1682218822Sdim { "nosnapshot", L"nosnapshot", SF_SNAPSHOT, 0 }, 1683218822Sdim#endif 1684218822Sdim#ifdef UF_APPEND 168560484Sobrien { "nouappnd", L"nouappnd", UF_APPEND, 0 }, 1686218822Sdim { "nouappend", L"nouappend", UF_APPEND, 0 }, 1687130561Sobrien#endif 1688218822Sdim#ifdef UF_IMMUTABLE 1689218822Sdim { "nouchg", L"nouchg", UF_IMMUTABLE, 0 }, 1690218822Sdim { "nouchange", L"nouchange", UF_IMMUTABLE, 0 }, 1691218822Sdim { "nouimmutable", L"nouimmutable", UF_IMMUTABLE, 0 }, 1692218822Sdim#endif 1693218822Sdim#ifdef UF_NODUMP 1694218822Sdim { "nodump", L"nodump", 0, UF_NODUMP}, 1695218822Sdim#endif 1696218822Sdim#if defined(FS_NODUMP_FL) /* 'd' */ 1697218822Sdim { "nodump", L"nodump", 0, FS_NODUMP_FL}, 1698218822Sdim#elif defined(EXT2_NODUMP_FL) /* 'd' */ 1699130561Sobrien { "nodump", L"nodump", 0, EXT2_NODUMP_FL}, 1700218822Sdim#endif 1701218822Sdim#ifdef UF_OPAQUE 1702218822Sdim { "noopaque", L"noopaque", UF_OPAQUE, 0 }, 170360484Sobrien#endif 1704218822Sdim#ifdef UF_NOUNLINK 1705218822Sdim { "nouunlnk", L"nouunlnk", UF_NOUNLINK, 0 }, 1706218822Sdim { "nouunlink", L"nouunlink", UF_NOUNLINK, 0 }, 1707218822Sdim#endif 1708218822Sdim#ifdef UF_COMPRESSED 1709218822Sdim { "nocompressed",L"nocompressed", UF_COMPRESSED, 0 }, 1710218822Sdim#endif 1711218822Sdim#ifdef UF_HIDDEN 1712218822Sdim { "nohidden", L"nohidden", UF_HIDDEN, 0 }, 1713130561Sobrien#endif 1714218822Sdim#if defined(FS_UNRM_FL) 1715218822Sdim { "nouunlink", L"nouunlink", FS_UNRM_FL, 0}, 1716218822Sdim#elif defined(EXT2_UNRM_FL) 1717218822Sdim { "nouunlink", L"nouunlink", EXT2_UNRM_FL, 0}, 1718218822Sdim#endif 1719218822Sdim 1720218822Sdim#if defined(FS_BTREE_FL) 1721218822Sdim { "nobtree", L"nobtree", FS_BTREE_FL, 0 }, 1722218822Sdim#elif defined(EXT2_BTREE_FL) 1723218822Sdim { "nobtree", L"nobtree", EXT2_BTREE_FL, 0 }, 1724218822Sdim#endif 1725218822Sdim 1726218822Sdim#if defined(FS_ECOMPR_FL) 1727218822Sdim { "nocomperr", L"nocomperr", FS_ECOMPR_FL, 0 }, 1728218822Sdim#elif defined(EXT2_ECOMPR_FL) 1729218822Sdim { "nocomperr", L"nocomperr", EXT2_ECOMPR_FL, 0 }, 1730218822Sdim#endif 1731218822Sdim 1732218822Sdim#if defined(FS_COMPR_FL) /* 'c' */ 1733218822Sdim { "nocompress", L"nocompress", FS_COMPR_FL, 0 }, 1734218822Sdim#elif defined(EXT2_COMPR_FL) /* 'c' */ 1735218822Sdim { "nocompress", L"nocompress", EXT2_COMPR_FL, 0 }, 1736218822Sdim#endif 1737218822Sdim 1738218822Sdim#if defined(FS_NOATIME_FL) /* 'A' */ 1739218822Sdim { "noatime", L"noatime", 0, FS_NOATIME_FL}, 1740218822Sdim#elif defined(EXT2_NOATIME_FL) /* 'A' */ 1741218822Sdim { "noatime", L"noatime", 0, EXT2_NOATIME_FL}, 1742218822Sdim#endif 1743218822Sdim 1744218822Sdim#if defined(FS_DIRTY_FL) 1745218822Sdim { "nocompdirty",L"nocompdirty", FS_DIRTY_FL, 0}, 1746218822Sdim#elif defined(EXT2_DIRTY_FL) 1747218822Sdim { "nocompdirty",L"nocompdirty", EXT2_DIRTY_FL, 0}, 1748218822Sdim#endif 1749218822Sdim 1750218822Sdim#if defined(FS_COMPRBLK_FL) 1751218822Sdim#if defined(FS_NOCOMPR_FL) 1752218822Sdim { "nocomprblk", L"nocomprblk", FS_COMPRBLK_FL, FS_NOCOMPR_FL}, 175360484Sobrien#else 1754218822Sdim { "nocomprblk", L"nocomprblk", FS_COMPRBLK_FL, 0}, 1755218822Sdim#endif 1756218822Sdim#elif defined(EXT2_COMPRBLK_FL) 175760484Sobrien#if defined(EXT2_NOCOMPR_FL) 1758218822Sdim { "nocomprblk", L"nocomprblk", EXT2_COMPRBLK_FL, EXT2_NOCOMPR_FL}, 1759218822Sdim#else 1760218822Sdim { "nocomprblk", L"nocomprblk", EXT2_COMPRBLK_FL, 0}, 1761218822Sdim#endif 1762218822Sdim#endif 1763218822Sdim#if defined(FS_DIRSYNC_FL) 1764218822Sdim { "nodirsync", L"nodirsync", FS_DIRSYNC_FL, 0}, 176560484Sobrien#elif defined(EXT2_DIRSYNC_FL) 1766218822Sdim { "nodirsync", L"nodirsync", EXT2_DIRSYNC_FL, 0}, 1767130561Sobrien#endif 1768218822Sdim#if defined(FS_INDEX_FL) 1769218822Sdim { "nohashidx", L"nohashidx", FS_INDEX_FL, 0}, 1770218822Sdim#elif defined(EXT2_INDEX_FL) 1771218822Sdim { "nohashidx", L"nohashidx", EXT2_INDEX_FL, 0}, 1772218822Sdim#endif 1773218822Sdim#if defined(FS_IMAGIC_FL) 1774218822Sdim { "noimagic", L"noimagic", FS_IMAGIC_FL, 0}, 1775218822Sdim#elif defined(EXT2_IMAGIC_FL) 1776218822Sdim { "noimagic", L"noimagic", EXT2_IMAGIC_FL, 0}, 1777218822Sdim#endif 1778218822Sdim#if defined(FS_JOURNAL_DATA_FL) 1779218822Sdim { "nojournal", L"nojournal", FS_JOURNAL_DATA_FL, 0}, 1780218822Sdim#elif defined(EXT3_JOURNAL_DATA_FL) 1781218822Sdim { "nojournal", L"nojournal", EXT3_JOURNAL_DATA_FL, 0}, 1782218822Sdim#endif 1783218822Sdim#if defined(FS_SECRM_FL) 1784218822Sdim { "nosecuredeletion",L"nosecuredeletion",FS_SECRM_FL, 0}, 1785218822Sdim#elif defined(EXT2_SECRM_FL) 1786218822Sdim { "nosecuredeletion",L"nosecuredeletion",EXT2_SECRM_FL, 0}, 1787218822Sdim#endif 1788218822Sdim#if defined(FS_SYNC_FL) 1789218822Sdim { "nosync", L"nosync", FS_SYNC_FL, 0}, 1790218822Sdim#elif defined(EXT2_SYNC_FL) 179160484Sobrien { "nosync", L"nosync", EXT2_SYNC_FL, 0}, 1792218822Sdim#endif 1793218822Sdim#if defined(FS_NOTAIL_FL) 1794218822Sdim { "notail", L"notail", 0, FS_NOTAIL_FL}, 1795218822Sdim#elif defined(EXT2_NOTAIL_FL) 179660484Sobrien { "notail", L"notail", 0, EXT2_NOTAIL_FL}, 1797218822Sdim#endif 1798218822Sdim#if defined(FS_TOPDIR_FL) 1799218822Sdim { "notopdir", L"notopdir", FS_TOPDIR_FL, 0}, 1800218822Sdim#elif defined(EXT2_TOPDIR_FL) 1801218822Sdim { "notopdir", L"notopdir", EXT2_TOPDIR_FL, 0}, 1802218822Sdim#endif 1803218822Sdim#ifdef FS_ENCRYPT_FL 1804218822Sdim { "noencrypt", L"noencrypt", FS_ENCRYPT_FL, 0}, 1805218822Sdim#endif 1806218822Sdim#ifdef FS_HUGE_FILE_FL 1807218822Sdim { "nohugefile", L"nohugefile", FS_HUGE_FILE_FL, 0}, 1808218822Sdim#endif 1809218822Sdim#ifdef FS_EXTENT_FL 1810218822Sdim { "noextent", L"noextent", FS_EXTENT_FL, 0}, 1811218822Sdim#endif 1812218822Sdim#ifdef FS_EA_INODE_FL 1813218822Sdim { "noeainode", L"noeainode", FS_EA_INODE_FL, 0}, 1814218822Sdim#endif 1815218822Sdim#ifdef FS_EOFBLOCKS_FL 1816218822Sdim { "noeofblocks",L"noeofblocks", FS_EOFBLOCKS_FL, 0}, 1817218822Sdim#endif 1818218822Sdim#ifdef FS_NOCOW_FL 1819218822Sdim { "nocow", L"nocow", FS_NOCOW_FL, 0}, 1820218822Sdim#endif 1821218822Sdim#ifdef FS_INLINE_DATA_FL 1822218822Sdim { "noinlinedata",L"noinlinedata", FS_INLINE_DATA_FL, 0}, 1823218822Sdim#endif 1824218822Sdim#ifdef FS_PROJINHERIT_FL 1825218822Sdim { "noprojinherit",L"noprojinherit", FS_PROJINHERIT_FL, 0}, 1826218822Sdim#endif 1827218822Sdim#if defined(FS_RESERVED_FL) 1828218822Sdim { "noreserved", L"noreserved", FS_RESERVED_FL, 0}, 1829218822Sdim#elif defined(EXT2_RESERVED_FL) 1830218822Sdim { "noreserved", L"noreserved", EXT2_RESERVED_FL, 0}, 1831218822Sdim#endif 1832218822Sdim { NULL, NULL, 0, 0 } 1833218822Sdim}; 1834218822Sdim 1835218822Sdim/* 1836218822Sdim * fflagstostr -- 1837218822Sdim * Convert file flags to a comma-separated string. If no flags 1838218822Sdim * are set, return the empty string. 1839218822Sdim */ 1840218822Sdimstatic char * 1841218822Sdimae_fflagstostr(unsigned long bitset, unsigned long bitclear) 1842218822Sdim{ 1843218822Sdim char *string, *dp; 1844218822Sdim const char *sp; 1845218822Sdim unsigned long bits; 1846218822Sdim const struct flag *flag; 1847218822Sdim size_t length; 1848218822Sdim 1849218822Sdim bits = bitset | bitclear; 1850218822Sdim length = 0; 1851218822Sdim for (flag = flags; flag->name != NULL; flag++) 1852218822Sdim if (bits & (flag->set | flag->clear)) { 1853218822Sdim length += strlen(flag->name) + 1; 1854218822Sdim bits &= ~(flag->set | flag->clear); 1855218822Sdim } 1856218822Sdim 1857218822Sdim if (length == 0) 1858218822Sdim return (NULL); 1859218822Sdim string = (char *)malloc(length); 1860218822Sdim if (string == NULL) 1861218822Sdim return (NULL); 1862218822Sdim 1863218822Sdim dp = string; 1864218822Sdim for (flag = flags; flag->name != NULL; flag++) { 1865218822Sdim if (bitset & flag->set || bitclear & flag->clear) { 1866218822Sdim sp = flag->name + 2; 1867218822Sdim } else if (bitset & flag->clear || bitclear & flag->set) { 1868218822Sdim sp = flag->name; 1869218822Sdim } else 1870218822Sdim continue; 1871218822Sdim bitset &= ~(flag->set | flag->clear); 1872218822Sdim bitclear &= ~(flag->set | flag->clear); 1873218822Sdim if (dp > string) 1874218822Sdim *dp++ = ','; 1875218822Sdim while ((*dp++ = *sp++) != '\0') 1876218822Sdim ; 1877218822Sdim dp--; 1878218822Sdim } 1879218822Sdim 1880218822Sdim *dp = '\0'; 1881218822Sdim return (string); 1882218822Sdim} 1883218822Sdim 1884218822Sdim/* 1885218822Sdim * strtofflags -- 1886218822Sdim * Take string of arguments and return file flags. This 1887218822Sdim * version works a little differently than strtofflags(3). 1888218822Sdim * In particular, it always tests every token, skipping any 1889218822Sdim * unrecognized tokens. It returns a pointer to the first 1890218822Sdim * unrecognized token, or NULL if every token was recognized. 1891218822Sdim * This version is also const-correct and does not modify the 1892218822Sdim * provided string. 1893218822Sdim */ 1894218822Sdimstatic const char * 1895218822Sdimae_strtofflags(const char *s, unsigned long *setp, unsigned long *clrp) 1896218822Sdim{ 1897218822Sdim const char *start, *end; 1898218822Sdim const struct flag *flag; 1899218822Sdim unsigned long set, clear; 1900218822Sdim const char *failed; 1901218822Sdim 1902218822Sdim set = clear = 0; 1903218822Sdim start = s; 1904218822Sdim failed = NULL; 1905218822Sdim /* Find start of first token. */ 1906218822Sdim while (*start == '\t' || *start == ' ' || *start == ',') 1907218822Sdim start++; 1908218822Sdim while (*start != '\0') { 1909218822Sdim size_t length; 1910218822Sdim /* Locate end of token. */ 1911218822Sdim end = start; 1912218822Sdim while (*end != '\0' && *end != '\t' && 1913218822Sdim *end != ' ' && *end != ',') 1914218822Sdim end++; 1915218822Sdim length = end - start; 1916218822Sdim for (flag = flags; flag->name != NULL; flag++) { 1917218822Sdim size_t flag_length = strlen(flag->name); 1918218822Sdim if (length == flag_length 1919218822Sdim && memcmp(start, flag->name, length) == 0) { 1920218822Sdim /* Matched "noXXXX", so reverse the sense. */ 1921218822Sdim clear |= flag->set; 1922218822Sdim set |= flag->clear; 1923218822Sdim break; 1924218822Sdim } else if (length == flag_length - 2 1925218822Sdim && memcmp(start, flag->name + 2, length) == 0) { 1926218822Sdim /* Matched "XXXX", so don't reverse. */ 1927218822Sdim set |= flag->set; 192860484Sobrien clear |= flag->clear; 1929218822Sdim break; 1930218822Sdim } 1931218822Sdim } 1932218822Sdim /* Ignore unknown flag names. */ 1933218822Sdim if (flag->name == NULL && failed == NULL) 1934218822Sdim failed = start; 193560484Sobrien 1936218822Sdim /* Find start of next token. */ 1937218822Sdim start = end; 193860484Sobrien while (*start == '\t' || *start == ' ' || *start == ',') 1939218822Sdim start++; 1940218822Sdim 1941218822Sdim } 1942218822Sdim 1943218822Sdim if (setp) 1944218822Sdim *setp = set; 1945218822Sdim if (clrp) 194660484Sobrien *clrp = clear; 1947218822Sdim 1948218822Sdim /* Return location of first failure. */ 194960484Sobrien return (failed); 1950218822Sdim} 1951218822Sdim 1952218822Sdim/* 195360484Sobrien * wcstofflags -- 1954218822Sdim * Take string of arguments and return file flags. This 1955218822Sdim * version works a little differently than strtofflags(3). 1956218822Sdim * In particular, it always tests every token, skipping any 1957218822Sdim * unrecognized tokens. It returns a pointer to the first 1958218822Sdim * unrecognized token, or NULL if every token was recognized. 1959218822Sdim * This version is also const-correct and does not modify the 1960218822Sdim * provided string. 1961218822Sdim */ 1962218822Sdimstatic const wchar_t * 1963218822Sdimae_wcstofflags(const wchar_t *s, unsigned long *setp, unsigned long *clrp) 1964218822Sdim{ 1965218822Sdim const wchar_t *start, *end; 1966218822Sdim const struct flag *flag; 1967218822Sdim unsigned long set, clear; 1968218822Sdim const wchar_t *failed; 1969218822Sdim 1970218822Sdim set = clear = 0; 1971218822Sdim start = s; 1972218822Sdim failed = NULL; 1973218822Sdim /* Find start of first token. */ 1974218822Sdim while (*start == L'\t' || *start == L' ' || *start == L',') 1975218822Sdim start++; 1976218822Sdim while (*start != L'\0') { 1977218822Sdim size_t length; 1978218822Sdim /* Locate end of token. */ 197960484Sobrien end = start; 1980218822Sdim while (*end != L'\0' && *end != L'\t' && 1981218822Sdim *end != L' ' && *end != L',') 1982218822Sdim end++; 1983218822Sdim length = end - start; 198460484Sobrien for (flag = flags; flag->wname != NULL; flag++) { 1985218822Sdim size_t flag_length = wcslen(flag->wname); 1986218822Sdim if (length == flag_length 1987218822Sdim && wmemcmp(start, flag->wname, length) == 0) { 1988218822Sdim /* Matched "noXXXX", so reverse the sense. */ 1989218822Sdim clear |= flag->set; 1990218822Sdim set |= flag->clear; 199160484Sobrien break; 1992218822Sdim } else if (length == flag_length - 2 1993218822Sdim && wmemcmp(start, flag->wname + 2, length) == 0) { 1994218822Sdim /* Matched "XXXX", so don't reverse. */ 199560484Sobrien set |= flag->set; 1996218822Sdim clear |= flag->clear; 1997218822Sdim break; 1998218822Sdim } 1999218822Sdim } 2000218822Sdim /* Ignore unknown flag names. */ 2001218822Sdim if (flag->wname == NULL && failed == NULL) 2002218822Sdim failed = start; 2003218822Sdim 2004218822Sdim /* Find start of next token. */ 2005218822Sdim start = end; 2006218822Sdim while (*start == L'\t' || *start == L' ' || *start == L',') 2007218822Sdim start++; 2008218822Sdim 2009218822Sdim } 2010218822Sdim 2011218822Sdim if (setp) 2012218822Sdim *setp = set; 2013218822Sdim if (clrp) 2014218822Sdim *clrp = clear; 2015218822Sdim 2016218822Sdim /* Return location of first failure. */ 2017218822Sdim return (failed); 2018218822Sdim} 2019218822Sdim 2020218822Sdim 2021218822Sdim#ifdef TEST 2022218822Sdim#include <stdio.h> 2023218822Sdimint 2024218822Sdimmain(int argc, char **argv) 2025218822Sdim{ 2026218822Sdim struct archive_entry *entry = archive_entry_new(); 2027218822Sdim unsigned long set, clear; 2028218822Sdim const wchar_t *remainder; 2029218822Sdim 2030218822Sdim remainder = archive_entry_copy_fflags_text_w(entry, L"nosappnd dump archive,,,,,,,"); 2031218822Sdim archive_entry_fflags(entry, &set, &clear); 2032218822Sdim 2033218822Sdim wprintf(L"set=0x%lX clear=0x%lX remainder='%ls'\n", set, clear, remainder); 2034218822Sdim 2035218822Sdim wprintf(L"new flags='%s'\n", archive_entry_fflags_text(entry)); 2036218822Sdim return (0); 2037218822Sdim} 2038218822Sdim#endif 2039218822Sdim