xref: /third_party/toybox/toys/posix/chmod.c (revision 0f66f451)
1/* chmod.c - Change file mode bits
2 *
3 * Copyright 2012 Rob Landley <rob@landley.net>
4 *
5 * See http://opengroup.org/onlinepubs/9699919799/utilities/chmod.html
6
7USE_CHMOD(NEWTOY(chmod, "<2?vRf[-vf]", TOYFLAG_BIN))
8
9config CHMOD
10  bool "chmod"
11  default y
12  help
13    usage: chmod [-R] MODE FILE...
14
15    Change mode of listed file[s] (recursively with -R).
16
17    MODE can be (comma-separated) stanzas: [ugoa][+-=][rwxstXugo]
18
19    Stanzas are applied in order: For each category (u = user,
20    g = group, o = other, a = all three, if none specified default is a),
21    set (+), clear (-), or copy (=), r = read, w = write, x = execute.
22    s = u+s = suid, g+s = sgid, o+s = sticky. (+t is an alias for o+s).
23    suid/sgid: execute as the user/group who owns the file.
24    sticky: can't delete files you don't own out of this directory
25    X = x for directories or if any category already has x set.
26
27    Or MODE can be an octal value up to 7777	ug uuugggooo	top +
28    bit 1 = o+x, bit 1<<8 = u+w, 1<<11 = g+1	sstrwxrwxrwx	bottom
29
30    Examples:
31    chmod u+w file - allow owner of "file" to write to it.
32    chmod 744 file - user can read/write/execute, everyone else read only
33*/
34
35#define FOR_chmod
36#include "toys.h"
37
38GLOBALS(
39  char *mode;
40)
41
42static int do_chmod(struct dirtree *try)
43{
44  mode_t mode;
45
46  if (!dirtree_notdotdot(try)) return 0;
47
48  mode = string_to_mode(TT.mode, try->st.st_mode);
49  if (toys.optflags & FLAG_v) {
50    char *s = dirtree_path(try, 0);
51    printf("chmod '%s' to %04o\n", s, mode);
52    free(s);
53  }
54  wfchmodat(dirtree_parentfd(try), try->name, mode);
55
56  return (toys.optflags & FLAG_R) ? DIRTREE_RECURSE : 0;
57}
58
59void chmod_main(void)
60{
61  TT.mode = *toys.optargs;
62  char **file;
63
64  for (file = toys.optargs+1; *file; file++) dirtree_read(*file, do_chmod);
65}
66