/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * Copyright 2019, Danny Robson */ #include "acl.hpp" #include #include #include #include using cruft::acl; using cruft::entry; using cruft::permset; /////////////////////////////////////////////////////////////////////////////// acl::acl (int count) : acl (acl_init (count)) { ; } //----------------------------------------------------------------------------- acl::acl (std::filesystem::path const &path, acl_type_t type) : acl (acl_get_file (path.native ().c_str (), type)) { ; } //----------------------------------------------------------------------------- acl::acl (acl_t &&_native) : m_native (_native) { if (!m_native) cruft::posix::error::throw_code (); } /////////////////////////////////////////////////////////////////////////////// acl::~acl () { if (m_native) acl_free (m_native); } /////////////////////////////////////////////////////////////////////////////// acl acl::dup (void) const { return acl { acl_dup (m_native) }; } /////////////////////////////////////////////////////////////////////////////// acl::iterator::iterator (acl const &_parent) : m_parent (&_parent) { fetch (ACL_FIRST_ENTRY); } //----------------------------------------------------------------------------- acl::iterator::iterator () : m_parent (nullptr) { ; } //----------------------------------------------------------------------------- acl::iterator::value_type acl::iterator::operator* (void) { return entry { m_value }; } //----------------------------------------------------------------------------- acl::iterator& acl::iterator::operator++ () { fetch (ACL_NEXT_ENTRY); return *this; } //----------------------------------------------------------------------------- bool acl::iterator::operator== (iterator const &rhs) const { return m_parent == rhs.m_parent; } //----------------------------------------------------------------------------- bool acl::iterator::operator!= (iterator const &rhs) const { return m_parent != rhs.m_parent; } //----------------------------------------------------------------------------- void acl::iterator::fetch (int pos) { auto const res = acl_get_entry (m_parent->native (), pos, &m_value); switch (res) { case 0: m_parent = nullptr; return; case 1: return; default: cruft::posix::error::throw_code (); } } /////////////////////////////////////////////////////////////////////////////// acl::const_iterator acl::begin (void) const { return const_iterator { *this }; } //----------------------------------------------------------------------------- acl::const_iterator acl::end (void) const { return iterator {}; } /////////////////////////////////////////////////////////////////////////////// int acl::size (void) const { return cruft::posix::error::try_call (acl_entries, m_native); } /////////////////////////////////////////////////////////////////////////////// entry::entry (acl_entry_t _native) : m_native (_native) { ; } //----------------------------------------------------------------------------- acl_tag_t entry::tag (void) const { acl_tag_t res; cruft::posix::error::try_call (acl_get_tag_type, m_native, &res); return res; } //----------------------------------------------------------------------------- class cruft::permset entry::permset (void) const { acl_permset_t res; cruft::posix::error::try_call (acl_get_permset, m_native, &res); return res; } /////////////////////////////////////////////////////////////////////////////// permset::permset (acl_permset_t _native) : m_native (_native) { ; } //----------------------------------------------------------------------------- bool permset::operator& (acl_perm_t val) const { return cruft::posix::error::try_call (acl_get_perm, m_native, val); } /////////////////////////////////////////////////////////////////////////////// std::ostream& cruft::operator<< (std::ostream &os, cruft::acl const &val) { return os << "[ " << cruft::iterator::make_infix (val) << " ]"; } //----------------------------------------------------------------------------- std::ostream& cruft::operator<< (std::ostream &os, cruft::entry const &val) { os << "{ "; auto t = val.tag (); switch (t) { case ACL_USER: os << "uid: " << +val.qualifier (); break; case ACL_GROUP: os << "gid: " << +val.qualifier (); break; case ACL_USER_OBJ: os << "owner: null"; break; case ACL_GROUP_OBJ: os << "group: null"; break; case ACL_MASK: os << "mask: null"; break; case ACL_OTHER: os << "other: null"; break; default: unhandled (t); } os << ", permset: " << val.permset () << " }"; return os; } //----------------------------------------------------------------------------- std::ostream& cruft::operator<< (std::ostream &os, cruft::permset const &val) { return os << ((val & ACL_READ ) ? 'r' : '_') << ((val & ACL_WRITE ) ? 'w' : '_') << ((val & ACL_EXECUTE) ? 'x' : '_'); }