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