diff options
-rw-r--r-- | include/libacl.h | 5 | ||||
-rw-r--r-- | libacl/Makefile | 2 | ||||
-rw-r--r-- | libacl/acl_entry_to_any_str.c | 300 | ||||
-rw-r--r-- | libacl/acl_to_any_text.c | 252 |
4 files changed, 254 insertions, 305 deletions
diff --git a/include/libacl.h b/include/libacl.h index 9b6d57b..2c0db6e 100644 --- a/include/libacl.h +++ b/include/libacl.h @@ -13,7 +13,7 @@ extern "C" { #endif -/* acl_entry_to_any_str(), acl_to_any_text() */ +/* Flags for acl_to_any_text() */ /* Print NO, SOME or ALL effective permissions comments. SOME prints effective rights comments for entries which have different permissions @@ -42,9 +42,6 @@ extern "C" { extern char *acl_to_any_text(acl_t acl, ssize_t *len_p, const char *prefix, char separator, const char *suffix, int options); -extern ssize_t acl_entry_to_any_str(const acl_entry_t entry_d, char *text_p, - ssize_t size, const acl_entry_t mask_d, - const char *prefix, int options); extern int acl_cmp(acl_t acl1, acl_t acl2); extern int acl_check(acl_t acl, int *last); extern acl_t acl_from_mode(mode_t mode); diff --git a/libacl/Makefile b/libacl/Makefile index 0810c32..8cd2a97 100644 --- a/libacl/Makefile +++ b/libacl/Makefile @@ -54,7 +54,7 @@ POSIX_CFILES = \ acl_valid.c LIBACL_CFILES = \ - acl_check.c acl_cmp.c acl_entries.c acl_entry_to_any_str.c \ + acl_check.c acl_cmp.c acl_entries.c \ acl_equiv_mode.c acl_error.c acl_extended_fd.c acl_extended_file.c \ acl_from_mode.c acl_get_fd_mode.c acl_get_file_mode.c \ acl_set_fd_mode.c acl_set_file_mode.c acl_size.c acl_to_any_text.c diff --git a/libacl/acl_entry_to_any_str.c b/libacl/acl_entry_to_any_str.c deleted file mode 100644 index 1dd336b..0000000 --- a/libacl/acl_entry_to_any_str.c +++ /dev/null @@ -1,300 +0,0 @@ -/* - File: acl_entry_to_any_str.c - - Copyright (C) 1999, 2000 - Andreas Gruenbacher, <a.gruenbacher@computer.org> - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -*/ - -#include <stdlib.h> -#include <errno.h> -#include <string.h> -#include <pwd.h> -#include <grp.h> -#include <sys/stat.h> -#include <acl/libacl.h> -#include "libacl.h" - - -static ssize_t snprint_uint(char *text_p, ssize_t size, unsigned int i); -static const char *user_name(uid_t uid); -static const char *group_name(gid_t uid); - - -/* - Convert an ACL entry to text form. - - text_p - points to a buffer - size - the size of text_p - Returns - the size of the buffer that was used, or that - would be used (if size is too small). -*/ - -#define EFFECTIVE_STR "#effective:" - -#define ADVANCE(x) \ - text_p += (x); \ - size -= (x); \ - if (size < 0) \ - size = 0; - -#define ABBREV(s, str_len) \ - if (options & TEXT_ABBREVIATE) { \ - if (size > 0) \ - text_p[0] = *(s); \ - if (size > 1) \ - text_p[1] = ':'; \ - ADVANCE(2); \ - } else { \ - strncpy(text_p, (s), size); \ - ADVANCE(str_len); \ - } - -ssize_t -acl_entry_to_any_str(const acl_entry_t entry_d, char *text_p, ssize_t size, - const acl_entry_t mask_d, const char *prefix, int options) -{ - #define TABS 4 - static const char *tabs = "\t\t\t\t"; - acl_entry_obj *entry_obj_p = ext2int(acl_entry, entry_d); - acl_entry_obj *mask_obj_p = NULL; - permset_t effective; - acl_tag_t type; - ssize_t x; - const char *orig_text_p = text_p, *str; - if (!entry_obj_p) - return -1; - if (mask_d) { - mask_obj_p = ext2int(acl_entry, mask_d); - if (!mask_obj_p) - return -1; - } - if (text_p == NULL) - size = 0; - - if (prefix) { - strncpy(text_p, prefix, size); - ADVANCE(strlen(prefix)); - } - - type = entry_obj_p->etag; - switch (type) { - case ACL_USER_OBJ: /* owner */ - mask_obj_p = NULL; - /* fall through */ - case ACL_USER: /* additional user */ - //strncpy(text_p, "user:", size); - //ADVANCE(5); - ABBREV("user:", 5); - if (type == ACL_USER) { - if (options & TEXT_NUMERIC_IDS) - str = NULL; - else - str = user_name(entry_obj_p->eid.qid); - if (str != NULL) { - strncpy(text_p, str, size); - ADVANCE(strlen(str)); - } else { - x = snprint_uint(text_p, size, - entry_obj_p->eid.qid); - ADVANCE(x); - } - } - if (size > 0) - *text_p = ':'; - ADVANCE(1); - break; - - case ACL_GROUP_OBJ: /* owning group */ - case ACL_GROUP: /* additional group */ - //strncpy(text_p, "group:", size); - //ADVANCE(6); - ABBREV("group:", 6); - if (type == ACL_GROUP) { - if (options & TEXT_NUMERIC_IDS) - str = NULL; - else - str = group_name(entry_obj_p->eid.qid); - if (str != NULL) { - strncpy(text_p, str, size); - ADVANCE(strlen(str)); - } else { - x = snprint_uint(text_p, size, - entry_obj_p->eid.qid); - ADVANCE(x); - } - } - if (size > 0) - *text_p = ':'; - ADVANCE(1); - break; - - - case ACL_MASK: /* acl mask */ - //strncpy(text_p, "mask:", size); - //ADVANCE(5); - ABBREV("mask:", 5); - if (size > 0) - *text_p = ':'; - ADVANCE(1); - break; - - case ACL_OTHER: /* other users */ - mask_obj_p = NULL; - /* fall through */ - //strncpy(text_p, "other:", size); - //ADVANCE(6); - ABBREV("other:", 6); - if (size > 0) - *text_p = ':'; - ADVANCE(1); - break; - - default: - return 0; - } - - switch ((size >= 3) ? 3 : size) { - case 3: - text_p[2] = (entry_obj_p->eperm.sperm & - ACL_EXECUTE) ? 'x' : '-'; - /* fall through */ - case 2: - text_p[1] = (entry_obj_p->eperm.sperm & - ACL_WRITE) ? 'w' : '-'; - /* fall through */ - case 1: - text_p[0] = (entry_obj_p->eperm.sperm & - ACL_READ) ? 'r' : '-'; - break; - } - ADVANCE(3); - - if (mask_obj_p && - (options & (TEXT_SOME_EFFECTIVE|TEXT_ALL_EFFECTIVE))) { - mask_obj_p = ext2int(acl_entry, mask_d); - if (!mask_obj_p) - return -1; - - effective = entry_obj_p->eperm.sperm & - mask_obj_p->eperm.sperm; - if (options & TEXT_NO_EFFECTIVE) - effective = ~ACL_PERM_NONE; - else if (options & TEXT_ALL_EFFECTIVE) - effective = ACL_PERM_NONE; - - if (effective != entry_obj_p->eperm.sperm) { - x = (options & TEXT_SMART_INDENT) ? - ((text_p - orig_text_p)/8) : TABS-1; - strncpy(text_p, tabs+x, size); - ADVANCE(TABS-x); - - strncpy(text_p, EFFECTIVE_STR, size); - ADVANCE(sizeof(EFFECTIVE_STR)-1); - - switch ((size >= 3) ? 3 : size) { - case 3: - text_p[2] = (effective & - ACL_EXECUTE) ? 'x' : '-'; - /* fall through */ - case 2: - text_p[1] = (effective & - ACL_WRITE) ? 'w' : '-'; - /* fall through */ - case 1: - text_p[0] = (effective & - ACL_READ) ? 'r' : '-'; - break; - } - ADVANCE(3); - - } - } - - /* zero-terminate string (but don't count '\0' character) */ - if (size > 0) - *text_p = '\0'; - - return (text_p - orig_text_p); /* total size required, excluding - final NULL character. */ -} - -#undef ADVANCE - - - -/* - This function is equivalent to the proposed changes to snprintf: - snprintf(text_p, size, "%u", i) - (The current snprintf returns -1 if the buffer is too small; the proposal - is to return the number of characters that would be required. See the - snprintf manual page.) -*/ - -static ssize_t -snprint_uint(char *text_p, ssize_t size, unsigned int i) -{ - unsigned int tmp = i; - int digits = 1; - unsigned int factor = 1; - - while ((tmp /= 10) != 0) { - digits++; - factor *= 10; - } - if (size && (i == 0)) { - *text_p++ = '0'; - } else { - while (size > 0 && factor > 0) { - *text_p++ = '0' + (i / factor); - size--; - i %= factor; - factor /= 10; - } - } - if (size) - *text_p = '\0'; - - return digits; -} - - -static const char * -user_name(uid_t uid) -{ - struct passwd *passwd = getpwuid(uid); - - if (passwd != NULL) - return passwd->pw_name; - else - return NULL; -} - - -static const char * -group_name(gid_t gid) -{ - struct group *group = getgrgid(gid); - - if (group != NULL) - return group->gr_name; - else - return NULL; -} - diff --git a/libacl/acl_to_any_text.c b/libacl/acl_to_any_text.c index 0dcf9b6..6562746 100644 --- a/libacl/acl_to_any_text.c +++ b/libacl/acl_to_any_text.c @@ -22,9 +22,18 @@ #include <stdio.h> #include <errno.h> #include <string.h> +#include <pwd.h> +#include <grp.h> #include <acl/libacl.h> #include "libacl.h" +static ssize_t acl_entry_to_any_str(const acl_entry_t entry_d, char *text_p, + ssize_t size, const acl_entry_t mask_d, + const char *prefix, int options); +static ssize_t snprint_uint(char *text_p, ssize_t size, unsigned int i); +static const char *user_name(uid_t uid); +static const char *group_name(gid_t uid); + char * acl_to_any_text(acl_t acl, ssize_t *len_p, const char *prefix, char separator, const char *suffix, int options) @@ -92,3 +101,246 @@ fail: return NULL; } +#define ADVANCE(x) \ + text_p += (x); \ + size -= (x); \ + if (size < 0) \ + size = 0; + +#define ABBREV(s, str_len) \ + if (options & TEXT_ABBREVIATE) { \ + if (size > 0) \ + text_p[0] = *(s); \ + if (size > 1) \ + text_p[1] = ':'; \ + ADVANCE(2); \ + } else { \ + strncpy(text_p, (s), size); \ + ADVANCE(str_len); \ + } + +#define EFFECTIVE_STR "#effective:" + +static ssize_t +acl_entry_to_any_str(const acl_entry_t entry_d, char *text_p, ssize_t size, + const acl_entry_t mask_d, const char *prefix, int options) +{ + #define TABS 4 + static const char *tabs = "\t\t\t\t"; + acl_entry_obj *entry_obj_p = ext2int(acl_entry, entry_d); + acl_entry_obj *mask_obj_p = NULL; + permset_t effective; + acl_tag_t type; + ssize_t x; + const char *orig_text_p = text_p, *str; + if (!entry_obj_p) + return -1; + if (mask_d) { + mask_obj_p = ext2int(acl_entry, mask_d); + if (!mask_obj_p) + return -1; + } + if (text_p == NULL) + size = 0; + + if (prefix) { + strncpy(text_p, prefix, size); + ADVANCE(strlen(prefix)); + } + + type = entry_obj_p->etag; + switch (type) { + case ACL_USER_OBJ: /* owner */ + mask_obj_p = NULL; + /* fall through */ + case ACL_USER: /* additional user */ + ABBREV("user:", 5); + if (type == ACL_USER) { + if (options & TEXT_NUMERIC_IDS) + str = NULL; + else + str = user_name(entry_obj_p->eid.qid); + if (str != NULL) { + strncpy(text_p, str, size); + ADVANCE(strlen(str)); + } else { + x = snprint_uint(text_p, size, + entry_obj_p->eid.qid); + ADVANCE(x); + } + } + if (size > 0) + *text_p = ':'; + ADVANCE(1); + break; + + case ACL_GROUP_OBJ: /* owning group */ + case ACL_GROUP: /* additional group */ + ABBREV("group:", 6); + if (type == ACL_GROUP) { + if (options & TEXT_NUMERIC_IDS) + str = NULL; + else + str = group_name(entry_obj_p->eid.qid); + if (str != NULL) { + strncpy(text_p, str, size); + ADVANCE(strlen(str)); + } else { + x = snprint_uint(text_p, size, + entry_obj_p->eid.qid); + ADVANCE(x); + } + } + if (size > 0) + *text_p = ':'; + ADVANCE(1); + break; + + case ACL_MASK: /* acl mask */ + ABBREV("mask:", 5); + if (size > 0) + *text_p = ':'; + ADVANCE(1); + break; + + case ACL_OTHER: /* other users */ + mask_obj_p = NULL; + /* fall through */ + ABBREV("other:", 6); + if (size > 0) + *text_p = ':'; + ADVANCE(1); + break; + + default: + return 0; + } + + switch ((size >= 3) ? 3 : size) { + case 3: + text_p[2] = (entry_obj_p->eperm.sperm & + ACL_EXECUTE) ? 'x' : '-'; + /* fall through */ + case 2: + text_p[1] = (entry_obj_p->eperm.sperm & + ACL_WRITE) ? 'w' : '-'; + /* fall through */ + case 1: + text_p[0] = (entry_obj_p->eperm.sperm & + ACL_READ) ? 'r' : '-'; + break; + } + ADVANCE(3); + + if (mask_obj_p && + (options & (TEXT_SOME_EFFECTIVE|TEXT_ALL_EFFECTIVE))) { + mask_obj_p = ext2int(acl_entry, mask_d); + if (!mask_obj_p) + return -1; + + effective = entry_obj_p->eperm.sperm & + mask_obj_p->eperm.sperm; + if (options & TEXT_NO_EFFECTIVE) + effective = ~ACL_PERM_NONE; + else if (options & TEXT_ALL_EFFECTIVE) + effective = ACL_PERM_NONE; + + if (effective != entry_obj_p->eperm.sperm) { + x = (options & TEXT_SMART_INDENT) ? + ((text_p - orig_text_p)/8) : TABS-1; + strncpy(text_p, tabs+x, size); + ADVANCE(TABS-x); + + strncpy(text_p, EFFECTIVE_STR, size); + ADVANCE(sizeof(EFFECTIVE_STR)-1); + + switch ((size >= 3) ? 3 : size) { + case 3: + text_p[2] = (effective & + ACL_EXECUTE) ? 'x' : '-'; + /* fall through */ + case 2: + text_p[1] = (effective & + ACL_WRITE) ? 'w' : '-'; + /* fall through */ + case 1: + text_p[0] = (effective & + ACL_READ) ? 'r' : '-'; + break; + } + ADVANCE(3); + + } + } + + /* zero-terminate string (but don't count '\0' character) */ + if (size > 0) + *text_p = '\0'; + + return (text_p - orig_text_p); /* total size required, excluding + final NULL character. */ +} + +#undef ADVANCE + + + +/* + This function is equivalent to the proposed changes to snprintf: + snprintf(text_p, size, "%u", i) + (The current snprintf returns -1 if the buffer is too small; the proposal + is to return the number of characters that would be required. See the + snprintf manual page.) +*/ + +static ssize_t +snprint_uint(char *text_p, ssize_t size, unsigned int i) +{ + unsigned int tmp = i; + int digits = 1; + unsigned int factor = 1; + + while ((tmp /= 10) != 0) { + digits++; + factor *= 10; + } + if (size && (i == 0)) { + *text_p++ = '0'; + } else { + while (size > 0 && factor > 0) { + *text_p++ = '0' + (i / factor); + size--; + i %= factor; + factor /= 10; + } + } + if (size) + *text_p = '\0'; + + return digits; +} + + +static const char * +user_name(uid_t uid) +{ + struct passwd *passwd = getpwuid(uid); + + if (passwd != NULL) + return passwd->pw_name; + else + return NULL; +} + + +static const char * +group_name(gid_t gid) +{ + struct group *group = getgrgid(gid); + + if (group != NULL) + return group->gr_name; + else + return NULL; +} + |