diff options
Diffstat (limited to 'src/repo.cpp')
-rw-r--r-- | src/repo.cpp | 174 |
1 files changed, 174 insertions, 0 deletions
diff --git a/src/repo.cpp b/src/repo.cpp new file mode 100644 index 0000000..299f2ce --- /dev/null +++ b/src/repo.cpp @@ -0,0 +1,174 @@ +#include <Ice/ObjectAdapter.h> +#include <sys/stat.h> +#include "repo.h" +#include "blob.h" +#include "dir.h" + +GitFS::Repo::Repo() : + repo(Git::RepositoryOpenBare("/usr/portage/.git")), + commit(Git::CommitLookup(repo, Git::OidParse("97a435f30472eb941f96234d274b3aeb492e2793"))), + tree(Git::TreeLookup(repo, *git_commit_tree_id(commit.get()))) +{ +} + +void +GitFS::Repo::disconnect(const ::Ice::Current& current) +{ + current.adapter->remove(current.id); +} + + +NetFS::DirectoryPrxPtr +GitFS::Repo::opendir(ReqEnv, ::std::string path, const ::Ice::Current& ice) +{ + return Ice::uncheckedCast<NetFS::DirectoryV2Prx>(ice.adapter->addWithUUID( + std::make_shared<Directory>(tree, path))); +} + + +NetFS::VFS +GitFS::Repo::statfs(ReqEnv, ::std::string, const ::Ice::Current&) +{ + return {}; +} + + +int +GitFS::Repo::access(ReqEnv, ::std::string path, int mode, const ::Ice::Current&) +{ + if (mode & W_OK) return EACCES; + if (path.empty()) return EINVAL; + if (path == "/") return 0; + + try { + auto e = Git::TreeEntryByPath(tree, path); + const auto emode = git_tree_entry_filemode(e.get()); + + if (S_ISDIR(emode)) return 0; + if (mode & R_OK && !(S_IRUSR & emode)) return EACCES; + if (mode & X_OK && !(S_IXUSR & emode)) return EACCES; + + return 0; + } + catch (const Git::Error & e) { + if (e.err == GIT_ENOTFOUND) { + return ENOENT; + } + throw NetFS::SystemError(EIO); + } +} + + +NetFS::Attr +GitFS::Repo::getattr(ReqEnv, ::std::string path, const ::Ice::Current&) +{ + NetFS::Attr a {}; + (void)path; + a.ctime = a.atime = a.mtime = git_commit_time(commit.get()); + return a; +} + + +::std::string +GitFS::Repo::readlink(ReqEnv, ::std::string path, const ::Ice::Current&) +{ + auto e = Git::TreeEntryByPath(tree, path); + if (!e) throw NetFS::SystemError(ENOENT); + const auto emode = git_tree_entry_filemode(e.get()); + if (!S_ISLNK(emode)) throw NetFS::SystemError(EINVAL); + return {}; +} + + +NetFS::FilePrxPtr +GitFS::Repo::open(ReqEnv, ::std::string path, int, const ::Ice::Current& ice) +{ + return Ice::uncheckedCast<NetFS::FilePrx>(ice.adapter->addWithUUID( + std::make_shared<Blob>(repo, Git::TreeEntryByPath(tree, path)))); +} + + +NetFS::FilePrxPtr +GitFS::Repo::create(ReqEnv, ::std::string, int, int, const ::Ice::Current&) +{ + throw NetFS::SystemError(EROFS); +} + + +void +GitFS::Repo::truncate(ReqEnv, ::std::string, long long int, const ::Ice::Current&) +{ + throw NetFS::SystemError(EROFS); +} + + +void +GitFS::Repo::unlink(ReqEnv, ::std::string, const ::Ice::Current&) +{ + throw NetFS::SystemError(EROFS); +} + + +void +GitFS::Repo::mkdir(ReqEnv, ::std::string, int, const ::Ice::Current&) +{ + throw NetFS::SystemError(EROFS); +} + + +void +GitFS::Repo::rmdir(ReqEnv, ::std::string, const ::Ice::Current&) +{ + throw NetFS::SystemError(EROFS); +} + + +void +GitFS::Repo::mknod(ReqEnv, ::std::string, int, int, const ::Ice::Current&) +{ + throw NetFS::SystemError(EROFS); +} + + +void +GitFS::Repo::symlink(ReqEnv, ::std::string, ::std::string, const ::Ice::Current&) +{ + throw NetFS::SystemError(EROFS); +} + + +void +GitFS::Repo::link(ReqEnv, ::std::string, ::std::string, const ::Ice::Current&) +{ + throw NetFS::SystemError(EROFS); +} + + +void +GitFS::Repo::rename(ReqEnv, ::std::string, ::std::string, const ::Ice::Current&) +{ + throw NetFS::SystemError(EROFS); +} + + +void +GitFS::Repo::chmod(ReqEnv, ::std::string, int, const ::Ice::Current&) +{ + throw NetFS::SystemError(EROFS); +} + + +void +GitFS::Repo::chown(ReqEnv, ::std::string, int, int, const ::Ice::Current&) +{ + throw NetFS::SystemError(EROFS); +} + + +void +GitFS::Repo::utimens(ReqEnv, ::std::string, long long int, long long int, long long int, long long int, const ::Ice::Current&) +{ + throw NetFS::SystemError(EROFS); +} + + |