@@ -1901,6 +1901,8 @@ static int parse_mode(const struct bfs_parser *parser, const char *mode, struct
19011901		return  0 ;
19021902	}
19031903
1904+ 	mode_t  umask  =  parser -> ctx -> umask ;
1905+ 
19041906	expr -> file_mode  =  0 ;
19051907	expr -> dir_mode  =  0 ;
19061908
@@ -1938,6 +1940,7 @@ static int parse_mode(const struct bfs_parser *parser, const char *mode, struct
19381940	} op  uninit (MODE_EQUALS );
19391941
19401942	mode_t  who  uninit (0 );
1943+ 	mode_t  mask  uninit (0 );
19411944	mode_t  file_change  uninit (0 );
19421945	mode_t  dir_change  uninit (0 );
19431946
@@ -1946,6 +1949,7 @@ static int parse_mode(const struct bfs_parser *parser, const char *mode, struct
19461949		switch  (state ) {
19471950		case  MODE_CLAUSE :
19481951			who  =  0 ;
1952+ 			mask  =  0777 ;
19491953			state  =  MODE_WHO ;
19501954			fallthru ;
19511955
@@ -1989,6 +1993,9 @@ static int parse_mode(const struct bfs_parser *parser, const char *mode, struct
19891993		case  MODE_ACTION :
19901994			if  (who  ==  0 ) {
19911995				who  =  0777 ;
1996+ 				mask  =  who  &  ~umask ;
1997+ 			} else  {
1998+ 				mask  =  who ;
19921999			}
19932000
19942001			switch  (* i ) {
@@ -2048,27 +2055,27 @@ static int parse_mode(const struct bfs_parser *parser, const char *mode, struct
20482055			}
20492056
20502057			file_change  |= (file_change  << 6 ) | (file_change  << 3 );
2051- 			file_change  &= who ;
2058+ 			file_change  &= mask ;
20522059			dir_change  |= (dir_change  << 6 ) | (dir_change  << 3 );
2053- 			dir_change  &= who ;
2060+ 			dir_change  &= mask ;
20542061			state  =  MODE_ACTION_APPLY ;
20552062			break ;
20562063
20572064		case  MODE_PERM :
20582065			switch  (* i ) {
20592066			case  'r' :
2060- 				file_change  |= who  &  0444 ;
2061- 				dir_change  |= who  &  0444 ;
2067+ 				file_change  |= mask  &  0444 ;
2068+ 				dir_change  |= mask  &  0444 ;
20622069				break ;
20632070			case  'w' :
2064- 				file_change  |= who  &  0222 ;
2065- 				dir_change  |= who  &  0222 ;
2071+ 				file_change  |= mask  &  0222 ;
2072+ 				dir_change  |= mask  &  0222 ;
20662073				break ;
20672074			case  'x' :
2068- 				file_change  |= who  &  0111 ;
2075+ 				file_change  |= mask  &  0111 ;
20692076				fallthru ;
20702077			case  'X' :
2071- 				dir_change  |= who  &  0111 ;
2078+ 				dir_change  |= mask  &  0111 ;
20722079				break ;
20732080			case  's' :
20742081				if  (who  &  0700 ) {
0 commit comments