7 const char chmod_usage[] = "chmod [-R] mode file [file ...]\n"
8 "\nmode may be an octal integer representing the bit pattern for the\n"
9 "\tnew mode, or a symbolic value matching the pattern\n"
10 "\t[ugoa]{+|-|=}[rwxst] .\n"
16 "\n+:\tAdd privilege\n"
17 "\n-:\tRemove privilege\n"
18 "\n=:\tSet privilege\n"
23 "\t\ts:\tSet User ID\n"
24 "\t\tt:\t\"Sticky\" Text\n"
26 "\tModes may be concatenated, as in \"u=rwx,g=rx,o=rx,-t,-s\n"
28 "\t-R:\tRecursively change the mode of all files and directories\n"
29 "\t\tunder the argument directory.";
38 /* [ugoa]{+|-|=}[rwxstl] */
40 mode_t groups = S_ISVTX;
50 groups |= S_ISUID|S_IRWXU;
53 groups |= S_ISGID|S_IRWXG;
59 groups |= S_ISUID|S_ISGID|S_IRWXU|S_IRWXG|S_IRWXO;
65 if ( groups == S_ISVTX ) /* The default is "all" */
66 groups |= S_ISUID|S_ISGID|S_IRWXU|S_IRWXG|S_IRWXO;
69 if ( c >= '0' && c <= '7' && mode == 0 && groups == S_ISVTX ) {
71 *or = strtol(--s, 0, 010);
80 while ( (c = *s++) != '\0' ) {
85 mode |= S_IRUSR|S_IRGRP|S_IROTH;
88 mode |= S_IWUSR|S_IWGRP|S_IWOTH;
91 mode |= S_IXUSR|S_IXGRP|S_IXOTH;
94 if ( group_execute != 0 && (groups & S_IRWXG) ) {
95 if ( *group_execute < 0 )
102 mode |= S_ISUID|S_ISGID;
105 if ( *group_execute > 0 )
127 *or |= mode & groups;
130 *and &= ~(mode & groups);
134 } while ( c == ',' );
139 chmod_main(struct FileInfo * i, int argc, char * * argv)
141 i->andWithMode = S_ISVTX|S_ISUID|S_ISGID|S_IRWXU|S_IRWXG|S_IRWXO;
144 while ( argc >= 3 ) {
145 if ( parse_mode(argv[1], &i->orWithMode, &i->andWithMode, 0)
150 else if ( strcmp(argv[1], "-R") == 0 ) {
160 i->complainInPostProcess = 1;
162 return monadic_main(i, argc, argv);