#include #include #include "repo.h" #include "blob.h" #include "dir.h" std::string operator/(const std::string & a, const std::string & b) { return a.empty() ? b : a; } GitFS::Repo::Repo(const PropertyReader & properties) : repo(Git::RepositoryOpenBare(properties("gitdir"))), commitish(properties("commitish") / "master"), gid(properties("gid") / "root"), uid(properties("uid") / "root") { git_oid commitId; if (commitish.length() == GIT_OID_HEXSZ) { commitId = Git::OidParse(commitish); } else { auto ref = Git::Commitish(repo, commitish); isBranch = git_reference_is_branch(ref.get()); ref = Git::Resolve(ref); commitId = *git_reference_target(ref.get()); } commit = Git::CommitLookup(repo, commitId); 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) { if (path.empty()) throw NetFS::SystemError(EINVAL); return Ice::uncheckedCast(ice.adapter->addWithUUID( std::make_shared(this, path))); } NetFS::VFS GitFS::Repo::statfs(ReqEnv, ::std::string path, const ::Ice::Current&) { if (path.empty()) throw NetFS::SystemError(EINVAL); 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 (S_ISLNK(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 NetFS::SystemError & e) { return e.syserrno; } } NetFS::Attr GitFS::Repo::getattr(ReqEnv, ::std::string path, const ::Ice::Current&) { if (path.empty()) throw NetFS::SystemError(EINVAL); NetFS::Attr a {}; if (path == "/") { a.mode = S_IFDIR | S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH; } else { auto entry = Git::TreeEntryByPath(tree, path); a << *entry; if (S_ISREG(git_tree_entry_filemode(entry.get()))) { auto blob = Git::BlobLookup(repo, *git_tree_entry_id(entry.get())); a << *blob; } } a << *commit; a.gid = gid; a.uid = uid; return a; } ::std::string GitFS::Repo::readlink(ReqEnv, ::std::string path, const ::Ice::Current&) { if (path.empty() || path == "/") throw NetFS::SystemError(EINVAL); auto e = Git::TreeEntryByPath(tree, path); if (!S_ISLNK(git_tree_entry_filemode(e.get()))) throw NetFS::SystemError(EINVAL); auto blob = Git::BlobLookup(repo, *git_tree_entry_id(e.get())); auto n = static_cast(git_blob_rawcontent(blob.get())); return { n, n + git_blob_rawsize(blob.get()) }; } NetFS::FilePrxPtr GitFS::Repo::open(ReqEnv, ::std::string path, int, const ::Ice::Current& ice) { if (path.empty()) throw NetFS::SystemError(EINVAL); if (path == "/") throw NetFS::SystemError(EISDIR); return Ice::uncheckedCast(ice.adapter->addWithUUID( std::make_shared(this, 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); }