summaryrefslogtreecommitdiff
path: root/src/dir.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/dir.cpp')
-rw-r--r--src/dir.cpp55
1 files changed, 50 insertions, 5 deletions
diff --git a/src/dir.cpp b/src/dir.cpp
index 8a9fd86..cee26f0 100644
--- a/src/dir.cpp
+++ b/src/dir.cpp
@@ -1,10 +1,36 @@
#include <Ice/ObjectAdapter.h>
+#include <sys/stat.h>
+#include "repo.h"
#include "dir.h"
-GitFS::Directory::Directory(const GitFS::Git::TreePtr & t, const std::string & p) :
- tree(t),
- path(p)
+GitFS::Directory::Directory(const Repo * r, const std::string & p) :
+ repo(r),
+ path(p),
+ subTreeCacheRootId({})
{
+ getSubtree();
+}
+
+GitFS::Git::TreePtr
+GitFS::Directory::getSubtree() const
+{
+ if (!git_oid_equal(&subTreeCacheRootId, git_tree_id(repo->tree.get()))) {
+ if (path == "/") {
+ subTreeCache = repo->tree;
+ }
+ else {
+ try {
+ auto e = Git::TreeEntryByPath(repo->tree, path);
+ if (!S_ISDIR(git_tree_entry_filemode(e.get()))) throw NetFS::SystemError(ENOTDIR);
+ subTreeCache = Git::TreeLookup(repo->repo, *git_tree_entry_id(e.get()));
+ }
+ catch (const Git::Error & e) {
+ Git::ErrorToSystemError(e);
+ }
+ }
+ subTreeCacheRootId = *git_tree_id(repo->tree.get());
+ }
+ return subTreeCache;
}
void
@@ -17,14 +43,33 @@ GitFS::Directory::close(const ::Ice::Current& current)
NetFS::NameList
GitFS::Directory::readdir(const ::Ice::Current&)
{
- return {};
+ const auto subTree = getSubtree();
+ NetFS::NameList list;
+ for (int idx = git_tree_entrycount(subTree.get()); idx--;) {
+ const auto entry = git_tree_entry_byindex(subTree.get(), idx);
+ list.push_back(git_tree_entry_name(entry));
+ }
+ return list;
}
NetFS::DirectoryContents
GitFS::Directory::listdir(const ::Ice::Current&)
{
- return {};
+ const auto subTree = getSubtree();
+ NetFS::DirectoryContents list;
+ for (int idx = git_tree_entrycount(subTree.get()); idx--;) {
+ const auto entry = git_tree_entry_byindex(subTree.get(), idx);
+ NetFS::Attr a {};
+ a << *entry << *repo->commit;
+ if (S_ISREG(git_tree_entry_filemode(entry))) {
+ auto blob = Git::BlobLookup(repo->repo, *git_tree_entry_id(entry));
+ a << *blob;
+ }
+ a.gid = a.uid = "root";
+ list.emplace(git_tree_entry_name(entry), a);
+ }
+ return list;
}