diff options
author | Tim Kientzle <kientzle@gmail.com> | 2010-11-20 02:17:02 -0500 |
---|---|---|
committer | Tim Kientzle <kientzle@gmail.com> | 2010-11-20 02:17:02 -0500 |
commit | ab9806b4b7388dec10992d33c706c9db27bbf513 (patch) | |
tree | c861410f833921495d07f2c2dcce0174123028aa /libarchive/archive_entry.c | |
parent | 7aa7ee23faea6af42e0481a3c4b531e95a2c7b10 (diff) | |
download | libarchive-ab9806b4b7388dec10992d33c706c9db27bbf513.tar.gz |
Move the abstract ACL manipulations into a separate source file.
SVN-Revision: 2793
Diffstat (limited to 'libarchive/archive_entry.c')
-rw-r--r-- | libarchive/archive_entry.c | 679 |
1 files changed, 25 insertions, 654 deletions
diff --git a/libarchive/archive_entry.c b/libarchive/archive_entry.c index 6af94d2d..e9246f8a 100644 --- a/libarchive/archive_entry.c +++ b/libarchive/archive_entry.c @@ -68,13 +68,11 @@ __FBSDID("$FreeBSD: head/lib/libarchive/archive_entry.c 201096 2009-12-28 02:41: #endif #include "archive.h" +#include "archive_acl_private.h" #include "archive_entry.h" #include "archive_private.h" #include "archive_entry_private.h" -#undef max -#define max(a, b) ((a)>(b)?(a):(b)) - #if !defined(HAVE_MAJOR) && !defined(major) /* Replacement for major/minor/makedev. */ #define major(x) ((int)(0x00ff & ((x) >> 8))) @@ -118,24 +116,6 @@ static const wchar_t *ae_wcstofflags(const wchar_t *stringp, unsigned long *setp, unsigned long *clrp); static const char *ae_strtofflags(const char *stringp, unsigned long *setp, unsigned long *clrp); -static void append_entry_w(wchar_t **wp, const wchar_t *prefix, int tag, - const wchar_t *wname, int perm, int id); -static void append_id_w(wchar_t **wp, int id); - -static int acl_special(struct archive_entry *entry, - int type, int permset, int tag); -static struct ae_ace *acl_new_entry(struct archive_entry *entry, - int type, int permset, int tag, int id); -static int isint_w(const wchar_t *start, const wchar_t *end, int *result); -static int ismode_w(const wchar_t *start, const wchar_t *end, int *result); -static void next_field_w(const wchar_t **wp, const wchar_t **start, - const wchar_t **end, wchar_t *sep); -static int prefix_w(const wchar_t *start, const wchar_t *end, - const wchar_t *test); -static void -archive_entry_acl_add_entry_w_len(struct archive_entry *entry, int type, - int permset, int tag, int id, const wchar_t *name, size_t); - #ifndef HAVE_WCSCPY static wchar_t * wcscpy(wchar_t *s1, const wchar_t *s2) @@ -182,7 +162,7 @@ archive_entry_clear(struct archive_entry *entry) archive_mstring_clean(&entry->ae_symlink); archive_mstring_clean(&entry->ae_uname); archive_entry_copy_mac_metadata(entry, NULL, 0); - archive_entry_acl_clear(entry); + archive_acl_clear(&entry->acl); archive_entry_xattr_clear(entry); archive_entry_sparse_clear(entry); free(entry->stat); @@ -194,7 +174,6 @@ struct archive_entry * archive_entry_clone(struct archive_entry *entry) { struct archive_entry *entry2; - struct ae_ace *ap, *ap2; struct ae_xattr *xp; struct ae_sparse *sp; size_t s; @@ -218,14 +197,7 @@ archive_entry_clone(struct archive_entry *entry) archive_mstring_copy(&entry2->ae_uname, &entry->ae_uname); /* Copy ACL data over. */ - ap = entry->acl.acl_head; - while (ap != NULL) { - ap2 = acl_new_entry(entry2, - ap->type, ap->permset, ap->tag, ap->id); - if (ap2 != NULL) - archive_mstring_copy(&ap2->name, &ap->name); - ap = ap->next; - } + archive_acl_copy(&entry2->acl, &entry->acl); /* Copy Mac OS metadata. */ p = archive_entry_mac_metadata(entry, &s); @@ -358,7 +330,7 @@ archive_entry_devminor(struct archive_entry *entry) mode_t archive_entry_filetype(struct archive_entry *entry) { - return (AE_IFMT & entry->ae_stat.aest_mode); + return (AE_IFMT & entry->acl.mode); } void @@ -463,7 +435,7 @@ archive_entry_ino64(struct archive_entry *entry) mode_t archive_entry_mode(struct archive_entry *entry) { - return (entry->ae_stat.aest_mode); + return (entry->acl.mode); } time_t @@ -505,7 +477,7 @@ archive_entry_pathname_w(struct archive_entry *entry) mode_t archive_entry_perm(struct archive_entry *entry) { - return (~AE_IFMT & entry->ae_stat.aest_mode); + return (~AE_IFMT & entry->acl.mode); } dev_t @@ -601,8 +573,8 @@ void archive_entry_set_filetype(struct archive_entry *entry, unsigned int type) { entry->stat_valid = 0; - entry->ae_stat.aest_mode &= ~AE_IFMT; - entry->ae_stat.aest_mode |= AE_IFMT & type; + entry->acl.mode &= ~AE_IFMT; + entry->acl.mode |= AE_IFMT & type; } void @@ -849,7 +821,7 @@ void archive_entry_set_mode(struct archive_entry *entry, mode_t m) { entry->stat_valid = 0; - entry->ae_stat.aest_mode = m; + entry->acl.mode = m; } void @@ -904,8 +876,8 @@ void archive_entry_set_perm(struct archive_entry *entry, mode_t p) { entry->stat_valid = 0; - entry->ae_stat.aest_mode &= AE_IFMT; - entry->ae_stat.aest_mode |= ~AE_IFMT & p; + entry->acl.mode &= AE_IFMT; + entry->acl.mode |= ~AE_IFMT & p; } void @@ -1062,23 +1034,16 @@ archive_entry_copy_mac_metadata(struct archive_entry *entry, * uninitiated. */ +struct archive_acl * +archive_entry_acl(struct archive_entry *entry) +{ + return &entry->acl; +} + void archive_entry_acl_clear(struct archive_entry *entry) { - struct ae_ace *ap; - - while (entry->acl.acl_head != NULL) { - ap = entry->acl.acl_head->next; - archive_mstring_clean(&entry->acl.acl_head->name); - free(entry->acl.acl_head); - entry->acl.acl_head = ap; - } - if (entry->acl.acl_text_w != NULL) { - free(entry->acl.acl_text_w); - entry->acl.acl_text_w = NULL; - } - entry->acl.acl_p = NULL; - entry->acl.acl_state = 0; /* Not counting. */ + archive_acl_clear(&entry->acl); } /* @@ -1088,19 +1053,7 @@ void archive_entry_acl_add_entry(struct archive_entry *entry, int type, int permset, int tag, int id, const char *name) { - struct ae_ace *ap; - - if (acl_special(entry, type, permset, tag) == 0) - return; - ap = acl_new_entry(entry, type, permset, tag, id); - if (ap == NULL) { - /* XXX Error XXX */ - return; - } - if (name != NULL && *name != '\0') - archive_mstring_copy_mbs(&ap->name, name); - else - archive_mstring_clean(&ap->name); + archive_acl_add_entry(&entry->acl, type, permset, tag, id, name); } /* @@ -1110,100 +1063,8 @@ void archive_entry_acl_add_entry_w(struct archive_entry *entry, int type, int permset, int tag, int id, const wchar_t *name) { - archive_entry_acl_add_entry_w_len(entry, type, permset, tag, id, name, wcslen(name)); -} - -static void -archive_entry_acl_add_entry_w_len(struct archive_entry *entry, - int type, int permset, int tag, int id, const wchar_t *name, size_t len) -{ - struct ae_ace *ap; - - if (acl_special(entry, type, permset, tag) == 0) - return; - ap = acl_new_entry(entry, type, permset, tag, id); - if (ap == NULL) { - /* XXX Error XXX */ - return; - } - if (name != NULL && *name != L'\0' && len > 0) - archive_mstring_copy_wcs_len(&ap->name, name, len); - else - archive_mstring_clean(&ap->name); -} - -/* - * If this ACL entry is part of the standard POSIX permissions set, - * store the permissions in the stat structure and return zero. - */ -static int -acl_special(struct archive_entry *entry, int type, int permset, int tag) -{ - if (type == ARCHIVE_ENTRY_ACL_TYPE_ACCESS) { - switch (tag) { - case ARCHIVE_ENTRY_ACL_USER_OBJ: - entry->ae_stat.aest_mode &= ~0700; - entry->ae_stat.aest_mode |= (permset & 7) << 6; - return (0); - case ARCHIVE_ENTRY_ACL_GROUP_OBJ: - entry->ae_stat.aest_mode &= ~0070; - entry->ae_stat.aest_mode |= (permset & 7) << 3; - return (0); - case ARCHIVE_ENTRY_ACL_OTHER: - entry->ae_stat.aest_mode &= ~0007; - entry->ae_stat.aest_mode |= permset & 7; - return (0); - } - } - return (1); -} - -/* - * Allocate and populate a new ACL entry with everything but the - * name. - */ -static struct ae_ace * -acl_new_entry(struct archive_entry *entry, - int type, int permset, int tag, int id) -{ - struct ae_ace *ap, *aq; - - if (type != ARCHIVE_ENTRY_ACL_TYPE_ACCESS && - type != ARCHIVE_ENTRY_ACL_TYPE_DEFAULT) - return (NULL); - if (entry->acl.acl_text_w != NULL) { - free(entry->acl.acl_text_w); - entry->acl.acl_text_w = NULL; - } - - /* XXX TODO: More sanity-checks on the arguments XXX */ - - /* If there's a matching entry already in the list, overwrite it. */ - ap = entry->acl.acl_head; - aq = NULL; - while (ap != NULL) { - if (ap->type == type && ap->tag == tag && ap->id == id) { - ap->permset = permset; - return (ap); - } - aq = ap; - ap = ap->next; - } - - /* Add a new entry to the end of the list. */ - ap = (struct ae_ace *)malloc(sizeof(*ap)); - if (ap == NULL) - return (NULL); - memset(ap, 0, sizeof(*ap)); - if (aq == NULL) - entry->acl.acl_head = ap; - else - aq->next = ap; - ap->type = type; - ap->tag = tag; - ap->id = id; - ap->permset = permset; - return (ap); + archive_acl_add_entry_w_len(&entry->acl, + type, permset, tag, id, name, wcslen(name)); } /* @@ -1212,20 +1073,7 @@ acl_new_entry(struct archive_entry *entry, int archive_entry_acl_count(struct archive_entry *entry, int want_type) { - int count; - struct ae_ace *ap; - - count = 0; - ap = entry->acl.acl_head; - while (ap != NULL) { - if ((ap->type & want_type) != 0) - count++; - ap = ap->next; - } - - if (count > 0 && ((want_type & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) != 0)) - count += 3; - return (count); + return archive_acl_count(&entry->acl, want_type); } /* @@ -1236,93 +1084,18 @@ archive_entry_acl_count(struct archive_entry *entry, int want_type) int archive_entry_acl_reset(struct archive_entry *entry, int want_type) { - int count, cutoff; - - count = archive_entry_acl_count(entry, want_type); - - /* - * If the only entries are the three standard ones, - * then don't return any ACL data. (In this case, - * client can just use chmod(2) to set permissions.) - */ - if ((want_type & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) != 0) - cutoff = 3; - else - cutoff = 0; - - if (count > cutoff) - entry->acl.acl_state = ARCHIVE_ENTRY_ACL_USER_OBJ; - else - entry->acl.acl_state = 0; - entry->acl.acl_p = entry->acl.acl_head; - return (count); + return archive_acl_reset(&entry->acl, want_type); } /* * Return the next ACL entry in the list. Fake entries for the * standard permissions and include them in the returned list. */ - int archive_entry_acl_next(struct archive_entry *entry, int want_type, int *type, int *permset, int *tag, int *id, const char **name) { - *name = NULL; - *id = -1; - - /* - * The acl_state is either zero (no entries available), -1 - * (reading from list), or an entry type (retrieve that type - * from ae_stat.aest_mode). - */ - if (entry->acl.acl_state == 0) - return (ARCHIVE_WARN); - - /* The first three access entries are special. */ - if ((want_type & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) != 0) { - switch (entry->acl.acl_state) { - case ARCHIVE_ENTRY_ACL_USER_OBJ: - *permset = (entry->ae_stat.aest_mode >> 6) & 7; - *type = ARCHIVE_ENTRY_ACL_TYPE_ACCESS; - *tag = ARCHIVE_ENTRY_ACL_USER_OBJ; - entry->acl.acl_state = ARCHIVE_ENTRY_ACL_GROUP_OBJ; - return (ARCHIVE_OK); - case ARCHIVE_ENTRY_ACL_GROUP_OBJ: - *permset = (entry->ae_stat.aest_mode >> 3) & 7; - *type = ARCHIVE_ENTRY_ACL_TYPE_ACCESS; - *tag = ARCHIVE_ENTRY_ACL_GROUP_OBJ; - entry->acl.acl_state = ARCHIVE_ENTRY_ACL_OTHER; - return (ARCHIVE_OK); - case ARCHIVE_ENTRY_ACL_OTHER: - *permset = entry->ae_stat.aest_mode & 7; - *type = ARCHIVE_ENTRY_ACL_TYPE_ACCESS; - *tag = ARCHIVE_ENTRY_ACL_OTHER; - entry->acl.acl_state = -1; - entry->acl.acl_p = entry->acl.acl_head; - return (ARCHIVE_OK); - default: - break; - } - } - - while (entry->acl.acl_p != NULL && (entry->acl.acl_p->type & want_type) == 0) - entry->acl.acl_p = entry->acl.acl_p->next; - if (entry->acl.acl_p == NULL) { - entry->acl.acl_state = 0; - *type = 0; - *permset = 0; - *tag = 0; - *id = -1; - *name = NULL; - return (ARCHIVE_EOF); /* End of ACL entries. */ - } - *type = entry->acl.acl_p->type; - *permset = entry->acl.acl_p->permset; - *tag = entry->acl.acl_p->tag; - *id = entry->acl.acl_p->id; - *name = archive_mstring_get_mbs(&entry->acl.acl_p->name); - entry->acl.acl_p = entry->acl.acl_p->next; - return (ARCHIVE_OK); + return archive_acl_next(&entry->acl, want_type, type, permset, tag, id, name); } /* @@ -1332,412 +1105,10 @@ archive_entry_acl_next(struct archive_entry *entry, int want_type, int *type, const wchar_t * archive_entry_acl_text_w(struct archive_entry *entry, int flags) { - int count; - size_t length; - const wchar_t *wname; - const wchar_t *prefix; - wchar_t separator; - struct ae_ace *ap; - int id; - wchar_t *wp; - - if (entry->acl.acl_text_w != NULL) { - free (entry->acl.acl_text_w); - entry->acl.acl_text_w = NULL; - } - - separator = L','; - count = 0; - length = 0; - ap = entry->acl.acl_head; - while (ap != NULL) { - if ((ap->type & flags) != 0) { - count++; - if ((flags & ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT) && - (ap->type & ARCHIVE_ENTRY_ACL_TYPE_DEFAULT)) - length += 8; /* "default:" */ - length += 5; /* tag name */ - length += 1; /* colon */ - wname = archive_mstring_get_wcs(&ap->name); - if (wname != NULL) - length += wcslen(wname); - else - length += sizeof(uid_t) * 3 + 1; - length ++; /* colon */ - length += 3; /* rwx */ - length += 1; /* colon */ - length += max(sizeof(uid_t), sizeof(gid_t)) * 3 + 1; - length ++; /* newline */ - } - ap = ap->next; - } - - if (count > 0 && ((flags & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) != 0)) { - length += 10; /* "user::rwx\n" */ - length += 11; /* "group::rwx\n" */ - length += 11; /* "other::rwx\n" */ - } - - if (count == 0) - return (NULL); - - /* Now, allocate the string and actually populate it. */ - wp = entry->acl.acl_text_w = (wchar_t *)malloc(length * sizeof(wchar_t)); - if (wp == NULL) - __archive_errx(1, "No memory to generate the text version of the ACL"); - count = 0; - if ((flags & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) != 0) { - append_entry_w(&wp, NULL, ARCHIVE_ENTRY_ACL_USER_OBJ, NULL, - entry->ae_stat.aest_mode & 0700, -1); - *wp++ = ','; - append_entry_w(&wp, NULL, ARCHIVE_ENTRY_ACL_GROUP_OBJ, NULL, - entry->ae_stat.aest_mode & 0070, -1); - *wp++ = ','; - append_entry_w(&wp, NULL, ARCHIVE_ENTRY_ACL_OTHER, NULL, - entry->ae_stat.aest_mode & 0007, -1); - count += 3; - - ap = entry->acl.acl_head; - while (ap != NULL) { - if ((ap->type & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) != 0) { - wname = archive_mstring_get_wcs(&ap->name); - *wp++ = separator; - if (flags & ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID) - id = ap->id; - else - id = -1; - append_entry_w(&wp, NULL, ap->tag, wname, - ap->permset, id); - count++; - } - ap = ap->next; - } - } - - - if ((flags & ARCHIVE_ENTRY_ACL_TYPE_DEFAULT) != 0) { - if (flags & ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT) - prefix = L"default:"; - else - prefix = NULL; - ap = entry->acl.acl_head; - count = 0; - while (ap != NULL) { - if ((ap->type & ARCHIVE_ENTRY_ACL_TYPE_DEFAULT) != 0) { - wname = archive_mstring_get_wcs(&ap->name); - if (count > 0) - *wp++ = separator; - if (flags & ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID) - id = ap->id; - else - id = -1; - append_entry_w(&wp, prefix, ap->tag, - wname, ap->permset, id); - count ++; - } - ap = ap->next; - } - } - - return (entry->acl.acl_text_w); -} - -static void -append_id_w(wchar_t **wp, int id) -{ - if (id < 0) - id = 0; - if (id > 9) - append_id_w(wp, id / 10); - *(*wp)++ = L"0123456789"[id % 10]; -} - -static void -append_entry_w(wchar_t **wp, const wchar_t *prefix, int tag, - const wchar_t *wname, int perm, int id) -{ - if (prefix != NULL) { - wcscpy(*wp, prefix); - *wp += wcslen(*wp); - } - switch (tag) { - case ARCHIVE_ENTRY_ACL_USER_OBJ: - wname = NULL; - id = -1; - /* FALLTHROUGH */ - case ARCHIVE_ENTRY_ACL_USER: - wcscpy(*wp, L"user"); - break; - case ARCHIVE_ENTRY_ACL_GROUP_OBJ: - wname = NULL; - id = -1; - /* FALLTHROUGH */ - case ARCHIVE_ENTRY_ACL_GROUP: - wcscpy(*wp, L"group"); - break; - case ARCHIVE_ENTRY_ACL_MASK: - wcscpy(*wp, L"mask"); - wname = NULL; - id = -1; - break; - case ARCHIVE_ENTRY_ACL_OTHER: - wcscpy(*wp, L"other"); - wname = NULL; - id = -1; - break; - } - *wp += wcslen(*wp); - *(*wp)++ = L':'; - if (wname != NULL) { - wcscpy(*wp, wname); - *wp += wcslen(*wp); - } else if (tag == ARCHIVE_ENTRY_ACL_USER - || tag == ARCHIVE_ENTRY_ACL_GROUP) { - append_id_w(wp, id); - id = -1; - } - *(*wp)++ = L':'; - *(*wp)++ = (perm & 0444) ? L'r' : L'-'; - *(*wp)++ = (perm & 0222) ? L'w' : L'-'; - *(*wp)++ = (perm & 0111) ? L'x' : L'-'; - if (id != -1) { - *(*wp)++ = L':'; - append_id_w(wp, id); - } - **wp = L'\0'; -} - -/* - * Parse a textual ACL. This automatically recognizes and supports - * extensions described above. The 'type' argument is used to - * indicate the type that should be used for any entries not - * explicitly marked as "default:". - */ -int -__archive_entry_acl_parse_w(struct archive_entry *entry, - const wchar_t *text, int default_type) -{ - struct { - const wchar_t *start; - const wchar_t *end; - } field[4], name; - - int fields, n; - int type, tag, permset, id; - wchar_t sep; - - while (text != NULL && *text != L'\0') { - /* - * Parse the fields out of the next entry, - * advance 'text' to start of next entry. - */ - fields = 0; - do { - const wchar_t *start, *end; - next_field_w(&text, &start, &end, &sep); - if (fields < 4) { - field[fields].start = start; - field[fields].end = end; - } - ++fields; - } while (sep == L':'); - - /* Set remaining fields to blank. */ - for (n = fields; n < 4; ++n) - field[n].start = field[n].end = NULL; - - /* Check for a numeric ID in field 1 or 3. */ - id = -1; - isint_w(field[1].start, field[1].end, &id); - /* Field 3 is optional. */ - if (id == -1 && fields > 3) - isint_w(field[3].start, field[3].end, &id); - - /* - * Solaris extension: "defaultuser::rwx" is the - * default ACL corresponding to "user::rwx", etc. - */ - if (field[0].end - field[0].start > 7 - && wmemcmp(field[0].start, L"default", 7) == 0) { - type = ARCHIVE_ENTRY_ACL_TYPE_DEFAULT; - field[0].start += 7; - } else - type = default_type; - - name.start = name.end = NULL; - if (prefix_w(field[0].start, field[0].end, L"user")) { - if (!ismode_w(field[2].start, field[2].end, &permset)) - return (ARCHIVE_WARN); - if (id != -1 || field[1].start < field[1].end) { - tag = ARCHIVE_ENTRY_ACL_USER; - name = field[1]; - } else - tag = ARCHIVE_ENTRY_ACL_USER_OBJ; - } else if (prefix_w(field[0].start, field[0].end, L"group")) { - if (!ismode_w(field[2].start, field[2].end, &permset)) - return (ARCHIVE_WARN); - if (id != -1 || field[1].start < field[1].end) { - tag = ARCHIVE_ENTRY_ACL_GROUP; - name = field[1]; - } else - tag = ARCHIVE_ENTRY_ACL_GROUP_OBJ; - } else if (prefix_w(field[0].start, field[0].end, L"other")) { - if (fields == 2 - && field[1].start < field[1].end - && ismode_w(field[1].start, field[1].end, &permset)) { - /* This is Solaris-style "other:rwx" */ - } else if (fields == 3 - && field[1].start == field[1].end - && field[2].start < field[2].end - && ismode_w(field[2].start, field[2].end, &permset)) { - /* This is FreeBSD-style "other::rwx" */ - } else - return (ARCHIVE_WARN); - tag = ARCHIVE_ENTRY_ACL_OTHER; - } else if (prefix_w(field[0].start, field[0].end, L"mask")) { - if (fields == 2 - && field[1].start < field[1].end - && ismode_w(field[1].start, field[1].end, &permset)) { - /* This is Solaris-style "mask:rwx" */ - } else if (fields == 3 - && field[1].start == field[1].end - && field[2].start < field[2].end - && ismode_w(field[2].start, field[2].end, &permset)) { - /* This is FreeBSD-style "mask::rwx" */ - } else - return (ARCHIVE_WARN); - tag = ARCHIVE_ENTRY_ACL_MASK; - } else - return (ARCHIVE_WARN); - - /* Add entry to the internal list. */ - archive_entry_acl_add_entry_w_len(entry, type, permset, - tag, id, name.start, name.end - name.start); - } - return (ARCHIVE_OK); -} - -/* - * Parse a string to a positive decimal integer. Returns true if - * the string is non-empty and consists only of decimal digits, - * false otherwise. - */ -static int -isint_w(const wchar_t *start, const wchar_t *end, int *result) -{ - int n = 0; - if (start >= end) - return (0); - while (start < end) { - if (*start < '0' || *start > '9') - return (0); - if (n > (INT_MAX / 10)) - n = INT_MAX; - else { - n *= 10; - n += *start - '0'; - } - start++; - } - *result = n; - return (1); -} - -/* - * Parse a string as a mode field. Returns true if - * the string is non-empty and consists only of mode characters, - * false otherwise. - */ -static int -ismode_w(const wchar_t *start, const wchar_t *end, int *permset) -{ - const wchar_t *p; - - if (start >= end) - return (0); - p = start; - *permset = 0; - while (p < end) { - switch (*p++) { - case 'r': case 'R': - *permset |= ARCHIVE_ENTRY_ACL_READ; - break; - case 'w': case 'W': - *permset |= ARCHIVE_ENTRY_ACL_WRITE; - break; - case 'x': case 'X': - *permset |= ARCHIVE_ENTRY_ACL_EXECUTE; - break; - case '-': - break; - default: - return (0); - } - } - return (1); + return archive_acl_text_w(&entry->acl, flags); } /* - * Match "[:whitespace:]*(.*)[:whitespace:]*[:,\n]". *wp is updated - * to point to just after the separator. *start points to the first - * character of the matched text and *end just after the last - * character of the matched identifier. In particular *end - *start - * is the length of the field body, not including leading or trailing - * whitespace. - */ -static void -next_field_w(const wchar_t **wp, const wchar_t **start, - const wchar_t **end, wchar_t *sep) -{ - /* Skip leading whitespace to find start of field. */ - while (**wp == L' ' || **wp == L'\t' || **wp == L'\n') { - (*wp)++; - } - *start = *wp; - - /* Scan for the separator. */ - while (**wp != L'\0' && **wp != L',' && **wp != L':' && - **wp != L'\n') { - (*wp)++; - } - *sep = **wp; - - /* Trim trailing whitespace to locate end of field. */ - *end = *wp - 1; - while (**end == L' ' || **end == L'\t' || **end == L'\n') { - (*end)--; - } - (*end)++; - - /* Adjust scanner location. */ - if (**wp != L'\0') - (*wp)++; -} - -/* - * Return true if the characters [start...end) are a prefix of 'test'. - * This makes it easy to handle the obvious abbreviations: 'u' for 'user', etc. - */ -static int -prefix_w(const wchar_t *start, const wchar_t *end, const wchar_t *test) -{ - if (start == end) - return (0); - - if (*start++ != *test++) - return (0); - - while (start < end && *start++ == *test++) - ; - - if (start < end) - return (0); - - return (1); -} - - -/* * Following code is modified from UC Berkeley sources, and * is subject to the following copyright notice. */ |