File permissions
Every file in Unix has nine permissions: read (r), write (w) and execute (x) for the owner (u), the group (g) and everyone else (o). They are written as a three-digit octal number, for example 754, or as a string rwxr-xr--: each digit is the three bits of one class, the high bit read and the low bit execute.
The chmod command changes permissions in two ways. An octal number sets all permissions at once. The symbolic form is one or more clauses separated by commas. A clause is classes (u, g, o in any combination, or a for all three), then an operator and permissions (r, w, x, possibly none):
+adds these permissions to the chosen classes;-removes them;=leaves the chosen classes with exactly these permissions and removes the rest.
Clauses are applied from left to right. Starting from the given permissions, carry out the commands in turn and print the permissions after each one.
Input
The first line holds the initial permissions, three octal digits. The second holds the number of commands q (1 ≤ q ≤ 2·10⁵). Then q lines, one command each, without spaces.
Output
After each command, the permissions as three octal digits and as a string of nine characters, separated by a space.
Examples
Example 1
644 10 u+x go-r g+rx o=r a+w a-x u=rwx,g=rx,o= 750 g= o+rwx
744 rwxr--r-- 700 rwx------ 750 rwxr-x--- 754 rwxr-xr-- 776 rwxrwxrw- 666 rw-rw-rw- 750 rwxr-x--- 750 rwxr-x--- 700 rwx------ 707 rwx---rwx
Limits
- Time · Python
- 4000 ms
- Time · Go
- 1000 ms
- Memory
- 256 MB
- Judging
- 5 tests
Walkthrough
Open it step by step: each step gives away a little more. You can jump straight to the solution, but a problem solved with one hint stays with you longer.
1Hint 1
The permissions are nine bits of one number. Which mask selects the class “group”? And the permission “write” in all classes at once?
2The idea
The mask of a class: u is 0o700, g 0o070, o 0o007, a 0o777; several classes are combined with “or”. The mask of a permission in all classes: r is 0o444, w 0o222, x 0o111. The intersection of the two masks is exactly the bits the clause touches. Then one bit operation: + is “or”, - is “and” with a negation, = first clears the whole class, then sets the bits.
3Walkthrough
In the sample: 644 is rw-r--r--. u+x adds the bit 0o100 and gives 744; go-r clears 0o044 and gives 700; o=r on 750 first clears the class of others (0o007, empty anyway), then sets 0o004, giving 754. Octal notation is convenient because each digit is one class: 7 = 4 + 2 + 1 = rwx, 5 = 4 + 1 = r-x.
The = operator is the main trap. If it is handled like +, the class's old permissions stay: o=r on rwxrwxrwx must give rwxrwxr--, not leave everything as it was. More on masks, flags and sets as numbers is in the article “Bit tricks”.
3+Solution
4Complexity
O(length of the command) per command: one bit operation per character.
5Common mistakes
=as+. It does not clear the class's old permissions: the very first test.- Forgetting several classes.
go-rremoves read from the group and the others at once: the class masks are combined. - An empty set of permissions.
g=is a legal command: the group is left with nothing. - Leading zeros. The permissions 007 are printed as
007, not7.