Compare commits

...
16 Commits
Author SHA1 Message Date
Antonio SJ Musumeci 5c41e39874 checkpoint 2022-09-03 15:01:13 -04:00
Antonio SJ Musumeci 469492800c checkpoint 2022-05-23 10:29:25 -04:00
Antonio SJ Musumeci 9019df57d0 checkpoint 2022-05-20 00:04:28 -04:00
Antonio SJ Musumeci 8e1d4c5a8e checkpoint 2022-05-19 23:16:41 -04:00
Antonio SJ Musumeci 8f6467a11c checkpoint 2022-05-19 18:30:29 -04:00
Antonio SJ Musumeci 7a81a5112c checkpoint 2022-05-18 21:05:19 -04:00
Antonio SJ Musumeci 3cc77d6066 checkpoint 2022-05-17 23:26:04 -04:00
Antonio SJ Musumeci a675e14508 checkpoint 2022-05-17 21:52:36 -04:00
Antonio SJ Musumeci c8e8865495 checkpoint 2022-05-16 23:54:48 -04:00
Antonio SJ Musumeci 202f29286b checkpoint 2022-05-15 23:34:21 -04:00
Antonio SJ Musumeci 551ee1ab05 checkpoint 2022-05-15 20:54:43 -04:00
Antonio SJ Musumeci 5e48ba69b5 checkpoint 2022-05-15 20:53:29 -04:00
Antonio SJ Musumeci dc8baee8a6 checkpoint 2022-05-15 16:05:40 -04:00
Antonio SJ Musumeci cba7433166 checkpoint 2022-05-15 13:11:02 -04:00
Antonio SJ Musumeci 2ae212ae81 checkpoint 2022-05-13 19:43:11 -04:00
Antonio SJ Musumeci 0bb55624a4 checkpoint 2022-05-13 19:11:10 -04:00
424 changed files with 23250 additions and 10991 deletions
+1 -1
View File
@@ -1,7 +1,7 @@
/*
ISC License
Copyright (c) 2021, Antonio SJ Musumeci <trapexit@spawn.link>
Copyright (c) 2022, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
+93
View File
@@ -0,0 +1,93 @@
# test file
[filesystem]
name = 'foo'
mountpoint = '/tmp/test'
threads = 0
[fuse]
posix-acl = false
async-read = true
message-size = 256
[func]
inode-calc = 'hybrid-hash'
symlinkify = false
symlinkify-timeout = 0
xattr = 'passthrough'
[func.access]
policy = 'ff'
[func.create]
policy = 'ff'
[func.getattr]
policy = 'ff'
follow-symlinks = 'never'
[func.rmdir]
policy = 'all'
follow-symlinks = 'never'
[func.link]
policy = 'all' # 'preserve-paths' | 'create-paths' | 'per-branch'
exdev = 'passthrough'
[func.write]
policy = 'null'
move-on-enospc = 'mfs'
[func.release]
drop-cache = true
[func.read]
policy = 'null'
[func.getxattr]
security-capability = false
[func.setxattr]
security-capability = false
[func.open]
link-cow = true
nfs-hack = 'off'
[func.rename]
policy = 'all'
exdev = 'passthrough'
[func.statfs]
policy = 'base'
ignore = 'none'
[func.readdir]
policy = 'posix'
readdirplus = false
[cache]
files = 'off'
statfs = 0
attr-timeout = 0
entry-timeout = 0
negative-entry-timeout = 0
writeback = false
symlinks = false
readdir = false
[branches]
min-free-space = 123
[[branches.group]]
[[branches.group.branch]]
active = true
path = '/tmp/mergerfs/a'
path-type = 'literal'
mode = 'RW'
if-not-mountpoint = 'fail' # 'fail' | 'deactivate' ?
#[[branches.group.branch]]
#path = '/tmp/mergerfs/*'
#path-type = 'glob'
File diff suppressed because it is too large Load Diff
+16 -71
View File
@@ -17,81 +17,26 @@
*/
#include "branch.hpp"
#include "ef.hpp"
#include "errno.hpp"
#include "num.hpp"
Branch::Branch(const uint64_t &default_minfreespace_)
: _default_minfreespace(&default_minfreespace_)
Branch::Mode
Branch::str2mode(const std::string &str_)
{
if(str_ == "RW")
return Branch::Mode::RW;
if(str_ == "RO")
return Branch::Mode::RO;
if(str_ == "NC")
return Branch::Mode::NC;
return Branch::Mode::RW;
}
int
Branch::from_string(const std::string &str_)
Branch::Branch(const toml::value &toml_,
const Branch::Mode default_mode_,
const uint64_t default_minfreespace_)
{
return -EINVAL;
}
std::string
Branch::to_string(void) const
{
std::string rv;
rv = path;
rv += '=';
switch(mode)
{
default:
case Branch::Mode::RW:
rv += "RW";
break;
case Branch::Mode::RO:
rv += "RO";
break;
case Branch::Mode::NC:
rv += "NC";
break;
}
if(_minfreespace.has_value())
{
rv += ',';
rv += num::humanize(_minfreespace.value());
}
return rv;
}
void
Branch::set_minfreespace(const uint64_t minfreespace_)
{
_minfreespace = minfreespace_;
}
uint64_t
Branch::minfreespace(void) const
{
if(_minfreespace.has_value())
return _minfreespace.value();
return *_default_minfreespace;
}
bool
Branch::ro(void) const
{
return (mode == Branch::Mode::RO);
}
bool
Branch::nc(void) const
{
return (mode == Branch::Mode::NC);
}
bool
Branch::ro_or_nc(void) const
{
return ((mode == Branch::Mode::RO) ||
(mode == Branch::Mode::NC));
mode = toml::find_or(toml_,"mode",default_mode_);
minfreespace = toml::find_or(toml_,"min-free-space",default_minfreespace_);
path = toml::find<std::string>(toml_,"path");
}
+37 -24
View File
@@ -18,23 +18,17 @@
#pragma once
#include "nonstd/optional.hpp"
#include "strvec.hpp"
#include "tofrom_string.hpp"
#include "fs_path.hpp"
#include "toml.hpp"
#include <cstdint>
#include <string>
#include <vector>
class Branch final : public ToFromString
class Branch
{
public:
typedef std::vector<Branch> Vector;
public:
Branch(const uint64_t &default_minfreespace_);
public:
enum class Mode
{
@@ -44,24 +38,43 @@ public:
NC
};
static Mode str2mode(const std::string &);
public:
Branch(const toml::value &toml,
const Branch::Mode default_mode,
const uint64_t default_minfreespace);
public:
bool ro(void) const;
bool nc(void) const;
bool ro_or_nc(void) const;
public:
int from_string(const std::string &str) final;
std::string to_string(void) const final;
public:
uint64_t minfreespace() const;
void set_minfreespace(const uint64_t);
public:
Mode mode;
std::string path;
private:
nonstd::optional<uint64_t> _minfreespace;
const uint64_t *_default_minfreespace;
gfs::path path;
Mode mode;
uint64_t minfreespace;
};
namespace toml
{
template<>
struct from<Branch::Mode>
{
static
Branch::Mode
from_toml(const toml::value &v_)
{
std::string str = v_.as_string();
if(str == "RW")
return Branch::Mode::RW;
if(str == "RO")
return Branch::Mode::RO;
if(str == "NC")
return Branch::Mode::NC;
return Branch::Mode::RW;
}
};
}
+92
View File
@@ -0,0 +1,92 @@
/*
ISC License
Copyright (c) 2022, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "branch_group.hpp"
#include "fs_glob.hpp"
#include "fs_path.hpp"
#include <iostream>
#include <stdexcept>
namespace l
{
static
void
add_literal(const toml::value &branch_,
const Branch::Mode default_mode_,
const uint64_t default_minfreespace_,
BranchGroup *branch_group_)
{
branch_group_->emplace_back(branch_,default_mode_,default_minfreespace_);
}
static
void
add_glob(const toml::value &branch_,
const Branch::Mode default_mode_,
const uint64_t default_minfreespace_,
BranchGroup *branch_group_)
{
std::string pattern;
std::vector<gfs::path> paths;
pattern = toml::find<std::string>(branch_,"path");
fs::glob(pattern,&paths);
for(const auto &path : paths)
{
toml::value v = branch_;
v["path"] = path.native();
v["path-type"] = "literal";
l::add_literal(v,default_mode_,default_minfreespace_,branch_group_);
}
}
}
BranchGroup::BranchGroup(const toml::value &toml_,
const Branch::Mode default_mode_,
const uint64_t default_minfreespace_)
{
Branch::Mode default_mode;
uint64_t default_minfreespace;
default_mode = toml::find_or(toml_,"mode",default_mode_);
default_minfreespace = toml::find_or(toml_,"min-free-space",default_minfreespace_);
for(const auto &branch : toml_.at("branch").as_array())
{
std::string path_type;
if(!toml::find_or(branch,"active",true))
continue;
path_type = toml::find_or(branch,"path-type","literal");
if(path_type == "literal")
l::add_literal(branch,default_mode,default_minfreespace_,this);
else if(path_type == "glob")
l::add_glob(branch,default_mode,default_minfreespace,this);
else
throw std::runtime_error("invalid path-type = " + path_type);
}
}
+11 -9
View File
@@ -1,5 +1,7 @@
/*
Copyright (c) 2016, Antonio SJ Musumeci <trapexit@spawn.link>
ISC License
Copyright (c) 2022, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
@@ -16,14 +18,14 @@
#pragma once
#include "config.hpp"
#include "branch.hpp"
#include "fuse.h"
#include <vector>
namespace options
class BranchGroup : public std::vector<Branch>
{
void
parse(fuse_args *args,
Config::ErrVec *errs);
}
public:
BranchGroup(const toml::value &,
const Branch::Mode,
const uint64_t);
};
+12 -394
View File
@@ -19,413 +19,31 @@
#include "branches.hpp"
#include "ef.hpp"
#include "errno.hpp"
#include "from_string.hpp"
#include "fs_glob.hpp"
#include "fs_realpathize.hpp"
#include "nonstd/optional.hpp"
#include "num.hpp"
#include "str.hpp"
#include <string>
#include <fnmatch.h>
using std::string;
using std::vector;
using nonstd::optional;
#include <iostream>
Branches::Impl::Impl(const uint64_t &default_minfreespace_)
: _default_minfreespace(default_minfreespace_)
Branches::Branches(const toml::value &toml_)
{
}
toml::value branches;
Branch::Mode default_mode;
uint64_t default_minfreespace;
Branches::Impl&
Branches::Impl::operator=(Branches::Impl &rval_)
{
auto this_base = dynamic_cast<Branch::Vector*>(this);
auto rval_base = dynamic_cast<Branch::Vector*>(&rval_);
default_mode = toml::find_or(toml_,"branches","mode",Branch::Mode::RW);
default_minfreespace = toml::find_or(toml_,"branches","min-free-space",0);
*this_base = *rval_base;
branches = toml::find(toml_,"branches");
return *this;
}
Branches::Impl&
Branches::Impl::operator=(Branches::Impl &&rval_)
{
auto this_base = dynamic_cast<Branch::Vector*>(this);
auto rval_base = dynamic_cast<Branch::Vector*>(&rval_);
*this_base = std::move(*rval_base);
return *this;
}
const
uint64_t&
Branches::Impl::minfreespace(void) const
{
return _default_minfreespace;
}
namespace l
{
static
void
split(const std::string &s_,
std::string *instr_,
std::string *values_)
{
uint64_t offset;
offset = s_.find_first_not_of("+<>-=");
if(offset > 1)
offset = 2;
*instr_ = s_.substr(0,offset);
if(offset != std::string::npos)
*values_ = s_.substr(offset);
}
static
int
parse_mode(const string &str_,
Branch::Mode *mode_)
{
if(str_ == "RW")
*mode_ = Branch::Mode::RW;
ef(str_ == "RO")
*mode_ = Branch::Mode::RO;
ef(str_ == "NC")
*mode_ = Branch::Mode::NC;
else
return -EINVAL;
return 0;
}
static
int
parse_minfreespace(const string &str_,
optional<uint64_t> *minfreespace_)
{
int rv;
uint64_t uint64;
rv = str::from(str_,&uint64);
if(rv < 0)
return rv;
*minfreespace_ = uint64;
return 0;
}
static
int
parse_branch(const string &str_,
string *glob_,
Branch::Mode *mode_,
optional<uint64_t> *minfreespace_)
{
int rv;
string options;
vector<string> v;
str::rsplit1(str_,'=',&v);
switch(v.size())
{
case 1:
*glob_ = v[0];
*mode_ = Branch::Mode::RW;
break;
case 2:
*glob_ = v[0];
options = v[1];
v.clear();
str::split(options,',',&v);
switch(v.size())
{
case 2:
rv = l::parse_minfreespace(v[1],minfreespace_);
if(rv < 0)
return rv;
case 1:
rv = l::parse_mode(v[0],mode_);
if(rv < 0)
return rv;
break;
case 0:
return -EINVAL;
}
break;
default:
return -EINVAL;
}
return 0;
}
static
int
parse(const string &str_,
Branches::Impl *branches_)
{
int rv;
string glob;
StrVec paths;
optional<uint64_t> minfreespace;
Branch branch(branches_->minfreespace());
rv = l::parse_branch(str_,&glob,&branch.mode,&minfreespace);
if(rv < 0)
return rv;
if(minfreespace.has_value())
branch.set_minfreespace(minfreespace.value());
fs::glob(glob,&paths);
fs::realpathize(&paths);
for(auto &path : paths)
{
branch.path = path;
branches_->push_back(branch);
}
return 0;
}
static
int
set(const std::string &str_,
Branches::Impl *branches_)
{
int rv;
StrVec paths;
Branches::Impl tmp_branches(branches_->minfreespace());
str::split(str_,':',&paths);
for(auto &path : paths)
{
rv = l::parse(path,&tmp_branches);
if(rv < 0)
return rv;
}
*branches_ = std::move(tmp_branches);
return 0;
}
static
int
add_begin(const std::string &str_,
Branches::Impl *branches_)
{
int rv;
vector<string> paths;
Branches::Impl tmp_branches(branches_->minfreespace());
str::split(str_,':',&paths);
for(auto &path : paths)
{
rv = l::parse(path,&tmp_branches);
if(rv < 0)
return rv;
}
branches_->insert(branches_->begin(),
tmp_branches.begin(),
tmp_branches.end());
return 0;
}
static
int
add_end(const std::string &str_,
Branches::Impl *branches_)
{
int rv;
StrVec paths;
Branches::Impl tmp_branches(branches_->minfreespace());
str::split(str_,':',&paths);
for(auto &path : paths)
{
rv = l::parse(path,&tmp_branches);
if(rv < 0)
return rv;
}
branches_->insert(branches_->end(),
tmp_branches.begin(),
tmp_branches.end());
return 0;
}
static
int
erase_begin(Branches::Impl *branches_)
{
branches_->erase(branches_->begin());
return 0;
}
static
int
erase_end(Branches::Impl *branches_)
{
branches_->pop_back();
return 0;
}
static
int
erase_fnmatch(const std::string &str_,
Branches::Impl *branches_)
{
StrVec patterns;
str::split(str_,':',&patterns);
for(auto i = branches_->begin(); i != branches_->end();)
{
int match = FNM_NOMATCH;
for(auto pi = patterns.cbegin(); pi != patterns.cend() && match != 0; ++pi)
{
match = ::fnmatch(pi->c_str(),i->path.c_str(),0);
}
i = ((match == 0) ? branches_->erase(i) : (i+1));
}
return 0;
}
}
int
Branches::Impl::from_string(const std::string &s_)
{
std::string instr;
std::string values;
l::split(s_,&instr,&values);
if(instr == "+")
return l::add_end(values,this);
if(instr == "+<")
return l::add_begin(values,this);
if(instr == "+>")
return l::add_end(values,this);
if(instr == "-")
return l::erase_fnmatch(values,this);
if(instr == "-<")
return l::erase_begin(this);
if(instr == "->")
return l::erase_end(this);
if(instr == "=")
return l::set(values,this);
if(instr.empty())
return l::set(values,this);
return -EINVAL;
}
std::string
Branches::Impl::to_string(void) const
{
string tmp;
if(empty())
return tmp;
for(auto &branch : *this)
for(const auto &branch_group : branches.at("group").as_array())
{
tmp += branch.to_string();
tmp += ':';
}
if(!toml::find_or(branch_group,"active",true))
continue;
tmp.pop_back();
return tmp;
}
void
Branches::Impl::to_paths(StrVec &paths_) const
{
for(auto &branch : *this)
{
paths_.push_back(branch.path);
emplace_back(branch_group,default_mode,default_minfreespace);
}
}
int
Branches::from_string(const std::string &str_)
{
int rv;
Branches::Ptr impl;
Branches::Ptr new_impl;
{
std::lock_guard<std::mutex> lock_guard(_mutex);
impl = _impl;
}
new_impl = std::make_shared<Branches::Impl>(impl->minfreespace());
*new_impl = *impl;
rv = new_impl->from_string(str_);
if(rv < 0)
return rv;
{
std::lock_guard<std::mutex> lock_guard(_mutex);
_impl = new_impl;
}
return 0;
}
string
Branches::to_string(void) const
{
std::lock_guard<std::mutex> lock_guard(_mutex);
return _impl->to_string();
}
SrcMounts::SrcMounts(Branches &b_)
: _branches(b_)
{
}
int
SrcMounts::from_string(const std::string &s_)
{
return _branches.from_string(s_);
}
std::string
SrcMounts::to_string(void) const
{
std::string rv;
Branches::CPtr branches = _branches;
if(branches->empty())
return rv;
for(const auto &branch : *branches)
{
rv += branch.path;
rv += ':';
}
rv.pop_back();
return rv;
}
+3 -66
View File
@@ -19,76 +19,13 @@
#pragma once
#include "branch.hpp"
#include "nonstd/optional.hpp"
#include "strvec.hpp"
#include "tofrom_string.hpp"
#include "branch_group.hpp"
#include <cstdint>
#include <memory>
#include <mutex>
#include <string>
#include <vector>
class Branches final : public ToFromString
class Branches : public std::vector<BranchGroup>
{
public:
class Impl final : public ToFromString, public Branch::Vector
{
public:
typedef std::shared_ptr<Impl> Ptr;
typedef std::shared_ptr<const Impl> CPtr;
public:
Impl(const uint64_t &default_minfreespace_);
public:
int from_string(const std::string &str) final;
std::string to_string(void) const final;
public:
const uint64_t& minfreespace(void) const;
void to_paths(StrVec &strvec) const;
public:
Impl& operator=(Impl &impl_);
Impl& operator=(Impl &&impl_);
private:
const uint64_t &_default_minfreespace;
};
public:
typedef Branches::Impl::Ptr Ptr;
typedef Branches::Impl::CPtr CPtr;
public:
Branches(const uint64_t &default_minfreespace_)
: _impl(std::make_shared<Impl>(default_minfreespace_))
{}
public:
int from_string(const std::string &str) final;
std::string to_string(void) const final;
public:
operator CPtr() const { std::lock_guard<std::mutex> lg(_mutex); return _impl; }
CPtr operator->() const { std::lock_guard<std::mutex> lg(_mutex); return _impl; }
private:
mutable std::mutex _mutex;
Ptr _impl;
};
class SrcMounts : public ToFromString
{
public:
SrcMounts(Branches &b_);
public:
int from_string(const std::string &str) final;
std::string to_string(void) const final;
private:
Branches &_branches;
Branches(const toml::value &);
};
-107
View File
@@ -1,107 +0,0 @@
/*
Copyright (c) 2020, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#pragma once
#include "tofrom_string.hpp"
#include "funcs.hpp"
#include "func.hpp"
#include <string>
namespace Category
{
class Base : public ToFromString
{
public:
int from_string(const std::string &s) final;
std::string to_string() const final;
protected:
std::vector<ToFromString*> funcs;
};
class Action final : public Base
{
private:
Action();
public:
Action(Funcs &funcs_)
{
funcs.push_back(&funcs_.chmod);
funcs.push_back(&funcs_.chown);
funcs.push_back(&funcs_.link);
funcs.push_back(&funcs_.removexattr);
funcs.push_back(&funcs_.rename);
funcs.push_back(&funcs_.rmdir);
funcs.push_back(&funcs_.setxattr);
funcs.push_back(&funcs_.truncate);
funcs.push_back(&funcs_.unlink);
funcs.push_back(&funcs_.utimens);
}
};
class Create final : public Base
{
private:
Create();
public:
Create(Funcs &funcs_)
{
funcs.push_back(&funcs_.create);
funcs.push_back(&funcs_.mkdir);
funcs.push_back(&funcs_.mknod);
funcs.push_back(&funcs_.symlink);
}
};
class Search final : public Base
{
private:
Search();
public:
Search(Funcs &funcs_)
{
funcs.push_back(&funcs_.access);
funcs.push_back(&funcs_.getattr);
funcs.push_back(&funcs_.getxattr);
funcs.push_back(&funcs_.listxattr);
funcs.push_back(&funcs_.open);
funcs.push_back(&funcs_.readlink);
}
};
}
class Categories final
{
private:
Categories();
public:
Categories(Funcs &funcs_)
: action(funcs_),
create(funcs_),
search(funcs_)
{}
public:
Category::Action action;
Category::Create create;
Category::Search search;
};
-401
View File
@@ -1,401 +0,0 @@
/*
Copyright (c) 2016, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "config.hpp"
#include "ef.hpp"
#include "errno.hpp"
#include "from_string.hpp"
#include "num.hpp"
#include "rwlock.hpp"
#include "str.hpp"
#include "to_string.hpp"
#include "version.hpp"
#include <algorithm>
#include <cstdint>
#include <fstream>
#include <iostream>
#include <string>
#include <pthread.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>
#define MINFREESPACE_DEFAULT (4294967295ULL)
using std::string;
#define IFERT(S) if(S == s_) return true
const std::string CONTROLFILE = "/.mergerfs";
Config Config::_singleton;
namespace l
{
static
bool
readonly(const std::string &s_)
{
IFERT("async_read");
IFERT("cache.symlinks");
IFERT("cache.writeback");
IFERT("fsname");
IFERT("fuse_msg_size");
IFERT("mount");
IFERT("nullrw");
IFERT("pid");
IFERT("readdirplus");
IFERT("threads");
IFERT("version");
return false;
}
}
Config::Config()
: async_read(true),
auto_cache(false),
minfreespace(MINFREESPACE_DEFAULT),
branches(minfreespace),
cache_attr(1),
cache_entry(1),
cache_files(CacheFiles::ENUM::LIBFUSE),
cache_negative_entry(0),
cache_readdir(false),
cache_statfs(0),
cache_symlinks(false),
category(func),
direct_io(false),
dropcacheonclose(false),
fsname(),
follow_symlinks(FollowSymlinks::ENUM::NEVER),
func(),
fuse_msg_size(FUSE_MAX_MAX_PAGES),
ignorepponrename(false),
inodecalc("hybrid-hash"),
link_cow(false),
link_exdev(LinkEXDEV::ENUM::PASSTHROUGH),
log_metrics(false),
mount(),
moveonenospc(false),
nfsopenhack(NFSOpenHack::ENUM::OFF),
nullrw(false),
pid(::getpid()),
posix_acl(false),
readdir(ReadDir::ENUM::POSIX),
readdirplus(false),
rename_exdev(RenameEXDEV::ENUM::PASSTHROUGH),
security_capability(true),
srcmounts(branches),
statfs(StatFS::ENUM::BASE),
statfs_ignore(StatFSIgnore::ENUM::NONE),
symlinkify(false),
symlinkify_timeout(3600),
threads(0),
version(MERGERFS_VERSION),
writeback_cache(false),
xattr(XAttr::ENUM::PASSTHROUGH)
{
_map["async_read"] = &async_read;
_map["auto_cache"] = &auto_cache;
_map["branches"] = &branches;
_map["cache.attr"] = &cache_attr;
_map["cache.entry"] = &cache_entry;
_map["cache.files"] = &cache_files;
_map["cache.negative_entry"] = &cache_negative_entry;
_map["cache.readdir"] = &cache_readdir;
_map["cache.statfs"] = &cache_statfs;
_map["cache.symlinks"] = &cache_symlinks;
_map["cache.writeback"] = &writeback_cache;
_map["category.action"] = &category.action;
_map["category.create"] = &category.create;
_map["category.search"] = &category.search;
_map["direct_io"] = &direct_io;
_map["dropcacheonclose"] = &dropcacheonclose;
_map["follow-symlinks"] = &follow_symlinks;
_map["fsname"] = &fsname;
_map["func.access"] = &func.access;
_map["func.chmod"] = &func.chmod;
_map["func.chown"] = &func.chown;
_map["func.create"] = &func.create;
_map["func.getattr"] = &func.getattr;
_map["func.getxattr"] = &func.getxattr;
_map["func.link"] = &func.link;
_map["func.listxattr"] = &func.listxattr;
_map["func.mkdir"] = &func.mkdir;
_map["func.mknod"] = &func.mknod;
_map["func.open"] = &func.open;
_map["func.readlink"] = &func.readlink;
_map["func.removexattr"] = &func.removexattr;
_map["func.rename"] = &func.rename;
_map["func.rmdir"] = &func.rmdir;
_map["func.setxattr"] = &func.setxattr;
_map["func.symlink"] = &func.symlink;
_map["func.truncate"] = &func.truncate;
_map["func.unlink"] = &func.unlink;
_map["func.utimens"] = &func.utimens;
_map["fuse_msg_size"] = &fuse_msg_size;
_map["ignorepponrename"] = &ignorepponrename;
_map["inodecalc"] = &inodecalc;
_map["kernel_cache"] = &kernel_cache;
_map["link_cow"] = &link_cow;
_map["link-exdev"] = &link_exdev;
_map["log.metrics"] = &log_metrics;
_map["minfreespace"] = &minfreespace;
_map["mount"] = &mount;
_map["moveonenospc"] = &moveonenospc;
_map["nfsopenhack"] = &nfsopenhack;
_map["nullrw"] = &nullrw;
_map["pid"] = &pid;
_map["posix_acl"] = &posix_acl;
// _map["readdir"] = &readdir;
_map["readdirplus"] = &readdirplus;
_map["rename-exdev"] = &rename_exdev;
_map["security_capability"] = &security_capability;
_map["srcmounts"] = &srcmounts;
_map["statfs"] = &statfs;
_map["statfs_ignore"] = &statfs_ignore;
_map["symlinkify"] = &symlinkify;
_map["symlinkify_timeout"] = &symlinkify_timeout;
_map["threads"] = &threads;
_map["version"] = &version;
_map["xattr"] = &xattr;
}
Config&
Config::operator=(const Config &cfg_)
{
int rv;
std::string val;
for(auto &kv : _map)
{
rv = cfg_.get(kv.first,&val);
if(rv)
continue;
kv.second->from_string(val);
}
return *this;
}
bool
Config::has_key(const std::string &key_) const
{
return _map.count(key_);
}
void
Config::keys(std::string &s_) const
{
Str2TFStrMap::const_iterator i;
Str2TFStrMap::const_iterator ei;
s_.reserve(512);
i = _map.begin();
ei = _map.end();
for(; i != ei; ++i)
{
s_ += i->first;
s_ += '\0';
}
s_.resize(s_.size() - 1);
}
void
Config::keys_xattr(std::string &s_) const
{
Str2TFStrMap::const_iterator i;
Str2TFStrMap::const_iterator ei;
s_.reserve(1024);
for(i = _map.begin(), ei = _map.end(); i != ei; ++i)
{
s_ += "user.mergerfs.";
s_ += i->first;
s_ += '\0';
}
}
int
Config::get(const std::string &key_,
std::string *val_) const
{
Str2TFStrMap::const_iterator i;
i = _map.find(key_);
if(i == _map.end())
return -ENOATTR;
*val_ = i->second->to_string();
return 0;
}
int
Config::set_raw(const std::string &key_,
const std::string &value_)
{
Str2TFStrMap::iterator i;
i = _map.find(key_);
if(i == _map.end())
return -ENOATTR;
return i->second->from_string(value_);
}
int
Config::set(const std::string &key_,
const std::string &value_)
{
if(l::readonly(key_))
return -EROFS;
return set_raw(key_,value_);
}
int
Config::set(const std::string &kv_)
{
std::string key;
std::string val;
str::splitkv(kv_,'=',&key,&val);
key = str::trim(key);
val = str::trim(val);
return set(key,val);
}
int
Config::from_stream(std::istream &istrm_,
ErrVec *errs_)
{
int rv;
std::string line;
std::string key;
std::string val;
Config newcfg;
newcfg = *this;
while(std::getline(istrm_,line,'\n'))
{
line = str::trim(line);
if(!line.empty() && (line[0] == '#'))
continue;
str::splitkv(line,'=',&key,&val);
key = str::trim(key);
val = str::trim(val);
rv = newcfg.set(key,val);
if(rv < 0)
errs_->push_back({rv,key});
}
if(!errs_->empty())
return -EINVAL;
*this = newcfg;
return 0;
}
int
Config::from_file(const std::string &filepath_,
ErrVec *errs_)
{
int rv;
std::ifstream ifstrm;
ifstrm.open(filepath_);
if(!ifstrm.good())
{
errs_->push_back({-errno,filepath_});
return -errno;
}
rv = from_stream(ifstrm,errs_);
ifstrm.close();
return rv;
}
std::ostream&
operator<<(std::ostream &os_,
const Config &c_)
{
Str2TFStrMap::const_iterator i;
Str2TFStrMap::const_iterator ei;
for(i = c_._map.begin(), ei = c_._map.end(); i != ei; ++i)
{
os_ << i->first << '=' << i->second->to_string() << std::endl;
}
return os_;
}
static
std::string
err2str(const int err_)
{
switch(err_)
{
case 0:
return std::string();
case -EINVAL:
return "invalid value";
case -ENOATTR:
return "unknown option";
case -EROFS:
return "read-only option";
default:
return strerror(-err_);
}
return std::string();
}
std::ostream&
operator<<(std::ostream &os_,
const Config::ErrVec &ev_)
{
std::string errstr;
for(auto &err : ev_)
{
os_ << "* ERROR: ";
errstr = err2str(err.err);
if(!errstr.empty())
os_ << errstr << " - ";
os_ << err.str << std::endl;
}
return os_;
}
-205
View File
@@ -1,205 +0,0 @@
/*
Copyright (c) 2016, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#pragma once
#include "branches.hpp"
#include "category.hpp"
#include "config_cachefiles.hpp"
#include "config_follow_symlinks.hpp"
#include "config_inodecalc.hpp"
#include "config_link_exdev.hpp"
#include "config_log_metrics.hpp"
#include "config_moveonenospc.hpp"
#include "config_nfsopenhack.hpp"
#include "config_readdir.hpp"
#include "config_rename_exdev.hpp"
#include "config_statfs.hpp"
#include "config_statfsignore.hpp"
#include "config_xattr.hpp"
#include "enum.hpp"
#include "errno.hpp"
#include "funcs.hpp"
#include "policy.hpp"
#include "rwlock.hpp"
#include "tofrom_wrapper.hpp"
#include "fuse.h"
#include <cstdint>
#include <map>
#include <memory>
#include <string>
#include <vector>
#include <sys/stat.h>
typedef ToFromWrapper<bool> ConfigBOOL;
typedef ToFromWrapper<uint64_t> ConfigUINT64;
typedef ToFromWrapper<int> ConfigINT;
typedef ToFromWrapper<std::string> ConfigSTR;
typedef std::map<std::string,ToFromString*> Str2TFStrMap;
extern const std::string CONTROLFILE;
class Config
{
public:
struct Err
{
int err;
std::string str;
};
typedef std::vector<Err> ErrVec;
public:
class Read
{
public:
Read();
public:
inline const Config* operator->() const;
private:
const Config &_cfg;
};
public:
class Write
{
public:
Write();
public:
Config* operator->();
private:
Config &_cfg;
};
public:
Config();
public:
Config& operator=(const Config&);
public:
ConfigBOOL async_read;
ConfigBOOL auto_cache;
ConfigUINT64 minfreespace;
Branches branches;
ConfigUINT64 cache_attr;
ConfigUINT64 cache_entry;
CacheFiles cache_files;
ConfigUINT64 cache_negative_entry;
ConfigBOOL cache_readdir;
ConfigUINT64 cache_statfs;
ConfigBOOL cache_symlinks;
Categories category;
ConfigBOOL direct_io;
ConfigBOOL dropcacheonclose;
ConfigSTR fsname;
FollowSymlinks follow_symlinks;
Funcs func;
ConfigUINT64 fuse_msg_size;
ConfigBOOL ignorepponrename;
InodeCalc inodecalc;
ConfigBOOL kernel_cache;
ConfigBOOL link_cow;
LinkEXDEV link_exdev;
LogMetrics log_metrics;
ConfigSTR mount;
MoveOnENOSPC moveonenospc;
NFSOpenHack nfsopenhack;
ConfigBOOL nullrw;
ConfigUINT64 pid;
ConfigBOOL posix_acl;
ReadDir readdir;
ConfigBOOL readdirplus;
RenameEXDEV rename_exdev;
ConfigBOOL security_capability;
SrcMounts srcmounts;
StatFS statfs;
StatFSIgnore statfs_ignore;
ConfigBOOL symlinkify;
ConfigUINT64 symlinkify_timeout;
ConfigINT threads;
ConfigSTR version;
ConfigBOOL writeback_cache;
XAttr xattr;
public:
friend std::ostream& operator<<(std::ostream &s,
const Config &c);
public:
bool has_key(const std::string &key) const;
void keys(std::string &s) const;
void keys_xattr(std::string &s) const;
public:
int get(const std::string &key, std::string *val) const;
int set_raw(const std::string &key, const std::string &val);
int set(const std::string &key, const std::string &val);
int set(const std::string &kv);
public:
int from_stream(std::istream &istrm, ErrVec *errs);
int from_file(const std::string &filepath, ErrVec *errs);
private:
Str2TFStrMap _map;
private:
static Config _singleton;
public:
friend class Read;
friend class Write;
};
std::ostream& operator<<(std::ostream &s,const Config::ErrVec &ev);
inline
Config::Read::Read()
: _cfg(Config::_singleton)
{
}
inline
const
Config*
Config::Read::operator->() const
{
return &_cfg;
}
inline
Config::Write::Write()
: _cfg(Config::_singleton)
{
}
inline
Config*
Config::Write::operator->()
{
return &_cfg;
}
-62
View File
@@ -1,62 +0,0 @@
/*
ISC License
Copyright (c) 2020, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "config_cachefiles.hpp"
#include "ef.hpp"
#include "errno.hpp"
template<>
std::string
CacheFiles::to_string() const
{
switch(_data)
{
case CacheFiles::ENUM::LIBFUSE:
return "libfuse";
case CacheFiles::ENUM::OFF:
return "off";
case CacheFiles::ENUM::PARTIAL:
return "partial";
case CacheFiles::ENUM::FULL:
return "full";
case CacheFiles::ENUM::AUTO_FULL:
return "auto-full";
}
return "invalid";
}
template<>
int
CacheFiles::from_string(const std::string &s_)
{
if(s_ == "libfuse")
_data = CacheFiles::ENUM::LIBFUSE;
ef(s_ == "off")
_data = CacheFiles::ENUM::OFF;
ef(s_ == "partial")
_data = CacheFiles::ENUM::PARTIAL;
ef(s_ == "full")
_data = CacheFiles::ENUM::FULL;
ef(s_ == "auto-full")
_data = CacheFiles::ENUM::AUTO_FULL;
else
return -EINVAL;
return 0;
}
-58
View File
@@ -1,58 +0,0 @@
/*
ISC License
Copyright (c) 2020, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "config_follow_symlinks.hpp"
#include "ef.hpp"
#include "errno.hpp"
template<>
std::string
FollowSymlinks::to_string(void) const
{
switch(_data)
{
case FollowSymlinks::ENUM::NEVER:
return "never";
case FollowSymlinks::ENUM::DIRECTORY:
return "directory";
case FollowSymlinks::ENUM::REGULAR:
return "regular";
case FollowSymlinks::ENUM::ALL:
return "all";
}
return "invalid";
}
template<>
int
FollowSymlinks::from_string(const std::string &s_)
{
if(s_ == "never")
_data = FollowSymlinks::ENUM::NEVER;
ef(s_ == "directory")
_data = FollowSymlinks::ENUM::DIRECTORY;
ef(s_ == "regular")
_data = FollowSymlinks::ENUM::REGULAR;
ef(s_ == "all")
_data = FollowSymlinks::ENUM::ALL;
else
return -EINVAL;
return 0;
}
-58
View File
@@ -1,58 +0,0 @@
/*
ISC License
Copyright (c) 2021, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "config_link_exdev.hpp"
#include "ef.hpp"
#include "errno.hpp"
template<>
std::string
LinkEXDEV::to_string(void) const
{
switch(_data)
{
case LinkEXDEV::ENUM::PASSTHROUGH:
return "passthrough";
case LinkEXDEV::ENUM::REL_SYMLINK:
return "rel-symlink";
case LinkEXDEV::ENUM::ABS_BASE_SYMLINK:
return "abs-base-symlink";
case LinkEXDEV::ENUM::ABS_POOL_SYMLINK:
return "abs-pool-symlink";
}
return "invalid";
}
template<>
int
LinkEXDEV::from_string(const std::string &s_)
{
if(s_ == "passthrough")
_data = LinkEXDEV::ENUM::PASSTHROUGH;
ef(s_ == "rel-symlink")
_data = LinkEXDEV::ENUM::REL_SYMLINK;
ef(s_ == "abs-base-symlink")
_data = LinkEXDEV::ENUM::ABS_BASE_SYMLINK;
ef(s_ == "abs-pool-symlink")
_data = LinkEXDEV::ENUM::ABS_POOL_SYMLINK;
else
return -EINVAL;
return 0;
}
-54
View File
@@ -1,54 +0,0 @@
/*
ISC License
Copyright (c) 2021, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "config_rename_exdev.hpp"
#include "ef.hpp"
#include "errno.hpp"
template<>
std::string
RenameEXDEV::to_string(void) const
{
switch(_data)
{
case RenameEXDEV::ENUM::PASSTHROUGH:
return "passthrough";
case RenameEXDEV::ENUM::REL_SYMLINK:
return "rel-symlink";
case RenameEXDEV::ENUM::ABS_SYMLINK:
return "abs-symlink";
}
return "invalid";
}
template<>
int
RenameEXDEV::from_string(const std::string &s_)
{
if(s_ == "passthrough")
_data = RenameEXDEV::ENUM::PASSTHROUGH;
ef(s_ == "rel-symlink")
_data = RenameEXDEV::ENUM::REL_SYMLINK;
ef(s_ == "abs-symlink")
_data = RenameEXDEV::ENUM::ABS_SYMLINK;
else
return -EINVAL;
return 0;
}
-55
View File
@@ -1,55 +0,0 @@
/*
ISC License
Copyright (c) 2020, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "config_statfsignore.hpp"
#include "ef.hpp"
#include "errno.hpp"
template<>
std::string
StatFSIgnore::to_string() const
{
switch(_data)
{
case StatFSIgnore::ENUM::NONE:
return "none";
case StatFSIgnore::ENUM::RO:
return "ro";
case StatFSIgnore::ENUM::NC:
return "nc";
}
return "invalid";
}
template<>
int
StatFSIgnore::from_string(const std::string &s_)
{
if(s_ == "none")
_data = StatFSIgnore::ENUM::NONE;
ef(s_ == "ro")
_data = StatFSIgnore::ENUM::RO;
ef(s_ == "nc")
_data = StatFSIgnore::ENUM::NC;
else
return -EINVAL;
return 0;
}
+13 -1
View File
@@ -16,6 +16,8 @@
#pragma once
#include "fs_path.hpp"
#include <string>
@@ -27,6 +29,16 @@ public:
{
}
FH(const gfs::path &fusepath_)
: fusepath(fusepath_)
{
}
FH(const std::string &fusepath_)
: fusepath(fusepath_)
{
}
public:
std::string fusepath;
gfs::path fusepath;
};
+14 -2
View File
@@ -18,8 +18,6 @@
#include "fh.hpp"
#include <string>
class FileInfo : public FH
{
@@ -31,6 +29,20 @@ public:
{
}
FileInfo(const int fd_,
const std::string &fusepath_)
: FH(fusepath_),
fd(fd_)
{
}
FileInfo(const int fd_,
const gfs::path &fusepath_)
: FH(fusepath_),
fd(fd_)
{
}
public:
int fd;
};
+7 -10
View File
@@ -1,7 +1,7 @@
/*
ISC License
Copyright (c) 2020, Antonio SJ Musumeci <trapexit@spawn.link>
Copyright (c) 2022, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
@@ -18,13 +18,10 @@
#pragma once
#include "enum.hpp"
#include "toml.hpp"
enum class StatFSEnum
{
BASE,
FULL
};
typedef Enum<StatFSEnum> StatFS;
class FromTOML
{
public:
virtual void operator=(const toml::value &) = 0;
};
+13
View File
@@ -18,9 +18,12 @@
#include "fs_lgetxattr.hpp"
#include "fs_path.hpp"
#include "ghc/filesystem.hpp"
#include <string>
namespace gfs = ghc::filesystem;
const char POSIX_ACL_DEFAULT_XATTR[] = "system.posix_acl_default";
@@ -40,5 +43,15 @@ namespace fs
return (rv != -1);
}
int
dir_has_defaults(const gfs::path &fullpath_)
{
int rv;
rv = fs::lgetxattr(fullpath_.parent_path(),POSIX_ACL_DEFAULT_XATTR,NULL,0);
return rv;
}
}
}
+5
View File
@@ -18,6 +18,8 @@
#pragma once
#include "ghc/filesystem.hpp"
#include <string>
@@ -27,5 +29,8 @@ namespace fs
{
bool
dir_has_defaults(const std::string &fullpath);
int
dir_has_defaults(const ghc::filesystem::path &fullpath);
}
}
+3 -3
View File
@@ -16,7 +16,7 @@
#pragma once
#include <string>
#include "ghc/filesystem.hpp"
namespace fs
@@ -25,7 +25,7 @@ namespace fs
{
int copy(const int fdin,
const int fdout);
int copy(const std::string &from,
const std::string &to);
int copy(const ghc::filesystem::path &from,
const ghc::filesystem::path &to);
}
}
+40 -45
View File
@@ -18,14 +18,13 @@
#include "fs_close.hpp"
#include "fs_open.hpp"
#include "fs_ioctl.hpp"
#include <string>
#include "ghc/filesystem.hpp"
#include <fcntl.h>
#include <linux/fs.h>
using std::string;
namespace gfs = ghc::filesystem;
namespace fs
{
@@ -33,38 +32,36 @@ namespace fs
{
static
int
get_fs_ioc_flags(const int fd,
int &flags)
get_fs_ioc_flags(const int fd_,
int *flags_)
{
int rv;
rv = fs::ioctl(fd,FS_IOC_GETFLAGS,(void*)&flags);
if((rv == -1) && (errno == EINVAL))
errno = ENOTSUP;
rv = fs::ioctl(fd_,FS_IOC_GETFLAGS,(void*)flags_);
if(rv == -EINVAL)
rv = -ENOTSUP;
return rv;
}
static
int
get_fs_ioc_flags(const string &file,
int &flags)
get_fs_ioc_flags(const gfs::path &file_,
int *flags_)
{
int fd;
int rv;
const int openflags = O_RDONLY|O_NONBLOCK;
fd = fs::open(file,openflags);
if(fd == -1)
return -1;
fd = fs::open(file_,openflags);
if(fd < 0)
return fd;
rv = get_fs_ioc_flags(fd,flags);
if(rv == -1)
rv = get_fs_ioc_flags(fd,flags_);
if(rv < 0)
{
int error = errno;
fs::close(fd);
errno = error;
return -1;
return rv;
}
return fs::close(fd);
@@ -72,69 +69,67 @@ namespace fs
static
int
set_fs_ioc_flags(const int fd,
const int flags)
set_fs_ioc_flags(const int fd_,
const int flags_)
{
int rv;
rv = fs::ioctl(fd,FS_IOC_SETFLAGS,(void*)&flags);
if((rv == -1) && (errno == EINVAL))
errno = ENOTSUP;
rv = fs::ioctl(fd_,FS_IOC_SETFLAGS,(void*)&flags_);
if(rv == -EINVAL)
rv = -ENOTSUP;
return rv;
}
static
int
set_fs_ioc_flags(const string &file,
const int flags)
set_fs_ioc_flags(const gfs::path &file_,
const int flags_)
{
int fd;
int rv;
const int openflags = O_RDONLY|O_NONBLOCK;
fd = fs::open(file,openflags);
if(fd == -1)
return -1;
fd = fs::open(file_,openflags);
if(fd < 0)
return fd;
rv = set_fs_ioc_flags(fd,flags);
if(rv == -1)
rv = set_fs_ioc_flags(fd,flags_);
if(rv < 0)
{
int error = errno;
fs::close(fd);
errno = error;
return -1;
return rv;
}
return fs::close(fd);
}
int
copy(const int fdin,
const int fdout)
copy(const int fdin_,
const int fdout_)
{
int rv;
int flags;
rv = get_fs_ioc_flags(fdin,flags);
if(rv == -1)
return -1;
rv = get_fs_ioc_flags(fdin_,&flags);
if(rv < 0)
return rv;
return set_fs_ioc_flags(fdout,flags);
return set_fs_ioc_flags(fdout_,flags);
}
int
copy(const string &from,
const string &to)
copy(const gfs::path &from_,
const gfs::path &to_)
{
int rv;
int flags;
rv = get_fs_ioc_flags(from,flags);
if(rv == -1)
return -1;
rv = get_fs_ioc_flags(from_,&flags);
if(rv < 0)
return rv;
return set_fs_ioc_flags(to,flags);
return set_fs_ioc_flags(to_,flags);
}
}
}
+154 -101
View File
@@ -25,10 +25,13 @@
#include "fs_xattr.hpp"
#include "ugid.hpp"
#include "ghc/filesystem.hpp"
#include <string>
using std::string;
namespace gfs = ghc::filesystem;
namespace l
{
@@ -38,10 +41,10 @@ namespace l
{
switch(err_)
{
case ENOTTY:
case ENOTSUP:
case -ENOTTY:
case -ENOTSUP:
#if ENOTSUP != EOPNOTSUPP
case EOPNOTSUPP:
case -EOPNOTSUPP:
#endif
return true;
}
@@ -50,111 +53,161 @@ namespace l
}
}
namespace fs
/*
Attempts to clone a path.
The directories which already exist are left alone.
The new directories have metadata set to match the original if
possible. Optionally ignore errors on metadata copies.
*/
int
fs::clonepath(const string &fromsrc_,
const string &tosrc_,
const char *relative_,
const bool return_metadata_errors_)
{
/*
Attempts to clone a path.
The directories which already exist are left alone.
The new directories have metadata set to match the original if
possible. Optionally ignore errors on metadata copies.
*/
int
clonepath(const string &fromsrc_,
const string &tosrc_,
const char *relative_,
const bool return_metadata_errors_)
{
int rv;
struct stat st;
string topath;
string frompath;
string dirname;
if((relative_ == NULL) || (relative_[0] == '\0'))
return 0;
dirname = fs::path::dirname(relative_);
if(dirname != "/")
{
rv = fs::clonepath(fromsrc_,tosrc_,dirname,return_metadata_errors_);
if(rv == -1)
return -1;
}
frompath = fs::path::make(fromsrc_,relative_);
rv = fs::lstat(frompath,&st);
if(rv == -1)
return -1;
else if(!S_ISDIR(st.st_mode))
return (errno=ENOTDIR,-1);
topath = fs::path::make(tosrc_,relative_);
rv = fs::mkdir(topath,st.st_mode);
if(rv == -1)
{
if(errno == EEXIST)
return 0;
else
return -1;
}
// it may not support it... it's fine...
rv = fs::attr::copy(frompath,topath);
if(return_metadata_errors_ && (rv == -1) && !l::ignorable_error(errno))
return -1;
// it may not support it... it's fine...
rv = fs::xattr::copy(frompath,topath);
if(return_metadata_errors_ && (rv == -1) && !l::ignorable_error(errno))
return -1;
rv = fs::lchown_check_on_error(topath,st);
if(return_metadata_errors_ && (rv == -1))
return -1;
rv = fs::lutimens(topath,st);
if(return_metadata_errors_ && (rv == -1))
return -1;
int rv;
struct stat st;
string topath;
string frompath;
string dirname;
if((relative_ == NULL) || (relative_[0] == '\0'))
return 0;
}
int
clonepath(const string &from_,
const string &to_,
const string &relative_,
const bool return_metadata_errors_)
{
return fs::clonepath(from_,
to_,
relative_.c_str(),
return_metadata_errors_);
}
int
clonepath_as_root(const string &from_,
const string &to_,
const char *relative_,
const bool return_metadata_errors_)
{
if((relative_ == NULL) || (relative_[0] == '\0'))
return 0;
if(from_ == to_)
return 0;
dirname = fs::path::dirname(relative_);
if(dirname != "/")
{
const ugid::SetRootGuard ugidGuard;
return fs::clonepath(from_,to_,relative_,return_metadata_errors_);
rv = fs::clonepath(fromsrc_,tosrc_,dirname,return_metadata_errors_);
if(rv == -1)
return -1;
}
}
int
clonepath_as_root(const string &from_,
const string &to_,
const string &relative_,
const bool return_metadata_errors_)
frompath = fs::path::make(fromsrc_,relative_);
rv = fs::lstat(frompath,&st);
if(rv == -1)
return -1;
else if(!S_ISDIR(st.st_mode))
return (errno=ENOTDIR,-1);
topath = fs::path::make(tosrc_,relative_);
rv = fs::mkdir(topath,st.st_mode);
if(rv == -1)
{
if(errno == EEXIST)
return 0;
else
return -1;
}
// it may not support it... it's fine...
rv = fs::attr::copy(frompath,topath);
if(return_metadata_errors_ && (rv == -1) && !l::ignorable_error(errno))
return -1;
// it may not support it... it's fine...
rv = fs::xattr::copy(frompath,topath);
if(return_metadata_errors_ && (rv == -1) && !l::ignorable_error(errno))
return -1;
rv = fs::lchown_check_on_error(topath,st);
if(return_metadata_errors_ && (rv == -1))
return -1;
rv = fs::lutimens(topath,st);
if(return_metadata_errors_ && (rv == -1))
return -1;
return 0;
}
int
fs::clonepath(const gfs::path &fromsrc_,
const gfs::path &tosrc_,
const gfs::path &relative_)
{
int rv;
struct stat st;
gfs::path topath;
gfs::path frompath;
if(relative_.empty())
return 0;
if(!relative_.parent_path().empty())
{
rv = fs::clonepath(fromsrc_,tosrc_,relative_.parent_path());
if(rv < 0)
return rv;
}
frompath = fromsrc_ / relative_;
rv = fs::lstat(frompath,&st);
if(rv < 0)
return rv;
else if(!S_ISDIR(st.st_mode))
return -ENOTDIR;
topath = tosrc_ / relative_;
rv = fs::mkdir(topath,st.st_mode);
if(rv == -EEXIST)
return 0;
else if(rv < 0)
return rv;
// it may not support it... it's fine...
fs::attr::copy(frompath,topath);
fs::xattr::copy(frompath,topath);
fs::lchown_check_on_error(topath,st);
fs::lutimens(topath,st);
return 0;
}
int
fs::clonepath(const string &from_,
const string &to_,
const string &relative_,
const bool return_metadata_errors_)
{
return fs::clonepath(from_,
to_,
relative_.c_str(),
return_metadata_errors_);
}
int
fs::clonepath_as_root(const string &from_,
const string &to_,
const char *relative_,
const bool return_metadata_errors_)
{
if((relative_ == NULL) || (relative_[0] == '\0'))
return 0;
if(from_ == to_)
return 0;
{
return fs::clonepath_as_root(from_,to_,relative_.c_str(),return_metadata_errors_);
const ugid::SetRootGuard ugidGuard;
return fs::clonepath(from_,to_,relative_,return_metadata_errors_);
}
}
int
fs::clonepath_as_root(const string &from_,
const string &to_,
const string &relative_,
const bool return_metadata_errors_)
{
return fs::clonepath_as_root(from_,to_,relative_.c_str(),return_metadata_errors_);
}
int
fs::clonepath_as_root(const gfs::path &from_,
const gfs::path &to_,
const gfs::path &relative_)
{
const ugid::SetRootGuard ugidGuard;
return fs::clonepath(from_,to_,relative_);
}
+9
View File
@@ -16,6 +16,8 @@
#pragma once
#include "ghc/filesystem.hpp"
#include <string>
@@ -30,6 +32,10 @@ namespace fs
const std::string &relative,
const bool return_metadata_errors = false);
int clonepath(const ghc::filesystem::path &fromsrc,
const ghc::filesystem::path &tosrc,
const ghc::filesystem::path &relative);
int clonepath_as_root(const std::string &from,
const std::string &to,
const char *relative,
@@ -38,4 +44,7 @@ namespace fs
const std::string &to,
const std::string &relative,
const bool return_metadata_errors = false);
int clonepath_as_root(const ghc::filesystem::path &from,
const ghc::filesystem::path &to,
const ghc::filesystem::path &relative);
}
@@ -1,7 +1,7 @@
/*
ISC License
Copyright (c) 2020, Antonio SJ Musumeci <trapexit@spawn.link>
Copyright (c) 2022, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
@@ -16,41 +16,34 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "config_moveonenospc.hpp"
#include "ef.hpp"
#include "errno.hpp"
#include "from_string.hpp"
#include "fs_clonepath_branches.hpp"
#include "ugid.hpp"
#include "fs_clonepath.hpp"
namespace gfs = ghc::filesystem;
int
MoveOnENOSPC::from_string(const std::string &s_)
fs::clonepath_as_root(const Branches &branches_,
const gfs::path &to_,
const gfs::path &relative_)
{
int rv;
std::string s;
Policy::CreateImpl *tmp;
const ugid::SetRootGuard ugidGuard;
rv = str::from(s_,&enabled);
if((rv == 0) && (enabled == true))
s = "mfs";
ef(rv != 0)
s = s_;
else
return 0;
for(const auto &branch_group : branches_)
{
for(const auto &branch : branch_group)
{
rv = fs::clonepath(branch.path,to_,relative_);
if(rv == -ENOENT)
continue;
tmp = Policies::Create::find(s);
if(tmp == NULL)
return -EINVAL;
return rv;
}
}
policy = tmp;
enabled = true;
return 0;
}
std::string
MoveOnENOSPC::to_string(void) const
{
if(enabled)
return policy.name();
return "false";
return -ENOENT;
}
@@ -1,7 +1,7 @@
/*
ISC License
Copyright (c) 2021, Antonio SJ Musumeci <trapexit@spawn.link>
Copyright (c) 2022, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
@@ -18,14 +18,14 @@
#pragma once
#include "tofrom_string.hpp"
#include "branches.hpp"
#include "fs_path.hpp"
class LogMetrics : public ToFromString
namespace fs
{
public:
LogMetrics(const bool);
public:
std::string to_string(void) const final;
int from_string(const std::string &) final;
};
int
clonepath_as_root(const Branches &branches_,
const gfs::path &to_,
const gfs::path &relative_);
}
+5 -1
View File
@@ -28,6 +28,10 @@ namespace fs
int
close(const int fd_)
{
return ::close(fd_);
int rv;
rv = ::close(fd_);
return ((rv == -1) ? -errno : 0);
}
}
+12
View File
@@ -21,6 +21,8 @@
#include "fs_lstat.hpp"
#include "fs_path.hpp"
#include "ghc/filesystem.hpp"
#include <string>
@@ -49,6 +51,16 @@ namespace fs
return fs::exists(path_,&st);
}
static
inline
bool
exists(const ghc::filesystem::path &path_)
{
struct stat st;
return fs::exists(path_.c_str(),&st);
}
static
inline
bool
+6 -2
View File
@@ -34,9 +34,13 @@ namespace fs
const size_t size_)
{
#ifdef USE_XATTR
return ::flistxattr(fd_,list_,size_);
int rv;
rv = ::flistxattr(fd_,list_,size_);
return ((rv == -1) ? -errno : rv);
#else
return (errno=ENOTSUP,-1);
return -ENOTSUP;
#endif
}
}
+30 -13
View File
@@ -14,6 +14,8 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "fs_glob.hpp"
#include <glob.h>
#include <cstdint>
@@ -23,22 +25,37 @@
using std::string;
using std::vector;
namespace gfs = ghc::filesystem;
namespace fs
void
fs::glob(const string &pattern_,
vector<string> *strs_)
{
void
glob(const string &pattern_,
vector<string> *strs_)
{
int flags;
glob_t gbuf = {0};
int flags;
glob_t gbuf = {0};
flags = GLOB_NOCHECK;
::glob(pattern_.c_str(),flags,NULL,&gbuf);
flags = GLOB_NOCHECK;
::glob(pattern_.c_str(),flags,NULL,&gbuf);
for(size_t i = 0; i < gbuf.gl_pathc; i++)
strs_->push_back(gbuf.gl_pathv[i]);
for(size_t i = 0; i < gbuf.gl_pathc; i++)
strs_->push_back(gbuf.gl_pathv[i]);
::globfree(&gbuf);
}
::globfree(&gbuf);
}
void
fs::glob(const string &pattern_,
vector<gfs::path> *paths_)
{
int flags;
glob_t gbuf = {0};
flags = GLOB_NOCHECK;
::glob(pattern_.c_str(),flags,NULL,&gbuf);
for(size_t i = 0; i < gbuf.gl_pathc; i++)
paths_->push_back(gbuf.gl_pathv[i]);
::globfree(&gbuf);
}
+6
View File
@@ -16,6 +16,8 @@
#pragma once
#include "ghc/filesystem.hpp"
#include <string>
#include <vector>
@@ -25,4 +27,8 @@ namespace fs
void
glob(const std::string &pattern,
std::vector<std::string> *strs);
void
glob(const std::string &pattern,
std::vector<ghc::filesystem::path> *paths);
}
+15 -3
View File
@@ -29,7 +29,11 @@ namespace fs
ioctl(const int fd_,
const unsigned long request_)
{
return ::ioctl(fd_,request_);
int rv;
rv = ::ioctl(fd_,request_);
return ((rv == -1) ? -errno : rv);
}
static
@@ -39,7 +43,11 @@ namespace fs
const unsigned long request_,
void *data_)
{
return ::ioctl(fd_,request_,data_);
int rv;
rv = ::ioctl(fd_,request_,data_);
return ((rv == -1) ? -errno : rv);
}
static
@@ -49,6 +57,10 @@ namespace fs
const unsigned long request_,
const int int_)
{
return ::ioctl(fd_,request_,int_);
int rv;
rv = ::ioctl(fd_,request_,int_);
return ((rv == -1) ? -errno : rv);
}
}
+19 -2
View File
@@ -20,10 +20,14 @@
#include "fs_lstat.hpp"
#include "ghc/filesystem.hpp"
#include <string>
#include <errno.h>
#include <sys/stat.h>
#define MODE_BITS (S_ISUID|S_ISGID|S_ISVTX|S_IRWXU|S_IRWXG|S_IRWXO)
@@ -35,11 +39,15 @@ namespace fs
lchmod(const char *pathname_,
const mode_t mode_)
{
int rv;
#if defined __linux__
return ::chmod(pathname_,mode_);
rv = ::chmod(pathname_,mode_);
#else
return ::lchmod(pathname_,mode_);
rv = ::lchmod(pathname_,mode_);
#endif
return ((rv == -1) ? -errno : 0);
}
static
@@ -51,6 +59,15 @@ namespace fs
return fs::lchmod(pathname_.c_str(),mode_);
}
static
inline
int
lchmod(const ghc::filesystem::path &pathname_,
const mode_t mode_)
{
return fs::lchmod(pathname_.native(),mode_);
}
static
inline
int
+38 -5
View File
@@ -19,6 +19,7 @@
#pragma once
#include "errno.hpp"
#include "ghc/filesystem.hpp"
#include "xattr.hpp"
#include <string>
@@ -37,12 +38,16 @@ namespace fs
const size_t size_)
{
#ifdef USE_XATTR
return ::lgetxattr(path_,
attrname_,
value_,
size_);
int rv;
rv = ::lgetxattr(path_,
attrname_,
value_,
size_);
return ((rv == -1) ? -errno : rv);
#else
return (errno=ENOTSUP,-1);
return -ENOTSUP;
#endif
}
@@ -60,6 +65,34 @@ namespace fs
size_);
}
static
inline
int
lgetxattr(const ghc::filesystem::path &path_,
const char *attrname_,
void *value_,
const size_t size_)
{
return fs::lgetxattr(path_.c_str(),
attrname_,
value_,
size_);
}
static
inline
int
lgetxattr(const ghc::filesystem::path &path_,
const std::string &attrname_,
void *value_,
const size_t size_)
{
return fs::lgetxattr(path_.c_str(),
attrname_.c_str(),
value_,
size_);
}
static
inline
int
+28 -2
View File
@@ -18,20 +18,46 @@
#pragma once
#include "ghc/filesystem.hpp"
#include <string>
#include <errno.h>
#include <unistd.h>
namespace fs
{
static
inline
int
link(const char *oldpath_,
const char *newpath_)
{
int rv;
rv = ::link(oldpath_,newpath_);
return ((rv == -1) ? -errno : rv);
}
static
inline
int
link(const std::string &oldpath_,
const std::string &newpath_)
{
return ::link(oldpath_.c_str(),
newpath_.c_str());
return fs::link(oldpath_.c_str(),
newpath_.c_str());
}
static
inline
int
link(const ghc::filesystem::path &oldpath_,
const ghc::filesystem::path &newpath_)
{
return fs::link(oldpath_.c_str(),
newpath_.c_str());
}
}
+15 -6
View File
@@ -19,6 +19,7 @@
#pragma once
#include "errno.hpp"
#include "ghc/filesystem.hpp"
#include "xattr.hpp"
#include <string>
@@ -36,19 +37,27 @@ namespace fs
const size_t size_)
{
#ifdef USE_XATTR
return ::llistxattr(path_,list_,size_);
int rv;
rv = ::llistxattr(path_,list_,size_);
return ((rv == -1) ? -errno : rv);
#else
return (errno=ENOTSUP,-1);
return -ENOTSUP;
#endif
}
static
inline
int
llistxattr(const std::string &path_,
char *list_,
const size_t size_)
llistxattr(const ghc::filesystem::path &path_,
char *list_,
const size_t size_)
{
return fs::llistxattr(path_.c_str(),list_,size_);
return fs::llistxattr(path_.c_str(),
list_,
size_);
}
}
+2
View File
@@ -21,6 +21,8 @@
#include "errno.hpp"
#include "xattr.hpp"
#include <string>
#include <sys/types.h>
+18 -12
View File
@@ -21,6 +21,8 @@
#include "errno.hpp"
#include "xattr.hpp"
#include "ghc/filesystem.hpp"
#include <string>
#include <sys/types.h>
@@ -38,27 +40,31 @@ namespace fs
const int flags_)
{
#ifdef USE_XATTR
return ::lsetxattr(path_,
name_,
value_,
size_,
flags_);
int rv;
rv = ::lsetxattr(path_,
name_,
value_,
size_,
flags_);
return ((rv == -1) ? -errno : rv);
#else
return (errno=ENOTSUP,-1);
return -ENOTSUP;
#endif
}
static
inline
int
lsetxattr(const std::string &path_,
const std::string &name_,
const void *value_,
const size_t size_,
const int flags_)
lsetxattr(const ghc::filesystem::path &path_,
const char *name_,
const void *value_,
const size_t size_,
const int flags_)
{
return fs::lsetxattr(path_.c_str(),
name_.c_str(),
name_,
value_,
size_,
flags_);
+16 -1
View File
@@ -18,6 +18,8 @@
#pragma once
#include "ghc/filesystem.hpp"
#include <string>
#include <sys/stat.h>
@@ -33,7 +35,11 @@ namespace fs
lstat(const char *path_,
struct stat *st_)
{
return ::lstat(path_,st_);
int rv;
rv = ::lstat(path_,st_);
return ((rv == -1) ? -errno : 0);
}
static
@@ -44,4 +50,13 @@ namespace fs
{
return fs::lstat(path_.c_str(),st_);
}
static
inline
int
lstat(const ghc::filesystem::path &path_,
struct stat *st_)
{
return fs::lstat(path_.c_str(),st_);
}
}
+6 -4
View File
@@ -21,14 +21,16 @@
#include "fs_utimensat.hpp"
#include "fs_stat_utils.hpp"
#include "ghc/filesystem.hpp"
namespace fs
{
static
inline
int
lutimens(const std::string &path_,
const struct timespec ts_[2])
lutimens(const ghc::filesystem::path &path_,
const struct timespec ts_[2])
{
return fs::utimensat(AT_FDCWD,path_,ts_,AT_SYMLINK_NOFOLLOW);
}
@@ -36,8 +38,8 @@ namespace fs
static
inline
int
lutimens(const std::string &path_,
const struct stat &st_)
lutimens(const ghc::filesystem::path &path_,
const struct stat &st_)
{
struct timespec ts[2];
+5 -1
View File
@@ -34,7 +34,11 @@ namespace fs
mkdir(const char *path_,
const mode_t mode_)
{
return ::mkdir(path_,mode_);
int rv;
rv = ::mkdir(path_,mode_);
return ((rv == -1) ? -errno : 0);
}
static
+10 -11
View File
@@ -17,22 +17,21 @@
#pragma once
#include "branches.hpp"
#include "policy.hpp"
#include <string>
namespace fs
{
int
movefile(const Policy::Create &policy,
const Branches::CPtr &branches,
const std::string &fusepath,
int *origfd);
// int
// movefile(const Policy::Create &policy,
// const Branches::CPtr &branches,
// const std::string &fusepath,
// int *origfd);
int
movefile_as_root(const Policy::Create &policy,
const Branches::CPtr &branches,
const std::string &fusepath,
int *origfd);
// int
// movefile_as_root(const Policy::Create &policy,
// const Branches::CPtr &branches,
// const std::string &fusepath,
// int *origfd);
}
+27 -2
View File
@@ -18,8 +18,11 @@
#pragma once
#include "ghc/filesystem.hpp"
#include <string>
#include <errno.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
@@ -33,7 +36,13 @@ namespace fs
open(const char *path_,
const int flags_)
{
return ::open(path_,flags_);
int rv;
rv = ::open(path_,flags_);
if(rv == -1)
return -errno;
return rv;
}
static
@@ -43,7 +52,23 @@ namespace fs
const int flags_,
const mode_t mode_)
{
return ::open(path_,flags_,mode_);
int rv;
rv = ::open(path_,flags_,mode_);
if(rv == -1)
return -errno;
return rv;
}
static
inline
int
open(const ghc::filesystem::path &path_,
const int flags_,
const mode_t mode_)
{
return fs::open(path_.c_str(),flags_,mode_);
}
static
+4 -1
View File
@@ -1,5 +1,5 @@
/*
Copyright (c) 2016, Antonio SJ Musumeci <trapexit@spawn.link>
Copyright (c) 2022, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
@@ -19,6 +19,9 @@
#include <string>
#include <vector>
#include "ghc/filesystem.hpp"
namespace gfs = ghc::filesystem;
namespace fs
{
+20 -4
View File
@@ -18,6 +18,8 @@
#pragma once
#include "ghc/filesystem.hpp"
#include <string>
#include <unistd.h>
@@ -28,10 +30,24 @@ namespace fs
static
inline
int
readlink(const std::string &path_,
char *buf_,
const size_t bufsiz_)
readlink(const char *pathname_,
char *buf_,
const size_t bufsiz_)
{
return ::readlink(path_.c_str(),buf_,bufsiz_);
int rv;
rv = ::readlink(pathname_,buf_,bufsiz_);
return ((rv == -1) ? -errno : rv);
}
static
inline
int
readlink(const ghc::filesystem::path &pathname_,
char *buf_,
const size_t bufsiz_)
{
return fs::readlink(pathname_.c_str(),buf_,bufsiz_);
}
}
+18 -3
View File
@@ -18,6 +18,8 @@
#pragma once
#include "ghc/filesystem.hpp"
#include <string>
#include <unistd.h>
@@ -31,7 +33,11 @@ namespace fs
symlink(const char *target_,
const char *linkpath_)
{
return ::symlink(target_,linkpath_);
int rv;
rv = ::symlink(target_,linkpath_);
return ((rv == -1) ? -errno : rv);
}
static
@@ -40,7 +46,7 @@ namespace fs
symlink(const std::string &target_,
const std::string &linkpath_)
{
return ::symlink(target_.c_str(),linkpath_.c_str());
return fs::symlink(target_.c_str(),linkpath_.c_str());
}
static
@@ -49,6 +55,15 @@ namespace fs
symlink(const char *target_,
const std::string &linkpath_)
{
return ::symlink(target_,linkpath_.c_str());
return fs::symlink(target_,linkpath_.c_str());
}
static
inline
int
symlink(const char *target_,
const ghc::filesystem::path &linkpath_)
{
return fs::symlink(target_,linkpath_.c_str());
}
}
+16 -1
View File
@@ -18,6 +18,8 @@
#pragma once
#include "errno.hpp"
#include <string>
#include <sys/types.h>
@@ -32,7 +34,11 @@ namespace fs
truncate(const char *path_,
const off_t length_)
{
return ::truncate(path_,length_);
int rv;
rv = ::truncate(path_,length_);
return ((rv == -1) ? -errno : rv);
}
static
@@ -43,4 +49,13 @@ namespace fs
{
return fs::truncate(path_.c_str(),length_);
}
static
inline
int
truncate(const ghc::filesystem::path &path_,
const off_t length_)
{
return fs::truncate(path_.c_str(),length_);
}
}
+15 -1
View File
@@ -18,6 +18,8 @@
#pragma once
#include "ghc/filesystem.hpp"
#include <string>
#include <unistd.h>
@@ -30,7 +32,11 @@ namespace fs
int
unlink(const char *path_)
{
return ::unlink(path_);
int rv;
rv = ::unlink(path_);
return ((rv == -1) ? -errno : rv);
}
static
@@ -40,4 +46,12 @@ namespace fs
{
return fs::unlink(path_.c_str());
}
static
inline
int
unlink(const ghc::filesystem::path &path_)
{
return fs::unlink(path_.c_str());
}
}
+18 -1
View File
@@ -18,6 +18,8 @@
#pragma once
#include "ghc/filesystem.hpp"
#include <string>
#include <fcntl.h>
@@ -34,7 +36,11 @@ namespace fs
const struct timespec times_[2],
const int flags_)
{
return ::utimensat(dirfd_,pathname_,times_,flags_);
int rv;
rv = ::utimensat(dirfd_,pathname_,times_,flags_);
return ((rv == -1) ? -errno : rv);
}
static
@@ -47,4 +53,15 @@ namespace fs
{
return fs::utimensat(dirfd_,pathname_.c_str(),times_,flags_);
}
static
inline
int
utimensat(const int dirfd_,
const ghc::filesystem::path &pathname_,
const struct timespec times_[2],
const int flags_)
{
return fs::utimensat(dirfd_,pathname_.c_str(),times_,flags_);
}
}
+4 -4
View File
@@ -276,21 +276,21 @@ namespace fs
struct timeval *tvp;
if(l::flags_invalid(flags))
return (errno=EINVAL,-1);
return -EINVAL;
if(l::timespec_invalid(ts_))
return (errno=EINVAL,-1);
return -EINVAL;
if(l::should_ignore(ts_))
return 0;
rv = l::convert_timespec_to_timeval(dirfd_,path_,ts_,tv,&tvp,flags_);
if(rv == -1)
return -1;
return -errno;
if((flags_ & AT_SYMLINK_NOFOLLOW) == 0)
return fs::futimesat(dirfd_,path_,tvp);
if(l::can_call_lutimes(dirfd_,path_,flags))
return fs::lutimes(path_,tvp);
return (errno=ENOTSUP,-1);
return -ENOTSUP;
}
}
+18 -1
View File
@@ -18,6 +18,8 @@
#pragma once
#include "ghc/filesystem.hpp"
#include <string>
#include <fcntl.h>
@@ -34,7 +36,11 @@ namespace fs
const struct timespec times_[2],
const int flags_)
{
return ::utimensat(dirfd_,pathname_,times_,flags_);
int rv;
rv = ::utimensat(dirfd_,pathname_,times_,flags_);
return ((rv == -1) ? -errno : rv);
}
static
@@ -47,4 +53,15 @@ namespace fs
{
return fs::utimensat(dirfd_,pathname_.c_str(),times_,flags_);
}
static
inline
int
utimensat(const int dirfd_,
const ghc::filesystem::path &pathname_,
const struct timespec times_[2],
const int flags_)
{
return fs::utimensat(dirfd_,pathname_.c_str(),times_,flags_);
}
}
+55 -59
View File
@@ -14,6 +14,8 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "fs_xattr.hpp"
#include "errno.hpp"
#include "fs_close.hpp"
#include "fs_fgetxattr.hpp"
@@ -24,6 +26,7 @@
#include "fs_lremovexattr.hpp"
#include "fs_lsetxattr.hpp"
#include "fs_open.hpp"
#include "ghc/filesystem.hpp"
#include "str.hpp"
#include <map>
@@ -37,6 +40,8 @@ using std::map;
using std::istringstream;
namespace gfs = ghc::filesystem;
namespace fs
{
namespace xattr
@@ -47,9 +52,8 @@ namespace fs
{
ssize_t rv;
rv = -1;
errno = ERANGE;
while((rv == -1) && (errno == ERANGE))
rv = -ERANGE;
while(rv == -ERANGE)
{
rv = fs::flistxattr(fd_,NULL,0);
if(rv <= 0)
@@ -64,14 +68,13 @@ namespace fs
}
int
list(const string &path_,
vector<char> *attrs_)
list(const gfs::path &path_,
vector<char> *attrs_)
{
ssize_t rv;
rv = -1;
errno = ERANGE;
while((rv == -1) && (errno == ERANGE))
rv = -ERANGE;
while(rv == -ERANGE)
{
rv = fs::llistxattr(path_,NULL,0);
if(rv <= 0)
@@ -93,7 +96,7 @@ namespace fs
vector<char> attrs;
rv = fs::xattr::list(fd_,&attrs);
if(rv != -1)
if(rv > 0)
{
string tmp(attrs.begin(),attrs.end());
str::split(tmp,'\0',attrvector_);
@@ -103,14 +106,14 @@ namespace fs
}
int
list(const string &path_,
vector<string> *attrvector_)
list(const gfs::path &path_,
vector<string> *attrvector_)
{
int rv;
vector<char> attrs;
rv = fs::xattr::list(path_,&attrs);
if(rv != -1)
if(rv > 0)
{
string tmp(attrs.begin(),attrs.end());
str::split(tmp,'\0',attrvector_);
@@ -127,21 +130,21 @@ namespace fs
vector<char> attrs;
rv = fs::xattr::list(fd_,&attrs);
if(rv != -1)
if(rv > 0)
*attrstr_ = string(attrs.begin(),attrs.end());
return rv;
}
int
list(const string &path_,
string *attrstr_)
list(const gfs::path &path_,
string *attrstr_)
{
int rv;
vector<char> attrs;
rv = fs::xattr::list(path_,&attrs);
if(rv != -1)
if(rv > 0)
*attrstr_ = string(attrs.begin(),attrs.end());
return rv;
@@ -154,9 +157,8 @@ namespace fs
{
ssize_t rv;
rv = -1;
errno = ERANGE;
while((rv == -1) && (errno == ERANGE))
rv = -ERANGE;
while(rv == -ERANGE)
{
rv = fs::fgetxattr(fd_,attr_,NULL,0);
if(rv <= 0)
@@ -171,15 +173,14 @@ namespace fs
}
int
get(const string &path_,
const string &attr_,
vector<char> *value_)
get(const gfs::path &path_,
const string &attr_,
vector<char> *value_)
{
ssize_t rv;
rv = -1;
errno = ERANGE;
while((rv == -1) && (errno == ERANGE))
rv = -ERANGE;
while(rv == -ERANGE)
{
rv = fs::lgetxattr(path_,attr_,NULL,0);
if(rv <= 0)
@@ -201,23 +202,23 @@ namespace fs
int rv;
vector<char> tmpvalue;
rv = get(fd_,attr_,&tmpvalue);
if(rv != -1)
rv = fs::xattr::get(fd_,attr_,&tmpvalue);
if(rv > 0)
*value_ = string(tmpvalue.begin(),tmpvalue.end());
return rv;
}
int
get(const string &path_,
const string &attr_,
string *value_)
get(const gfs::path &path_,
const string &attr_,
string *value_)
{
int rv;
vector<char> tmpvalue;
rv = fs::xattr::get(path_,attr_,&tmpvalue);
if(rv != -1)
if(rv > 0)
*value_ = string(tmpvalue.begin(),tmpvalue.end());
return rv;
@@ -231,8 +232,8 @@ namespace fs
string attrstr;
rv = fs::xattr::list(fd_,&attrstr);
if(rv == -1)
return -1;
if(rv <= 0)
return rv;
{
string key;
@@ -243,7 +244,7 @@ namespace fs
string value;
rv = fs::xattr::get(fd_,key,&value);
if(rv != -1)
if(rv > 0)
(*attrs_)[key] = value;
}
}
@@ -252,15 +253,15 @@ namespace fs
}
int
get(const string &path_,
get(const gfs::path &path_,
map<string,string> *attrs_)
{
int rv;
string attrstr;
rv = fs::xattr::list(path_,&attrstr);
if(rv == -1)
return -1;
if(rv <= 0)
return rv;
{
string key;
@@ -271,7 +272,7 @@ namespace fs
string value;
rv = fs::xattr::get(path_,key,&value);
if(rv != -1)
if(rv > 0)
(*attrs_)[key] = value;
}
}
@@ -293,13 +294,13 @@ namespace fs
}
int
set(const string &path_,
const string &key_,
const string &value_,
const int flags_)
set(const gfs::path &path_,
const string &key_,
const string &value_,
const int flags_)
{
return fs::lsetxattr(path_,
key_,
key_.c_str(),
value_.data(),
value_.size(),
flags_);
@@ -309,28 +310,23 @@ namespace fs
set(const int fd_,
const map<string,string> &attrs_)
{
int rv;
for(map<string,string>::const_iterator
i = attrs_.begin(), ei = attrs_.end(); i != ei; ++i)
for(const auto &kv : attrs_)
{
rv = fs::xattr::set(fd_,i->first,i->second,0);
if(rv == -1)
return -1;
fs::xattr::set(fd_,kv.first,kv.second,0);
}
return 0;
}
int
set(const string &path_,
set(const gfs::path &path_,
const map<string,string> &attrs_)
{
int fd;
fd = fs::open(path_,O_RDONLY|O_NONBLOCK);
if(fd == -1)
return -1;
if(fd < 0)
return fd;
fs::xattr::set(fd,attrs_);
@@ -345,22 +341,22 @@ namespace fs
map<string,string> attrs;
rv = fs::xattr::get(fdin_,&attrs);
if(rv == -1)
return -1;
if(rv < 0)
return rv;
return fs::xattr::set(fdout_,attrs);
}
int
copy(const string &from_,
const string &to_)
copy(const gfs::path &from_,
const gfs::path &to_)
{
int rv;
map<string,string> attrs;
rv = fs::xattr::get(from_,&attrs);
if(rv == -1)
return -1;
if(rv < 0)
return rv;
return fs::xattr::set(to_,attrs);
}
+28 -31
View File
@@ -16,6 +16,8 @@
#pragma once
#include "ghc/filesystem.hpp"
#include <string>
#include <vector>
#include <map>
@@ -25,43 +27,38 @@ namespace fs
{
namespace xattr
{
using std::string;
using std::vector;
using std::map;
int list(const ghc::filesystem::path &path,
std::vector<char> *attrs);
int list(const ghc::filesystem::path &path,
std::string *attrs);
int list(const ghc::filesystem::path &path,
std::vector<std::string> *attrs);
int get(const ghc::filesystem::path &path,
const std::string &attr,
std::vector<char> *value);
int get(const ghc::filesystem::path &path,
const std::string &attr,
std::string *value);
int list(const string &path,
vector<char> *attrs);
int list(const string &path,
string *attrs);
int list(const string &path,
vector<string> *attrs);
int get(const ghc::filesystem::path &path,
std::map<std::string,std::string> *attrs);
int get(const string &path,
const string &attr,
vector<char> *value);
int get(const string &path,
const string &attr,
string *value);
int set(const ghc::filesystem::path &path,
const std::string &key,
const std::string &value,
const int flags);
int set(const int fd,
const std::string &key,
const std::string &value,
const int flags);
int get(const string &path,
map<string,string> *attrs);
int set(const string &path,
const string &key,
const string &value,
const int flags);
int set(const int fd,
const string &key,
const string &value,
const int flags);
int set(const string &path,
const map<string,string> &attrs);
int set(const ghc::filesystem::path &path,
const std::map<std::string,std::string> &attrs);
int copy(const int fdin,
const int fdout);
int copy(const string &from,
const string &to);
int copy(const ghc::filesystem::path &from,
const ghc::filesystem::path &to);
}
}
-62
View File
@@ -1,62 +0,0 @@
/*
ISC License
Copyright (c) 2019, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "func.hpp"
int
Func::Base::Action::from_string(const std::string &policyname_)
{
policy = Policies::Action::find(policyname_);
return 0;
}
std::string
Func::Base::Action::to_string(void) const
{
return policy.name();
}
int
Func::Base::Create::from_string(const std::string &policyname_)
{
policy = Policies::Create::find(policyname_);
return 0;
}
std::string
Func::Base::Create::to_string(void) const
{
return policy.name();
}
int
Func::Base::Search::from_string(const std::string &policyname_)
{
policy = Policies::Search::find(policyname_);
return 0;
}
std::string
Func::Base::Search::to_string(void) const
{
return policy.name();
}
-184
View File
@@ -1,184 +0,0 @@
/*
ISC License
Copyright (c) 2019, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#pragma once
#include "policy.hpp"
#include "policies.hpp"
#include "tofrom_string.hpp"
#include <string>
namespace Func
{
namespace Base
{
class Action : public ToFromString
{
public:
Action(Policy::ActionImpl *policy_)
: policy(policy_)
{}
public:
int from_string(const std::string &s) final;
std::string to_string() const final;
public:
Policy::Action policy;
};
class Create : public ToFromString
{
public:
Create(Policy::CreateImpl *policy_)
: policy(policy_)
{}
public:
int from_string(const std::string &s) final;
std::string to_string() const final;
public:
Policy::Create policy;
};
class Search : public ToFromString
{
public:
Search(Policy::SearchImpl *policy_)
: policy(policy_)
{}
public:
int from_string(const std::string &s) final;
std::string to_string() const final;
public:
Policy::Search policy;
};
class ActionDefault : public Action
{
public:
ActionDefault()
: Func::Base::Action(&Policies::Action::epall)
{
}
};
class CreateDefault : public Create
{
public:
CreateDefault()
: Func::Base::Create(&Policies::Create::epmfs)
{
}
};
class SearchDefault : public Search
{
public:
SearchDefault()
: Func::Base::Search(&Policies::Search::ff)
{
}
};
}
class Access final : public Base::SearchDefault
{
};
class Chmod final : public Base::ActionDefault
{
};
class Chown final : public Base::ActionDefault
{
};
class Create final : public Base::CreateDefault
{
};
class GetAttr final : public Base::SearchDefault
{
};
class GetXAttr final : public Base::SearchDefault
{
};
class Link final : public Base::ActionDefault
{
};
class ListXAttr final : public Base::SearchDefault
{
};
class Mkdir final : public Base::CreateDefault
{
};
class Mknod final : public Base::CreateDefault
{
};
class Open final : public Base::SearchDefault
{
};
class Readlink final : public Base::SearchDefault
{
};
class RemoveXAttr final : public Base::ActionDefault
{
};
class Rename final : public Base::ActionDefault
{
};
class Rmdir final : public Base::ActionDefault
{
};
class SetXAttr final : public Base::ActionDefault
{
};
class Symlink final : public Base::CreateDefault
{
};
class Truncate final : public Base::ActionDefault
{
};
class Unlink final : public Base::ActionDefault
{
};
class Utimens final : public Base::ActionDefault
{
};
}
-46
View File
@@ -1,46 +0,0 @@
/*
ISC License
Copyright (c) 2019, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#pragma once
#include "func.hpp"
struct Funcs
{
Func::Access access;
Func::Chmod chmod;
Func::Chown chown;
Func::Create create;
Func::GetAttr getattr;
Func::GetXAttr getxattr;
Func::Link link;
Func::ListXAttr listxattr;
Func::Mkdir mkdir;
Func::Mknod mknod;
Func::Open open;
Func::Readlink readlink;
Func::RemoveXAttr removexattr;
Func::Rename rename;
Func::Rmdir rmdir;
Func::SetXAttr setxattr;
Func::Symlink symlink;
Func::Truncate truncate;
Func::Unlink unlink;
Func::Utimens utimens;
};
+6 -40
View File
@@ -14,57 +14,23 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "config.hpp"
#include "errno.hpp"
#include "fs_eaccess.hpp"
#include "fs_path.hpp"
#include "state.hpp"
#include "ugid.hpp"
#include <string>
#include <vector>
using std::string;
using std::vector;
#include "fuse.h"
namespace l
{
static
int
access(const Policy::Search &searchFunc_,
const Branches &branches_,
const char *fusepath_,
const int mask_)
{
int rv;
string fullpath;
StrVec basepaths;
rv = searchFunc_(branches_,fusepath_,&basepaths);
if(rv == -1)
return -errno;
fullpath = fs::path::make(basepaths[0],fusepath_);
rv = fs::eaccess(fullpath,mask_);
return ((rv == -1) ? -errno : 0);
}
}
namespace FUSE
namespace FUSE::ACCESS
{
int
access(const char *fusepath_,
int mask_)
int mode_)
{
Config::Read cfg;
State s;
const fuse_context *fc = fuse_get_context();
const ugid::Set ugid(fc->uid,fc->gid);
return l::access(cfg->func.access.policy,
cfg->branches,
fusepath_,
mask_);
return s->access(&fusepath_[1],mode_);
}
}
+1 -2
View File
@@ -16,8 +16,7 @@
#pragma once
namespace FUSE
namespace FUSE::ACCESS
{
int
access(const char *fusepath,
+46
View File
@@ -0,0 +1,46 @@
/*
ISC License
Copyright (c) 2022, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#pragma once
#include "fuse_access_policy_base.hpp"
#include "fuse_access_policy_factory.hpp"
namespace FUSE::ACCESS
{
class Policy
{
public:
Policy(const toml::value &toml_)
{
_access = POLICY::factory(toml_);
}
public:
int
operator()(const gfs::path &fusepath_,
const int mask_)
{
return (*_access)(fusepath_,mask_);
}
private:
POLICY::Base::Ptr _access;
};
}
+37
View File
@@ -0,0 +1,37 @@
/*
ISC License
Copyright (c) 2022, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#pragma once
#include "fs_path.hpp"
#include <memory>
namespace FUSE::ACCESS::POLICY
{
class Base
{
public:
typedef std::shared_ptr<Base> Ptr;
public:
virtual int operator()(const gfs::path &fusepath,
const int mask) = 0;
};
}
+38
View File
@@ -0,0 +1,38 @@
/*
ISC License
Copyright (c) 2022, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "fuse_access_policy_factory.hpp"
#include "fuse_access_policy_ff.hpp"
#include <stdexcept>
namespace FUSE::ACCESS::POLICY
{
Base::Ptr
factory(const toml::value &toml_)
{
std::string str;
str = toml::find_or(toml_,"func","access","policy","ff");
if(str == "ff")
return std::make_shared<FF>(toml_);
throw std::runtime_error("access");
}
}
+30
View File
@@ -0,0 +1,30 @@
/*
ISC License
Copyright (c) 2022, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#pragma once
#include "fuse_access_policy_base.hpp"
#include "toml.hpp"
namespace FUSE::ACCESS::POLICY
{
Base::Ptr
factory(const toml::value &);
}
+52
View File
@@ -0,0 +1,52 @@
/*
ISC License
Copyright (c) 2022, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "fuse_access_policy_ff.hpp"
#include "fs_eaccess.hpp"
FUSE::ACCESS::POLICY::FF::FF(const toml::value &toml_)
: _branches(toml_)
{
}
int
FUSE::ACCESS::POLICY::FF::operator()(const gfs::path &fusepath_,
const int mode_)
{
int rv;
gfs::path fullpath;
for(const auto &branch_group : _branches)
{
for(const auto &branch : branch_group)
{
fullpath = branch.path / fusepath_;
rv = fs::eaccess(fullpath,mode_);
if(rv != 0)
continue;
return 0;
}
}
return -errno;
}
+40
View File
@@ -0,0 +1,40 @@
/*
ISC License
Copyright (c) 2022, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#pragma once
#include "fuse_access_policy_base.hpp"
#include "branches.hpp"
namespace FUSE::ACCESS::POLICY
{
class FF : public Base
{
public:
FF(const toml::value &);
public:
int operator()(const gfs::path &fusepath,
const int mode) final;
private:
Branches _branches;
};
}
+9 -1
View File
@@ -16,6 +16,8 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "toml.hpp"
#include "errno.hpp"
#include <cstdint>
@@ -23,8 +25,14 @@
#include <stddef.h>
namespace FUSE
namespace FUSE::BMAP
{
int
config(const toml::value &cfg_)
{
return 0;
}
int
bmap(const char *fusepath_,
size_t blocksize_,
+6 -1
View File
@@ -18,10 +18,15 @@
#pragma once
#include "toml.hpp"
#include "fuse.h"
namespace FUSE
namespace FUSE::BMAP
{
int
config(const toml::value &cfg);
int
bmap(const char *fusepath,
size_t blocksize,
+5 -100
View File
@@ -14,119 +14,24 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "config.hpp"
#include "errno.hpp"
#include "fs_lchmod.hpp"
#include "fs_path.hpp"
#include "policy_rv.hpp"
#include "state.hpp"
#include "ugid.hpp"
#include "fuse.h"
#include <string>
#include <string.h>
using std::string;
namespace l
{
static
int
get_error(const PolicyRV &prv_,
const string &basepath_)
{
for(int i = 0, ei = prv_.success.size(); i < ei; i++)
{
if(prv_.success[i].basepath == basepath_)
return prv_.success[i].rv;
}
for(int i = 0, ei = prv_.error.size(); i < ei; i++)
{
if(prv_.error[i].basepath == basepath_)
return prv_.error[i].rv;
}
return 0;
}
static
void
chmod_loop_core(const string &basepath_,
const char *fusepath_,
const mode_t mode_,
PolicyRV *prv_)
{
string fullpath;
fullpath = fs::path::make(basepath_,fusepath_);
errno = 0;
fs::lchmod(fullpath,mode_);
prv_->insert(errno,basepath_);
}
static
void
chmod_loop(const StrVec &basepaths_,
const char *fusepath_,
const mode_t mode_,
PolicyRV *prv_)
{
for(size_t i = 0, ei = basepaths_.size(); i != ei; i++)
{
l::chmod_loop_core(basepaths_[i],fusepath_,mode_,prv_);
}
}
static
int
chmod(const Policy::Action &actionFunc_,
const Policy::Search &searchFunc_,
const Branches &branches_,
const char *fusepath_,
const mode_t mode_)
{
int rv;
PolicyRV prv;
StrVec basepaths;
rv = actionFunc_(branches_,fusepath_,&basepaths);
if(rv == -1)
return -errno;
l::chmod_loop(basepaths,fusepath_,mode_,&prv);
if(prv.error.empty())
return 0;
if(prv.success.empty())
return prv.error[0].rv;
basepaths.clear();
rv = searchFunc_(branches_,fusepath_,&basepaths);
if(rv == -1)
return -errno;
return l::get_error(prv,basepaths[0]);
}
}
namespace FUSE
namespace FUSE::CHMOD
{
int
chmod(const char *fusepath_,
mode_t mode_)
{
Config::Read cfg;
State s;
gfs::path fusepath(&fusepath_[1]);
const fuse_context *fc = fuse_get_context();
const ugid::Set ugid(fc->uid,fc->gid);
return l::chmod(cfg->func.chmod.policy,
cfg->func.getattr.policy,
cfg->branches,
fusepath_,
mode_);
return s->chmod(fusepath,mode_);
}
}
+7 -1
View File
@@ -16,9 +16,15 @@
#pragma once
#include "toml.hpp"
namespace FUSE
#include <sys/stat.h>
namespace FUSE::CHMOD
{
int
config(const toml::value &cfg);
int
chmod(const char *fusepath,
mode_t mode);
+54
View File
@@ -0,0 +1,54 @@
/*
ISC License
Copyright (c) 2022, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#pragma once
namespace FUSE::CHMOD
{
class Err
{
public:
Err()
: _err(0)
{
}
public:
inline
Err&
operator=(const int err_)
{
if(_err != 0)
{
if(_err == -ENOENT)
_err = err_;
}
return *this;
}
public:
inline
operator int()
{
return _err;
}
private:
int _err;
};
}
+48
View File
@@ -0,0 +1,48 @@
/*
ISC License
Copyright (c) 2022, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#pragma once
#include "fuse_chmod_policy_base.hpp"
#include "fuse_chmod_policy_factory.hpp"
#include <sys/stat.h>
namespace FUSE::CHMOD
{
class Policy
{
public:
Policy(const toml::value &toml_)
{
_chmod = POLICY::factory(toml_);
}
public:
int
operator()(const gfs::path &fusepath_,
const mode_t mode_)
{
return (*_chmod)(fusepath_,mode_);
}
private:
POLICY::Base::Ptr _chmod;
};
}
+49
View File
@@ -0,0 +1,49 @@
/*
ISC License
Copyright (c) 2022, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "fuse_chmod_policy_all.hpp"
#include "fuse_chmod_err.hpp"
#include "fs_lchmod.hpp"
FUSE::CHMOD::POLICY::ALL::ALL(const toml::value &toml_)
: _branches(toml_)
{
}
int
FUSE::CHMOD::POLICY::ALL::operator()(const gfs::path &fusepath_,
const mode_t mode_)
{
Err rv;
gfs::path fullpath;
for(const auto &branch_group : _branches)
{
for(const auto &branch : branch_group)
{
fullpath = branch.path / fusepath_;
rv = fs::lchmod(fullpath,mode_);
}
}
return rv;
}
+40
View File
@@ -0,0 +1,40 @@
/*
ISC License
Copyright (c) 2022, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#pragma once
#include "fuse_chmod_policy_base.hpp"
#include "branches.hpp"
namespace FUSE::CHMOD::POLICY
{
class ALL : public Base
{
public:
ALL(const toml::value &);
public:
int operator()(const gfs::path &fusepath,
const mode_t mode) final;
private:
Branches _branches;
};
}
+37
View File
@@ -0,0 +1,37 @@
/*
ISC License
Copyright (c) 2022, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#pragma once
#include "fs_path.hpp"
#include <memory>
namespace FUSE::CHMOD::POLICY
{
class Base
{
public:
typedef std::shared_ptr<Base> Ptr;
public:
virtual int operator()(const gfs::path &fusepath,
const mode_t mode) = 0;
};
}
+38
View File
@@ -0,0 +1,38 @@
/*
ISC License
Copyright (c) 2022, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "fuse_chmod_policy_factory.hpp"
#include "fuse_chmod_policy_all.hpp"
#include <stdexcept>
namespace FUSE::CHMOD::POLICY
{
Base::Ptr
factory(const toml::value &toml_)
{
std::string str;
str = toml::find_or(toml_,"func","chmod","policy","all");
if(str == "all")
return std::make_shared<ALL>(toml_);
throw std::runtime_error("chmod");
}
}
@@ -1,7 +1,7 @@
/*
ISC License
Copyright (c) 2020, Antonio SJ Musumeci <trapexit@spawn.link>
Copyright (c) 2022, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
@@ -18,13 +18,13 @@
#pragma once
#include "enum.hpp"
#include "fuse_chmod_policy_base.hpp"
enum class StatFSIgnoreEnum
{
NONE,
RO,
NC
};
#include "toml.hpp"
typedef Enum<StatFSIgnoreEnum> StatFSIgnore;
namespace FUSE::CHMOD::POLICY
{
Base::Ptr
factory(const toml::value &);
}
+6 -105
View File
@@ -1,5 +1,5 @@
/*
Copyright (c) 2016, Antonio SJ Musumeci <trapexit@spawn.link>
Copyright (c) 2022, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
@@ -14,124 +14,25 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "config.hpp"
#include "errno.hpp"
#include "fs_lchown.hpp"
#include "fs_path.hpp"
#include "policy_rv.hpp"
#include "state.hpp"
#include "ugid.hpp"
#include "fuse.h"
#include <string>
#include <vector>
using std::string;
using std::vector;
namespace l
{
static
int
get_error(const PolicyRV &prv_,
const string &basepath_)
{
for(int i = 0, ei = prv_.success.size(); i < ei; i++)
{
if(prv_.success[i].basepath == basepath_)
return prv_.success[i].rv;
}
for(int i = 0, ei = prv_.error.size(); i < ei; i++)
{
if(prv_.error[i].basepath == basepath_)
return prv_.error[i].rv;
}
return 0;
}
static
void
chown_loop_core(const string &basepath_,
const char *fusepath_,
const uid_t uid_,
const gid_t gid_,
PolicyRV *prv_)
{
string fullpath;
fullpath = fs::path::make(basepath_,fusepath_);
errno = 0;
fs::lchown(fullpath,uid_,gid_);
prv_->insert(errno,basepath_);
}
static
void
chown_loop(const vector<string> &basepaths_,
const char *fusepath_,
const uid_t uid_,
const gid_t gid_,
PolicyRV *prv_)
{
for(size_t i = 0, ei = basepaths_.size(); i != ei; i++)
{
l::chown_loop_core(basepaths_[i],fusepath_,uid_,gid_,prv_);
}
}
static
int
chown(const Policy::Action &actionFunc_,
const Policy::Search &searchFunc_,
const Branches &branches_,
const char *fusepath_,
const uid_t uid_,
const gid_t gid_)
{
int rv;
PolicyRV prv;
vector<string> basepaths;
rv = actionFunc_(branches_,fusepath_,&basepaths);
if(rv == -1)
return -errno;
l::chown_loop(basepaths,fusepath_,uid_,gid_,&prv);
if(prv.error.empty())
return 0;
if(prv.success.empty())
return prv.error[0].rv;
basepaths.clear();
rv = searchFunc_(branches_,fusepath_,&basepaths);
if(rv == -1)
return -errno;
return l::get_error(prv,basepaths[0]);
}
}
namespace FUSE
namespace FUSE::CHOWN
{
int
chown(const char *fusepath_,
uid_t uid_,
gid_t gid_)
{
Config::Read cfg;
State s;
gfs::path fusepath(&fusepath_[1]);
const fuse_context *fc = fuse_get_context();
const ugid::Set ugid(fc->uid,fc->gid);
return l::chown(cfg->func.chown.policy,
cfg->func.getattr.policy,
cfg->branches,
fusepath_,
uid_,
gid_);
return s->chown(fusepath,uid_,gid_);
}
}
+5 -1
View File
@@ -16,8 +16,12 @@
#pragma once
#include "toml.hpp"
namespace FUSE
#include <unistd.h>
namespace FUSE::CHOWN
{
int
chown(const char *fusepath,
+51
View File
@@ -0,0 +1,51 @@
/*
ISC License
Copyright (c) 2022, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#pragma once
namespace FUSE::CHOWN
{
class Err
{
public:
Err()
: _err(-ENOENT)
{
}
public:
inline
Err&
operator=(const int err_)
{
if(_err == -ENOENT)
_err = err_;
return *this;
}
public:
inline
operator int()
{
return _err;
}
private:
int _err;
};
}
+23 -25
View File
@@ -1,7 +1,7 @@
/*
ISC License
Copyright (c) 2020, Antonio SJ Musumeci <trapexit@spawn.link>
Copyright (c) 2022, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
@@ -18,34 +18,32 @@
#pragma once
#include <string>
#include <vector>
#include "fuse_chown_policy_base.hpp"
#include "fuse_chown_policy_factory.hpp"
struct PolicyRV
#include <sys/stat.h>
namespace FUSE::CHOWN
{
struct RV
class Policy
{
RV(const int rv_,
const std::string &basepath_)
: rv(rv_),
basepath(basepath_)
public:
Policy(const toml::value &toml_)
{
_chown = POLICY::factory(toml_);
}
int rv;
std::string basepath;
public:
int
operator()(const gfs::path &fusepath_,
const uid_t uid_,
const gid_t gid_)
{
return (*_chown)(fusepath_,uid_,gid_);
}
private:
POLICY::Base::Ptr _chown;
};
std::vector<RV> success;
std::vector<RV> error;
void
insert(const int err_,
const std::string &basepath_)
{
if(err_ == 0)
success.push_back(RV(err_,basepath_));
else
error.push_back(RV(-err_,basepath_));
}
};
}
+50
View File
@@ -0,0 +1,50 @@
/*
ISC License
Copyright (c) 2022, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "fuse_chown_policy_all.hpp"
#include "fuse_chown_err.hpp"
#include "fs_lchown.hpp"
FUSE::CHOWN::POLICY::ALL::ALL(const toml::value &toml_)
: _branches(toml_)
{
}
int
FUSE::CHOWN::POLICY::ALL::operator()(const gfs::path &fusepath_,
const uid_t uid_,
const gid_t gid_)
{
Err rv;
gfs::path fullpath;
for(const auto &branch_group : _branches)
{
for(const auto &branch : branch_group)
{
fullpath = branch.path / fusepath_;
rv = fs::lchown(fullpath,uid_,gid_);
}
}
return rv;
}
+41
View File
@@ -0,0 +1,41 @@
/*
ISC License
Copyright (c) 2022, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#pragma once
#include "fuse_chown_policy_base.hpp"
#include "branches.hpp"
namespace FUSE::CHOWN::POLICY
{
class ALL : public Base
{
public:
ALL(const toml::value &);
public:
int operator()(const gfs::path &fusepath,
const uid_t uid,
const gid_t gid) final;
private:
Branches _branches;
};
}
+40
View File
@@ -0,0 +1,40 @@
/*
ISC License
Copyright (c) 2022, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#pragma once
#include "fs_path.hpp"
#include <memory>
#include <unistd.h>
namespace FUSE::CHOWN::POLICY
{
class Base
{
public:
typedef std::shared_ptr<Base> Ptr;
public:
virtual int operator()(const gfs::path &fusepath,
const uid_t uid,
const gid_t gid) = 0;
};
}
+38
View File
@@ -0,0 +1,38 @@
/*
ISC License
Copyright (c) 2022, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "fuse_chown_policy_factory.hpp"
#include "fuse_chown_policy_all.hpp"
#include <stdexcept>
namespace FUSE::CHOWN::POLICY
{
Base::Ptr
factory(const toml::value &toml_)
{
std::string str;
str = toml::find_or(toml_,"func","chown","policy","all");
if(str == "all")
return std::make_shared<ALL>(toml_);
throw std::runtime_error("chown");
}
}
+30
View File
@@ -0,0 +1,30 @@
/*
ISC License
Copyright (c) 2022, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#pragma once
#include "fuse_chown_policy_base.hpp"
#include "toml.hpp"
namespace FUSE::CHOWN::POLICY
{
Base::Ptr
factory(const toml::value &);
}
+9 -1
View File
@@ -14,6 +14,8 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "toml.hpp"
#include "errno.hpp"
#include "fileinfo.hpp"
#include "fs_copy_file_range.hpp"
@@ -47,8 +49,14 @@ namespace l
}
}
namespace FUSE
namespace FUSE::COPY_FILE_RANGE
{
int
config(const toml::value &cfg_)
{
return 0;
}
ssize_t
copy_file_range(const fuse_file_info_t *ffi_in_,
off_t offset_in_,
+6 -1
View File
@@ -16,9 +16,14 @@
#pragma once
#include "toml.hpp"
namespace FUSE
namespace FUSE::COPY_FILE_RANGE
{
int
config(const toml::value &cfg);
ssize_t
copy_file_range(const fuse_file_info_t *ffi_in,
off_t offset_in,
+4 -160
View File
@@ -14,179 +14,23 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "config.hpp"
#include "errno.hpp"
#include "fileinfo.hpp"
#include "fs_acl.hpp"
#include "fs_clonepath.hpp"
#include "fs_open.hpp"
#include "fs_path.hpp"
#include "state.hpp"
#include "ugid.hpp"
#include "fuse.h"
#include <string>
#include <vector>
using std::string;
using std::vector;
namespace l
{
/*
The kernel expects being able to issue read requests when running
with writeback caching enabled so we must change O_WRONLY to
O_RDWR.
With writeback caching enabled the kernel handles O_APPEND. Could
be an issue if the underlying file changes out of band but that is
true of any caching.
*/
static
void
tweak_flags_writeback_cache(int *flags_)
{
if((*flags_ & O_ACCMODE) == O_WRONLY)
*flags_ = ((*flags_ & ~O_ACCMODE) | O_RDWR);
if(*flags_ & O_APPEND)
*flags_ &= ~O_APPEND;
}
static
void
config_to_ffi_flags(Config::Read &cfg_,
fuse_file_info_t *ffi_)
{
switch(cfg_->cache_files)
{
case CacheFiles::ENUM::LIBFUSE:
ffi_->direct_io = cfg_->direct_io;
ffi_->keep_cache = cfg_->kernel_cache;
ffi_->auto_cache = cfg_->auto_cache;
break;
case CacheFiles::ENUM::OFF:
ffi_->direct_io = 1;
ffi_->keep_cache = 0;
ffi_->auto_cache = 0;
break;
case CacheFiles::ENUM::PARTIAL:
ffi_->direct_io = 0;
ffi_->keep_cache = 0;
ffi_->auto_cache = 0;
break;
case CacheFiles::ENUM::FULL:
ffi_->direct_io = 0;
ffi_->keep_cache = 1;
ffi_->auto_cache = 0;
break;
case CacheFiles::ENUM::AUTO_FULL:
ffi_->direct_io = 0;
ffi_->keep_cache = 0;
ffi_->auto_cache = 1;
break;
}
}
static
int
create_core(const string &fullpath_,
mode_t mode_,
const mode_t umask_,
const int flags_)
{
if(!fs::acl::dir_has_defaults(fullpath_))
mode_ &= ~umask_;
return fs::open(fullpath_,flags_,mode_);
}
static
int
create_core(const string &createpath_,
const char *fusepath_,
const mode_t mode_,
const mode_t umask_,
const int flags_,
uint64_t *fh_)
{
int rv;
string fullpath;
fullpath = fs::path::make(createpath_,fusepath_);
rv = l::create_core(fullpath,mode_,umask_,flags_);
if(rv == -1)
return -errno;
*fh_ = reinterpret_cast<uint64_t>(new FileInfo(rv,fusepath_));
return 0;
}
static
int
create(const Policy::Search &searchFunc_,
const Policy::Create &createFunc_,
const Branches &branches_,
const char *fusepath_,
const mode_t mode_,
const mode_t umask_,
const int flags_,
uint64_t *fh_)
{
int rv;
string fullpath;
string fusedirpath;
StrVec createpaths;
StrVec existingpaths;
fusedirpath = fs::path::dirname(fusepath_);
rv = searchFunc_(branches_,fusedirpath,&existingpaths);
if(rv == -1)
return -errno;
rv = createFunc_(branches_,fusedirpath,&createpaths);
if(rv == -1)
return -errno;
rv = fs::clonepath_as_root(existingpaths[0],createpaths[0],fusedirpath);
if(rv == -1)
return -errno;
return l::create_core(createpaths[0],
fusepath_,
mode_,
umask_,
flags_,
fh_);
}
}
namespace FUSE
namespace FUSE::CREATE
{
int
create(const char *fusepath_,
mode_t mode_,
fuse_file_info_t *ffi_)
{
Config::Read cfg;
State s;
const fuse_context *fc = fuse_get_context();
const ugid::Set ugid(fc->uid,fc->gid);
l::config_to_ffi_flags(cfg,ffi_);
if(cfg->writeback_cache)
l::tweak_flags_writeback_cache(&ffi_->flags);
return l::create(cfg->func.getattr.policy,
cfg->func.create.policy,
cfg->branches,
fusepath_,
mode_,
fc->umask,
ffi_->flags,
&ffi_->fh);
return s->create(&fusepath_[1],mode_,fc->umask,ffi_);
}
}
+3 -1
View File
@@ -16,12 +16,14 @@
#pragma once
#include "toml.hpp"
#include "fuse.h"
#include <sys/types.h>
namespace FUSE
namespace FUSE::CREATE
{
int
create(const char *fusepath,
+48
View File
@@ -0,0 +1,48 @@
/*
ISC License
Copyright (c) 2022, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#pragma once
#include "fuse_create_policy_base.hpp"
#include "fuse_create_policy_factory.hpp"
namespace FUSE::CREATE
{
class Policy
{
public:
Policy(const toml::value &toml_)
{
_create = POLICY::factory(toml_);
}
public:
int
operator()(const gfs::path &fusepath_,
const mode_t mode_,
const mode_t umask_,
fuse_file_info_t *ffi_)
{
return (*_create)(fusepath_,mode_,umask_,ffi_);
}
private:
POLICY::Base::Ptr _create;
};
}
+41
View File
@@ -0,0 +1,41 @@
/*
ISC License
Copyright (c) 2022, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#pragma once
#include "fs_path.hpp"
#include "fuse.h"
#include <memory>
namespace FUSE::CREATE::POLICY
{
class Base
{
public:
typedef std::shared_ptr<Base> Ptr;
public:
virtual int operator()(const gfs::path &fusepath,
const mode_t mode,
const mode_t umask,
fuse_file_info_t *ffi) = 0;
};
}
+68
View File
@@ -0,0 +1,68 @@
/*
ISC License
Copyright (c) 2022, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "fuse_create_policy_epff.hpp"
#include "fileinfo.hpp"
#include "fs_acl.hpp"
#include "fs_open.hpp"
FUSE::CREATE::POLICY::EPFF::EPFF(const toml::value &toml_)
: _branches(toml_)
{
}
int
FUSE::CREATE::POLICY::EPFF::operator()(const gfs::path &fusepath_,
const mode_t mode_,
const mode_t umask_,
fuse_file_info_t *ffi_)
{
int rv;
mode_t mode;
gfs::path fullpath;
mode = mode_;
for(const auto &branch_group : _branches)
{
for(const auto &branch : branch_group)
{
fullpath = branch.path / fusepath_;
rv = fs::acl::dir_has_defaults(fullpath);
if(rv == -ENOENT)
continue;
if(rv >= 0)
mode &= umask_;
rv = fs::open(fullpath,ffi_->flags,mode);
if(rv == -ENOENT)
continue;
if(rv < 0)
return rv;
ffi_->fh = reinterpret_cast<uint64_t>(new FileInfo(rv,fusepath_));
return 0;
}
}
return -ENOENT;
}
+44
View File
@@ -0,0 +1,44 @@
/*
ISC License
Copyright (c) 2022, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#pragma once
#include "fuse_create_policy_base.hpp"
#include "branches.hpp"
#include "fs_path.hpp"
namespace FUSE::CREATE::POLICY
{
class EPFF : public Base
{
public:
EPFF(const toml::value &);
public:
int operator()(const gfs::path &fusepath,
const mode_t mode,
const mode_t umask,
fuse_file_info_t *ffi) final;
private:
Branches _branches;
};
}
+40
View File
@@ -0,0 +1,40 @@
/*
ISC License
Copyright (c) 2022, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "fuse_create_policy_factory.hpp"
#include "fuse_create_policy_ff.hpp"
#include "fuse_create_policy_epff.hpp"
#include <stdexcept>
namespace FUSE::CREATE::POLICY
{
Base::Ptr
factory(const toml::value &toml_)
{
std::string str;
str = toml::find_or(toml_,"func","create","policy","ff");
if(str == "ff")
return std::make_shared<FF>(toml_);
if(str == "epff")
return std::make_shared<EPFF>(toml_);
throw std::runtime_error("create");
}
}
+30
View File
@@ -0,0 +1,30 @@
/*
ISC License
Copyright (c) 2022, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#pragma once
#include "fuse_create_policy_base.hpp"
#include "toml.hpp"
namespace FUSE::CREATE::POLICY
{
Base::Ptr
factory(const toml::value &);
}
+86
View File
@@ -0,0 +1,86 @@
/*
ISC License
Copyright (c) 2022, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "fuse_create_policy_ff.hpp"
#include "fileinfo.hpp"
#include "fs_acl.hpp"
#include "fs_clonepath.hpp"
#include "fs_clonepath_branches.hpp"
#include "fs_open.hpp"
#include "ugid.hpp"
FUSE::CREATE::POLICY::FF::FF(const toml::value &toml_)
: _branches(toml_)
{
}
int
FUSE::CREATE::POLICY::FF::operator()(const gfs::path &fusepath_,
const mode_t mode_,
const mode_t umask_,
fuse_file_info_t *ffi_)
{
int rv;
mode_t mode;
gfs::path fullpath;
mode = mode_;
for(const auto &branch_group : _branches)
{
for(const auto &branch : branch_group)
{
fullpath = branch.path / fusepath_;
rv = fs::acl::dir_has_defaults(fullpath);
if(rv == -ENOENT)
{
rv = fs::clonepath_as_root(_branches,branch.path,fusepath_);
if(rv >= 0)
rv = fs::acl::dir_has_defaults(fullpath);
}
if(rv >= 0)
mode &= ~umask_;
rv = fs::open(fullpath,ffi_->flags,mode);
if(rv == -ENOENT)
{
rv = fs::clonepath_as_root(_branches,branch.path,fusepath_);
if(rv >= 0)
{
rv = fs::acl::dir_has_defaults(fullpath);
if(rv >= 0)
mode &= ~umask_;
rv = fs::open(fullpath,ffi_->flags,mode);
}
}
if(rv < 0)
return rv;
ffi_->fh = reinterpret_cast<uint64_t>(new FileInfo(rv,fusepath_));
return 0;
}
}
return -ENOENT;
}
+42
View File
@@ -0,0 +1,42 @@
/*
ISC License
Copyright (c) 2022, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#pragma once
#include "fuse_create_policy_base.hpp"
#include "branches.hpp"
namespace FUSE::CREATE::POLICY
{
class FF : public Base
{
public:
FF(const toml::value &);
public:
int operator()(const gfs::path &fusepath,
const mode_t mode,
const mode_t umask,
fuse_file_info_t *ffi) final;
private:
Branches2 _branches;
};
}
+1 -1
View File
@@ -14,7 +14,7 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
namespace FUSE
namespace FUSE::DESTROY
{
void
destroy(void)
+1 -1
View File
@@ -17,7 +17,7 @@
#pragma once
namespace FUSE
namespace FUSE::DESTROY
{
void
destroy(void);

Some files were not shown because too many files have changed in this diff Show More