bb_parse_mode: do not do umask() needlessly.
diff --git a/libbb/parse_mode.c b/libbb/parse_mode.c
index 356d95d..3ab4eb6 100644
--- a/libbb/parse_mode.c
+++ b/libbb/parse_mode.c
@@ -9,49 +9,40 @@
 
 /* http://www.opengroup.org/onlinepubs/007904975/utilities/chmod.html */
 
-#include <stdlib.h>
-#include <assert.h>
-#include <sys/stat.h>
 #include "libbb.h"
 
-#define FILEMODEBITS    (S_ISUID | S_ISGID | S_ISVTX | S_IRWXU | S_IRWXG | S_IRWXO)
+#define FILEMODEBITS (S_ISUID | S_ISGID | S_ISVTX | S_IRWXU | S_IRWXG | S_IRWXO)
 
 int 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 */
+		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 */
+		S_ISUID | S_ISGID,           /* s */
+		S_ISVTX                      /* t */
 	};
-
 	static const char who_chars[] = "augo";
 	static const char perm_chars[] = "rwxXst";
 
 	const char *p;
-
 	mode_t wholist;
 	mode_t permlist;
-	mode_t mask;
 	mode_t new_mode;
 	char op;
 
-	assert(s);
-
 	if (((unsigned int)(*s - '0')) < 8) {
 		unsigned long tmp;
 		char *e;
 
-		tmp = strtol(s, &e, 8);
+		tmp = strtoul(s, &e, 8);
 		if (*e || (tmp > 07777U)) { /* Check range and trailing chars. */
 			return 0;
 		}
@@ -59,16 +50,12 @@
 		return 1;
 	}
 
-	mask = umask(0);
-	umask(mask);
-
 	new_mode = *current_mode;
 
-	/* Note: We allow empty clauses, and hence empty modes.
+	/* 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;
@@ -76,8 +63,7 @@
 
 		/* Get a wholist. */
 		wholist = 0;
-
-	WHO_LIST:
+ WHO_LIST:
 		p = who_chars;
 		do {
 			if (*p == *s) {
@@ -95,7 +81,7 @@
 					return 0;
 				}
 				/* Since op is '=', clear all bits corresponding to the
-				 * wholist, of all file bits if wholist is empty. */
+				 * wholist, or all file bits if wholist is empty. */
 				permlist = ~FILEMODEBITS;
 				if (wholist) {
 					permlist = ~wholist;
@@ -124,13 +110,12 @@
 
 			/* It was not a permcopy, so get a permlist. */
 			permlist = 0;
-
-		PERM_LIST:
+ PERM_LIST:
 			p = perm_chars;
 			do {
 				if (*p == *s) {
 					if ((*p != 'X')
-						|| (new_mode & (S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH))
+					 || (new_mode & (S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH))
 					) {
 						permlist |= perm_mask[(int)(p-perm_chars)];
 					}
@@ -140,15 +125,15 @@
 					goto PERM_LIST;
 				}
 			} while (*++p);
-
-		GOT_ACTION:
+ GOT_ACTION:
 			if (permlist) {	/* The permlist was nonempty. */
-				mode_t tmp = ~mask;
-				if (wholist) {
-					tmp = wholist;
+				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 {
@@ -159,6 +144,5 @@
 	}
 
 	*current_mode = new_mode;
-
 	return 1;
 }