aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2009-01-22 15:06:26 +0000
committerAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2009-01-22 14:50:12 +0000
commit5f20568eeabb55334d461a4e516b4b2396780222 (patch)
tree51bc1df013176abdcc8d686adcbb3b3b6f443ca5
parent66b4acc5c80fb242eac4e5e3358a80614d005865 (diff)
downloadpaludis-5f20568eeabb55334d461a4e516b4b2396780222.tar.gz
paludis-5f20568eeabb55334d461a4e516b4b2396780222.tar.xz
Support account groups too
-rw-r--r--paludis/repositories/accounts/accounts_id.cc160
-rw-r--r--paludis/repositories/accounts/accounts_id.hh14
-rw-r--r--paludis/repositories/accounts/accounts_repository_store.cc69
-rw-r--r--paludis/repositories/accounts/accounts_repository_store.hh12
-rw-r--r--paludis/repositories/accounts/installed_accounts_id.cc84
-rw-r--r--paludis/repositories/accounts/installed_accounts_id.hh15
-rw-r--r--paludis/repositories/accounts/passwd_accounts_handler.cc70
-rw-r--r--paludis/repositories/accounts/passwd_accounts_handler.hh3
8 files changed, 288 insertions, 139 deletions
diff --git a/paludis/repositories/accounts/accounts_id.cc b/paludis/repositories/accounts/accounts_id.cc
index 7d7c9e2..e53a9a3 100644
--- a/paludis/repositories/accounts/accounts_id.cc
+++ b/paludis/repositories/accounts/accounts_id.cc
@@ -40,7 +40,7 @@ using namespace paludis::accounts_repository;
namespace paludis
{
template <>
- struct Implementation<AccountsUserID>
+ struct Implementation<AccountsID>
{
const Environment * const env;
@@ -52,9 +52,12 @@ namespace paludis
const std::tr1::shared_ptr<const LiteralMetadataValueKey<FSEntry> > fs_location_key;
const std::tr1::shared_ptr<const MetadataCollectionKey<Set<std::string> > > from_repositories_key;
+ const bool is_user;
+
mutable Mutex mutex;
mutable bool has_file_keys;
mutable bool has_metadata_keys;
+
mutable std::tr1::shared_ptr<const LiteralMetadataValueKey<std::string> > username_key;
mutable std::tr1::shared_ptr<const LiteralMetadataValueKey<std::string> > gecos_key;
mutable std::tr1::shared_ptr<const LiteralMetadataValueKey<std::string> > preferred_uid_key;
@@ -63,10 +66,13 @@ namespace paludis
mutable std::tr1::shared_ptr<const LiteralMetadataValueKey<std::string> > home_key;
mutable std::tr1::shared_ptr<const LiteralMetadataValueKey<std::string> > shell_key;
+ mutable std::tr1::shared_ptr<const LiteralMetadataValueKey<std::string> > groupname_key;
+ mutable std::tr1::shared_ptr<const LiteralMetadataValueKey<std::string> > preferred_gid_key;
+
Implementation(const Environment * const e,
const QualifiedPackageName & q, const std::tr1::shared_ptr<const Repository> & r,
const std::tr1::shared_ptr<const MetadataCollectionKey<Set<std::string> > > & f,
- const FSEntry & l) :
+ const FSEntry & l, const bool u) :
env(e),
name(q),
version("0"),
@@ -74,6 +80,7 @@ namespace paludis
repository(r),
fs_location_key(new LiteralMetadataValueKey<FSEntry>("location", "Location", mkt_internal, l)),
from_repositories_key(f),
+ is_user(u),
has_file_keys(false),
has_metadata_keys(false)
{
@@ -81,20 +88,21 @@ namespace paludis
};
}
-AccountsUserID::AccountsUserID(const Environment * const e,
+AccountsID::AccountsID(const Environment * const e,
const QualifiedPackageName & q, const std::tr1::shared_ptr<const Repository> & r,
- const std::tr1::shared_ptr<const MetadataCollectionKey<Set<std::string> > > & f, const FSEntry & l) :
- PrivateImplementationPattern<AccountsUserID>(new Implementation<AccountsUserID>(e, q, r, f, l)),
- _imp(PrivateImplementationPattern<AccountsUserID>::_imp)
+ const std::tr1::shared_ptr<const MetadataCollectionKey<Set<std::string> > > & f, const FSEntry & l,
+ const bool u) :
+ PrivateImplementationPattern<AccountsID>(new Implementation<AccountsID>(e, q, r, f, l, u)),
+ _imp(PrivateImplementationPattern<AccountsID>::_imp)
{
}
-AccountsUserID::~AccountsUserID()
+AccountsID::~AccountsID()
{
}
void
-AccountsUserID::_add_metadata_keys() const
+AccountsID::_add_metadata_keys() const
{
Lock lock(_imp->mutex);
@@ -119,11 +127,16 @@ AccountsUserID::_add_metadata_keys() const
if (_imp->home_key)
add_metadata_key(_imp->home_key);
+ if (_imp->groupname_key)
+ add_metadata_key(_imp->groupname_key);
+ if (_imp->preferred_gid_key)
+ add_metadata_key(_imp->preferred_gid_key);
+
_imp->has_metadata_keys = true;
}
void
-AccountsUserID::_need_file_keys() const
+AccountsID::_need_file_keys() const
{
if (_imp->has_file_keys)
return;
@@ -135,42 +148,54 @@ AccountsUserID::_need_file_keys() const
/* also need to change the handlers if any of the raw names are changed */
- _imp->username_key.reset(new LiteralMetadataValueKey<std::string>("username", "Username",
- mkt_significant, stringify(name().package())));
+ if (_imp->is_user)
+ {
+ _imp->username_key.reset(new LiteralMetadataValueKey<std::string>("username", "Username",
+ mkt_significant, stringify(name().package())));
- if (! k.get("gecos").empty())
- _imp->gecos_key.reset(new LiteralMetadataValueKey<std::string>("gecos", "Description",
- mkt_significant, k.get("gecos")));
+ if (! k.get("gecos").empty())
+ _imp->gecos_key.reset(new LiteralMetadataValueKey<std::string>("gecos", "Description",
+ mkt_significant, k.get("gecos")));
- if (! k.get("preferred_uid").empty())
- _imp->preferred_uid_key.reset(new LiteralMetadataValueKey<std::string>("preferred_uid", "Preferred UID",
- mkt_normal, k.get("preferred_uid")));
+ if (! k.get("preferred_uid").empty())
+ _imp->preferred_uid_key.reset(new LiteralMetadataValueKey<std::string>("preferred_uid", "Preferred UID",
+ mkt_normal, k.get("preferred_uid")));
- if (! k.get("shell").empty())
- _imp->shell_key.reset(new LiteralMetadataValueKey<std::string>("shell", "Shell",
- mkt_normal, k.get("shell")));
+ if (! k.get("shell").empty())
+ _imp->shell_key.reset(new LiteralMetadataValueKey<std::string>("shell", "Shell",
+ mkt_normal, k.get("shell")));
- if (! k.get("home").empty())
- _imp->home_key.reset(new LiteralMetadataValueKey<std::string>("home", "Home Directory",
- mkt_normal, k.get("home")));
+ if (! k.get("home").empty())
+ _imp->home_key.reset(new LiteralMetadataValueKey<std::string>("home", "Home Directory",
+ mkt_normal, k.get("home")));
- if (! k.get("default_group").empty())
- _imp->default_group_key.reset(new LiteralMetadataValueKey<std::string>("default_group", "Default Group",
- mkt_normal, k.get("default_group")));
+ if (! k.get("default_group").empty())
+ _imp->default_group_key.reset(new LiteralMetadataValueKey<std::string>("default_group", "Default Group",
+ mkt_normal, k.get("default_group")));
- if (! k.get("extra_groups").empty())
+ if (! k.get("extra_groups").empty())
+ {
+ std::tr1::shared_ptr<Set<std::string> > groups_s(new Set<std::string>);
+ tokenise_whitespace(k.get("extra_groups"), groups_s->inserter());
+ _imp->extra_groups_key.reset(new LiteralMetadataStringSetKey("extra_groups", "Extra Groups",
+ mkt_normal, groups_s));
+ }
+ }
+ else
{
- std::tr1::shared_ptr<Set<std::string> > groups_s(new Set<std::string>);
- tokenise_whitespace(k.get("extra_groups"), groups_s->inserter());
- _imp->extra_groups_key.reset(new LiteralMetadataStringSetKey("extra_groups", "Extra Groups",
- mkt_normal, groups_s));
+ _imp->groupname_key.reset(new LiteralMetadataValueKey<std::string>("groupname", "Groupname",
+ mkt_significant, stringify(name().package())));
+
+ if (! k.get("preferred_gid").empty())
+ _imp->preferred_gid_key.reset(new LiteralMetadataValueKey<std::string>("preferred_gid", "Preferred GID",
+ mkt_normal, k.get("preferred_gid")));
}
_imp->has_file_keys = true;
}
void
-AccountsUserID::need_keys_added() const
+AccountsID::need_keys_added() const
{
if (! _imp->has_file_keys)
_need_file_keys();
@@ -180,7 +205,7 @@ AccountsUserID::need_keys_added() const
}
void
-AccountsUserID::clear_metadata_keys() const
+AccountsID::clear_metadata_keys() const
{
Lock lock(_imp->mutex);
_imp->has_metadata_keys = false;
@@ -188,36 +213,36 @@ AccountsUserID::clear_metadata_keys() const
}
void
-AccountsUserID::need_masks_added() const
+AccountsID::need_masks_added() const
{
}
const QualifiedPackageName
-AccountsUserID::name() const
+AccountsID::name() const
{
return _imp->name;
}
const VersionSpec
-AccountsUserID::version() const
+AccountsID::version() const
{
return _imp->version;
}
const SlotName
-AccountsUserID::slot() const
+AccountsID::slot() const
{
return _imp->slot;
}
const std::tr1::shared_ptr<const Repository>
-AccountsUserID::repository() const
+AccountsID::repository() const
{
return _imp->repository;
}
const std::string
-AccountsUserID::canonical_form(const PackageIDCanonicalForm f) const
+AccountsID::canonical_form(const PackageIDCanonicalForm f) const
{
switch (f)
{
@@ -238,128 +263,133 @@ AccountsUserID::canonical_form(const PackageIDCanonicalForm f) const
}
const std::tr1::shared_ptr<const MetadataValueKey<std::tr1::shared_ptr<const PackageID> > >
-AccountsUserID::virtual_for_key() const
+AccountsID::virtual_for_key() const
{
return make_null_shared_ptr();
}
const std::tr1::shared_ptr<const MetadataCollectionKey<KeywordNameSet> >
-AccountsUserID::keywords_key() const
+AccountsID::keywords_key() const
{
return make_null_shared_ptr();
}
const std::tr1::shared_ptr<const MetadataSpecTreeKey<ProvideSpecTree> >
-AccountsUserID::provide_key() const
+AccountsID::provide_key() const
{
return make_null_shared_ptr();
}
const std::tr1::shared_ptr<const MetadataCollectionKey<PackageIDSequence> >
-AccountsUserID::contains_key() const
+AccountsID::contains_key() const
{
return make_null_shared_ptr();
}
const std::tr1::shared_ptr<const MetadataValueKey<std::tr1::shared_ptr<const PackageID> > >
-AccountsUserID::contained_in_key() const
+AccountsID::contained_in_key() const
{
return make_null_shared_ptr();
}
const std::tr1::shared_ptr<const MetadataSpecTreeKey<DependencySpecTree> >
-AccountsUserID::build_dependencies_key() const
+AccountsID::build_dependencies_key() const
{
return make_null_shared_ptr();
}
const std::tr1::shared_ptr<const MetadataSpecTreeKey<DependencySpecTree> >
-AccountsUserID::run_dependencies_key() const
+AccountsID::run_dependencies_key() const
{
return make_null_shared_ptr();
}
const std::tr1::shared_ptr<const MetadataSpecTreeKey<DependencySpecTree> >
-AccountsUserID::post_dependencies_key() const
+AccountsID::post_dependencies_key() const
{
return make_null_shared_ptr();
}
const std::tr1::shared_ptr<const MetadataSpecTreeKey<DependencySpecTree> >
-AccountsUserID::suggested_dependencies_key() const
+AccountsID::suggested_dependencies_key() const
{
return make_null_shared_ptr();
}
const std::tr1::shared_ptr<const MetadataSpecTreeKey<FetchableURISpecTree> >
-AccountsUserID::fetches_key() const
+AccountsID::fetches_key() const
{
return make_null_shared_ptr();
}
const std::tr1::shared_ptr<const MetadataSpecTreeKey<SimpleURISpecTree> >
-AccountsUserID::homepage_key() const
+AccountsID::homepage_key() const
{
return make_null_shared_ptr();
}
const std::tr1::shared_ptr<const MetadataValueKey<std::string> >
-AccountsUserID::short_description_key() const
+AccountsID::short_description_key() const
{
- _need_file_keys();
- return _imp->gecos_key;
+ if (_imp->is_user)
+ {
+ _need_file_keys();
+ return _imp->gecos_key;
+ }
+ else
+ return _imp->groupname_key;
}
const std::tr1::shared_ptr<const MetadataValueKey<std::string> >
-AccountsUserID::long_description_key() const
+AccountsID::long_description_key() const
{
return make_null_shared_ptr();
}
const std::tr1::shared_ptr<const MetadataValueKey<std::tr1::shared_ptr<const Contents> > >
-AccountsUserID::contents_key() const
+AccountsID::contents_key() const
{
return make_null_shared_ptr();
}
const std::tr1::shared_ptr<const MetadataTimeKey>
-AccountsUserID::installed_time_key() const
+AccountsID::installed_time_key() const
{
return make_null_shared_ptr();
}
const std::tr1::shared_ptr<const MetadataCollectionKey<Set<std::string> > >
-AccountsUserID::from_repositories_key() const
+AccountsID::from_repositories_key() const
{
return _imp->from_repositories_key;
}
const std::tr1::shared_ptr<const MetadataValueKey<FSEntry> >
-AccountsUserID::fs_location_key() const
+AccountsID::fs_location_key() const
{
return _imp->fs_location_key;
}
const std::tr1::shared_ptr<const MetadataValueKey<bool> >
-AccountsUserID::transient_key() const
+AccountsID::transient_key() const
{
return make_null_shared_ptr();
}
const std::tr1::shared_ptr<const MetadataValueKey<std::tr1::shared_ptr<const Choices> > >
-AccountsUserID::choices_key() const
+AccountsID::choices_key() const
{
return make_null_shared_ptr();
}
std::tr1::shared_ptr<const Set<std::string> >
-AccountsUserID::breaks_portage() const
+AccountsID::breaks_portage() const
{
return make_shared_ptr(new Set<std::string>);
}
bool
-AccountsUserID::arbitrary_less_than_comparison(const PackageID & other) const
+AccountsID::arbitrary_less_than_comparison(const PackageID & other) const
{
if (slot() < other.slot())
return true;
@@ -368,19 +398,19 @@ AccountsUserID::arbitrary_less_than_comparison(const PackageID & other) const
}
std::size_t
-AccountsUserID::extra_hash_value() const
+AccountsID::extra_hash_value() const
{
return Hash<SlotName>()(slot());
}
bool
-AccountsUserID::supports_action(const SupportsActionTestBase & test) const
+AccountsID::supports_action(const SupportsActionTestBase & test) const
{
return simple_visitor_cast<const SupportsActionTest<InstallAction> >(test);
}
void
-AccountsUserID::perform_action(Action & action) const
+AccountsID::perform_action(Action & action) const
{
const InstallAction * const install_action(simple_visitor_cast<const InstallAction>(action));
if (! install_action)
diff --git a/paludis/repositories/accounts/accounts_id.hh b/paludis/repositories/accounts/accounts_id.hh
index a3fc52c..557294c 100644
--- a/paludis/repositories/accounts/accounts_id.hh
+++ b/paludis/repositories/accounts/accounts_id.hh
@@ -29,13 +29,13 @@ namespace paludis
{
class AccountsRepository;
- class AccountsUserID :
+ class AccountsID :
public PackageID,
- private PrivateImplementationPattern<AccountsUserID>,
- public std::tr1::enable_shared_from_this<AccountsUserID>
+ private PrivateImplementationPattern<AccountsID>,
+ public std::tr1::enable_shared_from_this<AccountsID>
{
private:
- PrivateImplementationPattern<AccountsUserID>::ImpPtr & _imp;
+ PrivateImplementationPattern<AccountsID>::ImpPtr & _imp;
void _add_metadata_keys() const;
void _need_file_keys() const;
@@ -46,11 +46,11 @@ namespace paludis
virtual void need_masks_added() const;
public:
- AccountsUserID(const Environment * const,
+ AccountsID(const Environment * const,
const QualifiedPackageName &, const std::tr1::shared_ptr<const Repository> &,
const std::tr1::shared_ptr<const MetadataCollectionKey<Set<std::string> > > &,
- const FSEntry &);
- ~AccountsUserID();
+ const FSEntry &, const bool is_user);
+ ~AccountsID();
virtual const std::string canonical_form(const PackageIDCanonicalForm) const;
diff --git a/paludis/repositories/accounts/accounts_repository_store.cc b/paludis/repositories/accounts/accounts_repository_store.cc
index fb98ac5..6f34a97 100644
--- a/paludis/repositories/accounts/accounts_repository_store.cc
+++ b/paludis/repositories/accounts/accounts_repository_store.cc
@@ -45,6 +45,7 @@
#include <set>
#include <sys/types.h>
#include <pwd.h>
+#include <grp.h>
using namespace paludis;
using namespace paludis::accounts_repository;
@@ -153,7 +154,7 @@ AccountsRepositoryStore::_load_one(
"Repository " << repo->name() << " has accounts_repository_data_location " << dir << ", but no users subdirectory";
if ((dir / "groups").is_directory_or_symlink_to_directory())
- _load_one_groups(repo, dir / "groups");
+ _load_one_groups(repo, from_repo, dir / "groups");
else
Log::get_instance()->message("accounts.no_groups", ll_debug, lc_context) <<
"Repository " << repo->name() << " has accounts_repository_data_location " << dir << ", but no groups subdirectory";
@@ -175,17 +176,6 @@ AccountsRepositoryStore::_load_one_users(
}
void
-AccountsRepositoryStore::_load_one_groups(const std::tr1::shared_ptr<const Repository> & repo, const FSEntry & dir)
-{
- for (DirIterator d(dir, DirIteratorOptions()), d_end ; d != d_end ; ++d)
- if (is_file_with_extension(*d, ".conf", IsFileWithOptions()))
- _load_one_group(repo, *d);
- else
- Log::get_instance()->message("accounts.unknown_file", ll_debug, lc_context) <<
- "Don't know what to do with '" << *d << "'";
-}
-
-void
AccountsRepositoryStore::_load_one_user(
const std::tr1::shared_ptr<const Repository> & repo,
const std::tr1::shared_ptr<const MetadataCollectionKey<Set<std::string> > > & from_repo,
@@ -220,14 +210,63 @@ AccountsRepositoryStore::_load_one_user(
q->second.reset(new PackageIDSequence);
if (_imp->installed)
- q->second->push_back(make_shared_ptr(new InstalledAccountsUserID(_imp->env, qpn, repo)));
+ q->second->push_back(make_shared_ptr(new InstalledAccountsID(_imp->env, qpn, repo, true)));
else
- q->second->push_back(make_shared_ptr(new AccountsUserID(_imp->env, qpn, repo, from_repo, filename)));
+ q->second->push_back(make_shared_ptr(new AccountsID(_imp->env, qpn, repo, from_repo, filename, true)));
}
void
-AccountsRepositoryStore::_load_one_group(const std::tr1::shared_ptr<const Repository> &, const FSEntry &)
+AccountsRepositoryStore::_load_one_groups(
+ const std::tr1::shared_ptr<const Repository> & repo,
+ const std::tr1::shared_ptr<const MetadataCollectionKey<Set<std::string> > > & from_repo,
+ const FSEntry & dir)
{
+ for (DirIterator d(dir, DirIteratorOptions()), d_end ; d != d_end ; ++d)
+ if (is_file_with_extension(*d, ".conf", IsFileWithOptions()))
+ _load_one_group(repo, from_repo, *d);
+ else
+ Log::get_instance()->message("accounts.unknown_file", ll_debug, lc_context) <<
+ "Don't know what to do with '" << *d << "'";
+}
+
+void
+AccountsRepositoryStore::_load_one_group(
+ const std::tr1::shared_ptr<const Repository> & repo,
+ const std::tr1::shared_ptr<const MetadataCollectionKey<Set<std::string> > > & from_repo,
+ const FSEntry & filename)
+{
+ CategoryNamePart cat("group");
+ PackageNamePart pkg(strip_trailing_string(filename.basename(), ".conf"));
+ QualifiedPackageName qpn(cat + pkg);
+ std::string groupname(stringify(pkg));
+
+ if (_imp->installed)
+ {
+ if (! getgrnam(groupname.c_str()))
+ return;
+ }
+ else
+ {
+ if (getgrnam(groupname.c_str()))
+ return;
+ }
+
+ PackageNames::iterator p(_imp->package_names.find(cat));
+ if (p == _imp->package_names.end())
+ p = _imp->package_names.insert(std::make_pair(cat, make_shared_ptr(new QualifiedPackageNameSet))).first;
+
+ p->second->insert(qpn);
+
+ IDs::iterator q(_imp->ids.find(qpn));
+ if (q == _imp->ids.end())
+ q = _imp->ids.insert(std::make_pair(qpn, make_shared_ptr(new PackageIDSequence))).first;
+ else
+ q->second.reset(new PackageIDSequence);
+
+ if (_imp->installed)
+ q->second->push_back(make_shared_ptr(new InstalledAccountsID(_imp->env, qpn, repo, false)));
+ else
+ q->second->push_back(make_shared_ptr(new AccountsID(_imp->env, qpn, repo, from_repo, filename, false)));
}
bool
diff --git a/paludis/repositories/accounts/accounts_repository_store.hh b/paludis/repositories/accounts/accounts_repository_store.hh
index d7f222b..45de761 100644
--- a/paludis/repositories/accounts/accounts_repository_store.hh
+++ b/paludis/repositories/accounts/accounts_repository_store.hh
@@ -51,14 +51,20 @@ namespace paludis
const std::tr1::shared_ptr<const MetadataCollectionKey<Set<std::string> > > & from_repo,
const FSEntry & dir);
- void _load_one_groups(const std::tr1::shared_ptr<const Repository> & repo, const FSEntry & dir);
-
void _load_one_user(
const std::tr1::shared_ptr<const Repository> & repo,
const std::tr1::shared_ptr<const MetadataCollectionKey<Set<std::string> > > & from_repo,
const FSEntry & file);
- void _load_one_group(const std::tr1::shared_ptr<const Repository> & repo, const FSEntry & file);
+ void _load_one_groups(
+ const std::tr1::shared_ptr<const Repository> & repo,
+ const std::tr1::shared_ptr<const MetadataCollectionKey<Set<std::string> > > & from_repo,
+ const FSEntry & dir);
+
+ void _load_one_group(
+ const std::tr1::shared_ptr<const Repository> & repo,
+ const std::tr1::shared_ptr<const MetadataCollectionKey<Set<std::string> > > & from_repo,
+ const FSEntry & file);
public:
AccountsRepositoryStore(
diff --git a/paludis/repositories/accounts/installed_accounts_id.cc b/paludis/repositories/accounts/installed_accounts_id.cc
index 1750255..67eaa15 100644
--- a/paludis/repositories/accounts/installed_accounts_id.cc
+++ b/paludis/repositories/accounts/installed_accounts_id.cc
@@ -39,7 +39,7 @@ using namespace paludis::accounts_repository;
namespace paludis
{
template <>
- struct Implementation<InstalledAccountsUserID>
+ struct Implementation<InstalledAccountsID>
{
const Environment * const env;
@@ -50,72 +50,76 @@ namespace paludis
const std::tr1::shared_ptr<const LiteralMetadataValueKey<bool> > transient_key;
+ const bool is_user;
+
Implementation(const Environment * const e,
- const QualifiedPackageName & q, const std::tr1::shared_ptr<const Repository> & r) :
+ const QualifiedPackageName & q, const std::tr1::shared_ptr<const Repository> & r,
+ const bool u) :
env(e),
name(q),
version("0"),
slot("0"),
repository(r),
- transient_key(new LiteralMetadataValueKey<bool>("transient", "Transient", mkt_internal, true))
+ transient_key(new LiteralMetadataValueKey<bool>("transient", "Transient", mkt_internal, true)),
+ is_user(u)
{
}
};
}
-InstalledAccountsUserID::InstalledAccountsUserID(const Environment * const e,
- const QualifiedPackageName & q, const std::tr1::shared_ptr<const Repository> & r) :
- PrivateImplementationPattern<InstalledAccountsUserID>(new Implementation<InstalledAccountsUserID>(e, q, r)),
- _imp(PrivateImplementationPattern<InstalledAccountsUserID>::_imp)
+InstalledAccountsID::InstalledAccountsID(const Environment * const e,
+ const QualifiedPackageName & q, const std::tr1::shared_ptr<const Repository> & r, const bool u) :
+ PrivateImplementationPattern<InstalledAccountsID>(new Implementation<InstalledAccountsID>(e, q, r, u)),
+ _imp(PrivateImplementationPattern<InstalledAccountsID>::_imp)
{
add_metadata_key(_imp->transient_key);
}
-InstalledAccountsUserID::~InstalledAccountsUserID()
+InstalledAccountsID::~InstalledAccountsID()
{
}
void
-InstalledAccountsUserID::need_keys_added() const
+InstalledAccountsID::need_keys_added() const
{
}
void
-InstalledAccountsUserID::clear_metadata_keys() const
+InstalledAccountsID::clear_metadata_keys() const
{
}
void
-InstalledAccountsUserID::need_masks_added() const
+InstalledAccountsID::need_masks_added() const
{
}
const QualifiedPackageName
-InstalledAccountsUserID::name() const
+InstalledAccountsID::name() const
{
return _imp->name;
}
const VersionSpec
-InstalledAccountsUserID::version() const
+InstalledAccountsID::version() const
{
return _imp->version;
}
const SlotName
-InstalledAccountsUserID::slot() const
+InstalledAccountsID::slot() const
{
return _imp->slot;
}
const std::tr1::shared_ptr<const Repository>
-InstalledAccountsUserID::repository() const
+InstalledAccountsID::repository() const
{
return _imp->repository;
}
const std::string
-InstalledAccountsUserID::canonical_form(const PackageIDCanonicalForm f) const
+InstalledAccountsID::canonical_form(const PackageIDCanonicalForm f) const
{
switch (f)
{
@@ -136,127 +140,127 @@ InstalledAccountsUserID::canonical_form(const PackageIDCanonicalForm f) const
}
const std::tr1::shared_ptr<const MetadataValueKey<std::tr1::shared_ptr<const PackageID> > >
-InstalledAccountsUserID::virtual_for_key() const
+InstalledAccountsID::virtual_for_key() const
{
return make_null_shared_ptr();
}
const std::tr1::shared_ptr<const MetadataCollectionKey<KeywordNameSet> >
-InstalledAccountsUserID::keywords_key() const
+InstalledAccountsID::keywords_key() const
{
return make_null_shared_ptr();
}
const std::tr1::shared_ptr<const MetadataSpecTreeKey<ProvideSpecTree> >
-InstalledAccountsUserID::provide_key() const
+InstalledAccountsID::provide_key() const
{
return make_null_shared_ptr();
}
const std::tr1::shared_ptr<const MetadataCollectionKey<PackageIDSequence> >
-InstalledAccountsUserID::contains_key() const
+InstalledAccountsID::contains_key() const
{
return make_null_shared_ptr();
}
const std::tr1::shared_ptr<const MetadataValueKey<std::tr1::shared_ptr<const PackageID> > >
-InstalledAccountsUserID::contained_in_key() const
+InstalledAccountsID::contained_in_key() const
{
return make_null_shared_ptr();
}
const std::tr1::shared_ptr<const MetadataSpecTreeKey<DependencySpecTree> >
-InstalledAccountsUserID::build_dependencies_key() const
+InstalledAccountsID::build_dependencies_key() const
{
return make_null_shared_ptr();
}
const std::tr1::shared_ptr<const MetadataSpecTreeKey<DependencySpecTree> >
-InstalledAccountsUserID::run_dependencies_key() const
+InstalledAccountsID::run_dependencies_key() const
{
return make_null_shared_ptr();
}
const std::tr1::shared_ptr<const MetadataSpecTreeKey<DependencySpecTree> >
-InstalledAccountsUserID::post_dependencies_key() const
+InstalledAccountsID::post_dependencies_key() const
{
return make_null_shared_ptr();
}
const std::tr1::shared_ptr<const MetadataSpecTreeKey<DependencySpecTree> >
-InstalledAccountsUserID::suggested_dependencies_key() const
+InstalledAccountsID::suggested_dependencies_key() const
{
return make_null_shared_ptr();
}
const std::tr1::shared_ptr<const MetadataSpecTreeKey<FetchableURISpecTree> >
-InstalledAccountsUserID::fetches_key() const
+InstalledAccountsID::fetches_key() const
{
return make_null_shared_ptr();
}
const std::tr1::shared_ptr<const MetadataSpecTreeKey<SimpleURISpecTree> >
-InstalledAccountsUserID::homepage_key() const
+InstalledAccountsID::homepage_key() const
{
return make_null_shared_ptr();
}
const std::tr1::shared_ptr<const MetadataValueKey<std::string> >
-InstalledAccountsUserID::short_description_key() const
+InstalledAccountsID::short_description_key() const
{
return make_null_shared_ptr();
}
const std::tr1::shared_ptr<const MetadataValueKey<std::string> >
-InstalledAccountsUserID::long_description_key() const
+InstalledAccountsID::long_description_key() const
{
return make_null_shared_ptr();
}
const std::tr1::shared_ptr<const MetadataValueKey<std::tr1::shared_ptr<const Contents> > >
-InstalledAccountsUserID::contents_key() const
+InstalledAccountsID::contents_key() const
{
return make_null_shared_ptr();
}
const std::tr1::shared_ptr<const MetadataTimeKey>
-InstalledAccountsUserID::installed_time_key() const
+InstalledAccountsID::installed_time_key() const
{
return make_null_shared_ptr();
}
const std::tr1::shared_ptr<const MetadataCollectionKey<Set<std::string> > >
-InstalledAccountsUserID::from_repositories_key() const
+InstalledAccountsID::from_repositories_key() const
{
return make_null_shared_ptr();
}
const std::tr1::shared_ptr<const MetadataValueKey<FSEntry> >
-InstalledAccountsUserID::fs_location_key() const
+InstalledAccountsID::fs_location_key() const
{
return make_null_shared_ptr();
}
const std::tr1::shared_ptr<const MetadataValueKey<bool> >
-InstalledAccountsUserID::transient_key() const
+InstalledAccountsID::transient_key() const
{
return _imp->transient_key;
}
const std::tr1::shared_ptr<const MetadataValueKey<std::tr1::shared_ptr<const Choices> > >
-InstalledAccountsUserID::choices_key() const
+InstalledAccountsID::choices_key() const
{
return make_null_shared_ptr();
}
std::tr1::shared_ptr<const Set<std::string> >
-InstalledAccountsUserID::breaks_portage() const
+InstalledAccountsID::breaks_portage() const
{
return make_shared_ptr(new Set<std::string>);
}
bool
-InstalledAccountsUserID::arbitrary_less_than_comparison(const PackageID & other) const
+InstalledAccountsID::arbitrary_less_than_comparison(const PackageID & other) const
{
if (slot() < other.slot())
return true;
@@ -265,19 +269,19 @@ InstalledAccountsUserID::arbitrary_less_than_comparison(const PackageID & other)
}
std::size_t
-InstalledAccountsUserID::extra_hash_value() const
+InstalledAccountsID::extra_hash_value() const
{
return Hash<SlotName>()(slot());
}
bool
-InstalledAccountsUserID::supports_action(const SupportsActionTestBase & test) const
+InstalledAccountsID::supports_action(const SupportsActionTestBase & test) const
{
return simple_visitor_cast<const SupportsActionTest<InstalledAction> >(test);
}
void
-InstalledAccountsUserID::perform_action(Action & action) const
+InstalledAccountsID::perform_action(Action & action) const
{
throw UnsupportedActionError(*this, action);
}
diff --git a/paludis/repositories/accounts/installed_accounts_id.hh b/paludis/repositories/accounts/installed_accounts_id.hh
index 9625d94..436dc2f 100644
--- a/paludis/repositories/accounts/installed_accounts_id.hh
+++ b/paludis/repositories/accounts/installed_accounts_id.hh
@@ -29,13 +29,13 @@ namespace paludis
{
class AccountsRepository;
- class InstalledAccountsUserID :
+ class InstalledAccountsID :
public PackageID,
- private PrivateImplementationPattern<InstalledAccountsUserID>,
- public std::tr1::enable_shared_from_this<InstalledAccountsUserID>
+ private PrivateImplementationPattern<InstalledAccountsID>,
+ public std::tr1::enable_shared_from_this<InstalledAccountsID>
{
private:
- PrivateImplementationPattern<InstalledAccountsUserID>::ImpPtr & _imp;
+ PrivateImplementationPattern<InstalledAccountsID>::ImpPtr & _imp;
void _add_metadata_keys() const;
@@ -45,9 +45,10 @@ namespace paludis
virtual void need_masks_added() const;
public:
- InstalledAccountsUserID(const Environment * const,
- const QualifiedPackageName &, const std::tr1::shared_ptr<const Repository> &);
- ~InstalledAccountsUserID();
+ InstalledAccountsID(const Environment * const,
+ const QualifiedPackageName &, const std::tr1::shared_ptr<const Repository> &,
+ const bool is_user);
+ ~InstalledAccountsID();
virtual const std::string canonical_form(const PackageIDCanonicalForm) const;
diff --git a/paludis/repositories/accounts/passwd_accounts_handler.cc b/paludis/repositories/accounts/passwd_accounts_handler.cc
index f3d4d09..4415272 100644
--- a/paludis/repositories/accounts/passwd_accounts_handler.cc
+++ b/paludis/repositories/accounts/passwd_accounts_handler.cc
@@ -32,6 +32,7 @@
#include <iostream>
#include <sys/types.h>
#include <pwd.h>
+#include <grp.h>
using namespace paludis;
using namespace paludis::accounts_repository;
@@ -43,6 +44,17 @@ PasswdAccountsHandler::merge(const MergeParams & params)
std::cout << ">>> Installing " << *params.package_id() << " using passwd handler" << std::endl;
+ if (params.package_id()->end_metadata() != params.package_id()->find_metadata("groupname"))
+ merge_group(params);
+ else
+ merge_user(params);
+
+ std::cout << ">>> Finished installing " << *params.package_id() << std::endl;
+}
+
+void
+PasswdAccountsHandler::merge_user(const MergeParams & params)
+{
std::string username;
do
{
@@ -187,14 +199,68 @@ PasswdAccountsHandler::merge(const MergeParams & params)
home = " -d '" + home + "'";
} while (false);
- Command cmd("useradd " + username + gecos + primary_group + extra_groups + shell + home);
+ Command cmd("useradd -r " + username + preferred_uid + gecos + primary_group + extra_groups + shell + home);
cmd.with_echo_to_stderr();
int exit_status(run_command(cmd));
if (0 != exit_status)
throw InstallActionError("Install of '" + stringify(*params.package_id()) + "' failed because useradd returned "
+ stringify(exit_status));
+}
- std::cout << ">>> Finished installing " << *params.package_id() << std::endl;
+void
+PasswdAccountsHandler::merge_group(const MergeParams & params)
+{
+ std::string groupname;
+ do
+ {
+ PackageID::MetadataConstIterator m(params.package_id()->find_metadata("groupname"));
+ if (params.package_id()->end_metadata() == m)
+ throw InstallActionError("Key 'groupname' for '" + stringify(*params.package_id()) + "' does not exist");
+
+ const MetadataValueKey<std::string> * k(simple_visitor_cast<const MetadataValueKey<std::string> >(**m));
+ if (! k)
+ throw InstallActionError("Key 'groupname' for '" + stringify(*params.package_id()) + "' is not a string key");
+
+ groupname = k->value();
+
+ if (0 != getgrnam(groupname.c_str()))
+ throw InstallActionError("Group '" + groupname + "' already exists");
+ } while (false);
+
+ std::string preferred_gid;
+ do
+ {
+ PackageID::MetadataConstIterator m(params.package_id()->find_metadata("preferred_gid"));
+ if (params.package_id()->end_metadata() == m)
+ break;
+
+ const MetadataValueKey<std::string> * k(simple_visitor_cast<const MetadataValueKey<std::string> >(**m));
+ if (! k)
+ throw InstallActionError("Key 'preferred_gid' for '" + stringify(*params.package_id()) + "' is not a string key");
+
+ preferred_gid = k->value();
+
+ if (std::string::npos != preferred_gid.find_first_not_of("0123456789"))
+ throw InstallActionError("Value for key 'preferred_gid' for '" + stringify(*params.package_id()) + "' must be a number");
+
+ uid_t gid(destringify<uid_t>(preferred_gid));
+ if (getgrgid(gid))
+ {
+ std::cout << ">>> Preferred GID " << gid << " already in use, not specifying an ID" << std::endl;
+ preferred_gid = "";
+ }
+
+ if (! preferred_gid.empty())
+ preferred_gid = " -g '" + preferred_gid + "'";
+ } while (false);
+
+ Command cmd("groupadd -r " + groupname + preferred_gid);
+ cmd.with_echo_to_stderr();
+ int exit_status(run_command(cmd));
+
+ if (0 != exit_status)
+ throw InstallActionError("Install of '" + stringify(*params.package_id()) + "' failed because groupadd returned "
+ + stringify(exit_status));
}
diff --git a/paludis/repositories/accounts/passwd_accounts_handler.hh b/paludis/repositories/accounts/passwd_accounts_handler.hh
index 4ce9a2b..7da0cf9 100644
--- a/paludis/repositories/accounts/passwd_accounts_handler.hh
+++ b/paludis/repositories/accounts/passwd_accounts_handler.hh
@@ -31,6 +31,9 @@ namespace paludis
{
public:
virtual void merge(const MergeParams &);
+
+ void merge_user(const MergeParams &);
+ void merge_group(const MergeParams &);
};
}
}