diff options
author | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
---|---|---|
committer | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
commit | e5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch) | |
tree | d8d51eac403f07814b9e936eed0c9a79195e2450 /sys/src/cmd/chmod.c |
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/cmd/chmod.c')
-rwxr-xr-x | sys/src/cmd/chmod.c | 109 |
1 files changed, 109 insertions, 0 deletions
diff --git a/sys/src/cmd/chmod.c b/sys/src/cmd/chmod.c new file mode 100755 index 000000000..425f8efce --- /dev/null +++ b/sys/src/cmd/chmod.c @@ -0,0 +1,109 @@ +#include <u.h> +#include <libc.h> + +#define U(x) (x<<6) +#define G(x) (x<<3) +#define O(x) (x) +#define A(x) (U(x)|G(x)|O(x)) + +#define DMRWE (DMREAD|DMWRITE|DMEXEC) + +int parsemode(char *, ulong *, ulong *); + +void +main(int argc, char *argv[]) +{ + int i; + Dir *dir, ndir; + ulong mode, mask; + char *p; + + if(argc < 3){ + fprint(2, "usage: chmod 0777 file ... or chmod [who]op[rwxalt] file ...\n"); + exits("usage"); + } + mode = strtol(argv[1], &p, 8); + if(*p == 0) + mask = A(DMRWE); + else if(!parsemode(argv[1], &mask, &mode)){ + fprint(2, "chmod: bad mode: %s\n", argv[1]); + exits("mode"); + } + nulldir(&ndir); + for(i=2; i<argc; i++){ + dir = dirstat(argv[i]); + if(dir == nil){ + fprint(2, "chmod: can't stat %s: %r\n", argv[i]); + continue; + } + ndir.mode = (dir->mode & ~mask) | (mode & mask); + free(dir); + if(dirwstat(argv[i], &ndir)==-1){ + fprint(2, "chmod: can't wstat %s: %r\n", argv[i]); + continue; + } + } + exits(0); +} + +int +parsemode(char *spec, ulong *pmask, ulong *pmode) +{ + ulong mode, mask; + int done, op; + char *s; + + s = spec; + mask = DMAPPEND | DMEXCL | DMTMP; + for(done=0; !done; ){ + switch(*s){ + case 'u': + mask |= U(DMRWE); break; + case 'g': + mask |= G(DMRWE); break; + case 'o': + mask |= O(DMRWE); break; + case 'a': + mask |= A(DMRWE); break; + case 0: + return 0; + default: + done = 1; + } + if(!done) + s++; + } + if(s == spec) + mask |= A(DMRWE); + op = *s++; + if(op != '+' && op != '-' && op != '=') + return 0; + mode = 0; + for(; *s ; s++){ + switch(*s){ + case 'r': + mode |= A(DMREAD); break; + case 'w': + mode |= A(DMWRITE); break; + case 'x': + mode |= A(DMEXEC); break; + case 'a': + mode |= DMAPPEND; break; + case 'l': + mode |= DMEXCL; break; + case 't': + mode |= DMTMP; break; + default: + return 0; + } + } + if(*s != 0) + return 0; + if(op == '+' || op == '-') + mask &= mode; + if(op == '-') + mode = ~mode; + *pmask = mask; + *pmode = mode; + return 1; +} |