140 lines
3.4 KiB
C++
140 lines
3.4 KiB
C++
/*
|
|
* 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 <danny@nerdcruft.net>
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <cruft/util/std.hpp>
|
|
|
|
#include <iosfwd>
|
|
#include <filesystem>
|
|
#include <cstring>
|
|
#include <optional>
|
|
|
|
#include <sys/acl.h>
|
|
|
|
|
|
namespace cruft {
|
|
/// A combination of read, write, and/or execute flags.
|
|
class permset {
|
|
public:
|
|
permset (acl_permset_t _native);
|
|
|
|
bool operator& (acl_perm_t) const;
|
|
|
|
private:
|
|
acl_permset_t m_native;
|
|
};
|
|
|
|
|
|
/// One single entry in an ACL. Contains a tag, qualifier, and permset.
|
|
class entry {
|
|
public:
|
|
explicit entry (acl_entry_t);
|
|
|
|
acl_tag_t tag (void) const;
|
|
|
|
// It would be nice to use a tagged union, but uid_t and gid_t would
|
|
// clash if we used something like std::variant. And we can't just
|
|
// return an int because some systems have larger objects (eg, MacOS
|
|
// with ACL_EXTENDED_ALLOW returns a guid_t).
|
|
template <typename ValueT>
|
|
ValueT qualifier (void) const
|
|
{
|
|
static_assert (std::is_pod_v<ValueT>);
|
|
|
|
auto data = acl_get_qualifier (m_native);
|
|
|
|
union {
|
|
u08 raw[sizeof (ValueT)];
|
|
ValueT res;
|
|
};
|
|
|
|
memcpy (raw, data, sizeof (ValueT));
|
|
acl_free (data);
|
|
return res;
|
|
|
|
}
|
|
|
|
class permset permset (void) const;
|
|
|
|
acl_entry_t& native (void) &;
|
|
acl_entry_t const& native (void) const&;
|
|
|
|
private:
|
|
acl_entry_t m_native;
|
|
};
|
|
|
|
|
|
/// A context for a ACL operations.
|
|
class acl {
|
|
public:
|
|
using value_type = entry;
|
|
|
|
explicit acl (int count);
|
|
explicit acl (acl_t &&);
|
|
acl (std::filesystem::path const&, acl_type_t);
|
|
|
|
acl (acl&&);
|
|
acl& operator= (acl&&);
|
|
|
|
acl (acl const&) = delete;
|
|
acl& operator= (acl const&) = delete;
|
|
|
|
~acl ();
|
|
|
|
acl dup (void) const;
|
|
|
|
class iterator {
|
|
public:
|
|
using iterator_category = std::input_iterator_tag;
|
|
using difference_type = int;
|
|
using value_type = entry;
|
|
using pointer = value_type*;
|
|
using reference = value_type&;
|
|
|
|
explicit iterator ();
|
|
explicit iterator (acl const &parent);
|
|
|
|
iterator& operator++ ();
|
|
value_type operator* ();
|
|
|
|
bool operator== (iterator const&) const;
|
|
bool operator!= (iterator const&) const;
|
|
|
|
private:
|
|
void fetch (int pos);
|
|
|
|
acl const *m_parent;
|
|
acl_entry_t m_value;
|
|
};
|
|
|
|
using const_iterator = iterator;
|
|
|
|
//iterator begin (void);
|
|
//iterator end (void);
|
|
|
|
const_iterator begin (void) const;
|
|
const_iterator end (void) const;
|
|
|
|
const_iterator cbegin (void) const;
|
|
const_iterator cend (void) const;
|
|
|
|
int size (void) const;
|
|
|
|
acl_t& native (void)& { return m_native; }
|
|
acl_t const& native (void) const& { return m_native; }
|
|
|
|
private:
|
|
acl_t m_native;
|
|
};
|
|
|
|
std::ostream& operator<< (std::ostream&, acl const&);
|
|
std::ostream& operator<< (std::ostream&, entry const&);
|
|
std::ostream& operator<< (std::ostream&, permset const&);
|
|
}
|