diff options
Diffstat (limited to 'helpers')
-rw-r--r-- | helpers/defs.h | 27 | ||||
-rw-r--r-- | helpers/local.mk | 8 | ||||
-rw-r--r-- | helpers/mode.c | 285 | ||||
-rw-r--r-- | helpers/mode.h | 29 |
4 files changed, 4 insertions, 345 deletions
diff --git a/helpers/defs.h b/helpers/defs.h deleted file mode 100644 index 24e9776..0000000 --- a/helpers/defs.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (C) 2023 Patrick McDermott - * - * This file is part of opkg-opk. - * - * opkg-opk is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * opkg-opk is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with opkg-opk. If not, see <https://www.gnu.org/licenses/>. - */ - -#ifndef OPKG_OPK_DEFS_H_ -#define OPKG_OPK_DEFS_H_ - -#define OPKG_OPK_OK 0 -#define OPKG_OPK_END 1 -#define OPKG_OPK_ERROR -1 - -#endif /* OPKG_OPK_DEFS_H_ */ diff --git a/helpers/local.mk b/helpers/local.mk index 479b716..2d82b25 100644 --- a/helpers/local.mk +++ b/helpers/local.mk @@ -1,5 +1,5 @@ helpers_mknod_SOURCES = \ - %reldir%/defs.h \ - %reldir%/mknod.c \ - %reldir%/mode.c \ - %reldir%/mode.h + common/defs.h \ + common/mode.c \ + common/mode.h \ + %reldir%/mknod.c diff --git a/helpers/mode.c b/helpers/mode.c deleted file mode 100644 index b643a60..0000000 --- a/helpers/mode.c +++ /dev/null @@ -1,285 +0,0 @@ -/* - * Copyright (C) 2023 Patrick McDermott - * - * This file is part of opkg-opk. - * - * opkg-opk is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * opkg-opk is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with opkg-opk. If not, see <https://www.gnu.org/licenses/>. - */ - -#include <stdlib.h> -#include <sys/stat.h> -#include "defs.h" -#include "mode.h" - -static const mode_t OPKG_OPK_HELPER_MODE_U_ = 04700; -static const mode_t OPKG_OPK_HELPER_MODE_G_ = 02070; -static const mode_t OPKG_OPK_HELPER_MODE_O_ = 00007; -static const mode_t OPKG_OPK_HELPER_MODE_A_ = 01777; - -struct _opkg_opk_helper_mode { - mode_t umask; - mode_t cur_mode; - const char *sym_mode; - mode_t *new_mode; - mode_t who; - char op; -}; - -/* - * Grammar and operations from POSIX chown utility: - * https://pubs.opengroup.org/onlinepubs/9699919799/utilities/chmod.html - */ - -static void -_opkg_opk_helper_mode_chmod(struct _opkg_opk_helper_mode *mode, mode_t perm) -{ - switch (mode->op) { - case '+': - *mode->new_mode |= (mode->who & perm); - break; - case '-': - default: /* Should be unreachable */ - *mode->new_mode ^= (mode->who & perm); - break; - } -} - -static int -_opkg_opk_helper_mode_parse_perm(struct _opkg_opk_helper_mode *mode) -{ - switch (*mode->sym_mode) { - case 'r': - if (mode->who == 0000) { - mode->who = OPKG_OPK_HELPER_MODE_A_^mode->umask; - } - _opkg_opk_helper_mode_chmod(mode, 00444); - break; - case 'w': - if (mode->who == 0000) { - mode->who = OPKG_OPK_HELPER_MODE_A_^mode->umask; - } - _opkg_opk_helper_mode_chmod(mode, 00222); - break; - case 'x': - if (mode->who == 0000) { - mode->who = OPKG_OPK_HELPER_MODE_A_^mode->umask; - } - _opkg_opk_helper_mode_chmod(mode, 00111); - break; - case 'X': - if (mode->who == 0000) { - mode->who = OPKG_OPK_HELPER_MODE_A_^mode->umask; - } - if (S_ISDIR(mode->cur_mode) - || mode->cur_mode & 00111) { - _opkg_opk_helper_mode_chmod(mode, 00111); - } - break; - case 's': - if (mode->who == 0000) { - mode->who = OPKG_OPK_HELPER_MODE_A_^mode->umask; - } - _opkg_opk_helper_mode_chmod(mode, 06000); - break; - case 't': - if (S_ISDIR(mode->cur_mode) && (mode->who == - OPKG_OPK_HELPER_MODE_A_ || - mode->who == 0000)) { - mode->who = OPKG_OPK_HELPER_MODE_A_; - _opkg_opk_helper_mode_chmod(mode, 01000); - } - break; - default: - return OPKG_OPK_ERROR; - } - ++mode->sym_mode; - return OPKG_OPK_OK; -} - -static int -_opkg_opk_helper_mode_parse_permlist(struct _opkg_opk_helper_mode *mode) -{ - if (_opkg_opk_helper_mode_parse_perm(mode) != OPKG_OPK_OK) { - return OPKG_OPK_ERROR; - } - _opkg_opk_helper_mode_parse_permlist(mode); - return OPKG_OPK_OK; -} - -static int -_opkg_opk_helper_mode_parse_op(struct _opkg_opk_helper_mode *mode) -{ - switch (*mode->sym_mode) { - case '+': - case '-': - mode->op = *mode->sym_mode; - break; - case '=': - if (mode->who == 0000) { - *mode->new_mode &= ~07777; - } else { - *mode->new_mode &= ~mode->who; - } - mode->op = '+'; - break; - default: - return OPKG_OPK_ERROR; - } - ++mode->sym_mode; - return OPKG_OPK_OK; -} - -static int -_opkg_opk_helper_mode_parse_permcopy(struct _opkg_opk_helper_mode *mode) -{ - mode_t perm; - - switch (*mode->sym_mode) { - case 'u': - perm = (mode->cur_mode & 0700) - | (mode->cur_mode & 0700) >> 3 - | (mode->cur_mode & 0700) >> 6; - break; - case 'g': - perm = (mode->cur_mode & 0070) << 3 - | (mode->cur_mode & 0070) - | (mode->cur_mode & 0070) >> 3; - break; - case 'o': - perm = (mode->cur_mode & 0007) << 6 - | (mode->cur_mode & 0007) << 3 - | (mode->cur_mode & 0007); - break; - default: - return OPKG_OPK_ERROR; - } - if (mode->who == 0000) { - mode->who = OPKG_OPK_HELPER_MODE_A_ ^ mode->umask; - } - _opkg_opk_helper_mode_chmod(mode, perm); - ++mode->sym_mode; - return OPKG_OPK_OK; -} - -static int -_opkg_opk_helper_mode_parse_action(struct _opkg_opk_helper_mode *mode) -{ - if (_opkg_opk_helper_mode_parse_op(mode) != OPKG_OPK_OK) { - return OPKG_OPK_ERROR; - } - if (_opkg_opk_helper_mode_parse_permlist(mode) != OPKG_OPK_OK) { - _opkg_opk_helper_mode_parse_permcopy(mode); - } - return OPKG_OPK_OK; -} - -static int -_opkg_opk_helper_mode_parse_actionlist(struct _opkg_opk_helper_mode *mode) -{ - if (_opkg_opk_helper_mode_parse_action(mode) != OPKG_OPK_OK) { - return OPKG_OPK_ERROR; - } - _opkg_opk_helper_mode_parse_actionlist(mode); - return OPKG_OPK_OK; -} - -static int -_opkg_opk_helper_mode_parse_who(struct _opkg_opk_helper_mode *mode) -{ - switch (*mode->sym_mode) { - case 'u': - mode->who |= OPKG_OPK_HELPER_MODE_U_; - break; - case 'g': - mode->who |= OPKG_OPK_HELPER_MODE_G_; - break; - case 'o': - mode->who |= OPKG_OPK_HELPER_MODE_O_; - break; - case 'a': - mode->who |= OPKG_OPK_HELPER_MODE_A_; - break; - default: - return OPKG_OPK_ERROR; - } - ++mode->sym_mode; - return OPKG_OPK_OK; -} - -static int -_opkg_opk_helper_mode_parse_wholist(struct _opkg_opk_helper_mode *mode) -{ - if (_opkg_opk_helper_mode_parse_who(mode) != OPKG_OPK_OK) { - return OPKG_OPK_ERROR; - } - _opkg_opk_helper_mode_parse_wholist(mode); - return OPKG_OPK_OK; -} - -static int -_opkg_opk_helper_mode_parse_clause(struct _opkg_opk_helper_mode *mode) -{ - mode->who = 0000; - mode->op = '\0'; - _opkg_opk_helper_mode_parse_wholist(mode); - if (_opkg_opk_helper_mode_parse_actionlist(mode) != OPKG_OPK_OK) { - return OPKG_OPK_ERROR; - } - return OPKG_OPK_OK; -} - -static int -_opkg_opk_helper_mode_parse_symbolic_mode(struct _opkg_opk_helper_mode *mode) -{ - if (_opkg_opk_helper_mode_parse_clause(mode) != OPKG_OPK_OK) { - return OPKG_OPK_ERROR; - } - if (*mode->sym_mode != ',') { - return OPKG_OPK_OK; - } - ++mode->sym_mode; - if (_opkg_opk_helper_mode_parse_symbolic_mode(mode) != OPKG_OPK_OK) { - return OPKG_OPK_ERROR; - } - return OPKG_OPK_OK; -} - -int -opkg_opk_helper_mode_parse(mode_t cur_mode, const char *mode_str, - mode_t *new_mode) -{ - char *end; - long int mode_long; - struct _opkg_opk_helper_mode mode; - - mode_long = strtol(mode_str, &end, 8); - if (*end == '\0') { - if ((mode_long & 07777) != mode_long) { - return OPKG_OPK_ERROR; - } - *new_mode = (mode_long & 07777); - return OPKG_OPK_OK; - } - - mode.umask = umask(0); - umask(mode.umask); - - mode.cur_mode = cur_mode; - mode.sym_mode = mode_str; - mode.new_mode = new_mode; - - *new_mode = cur_mode; - - return _opkg_opk_helper_mode_parse_symbolic_mode(&mode); -} diff --git a/helpers/mode.h b/helpers/mode.h deleted file mode 100644 index b332268..0000000 --- a/helpers/mode.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (C) 2023 Patrick McDermott - * - * This file is part of opkg-opk. - * - * opkg-opk is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * opkg-opk is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with opkg-opk. If not, see <https://www.gnu.org/licenses/>. - */ - -#ifndef OPKG_OPK_HELPER_MODE_H_ -#define OPKG_OPK_HELPER_MODE_H_ - -#include <sys/stat.h> - -int -opkg_opk_helper_mode_parse(mode_t cur_mode, const char *mode_str, - mode_t *new_mode); - -#endif /* OPKG_OPK_HELPER_MODE_H_ */ |