aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/encoding.cc34
-rw-r--r--src/encoding.h6
-rw-r--r--src/operations.cc70
3 files changed, 63 insertions, 47 deletions
diff --git a/src/encoding.cc b/src/encoding.cc
index 620a821..3cd29a8 100644
--- a/src/encoding.cc
+++ b/src/encoding.cc
@@ -16,10 +16,13 @@
#include <array>
#include <cstdlib>
+#include <functional>
#include <ios>
#include <sstream>
#include <string>
+#include <glog/logging.h>
+
namespace scoville {
namespace {
@@ -47,12 +50,10 @@ char ReadHexAsAscii(std::istringstream* const in) {
bool IsVfatBadCharacter(const char c) noexcept {
return (0 <= c && c < 0x20) || c == '*' || c == '?' || c == '<' || c == '>' ||
- c == '|' || c == '"' || c == ':' || c == '/' || c == '\\';
+ c == '|' || c == '"' || c == ':' || c == '\\';
}
-} // namespace
-
-void Encode(std::istringstream* const in, std::ostringstream* const out) {
+void EncodeStream(std::istringstream* const in, std::ostringstream* const out) {
char c;
while (!in->get(c).eof()) {
if (IsVfatBadCharacter(c)) {
@@ -66,7 +67,7 @@ void Encode(std::istringstream* const in, std::ostringstream* const out) {
}
}
-void Decode(std::istringstream* const in, std::ostringstream* const out) {
+void DecodeStream(std::istringstream* const in, std::ostringstream* const out) {
char c;
while (!in->get(c).eof()) {
if (c == '%') {
@@ -82,4 +83,27 @@ void Decode(std::istringstream* const in, std::ostringstream* const out) {
}
}
+std::string TransformString(
+ std::function<void(std::istringstream*, std::ostringstream*)> f,
+ const std::string& in) {
+ std::istringstream in_stream(in);
+ std::ostringstream out_stream;
+ f(&in_stream, &out_stream);
+ return out_stream.str();
+}
+
+} // namespace
+
+std::string Encode(const std::string& in) {
+ const std::string result = TransformString(EncodeStream, in);
+ VLOG(1) << "Encode: \"" << in << "\" -> \"" << result << "\"";
+ return result;
+}
+
+std::string Decode(const std::string& in) {
+ const std::string result = TransformString(DecodeStream, in);
+ VLOG(1) << "Decode: \"" << in << "\" -> \"" << result << "\"";
+ return result;
+}
+
} // scoville
diff --git a/src/encoding.h b/src/encoding.h
index 717d421..d6e72ea 100644
--- a/src/encoding.h
+++ b/src/encoding.h
@@ -15,7 +15,7 @@
#ifndef ENCODING_H_
#define ENCODING_H_
-#include <sstream>
+#include <string>
#include <stdexcept>
namespace scoville {
@@ -30,9 +30,9 @@ class DecodingFailure : public std::logic_error {
using std::logic_error::logic_error;
};
-void Encode(std::istringstream*, std::ostringstream*);
+std::string Encode(const std::string&);
-void Decode(std::istringstream*, std::ostringstream*);
+std::string Decode(const std::string&);
} // scoville
diff --git a/src/operations.cc b/src/operations.cc
index cf53b05..8e2b008 100644
--- a/src/operations.cc
+++ b/src/operations.cc
@@ -37,6 +37,7 @@
#include <sys/types.h>
#include <time.h>
+#include "encoding.h"
#include "fuse.h"
#include "posix_extras.h"
@@ -51,7 +52,7 @@ mode_t DirectoryTypeToFileType(const unsigned char type) {
return static_cast<mode_t>(DTTOIF(type));
}
-std::string EncodePath(const std::string& path) {
+std::string MakeRelative(const std::string& path) {
if (path.at(0) != '/') {
throw std::system_error(ENOENT, std::system_category());
}
@@ -63,22 +64,22 @@ void* Initialize(fuse_conn_info*) noexcept { return nullptr; }
void Destroy(void*) noexcept {}
int Statfs(const char* const c_path, struct statvfs* const output) {
- const std::string path(c_path);
+ const std::string path(Encode(c_path));
if (path == "/") {
*output = root_->StatVFs();
} else {
*output =
- root_->OpenAt(EncodePath(path).c_str(), O_RDONLY | O_PATH).StatVFs();
+ root_->OpenAt(MakeRelative(path).c_str(), O_RDONLY | O_PATH).StatVFs();
}
return 0;
}
int Getattr(const char* const c_path, struct stat* output) {
- const std::string path(c_path);
+ const std::string path(Encode(c_path));
if (path == "/") {
*output = root_->Stat();
} else {
- *output = root_->LinkStatAt(EncodePath(path).c_str());
+ *output = root_->LinkStatAt(MakeRelative(path).c_str());
}
return 0;
}
@@ -90,12 +91,11 @@ int Fgetattr(const char*, struct stat* const output,
}
template <typename T>
-int OpenResource(const char* const c_path, const int flags,
+int OpenResource(const std::string& path, const int flags,
uint64_t* const handle, const mode_t mode = 0) {
try {
- const std::string path(c_path);
std::unique_ptr<T> t(
- new T(path == "/" ? *root_ : root_->OpenAt(EncodePath(path).c_str(),
+ new T(path == "/" ? *root_ : root_->OpenAt(MakeRelative(path).c_str(),
flags, mode)));
static_assert(sizeof(*handle) == sizeof(std::uintptr_t),
"FUSE file handles are a different size than pointers");
@@ -113,40 +113,41 @@ int ReleaseResource(const uint64_t handle) noexcept {
}
int Mknod(const char* const c_path, const mode_t mode, const dev_t dev) {
- const std::string path(c_path);
+ const std::string path(Encode(c_path));
if (path == "/") {
return -EISDIR;
} else {
- root_->MkNod(EncodePath(path).c_str(), mode, dev);
+ root_->MkNod(MakeRelative(path).c_str(), mode, dev);
return 0;
}
}
int Chmod(const char* const c_path, const mode_t mode) {
- const std::string path(c_path);
- root_->ChModAt(path == "/" ? "." : EncodePath(path).c_str(), mode);
+ const std::string path(Encode(c_path));
+ root_->ChModAt(path == "/" ? "." : MakeRelative(path).c_str(), mode);
return 0;
}
int Rename(const char* const c_old_path, const char* const c_new_path) {
- const std::string old_path(c_old_path);
- const std::string new_path(c_new_path);
+ const std::string old_path(Encode(c_old_path));
+ const std::string new_path(Encode(c_new_path));
if (old_path == "/" || new_path == "/") {
return -EINVAL;
} else {
- root_->RenameAt(EncodePath(old_path).c_str(), EncodePath(new_path).c_str());
+ root_->RenameAt(MakeRelative(old_path).c_str(),
+ MakeRelative(new_path).c_str());
return 0;
}
}
int Create(const char* const path, const mode_t mode,
fuse_file_info* const file_info) {
- return OpenResource<File>(path, file_info->flags | O_CREAT, &file_info->fh,
- mode);
+ return OpenResource<File>(Encode(path), file_info->flags | O_CREAT,
+ &file_info->fh, mode);
}
int Open(const char* const path, fuse_file_info* const file_info) {
- return OpenResource<File>(path, file_info->flags, &file_info->fh);
+ return OpenResource<File>(Encode(path), file_info->flags, &file_info->fh);
}
int Read(const char*, char* const buffer, const size_t bytes,
@@ -166,8 +167,8 @@ int Write(const char*, const char* const buffer, const size_t bytes,
}
int Utimens(const char* const c_path, const timespec times[2]) {
- const std::string path(c_path);
- root_->UTimeNs(path == "/" ? "." : EncodePath(path).c_str(), times[0],
+ const std::string path(Encode(c_path));
+ root_->UTimeNs(path == "/" ? "." : MakeRelative(path).c_str(), times[0],
times[1]);
return 0;
}
@@ -177,42 +178,33 @@ int Release(const char*, fuse_file_info* const file_info) {
}
int Unlink(const char* c_path) {
- const std::string path(c_path);
+ const std::string path(Encode(c_path));
if (path == "/") {
// Removing the root is probably a bad idea.
return -EPERM;
} else {
- root_->UnlinkAt(EncodePath(path).c_str());
+ root_->UnlinkAt(MakeRelative(path).c_str());
return 0;
}
}
-int Symlink(const char* const target, const char* const source) {
- root_->SymLinkAt(target, EncodePath(source).c_str());
- return 0;
-}
+int Symlink(const char*, const char*) { return -EPERM; }
-int Readlink(const char* const path, char* const output,
- const size_t output_size) {
- const std::string target = root_->ReadLinkAt(EncodePath(path).c_str());
- std::strncpy(output, target.c_str(), output_size);
- output[output_size - 1] = '\0';
- return 0;
-}
+int Readlink(const char*, char*, size_t) { return -EINVAL; }
int Mkdir(const char* const c_path, const mode_t mode) {
- const std::string path(c_path);
+ const std::string path(Encode(c_path));
if (path == "/") {
// They're asking to create the mount point. Huh?
return -EEXIST;
} else {
- root_->MkDir(EncodePath(path).c_str(), mode);
+ root_->MkDir(MakeRelative(path).c_str(), mode);
return 0;
}
}
int Opendir(const char* const path, fuse_file_info* const file_info) {
- return OpenResource<Directory>(path, O_DIRECTORY, &file_info->fh);
+ return OpenResource<Directory>(Encode(path), O_DIRECTORY, &file_info->fh);
}
int Readdir(const char*, void* const buffer, fuse_fill_dir_t filler,
@@ -232,7 +224,7 @@ int Readdir(const char*, void* const buffer, fuse_fill_dir_t filler,
stats.st_ino = entry->d_ino;
stats.st_mode = DirectoryTypeToFileType(entry->d_type);
const off_t next_offset = directory->offset();
- if (filler(buffer, entry->d_name, &stats, next_offset)) {
+ if (filler(buffer, Decode(entry->d_name).c_str(), &stats, next_offset)) {
break;
}
}
@@ -249,12 +241,12 @@ int Ftruncate(const char*, const off_t size, fuse_file_info* const file_info) {
}
int Rmdir(const char* c_path) {
- const std::string path(c_path);
+ const std::string path(Encode(c_path));
if (path == "/") {
// Removing the root is probably a bad idea.
return -EPERM;
} else {
- root_->RmDirAt(EncodePath(path).c_str());
+ root_->RmDirAt(MakeRelative(path).c_str());
return 0;
}
}