chmod.c 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  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. USE_CHMOD(NEWTOY(chmod, "<2?vfR[-vf]", TOYFLAG_BIN))
  7. config CHMOD
  8. bool "chmod"
  9. default y
  10. help
  11. usage: chmod [-R] MODE FILE...
  12. Change mode of listed file[s] (recursively with -R).
  13. MODE can be (comma-separated) stanzas: [ugoa][+-=][rwxstXugo]
  14. Stanzas are applied in order: For each category (u = user,
  15. g = group, o = other, a = all three, if none specified default is a),
  16. set (+), clear (-), or copy (=), r = read, w = write, x = execute.
  17. s = u+s = suid, g+s = sgid, +t = sticky. (o+s ignored so a+s doesn't set +t)
  18. suid/sgid: execute as the user/group who owns the file.
  19. sticky: can't delete files you don't own out of this directory
  20. X = x for directories or if any category already has x set.
  21. Or MODE can be an octal value up to 7777 ug uuugggooo top +
  22. bit 1 = o+x, bit 1<<8 = u+w, 1<<11 = g+1 sstrwxrwxrwx bottom
  23. Examples:
  24. chmod u+w file - allow owner of "file" to write to it.
  25. chmod 744 file - user can read/write/execute, everyone else read only
  26. */
  27. #define FOR_chmod
  28. #include "toys.h"
  29. GLOBALS(
  30. char *mode;
  31. )
  32. static int do_chmod(struct dirtree *try)
  33. {
  34. mode_t mode;
  35. if (!dirtree_notdotdot(try)) return 0;
  36. if (FLAG(R) && try->parent && S_ISLNK(try->st.st_mode)) {
  37. // Ignore symlinks found during recursion. We'll only try to modify
  38. // symlinks mentioned directly as arguments. We'll fail, of course,
  39. // but that's what you asked for in that case.
  40. } else {
  41. mode = string_to_mode(TT.mode, try->st.st_mode) & ~S_IFMT;
  42. if (FLAG(v)) {
  43. char *s = dirtree_path(try, 0);
  44. printf("chmod '%s' to %s\n", s, TT.mode);
  45. free(s);
  46. }
  47. wfchmodat(dirtree_parentfd(try), try->name, mode);
  48. }
  49. return FLAG(R)*DIRTREE_RECURSE;
  50. }
  51. void chmod_main(void)
  52. {
  53. TT.mode = *toys.optargs;
  54. char **file;
  55. for (file = toys.optargs+1; *file; file++) dirtree_read(*file, do_chmod);
  56. }