10f66f451Sopenharmony_ci/* chmod.c - Change file mode bits
20f66f451Sopenharmony_ci *
30f66f451Sopenharmony_ci * Copyright 2012 Rob Landley <rob@landley.net>
40f66f451Sopenharmony_ci *
50f66f451Sopenharmony_ci * See http://opengroup.org/onlinepubs/9699919799/utilities/chmod.html
60f66f451Sopenharmony_ci
70f66f451Sopenharmony_ciUSE_CHMOD(NEWTOY(chmod, "<2?vRf[-vf]", TOYFLAG_BIN))
80f66f451Sopenharmony_ci
90f66f451Sopenharmony_ciconfig CHMOD
100f66f451Sopenharmony_ci  bool "chmod"
110f66f451Sopenharmony_ci  default y
120f66f451Sopenharmony_ci  help
130f66f451Sopenharmony_ci    usage: chmod [-R] MODE FILE...
140f66f451Sopenharmony_ci
150f66f451Sopenharmony_ci    Change mode of listed file[s] (recursively with -R).
160f66f451Sopenharmony_ci
170f66f451Sopenharmony_ci    MODE can be (comma-separated) stanzas: [ugoa][+-=][rwxstXugo]
180f66f451Sopenharmony_ci
190f66f451Sopenharmony_ci    Stanzas are applied in order: For each category (u = user,
200f66f451Sopenharmony_ci    g = group, o = other, a = all three, if none specified default is a),
210f66f451Sopenharmony_ci    set (+), clear (-), or copy (=), r = read, w = write, x = execute.
220f66f451Sopenharmony_ci    s = u+s = suid, g+s = sgid, o+s = sticky. (+t is an alias for o+s).
230f66f451Sopenharmony_ci    suid/sgid: execute as the user/group who owns the file.
240f66f451Sopenharmony_ci    sticky: can't delete files you don't own out of this directory
250f66f451Sopenharmony_ci    X = x for directories or if any category already has x set.
260f66f451Sopenharmony_ci
270f66f451Sopenharmony_ci    Or MODE can be an octal value up to 7777	ug uuugggooo	top +
280f66f451Sopenharmony_ci    bit 1 = o+x, bit 1<<8 = u+w, 1<<11 = g+1	sstrwxrwxrwx	bottom
290f66f451Sopenharmony_ci
300f66f451Sopenharmony_ci    Examples:
310f66f451Sopenharmony_ci    chmod u+w file - allow owner of "file" to write to it.
320f66f451Sopenharmony_ci    chmod 744 file - user can read/write/execute, everyone else read only
330f66f451Sopenharmony_ci*/
340f66f451Sopenharmony_ci
350f66f451Sopenharmony_ci#define FOR_chmod
360f66f451Sopenharmony_ci#include "toys.h"
370f66f451Sopenharmony_ci
380f66f451Sopenharmony_ciGLOBALS(
390f66f451Sopenharmony_ci  char *mode;
400f66f451Sopenharmony_ci)
410f66f451Sopenharmony_ci
420f66f451Sopenharmony_cistatic int do_chmod(struct dirtree *try)
430f66f451Sopenharmony_ci{
440f66f451Sopenharmony_ci  mode_t mode;
450f66f451Sopenharmony_ci
460f66f451Sopenharmony_ci  if (!dirtree_notdotdot(try)) return 0;
470f66f451Sopenharmony_ci
480f66f451Sopenharmony_ci  mode = string_to_mode(TT.mode, try->st.st_mode);
490f66f451Sopenharmony_ci  if (toys.optflags & FLAG_v) {
500f66f451Sopenharmony_ci    char *s = dirtree_path(try, 0);
510f66f451Sopenharmony_ci    printf("chmod '%s' to %04o\n", s, mode);
520f66f451Sopenharmony_ci    free(s);
530f66f451Sopenharmony_ci  }
540f66f451Sopenharmony_ci  wfchmodat(dirtree_parentfd(try), try->name, mode);
550f66f451Sopenharmony_ci
560f66f451Sopenharmony_ci  return (toys.optflags & FLAG_R) ? DIRTREE_RECURSE : 0;
570f66f451Sopenharmony_ci}
580f66f451Sopenharmony_ci
590f66f451Sopenharmony_civoid chmod_main(void)
600f66f451Sopenharmony_ci{
610f66f451Sopenharmony_ci  TT.mode = *toys.optargs;
620f66f451Sopenharmony_ci  char **file;
630f66f451Sopenharmony_ci
640f66f451Sopenharmony_ci  for (file = toys.optargs+1; *file; file++) dirtree_read(*file, do_chmod);
650f66f451Sopenharmony_ci}
66