[Toybox] [PATCH] mode parser
Daniel Walter
d.walter at 0x90.at
Thu Mar 8 00:40:47 PST 2012
Add string to mode_t parser
added new function string_to_mode(char *m_string, mode_t base) which
parses a given string and converts it to a mode_t.
If either + or - are part of m_string the permissions are either
added or removed from base.
Currently support for permision copy is missing (e.g. g=u),
but all other flags should work.
Format for m_string: either symbolic modes or octal representation.
symbolic modes:
[auog][[+-=][rwxst]*]
examples:
string_to_mode("u=rwx,g=rw,o=r", 0);
string_to_mode("a-x", 0777);
string_to_mode("0744", 0);
--
Also included: -m for mkfifo
regards,
daniel
--
lib/lib.c | 144 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
lib/lib.h | 2 +
toys/mkfifo.c | 9 +++-
3 files changed, 153 insertions(+), 2 deletions(-)
--
diff -r a864aa8c6331 lib/lib.c
--- a/lib/lib.c Wed Mar 07 20:05:36 2012 -0600
+++ b/lib/lib.c Thu Mar 08 09:24:44 2012 +0100
@@ -892,3 +892,147 @@
if (signames[i].num == sig) return signames[i].name;
return NULL;
}
+
+
+/* mode parsing */
+
+#define USR_FLAGS (S_IRWXU)
+#define GRP_FLAGS (S_IRWXG)
+#define OTH_FLAGS (S_IRWXO)
+#define SGT_FLAGS (S_ISUID | S_ISGID | S_ISVTX)
+
+#define MODE_WHAT(v, w, x, y, z) { \
+ if (x & v) \
+ y |= S_I##w##z;\
+ }
+#define MODE_READ(x, y, z) MODE_WHAT(0x04, R, x, y, z)
+#define MODE_WRITE(x, y, z) MODE_WHAT(0x02, W, x, y, z)
+#define MODE_EXEC(x, y, z) MODE_WHAT(0x01, X, x, y, z)
+#define MODE_SUID(x, y) MODE_WHAT(0x08, S, x, y, UID)
+#define MODE_SGID(x, y) MODE_WHAT(0x08, S, x, y, GID)
+#define MODE_SVTX(x, y) MODE_WHAT(0x10, S, x, y, VTX)
+
+mode_t
+apply_mode(int who, int how, int what, mode_t base)
+{
+ mode_t new_mode = 0;
+ mode_t tmp_mode = 0;
+ mode_t tmp_mask = USR_FLAGS | GRP_FLAGS | OTH_FLAGS | SGT_FLAGS;
+ if (who & 0x01) {
+ /* u */
+ MODE_READ(what, tmp_mode, USR);
+ MODE_WRITE(what, tmp_mode, USR);
+ MODE_EXEC(what, tmp_mode, USR);
+ MODE_SUID(what, tmp_mode)
+ tmp_mask &= (GRP_FLAGS | OTH_FLAGS | SGT_FLAGS);
+ }
+ if (who & 0x02) {
+ /* g */
+ MODE_READ(what, tmp_mode, GRP);
+ MODE_WRITE(what, tmp_mode, GRP);
+ MODE_EXEC(what, tmp_mode, GRP);
+ MODE_SGID(what, tmp_mode)
+ tmp_mask &= (USR_FLAGS | OTH_FLAGS | SGT_FLAGS);
+ }
+ if (who & 0x04) {
+ /* o */
+ MODE_READ(what, tmp_mode, OTH);
+ MODE_WRITE(what, tmp_mode, OTH);
+ MODE_EXEC(what, tmp_mode, OTH);
+ tmp_mask &= (USR_FLAGS | GRP_FLAGS | SGT_FLAGS);
+ }
+ /* check sticky */
+ MODE_SVTX(what, tmp_mode);
+ switch (how){
+ case 1:
+ /* set */
+ new_mode = tmp_mode | (base & tmp_mask);
+ break;
+ case 2:
+ /* add */
+ new_mode = base | tmp_mode;
+ break;
+ case 3:
+ /* remove */
+ new_mode = base & ~(tmp_mode);
+ break;
+ }
+ return new_mode;
+}
+
+
+mode_t
+string_to_mode(char *mode_str, mode_t base)
+{
+ mode_t new_mode;
+ int what = 0;
+ int who = 0;
+ int how = 0;
+ char *p;
+ long tmp;
+ if (!mode_str)
+ return base;
+ if (isdigit(mode_str[0])) {
+ tmp = strtol(mode_str, &p, 8);
+ if (*p || tmp < 0 ||
+ (tmp & ~(OTH_FLAGS | SGT_FLAGS | GRP_FLAGS | USR_FLAGS)))
+ return base;
+ new_mode = (mode_t) tmp;
+ return new_mode;
+ }
+ new_mode = base;
+ while (*mode_str) {
+ /* TODO: add support for permission copying */
+ switch(*mode_str) {
+ case ',':
+ /* next command */
+ new_mode = apply_mode(who, how, what, new_mode);
+ who = 0;
+ how = 0;
+ what = 0;
+ break;
+ case 'a':
+ who = 0x01 | 0x02 | 0x04;
+ break;
+ case 'u':
+ who |= 0x01;
+ break;
+ case 'g':
+ who |= 0x02;
+ break;
+ case 'o':
+ who |= 0x04;
+ break;
+ case 'r':
+ what |= 0x04;
+ break;
+ case 'w':
+ what |= 0x02;
+ break;
+ case 'x':
+ what |= 0x01;
+ break;
+ case 't':
+ what |= 0x10;
+ break;
+ case 's':
+ what |= 0x08;
+ break;
+ case '=':
+ how = 1;
+ break;
+ case '+':
+ how = 2;
+ break;
+ case '-':
+ how = 3;
+ break;
+ default:
+ /* error case */
+ return base;
+ }
+ mode_str++;
+ }
+ new_mode = apply_mode(who, how, what, new_mode);
+ return new_mode;
+}
diff -r a864aa8c6331 lib/lib.h
--- a/lib/lib.h Wed Mar 07 20:05:36 2012 -0600
+++ b/lib/lib.h Thu Mar 08 09:24:44 2012 +0100
@@ -131,3 +131,5 @@
int sig_to_num(char *pidstr);
char *num_to_sig(int sig);
+
+mode_t string_to_mode(char *mode_str, mode_t base);
diff -r a864aa8c6331 toys/mkfifo.c
--- a/toys/mkfifo.c Wed Mar 07 20:05:36 2012 -0600
+++ b/toys/mkfifo.c Thu Mar 08 09:24:44 2012 +0100
@@ -8,7 +8,7 @@
*
* TODO: Add -m
-USE_MKFIFO(NEWTOY(mkfifo, "<1", TOYFLAG_BIN))
+USE_MKFIFO(NEWTOY(mkfifo, "<1m:", TOYFLAG_BIN))
config MKFIFO
bool "mkfifo"
@@ -22,16 +22,21 @@
#include "toys.h"
DEFINE_GLOBALS(
- long mode;
+ char *m_string;
+ mode_t mode;
)
#define TT this.mkfifo
+#define FLAG_m (1)
void mkfifo_main(void)
{
char **s;
TT.mode = 0666;
+ if (toys.optflags & FLAG_m) {
+ TT.mode = string_to_mode(TT.m_string, 0);
+ }
for (s = toys.optargs; *s; s++) {
if (mknod(*s, S_IFIFO | TT.mode, 0) < 0) {
1331196047.0
More information about the Toybox
mailing list