/* * libfud * Copyright 2024 Dominick Allen * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef FUD_PERMISSIONS_HPP #define FUD_PERMISSIONS_HPP #include #include #include #include namespace fud { static_assert(CHAR_BIT == 8, "Assume that uint8_t has 8 bits"); static_assert(sizeof(uint8_t) == 1, "Assume that uint8_t is 1 byte"); enum class PermissionType : uint8_t { None = 0x00, Exec = 0x01, Write = 0x02, Read = 0x04 }; struct PermissionField { explicit constexpr PermissionField(PermissionType permissionType) : m_permissions{static_cast(permissionType)} { } constexpr PermissionField(PermissionType lhs, PermissionType rhs) { m_permissions = static_cast(lhs) | static_cast(rhs); } constexpr PermissionField(PermissionType lhs, PermissionField rhs) { m_permissions = static_cast(lhs) | rhs.m_permissions; } constexpr PermissionField(PermissionField lhs, PermissionType rhs) { m_permissions = lhs.m_permissions | static_cast(rhs); } constexpr PermissionField(PermissionField lhs, PermissionField rhs) { m_permissions = lhs.m_permissions | rhs.m_permissions; } constexpr uint16_t operator()() { return m_permissions; } uint8_t m_permissions{}; }; enum class PermissionSpecialType : uint8_t { None = 0x00, Sticky = 0x01, SetGroupId = 0x02, SetUserId = 0x04 }; struct PermissionSpecial { explicit constexpr PermissionSpecial(PermissionSpecialType permissionType) : m_permissions{static_cast(permissionType)} { } constexpr PermissionSpecial(PermissionSpecialType lhs, PermissionSpecialType rhs) { m_permissions = static_cast(lhs) | static_cast(rhs); } constexpr PermissionSpecial(PermissionSpecialType lhs, PermissionSpecial rhs) { m_permissions = static_cast(lhs) | rhs.m_permissions; } constexpr PermissionSpecial(PermissionSpecial lhs, PermissionSpecialType rhs) { m_permissions = lhs.m_permissions | static_cast(rhs); } constexpr PermissionSpecial(PermissionSpecial lhs, PermissionSpecial rhs) { m_permissions = lhs.m_permissions | rhs.m_permissions; } constexpr uint16_t operator()() { return m_permissions; } uint8_t m_permissions{0}; }; class Permissions { public: static constexpr uint8_t GroupShift = 3; static constexpr uint8_t UserShift = GroupShift + 3; static constexpr uint8_t SpecialShift = UserShift + 3; constexpr Permissions(PermissionField user, PermissionField group, PermissionField others) { m_permissions = user() << UserShift | group() << GroupShift | others(); } template constexpr Permissions(U user, G group, O others) { m_permissions = PermissionField{user}() << UserShift | PermissionField{group}() << GroupShift | PermissionField{others}(); } constexpr Permissions( PermissionField user, PermissionField group, PermissionField others, PermissionSpecial special) { m_permissions = special() << SpecialShift | user() << UserShift | group() << GroupShift | others(); } template constexpr Permissions( PermissionField user, PermissionField group, PermissionField others, PermissionSpecial special) { m_permissions = special() << SpecialShift | PermissionField{user}() << UserShift | PermissionField{group}() << GroupShift | PermissionField{others}(); } constexpr int32_t operator()() { return m_permissions; } constexpr mode_t mode() { return static_cast(m_permissions); } private: int32_t m_permissions{0}; }; constexpr PermissionField operator|(PermissionType lhs, PermissionType rhs) { return PermissionField{lhs, rhs}; } constexpr PermissionField operator|(PermissionType lhs, PermissionField rhs) { return PermissionField{lhs, rhs}; } constexpr PermissionField operator|(PermissionField lhs, PermissionType rhs) { return PermissionField{lhs, rhs}; } constexpr PermissionField operator|(PermissionField lhs, PermissionField rhs) { return PermissionField{lhs, rhs}; } constexpr PermissionField PermReadWrite = PermissionType::Read | PermissionType::Write; } // namespace fud #endif