Mirror of git://git.busybox.net/busybox with our patches on top
Source
/* vi: set sw=4 ts=4: */
/*
* parse_mode implementation for busybox
*
* Copyright (C) 2003 Manuel Novoa III <mjn3@codepoet.org>
*
* Licensed under GPLv2 or later, see file LICENSE in this source tree.
*/
/* http://www.opengroup.org/onlinepubs/007904975/utilities/chmod.html */
/* This function is used from NOFORK applets. It must not allocate anything */
int FAST_FUNC bb_parse_mode(const char *s, mode_t *current_mode)
{
static const mode_t who_mask[] = {
S_ISUID | S_ISGID | S_ISVTX | S_IRWXU | S_IRWXG | S_IRWXO, /* a */
S_ISUID | S_IRWXU, /* u */
S_ISGID | S_IRWXG, /* g */
S_IRWXO /* o */
};
static const mode_t perm_mask[] = {
S_IRUSR | S_IRGRP | S_IROTH, /* r */
S_IWUSR | S_IWGRP | S_IWOTH, /* w */
S_IXUSR | S_IXGRP | S_IXOTH, /* x */
S_IXUSR | S_IXGRP | S_IXOTH, /* X -- special -- see below */
S_ISUID | S_ISGID, /* s */
S_ISVTX /* t */
};
static const char who_chars[] ALIGN1 = "augo";
static const char perm_chars[] ALIGN1 = "rwxXst";
const char *p;
mode_t wholist;
mode_t permlist;
mode_t new_mode;
char op;
if ((unsigned char)(*s - '0') < 8) {
unsigned long tmp;
char *e;
tmp = strtoul(s, &e, 8);
if (*e || (tmp > 07777U)) { /* Check range and trailing chars. */
return 0;
}
*current_mode = tmp;
return 1;
}
new_mode = *current_mode;
/* Note: we allow empty clauses, and hence empty modes.
* We treat an empty mode as no change to perms. */
while (*s) { /* Process clauses. */
if (*s == ',') { /* We allow empty clauses. */
++s;
continue;