aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpetershh <petershh@disroot.org>2022-07-31 15:35:39 +0300
committerPeter <santurysim@gmail.com>2022-08-03 00:37:07 +0300
commitba506d93e0954f02f13dbba742c83387b3bbd077 (patch)
tree7b97222622d42f13d9fc926b25a06b152666fbe7
parent209e0fd80abba905559c8542bf4adfcde2c4445d (diff)
downloadshh-portable-utils-ba506d93e0954f02f13dbba742c83387b3bbd077.tar.xz
Move parse_octal, parse_symbolic and change_mode to their own files
-rw-r--r--package/deps.mak7
-rw-r--r--src/shh-portable-utils/change_mode.c82
-rw-r--r--src/shh-portable-utils/chmod.c234
-rw-r--r--src/shh-portable-utils/deps-exe/chmod3
-rw-r--r--src/shh-portable-utils/parse_octal.c39
-rw-r--r--src/shh-portable-utils/parse_symbolic.c127
6 files changed, 256 insertions, 236 deletions
diff --git a/package/deps.mak b/package/deps.mak
index d078b77..d84009e 100644
--- a/package/deps.mak
+++ b/package/deps.mak
@@ -5,8 +5,9 @@
src/shh-portable-utils/basename.o src/shh-portable-utils/basename.lo: src/shh-portable-utils/basename.c
src/shh-portable-utils/byte_notin.o src/shh-portable-utils/byte_notin.lo: src/shh-portable-utils/byte_notin.c src/shh-portable-utils/shhfuncs.h
src/shh-portable-utils/cat.o src/shh-portable-utils/cat.lo: src/shh-portable-utils/cat.c
+src/shh-portable-utils/change_mode.o src/shh-portable-utils/change_mode.lo: src/shh-portable-utils/change_mode.c src/shh-portable-utils/shhfuncs.h
src/shh-portable-utils/chgrp.o src/shh-portable-utils/chgrp.lo: src/shh-portable-utils/chgrp.c src/shh-portable-utils/shhfuncs.h
-src/shh-portable-utils/chmod.o src/shh-portable-utils/chmod.lo: src/shh-portable-utils/chmod.c
+src/shh-portable-utils/chmod.o src/shh-portable-utils/chmod.lo: src/shh-portable-utils/chmod.c src/shh-portable-utils/shhfuncs.h
src/shh-portable-utils/chown.o src/shh-portable-utils/chown.lo: src/shh-portable-utils/chown.c src/shh-portable-utils/shhfuncs.h
src/shh-portable-utils/cut.o src/shh-portable-utils/cut.lo: src/shh-portable-utils/cut.c src/shh-portable-utils/shhfuncs.h
src/shh-portable-utils/dirname.o src/shh-portable-utils/dirname.lo: src/shh-portable-utils/dirname.c
@@ -16,6 +17,8 @@ src/shh-portable-utils/ln.o src/shh-portable-utils/ln.lo: src/shh-portable-utils
src/shh-portable-utils/nice.o src/shh-portable-utils/nice.lo: src/shh-portable-utils/nice.c
src/shh-portable-utils/nohup.o src/shh-portable-utils/nohup.lo: src/shh-portable-utils/nohup.c
src/shh-portable-utils/parse_group.o src/shh-portable-utils/parse_group.lo: src/shh-portable-utils/parse_group.c
+src/shh-portable-utils/parse_octal.o src/shh-portable-utils/parse_octal.lo: src/shh-portable-utils/parse_octal.c src/shh-portable-utils/shhfuncs.h
+src/shh-portable-utils/parse_symbolic.o src/shh-portable-utils/parse_symbolic.lo: src/shh-portable-utils/parse_symbolic.c
src/shh-portable-utils/parse_user.o src/shh-portable-utils/parse_user.lo: src/shh-portable-utils/parse_user.c src/shh-portable-utils/shhfuncs.h
src/shh-portable-utils/renice.o src/shh-portable-utils/renice.lo: src/shh-portable-utils/renice.c src/shh-portable-utils/shhfuncs.h
src/shh-portable-utils/shhgetln.o src/shh-portable-utils/shhgetln.lo: src/shh-portable-utils/shhgetln.c src/shh-portable-utils/shhfuncs.h
@@ -33,7 +36,7 @@ cat: src/shh-portable-utils/cat.o
chgrp: EXTRA_LIBS := ${SOCKET_LIB} -lskarnet
chgrp: src/shh-portable-utils/chgrp.o src/shh-portable-utils/parse_group.o ${LIBNSSS}
chmod: EXTRA_LIBS := -lskarnet
-chmod: src/shh-portable-utils/chmod.o
+chmod: src/shh-portable-utils/chmod.o src/shh-portable-utils/parse_octal.o src/shh-portable-utils/parse_symbolic.o src/shh-portable-utils/change_mode.o
chown: EXTRA_LIBS := ${SOCKET_LIB} -lskarnet
chown: src/shh-portable-utils/chown.o src/shh-portable-utils/parse_user.o src/shh-portable-utils/parse_group.o ${LIBNSSS}
cut: EXTRA_LIBS := -lskarnet
diff --git a/src/shh-portable-utils/change_mode.c b/src/shh-portable-utils/change_mode.c
new file mode 100644
index 0000000..611981c
--- /dev/null
+++ b/src/shh-portable-utils/change_mode.c
@@ -0,0 +1,82 @@
+#include <sys/stat.h>
+
+#include <skalibs/genalloc.h>
+#include <skalibs/strerr2.h>
+
+#include "shhfuncs.h"
+
+int change_mode(char const *file, mode_t mode, genalloc *directives,
+ mode_t mask)
+{
+ mode_t cur_mode;
+ if (!genalloc_len(chmod_directive, directives))
+ cur_mode = mode;
+ else {
+ struct stat st;
+ mode_t who, perm, clear;
+ chmod_directive const *s = genalloc_s(chmod_directive, directives);
+ size_t len = genalloc_len(chmod_directive, directives);
+
+ if (stat(file, &st) == -1) {
+ strerr_warnwu2sys("stat ", file);
+ return 1;
+ }
+ cur_mode = st.st_mode;
+
+ for (size_t i = 0; i < len; i++) {
+ if (s[i].who) {
+ who = s[i].who;
+ clear = s[i].who;
+ }
+ else {
+ who = ~mask;
+ clear = S_ISALL;
+ }
+ perm = s[i].perm;
+
+ if (s[i].permcopy & 1) {
+ if (cur_mode & S_IRUSR)
+ perm |= S_IRUSR | S_IRGRP | S_IROTH;
+ if (cur_mode & S_IWUSR)
+ perm |= S_IWUSR | S_IWGRP | S_IWOTH;
+ if (cur_mode & S_IXUSR)
+ perm |= S_IXUSR | S_IXGRP | S_IXOTH;
+ }
+ if (s[i].permcopy & 2) {
+ if (cur_mode & S_IRGRP)
+ perm |= S_IRUSR | S_IRGRP | S_IROTH;
+ if (cur_mode & S_IWGRP)
+ perm |= S_IWUSR | S_IWGRP | S_IWOTH;
+ if (cur_mode & S_IXGRP)
+ perm |= S_IXUSR | S_IXGRP | S_IXOTH;
+ }
+ if (s[i].permcopy & 4) {
+ if (cur_mode & S_IROTH)
+ perm |= S_IRUSR | S_IRGRP | S_IROTH;
+ if (cur_mode & S_IWOTH)
+ perm |= S_IWUSR | S_IWGRP | S_IWOTH;
+ if (cur_mode & S_IXOTH)
+ perm |= S_IXUSR | S_IXGRP | S_IXOTH;
+ }
+
+ if (s[i].dir_x && (S_ISDIR(cur_mode)
+ || (cur_mode & (S_IXUSR | S_IXGRP | S_IXOTH))))
+ perm |= S_IXUSR | S_IXGRP | S_IXOTH;
+
+ switch (s[i].action) {
+ case '=':
+ cur_mode &= ~clear;
+ case '+':
+ cur_mode |= (who & perm);
+ break;
+ case '-':
+ cur_mode &= ~(who & perm);
+ }
+ }
+ }
+ if (chmod(file, cur_mode) == -1) {
+ strerr_warnwu2sys("change mode of ", file);
+ return 1;
+ }
+ return 0;
+}
diff --git a/src/shh-portable-utils/chmod.c b/src/shh-portable-utils/chmod.c
index 40091e6..9518730 100644
--- a/src/shh-portable-utils/chmod.c
+++ b/src/shh-portable-utils/chmod.c
@@ -79,240 +79,6 @@ int main(int argc, char const *const *argv)
return failure ? 111 : 0;
}
-
-mode_t parse_octal(char const *raw_mode)
-{
- mode_t mode = 0;
- unsigned int m;
- if (!uint0_oscan(raw_mode, &m))
- strerr_dief2x(100, "invalid mode: ", raw_mode);
-
- if (m & 0001)
- mode |= S_IXOTH;
- if (m & 0002)
- mode |= S_IWOTH;
- if (m & 0004)
- mode |= S_IROTH;
- if (m & 0010)
- mode |= S_IXGRP;
- if (m & 0020)
- mode |= S_IWGRP;
- if (m & 0040)
- mode |= S_IRGRP;
- if (m & 0100)
- mode |= S_IXUSR;
- if (m & 0200)
- mode |= S_IWUSR;
- if (m & 0400)
- mode |= S_IRUSR;
- if (m & 01000)
- mode |= S_ISVTX;
- if (m & 02000)
- mode |= S_ISGID;
- if (m & 04000)
- mode |= S_ISUID;
-
- return mode;
-}
-
-void parse_symbolic(char const *raw, genalloc *directives)
-{
- char const *p = raw;
- for (;;) {
- chmod_directive d = CHMOD_DIRECTIVE_ZERO;
- /* stage 1: parse 'who' list */
- for (;;) {
- if (*p == 'u')
- d.who |= S_IRWXU | S_ISUID;
- else if (*p == 'g')
- d.who |= S_IRWXG | S_ISGID;
- else if (*p == 'o')
- d.who |= S_IRWXO;
- else if (*p == 'a')
- d.who |= S_IRWXU | S_IRWXG | S_IRWXO | S_ISUID | S_ISGID;
- else
- break;
- p++;
- }
- /* stage 2: actions. First cycle is out of the loop. */
- switch(*p) {
- case '+':
- case '-':
- case '=':
- d.action = *p;
- break;
- default:
- strerr_dief2x(100, "invalid mode: ", raw);
- }
- p++;
- for (;;) {
- if (*p == 'u')
- d.permcopy |= 1;
- else if (*p == 'g')
- d.permcopy |= 2;
- else if (*p == 'o')
- d.permcopy |= 4;
- else if (*p == 'r')
- d.perm |= S_IRUSR | S_IRGRP | S_IROTH;
- else if (*p == 'w')
- d.perm |= S_IWUSR | S_IWGRP | S_IWOTH;
- else if (*p == 'x')
- d.perm |= S_IXUSR | S_IXGRP | S_IXOTH;
- else if (*p == 'X')
- d.dir_x = 1;
- else if (*p == 's')
- d.perm |= S_ISUID | S_ISGID;
- else if (*p == 't')
- d.perm |= S_ISVTX;
- else if (*p == ',') {
- p++;
- break;
- }
- else if (*p == '\0') {
- if (d.perm && d.permcopy)
- strerr_dief2x(100, "invalid mode: ", raw);
- if (!genalloc_append(chmod_directive, directives, &d))
- strerr_diefu1sys(111, "parse mode");
- return;
- }
- p++;
- }
-
- if (d.perm && d.permcopy)
- strerr_dief2x(100, "invalid mode: ", raw);
- if (!genalloc_append(chmod_directive, directives, &d))
- strerr_diefu1sys(111, "parse mode");
-
- for (;;) {
- d.action = d.perm = d.permcopy = d.dir_x = 0;
- if (*p == '+' || *p == '-' || *p == '=')
- d.action = *p;
- else if (*p == ',')
- break;
- else if (*p == '\0')
- return;
- else
- strerr_dief2x(100, "invalid mode: ", raw);
-
- p++;
-
- for (;;) {
- if (*p == 'u')
- d.permcopy |= 1;
- else if (*p == 'g')
- d.permcopy |= 2;
- else if (*p == 'o')
- d.permcopy |= 4;
- else if (*p == 'r')
- d.perm |= S_IRUSR | S_IRGRP | S_IROTH;
- else if (*p == 'w')
- d.perm |= S_IWUSR | S_IWGRP | S_IWOTH;
- else if (*p == 'x')
- d.perm |= S_IXUSR | S_IXGRP | S_IXOTH;
- else if (*p == 'X')
- d.dir_x = 1;
- else if (*p == 's')
- d.perm |= S_ISUID | S_ISGID;
- else if (*p == 't')
- d.perm |= S_ISVTX;
- else if (*p == ',') {
- p++;
- break;
- }
- else if (*p == '\0') {
- if (d.perm && d.permcopy)
- strerr_dief2x(100, "invalid mode: ", raw);
- if (!genalloc_append(chmod_directive, directives, &d))
- strerr_diefu1sys(111, "parse mode");
- return;
- }
- p++;
- }
-
- if (d.perm && d.permcopy)
- strerr_dief2x(100, "invalid mode: ", raw);
- if (!genalloc_append(chmod_directive, directives, &d))
- strerr_diefu1sys(111, "parse mode");
- }
- }
-}
-
-int change_mode(char const *file, mode_t mode, genalloc *directives,
- mode_t mask)
-{
- mode_t cur_mode;
- if (!genalloc_len(chmod_directive, directives))
- cur_mode = mode;
- else {
- struct stat st;
- mode_t who, perm, clear;
- chmod_directive const *s = genalloc_s(chmod_directive, directives);
- size_t len = genalloc_len(chmod_directive, directives);
-
- if (stat(file, &st) == -1) {
- strerr_warnwu2sys("stat ", file);
- return 1;
- }
- cur_mode = st.st_mode;
-
- for (size_t i = 0; i < len; i++) {
- if (s[i].who) {
- who = s[i].who;
- clear = s[i].who;
- }
- else {
- who = ~mask;
- clear = S_ISALL;
- }
- perm = s[i].perm;
-
- if (s[i].permcopy & 1) {
- if (cur_mode & S_IRUSR)
- perm |= S_IRUSR | S_IRGRP | S_IROTH;
- if (cur_mode & S_IWUSR)
- perm |= S_IWUSR | S_IWGRP | S_IWOTH;
- if (cur_mode & S_IXUSR)
- perm |= S_IXUSR | S_IXGRP | S_IXOTH;
- }
- if (s[i].permcopy & 2) {
- if (cur_mode & S_IRGRP)
- perm |= S_IRUSR | S_IRGRP | S_IROTH;
- if (cur_mode & S_IWGRP)
- perm |= S_IWUSR | S_IWGRP | S_IWOTH;
- if (cur_mode & S_IXGRP)
- perm |= S_IXUSR | S_IXGRP | S_IXOTH;
- }
- if (s[i].permcopy & 4) {
- if (cur_mode & S_IROTH)
- perm |= S_IRUSR | S_IRGRP | S_IROTH;
- if (cur_mode & S_IWOTH)
- perm |= S_IWUSR | S_IWGRP | S_IWOTH;
- if (cur_mode & S_IXOTH)
- perm |= S_IXUSR | S_IXGRP | S_IXOTH;
- }
-
- if (s[i].dir_x && (S_ISDIR(cur_mode)
- || (cur_mode & (S_IXUSR | S_IXGRP | S_IXOTH))))
- perm |= S_IXUSR | S_IXGRP | S_IXOTH;
-
- switch (s[i].action) {
- case '=':
- cur_mode &= ~clear;
- case '+':
- cur_mode |= (who & perm);
- break;
- case '-':
- cur_mode &= ~(who & perm);
- }
- }
- }
- if (chmod(file, cur_mode) == -1) {
- strerr_warnwu2sys("change mode of ", file);
- return 1;
- }
- return 0;
-}
-
int traverse_dir(stralloc *dirname, mode_t mode, genalloc *directives,
mode_t mask)
{
diff --git a/src/shh-portable-utils/deps-exe/chmod b/src/shh-portable-utils/deps-exe/chmod
index e7187fe..939c605 100644
--- a/src/shh-portable-utils/deps-exe/chmod
+++ b/src/shh-portable-utils/deps-exe/chmod
@@ -1 +1,4 @@
+parse_octal.o
+parse_symbolic.o
+change_mode.o
-lskarnet
diff --git a/src/shh-portable-utils/parse_octal.c b/src/shh-portable-utils/parse_octal.c
new file mode 100644
index 0000000..c969f5f
--- /dev/null
+++ b/src/shh-portable-utils/parse_octal.c
@@ -0,0 +1,39 @@
+#include <skalibs/types.h>
+#include <skalibs/strerr2.h>
+
+#include "shhfuncs.h"
+
+mode_t parse_octal(char const *raw_mode)
+{
+ mode_t mode = 0;
+ unsigned int m;
+ if (!uint0_oscan(raw_mode, &m))
+ strerr_dief2x(100, "invalid mode: ", raw_mode);
+
+ if (m & 0001)
+ mode |= S_IXOTH;
+ if (m & 0002)
+ mode |= S_IWOTH;
+ if (m & 0004)
+ mode |= S_IROTH;
+ if (m & 0010)
+ mode |= S_IXGRP;
+ if (m & 0020)
+ mode |= S_IWGRP;
+ if (m & 0040)
+ mode |= S_IRGRP;
+ if (m & 0100)
+ mode |= S_IXUSR;
+ if (m & 0200)
+ mode |= S_IWUSR;
+ if (m & 0400)
+ mode |= S_IRUSR;
+ if (m & 01000)
+ mode |= S_ISVTX;
+ if (m & 02000)
+ mode |= S_ISGID;
+ if (m & 04000)
+ mode |= S_ISUID;
+
+ return mode;
+}
diff --git a/src/shh-portable-utils/parse_symbolic.c b/src/shh-portable-utils/parse_symbolic.c
new file mode 100644
index 0000000..3c2ea94
--- /dev/null
+++ b/src/shh-portable-utils/parse_symbolic.c
@@ -0,0 +1,127 @@
+#include <skalibs/genalloc.h>
+#include <skalibs/strerr2.h>
+
+#include "shhfuncs.h"
+
+void parse_symbolic(char const *raw, genalloc *directives)
+{
+ char const *p = raw;
+ for (;;) {
+ chmod_directive d = CHMOD_DIRECTIVE_ZERO;
+ /* stage 1: parse 'who' list */
+ for (;;) {
+ if (*p == 'u')
+ d.who |= S_IRWXU | S_ISUID;
+ else if (*p == 'g')
+ d.who |= S_IRWXG | S_ISGID;
+ else if (*p == 'o')
+ d.who |= S_IRWXO;
+ else if (*p == 'a')
+ d.who |= S_IRWXU | S_IRWXG | S_IRWXO | S_ISUID | S_ISGID;
+ else
+ break;
+ p++;
+ }
+ /* stage 2: actions. First cycle is out of the loop. */
+ switch(*p) {
+ case '+':
+ case '-':
+ case '=':
+ d.action = *p;
+ break;
+ default:
+ strerr_dief2x(100, "invalid mode: ", raw);
+ }
+ p++;
+ for (;;) {
+ if (*p == 'u')
+ d.permcopy |= 1;
+ else if (*p == 'g')
+ d.permcopy |= 2;
+ else if (*p == 'o')
+ d.permcopy |= 4;
+ else if (*p == 'r')
+ d.perm |= S_IRUSR | S_IRGRP | S_IROTH;
+ else if (*p == 'w')
+ d.perm |= S_IWUSR | S_IWGRP | S_IWOTH;
+ else if (*p == 'x')
+ d.perm |= S_IXUSR | S_IXGRP | S_IXOTH;
+ else if (*p == 'X')
+ d.dir_x = 1;
+ else if (*p == 's')
+ d.perm |= S_ISUID | S_ISGID;
+ else if (*p == 't')
+ d.perm |= S_ISVTX;
+ else if (*p == ',') {
+ p++;
+ break;
+ }
+ else if (*p == '\0') {
+ if (d.perm && d.permcopy)
+ strerr_dief2x(100, "invalid mode: ", raw);
+ if (!genalloc_append(chmod_directive, directives, &d))
+ strerr_diefu1sys(111, "parse mode");
+ return;
+ }
+ p++;
+ }
+
+ if (d.perm && d.permcopy)
+ strerr_dief2x(100, "invalid mode: ", raw);
+ if (!genalloc_append(chmod_directive, directives, &d))
+ strerr_diefu1sys(111, "parse mode");
+
+ for (;;) {
+ d.action = d.perm = d.permcopy = d.dir_x = 0;
+ if (*p == '+' || *p == '-' || *p == '=')
+ d.action = *p;
+ else if (*p == ',')
+ break;
+ else if (*p == '\0')
+ return;
+ else
+ strerr_dief2x(100, "invalid mode: ", raw);
+
+ p++;
+
+ for (;;) {
+ if (*p == 'u')
+ d.permcopy |= 1;
+ else if (*p == 'g')
+ d.permcopy |= 2;
+ else if (*p == 'o')
+ d.permcopy |= 4;
+ else if (*p == 'r')
+ d.perm |= S_IRUSR | S_IRGRP | S_IROTH;
+ else if (*p == 'w')
+ d.perm |= S_IWUSR | S_IWGRP | S_IWOTH;
+ else if (*p == 'x')
+ d.perm |= S_IXUSR | S_IXGRP | S_IXOTH;
+ else if (*p == 'X')
+ d.dir_x = 1;
+ else if (*p == 's')
+ d.perm |= S_ISUID | S_ISGID;
+ else if (*p == 't')
+ d.perm |= S_ISVTX;
+ else if (*p == ',') {
+ p++;
+ break;
+ }
+ else if (*p == '\0') {
+ if (d.perm && d.permcopy)
+ strerr_dief2x(100, "invalid mode: ", raw);
+ if (!genalloc_append(chmod_directive, directives, &d))
+ strerr_diefu1sys(111, "parse mode");
+ return;
+ }
+ p++;
+ }
+
+ if (d.perm && d.permcopy)
+ strerr_dief2x(100, "invalid mode: ", raw);
+ if (!genalloc_append(chmod_directive, directives, &d))
+ strerr_diefu1sys(111, "parse mode");
+ }
+ }
+}
+