1228753Smm/*- 2228753Smm * Copyright (c) 2003-2007 Tim Kientzle 3313571Smm * Copyright (c) 2016 Martin Matuska 4228753Smm * All rights reserved. 5228753Smm * 6228753Smm * Redistribution and use in source and binary forms, with or without 7228753Smm * modification, are permitted provided that the following conditions 8228753Smm * are met: 9228753Smm * 1. Redistributions of source code must retain the above copyright 10228753Smm * notice, this list of conditions and the following disclaimer. 11228753Smm * 2. Redistributions in binary form must reproduce the above copyright 12228753Smm * notice, this list of conditions and the following disclaimer in the 13228753Smm * documentation and/or other materials provided with the distribution. 14228753Smm * 15228753Smm * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR 16228753Smm * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17228753Smm * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18228753Smm * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, 19228753Smm * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20228753Smm * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21228753Smm * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22228753Smm * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23228753Smm * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24228753Smm * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25228753Smm */ 26228753Smm 27228753Smm#include "archive_platform.h" 28228763Smm__FBSDID("$FreeBSD: stable/10/contrib/libarchive/libarchive/archive_entry.c 368708 2020-12-16 22:25:40Z mm $"); 29228753Smm 30228753Smm#ifdef HAVE_SYS_STAT_H 31228753Smm#include <sys/stat.h> 32228753Smm#endif 33228753Smm#ifdef HAVE_SYS_TYPES_H 34228753Smm#include <sys/types.h> 35228753Smm#endif 36228753Smm#if MAJOR_IN_MKDEV 37228753Smm#include <sys/mkdev.h> 38228753Smm#define HAVE_MAJOR 39228753Smm#elif MAJOR_IN_SYSMACROS 40228753Smm#include <sys/sysmacros.h> 41228753Smm#define HAVE_MAJOR 42228753Smm#endif 43232153Smm#ifdef HAVE_ERRNO_H 44232153Smm#include <errno.h> 45232153Smm#endif 46228753Smm#ifdef HAVE_LIMITS_H 47228753Smm#include <limits.h> 48228753Smm#endif 49228753Smm#ifdef HAVE_LINUX_FS_H 50228753Smm#include <linux/fs.h> /* for Linux file flags */ 51228753Smm#endif 52228753Smm/* 53228753Smm * Some Linux distributions have both linux/ext2_fs.h and ext2fs/ext2_fs.h. 54228753Smm * As the include guards don't agree, the order of include is important. 55228753Smm */ 56228753Smm#ifdef HAVE_LINUX_EXT2_FS_H 57228753Smm#include <linux/ext2_fs.h> /* for Linux file flags */ 58228753Smm#endif 59228753Smm#if defined(HAVE_EXT2FS_EXT2_FS_H) && !defined(__CYGWIN__) 60228753Smm#include <ext2fs/ext2_fs.h> /* for Linux file flags */ 61228753Smm#endif 62228753Smm#include <stddef.h> 63228753Smm#include <stdio.h> 64228753Smm#ifdef HAVE_STDLIB_H 65228753Smm#include <stdlib.h> 66228753Smm#endif 67228753Smm#ifdef HAVE_STRING_H 68228753Smm#include <string.h> 69228753Smm#endif 70228753Smm#ifdef HAVE_WCHAR_H 71228753Smm#include <wchar.h> 72228753Smm#endif 73228753Smm 74228753Smm#include "archive.h" 75232153Smm#include "archive_acl_private.h" 76228753Smm#include "archive_entry.h" 77232153Smm#include "archive_entry_locale.h" 78228753Smm#include "archive_private.h" 79228753Smm#include "archive_entry_private.h" 80228753Smm 81228753Smm#if !defined(HAVE_MAJOR) && !defined(major) 82228753Smm/* Replacement for major/minor/makedev. */ 83228753Smm#define major(x) ((int)(0x00ff & ((x) >> 8))) 84228753Smm#define minor(x) ((int)(0xffff00ff & (x))) 85228753Smm#define makedev(maj,min) ((0xff00 & ((maj)<<8)) | (0xffff00ff & (min))) 86228753Smm#endif 87228753Smm 88228753Smm/* Play games to come up with a suitable makedev() definition. */ 89228753Smm#ifdef __QNXNTO__ 90228753Smm/* QNX. <sigh> */ 91228753Smm#include <sys/netmgr.h> 92228753Smm#define ae_makedev(maj, min) makedev(ND_LOCAL_NODE, (maj), (min)) 93228753Smm#elif defined makedev 94228753Smm/* There's a "makedev" macro. */ 95228753Smm#define ae_makedev(maj, min) makedev((maj), (min)) 96228753Smm#elif defined mkdev || ((defined _WIN32 || defined __WIN32__) && !defined(__CYGWIN__)) 97228753Smm/* Windows. <sigh> */ 98228753Smm#define ae_makedev(maj, min) mkdev((maj), (min)) 99228753Smm#else 100228753Smm/* There's a "makedev" function. */ 101228753Smm#define ae_makedev(maj, min) makedev((maj), (min)) 102228753Smm#endif 103228753Smm 104232153Smm/* 105232153Smm * This adjustment is needed to support the following idiom for adding 106232153Smm * 1000ns to the stored time: 107232153Smm * archive_entry_set_atime(archive_entry_atime(), 108232153Smm * archive_entry_atime_nsec() + 1000) 109232153Smm * The additional if() here compensates for ambiguity in the C standard, 110232153Smm * which permits two possible interpretations of a % b when a is negative. 111232153Smm */ 112232153Smm#define FIX_NS(t,ns) \ 113232153Smm do { \ 114232153Smm t += ns / 1000000000; \ 115232153Smm ns %= 1000000000; \ 116232153Smm if (ns < 0) { --t; ns += 1000000000; } \ 117232153Smm } while (0) 118228753Smm 119228753Smmstatic char * ae_fflagstostr(unsigned long bitset, unsigned long bitclear); 120228753Smmstatic const wchar_t *ae_wcstofflags(const wchar_t *stringp, 121228753Smm unsigned long *setp, unsigned long *clrp); 122228753Smmstatic const char *ae_strtofflags(const char *stringp, 123228753Smm unsigned long *setp, unsigned long *clrp); 124228753Smm 125228753Smm#ifndef HAVE_WCSCPY 126228753Smmstatic wchar_t * wcscpy(wchar_t *s1, const wchar_t *s2) 127228753Smm{ 128228753Smm wchar_t *dest = s1; 129228753Smm while ((*s1 = *s2) != L'\0') 130228753Smm ++s1, ++s2; 131228753Smm return dest; 132228753Smm} 133228753Smm#endif 134228753Smm#ifndef HAVE_WCSLEN 135228753Smmstatic size_t wcslen(const wchar_t *s) 136228753Smm{ 137228753Smm const wchar_t *p = s; 138228753Smm while (*p != L'\0') 139228753Smm ++p; 140228753Smm return p - s; 141228753Smm} 142228753Smm#endif 143228753Smm#ifndef HAVE_WMEMCMP 144228753Smm/* Good enough for simple equality testing, but not for sorting. */ 145228753Smm#define wmemcmp(a,b,i) memcmp((a), (b), (i) * sizeof(wchar_t)) 146228753Smm#endif 147228753Smm 148228753Smm/**************************************************************************** 149228753Smm * 150228753Smm * Public Interface 151228753Smm * 152228753Smm ****************************************************************************/ 153228753Smm 154228753Smmstruct archive_entry * 155228753Smmarchive_entry_clear(struct archive_entry *entry) 156228753Smm{ 157228753Smm if (entry == NULL) 158228753Smm return (NULL); 159232153Smm archive_mstring_clean(&entry->ae_fflags_text); 160232153Smm archive_mstring_clean(&entry->ae_gname); 161232153Smm archive_mstring_clean(&entry->ae_hardlink); 162232153Smm archive_mstring_clean(&entry->ae_pathname); 163232153Smm archive_mstring_clean(&entry->ae_sourcepath); 164232153Smm archive_mstring_clean(&entry->ae_symlink); 165232153Smm archive_mstring_clean(&entry->ae_uname); 166232153Smm archive_entry_copy_mac_metadata(entry, NULL, 0); 167232153Smm archive_acl_clear(&entry->acl); 168228753Smm archive_entry_xattr_clear(entry); 169232153Smm archive_entry_sparse_clear(entry); 170228753Smm free(entry->stat); 171348608Smm entry->ae_symlink_type = AE_SYMLINK_TYPE_UNDEFINED; 172228753Smm memset(entry, 0, sizeof(*entry)); 173228753Smm return entry; 174228753Smm} 175228753Smm 176228753Smmstruct archive_entry * 177228753Smmarchive_entry_clone(struct archive_entry *entry) 178228753Smm{ 179228753Smm struct archive_entry *entry2; 180228753Smm struct ae_xattr *xp; 181232153Smm struct ae_sparse *sp; 182232153Smm size_t s; 183232153Smm const void *p; 184228753Smm 185228753Smm /* Allocate new structure and copy over all of the fields. */ 186232153Smm /* TODO: Should we copy the archive over? Or require a new archive 187232153Smm * as an argument? */ 188232153Smm entry2 = archive_entry_new2(entry->archive); 189228753Smm if (entry2 == NULL) 190228753Smm return (NULL); 191228753Smm entry2->ae_stat = entry->ae_stat; 192228753Smm entry2->ae_fflags_set = entry->ae_fflags_set; 193228753Smm entry2->ae_fflags_clear = entry->ae_fflags_clear; 194228753Smm 195232153Smm /* TODO: XXX If clone can have a different archive, what do we do here if 196232153Smm * character sets are different? XXX */ 197232153Smm archive_mstring_copy(&entry2->ae_fflags_text, &entry->ae_fflags_text); 198232153Smm archive_mstring_copy(&entry2->ae_gname, &entry->ae_gname); 199232153Smm archive_mstring_copy(&entry2->ae_hardlink, &entry->ae_hardlink); 200232153Smm archive_mstring_copy(&entry2->ae_pathname, &entry->ae_pathname); 201232153Smm archive_mstring_copy(&entry2->ae_sourcepath, &entry->ae_sourcepath); 202232153Smm archive_mstring_copy(&entry2->ae_symlink, &entry->ae_symlink); 203228753Smm entry2->ae_set = entry->ae_set; 204232153Smm archive_mstring_copy(&entry2->ae_uname, &entry->ae_uname); 205228753Smm 206348608Smm /* Copy symlink type */ 207348608Smm entry2->ae_symlink_type = entry->ae_symlink_type; 208348608Smm 209302001Smm /* Copy encryption status */ 210302001Smm entry2->encryption = entry->encryption; 211368708Smm 212368708Smm /* Copy digests */ 213368708Smm#define copy_digest(_e2, _e, _t) \ 214368708Smm memcpy(_e2->digest._t, _e->digest._t, sizeof(_e2->digest._t)) 215368708Smm 216368708Smm copy_digest(entry2, entry, md5); 217368708Smm copy_digest(entry2, entry, rmd160); 218368708Smm copy_digest(entry2, entry, sha1); 219368708Smm copy_digest(entry2, entry, sha256); 220368708Smm copy_digest(entry2, entry, sha384); 221368708Smm copy_digest(entry2, entry, sha512); 222368708Smm 223368708Smm#undef copy_digest 224302001Smm 225228753Smm /* Copy ACL data over. */ 226232153Smm archive_acl_copy(&entry2->acl, &entry->acl); 227228753Smm 228232153Smm /* Copy Mac OS metadata. */ 229232153Smm p = archive_entry_mac_metadata(entry, &s); 230232153Smm archive_entry_copy_mac_metadata(entry2, p, s); 231232153Smm 232228753Smm /* Copy xattr data over. */ 233228753Smm xp = entry->xattr_head; 234228753Smm while (xp != NULL) { 235228753Smm archive_entry_xattr_add_entry(entry2, 236228753Smm xp->name, xp->value, xp->size); 237228753Smm xp = xp->next; 238228753Smm } 239228753Smm 240232153Smm /* Copy sparse data over. */ 241232153Smm sp = entry->sparse_head; 242232153Smm while (sp != NULL) { 243232153Smm archive_entry_sparse_add_entry(entry2, 244232153Smm sp->offset, sp->length); 245232153Smm sp = sp->next; 246232153Smm } 247232153Smm 248228753Smm return (entry2); 249228753Smm} 250228753Smm 251228753Smmvoid 252228753Smmarchive_entry_free(struct archive_entry *entry) 253228753Smm{ 254228753Smm archive_entry_clear(entry); 255228753Smm free(entry); 256228753Smm} 257228753Smm 258228753Smmstruct archive_entry * 259228753Smmarchive_entry_new(void) 260228753Smm{ 261232153Smm return archive_entry_new2(NULL); 262232153Smm} 263232153Smm 264232153Smmstruct archive_entry * 265232153Smmarchive_entry_new2(struct archive *a) 266232153Smm{ 267228753Smm struct archive_entry *entry; 268228753Smm 269311042Smm entry = (struct archive_entry *)calloc(1, sizeof(*entry)); 270228753Smm if (entry == NULL) 271228753Smm return (NULL); 272232153Smm entry->archive = a; 273348608Smm entry->ae_symlink_type = AE_SYMLINK_TYPE_UNDEFINED; 274228753Smm return (entry); 275228753Smm} 276228753Smm 277228753Smm/* 278228753Smm * Functions for reading fields from an archive_entry. 279228753Smm */ 280228753Smm 281228753Smmtime_t 282228753Smmarchive_entry_atime(struct archive_entry *entry) 283228753Smm{ 284228753Smm return (entry->ae_stat.aest_atime); 285228753Smm} 286228753Smm 287228753Smmlong 288228753Smmarchive_entry_atime_nsec(struct archive_entry *entry) 289228753Smm{ 290228753Smm return (entry->ae_stat.aest_atime_nsec); 291228753Smm} 292228753Smm 293228753Smmint 294228753Smmarchive_entry_atime_is_set(struct archive_entry *entry) 295228753Smm{ 296228753Smm return (entry->ae_set & AE_SET_ATIME); 297228753Smm} 298228753Smm 299228753Smmtime_t 300228753Smmarchive_entry_birthtime(struct archive_entry *entry) 301228753Smm{ 302228753Smm return (entry->ae_stat.aest_birthtime); 303228753Smm} 304228753Smm 305228753Smmlong 306228753Smmarchive_entry_birthtime_nsec(struct archive_entry *entry) 307228753Smm{ 308228753Smm return (entry->ae_stat.aest_birthtime_nsec); 309228753Smm} 310228753Smm 311228753Smmint 312228753Smmarchive_entry_birthtime_is_set(struct archive_entry *entry) 313228753Smm{ 314228753Smm return (entry->ae_set & AE_SET_BIRTHTIME); 315228753Smm} 316228753Smm 317228753Smmtime_t 318228753Smmarchive_entry_ctime(struct archive_entry *entry) 319228753Smm{ 320228753Smm return (entry->ae_stat.aest_ctime); 321228753Smm} 322228753Smm 323228753Smmint 324228753Smmarchive_entry_ctime_is_set(struct archive_entry *entry) 325228753Smm{ 326228753Smm return (entry->ae_set & AE_SET_CTIME); 327228753Smm} 328228753Smm 329228753Smmlong 330228753Smmarchive_entry_ctime_nsec(struct archive_entry *entry) 331228753Smm{ 332228753Smm return (entry->ae_stat.aest_ctime_nsec); 333228753Smm} 334228753Smm 335228753Smmdev_t 336228753Smmarchive_entry_dev(struct archive_entry *entry) 337228753Smm{ 338228753Smm if (entry->ae_stat.aest_dev_is_broken_down) 339228753Smm return ae_makedev(entry->ae_stat.aest_devmajor, 340228753Smm entry->ae_stat.aest_devminor); 341228753Smm else 342228753Smm return (entry->ae_stat.aest_dev); 343228753Smm} 344228753Smm 345232153Smmint 346232153Smmarchive_entry_dev_is_set(struct archive_entry *entry) 347232153Smm{ 348232153Smm return (entry->ae_set & AE_SET_DEV); 349232153Smm} 350232153Smm 351228753Smmdev_t 352228753Smmarchive_entry_devmajor(struct archive_entry *entry) 353228753Smm{ 354228753Smm if (entry->ae_stat.aest_dev_is_broken_down) 355228753Smm return (entry->ae_stat.aest_devmajor); 356228753Smm else 357228753Smm return major(entry->ae_stat.aest_dev); 358228753Smm} 359228753Smm 360228753Smmdev_t 361228753Smmarchive_entry_devminor(struct archive_entry *entry) 362228753Smm{ 363228753Smm if (entry->ae_stat.aest_dev_is_broken_down) 364228753Smm return (entry->ae_stat.aest_devminor); 365228753Smm else 366228753Smm return minor(entry->ae_stat.aest_dev); 367228753Smm} 368228753Smm 369362134Smm__LA_MODE_T 370228753Smmarchive_entry_filetype(struct archive_entry *entry) 371228753Smm{ 372232153Smm return (AE_IFMT & entry->acl.mode); 373228753Smm} 374228753Smm 375228753Smmvoid 376228753Smmarchive_entry_fflags(struct archive_entry *entry, 377228753Smm unsigned long *set, unsigned long *clear) 378228753Smm{ 379228753Smm *set = entry->ae_fflags_set; 380228753Smm *clear = entry->ae_fflags_clear; 381228753Smm} 382228753Smm 383228753Smm/* 384228753Smm * Note: if text was provided, this just returns that text. If you 385228753Smm * really need the text to be rebuilt in a canonical form, set the 386228753Smm * text, ask for the bitmaps, then set the bitmaps. (Setting the 387228753Smm * bitmaps clears any stored text.) This design is deliberate: if 388228753Smm * we're editing archives, we don't want to discard flags just because 389228753Smm * they aren't supported on the current system. The bitmap<->text 390228753Smm * conversions are platform-specific (see below). 391228753Smm */ 392228753Smmconst char * 393228753Smmarchive_entry_fflags_text(struct archive_entry *entry) 394228753Smm{ 395228753Smm const char *f; 396228753Smm char *p; 397228753Smm 398232153Smm if (archive_mstring_get_mbs(entry->archive, 399238856Smm &entry->ae_fflags_text, &f) == 0) { 400238856Smm if (f != NULL) 401238856Smm return (f); 402238856Smm } else if (errno == ENOMEM) 403238856Smm __archive_errx(1, "No memory"); 404228753Smm 405228753Smm if (entry->ae_fflags_set == 0 && entry->ae_fflags_clear == 0) 406228753Smm return (NULL); 407228753Smm 408228753Smm p = ae_fflagstostr(entry->ae_fflags_set, entry->ae_fflags_clear); 409228753Smm if (p == NULL) 410228753Smm return (NULL); 411228753Smm 412232153Smm archive_mstring_copy_mbs(&entry->ae_fflags_text, p); 413228753Smm free(p); 414232153Smm if (archive_mstring_get_mbs(entry->archive, 415232153Smm &entry->ae_fflags_text, &f) == 0) 416232153Smm return (f); 417238856Smm if (errno == ENOMEM) 418238856Smm __archive_errx(1, "No memory"); 419232153Smm return (NULL); 420228753Smm} 421228753Smm 422315433Smmla_int64_t 423228753Smmarchive_entry_gid(struct archive_entry *entry) 424228753Smm{ 425228753Smm return (entry->ae_stat.aest_gid); 426228753Smm} 427228753Smm 428228753Smmconst char * 429228753Smmarchive_entry_gname(struct archive_entry *entry) 430228753Smm{ 431232153Smm const char *p; 432232153Smm if (archive_mstring_get_mbs(entry->archive, &entry->ae_gname, &p) == 0) 433232153Smm return (p); 434238856Smm if (errno == ENOMEM) 435238856Smm __archive_errx(1, "No memory"); 436232153Smm return (NULL); 437228753Smm} 438228753Smm 439302001Smmconst char * 440302001Smmarchive_entry_gname_utf8(struct archive_entry *entry) 441302001Smm{ 442302001Smm const char *p; 443302001Smm if (archive_mstring_get_utf8(entry->archive, &entry->ae_gname, &p) == 0) 444302001Smm return (p); 445302001Smm if (errno == ENOMEM) 446302001Smm __archive_errx(1, "No memory"); 447302001Smm return (NULL); 448302001Smm} 449302001Smm 450302001Smm 451228753Smmconst wchar_t * 452228753Smmarchive_entry_gname_w(struct archive_entry *entry) 453228753Smm{ 454232153Smm const wchar_t *p; 455232153Smm if (archive_mstring_get_wcs(entry->archive, &entry->ae_gname, &p) == 0) 456232153Smm return (p); 457238856Smm if (errno == ENOMEM) 458238856Smm __archive_errx(1, "No memory"); 459232153Smm return (NULL); 460228753Smm} 461228753Smm 462232153Smmint 463232153Smm_archive_entry_gname_l(struct archive_entry *entry, 464232153Smm const char **p, size_t *len, struct archive_string_conv *sc) 465232153Smm{ 466368708Smm return (archive_mstring_get_mbs_l(entry->archive, &entry->ae_gname, p, len, sc)); 467232153Smm} 468232153Smm 469228753Smmconst char * 470228753Smmarchive_entry_hardlink(struct archive_entry *entry) 471228753Smm{ 472232153Smm const char *p; 473238856Smm if ((entry->ae_set & AE_SET_HARDLINK) == 0) 474238856Smm return (NULL); 475238856Smm if (archive_mstring_get_mbs( 476232153Smm entry->archive, &entry->ae_hardlink, &p) == 0) 477232153Smm return (p); 478238856Smm if (errno == ENOMEM) 479238856Smm __archive_errx(1, "No memory"); 480228753Smm return (NULL); 481228753Smm} 482228753Smm 483302001Smmconst char * 484302001Smmarchive_entry_hardlink_utf8(struct archive_entry *entry) 485302001Smm{ 486302001Smm const char *p; 487302001Smm if ((entry->ae_set & AE_SET_HARDLINK) == 0) 488302001Smm return (NULL); 489302001Smm if (archive_mstring_get_utf8( 490302001Smm entry->archive, &entry->ae_hardlink, &p) == 0) 491302001Smm return (p); 492302001Smm if (errno == ENOMEM) 493302001Smm __archive_errx(1, "No memory"); 494302001Smm return (NULL); 495302001Smm} 496302001Smm 497228753Smmconst wchar_t * 498228753Smmarchive_entry_hardlink_w(struct archive_entry *entry) 499228753Smm{ 500232153Smm const wchar_t *p; 501238856Smm if ((entry->ae_set & AE_SET_HARDLINK) == 0) 502238856Smm return (NULL); 503238856Smm if (archive_mstring_get_wcs( 504232153Smm entry->archive, &entry->ae_hardlink, &p) == 0) 505232153Smm return (p); 506238856Smm if (errno == ENOMEM) 507238856Smm __archive_errx(1, "No memory"); 508228753Smm return (NULL); 509228753Smm} 510228753Smm 511232153Smmint 512232153Smm_archive_entry_hardlink_l(struct archive_entry *entry, 513232153Smm const char **p, size_t *len, struct archive_string_conv *sc) 514232153Smm{ 515232153Smm if ((entry->ae_set & AE_SET_HARDLINK) == 0) { 516232153Smm *p = NULL; 517232153Smm *len = 0; 518232153Smm return (0); 519232153Smm } 520368708Smm return (archive_mstring_get_mbs_l(entry->archive, &entry->ae_hardlink, p, len, sc)); 521232153Smm} 522232153Smm 523315433Smmla_int64_t 524228753Smmarchive_entry_ino(struct archive_entry *entry) 525228753Smm{ 526228753Smm return (entry->ae_stat.aest_ino); 527228753Smm} 528228753Smm 529232153Smmint 530232153Smmarchive_entry_ino_is_set(struct archive_entry *entry) 531232153Smm{ 532232153Smm return (entry->ae_set & AE_SET_INO); 533232153Smm} 534232153Smm 535315433Smmla_int64_t 536228753Smmarchive_entry_ino64(struct archive_entry *entry) 537228753Smm{ 538228753Smm return (entry->ae_stat.aest_ino); 539228753Smm} 540228753Smm 541362134Smm__LA_MODE_T 542228753Smmarchive_entry_mode(struct archive_entry *entry) 543228753Smm{ 544232153Smm return (entry->acl.mode); 545228753Smm} 546228753Smm 547228753Smmtime_t 548228753Smmarchive_entry_mtime(struct archive_entry *entry) 549228753Smm{ 550228753Smm return (entry->ae_stat.aest_mtime); 551228753Smm} 552228753Smm 553228753Smmlong 554228753Smmarchive_entry_mtime_nsec(struct archive_entry *entry) 555228753Smm{ 556228753Smm return (entry->ae_stat.aest_mtime_nsec); 557228753Smm} 558228753Smm 559228753Smmint 560228753Smmarchive_entry_mtime_is_set(struct archive_entry *entry) 561228753Smm{ 562228753Smm return (entry->ae_set & AE_SET_MTIME); 563228753Smm} 564228753Smm 565228753Smmunsigned int 566228753Smmarchive_entry_nlink(struct archive_entry *entry) 567228753Smm{ 568228753Smm return (entry->ae_stat.aest_nlink); 569228753Smm} 570228753Smm 571228753Smmconst char * 572228753Smmarchive_entry_pathname(struct archive_entry *entry) 573228753Smm{ 574232153Smm const char *p; 575232153Smm if (archive_mstring_get_mbs( 576232153Smm entry->archive, &entry->ae_pathname, &p) == 0) 577232153Smm return (p); 578238856Smm if (errno == ENOMEM) 579238856Smm __archive_errx(1, "No memory"); 580232153Smm return (NULL); 581228753Smm} 582228753Smm 583302001Smmconst char * 584302001Smmarchive_entry_pathname_utf8(struct archive_entry *entry) 585302001Smm{ 586302001Smm const char *p; 587302001Smm if (archive_mstring_get_utf8( 588302001Smm entry->archive, &entry->ae_pathname, &p) == 0) 589302001Smm return (p); 590302001Smm if (errno == ENOMEM) 591302001Smm __archive_errx(1, "No memory"); 592302001Smm return (NULL); 593302001Smm} 594302001Smm 595228753Smmconst wchar_t * 596228753Smmarchive_entry_pathname_w(struct archive_entry *entry) 597228753Smm{ 598232153Smm const wchar_t *p; 599232153Smm if (archive_mstring_get_wcs( 600232153Smm entry->archive, &entry->ae_pathname, &p) == 0) 601232153Smm return (p); 602238856Smm if (errno == ENOMEM) 603238856Smm __archive_errx(1, "No memory"); 604232153Smm return (NULL); 605228753Smm} 606228753Smm 607232153Smmint 608232153Smm_archive_entry_pathname_l(struct archive_entry *entry, 609232153Smm const char **p, size_t *len, struct archive_string_conv *sc) 610232153Smm{ 611368708Smm return (archive_mstring_get_mbs_l(entry->archive, &entry->ae_pathname, p, len, sc)); 612232153Smm} 613232153Smm 614362134Smm__LA_MODE_T 615232153Smmarchive_entry_perm(struct archive_entry *entry) 616232153Smm{ 617232153Smm return (~AE_IFMT & entry->acl.mode); 618232153Smm} 619232153Smm 620228753Smmdev_t 621228753Smmarchive_entry_rdev(struct archive_entry *entry) 622228753Smm{ 623228753Smm if (entry->ae_stat.aest_rdev_is_broken_down) 624228753Smm return ae_makedev(entry->ae_stat.aest_rdevmajor, 625228753Smm entry->ae_stat.aest_rdevminor); 626228753Smm else 627228753Smm return (entry->ae_stat.aest_rdev); 628228753Smm} 629228753Smm 630228753Smmdev_t 631228753Smmarchive_entry_rdevmajor(struct archive_entry *entry) 632228753Smm{ 633228753Smm if (entry->ae_stat.aest_rdev_is_broken_down) 634228753Smm return (entry->ae_stat.aest_rdevmajor); 635228753Smm else 636228753Smm return major(entry->ae_stat.aest_rdev); 637228753Smm} 638228753Smm 639228753Smmdev_t 640228753Smmarchive_entry_rdevminor(struct archive_entry *entry) 641228753Smm{ 642228753Smm if (entry->ae_stat.aest_rdev_is_broken_down) 643228753Smm return (entry->ae_stat.aest_rdevminor); 644228753Smm else 645228753Smm return minor(entry->ae_stat.aest_rdev); 646228753Smm} 647228753Smm 648315433Smmla_int64_t 649228753Smmarchive_entry_size(struct archive_entry *entry) 650228753Smm{ 651228753Smm return (entry->ae_stat.aest_size); 652228753Smm} 653228753Smm 654228753Smmint 655228753Smmarchive_entry_size_is_set(struct archive_entry *entry) 656228753Smm{ 657228753Smm return (entry->ae_set & AE_SET_SIZE); 658228753Smm} 659228753Smm 660228753Smmconst char * 661228753Smmarchive_entry_sourcepath(struct archive_entry *entry) 662228753Smm{ 663232153Smm const char *p; 664232153Smm if (archive_mstring_get_mbs( 665232153Smm entry->archive, &entry->ae_sourcepath, &p) == 0) 666232153Smm return (p); 667238856Smm if (errno == ENOMEM) 668238856Smm __archive_errx(1, "No memory"); 669232153Smm return (NULL); 670228753Smm} 671228753Smm 672232153Smmconst wchar_t * 673232153Smmarchive_entry_sourcepath_w(struct archive_entry *entry) 674232153Smm{ 675232153Smm const wchar_t *p; 676232153Smm if (archive_mstring_get_wcs( 677232153Smm entry->archive, &entry->ae_sourcepath, &p) == 0) 678232153Smm return (p); 679232153Smm return (NULL); 680232153Smm} 681232153Smm 682228753Smmconst char * 683228753Smmarchive_entry_symlink(struct archive_entry *entry) 684228753Smm{ 685232153Smm const char *p; 686238856Smm if ((entry->ae_set & AE_SET_SYMLINK) == 0) 687238856Smm return (NULL); 688238856Smm if (archive_mstring_get_mbs( 689232153Smm entry->archive, &entry->ae_symlink, &p) == 0) 690232153Smm return (p); 691238856Smm if (errno == ENOMEM) 692238856Smm __archive_errx(1, "No memory"); 693228753Smm return (NULL); 694228753Smm} 695228753Smm 696348608Smmint 697348608Smmarchive_entry_symlink_type(struct archive_entry *entry) 698348608Smm{ 699348608Smm return (entry->ae_symlink_type); 700348608Smm} 701348608Smm 702302001Smmconst char * 703302001Smmarchive_entry_symlink_utf8(struct archive_entry *entry) 704302001Smm{ 705302001Smm const char *p; 706302001Smm if ((entry->ae_set & AE_SET_SYMLINK) == 0) 707302001Smm return (NULL); 708302001Smm if (archive_mstring_get_utf8( 709302001Smm entry->archive, &entry->ae_symlink, &p) == 0) 710302001Smm return (p); 711302001Smm if (errno == ENOMEM) 712302001Smm __archive_errx(1, "No memory"); 713302001Smm return (NULL); 714302001Smm} 715302001Smm 716228753Smmconst wchar_t * 717228753Smmarchive_entry_symlink_w(struct archive_entry *entry) 718228753Smm{ 719232153Smm const wchar_t *p; 720238856Smm if ((entry->ae_set & AE_SET_SYMLINK) == 0) 721238856Smm return (NULL); 722238856Smm if (archive_mstring_get_wcs( 723232153Smm entry->archive, &entry->ae_symlink, &p) == 0) 724232153Smm return (p); 725238856Smm if (errno == ENOMEM) 726238856Smm __archive_errx(1, "No memory"); 727228753Smm return (NULL); 728228753Smm} 729228753Smm 730232153Smmint 731232153Smm_archive_entry_symlink_l(struct archive_entry *entry, 732232153Smm const char **p, size_t *len, struct archive_string_conv *sc) 733232153Smm{ 734232153Smm if ((entry->ae_set & AE_SET_SYMLINK) == 0) { 735232153Smm *p = NULL; 736232153Smm *len = 0; 737232153Smm return (0); 738232153Smm } 739368708Smm return (archive_mstring_get_mbs_l(entry->archive, &entry->ae_symlink, p, len, sc)); 740232153Smm} 741232153Smm 742315433Smmla_int64_t 743228753Smmarchive_entry_uid(struct archive_entry *entry) 744228753Smm{ 745228753Smm return (entry->ae_stat.aest_uid); 746228753Smm} 747228753Smm 748228753Smmconst char * 749228753Smmarchive_entry_uname(struct archive_entry *entry) 750228753Smm{ 751232153Smm const char *p; 752232153Smm if (archive_mstring_get_mbs(entry->archive, &entry->ae_uname, &p) == 0) 753232153Smm return (p); 754238856Smm if (errno == ENOMEM) 755238856Smm __archive_errx(1, "No memory"); 756232153Smm return (NULL); 757228753Smm} 758228753Smm 759302001Smmconst char * 760302001Smmarchive_entry_uname_utf8(struct archive_entry *entry) 761302001Smm{ 762302001Smm const char *p; 763302001Smm if (archive_mstring_get_utf8(entry->archive, &entry->ae_uname, &p) == 0) 764302001Smm return (p); 765302001Smm if (errno == ENOMEM) 766302001Smm __archive_errx(1, "No memory"); 767302001Smm return (NULL); 768302001Smm} 769302001Smm 770228753Smmconst wchar_t * 771228753Smmarchive_entry_uname_w(struct archive_entry *entry) 772228753Smm{ 773232153Smm const wchar_t *p; 774232153Smm if (archive_mstring_get_wcs(entry->archive, &entry->ae_uname, &p) == 0) 775232153Smm return (p); 776238856Smm if (errno == ENOMEM) 777238856Smm __archive_errx(1, "No memory"); 778232153Smm return (NULL); 779228753Smm} 780228753Smm 781232153Smmint 782232153Smm_archive_entry_uname_l(struct archive_entry *entry, 783232153Smm const char **p, size_t *len, struct archive_string_conv *sc) 784232153Smm{ 785368708Smm return (archive_mstring_get_mbs_l(entry->archive, &entry->ae_uname, p, len, sc)); 786232153Smm} 787232153Smm 788302001Smmint 789302001Smmarchive_entry_is_data_encrypted(struct archive_entry *entry) 790302001Smm{ 791302001Smm return ((entry->encryption & AE_ENCRYPTION_DATA) == AE_ENCRYPTION_DATA); 792302001Smm} 793302001Smm 794302001Smmint 795302001Smmarchive_entry_is_metadata_encrypted(struct archive_entry *entry) 796302001Smm{ 797302001Smm return ((entry->encryption & AE_ENCRYPTION_METADATA) == AE_ENCRYPTION_METADATA); 798302001Smm} 799302001Smm 800302001Smmint 801302001Smmarchive_entry_is_encrypted(struct archive_entry *entry) 802302001Smm{ 803302001Smm return (entry->encryption & (AE_ENCRYPTION_DATA|AE_ENCRYPTION_METADATA)); 804302001Smm} 805302001Smm 806228753Smm/* 807228753Smm * Functions to set archive_entry properties. 808228753Smm */ 809228753Smm 810228753Smmvoid 811228753Smmarchive_entry_set_filetype(struct archive_entry *entry, unsigned int type) 812228753Smm{ 813228753Smm entry->stat_valid = 0; 814232153Smm entry->acl.mode &= ~AE_IFMT; 815232153Smm entry->acl.mode |= AE_IFMT & type; 816228753Smm} 817228753Smm 818228753Smmvoid 819228753Smmarchive_entry_set_fflags(struct archive_entry *entry, 820228753Smm unsigned long set, unsigned long clear) 821228753Smm{ 822232153Smm archive_mstring_clean(&entry->ae_fflags_text); 823228753Smm entry->ae_fflags_set = set; 824228753Smm entry->ae_fflags_clear = clear; 825228753Smm} 826228753Smm 827228753Smmconst char * 828228753Smmarchive_entry_copy_fflags_text(struct archive_entry *entry, 829228753Smm const char *flags) 830228753Smm{ 831232153Smm archive_mstring_copy_mbs(&entry->ae_fflags_text, flags); 832228753Smm return (ae_strtofflags(flags, 833228753Smm &entry->ae_fflags_set, &entry->ae_fflags_clear)); 834228753Smm} 835228753Smm 836228753Smmconst wchar_t * 837228753Smmarchive_entry_copy_fflags_text_w(struct archive_entry *entry, 838228753Smm const wchar_t *flags) 839228753Smm{ 840232153Smm archive_mstring_copy_wcs(&entry->ae_fflags_text, flags); 841228753Smm return (ae_wcstofflags(flags, 842228753Smm &entry->ae_fflags_set, &entry->ae_fflags_clear)); 843228753Smm} 844228753Smm 845228753Smmvoid 846315433Smmarchive_entry_set_gid(struct archive_entry *entry, la_int64_t g) 847228753Smm{ 848228753Smm entry->stat_valid = 0; 849228753Smm entry->ae_stat.aest_gid = g; 850228753Smm} 851228753Smm 852228753Smmvoid 853228753Smmarchive_entry_set_gname(struct archive_entry *entry, const char *name) 854228753Smm{ 855232153Smm archive_mstring_copy_mbs(&entry->ae_gname, name); 856228753Smm} 857228753Smm 858228753Smmvoid 859302001Smmarchive_entry_set_gname_utf8(struct archive_entry *entry, const char *name) 860302001Smm{ 861302001Smm archive_mstring_copy_utf8(&entry->ae_gname, name); 862302001Smm} 863302001Smm 864302001Smmvoid 865228753Smmarchive_entry_copy_gname(struct archive_entry *entry, const char *name) 866228753Smm{ 867232153Smm archive_mstring_copy_mbs(&entry->ae_gname, name); 868228753Smm} 869228753Smm 870228753Smmvoid 871228753Smmarchive_entry_copy_gname_w(struct archive_entry *entry, const wchar_t *name) 872228753Smm{ 873232153Smm archive_mstring_copy_wcs(&entry->ae_gname, name); 874228753Smm} 875228753Smm 876228753Smmint 877228753Smmarchive_entry_update_gname_utf8(struct archive_entry *entry, const char *name) 878228753Smm{ 879232153Smm if (archive_mstring_update_utf8(entry->archive, 880232153Smm &entry->ae_gname, name) == 0) 881232153Smm return (1); 882238856Smm if (errno == ENOMEM) 883238856Smm __archive_errx(1, "No memory"); 884232153Smm return (0); 885228753Smm} 886228753Smm 887232153Smmint 888232153Smm_archive_entry_copy_gname_l(struct archive_entry *entry, 889232153Smm const char *name, size_t len, struct archive_string_conv *sc) 890232153Smm{ 891232153Smm return (archive_mstring_copy_mbs_len_l(&entry->ae_gname, name, len, sc)); 892232153Smm} 893232153Smm 894228753Smmvoid 895315433Smmarchive_entry_set_ino(struct archive_entry *entry, la_int64_t ino) 896228753Smm{ 897228753Smm entry->stat_valid = 0; 898232153Smm entry->ae_set |= AE_SET_INO; 899228753Smm entry->ae_stat.aest_ino = ino; 900228753Smm} 901228753Smm 902228753Smmvoid 903315433Smmarchive_entry_set_ino64(struct archive_entry *entry, la_int64_t ino) 904228753Smm{ 905228753Smm entry->stat_valid = 0; 906232153Smm entry->ae_set |= AE_SET_INO; 907228753Smm entry->ae_stat.aest_ino = ino; 908228753Smm} 909228753Smm 910228753Smmvoid 911228753Smmarchive_entry_set_hardlink(struct archive_entry *entry, const char *target) 912228753Smm{ 913232153Smm archive_mstring_copy_mbs(&entry->ae_hardlink, target); 914228753Smm if (target != NULL) 915228753Smm entry->ae_set |= AE_SET_HARDLINK; 916228753Smm else 917228753Smm entry->ae_set &= ~AE_SET_HARDLINK; 918228753Smm} 919228753Smm 920228753Smmvoid 921302001Smmarchive_entry_set_hardlink_utf8(struct archive_entry *entry, const char *target) 922302001Smm{ 923302001Smm archive_mstring_copy_utf8(&entry->ae_hardlink, target); 924302001Smm if (target != NULL) 925302001Smm entry->ae_set |= AE_SET_HARDLINK; 926302001Smm else 927302001Smm entry->ae_set &= ~AE_SET_HARDLINK; 928302001Smm} 929302001Smm 930302001Smmvoid 931228753Smmarchive_entry_copy_hardlink(struct archive_entry *entry, const char *target) 932228753Smm{ 933232153Smm archive_mstring_copy_mbs(&entry->ae_hardlink, target); 934228753Smm if (target != NULL) 935228753Smm entry->ae_set |= AE_SET_HARDLINK; 936228753Smm else 937228753Smm entry->ae_set &= ~AE_SET_HARDLINK; 938228753Smm} 939228753Smm 940228753Smmvoid 941228753Smmarchive_entry_copy_hardlink_w(struct archive_entry *entry, const wchar_t *target) 942228753Smm{ 943232153Smm archive_mstring_copy_wcs(&entry->ae_hardlink, target); 944228753Smm if (target != NULL) 945228753Smm entry->ae_set |= AE_SET_HARDLINK; 946228753Smm else 947228753Smm entry->ae_set &= ~AE_SET_HARDLINK; 948228753Smm} 949228753Smm 950228753Smmint 951228753Smmarchive_entry_update_hardlink_utf8(struct archive_entry *entry, const char *target) 952228753Smm{ 953228753Smm if (target != NULL) 954228753Smm entry->ae_set |= AE_SET_HARDLINK; 955228753Smm else 956228753Smm entry->ae_set &= ~AE_SET_HARDLINK; 957232153Smm if (archive_mstring_update_utf8(entry->archive, 958232153Smm &entry->ae_hardlink, target) == 0) 959232153Smm return (1); 960238856Smm if (errno == ENOMEM) 961238856Smm __archive_errx(1, "No memory"); 962232153Smm return (0); 963228753Smm} 964228753Smm 965232153Smmint 966232153Smm_archive_entry_copy_hardlink_l(struct archive_entry *entry, 967232153Smm const char *target, size_t len, struct archive_string_conv *sc) 968232153Smm{ 969232153Smm int r; 970232153Smm 971232153Smm r = archive_mstring_copy_mbs_len_l(&entry->ae_hardlink, 972232153Smm target, len, sc); 973232153Smm if (target != NULL && r == 0) 974232153Smm entry->ae_set |= AE_SET_HARDLINK; 975232153Smm else 976232153Smm entry->ae_set &= ~AE_SET_HARDLINK; 977232153Smm return (r); 978232153Smm} 979232153Smm 980228753Smmvoid 981228753Smmarchive_entry_set_atime(struct archive_entry *entry, time_t t, long ns) 982228753Smm{ 983232153Smm FIX_NS(t, ns); 984228753Smm entry->stat_valid = 0; 985228753Smm entry->ae_set |= AE_SET_ATIME; 986228753Smm entry->ae_stat.aest_atime = t; 987228753Smm entry->ae_stat.aest_atime_nsec = ns; 988228753Smm} 989228753Smm 990228753Smmvoid 991228753Smmarchive_entry_unset_atime(struct archive_entry *entry) 992228753Smm{ 993228753Smm archive_entry_set_atime(entry, 0, 0); 994228753Smm entry->ae_set &= ~AE_SET_ATIME; 995228753Smm} 996228753Smm 997228753Smmvoid 998232153Smmarchive_entry_set_birthtime(struct archive_entry *entry, time_t t, long ns) 999228753Smm{ 1000232153Smm FIX_NS(t, ns); 1001228753Smm entry->stat_valid = 0; 1002228753Smm entry->ae_set |= AE_SET_BIRTHTIME; 1003232153Smm entry->ae_stat.aest_birthtime = t; 1004228753Smm entry->ae_stat.aest_birthtime_nsec = ns; 1005228753Smm} 1006228753Smm 1007228753Smmvoid 1008228753Smmarchive_entry_unset_birthtime(struct archive_entry *entry) 1009228753Smm{ 1010228753Smm archive_entry_set_birthtime(entry, 0, 0); 1011228753Smm entry->ae_set &= ~AE_SET_BIRTHTIME; 1012228753Smm} 1013228753Smm 1014228753Smmvoid 1015228753Smmarchive_entry_set_ctime(struct archive_entry *entry, time_t t, long ns) 1016228753Smm{ 1017232153Smm FIX_NS(t, ns); 1018228753Smm entry->stat_valid = 0; 1019228753Smm entry->ae_set |= AE_SET_CTIME; 1020228753Smm entry->ae_stat.aest_ctime = t; 1021228753Smm entry->ae_stat.aest_ctime_nsec = ns; 1022228753Smm} 1023228753Smm 1024228753Smmvoid 1025228753Smmarchive_entry_unset_ctime(struct archive_entry *entry) 1026228753Smm{ 1027228753Smm archive_entry_set_ctime(entry, 0, 0); 1028228753Smm entry->ae_set &= ~AE_SET_CTIME; 1029228753Smm} 1030228753Smm 1031228753Smmvoid 1032228753Smmarchive_entry_set_dev(struct archive_entry *entry, dev_t d) 1033228753Smm{ 1034228753Smm entry->stat_valid = 0; 1035232153Smm entry->ae_set |= AE_SET_DEV; 1036228753Smm entry->ae_stat.aest_dev_is_broken_down = 0; 1037228753Smm entry->ae_stat.aest_dev = d; 1038228753Smm} 1039228753Smm 1040228753Smmvoid 1041228753Smmarchive_entry_set_devmajor(struct archive_entry *entry, dev_t m) 1042228753Smm{ 1043228753Smm entry->stat_valid = 0; 1044232153Smm entry->ae_set |= AE_SET_DEV; 1045228753Smm entry->ae_stat.aest_dev_is_broken_down = 1; 1046228753Smm entry->ae_stat.aest_devmajor = m; 1047228753Smm} 1048228753Smm 1049228753Smmvoid 1050228753Smmarchive_entry_set_devminor(struct archive_entry *entry, dev_t m) 1051228753Smm{ 1052228753Smm entry->stat_valid = 0; 1053232153Smm entry->ae_set |= AE_SET_DEV; 1054228753Smm entry->ae_stat.aest_dev_is_broken_down = 1; 1055228753Smm entry->ae_stat.aest_devminor = m; 1056228753Smm} 1057228753Smm 1058228753Smm/* Set symlink if symlink is already set, else set hardlink. */ 1059228753Smmvoid 1060228753Smmarchive_entry_set_link(struct archive_entry *entry, const char *target) 1061228753Smm{ 1062228753Smm if (entry->ae_set & AE_SET_SYMLINK) 1063232153Smm archive_mstring_copy_mbs(&entry->ae_symlink, target); 1064228753Smm else 1065232153Smm archive_mstring_copy_mbs(&entry->ae_hardlink, target); 1066228753Smm} 1067228753Smm 1068302001Smmvoid 1069302001Smmarchive_entry_set_link_utf8(struct archive_entry *entry, const char *target) 1070302001Smm{ 1071302001Smm if (entry->ae_set & AE_SET_SYMLINK) 1072302001Smm archive_mstring_copy_utf8(&entry->ae_symlink, target); 1073302001Smm else 1074302001Smm archive_mstring_copy_utf8(&entry->ae_hardlink, target); 1075302001Smm} 1076302001Smm 1077228753Smm/* Set symlink if symlink is already set, else set hardlink. */ 1078228753Smmvoid 1079228753Smmarchive_entry_copy_link(struct archive_entry *entry, const char *target) 1080228753Smm{ 1081228753Smm if (entry->ae_set & AE_SET_SYMLINK) 1082232153Smm archive_mstring_copy_mbs(&entry->ae_symlink, target); 1083228753Smm else 1084232153Smm archive_mstring_copy_mbs(&entry->ae_hardlink, target); 1085228753Smm} 1086228753Smm 1087228753Smm/* Set symlink if symlink is already set, else set hardlink. */ 1088228753Smmvoid 1089228753Smmarchive_entry_copy_link_w(struct archive_entry *entry, const wchar_t *target) 1090228753Smm{ 1091228753Smm if (entry->ae_set & AE_SET_SYMLINK) 1092232153Smm archive_mstring_copy_wcs(&entry->ae_symlink, target); 1093228753Smm else 1094232153Smm archive_mstring_copy_wcs(&entry->ae_hardlink, target); 1095228753Smm} 1096228753Smm 1097228753Smmint 1098228753Smmarchive_entry_update_link_utf8(struct archive_entry *entry, const char *target) 1099228753Smm{ 1100232153Smm int r; 1101228753Smm if (entry->ae_set & AE_SET_SYMLINK) 1102232153Smm r = archive_mstring_update_utf8(entry->archive, 1103232153Smm &entry->ae_symlink, target); 1104228753Smm else 1105232153Smm r = archive_mstring_update_utf8(entry->archive, 1106232153Smm &entry->ae_hardlink, target); 1107238856Smm if (r == 0) 1108238856Smm return (1); 1109238856Smm if (errno == ENOMEM) 1110238856Smm __archive_errx(1, "No memory"); 1111238856Smm return (0); 1112228753Smm} 1113228753Smm 1114232153Smmint 1115232153Smm_archive_entry_copy_link_l(struct archive_entry *entry, 1116232153Smm const char *target, size_t len, struct archive_string_conv *sc) 1117232153Smm{ 1118232153Smm int r; 1119232153Smm 1120232153Smm if (entry->ae_set & AE_SET_SYMLINK) 1121232153Smm r = archive_mstring_copy_mbs_len_l(&entry->ae_symlink, 1122232153Smm target, len, sc); 1123232153Smm else 1124232153Smm r = archive_mstring_copy_mbs_len_l(&entry->ae_hardlink, 1125232153Smm target, len, sc); 1126232153Smm return (r); 1127232153Smm} 1128232153Smm 1129228753Smmvoid 1130228753Smmarchive_entry_set_mode(struct archive_entry *entry, mode_t m) 1131228753Smm{ 1132228753Smm entry->stat_valid = 0; 1133232153Smm entry->acl.mode = m; 1134228753Smm} 1135228753Smm 1136228753Smmvoid 1137232153Smmarchive_entry_set_mtime(struct archive_entry *entry, time_t t, long ns) 1138228753Smm{ 1139232153Smm FIX_NS(t, ns); 1140228753Smm entry->stat_valid = 0; 1141228753Smm entry->ae_set |= AE_SET_MTIME; 1142232153Smm entry->ae_stat.aest_mtime = t; 1143228753Smm entry->ae_stat.aest_mtime_nsec = ns; 1144228753Smm} 1145228753Smm 1146228753Smmvoid 1147228753Smmarchive_entry_unset_mtime(struct archive_entry *entry) 1148228753Smm{ 1149228753Smm archive_entry_set_mtime(entry, 0, 0); 1150228753Smm entry->ae_set &= ~AE_SET_MTIME; 1151228753Smm} 1152228753Smm 1153228753Smmvoid 1154228753Smmarchive_entry_set_nlink(struct archive_entry *entry, unsigned int nlink) 1155228753Smm{ 1156228753Smm entry->stat_valid = 0; 1157228753Smm entry->ae_stat.aest_nlink = nlink; 1158228753Smm} 1159228753Smm 1160228753Smmvoid 1161228753Smmarchive_entry_set_pathname(struct archive_entry *entry, const char *name) 1162228753Smm{ 1163232153Smm archive_mstring_copy_mbs(&entry->ae_pathname, name); 1164228753Smm} 1165228753Smm 1166228753Smmvoid 1167302001Smmarchive_entry_set_pathname_utf8(struct archive_entry *entry, const char *name) 1168302001Smm{ 1169302001Smm archive_mstring_copy_utf8(&entry->ae_pathname, name); 1170302001Smm} 1171302001Smm 1172302001Smmvoid 1173228753Smmarchive_entry_copy_pathname(struct archive_entry *entry, const char *name) 1174228753Smm{ 1175232153Smm archive_mstring_copy_mbs(&entry->ae_pathname, name); 1176228753Smm} 1177228753Smm 1178228753Smmvoid 1179228753Smmarchive_entry_copy_pathname_w(struct archive_entry *entry, const wchar_t *name) 1180228753Smm{ 1181232153Smm archive_mstring_copy_wcs(&entry->ae_pathname, name); 1182228753Smm} 1183228753Smm 1184228753Smmint 1185228753Smmarchive_entry_update_pathname_utf8(struct archive_entry *entry, const char *name) 1186228753Smm{ 1187232153Smm if (archive_mstring_update_utf8(entry->archive, 1188232153Smm &entry->ae_pathname, name) == 0) 1189232153Smm return (1); 1190238856Smm if (errno == ENOMEM) 1191238856Smm __archive_errx(1, "No memory"); 1192232153Smm return (0); 1193228753Smm} 1194228753Smm 1195232153Smmint 1196232153Smm_archive_entry_copy_pathname_l(struct archive_entry *entry, 1197232153Smm const char *name, size_t len, struct archive_string_conv *sc) 1198232153Smm{ 1199232153Smm return (archive_mstring_copy_mbs_len_l(&entry->ae_pathname, 1200232153Smm name, len, sc)); 1201232153Smm} 1202232153Smm 1203228753Smmvoid 1204228753Smmarchive_entry_set_perm(struct archive_entry *entry, mode_t p) 1205228753Smm{ 1206228753Smm entry->stat_valid = 0; 1207232153Smm entry->acl.mode &= AE_IFMT; 1208232153Smm entry->acl.mode |= ~AE_IFMT & p; 1209228753Smm} 1210228753Smm 1211228753Smmvoid 1212228753Smmarchive_entry_set_rdev(struct archive_entry *entry, dev_t m) 1213228753Smm{ 1214228753Smm entry->stat_valid = 0; 1215228753Smm entry->ae_stat.aest_rdev = m; 1216228753Smm entry->ae_stat.aest_rdev_is_broken_down = 0; 1217228753Smm} 1218228753Smm 1219228753Smmvoid 1220228753Smmarchive_entry_set_rdevmajor(struct archive_entry *entry, dev_t m) 1221228753Smm{ 1222228753Smm entry->stat_valid = 0; 1223228753Smm entry->ae_stat.aest_rdev_is_broken_down = 1; 1224228753Smm entry->ae_stat.aest_rdevmajor = m; 1225228753Smm} 1226228753Smm 1227228753Smmvoid 1228228753Smmarchive_entry_set_rdevminor(struct archive_entry *entry, dev_t m) 1229228753Smm{ 1230228753Smm entry->stat_valid = 0; 1231228753Smm entry->ae_stat.aest_rdev_is_broken_down = 1; 1232228753Smm entry->ae_stat.aest_rdevminor = m; 1233228753Smm} 1234228753Smm 1235228753Smmvoid 1236315433Smmarchive_entry_set_size(struct archive_entry *entry, la_int64_t s) 1237228753Smm{ 1238228753Smm entry->stat_valid = 0; 1239228753Smm entry->ae_stat.aest_size = s; 1240228753Smm entry->ae_set |= AE_SET_SIZE; 1241228753Smm} 1242228753Smm 1243228753Smmvoid 1244228753Smmarchive_entry_unset_size(struct archive_entry *entry) 1245228753Smm{ 1246228753Smm archive_entry_set_size(entry, 0); 1247228753Smm entry->ae_set &= ~AE_SET_SIZE; 1248228753Smm} 1249228753Smm 1250228753Smmvoid 1251228753Smmarchive_entry_copy_sourcepath(struct archive_entry *entry, const char *path) 1252228753Smm{ 1253232153Smm archive_mstring_copy_mbs(&entry->ae_sourcepath, path); 1254228753Smm} 1255228753Smm 1256228753Smmvoid 1257232153Smmarchive_entry_copy_sourcepath_w(struct archive_entry *entry, const wchar_t *path) 1258232153Smm{ 1259232153Smm archive_mstring_copy_wcs(&entry->ae_sourcepath, path); 1260232153Smm} 1261232153Smm 1262232153Smmvoid 1263228753Smmarchive_entry_set_symlink(struct archive_entry *entry, const char *linkname) 1264228753Smm{ 1265232153Smm archive_mstring_copy_mbs(&entry->ae_symlink, linkname); 1266228753Smm if (linkname != NULL) 1267228753Smm entry->ae_set |= AE_SET_SYMLINK; 1268228753Smm else 1269228753Smm entry->ae_set &= ~AE_SET_SYMLINK; 1270228753Smm} 1271228753Smm 1272228753Smmvoid 1273348608Smmarchive_entry_set_symlink_type(struct archive_entry *entry, int type) 1274348608Smm{ 1275348608Smm entry->ae_symlink_type = type; 1276348608Smm} 1277348608Smm 1278348608Smmvoid 1279302001Smmarchive_entry_set_symlink_utf8(struct archive_entry *entry, const char *linkname) 1280302001Smm{ 1281302001Smm archive_mstring_copy_utf8(&entry->ae_symlink, linkname); 1282302001Smm if (linkname != NULL) 1283302001Smm entry->ae_set |= AE_SET_SYMLINK; 1284302001Smm else 1285302001Smm entry->ae_set &= ~AE_SET_SYMLINK; 1286302001Smm} 1287302001Smm 1288302001Smmvoid 1289228753Smmarchive_entry_copy_symlink(struct archive_entry *entry, const char *linkname) 1290228753Smm{ 1291232153Smm archive_mstring_copy_mbs(&entry->ae_symlink, linkname); 1292228753Smm if (linkname != NULL) 1293228753Smm entry->ae_set |= AE_SET_SYMLINK; 1294228753Smm else 1295228753Smm entry->ae_set &= ~AE_SET_SYMLINK; 1296228753Smm} 1297228753Smm 1298228753Smmvoid 1299228753Smmarchive_entry_copy_symlink_w(struct archive_entry *entry, const wchar_t *linkname) 1300228753Smm{ 1301232153Smm archive_mstring_copy_wcs(&entry->ae_symlink, linkname); 1302228753Smm if (linkname != NULL) 1303228753Smm entry->ae_set |= AE_SET_SYMLINK; 1304228753Smm else 1305228753Smm entry->ae_set &= ~AE_SET_SYMLINK; 1306228753Smm} 1307228753Smm 1308228753Smmint 1309228753Smmarchive_entry_update_symlink_utf8(struct archive_entry *entry, const char *linkname) 1310228753Smm{ 1311228753Smm if (linkname != NULL) 1312228753Smm entry->ae_set |= AE_SET_SYMLINK; 1313228753Smm else 1314228753Smm entry->ae_set &= ~AE_SET_SYMLINK; 1315232153Smm if (archive_mstring_update_utf8(entry->archive, 1316232153Smm &entry->ae_symlink, linkname) == 0) 1317232153Smm return (1); 1318238856Smm if (errno == ENOMEM) 1319238856Smm __archive_errx(1, "No memory"); 1320232153Smm return (0); 1321228753Smm} 1322228753Smm 1323232153Smmint 1324232153Smm_archive_entry_copy_symlink_l(struct archive_entry *entry, 1325232153Smm const char *linkname, size_t len, struct archive_string_conv *sc) 1326232153Smm{ 1327232153Smm int r; 1328232153Smm 1329232153Smm r = archive_mstring_copy_mbs_len_l(&entry->ae_symlink, 1330232153Smm linkname, len, sc); 1331232153Smm if (linkname != NULL && r == 0) 1332232153Smm entry->ae_set |= AE_SET_SYMLINK; 1333232153Smm else 1334232153Smm entry->ae_set &= ~AE_SET_SYMLINK; 1335232153Smm return (r); 1336232153Smm} 1337232153Smm 1338228753Smmvoid 1339315433Smmarchive_entry_set_uid(struct archive_entry *entry, la_int64_t u) 1340228753Smm{ 1341228753Smm entry->stat_valid = 0; 1342228753Smm entry->ae_stat.aest_uid = u; 1343228753Smm} 1344228753Smm 1345228753Smmvoid 1346228753Smmarchive_entry_set_uname(struct archive_entry *entry, const char *name) 1347228753Smm{ 1348232153Smm archive_mstring_copy_mbs(&entry->ae_uname, name); 1349228753Smm} 1350228753Smm 1351228753Smmvoid 1352302001Smmarchive_entry_set_uname_utf8(struct archive_entry *entry, const char *name) 1353302001Smm{ 1354302001Smm archive_mstring_copy_utf8(&entry->ae_uname, name); 1355302001Smm} 1356302001Smm 1357302001Smmvoid 1358228753Smmarchive_entry_copy_uname(struct archive_entry *entry, const char *name) 1359228753Smm{ 1360232153Smm archive_mstring_copy_mbs(&entry->ae_uname, name); 1361228753Smm} 1362228753Smm 1363228753Smmvoid 1364228753Smmarchive_entry_copy_uname_w(struct archive_entry *entry, const wchar_t *name) 1365228753Smm{ 1366232153Smm archive_mstring_copy_wcs(&entry->ae_uname, name); 1367228753Smm} 1368228753Smm 1369228753Smmint 1370228753Smmarchive_entry_update_uname_utf8(struct archive_entry *entry, const char *name) 1371228753Smm{ 1372232153Smm if (archive_mstring_update_utf8(entry->archive, 1373232153Smm &entry->ae_uname, name) == 0) 1374232153Smm return (1); 1375238856Smm if (errno == ENOMEM) 1376238856Smm __archive_errx(1, "No memory"); 1377232153Smm return (0); 1378228753Smm} 1379228753Smm 1380302001Smmvoid 1381302001Smmarchive_entry_set_is_data_encrypted(struct archive_entry *entry, char is_encrypted) 1382302001Smm{ 1383302001Smm if (is_encrypted) { 1384302001Smm entry->encryption |= AE_ENCRYPTION_DATA; 1385302001Smm } else { 1386302001Smm entry->encryption &= ~AE_ENCRYPTION_DATA; 1387302001Smm } 1388302001Smm} 1389302001Smm 1390302001Smmvoid 1391302001Smmarchive_entry_set_is_metadata_encrypted(struct archive_entry *entry, char is_encrypted) 1392302001Smm{ 1393302001Smm if (is_encrypted) { 1394302001Smm entry->encryption |= AE_ENCRYPTION_METADATA; 1395302001Smm } else { 1396302001Smm entry->encryption &= ~AE_ENCRYPTION_METADATA; 1397302001Smm } 1398302001Smm} 1399302001Smm 1400232153Smmint 1401232153Smm_archive_entry_copy_uname_l(struct archive_entry *entry, 1402232153Smm const char *name, size_t len, struct archive_string_conv *sc) 1403232153Smm{ 1404232153Smm return (archive_mstring_copy_mbs_len_l(&entry->ae_uname, 1405232153Smm name, len, sc)); 1406232153Smm} 1407232153Smm 1408232153Smmconst void * 1409232153Smmarchive_entry_mac_metadata(struct archive_entry *entry, size_t *s) 1410232153Smm{ 1411232153Smm *s = entry->mac_metadata_size; 1412232153Smm return entry->mac_metadata; 1413232153Smm} 1414232153Smm 1415232153Smmvoid 1416232153Smmarchive_entry_copy_mac_metadata(struct archive_entry *entry, 1417232153Smm const void *p, size_t s) 1418232153Smm{ 1419232153Smm free(entry->mac_metadata); 1420232153Smm if (p == NULL || s == 0) { 1421232153Smm entry->mac_metadata = NULL; 1422232153Smm entry->mac_metadata_size = 0; 1423232153Smm } else { 1424232153Smm entry->mac_metadata_size = s; 1425232153Smm entry->mac_metadata = malloc(s); 1426232153Smm if (entry->mac_metadata == NULL) 1427232153Smm abort(); 1428232153Smm memcpy(entry->mac_metadata, p, s); 1429232153Smm } 1430232153Smm} 1431232153Smm 1432368708Smm/* Digest handling */ 1433368708Smmconst unsigned char * 1434368708Smmarchive_entry_digest(struct archive_entry *entry, int type) 1435368708Smm{ 1436368708Smm switch (type) { 1437368708Smm case ARCHIVE_ENTRY_DIGEST_MD5: 1438368708Smm return entry->digest.md5; 1439368708Smm case ARCHIVE_ENTRY_DIGEST_RMD160: 1440368708Smm return entry->digest.rmd160; 1441368708Smm case ARCHIVE_ENTRY_DIGEST_SHA1: 1442368708Smm return entry->digest.sha1; 1443368708Smm case ARCHIVE_ENTRY_DIGEST_SHA256: 1444368708Smm return entry->digest.sha256; 1445368708Smm case ARCHIVE_ENTRY_DIGEST_SHA384: 1446368708Smm return entry->digest.sha384; 1447368708Smm case ARCHIVE_ENTRY_DIGEST_SHA512: 1448368708Smm return entry->digest.sha512; 1449368708Smm default: 1450368708Smm return NULL; 1451368708Smm } 1452368708Smm} 1453368708Smm 1454368708Smmint 1455368708Smmarchive_entry_set_digest(struct archive_entry *entry, int type, 1456368708Smm const unsigned char *digest) 1457368708Smm{ 1458368708Smm#define copy_digest(_e, _t, _d)\ 1459368708Smm memcpy(_e->digest._t, _d, sizeof(_e->digest._t)) 1460368708Smm 1461368708Smm switch (type) { 1462368708Smm case ARCHIVE_ENTRY_DIGEST_MD5: 1463368708Smm copy_digest(entry, md5, digest); 1464368708Smm break; 1465368708Smm case ARCHIVE_ENTRY_DIGEST_RMD160: 1466368708Smm copy_digest(entry, rmd160, digest); 1467368708Smm break; 1468368708Smm case ARCHIVE_ENTRY_DIGEST_SHA1: 1469368708Smm copy_digest(entry, sha1, digest); 1470368708Smm break; 1471368708Smm case ARCHIVE_ENTRY_DIGEST_SHA256: 1472368708Smm copy_digest(entry, sha256, digest); 1473368708Smm break; 1474368708Smm case ARCHIVE_ENTRY_DIGEST_SHA384: 1475368708Smm copy_digest(entry, sha384, digest); 1476368708Smm break; 1477368708Smm case ARCHIVE_ENTRY_DIGEST_SHA512: 1478368708Smm copy_digest(entry, sha512, digest); 1479368708Smm break; 1480368708Smm default: 1481368708Smm return ARCHIVE_WARN; 1482368708Smm } 1483368708Smm 1484368708Smm return ARCHIVE_OK; 1485368708Smm#undef copy_digest 1486368708Smm} 1487368708Smm 1488228753Smm/* 1489228753Smm * ACL management. The following would, of course, be a lot simpler 1490228753Smm * if: 1) the last draft of POSIX.1e were a really thorough and 1491228753Smm * complete standard that addressed the needs of ACL archiving and 2) 1492228753Smm * everyone followed it faithfully. Alas, neither is true, so the 1493228753Smm * following is a lot more complex than might seem necessary to the 1494228753Smm * uninitiated. 1495228753Smm */ 1496228753Smm 1497232153Smmstruct archive_acl * 1498232153Smmarchive_entry_acl(struct archive_entry *entry) 1499232153Smm{ 1500232153Smm return &entry->acl; 1501232153Smm} 1502232153Smm 1503228753Smmvoid 1504228753Smmarchive_entry_acl_clear(struct archive_entry *entry) 1505228753Smm{ 1506232153Smm archive_acl_clear(&entry->acl); 1507228753Smm} 1508228753Smm 1509228753Smm/* 1510228753Smm * Add a single ACL entry to the internal list of ACL data. 1511228753Smm */ 1512232153Smmint 1513228753Smmarchive_entry_acl_add_entry(struct archive_entry *entry, 1514228753Smm int type, int permset, int tag, int id, const char *name) 1515228753Smm{ 1516232153Smm return archive_acl_add_entry(&entry->acl, type, permset, tag, id, name); 1517228753Smm} 1518228753Smm 1519228753Smm/* 1520228753Smm * As above, but with a wide-character name. 1521228753Smm */ 1522232153Smmint 1523228753Smmarchive_entry_acl_add_entry_w(struct archive_entry *entry, 1524228753Smm int type, int permset, int tag, int id, const wchar_t *name) 1525228753Smm{ 1526232153Smm return archive_acl_add_entry_w_len(&entry->acl, 1527232153Smm type, permset, tag, id, name, wcslen(name)); 1528228753Smm} 1529228753Smm 1530228753Smm/* 1531311042Smm * Return a bitmask of ACL types in an archive entry ACL list 1532311042Smm */ 1533311042Smmint 1534311042Smmarchive_entry_acl_types(struct archive_entry *entry) 1535311042Smm{ 1536313571Smm return (archive_acl_types(&entry->acl)); 1537311042Smm} 1538311042Smm 1539311042Smm/* 1540228753Smm * Return a count of entries matching "want_type". 1541228753Smm */ 1542228753Smmint 1543228753Smmarchive_entry_acl_count(struct archive_entry *entry, int want_type) 1544228753Smm{ 1545232153Smm return archive_acl_count(&entry->acl, want_type); 1546228753Smm} 1547228753Smm 1548228753Smm/* 1549228753Smm * Prepare for reading entries from the ACL data. Returns a count 1550228753Smm * of entries matching "want_type", or zero if there are no 1551228753Smm * non-extended ACL entries of that type. 1552228753Smm */ 1553228753Smmint 1554228753Smmarchive_entry_acl_reset(struct archive_entry *entry, int want_type) 1555228753Smm{ 1556232153Smm return archive_acl_reset(&entry->acl, want_type); 1557228753Smm} 1558228753Smm 1559228753Smm/* 1560228753Smm * Return the next ACL entry in the list. Fake entries for the 1561228753Smm * standard permissions and include them in the returned list. 1562228753Smm */ 1563228753Smmint 1564228753Smmarchive_entry_acl_next(struct archive_entry *entry, int want_type, int *type, 1565228753Smm int *permset, int *tag, int *id, const char **name) 1566228753Smm{ 1567238856Smm int r; 1568238856Smm r = archive_acl_next(entry->archive, &entry->acl, want_type, type, 1569238856Smm permset, tag, id, name); 1570238856Smm if (r == ARCHIVE_FATAL && errno == ENOMEM) 1571238856Smm __archive_errx(1, "No memory"); 1572238856Smm return (r); 1573228753Smm} 1574228753Smm 1575228753Smm/* 1576313571Smm * Generate a text version of the ACL. The flags parameter controls 1577228753Smm * the style of the generated ACL. 1578228753Smm */ 1579313571Smmwchar_t * 1580337352Smmarchive_entry_acl_to_text_w(struct archive_entry *entry, la_ssize_t *len, 1581313571Smm int flags) 1582313571Smm{ 1583313571Smm return (archive_acl_to_text_w(&entry->acl, len, flags, 1584313571Smm entry->archive)); 1585313571Smm} 1586313571Smm 1587313571Smmchar * 1588337352Smmarchive_entry_acl_to_text(struct archive_entry *entry, la_ssize_t *len, 1589313571Smm int flags) 1590313571Smm{ 1591313571Smm return (archive_acl_to_text_l(&entry->acl, len, flags, NULL)); 1592313571Smm} 1593313571Smm 1594313571Smmchar * 1595313571Smm_archive_entry_acl_to_text_l(struct archive_entry *entry, ssize_t *len, 1596313571Smm int flags, struct archive_string_conv *sc) 1597313571Smm{ 1598313571Smm return (archive_acl_to_text_l(&entry->acl, len, flags, sc)); 1599313571Smm} 1600313571Smm 1601313571Smm/* 1602313571Smm * ACL text parser. 1603313571Smm */ 1604313571Smmint 1605313571Smmarchive_entry_acl_from_text_w(struct archive_entry *entry, 1606313571Smm const wchar_t *wtext, int type) 1607313571Smm{ 1608313571Smm return (archive_acl_from_text_w(&entry->acl, wtext, type)); 1609313571Smm} 1610313571Smm 1611313571Smmint 1612313571Smmarchive_entry_acl_from_text(struct archive_entry *entry, 1613313571Smm const char *text, int type) 1614313571Smm{ 1615313571Smm return (archive_acl_from_text_l(&entry->acl, text, type, NULL)); 1616313571Smm} 1617313571Smm 1618313571Smmint 1619313571Smm_archive_entry_acl_from_text_l(struct archive_entry *entry, const char *text, 1620313571Smm int type, struct archive_string_conv *sc) 1621313571Smm{ 1622313571Smm return (archive_acl_from_text_l(&entry->acl, text, type, sc)); 1623313571Smm} 1624313571Smm 1625313571Smm/* Deprecated */ 1626313571Smmstatic int 1627313571Smmarchive_entry_acl_text_compat(int *flags) 1628313571Smm{ 1629313571Smm if ((*flags & ARCHIVE_ENTRY_ACL_TYPE_POSIX1E) == 0) 1630313571Smm return (1); 1631313571Smm 1632313571Smm /* ABI compat with old ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID */ 1633313571Smm if ((*flags & OLD_ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID) != 0) 1634313571Smm *flags |= ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID; 1635313571Smm 1636313571Smm /* ABI compat with old ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT */ 1637313571Smm if ((*flags & OLD_ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT) != 0) 1638313571Smm *flags |= ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT; 1639313571Smm 1640313571Smm *flags |= ARCHIVE_ENTRY_ACL_STYLE_SEPARATOR_COMMA; 1641313571Smm 1642313571Smm return (0); 1643313571Smm} 1644313571Smm 1645313571Smm/* Deprecated */ 1646228753Smmconst wchar_t * 1647228753Smmarchive_entry_acl_text_w(struct archive_entry *entry, int flags) 1648228753Smm{ 1649344674Smm free(entry->acl.acl_text_w); 1650344674Smm entry->acl.acl_text_w = NULL; 1651313571Smm if (archive_entry_acl_text_compat(&flags) == 0) 1652313571Smm entry->acl.acl_text_w = archive_acl_to_text_w(&entry->acl, 1653313571Smm NULL, flags, entry->archive); 1654313571Smm return (entry->acl.acl_text_w); 1655228753Smm} 1656228753Smm 1657313571Smm/* Deprecated */ 1658232153Smmconst char * 1659232153Smmarchive_entry_acl_text(struct archive_entry *entry, int flags) 1660228753Smm{ 1661344674Smm free(entry->acl.acl_text); 1662344674Smm entry->acl.acl_text = NULL; 1663313571Smm if (archive_entry_acl_text_compat(&flags) == 0) 1664313571Smm entry->acl.acl_text = archive_acl_to_text_l(&entry->acl, NULL, 1665313571Smm flags, NULL); 1666313571Smm 1667313571Smm return (entry->acl.acl_text); 1668228753Smm} 1669228753Smm 1670313571Smm/* Deprecated */ 1671228753Smmint 1672232153Smm_archive_entry_acl_text_l(struct archive_entry *entry, int flags, 1673232153Smm const char **acl_text, size_t *len, struct archive_string_conv *sc) 1674228753Smm{ 1675344674Smm free(entry->acl.acl_text); 1676344674Smm entry->acl.acl_text = NULL; 1677313571Smm 1678313571Smm if (archive_entry_acl_text_compat(&flags) == 0) 1679313571Smm entry->acl.acl_text = archive_acl_to_text_l(&entry->acl, 1680313571Smm (ssize_t *)len, flags, sc); 1681313571Smm 1682313571Smm *acl_text = entry->acl.acl_text; 1683313571Smm 1684313571Smm return (0); 1685228753Smm} 1686228753Smm 1687228753Smm/* 1688228753Smm * Following code is modified from UC Berkeley sources, and 1689228753Smm * is subject to the following copyright notice. 1690228753Smm */ 1691228753Smm 1692228753Smm/*- 1693228753Smm * Copyright (c) 1993 1694228753Smm * The Regents of the University of California. All rights reserved. 1695228753Smm * 1696228753Smm * Redistribution and use in source and binary forms, with or without 1697228753Smm * modification, are permitted provided that the following conditions 1698228753Smm * are met: 1699228753Smm * 1. Redistributions of source code must retain the above copyright 1700228753Smm * notice, this list of conditions and the following disclaimer. 1701228753Smm * 2. Redistributions in binary form must reproduce the above copyright 1702228753Smm * notice, this list of conditions and the following disclaimer in the 1703228753Smm * documentation and/or other materials provided with the distribution. 1704228753Smm * 4. Neither the name of the University nor the names of its contributors 1705228753Smm * may be used to endorse or promote products derived from this software 1706228753Smm * without specific prior written permission. 1707228753Smm * 1708228753Smm * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 1709228753Smm * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1710228753Smm * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1711228753Smm * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 1712228753Smm * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1713228753Smm * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 1714228753Smm * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 1715228753Smm * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 1716228753Smm * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 1717228753Smm * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 1718228753Smm * SUCH DAMAGE. 1719228753Smm */ 1720228753Smm 1721346105Smm/* 1722346105Smm * Supported file flags on FreeBSD and Mac OS: 1723346105Smm * sappnd,sappend SF_APPEND 1724346105Smm * arch,archived SF_ARCHIVED 1725346105Smm * schg,schange,simmutable SF_IMMUTABLE 1726346105Smm * sunlnk,sunlink SF_NOUNLINK (FreeBSD only) 1727346105Smm * uappnd,uappend UF_APPEND 1728346105Smm * compressed UF_COMPRESSED (Mac OS only) 1729346105Smm * hidden,uhidden UF_HIDDEN 1730346105Smm * uchg,uchange,uimmutable UF_IMMUTABLE 1731346105Smm * nodump UF_NODUMP 1732346105Smm * uunlnk,uunlink UF_NOUNLINK (FreeBSD only) 1733346105Smm * offline,uoffline UF_OFFLINE (FreeBSD only) 1734346105Smm * opaque UF_OPAQUE 1735346105Smm * rdonly,urdonly,readonly UF_READONLY (FreeBSD only) 1736346105Smm * reparse,ureparse UF_REPARSE (FreeBSD only) 1737346105Smm * sparse,usparse UF_SPARSE (FreeBSD only) 1738346105Smm * system,usystem UF_SYSTEM (FreeBSD only) 1739346105Smm * 1740346105Smm * See chflags(2) for more information 1741346105Smm * 1742346105Smm * Supported file attributes on Linux: 1743346105Smm * a append only FS_APPEND_FL sappnd 1744346105Smm * A no atime updates FS_NOATIME_FL atime 1745346105Smm * c compress FS_COMPR_FL compress 1746346105Smm * C no copy on write FS_NOCOW_FL cow 1747346105Smm * d no dump FS_NODUMP_FL dump 1748346105Smm * D synchronous directory updates FS_DIRSYNC_FL dirsync 1749346105Smm * i immutable FS_IMMUTABLE_FL schg 1750346105Smm * j data journalling FS_JOURNAL_DATA_FL journal 1751346105Smm * P project hierarchy FS_PROJINHERIT_FL projinherit 1752346105Smm * s secure deletion FS_SECRM_FL securedeletion 1753346105Smm * S synchronous updates FS_SYNC_FL sync 1754346105Smm * t no tail-merging FS_NOTAIL_FL tail 1755346105Smm * T top of directory hierarchy FS_TOPDIR_FL topdir 1756346105Smm * u undeletable FS_UNRM_FL undel 1757346105Smm * 1758346105Smm * See ioctl_iflags(2) for more information 1759346105Smm * 1760346105Smm * Equivalent file flags supported on FreeBSD / Mac OS and Linux: 1761346105Smm * SF_APPEND FS_APPEND_FL sappnd 1762346105Smm * SF_IMMUTABLE FS_IMMUTABLE_FL schg 1763346105Smm * UF_NODUMP FS_NODUMP_FL nodump 1764346105Smm */ 1765346105Smm 1766316338Smmstatic const struct flag { 1767228753Smm const char *name; 1768228753Smm const wchar_t *wname; 1769228753Smm unsigned long set; 1770228753Smm unsigned long clear; 1771358090Smm} fileflags[] = { 1772228753Smm /* Preferred (shorter) names per flag first, all prefixed by "no" */ 1773228753Smm#ifdef SF_APPEND 1774346105Smm { "nosappnd", L"nosappnd", SF_APPEND, 0}, 1775346105Smm { "nosappend", L"nosappend", SF_APPEND, 0}, 1776228753Smm#endif 1777315433Smm#if defined(FS_APPEND_FL) /* 'a' */ 1778346105Smm { "nosappnd", L"nosappnd", FS_APPEND_FL, 0}, 1779346105Smm { "nosappend", L"nosappend", FS_APPEND_FL, 0}, 1780315433Smm#elif defined(EXT2_APPEND_FL) /* 'a' */ 1781346105Smm { "nosappnd", L"nosappnd", EXT2_APPEND_FL, 0}, 1782346105Smm { "nosappend", L"nosappend", EXT2_APPEND_FL, 0}, 1783228753Smm#endif 1784228753Smm#ifdef SF_ARCHIVED 1785346105Smm { "noarch", L"noarch", SF_ARCHIVED, 0}, 1786346105Smm { "noarchived", L"noarchived", SF_ARCHIVED, 0}, 1787228753Smm#endif 1788228753Smm#ifdef SF_IMMUTABLE 1789346105Smm { "noschg", L"noschg", SF_IMMUTABLE, 0}, 1790346105Smm { "noschange", L"noschange", SF_IMMUTABLE, 0}, 1791346105Smm { "nosimmutable", L"nosimmutable", SF_IMMUTABLE, 0}, 1792228753Smm#endif 1793315433Smm#if defined(FS_IMMUTABLE_FL) /* 'i' */ 1794346105Smm { "noschg", L"noschg", FS_IMMUTABLE_FL, 0}, 1795346105Smm { "noschange", L"noschange", FS_IMMUTABLE_FL, 0}, 1796346105Smm { "nosimmutable", L"nosimmutable", FS_IMMUTABLE_FL, 0}, 1797315433Smm#elif defined(EXT2_IMMUTABLE_FL) /* 'i' */ 1798346105Smm { "noschg", L"noschg", EXT2_IMMUTABLE_FL, 0}, 1799346105Smm { "noschange", L"noschange", EXT2_IMMUTABLE_FL, 0}, 1800346105Smm { "nosimmutable", L"nosimmutable", EXT2_IMMUTABLE_FL, 0}, 1801228753Smm#endif 1802228753Smm#ifdef SF_NOUNLINK 1803346105Smm { "nosunlnk", L"nosunlnk", SF_NOUNLINK, 0}, 1804346105Smm { "nosunlink", L"nosunlink", SF_NOUNLINK, 0}, 1805228753Smm#endif 1806228753Smm#ifdef UF_APPEND 1807346105Smm { "nouappnd", L"nouappnd", UF_APPEND, 0}, 1808346105Smm { "nouappend", L"nouappend", UF_APPEND, 0}, 1809228753Smm#endif 1810228753Smm#ifdef UF_IMMUTABLE 1811346105Smm { "nouchg", L"nouchg", UF_IMMUTABLE, 0}, 1812346105Smm { "nouchange", L"nouchange", UF_IMMUTABLE, 0}, 1813346105Smm { "nouimmutable", L"nouimmutable", UF_IMMUTABLE, 0}, 1814228753Smm#endif 1815228753Smm#ifdef UF_NODUMP 1816228753Smm { "nodump", L"nodump", 0, UF_NODUMP}, 1817228753Smm#endif 1818315433Smm#if defined(FS_NODUMP_FL) /* 'd' */ 1819315433Smm { "nodump", L"nodump", 0, FS_NODUMP_FL}, 1820346105Smm#elif defined(EXT2_NODUMP_FL) 1821228753Smm { "nodump", L"nodump", 0, EXT2_NODUMP_FL}, 1822228753Smm#endif 1823228753Smm#ifdef UF_OPAQUE 1824346105Smm { "noopaque", L"noopaque", UF_OPAQUE, 0}, 1825228753Smm#endif 1826228753Smm#ifdef UF_NOUNLINK 1827346105Smm { "nouunlnk", L"nouunlnk", UF_NOUNLINK, 0}, 1828346105Smm { "nouunlink", L"nouunlink", UF_NOUNLINK, 0}, 1829228753Smm#endif 1830248616Smm#ifdef UF_COMPRESSED 1831346105Smm /* Mac OS */ 1832346105Smm { "nocompressed", L"nocompressed", UF_COMPRESSED, 0}, 1833248616Smm#endif 1834316338Smm#ifdef UF_HIDDEN 1835346105Smm { "nohidden", L"nohidden", UF_HIDDEN, 0}, 1836346105Smm { "nouhidden", L"nouhidden", UF_HIDDEN, 0}, 1837316338Smm#endif 1838348608Smm#ifdef FILE_ATTRIBUTE_HIDDEN 1839348608Smm { "nohidden", L"nohidden", FILE_ATTRIBUTE_HIDDEN, 0}, 1840348608Smm { "nouhidden", L"nouhidden", FILE_ATTRIBUTE_HIDDEN, 0}, 1841348608Smm#endif 1842346105Smm#ifdef UF_OFFLINE 1843346105Smm { "nooffline", L"nooffline", UF_OFFLINE, 0}, 1844346105Smm { "nouoffline", L"nouoffline", UF_OFFLINE, 0}, 1845228753Smm#endif 1846346105Smm#ifdef UF_READONLY 1847346105Smm { "nordonly", L"nordonly", UF_READONLY, 0}, 1848346105Smm { "nourdonly", L"nourdonly", UF_READONLY, 0}, 1849346105Smm { "noreadonly", L"noreadonly", UF_READONLY, 0}, 1850228753Smm#endif 1851348608Smm#ifdef FILE_ATTRIBUTE_READONLY 1852348608Smm { "nordonly", L"nordonly", FILE_ATTRIBUTE_READONLY, 0}, 1853348608Smm { "nourdonly", L"nourdonly", FILE_ATTRIBUTE_READONLY, 0}, 1854348608Smm { "noreadonly", L"noreadonly", FILE_ATTRIBUTE_READONLY, 0}, 1855348608Smm#endif 1856346105Smm#ifdef UF_SPARSE 1857346105Smm { "nosparse", L"nosparse", UF_SPARSE, 0}, 1858346105Smm { "nousparse", L"nousparse", UF_SPARSE, 0}, 1859228753Smm#endif 1860346105Smm#ifdef UF_REPARSE 1861346105Smm { "noreparse", L"noreparse", UF_REPARSE, 0}, 1862346105Smm { "noureparse", L"noureparse", UF_REPARSE, 0}, 1863228753Smm#endif 1864346105Smm#ifdef UF_SYSTEM 1865346105Smm { "nosystem", L"nosystem", UF_SYSTEM, 0}, 1866346105Smm { "nousystem", L"nousystem", UF_SYSTEM, 0}, 1867228753Smm#endif 1868348608Smm#ifdef FILE_ATTRIBUTE_SYSTEM 1869348608Smm { "nosystem", L"nosystem", FILE_ATTRIBUTE_SYSTEM, 0}, 1870348608Smm { "nousystem", L"nousystem", FILE_ATTRIBUTE_SYSTEM, 0}, 1871348608Smm#endif 1872346105Smm#if defined(FS_UNRM_FL) /* 'u' */ 1873346105Smm { "noundel", L"noundel", FS_UNRM_FL, 0}, 1874346105Smm#elif defined(EXT2_UNRM_FL) 1875346105Smm { "noundel", L"noundel", EXT2_UNRM_FL, 0}, 1876346105Smm#endif 1877228753Smm 1878346105Smm#if defined(FS_COMPR_FL) /* 'c' */ 1879346105Smm { "nocompress", L"nocompress", FS_COMPR_FL, 0}, 1880346105Smm#elif defined(EXT2_COMPR_FL) 1881346105Smm { "nocompress", L"nocompress", EXT2_COMPR_FL, 0}, 1882228753Smm#endif 1883228753Smm 1884346105Smm#if defined(FS_NOATIME_FL) /* 'A' */ 1885346105Smm { "noatime", L"noatime", 0, FS_NOATIME_FL}, 1886346105Smm#elif defined(EXT2_NOATIME_FL) 1887346105Smm { "noatime", L"noatime", 0, EXT2_NOATIME_FL}, 1888315433Smm#endif 1889346105Smm#if defined(FS_DIRSYNC_FL) /* 'D' */ 1890346105Smm { "nodirsync", L"nodirsync", FS_DIRSYNC_FL, 0}, 1891315433Smm#elif defined(EXT2_DIRSYNC_FL) 1892346105Smm { "nodirsync", L"nodirsync", EXT2_DIRSYNC_FL, 0}, 1893228753Smm#endif 1894346105Smm#if defined(FS_JOURNAL_DATA_FL) /* 'j' */ 1895346105Smm { "nojournal-data",L"nojournal-data", FS_JOURNAL_DATA_FL, 0}, 1896346105Smm { "nojournal", L"nojournal", FS_JOURNAL_DATA_FL, 0}, 1897315433Smm#elif defined(EXT3_JOURNAL_DATA_FL) 1898346105Smm { "nojournal-data",L"nojournal-data", EXT3_JOURNAL_DATA_FL, 0}, 1899346105Smm { "nojournal", L"nojournal", EXT3_JOURNAL_DATA_FL, 0}, 1900228753Smm#endif 1901346105Smm#if defined(FS_SECRM_FL) /* 's' */ 1902346105Smm { "nosecdel", L"nosecdel", FS_SECRM_FL, 0}, 1903346105Smm { "nosecuredeletion",L"nosecuredeletion",FS_SECRM_FL, 0}, 1904315433Smm#elif defined(EXT2_SECRM_FL) 1905346105Smm { "nosecdel", L"nosecdel", EXT2_SECRM_FL, 0}, 1906346105Smm { "nosecuredeletion",L"nosecuredeletion",EXT2_SECRM_FL, 0}, 1907228753Smm#endif 1908346105Smm#if defined(FS_SYNC_FL) /* 'S' */ 1909346105Smm { "nosync", L"nosync", FS_SYNC_FL, 0}, 1910315433Smm#elif defined(EXT2_SYNC_FL) 1911346105Smm { "nosync", L"nosync", EXT2_SYNC_FL, 0}, 1912228753Smm#endif 1913346105Smm#if defined(FS_NOTAIL_FL) /* 't' */ 1914346105Smm { "notail", L"notail", 0, FS_NOTAIL_FL}, 1915315433Smm#elif defined(EXT2_NOTAIL_FL) 1916346105Smm { "notail", L"notail", 0, EXT2_NOTAIL_FL}, 1917228753Smm#endif 1918346105Smm#if defined(FS_TOPDIR_FL) /* 'T' */ 1919346105Smm { "notopdir", L"notopdir", FS_TOPDIR_FL, 0}, 1920315433Smm#elif defined(EXT2_TOPDIR_FL) 1921346105Smm { "notopdir", L"notopdir", EXT2_TOPDIR_FL, 0}, 1922228753Smm#endif 1923346105Smm#ifdef FS_NOCOW_FL /* 'C' */ 1924346105Smm { "nocow", L"nocow", 0, FS_NOCOW_FL}, 1925315433Smm#endif 1926346105Smm#ifdef FS_PROJINHERIT_FL /* 'P' */ 1927346105Smm { "noprojinherit",L"noprojinherit", FS_PROJINHERIT_FL, 0}, 1928315433Smm#endif 1929346105Smm { NULL, NULL, 0, 0} 1930228753Smm}; 1931228753Smm 1932228753Smm/* 1933228753Smm * fflagstostr -- 1934228753Smm * Convert file flags to a comma-separated string. If no flags 1935228753Smm * are set, return the empty string. 1936228753Smm */ 1937228753Smmstatic char * 1938228753Smmae_fflagstostr(unsigned long bitset, unsigned long bitclear) 1939228753Smm{ 1940228753Smm char *string, *dp; 1941228753Smm const char *sp; 1942228753Smm unsigned long bits; 1943316338Smm const struct flag *flag; 1944228753Smm size_t length; 1945228753Smm 1946228753Smm bits = bitset | bitclear; 1947228753Smm length = 0; 1948358090Smm for (flag = fileflags; flag->name != NULL; flag++) 1949228753Smm if (bits & (flag->set | flag->clear)) { 1950228753Smm length += strlen(flag->name) + 1; 1951228753Smm bits &= ~(flag->set | flag->clear); 1952228753Smm } 1953228753Smm 1954228753Smm if (length == 0) 1955228753Smm return (NULL); 1956228753Smm string = (char *)malloc(length); 1957228753Smm if (string == NULL) 1958228753Smm return (NULL); 1959228753Smm 1960228753Smm dp = string; 1961358090Smm for (flag = fileflags; flag->name != NULL; flag++) { 1962228753Smm if (bitset & flag->set || bitclear & flag->clear) { 1963228753Smm sp = flag->name + 2; 1964228753Smm } else if (bitset & flag->clear || bitclear & flag->set) { 1965228753Smm sp = flag->name; 1966228753Smm } else 1967228753Smm continue; 1968228753Smm bitset &= ~(flag->set | flag->clear); 1969228753Smm bitclear &= ~(flag->set | flag->clear); 1970228753Smm if (dp > string) 1971228753Smm *dp++ = ','; 1972228753Smm while ((*dp++ = *sp++) != '\0') 1973228753Smm ; 1974228753Smm dp--; 1975228753Smm } 1976228753Smm 1977228753Smm *dp = '\0'; 1978228753Smm return (string); 1979228753Smm} 1980228753Smm 1981228753Smm/* 1982228753Smm * strtofflags -- 1983228753Smm * Take string of arguments and return file flags. This 1984228753Smm * version works a little differently than strtofflags(3). 1985228753Smm * In particular, it always tests every token, skipping any 1986228753Smm * unrecognized tokens. It returns a pointer to the first 1987228753Smm * unrecognized token, or NULL if every token was recognized. 1988228753Smm * This version is also const-correct and does not modify the 1989228753Smm * provided string. 1990228753Smm */ 1991228753Smmstatic const char * 1992228753Smmae_strtofflags(const char *s, unsigned long *setp, unsigned long *clrp) 1993228753Smm{ 1994228753Smm const char *start, *end; 1995316338Smm const struct flag *flag; 1996228753Smm unsigned long set, clear; 1997228753Smm const char *failed; 1998228753Smm 1999228753Smm set = clear = 0; 2000228753Smm start = s; 2001228753Smm failed = NULL; 2002228753Smm /* Find start of first token. */ 2003228753Smm while (*start == '\t' || *start == ' ' || *start == ',') 2004228753Smm start++; 2005228753Smm while (*start != '\0') { 2006302001Smm size_t length; 2007228753Smm /* Locate end of token. */ 2008228753Smm end = start; 2009228753Smm while (*end != '\0' && *end != '\t' && 2010228753Smm *end != ' ' && *end != ',') 2011228753Smm end++; 2012302001Smm length = end - start; 2013358090Smm for (flag = fileflags; flag->name != NULL; flag++) { 2014302001Smm size_t flag_length = strlen(flag->name); 2015302001Smm if (length == flag_length 2016302001Smm && memcmp(start, flag->name, length) == 0) { 2017228753Smm /* Matched "noXXXX", so reverse the sense. */ 2018228753Smm clear |= flag->set; 2019228753Smm set |= flag->clear; 2020228753Smm break; 2021302001Smm } else if (length == flag_length - 2 2022302001Smm && memcmp(start, flag->name + 2, length) == 0) { 2023228753Smm /* Matched "XXXX", so don't reverse. */ 2024228753Smm set |= flag->set; 2025228753Smm clear |= flag->clear; 2026228753Smm break; 2027228753Smm } 2028228753Smm } 2029228753Smm /* Ignore unknown flag names. */ 2030228753Smm if (flag->name == NULL && failed == NULL) 2031228753Smm failed = start; 2032228753Smm 2033228753Smm /* Find start of next token. */ 2034228753Smm start = end; 2035228753Smm while (*start == '\t' || *start == ' ' || *start == ',') 2036228753Smm start++; 2037228753Smm 2038228753Smm } 2039228753Smm 2040228753Smm if (setp) 2041228753Smm *setp = set; 2042228753Smm if (clrp) 2043228753Smm *clrp = clear; 2044228753Smm 2045228753Smm /* Return location of first failure. */ 2046228753Smm return (failed); 2047228753Smm} 2048228753Smm 2049228753Smm/* 2050228753Smm * wcstofflags -- 2051228753Smm * Take string of arguments and return file flags. This 2052228753Smm * version works a little differently than strtofflags(3). 2053228753Smm * In particular, it always tests every token, skipping any 2054228753Smm * unrecognized tokens. It returns a pointer to the first 2055228753Smm * unrecognized token, or NULL if every token was recognized. 2056228753Smm * This version is also const-correct and does not modify the 2057228753Smm * provided string. 2058228753Smm */ 2059228753Smmstatic const wchar_t * 2060228753Smmae_wcstofflags(const wchar_t *s, unsigned long *setp, unsigned long *clrp) 2061228753Smm{ 2062228753Smm const wchar_t *start, *end; 2063316338Smm const struct flag *flag; 2064228753Smm unsigned long set, clear; 2065228753Smm const wchar_t *failed; 2066228753Smm 2067228753Smm set = clear = 0; 2068228753Smm start = s; 2069228753Smm failed = NULL; 2070228753Smm /* Find start of first token. */ 2071228753Smm while (*start == L'\t' || *start == L' ' || *start == L',') 2072228753Smm start++; 2073228753Smm while (*start != L'\0') { 2074302001Smm size_t length; 2075228753Smm /* Locate end of token. */ 2076228753Smm end = start; 2077228753Smm while (*end != L'\0' && *end != L'\t' && 2078228753Smm *end != L' ' && *end != L',') 2079228753Smm end++; 2080302001Smm length = end - start; 2081358090Smm for (flag = fileflags; flag->wname != NULL; flag++) { 2082302001Smm size_t flag_length = wcslen(flag->wname); 2083302001Smm if (length == flag_length 2084302001Smm && wmemcmp(start, flag->wname, length) == 0) { 2085228753Smm /* Matched "noXXXX", so reverse the sense. */ 2086228753Smm clear |= flag->set; 2087228753Smm set |= flag->clear; 2088228753Smm break; 2089302001Smm } else if (length == flag_length - 2 2090302001Smm && wmemcmp(start, flag->wname + 2, length) == 0) { 2091228753Smm /* Matched "XXXX", so don't reverse. */ 2092228753Smm set |= flag->set; 2093228753Smm clear |= flag->clear; 2094228753Smm break; 2095228753Smm } 2096228753Smm } 2097228753Smm /* Ignore unknown flag names. */ 2098228753Smm if (flag->wname == NULL && failed == NULL) 2099228753Smm failed = start; 2100228753Smm 2101228753Smm /* Find start of next token. */ 2102228753Smm start = end; 2103228753Smm while (*start == L'\t' || *start == L' ' || *start == L',') 2104228753Smm start++; 2105228753Smm 2106228753Smm } 2107228753Smm 2108228753Smm if (setp) 2109228753Smm *setp = set; 2110228753Smm if (clrp) 2111228753Smm *clrp = clear; 2112228753Smm 2113228753Smm /* Return location of first failure. */ 2114228753Smm return (failed); 2115228753Smm} 2116228753Smm 2117228753Smm 2118228753Smm#ifdef TEST 2119228753Smm#include <stdio.h> 2120228753Smmint 2121228753Smmmain(int argc, char **argv) 2122228753Smm{ 2123228753Smm struct archive_entry *entry = archive_entry_new(); 2124228753Smm unsigned long set, clear; 2125228753Smm const wchar_t *remainder; 2126228753Smm 2127228753Smm remainder = archive_entry_copy_fflags_text_w(entry, L"nosappnd dump archive,,,,,,,"); 2128228753Smm archive_entry_fflags(entry, &set, &clear); 2129228753Smm 2130228753Smm wprintf(L"set=0x%lX clear=0x%lX remainder='%ls'\n", set, clear, remainder); 2131228753Smm 2132228753Smm wprintf(L"new flags='%s'\n", archive_entry_fflags_text(entry)); 2133228753Smm return (0); 2134228753Smm} 2135228753Smm#endif 2136