4 Copyright (C) 1999, 2000, 2001
5 Andreas Gruenbacher, <a.gruenbacher@bestbits.at>
7 This program is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Lesser General Public
9 License as published by the Free Software Foundation; either
10 version 2.1 of the License, or (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
17 You should have received a copy of the GNU Lesser General Public
18 License along with this library; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
29 #define SKIP_WS(x) do { \
30 while (*(x)==' ' || *(x)=='\t' || *(x)=='\n' || *(x)=='\r') \
33 while (*(x)!='\n' && *(x)!='\0') \
39 static int parse_acl_entry(const char **text_p, acl_t *acl_p);
44 acl_from_text(const char *buf_p)
54 while (*buf_p != '\0') {
55 if (parse_acl_entry(&buf_p, &acl) != 0)
77 skip_tag_name(const char **text_p, const char *token)
79 size_t len = strlen(token);
80 const char *text = *text_p;
83 if (strncmp(text, token, len) == 0) {
87 if (*text == *token) {
103 get_token(const char **text_p)
111 while (*ep!='\0' && *ep!='\r' && *ep!='\n' && *ep!=':' && *ep!=',')
115 token = (char*)malloc(ep - *text_p + 1);
118 memcpy(token, *text_p, (ep - *text_p));
119 token[ep - *text_p] = '\0';
129 get_id(const char *token, id_t *id_p)
133 l = strtol(token, &ep, 0);
138 Negative values are interpreted as 16-bit numbers,
139 so that id -2 maps to 65534 (nobody/nogroup), etc.
149 get_uid(const char *token, uid_t *uid_p)
151 struct passwd *passwd;
153 if (get_id(token, uid_p) == 0)
155 passwd = getpwnam(token);
157 *uid_p = passwd->pw_uid;
165 get_gid(const char *token, gid_t *gid_p)
169 if (get_id(token, (uid_t *)gid_p) == 0)
171 group = getgrnam(token);
173 *gid_p = group->gr_gid;
181 Parses the next acl entry in text_p.
184 -1 on error, 0 on success.
188 parse_acl_entry(const char **text_p, acl_t *acl_p)
190 acl_entry_obj entry_obj;
194 int error, perm_chars;
196 new_obj_p_here(acl_entry, &entry_obj);
197 init_acl_entry_obj(entry_obj);
199 /* parse acl entry type */
203 if (!skip_tag_name(text_p, "user"))
206 str = get_token(text_p);
208 entry_obj.etag = ACL_USER;
209 error = get_uid(unquote(str),
217 entry_obj.etag = ACL_USER_OBJ;
221 case 'g': /* group */
222 if (!skip_tag_name(text_p, "group"))
225 str = get_token(text_p);
227 entry_obj.etag = ACL_GROUP;
228 error = get_gid(unquote(str),
236 entry_obj.etag = ACL_GROUP_OBJ;
241 if (!skip_tag_name(text_p, "mask"))
243 /* skip empty entry qualifier field (this field may
244 be missing for compatibility with Solaris.) */
248 entry_obj.etag = ACL_MASK;
251 case 'o': /* other */
252 if (!skip_tag_name(text_p, "other"))
254 /* skip empty entry qualifier field (this field may
255 be missing for compatibility with Solaris.) */
259 entry_obj.etag = ACL_OTHER;
266 for (perm_chars=0; perm_chars<3; perm_chars++, (*text_p)++) {
269 if (entry_obj.eperm.sperm & ACL_READ)
271 entry_obj.eperm.sperm |= ACL_READ;
275 if (entry_obj.eperm.sperm & ACL_WRITE)
277 entry_obj.eperm.sperm |= ACL_WRITE;
281 if (entry_obj.eperm.sperm & ACL_EXECUTE)
283 entry_obj.eperm.sperm |= ACL_EXECUTE;
298 if (acl_create_entry(acl_p, &entry_d) != 0)
300 if (acl_copy_entry(entry_d, int2ext(&entry_obj)) != 0)