#include "pch.hpp" #include "entCache.h" #include #include "lockHelpers.h" #include #include template EntCache::EntCache() : fillTime(0) { } template EntCache::~EntCache() { } template const typename EntCache::id_t & EntCache::getID(const EntCache::name_t & u) const { return getEntry(u)->id; } template const typename EntCache::name_t & EntCache::getName(const EntCache::id_t & u) const { return getEntry(u)->name; } template template typename EntCache::entry_ptr EntCache::getEntry(const key_t & key) const { typename EntCache::entry_ptr ent; if (fillTime + 60 > time(NULL)) { ent = getEntryNoFill(key); } if (!ent) { fillCache(); ent = getEntryNoFill(key); } if (!ent) { throw NetFS::SystemError(EPERM); } return ent; } template template typename EntCache::entry_ptr EntCache::getEntryNoFill(const key_t & key) const { SharedLock(lock); auto & collection = idcache.template get(); auto i = collection.find(key); if (i != collection.end()) { return *i; } return NULL; } User::User(uid_t u, const std::string & n, gid_t g) : id(u), name(n), group(g) { } const int BUFLEN = 8196; template<> void EntCache::fillCache() const { Lock(lock); setpwent(); idcache.clear(); char buf[BUFLEN]; struct passwd pwbuf, * pwp; while (getpwent_r(&pwbuf, buf, BUFLEN, &pwp) == 0) { idcache.insert(new User(pwp->pw_uid, pwp->pw_name, pwp->pw_gid)); } endpwent(); time(&fillTime); } Group::Group(gid_t g, const std::string & n) : id(g), name(n) { } template<> void EntCache::fillCache() const { Lock(lock); setgrent(); char buf[BUFLEN]; idcache.clear(); struct group grpbuf, * grp; while (getgrent_r(&grpbuf, buf, BUFLEN, &grp) == 0) { auto g = new Group(grp->gr_gid, grp->gr_name); for (auto member = grp->gr_mem; *member; member++) { try { g->members.insert(EntCache::instance.getID(*member)); } catch (const NetFS::SystemError &) { } } idcache.insert(g); } endgrent(); time(&fillTime); } bool Group::hasMember(uid_t u) const { return (members.find(u) != members.end()); } template const EntCache EntCache::instance; template class EntCache; template class EntCache;