mode.c (7129B)
- // utils-std: Collection of commonly available Unix tools
- // SPDX-FileCopyrightText: 2017 Haelwenn (lanodan) Monnier <contact+utils@hacktivis.me>
- // SPDX-License-Identifier: MPL-2.0
- #define _POSIX_C_SOURCE 200809L
- #include "../lib/mode.h"
- #include <assert.h>
- #include <stdio.h> // printf
- #include <string.h> // strcmp
- #include <sys/stat.h> // umask
- int counter = 0;
- int t_err = 0;
- static void
- t_mode(const char *str, mode_t old, mode_t expect)
- {
- int id = ++counter;
- const char *errstr = NULL;
- mode_t got = new_mode(str, old, &errstr);
- if(got == expect && errstr == NULL)
- {
- printf("ok %d - new_mode(\"%s\", 0%06o) == 0%06o\n", id, str, old, expect);
- return;
- }
- t_err = 1;
- printf("not ok %d - new_mode(\"%s\", 0%06o) == 0%06o\n", id, str, old, expect);
- if(got != expect) printf("# Got: 0%06o\n", got);
- if(errstr != NULL) printf("# Errstr: \"%s\"\n", errstr);
- }
- static void
- t_mode_errstr(const char *str, mode_t old, const char *expect_errstr)
- {
- assert(expect_errstr != NULL);
- int id = ++counter;
- const char *errstr = NULL;
- (void)new_mode(str, old, &errstr);
- if(errstr != NULL && strcmp(errstr, expect_errstr) == 0)
- {
- printf("ok %d - new_mode(\"%s\", 0%06o) -> %s\n", id, str, old, expect_errstr);
- }
- else
- {
- printf("not ok %d - new_mode(\"%s\", 0%06o) -> %s\n", id, str, old, expect_errstr);
- printf("# Got errstr: \"%s\"\n", errstr);
- t_err = 1;
- }
- }
- static void
- add_read(void)
- {
- printf("# => add_read\n");
- umask(0044);
- t_mode("+r", 0, 00400);
- t_mode("a+r", 0, 00444);
- t_mode("u+r", 0, 00400);
- t_mode("g+r", 0, 00040);
- t_mode("o+r", 0, 00004);
- t_mode("ug+r", 0, 00440);
- t_mode("go+r", 0, 00044);
- t_mode("uo+r", 0, 00404);
- t_mode("u+r,g+r", 0, 00440);
- t_mode("g+r,o+r", 0, 00044);
- t_mode("u+r,o+r", 0, 00404);
- t_mode("+r", 00777, 00777);
- t_mode("a+r", 00777, 00777);
- t_mode("u+r", 00777, 00777);
- t_mode("g+r", 00777, 00777);
- t_mode("o+r", 00777, 00777);
- t_mode("ug+r", 00777, 00777);
- t_mode("go+r", 00777, 00777);
- t_mode("uo+r", 00777, 00777);
- t_mode("u+r,g+r", 00777, 00777);
- t_mode("g+r,o+r", 00777, 00777);
- t_mode("u+r,o+r", 00777, 00777);
- }
- static void
- set_read(void)
- {
- printf("# => set_read\n");
- umask(0044);
- t_mode("=r", 0, 00400);
- t_mode("a=r", 0, 00444);
- t_mode("u=r", 0, 00400);
- t_mode("g=r", 0, 00040);
- t_mode("o=r", 0, 00004);
- t_mode("ug=r", 0, 00440);
- t_mode("go=r", 0, 00044);
- t_mode("uo=r", 0, 00404);
- t_mode("u=r,g=r", 0, 00440);
- t_mode("g=r,o=r", 0, 00044);
- t_mode("u=r,o=r", 0, 00404);
- t_mode("go=,u=xr", 0, 00500);
- t_mode("go=,u=xr", 00777, 00500);
- t_mode("=r", 00777, 00400);
- t_mode("a=r", 00777, 00444);
- t_mode("u=r", 00777, 00477);
- t_mode("g=r", 00777, 00747);
- t_mode("o=r", 00777, 00774);
- t_mode("ug=r", 00777, 00447);
- t_mode("go=r", 00777, 00744);
- t_mode("uo=r", 00777, 00474);
- t_mode("u=r,g=r", 00777, 00447);
- t_mode("g=r,o=r", 00777, 00744);
- t_mode("u=r,o=r", 00777, 00474);
- }
- static void
- del_read(void)
- {
- printf("# => del_read\n");
- umask(0044);
- t_mode("-r", 0, 0);
- t_mode("a-r", 0, 0);
- t_mode("u-r", 0, 0);
- t_mode("g-r", 0, 0);
- t_mode("o-r", 0, 0);
- t_mode("ug-r", 0, 0);
- t_mode("go-r", 0, 0);
- t_mode("uo-r", 0, 0);
- t_mode("u-r,g-r", 0, 0);
- t_mode("g-r,o-r", 0, 0);
- t_mode("u-r,o-r", 0, 0);
- t_mode("-r", 00777, 00377);
- t_mode("a-r", 00777, 00333);
- t_mode("u-r", 00777, 00377);
- t_mode("g-r", 00777, 00737);
- t_mode("o-r", 00777, 00773);
- t_mode("ug-r", 00777, 00337);
- t_mode("go-r", 00777, 00733);
- t_mode("uo-r", 00777, 00373);
- t_mode("u-r,g-r", 00777, 00337);
- t_mode("g-r,o-r", 00777, 00733);
- t_mode("u-r,o-r", 00777, 00373);
- }
- static void
- search(void)
- {
- printf("# => search\n");
- t_mode("-X", 0, 0);
- t_mode("a-X", 0, 0);
- t_mode("u-X", 0, 0);
- t_mode("g-X", 0, 0);
- t_mode("o-X", 0, 0);
- t_mode("+X", 0, 0);
- t_mode("a+X", 0, 0);
- t_mode("u+X", 0, 0);
- t_mode("g+X", 0, 0);
- t_mode("o+X", 0, 0);
- t_mode("=X", 0, 0);
- t_mode("a=X", 0, 0);
- t_mode("u=X", 0, 0);
- t_mode("g=X", 0, 0);
- t_mode("o=X", 0, 0);
- // S_IFDIR = 0040000
- t_mode("-X", 0040777, 0040666);
- t_mode("a-X", 0040777, 0040666);
- t_mode("u-X", 0040777, 0040677);
- t_mode("g-X", 0040777, 0040767);
- t_mode("o-X", 0040777, 0040776);
- t_mode("+X", 0040777, 0040777);
- t_mode("a+X", 0040777, 0040777);
- t_mode("u+X", 0040777, 0040777);
- t_mode("g+X", 0040777, 0040777);
- t_mode("o+X", 0040777, 0040777);
- t_mode("=X", 0040777, 0040111);
- t_mode("a=X", 0040777, 0040111);
- t_mode("u=X", 0040777, 0040177);
- t_mode("g=X", 0040777, 0040717);
- t_mode("o=X", 0040777, 0040771);
- t_mode("-X", 0040000, 0040000);
- t_mode("a-X", 0040000, 0040000);
- t_mode("u-X", 0040000, 0040000);
- t_mode("g-X", 0040000, 0040000);
- t_mode("o-X", 0040000, 0040000);
- t_mode("+X", 0040000, 0040111);
- t_mode("a+X", 0040000, 0040111);
- t_mode("u+X", 0040000, 0040100);
- t_mode("g+X", 0040000, 0040010);
- t_mode("o+X", 0040000, 0040001);
- t_mode("=X", 0040000, 0040111);
- t_mode("a=X", 0040000, 0040111);
- t_mode("u=X", 0040000, 0040100);
- t_mode("g=X", 0040000, 0040010);
- t_mode("o=X", 0040000, 0040001);
- }
- static void
- syntax(void)
- {
- printf("# => syntax\n");
- t_mode("=", 0, 0);
- t_mode("=", 0040777, 0040000);
- t_mode("-", 0, 0);
- t_mode("-", 0040777, 0040777);
- t_mode("+", 0, 0);
- t_mode("+", 0040777, 0040777);
- t_mode_errstr("/", 0, "syntax error, got invalid character");
- t_mode_errstr("foo", 0, "syntax error, got invalid character");
- t_mode_errstr("77777", 0, "can't be higher than 0o7777");
- t_mode_errstr("-0", 0, "syntax error, got invalid character");
- }
- static void
- posix_examples(void)
- {
- // Examples as given by POSIX in chmod(1p)
- printf("# => posix_examples\n");
- // clears all file mode bits.
- t_mode("a+=", 0040777, 0040000);
- t_mode("a+=", 0040000, 0040000);
- // clears group and other write bits
- t_mode("go+-w", 0040777, 0040755);
- t_mode("go+-w", 0040000, 0040000);
- // sets group bit to match other bits and then clears group write bit.
- t_mode("g=o-w", 0040777, 0040757);
- t_mode("g=o-w", 0040642, 0040602);
- t_mode("g=o-w", 0040246, 0040246);
- t_mode("g=o-w", 0040000, 0040000);
- // clears group read bit and sets group write bit.
- t_mode("g-r+w", 0040777, 0040737);
- t_mode("g-r+w", 0040000, 0040020);
- // Sets owner bits to match group bits and sets other bits to match group bits.
- t_mode("uo=g", 0040777, 0040777);
- t_mode("uo=g", 0040642, 0040444);
- t_mode("uo=g", 0040000, 0040000);
- }
- static void
- non_symbolic(void)
- {
- printf("# => non_symbolic\n");
- t_mode("0", 0, 0);
- t_mode("0", 0040777, 0040000);
- t_mode("7", 0, 07);
- t_mode("7", 0040777, 0040007);
- t_mode("77", 0, 077);
- t_mode("77", 0040777, 0040077);
- t_mode("777", 0, 0777);
- t_mode("777", 0040777, 0040777);
- t_mode("700", 0, 0700);
- t_mode("700", 0040777, 0040700);
- t_mode("7777", 0, 07777);
- t_mode("7777", 0040777, 0047777);
- }
- int
- main(void)
- {
- int plan = 155;
- printf("1..%d\n", plan);
- t_mode(NULL, 0, 0);
- t_mode(NULL, 00777, 00777);
- t_mode("", 0, 0);
- t_mode("", 00777, 00777);
- t_mode(",", 0, 0);
- t_mode(",", 00777, 00777);
- t_mode("-w,+x", 00666, 00577);
- add_read();
- set_read();
- del_read();
- search();
- posix_examples();
- syntax();
- non_symbolic();
- assert(counter == plan);
- return t_err;
- }