[T106][ZXW-22]7520V3SCV2.01.01.02P42U09_VEC_V0.8_AP_VEC origin source commit

Change-Id: Ic6e05d89ecd62fc34f82b23dcf306c93764aec4b
diff --git a/ap/app/busybox/src/libbb/parse_mode.c b/ap/app/busybox/src/libbb/parse_mode.c
new file mode 100644
index 0000000..5a4e1c5
--- /dev/null
+++ b/ap/app/busybox/src/libbb/parse_mode.c
@@ -0,0 +1,150 @@
+/* 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 */
+
+#include "libbb.h"
+
+/* This function is used from NOFORK applets. It must not allocate anything */
+
+#define FILEMODEBITS (S_ISUID | S_ISGID | S_ISVTX | S_IRWXU | S_IRWXG | S_IRWXO)
+
+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;
+		}
+
+		/* Get a wholist. */
+		wholist = 0;
+ WHO_LIST:
+		p = who_chars;
+		do {
+			if (*p == *s) {
+				wholist |= who_mask[(int)(p-who_chars)];
+				if (!*++s) {
+					return 0;
+				}
+				goto WHO_LIST;
+			}
+		} while (*++p);
+
+		do {    /* Process action list. */
+			if ((*s != '+') && (*s != '-')) {
+				if (*s != '=') {
+					return 0;
+				}
+				/* Since op is '=', clear all bits corresponding to the
+				 * wholist, or all file bits if wholist is empty. */
+				permlist = ~FILEMODEBITS;
+				if (wholist) {
+					permlist = ~wholist;
+				}
+				new_mode &= permlist;
+			}
+			op = *s++;
+
+			/* Check for permcopy. */
+			p = who_chars + 1;  /* Skip 'a' entry. */
+			do {
+				if (*p == *s) {
+					int i = 0;
+					permlist = who_mask[(int)(p-who_chars)]
+							 & (S_IRWXU | S_IRWXG | S_IRWXO)
+							 & new_mode;
+					do {
+						if (permlist & perm_mask[i]) {
+							permlist |= perm_mask[i];
+						}
+					} while (++i < 3);
+					++s;
+					goto GOT_ACTION;
+				}
+			} while (*++p);
+
+			/* It was not a permcopy, so get a permlist. */
+			permlist = 0;
+ PERM_LIST:
+			p = perm_chars;
+			do {
+				if (*p == *s) {
+					if ((*p != 'X')
+					 || (new_mode & (S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH))
+					) {
+						permlist |= perm_mask[(int)(p-perm_chars)];
+					}
+					if (!*++s) {
+						break;
+					}
+					goto PERM_LIST;
+				}
+			} while (*++p);
+ GOT_ACTION:
+			if (permlist) { /* The permlist was nonempty. */
+				mode_t tmp = wholist;
+				if (!wholist) {
+					mode_t u_mask = umask(0);
+					umask(u_mask);
+					tmp = ~u_mask;
+				}
+				permlist &= tmp;
+				if (op == '-') {
+					new_mode &= ~permlist;
+				} else {
+					new_mode |= permlist;
+				}
+			}
+		} while (*s && (*s != ','));
+	}
+
+	*current_mode = new_mode;
+	return 1;
+}