Merge pull request #3035 from stoeckmann/acl_string
acl: Simplify string creation
(cherry picked from commit 97595197b2)
This commit is contained in:
1 parent
357584ab84
commit
d01e6841b9
1 file changed
+101
-265
+101
-265
@@ -56,9 +56,7 @@ static int archive_acl_add_entry_len_l(struct archive_acl *acl,
|
||||
int type, int permset, int tag, int id, const char *name,
|
||||
size_t len, struct archive_string_conv *sc);
|
||||
static int archive_acl_text_want_type(struct archive_acl *acl, int flags);
|
||||
static size_t archive_acl_text_len(struct archive_acl *acl, int want_type,
|
||||
int flags, int wide, struct archive *a,
|
||||
struct archive_string_conv *sc);
|
||||
static size_t archive_acl_text_empty(struct archive_acl *acl, int want_type);
|
||||
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 int is_nfs4_flags_w(const wchar_t *start, const wchar_t *end,
|
||||
@@ -67,9 +65,9 @@ static int is_nfs4_perms_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 void append_entry_w(wchar_t **wp, const wchar_t *prefix, int type,
|
||||
static void append_entry_w(struct archive_wstring *ws, const wchar_t *prefix, int type,
|
||||
int tag, int flags, const wchar_t *wname, int perm, int id);
|
||||
static void append_id_w(wchar_t **wp, int id);
|
||||
static void append_id_w(struct archive_wstring *ws, int id);
|
||||
static int isint(const char *start, const char *end, int *result);
|
||||
static int ismode(const char *start, const char *end, int *result);
|
||||
static int is_nfs4_flags(const char *start, const char *end,
|
||||
@@ -78,9 +76,9 @@ static int is_nfs4_perms(const char *start, const char *end,
|
||||
int *result);
|
||||
static void next_field(const char **p, size_t *l, const char **start,
|
||||
const char **end, char *sep);
|
||||
static void append_entry(char **p, const char *prefix, int type,
|
||||
static void append_entry(struct archive_string *s, const char *prefix, int type,
|
||||
int tag, int flags, const char *name, int perm, int id);
|
||||
static void append_id(char **p, int id);
|
||||
static void append_id(struct archive_string *s, int id);
|
||||
|
||||
static const struct {
|
||||
const int perm;
|
||||
@@ -539,20 +537,12 @@ archive_acl_text_want_type(struct archive_acl *acl, int flags)
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate ACL text string length
|
||||
* Check if ACL text would be empty
|
||||
*/
|
||||
static size_t
|
||||
archive_acl_text_len(struct archive_acl *acl, int want_type, int flags,
|
||||
int wide, struct archive *a, struct archive_string_conv *sc) {
|
||||
archive_acl_text_empty(struct archive_acl *acl, int want_type) {
|
||||
struct archive_acl_entry *ap;
|
||||
const char *name;
|
||||
const wchar_t *wname;
|
||||
int count, idlen, tmp, r;
|
||||
size_t length;
|
||||
size_t len;
|
||||
|
||||
count = 0;
|
||||
length = 0;
|
||||
for (ap = acl->acl_head; ap != NULL; ap = ap->next) {
|
||||
if ((ap->type & want_type) == 0)
|
||||
continue;
|
||||
@@ -565,108 +555,11 @@ archive_acl_text_len(struct archive_acl *acl, int want_type, int flags,
|
||||
|| ap->tag == ARCHIVE_ENTRY_ACL_GROUP_OBJ
|
||||
|| ap->tag == ARCHIVE_ENTRY_ACL_OTHER))
|
||||
continue;
|
||||
count++;
|
||||
if ((want_type & ARCHIVE_ENTRY_ACL_TYPE_DEFAULT) != 0
|
||||
&& (ap->type & ARCHIVE_ENTRY_ACL_TYPE_DEFAULT) != 0)
|
||||
length += 8; /* "default:" */
|
||||
switch (ap->tag) {
|
||||
case ARCHIVE_ENTRY_ACL_USER_OBJ:
|
||||
if (want_type == ARCHIVE_ENTRY_ACL_TYPE_NFS4) {
|
||||
length += 6; /* "owner@" */
|
||||
break;
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
case ARCHIVE_ENTRY_ACL_USER:
|
||||
case ARCHIVE_ENTRY_ACL_MASK:
|
||||
length += 4; /* "user", "mask" */
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_GROUP_OBJ:
|
||||
if (want_type == ARCHIVE_ENTRY_ACL_TYPE_NFS4) {
|
||||
length += 6; /* "group@" */
|
||||
break;
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
case ARCHIVE_ENTRY_ACL_GROUP:
|
||||
case ARCHIVE_ENTRY_ACL_OTHER:
|
||||
length += 5; /* "group", "other" */
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_EVERYONE:
|
||||
length += 9; /* "everyone@" */
|
||||
break;
|
||||
}
|
||||
length += 1; /* colon after tag */
|
||||
if (ap->tag == ARCHIVE_ENTRY_ACL_USER ||
|
||||
ap->tag == ARCHIVE_ENTRY_ACL_GROUP) {
|
||||
if (wide) {
|
||||
r = archive_mstring_get_wcs(a, &ap->name,
|
||||
&wname);
|
||||
if (r == 0 && wname != NULL)
|
||||
length += wcslen(wname);
|
||||
else if (r < 0 && errno == ENOMEM)
|
||||
return (0);
|
||||
else
|
||||
length += sizeof(uid_t) * 3 + 1;
|
||||
} else {
|
||||
r = archive_mstring_get_mbs_l(a, &ap->name, &name,
|
||||
&len, sc);
|
||||
if (r != 0)
|
||||
return (0);
|
||||
if (len > 0 && name != NULL)
|
||||
length += len;
|
||||
else
|
||||
length += sizeof(uid_t) * 3 + 1;
|
||||
}
|
||||
length += 1; /* colon after user or group name */
|
||||
} else if (want_type != ARCHIVE_ENTRY_ACL_TYPE_NFS4)
|
||||
length += 1; /* 2nd colon empty user,group or other */
|
||||
|
||||
if (((flags & ARCHIVE_ENTRY_ACL_STYLE_SOLARIS) != 0)
|
||||
&& ((want_type & ARCHIVE_ENTRY_ACL_TYPE_POSIX1E) != 0)
|
||||
&& (ap->tag == ARCHIVE_ENTRY_ACL_OTHER
|
||||
|| ap->tag == ARCHIVE_ENTRY_ACL_MASK)) {
|
||||
/* Solaris has no colon after other: and mask: */
|
||||
length = length - 1;
|
||||
}
|
||||
|
||||
if (want_type == ARCHIVE_ENTRY_ACL_TYPE_NFS4) {
|
||||
/* rwxpdDaARWcCos:fdinSFI:deny */
|
||||
length += 27;
|
||||
if ((ap->type & ARCHIVE_ENTRY_ACL_TYPE_DENY) == 0)
|
||||
length += 1; /* allow, alarm, audit */
|
||||
} else
|
||||
length += 3; /* rwx */
|
||||
|
||||
if ((ap->tag == ARCHIVE_ENTRY_ACL_USER ||
|
||||
ap->tag == ARCHIVE_ENTRY_ACL_GROUP) &&
|
||||
((flags & ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID) != 0 ||
|
||||
(wide ? wname == NULL : name == NULL))) {
|
||||
length += 1; /* colon */
|
||||
/* ID digit count */
|
||||
idlen = 1;
|
||||
tmp = ap->id;
|
||||
while (tmp > 9) {
|
||||
tmp = tmp / 10;
|
||||
idlen++;
|
||||
}
|
||||
length += idlen;
|
||||
}
|
||||
length ++; /* entry separator */
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Add filemode-mapping access entries to the length */
|
||||
if ((want_type & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) != 0) {
|
||||
if ((flags & ARCHIVE_ENTRY_ACL_STYLE_SOLARIS) != 0) {
|
||||
/* "user::rwx\ngroup::rwx\nother:rwx\n" */
|
||||
length += 31;
|
||||
} else {
|
||||
/* "user::rwx\ngroup::rwx\nother::rwx\n" */
|
||||
length += 32;
|
||||
}
|
||||
} else if (count == 0)
|
||||
return (0);
|
||||
|
||||
/* The terminating character is included in count */
|
||||
return (length);
|
||||
return (1);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -677,15 +570,12 @@ wchar_t *
|
||||
archive_acl_to_text_w(struct archive_acl *acl, ssize_t *text_len, int flags,
|
||||
struct archive *a)
|
||||
{
|
||||
int count;
|
||||
size_t length;
|
||||
size_t len;
|
||||
const wchar_t *wname;
|
||||
const wchar_t *prefix;
|
||||
wchar_t separator;
|
||||
struct archive_acl_entry *ap;
|
||||
struct archive_wstring ws;
|
||||
int id, r, want_type;
|
||||
wchar_t *wp, *ws;
|
||||
|
||||
want_type = archive_acl_text_want_type(acl, flags);
|
||||
|
||||
@@ -696,9 +586,7 @@ archive_acl_to_text_w(struct archive_acl *acl, ssize_t *text_len, int flags,
|
||||
if (want_type == ARCHIVE_ENTRY_ACL_TYPE_POSIX1E)
|
||||
flags |= ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT;
|
||||
|
||||
length = archive_acl_text_len(acl, want_type, flags, 1, a, NULL);
|
||||
|
||||
if (length == 0)
|
||||
if (archive_acl_text_empty(acl, want_type))
|
||||
return (NULL);
|
||||
|
||||
if (flags & ARCHIVE_ENTRY_ACL_STYLE_SEPARATOR_COMMA)
|
||||
@@ -706,28 +594,20 @@ archive_acl_to_text_w(struct archive_acl *acl, ssize_t *text_len, int flags,
|
||||
else
|
||||
separator = L'\n';
|
||||
|
||||
/* Now, allocate the string and actually populate it. */
|
||||
wp = ws = malloc(length * sizeof(*wp));
|
||||
if (wp == NULL) {
|
||||
if (errno == ENOMEM)
|
||||
__archive_errx(1, "No memory");
|
||||
return (NULL);
|
||||
}
|
||||
count = 0;
|
||||
archive_string_init(&ws);
|
||||
|
||||
if ((want_type & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) != 0) {
|
||||
append_entry_w(&wp, NULL, ARCHIVE_ENTRY_ACL_TYPE_ACCESS,
|
||||
append_entry_w(&ws, NULL, ARCHIVE_ENTRY_ACL_TYPE_ACCESS,
|
||||
ARCHIVE_ENTRY_ACL_USER_OBJ, flags, NULL,
|
||||
acl->mode & 0700, -1);
|
||||
*wp++ = separator;
|
||||
append_entry_w(&wp, NULL, ARCHIVE_ENTRY_ACL_TYPE_ACCESS,
|
||||
archive_wstrappend_wchar(&ws, separator);
|
||||
append_entry_w(&ws, NULL, ARCHIVE_ENTRY_ACL_TYPE_ACCESS,
|
||||
ARCHIVE_ENTRY_ACL_GROUP_OBJ, flags, NULL,
|
||||
acl->mode & 0070, -1);
|
||||
*wp++ = separator;
|
||||
append_entry_w(&wp, NULL, ARCHIVE_ENTRY_ACL_TYPE_ACCESS,
|
||||
archive_wstrappend_wchar(&ws, separator);
|
||||
append_entry_w(&ws, NULL, ARCHIVE_ENTRY_ACL_TYPE_ACCESS,
|
||||
ARCHIVE_ENTRY_ACL_OTHER, flags, NULL,
|
||||
acl->mode & 0007, -1);
|
||||
count += 3;
|
||||
}
|
||||
|
||||
for (ap = acl->acl_head; ap != NULL; ap = ap->next) {
|
||||
@@ -749,109 +629,95 @@ archive_acl_to_text_w(struct archive_acl *acl, ssize_t *text_len, int flags,
|
||||
prefix = NULL;
|
||||
r = archive_mstring_get_wcs(a, &ap->name, &wname);
|
||||
if (r == 0) {
|
||||
if (count > 0)
|
||||
*wp++ = separator;
|
||||
if (ws.length > 0)
|
||||
archive_wstrappend_wchar(&ws, separator);
|
||||
if ((flags & ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID) ||
|
||||
wname == NULL)
|
||||
id = ap->id;
|
||||
else
|
||||
id = -1;
|
||||
append_entry_w(&wp, prefix, ap->type, ap->tag, flags,
|
||||
append_entry_w(&ws, prefix, ap->type, ap->tag, flags,
|
||||
wname, ap->permset, id);
|
||||
count++;
|
||||
} else if (r < 0 && errno == ENOMEM) {
|
||||
free(ws);
|
||||
archive_wstring_free(&ws);
|
||||
return (NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/* Add terminating character */
|
||||
*wp++ = L'\0';
|
||||
|
||||
len = wcslen(ws);
|
||||
|
||||
if (len > length - 1)
|
||||
__archive_errx(1, "Buffer overrun");
|
||||
|
||||
if (text_len != NULL)
|
||||
*text_len = len;
|
||||
*text_len = ws.length;
|
||||
|
||||
return (ws);
|
||||
return (ws.s);
|
||||
}
|
||||
|
||||
static void
|
||||
append_id_w(wchar_t **wp, int id)
|
||||
append_id_w(struct archive_wstring *ws, int id)
|
||||
{
|
||||
if (id < 0)
|
||||
id = 0;
|
||||
if (id > 9)
|
||||
append_id_w(wp, id / 10);
|
||||
*(*wp)++ = L"0123456789"[id % 10];
|
||||
append_id_w(ws, id / 10);
|
||||
archive_wstrappend_wchar(ws, L"0123456789"[id % 10]);
|
||||
}
|
||||
|
||||
static void
|
||||
append_entry_w(wchar_t **wp, const wchar_t *prefix, int type,
|
||||
append_entry_w(struct archive_wstring *ws, const wchar_t *prefix, int type,
|
||||
int tag, int flags, const wchar_t *wname, int perm, int id)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (prefix != NULL) {
|
||||
wcscpy(*wp, prefix);
|
||||
*wp += wcslen(*wp);
|
||||
}
|
||||
if (prefix != NULL)
|
||||
archive_wstrcat(ws, prefix);
|
||||
switch (tag) {
|
||||
case ARCHIVE_ENTRY_ACL_USER_OBJ:
|
||||
wname = NULL;
|
||||
id = -1;
|
||||
if ((type & ARCHIVE_ENTRY_ACL_TYPE_NFS4) != 0) {
|
||||
wcscpy(*wp, L"owner@");
|
||||
archive_wstrcat(ws, L"owner@");
|
||||
break;
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
case ARCHIVE_ENTRY_ACL_USER:
|
||||
wcscpy(*wp, L"user");
|
||||
archive_wstrcat(ws, L"user");
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_GROUP_OBJ:
|
||||
wname = NULL;
|
||||
id = -1;
|
||||
if ((type & ARCHIVE_ENTRY_ACL_TYPE_NFS4) != 0) {
|
||||
wcscpy(*wp, L"group@");
|
||||
archive_wstrcat(ws, L"group@");
|
||||
break;
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
case ARCHIVE_ENTRY_ACL_GROUP:
|
||||
wcscpy(*wp, L"group");
|
||||
archive_wstrcat(ws, L"group");
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_MASK:
|
||||
wcscpy(*wp, L"mask");
|
||||
archive_wstrcat(ws, L"mask");
|
||||
wname = NULL;
|
||||
id = -1;
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_OTHER:
|
||||
wcscpy(*wp, L"other");
|
||||
archive_wstrcat(ws, L"other");
|
||||
wname = NULL;
|
||||
id = -1;
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_EVERYONE:
|
||||
wcscpy(*wp, L"everyone@");
|
||||
archive_wstrcat(ws, L"everyone@");
|
||||
wname = NULL;
|
||||
id = -1;
|
||||
break;
|
||||
default:
|
||||
**wp = '\0';
|
||||
break;
|
||||
}
|
||||
*wp += wcslen(*wp);
|
||||
*(*wp)++ = L':';
|
||||
archive_wstrappend_wchar(ws, L':');
|
||||
if (((type & ARCHIVE_ENTRY_ACL_TYPE_POSIX1E) != 0) ||
|
||||
tag == ARCHIVE_ENTRY_ACL_USER ||
|
||||
tag == ARCHIVE_ENTRY_ACL_GROUP) {
|
||||
if (wname != NULL) {
|
||||
wcscpy(*wp, wname);
|
||||
*wp += wcslen(*wp);
|
||||
archive_wstrcat(ws, wname);
|
||||
} else if (tag == ARCHIVE_ENTRY_ACL_USER
|
||||
|| tag == ARCHIVE_ENTRY_ACL_GROUP) {
|
||||
append_id_w(wp, id);
|
||||
append_id_w(ws, id);
|
||||
if ((type & ARCHIVE_ENTRY_ACL_TYPE_NFS4) == 0)
|
||||
id = -1;
|
||||
}
|
||||
@@ -859,51 +725,49 @@ append_entry_w(wchar_t **wp, const wchar_t *prefix, int type,
|
||||
if (((flags & ARCHIVE_ENTRY_ACL_STYLE_SOLARIS) == 0)
|
||||
|| (tag != ARCHIVE_ENTRY_ACL_OTHER
|
||||
&& tag != ARCHIVE_ENTRY_ACL_MASK))
|
||||
*(*wp)++ = L':';
|
||||
archive_wstrappend_wchar(ws, L':');
|
||||
}
|
||||
if ((type & ARCHIVE_ENTRY_ACL_TYPE_POSIX1E) != 0) {
|
||||
/* POSIX.1e ACL perms */
|
||||
*(*wp)++ = (perm & 0444) ? L'r' : L'-';
|
||||
*(*wp)++ = (perm & 0222) ? L'w' : L'-';
|
||||
*(*wp)++ = (perm & 0111) ? L'x' : L'-';
|
||||
archive_wstrappend_wchar(ws, (perm & 0444) ? L'r' : L'-');
|
||||
archive_wstrappend_wchar(ws, (perm & 0222) ? L'w' : L'-');
|
||||
archive_wstrappend_wchar(ws, (perm & 0111) ? L'x' : L'-');
|
||||
} else {
|
||||
/* NFSv4 ACL perms */
|
||||
for (i = 0; i < nfsv4_acl_perm_map_size; i++) {
|
||||
if (perm & nfsv4_acl_perm_map[i].perm)
|
||||
*(*wp)++ = nfsv4_acl_perm_map[i].wc;
|
||||
archive_wstrappend_wchar(ws, nfsv4_acl_perm_map[i].wc);
|
||||
else if ((flags & ARCHIVE_ENTRY_ACL_STYLE_COMPACT) == 0)
|
||||
*(*wp)++ = L'-';
|
||||
archive_wstrappend_wchar(ws, L'-');
|
||||
}
|
||||
*(*wp)++ = L':';
|
||||
archive_wstrappend_wchar(ws, L':');
|
||||
for (i = 0; i < nfsv4_acl_flag_map_size; i++) {
|
||||
if (perm & nfsv4_acl_flag_map[i].perm)
|
||||
*(*wp)++ = nfsv4_acl_flag_map[i].wc;
|
||||
archive_wstrappend_wchar(ws, nfsv4_acl_flag_map[i].wc);
|
||||
else if ((flags & ARCHIVE_ENTRY_ACL_STYLE_COMPACT) == 0)
|
||||
*(*wp)++ = L'-';
|
||||
archive_wstrappend_wchar(ws, L'-');
|
||||
}
|
||||
*(*wp)++ = L':';
|
||||
archive_wstrappend_wchar(ws, L':');
|
||||
switch (type) {
|
||||
case ARCHIVE_ENTRY_ACL_TYPE_ALLOW:
|
||||
wcscpy(*wp, L"allow");
|
||||
archive_wstrcat(ws, L"allow");
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_TYPE_DENY:
|
||||
wcscpy(*wp, L"deny");
|
||||
archive_wstrcat(ws, L"deny");
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_TYPE_AUDIT:
|
||||
wcscpy(*wp, L"audit");
|
||||
archive_wstrcat(ws, L"audit");
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_TYPE_ALARM:
|
||||
wcscpy(*wp, L"alarm");
|
||||
archive_wstrcat(ws, L"alarm");
|
||||
break;
|
||||
default:
|
||||
*(*wp) = L'\0';
|
||||
break;
|
||||
}
|
||||
*wp += wcslen(*wp);
|
||||
}
|
||||
if (id != -1) {
|
||||
*(*wp)++ = L':';
|
||||
append_id_w(wp, id);
|
||||
archive_wstrappend_wchar(ws, L':');
|
||||
append_id_w(ws, id);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -915,15 +779,13 @@ char *
|
||||
archive_acl_to_text_l(struct archive_acl *acl, ssize_t *text_len, int flags,
|
||||
struct archive_string_conv *sc)
|
||||
{
|
||||
int count;
|
||||
size_t length;
|
||||
size_t len;
|
||||
const char *name;
|
||||
const char *prefix;
|
||||
char separator;
|
||||
struct archive_acl_entry *ap;
|
||||
struct archive_string s;
|
||||
int id, r, want_type;
|
||||
char *p, *s;
|
||||
|
||||
want_type = archive_acl_text_want_type(acl, flags);
|
||||
|
||||
@@ -934,9 +796,7 @@ archive_acl_to_text_l(struct archive_acl *acl, ssize_t *text_len, int flags,
|
||||
if (want_type == ARCHIVE_ENTRY_ACL_TYPE_POSIX1E)
|
||||
flags |= ARCHIVE_ENTRY_ACL_STYLE_MARK_DEFAULT;
|
||||
|
||||
length = archive_acl_text_len(acl, want_type, flags, 0, NULL, sc);
|
||||
|
||||
if (length == 0)
|
||||
if (archive_acl_text_empty(acl, want_type))
|
||||
return (NULL);
|
||||
|
||||
if (flags & ARCHIVE_ENTRY_ACL_STYLE_SEPARATOR_COMMA)
|
||||
@@ -944,28 +804,20 @@ archive_acl_to_text_l(struct archive_acl *acl, ssize_t *text_len, int flags,
|
||||
else
|
||||
separator = '\n';
|
||||
|
||||
/* Now, allocate the string and actually populate it. */
|
||||
p = s = malloc(length * sizeof(*p));
|
||||
if (p == NULL) {
|
||||
if (errno == ENOMEM)
|
||||
__archive_errx(1, "No memory");
|
||||
return (NULL);
|
||||
}
|
||||
count = 0;
|
||||
archive_string_init(&s);
|
||||
|
||||
if ((want_type & ARCHIVE_ENTRY_ACL_TYPE_ACCESS) != 0) {
|
||||
append_entry(&p, NULL, ARCHIVE_ENTRY_ACL_TYPE_ACCESS,
|
||||
append_entry(&s, NULL, ARCHIVE_ENTRY_ACL_TYPE_ACCESS,
|
||||
ARCHIVE_ENTRY_ACL_USER_OBJ, flags, NULL,
|
||||
acl->mode & 0700, -1);
|
||||
*p++ = separator;
|
||||
append_entry(&p, NULL, ARCHIVE_ENTRY_ACL_TYPE_ACCESS,
|
||||
archive_strappend_char(&s, separator);
|
||||
append_entry(&s, NULL, ARCHIVE_ENTRY_ACL_TYPE_ACCESS,
|
||||
ARCHIVE_ENTRY_ACL_GROUP_OBJ, flags, NULL,
|
||||
acl->mode & 0070, -1);
|
||||
*p++ = separator;
|
||||
append_entry(&p, NULL, ARCHIVE_ENTRY_ACL_TYPE_ACCESS,
|
||||
archive_strappend_char(&s, separator);
|
||||
append_entry(&s, NULL, ARCHIVE_ENTRY_ACL_TYPE_ACCESS,
|
||||
ARCHIVE_ENTRY_ACL_OTHER, flags, NULL,
|
||||
acl->mode & 0007, -1);
|
||||
count += 3;
|
||||
}
|
||||
|
||||
for (ap = acl->acl_head; ap != NULL; ap = ap->next) {
|
||||
@@ -988,109 +840,95 @@ archive_acl_to_text_l(struct archive_acl *acl, ssize_t *text_len, int flags,
|
||||
r = archive_mstring_get_mbs_l(
|
||||
NULL, &ap->name, &name, &len, sc);
|
||||
if (r != 0) {
|
||||
free(s);
|
||||
archive_string_free(&s);
|
||||
return (NULL);
|
||||
}
|
||||
if (count > 0)
|
||||
*p++ = separator;
|
||||
if (s.length > 0)
|
||||
archive_strappend_char(&s, separator);
|
||||
if (name == NULL ||
|
||||
(flags & ARCHIVE_ENTRY_ACL_STYLE_EXTRA_ID)) {
|
||||
id = ap->id;
|
||||
} else {
|
||||
id = -1;
|
||||
}
|
||||
append_entry(&p, prefix, ap->type, ap->tag, flags, name,
|
||||
append_entry(&s, prefix, ap->type, ap->tag, flags, name,
|
||||
ap->permset, id);
|
||||
count++;
|
||||
}
|
||||
|
||||
/* Add terminating character */
|
||||
*p++ = '\0';
|
||||
|
||||
len = strlen(s);
|
||||
|
||||
if (len > length - 1)
|
||||
__archive_errx(1, "Buffer overrun");
|
||||
|
||||
if (text_len != NULL)
|
||||
*text_len = len;
|
||||
*text_len = s.length;
|
||||
|
||||
return (s);
|
||||
return (s.s);
|
||||
}
|
||||
|
||||
static void
|
||||
append_id(char **p, int id)
|
||||
append_id(struct archive_string *s, int id)
|
||||
{
|
||||
if (id < 0)
|
||||
id = 0;
|
||||
if (id > 9)
|
||||
append_id(p, id / 10);
|
||||
*(*p)++ = "0123456789"[id % 10];
|
||||
append_id(s, id / 10);
|
||||
archive_strappend_char(s, "0123456789"[id % 10]);
|
||||
}
|
||||
|
||||
static void
|
||||
append_entry(char **p, const char *prefix, int type,
|
||||
append_entry(struct archive_string *s, const char *prefix, int type,
|
||||
int tag, int flags, const char *name, int perm, int id)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (prefix != NULL) {
|
||||
strcpy(*p, prefix);
|
||||
*p += strlen(*p);
|
||||
}
|
||||
if (prefix != NULL)
|
||||
archive_strcat(s, prefix);
|
||||
switch (tag) {
|
||||
case ARCHIVE_ENTRY_ACL_USER_OBJ:
|
||||
name = NULL;
|
||||
id = -1;
|
||||
if ((type & ARCHIVE_ENTRY_ACL_TYPE_NFS4) != 0) {
|
||||
strcpy(*p, "owner@");
|
||||
archive_strcat(s, "owner@");
|
||||
break;
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
case ARCHIVE_ENTRY_ACL_USER:
|
||||
strcpy(*p, "user");
|
||||
archive_strcat(s, "user");
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_GROUP_OBJ:
|
||||
name = NULL;
|
||||
id = -1;
|
||||
if ((type & ARCHIVE_ENTRY_ACL_TYPE_NFS4) != 0) {
|
||||
strcpy(*p, "group@");
|
||||
archive_strcat(s, "group@");
|
||||
break;
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
case ARCHIVE_ENTRY_ACL_GROUP:
|
||||
strcpy(*p, "group");
|
||||
archive_strcat(s, "group");
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_MASK:
|
||||
strcpy(*p, "mask");
|
||||
archive_strcat(s, "mask");
|
||||
name = NULL;
|
||||
id = -1;
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_OTHER:
|
||||
strcpy(*p, "other");
|
||||
archive_strcat(s, "other");
|
||||
name = NULL;
|
||||
id = -1;
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_EVERYONE:
|
||||
strcpy(*p, "everyone@");
|
||||
archive_strcat(s, "everyone@");
|
||||
name = NULL;
|
||||
id = -1;
|
||||
break;
|
||||
default:
|
||||
**p = '\0';
|
||||
break;
|
||||
}
|
||||
*p += strlen(*p);
|
||||
*(*p)++ = ':';
|
||||
archive_strappend_char(s, ':');
|
||||
if (((type & ARCHIVE_ENTRY_ACL_TYPE_POSIX1E) != 0) ||
|
||||
tag == ARCHIVE_ENTRY_ACL_USER ||
|
||||
tag == ARCHIVE_ENTRY_ACL_GROUP) {
|
||||
if (name != NULL) {
|
||||
strcpy(*p, name);
|
||||
*p += strlen(*p);
|
||||
archive_strcat(s, name);
|
||||
} else if (tag == ARCHIVE_ENTRY_ACL_USER
|
||||
|| tag == ARCHIVE_ENTRY_ACL_GROUP) {
|
||||
append_id(p, id);
|
||||
append_id(s, id);
|
||||
if ((type & ARCHIVE_ENTRY_ACL_TYPE_NFS4) == 0)
|
||||
id = -1;
|
||||
}
|
||||
@@ -1098,51 +936,49 @@ append_entry(char **p, const char *prefix, int type,
|
||||
if (((flags & ARCHIVE_ENTRY_ACL_STYLE_SOLARIS) == 0)
|
||||
|| (tag != ARCHIVE_ENTRY_ACL_OTHER
|
||||
&& tag != ARCHIVE_ENTRY_ACL_MASK))
|
||||
*(*p)++ = ':';
|
||||
archive_strappend_char(s, ':');
|
||||
}
|
||||
if ((type & ARCHIVE_ENTRY_ACL_TYPE_POSIX1E) != 0) {
|
||||
/* POSIX.1e ACL perms */
|
||||
*(*p)++ = (perm & 0444) ? 'r' : '-';
|
||||
*(*p)++ = (perm & 0222) ? 'w' : '-';
|
||||
*(*p)++ = (perm & 0111) ? 'x' : '-';
|
||||
archive_strappend_char(s, (perm & 0444) ? 'r' : '-');
|
||||
archive_strappend_char(s, (perm & 0222) ? 'w' : '-');
|
||||
archive_strappend_char(s, (perm & 0111) ? 'x' : '-');
|
||||
} else {
|
||||
/* NFSv4 ACL perms */
|
||||
for (i = 0; i < nfsv4_acl_perm_map_size; i++) {
|
||||
if (perm & nfsv4_acl_perm_map[i].perm)
|
||||
*(*p)++ = nfsv4_acl_perm_map[i].c;
|
||||
archive_strappend_char(s, nfsv4_acl_perm_map[i].c);
|
||||
else if ((flags & ARCHIVE_ENTRY_ACL_STYLE_COMPACT) == 0)
|
||||
*(*p)++ = '-';
|
||||
archive_strappend_char(s, '-');
|
||||
}
|
||||
*(*p)++ = ':';
|
||||
archive_strappend_char(s, ':');
|
||||
for (i = 0; i < nfsv4_acl_flag_map_size; i++) {
|
||||
if (perm & nfsv4_acl_flag_map[i].perm)
|
||||
*(*p)++ = nfsv4_acl_flag_map[i].c;
|
||||
archive_strappend_char(s, nfsv4_acl_flag_map[i].c);
|
||||
else if ((flags & ARCHIVE_ENTRY_ACL_STYLE_COMPACT) == 0)
|
||||
*(*p)++ = '-';
|
||||
archive_strappend_char(s, '-');
|
||||
}
|
||||
*(*p)++ = ':';
|
||||
archive_strappend_char(s, ':');
|
||||
switch (type) {
|
||||
case ARCHIVE_ENTRY_ACL_TYPE_ALLOW:
|
||||
strcpy(*p, "allow");
|
||||
archive_strcat(s, "allow");
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_TYPE_DENY:
|
||||
strcpy(*p, "deny");
|
||||
archive_strcat(s, "deny");
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_TYPE_AUDIT:
|
||||
strcpy(*p, "audit");
|
||||
archive_strcat(s, "audit");
|
||||
break;
|
||||
case ARCHIVE_ENTRY_ACL_TYPE_ALARM:
|
||||
strcpy(*p, "alarm");
|
||||
archive_strcat(s, "alarm");
|
||||
break;
|
||||
default:
|
||||
*(*p) = '\0';
|
||||
break;
|
||||
}
|
||||
*p += strlen(*p);
|
||||
}
|
||||
if (id != -1) {
|
||||
*(*p)++ = ':';
|
||||
append_id(p, id);
|
||||
archive_strappend_char(s, ':');
|
||||
append_id(s, id);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user