logo

utils-std

Collection of commonly available Unix tools git clone https://anongit.hacktivis.me/git/utils-std.git/
commit: 604787e02b2ad230af2861917848970a6484afda
parent 59a90280fe0ac46c055e2f317babcc8982a0f197
Author: Haelwenn (lanodan) Monnier <contact@hacktivis.me>
Date:   Sat, 12 Apr 2025 20:18:04 +0200

lib/mode: fix handling of …-s / …=s and …-t / …=t

Diffstat:

Mlib/mode.c40++++++++++++++++++++++++++++++++--------
Mtest-lib/t_mode.c10+++++++++-
2 files changed, 41 insertions(+), 9 deletions(-)

diff --git a/lib/mode.c b/lib/mode.c @@ -247,26 +247,50 @@ new_mode(const char *mode, mode_t old, const char **errstr) if(S_ISDIR(old)) apply(&meta, 01); break; case 's': + { if(meta.op == OP_RST) { *errstr = "perm 's' given without operator"; return 0; } - if(FIELD_MATCH(meta.dest, WHO_USER)) - meta.new_modes.set = S_ISUID >> 9; - else if(FIELD_MATCH(meta.dest, WHO_GROUP)) - meta.new_modes.set = S_ISGID >> 9; - else - meta.new_modes.set = S_ISUID >> 9; + mode_t set_id = S_ISUID >> 9; + if(FIELD_MATCH(meta.dest, WHO_GROUP)) set_id = S_ISGID >> 9; + + switch(meta.op) + { + case OP_ADD: + FIELD_SET(meta.new_modes.set, set_id); + break; + case OP_DEL: + FIELD_CLR(meta.new_modes.set, set_id); + break; + case OP_SET: + meta.new_modes.set = set_id; + break; + default: + abort(); + } break; + } case 't': // Implementation defined behavior outside of directories and !(WHO_ALL|WHO_RST) - if(meta.op == OP_RST) + switch(meta.op) { + case OP_RST: *errstr = "perm 't' given without operator"; return 0; + case OP_ADD: + FIELD_SET(meta.new_modes.set, S_ISVTX >> 9); + break; + case OP_DEL: + FIELD_CLR(meta.new_modes.set, S_ISVTX >> 9); + break; + case OP_SET: + meta.new_modes.set = S_ISVTX >> 9; + break; + default: + abort(); } - meta.new_modes.set = S_ISVTX >> 9; break; default: diff --git a/test-lib/t_mode.c b/test-lib/t_mode.c @@ -288,7 +288,7 @@ non_symbolic(void) int main(void) { - int plan = 155; + int plan = 161; printf("1..%d\n", plan); t_mode(NULL, 0, 0); @@ -300,6 +300,14 @@ main(void) t_mode("-w,+x", 00666, 00577); + t_mode("a-wx,u+x,u+s", 00666, 04544); + t_mode("a-wx,ug+x,g+s", 00666, 02554); + t_mode("a-wx,ug+x,+t", 00666, 01554); + + t_mode("-s", 04544, 00544); + t_mode("g-s", 02544, 00544); + t_mode("-t", 01544, 00544); + add_read(); set_read(); del_read();