From 2615b187c5e446bcba965f21def342e313656201 Mon Sep 17 00:00:00 2001 From: Patrick McDermott Date: Thu, 06 Jul 2023 12:04:37 -0400 Subject: Deduplicate defs.h under common/ And add `-I"$(top_srcdir)/common"` to CPPFLAGS. --- (limited to 'helpers/mode.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 . - */ - -#include -#include -#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); -} -- cgit v0.9.1