"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "encfs/DirNode.cpp" between
encfs-1.9.4.tar.gz and encfs-1.9.5.tar.gz

About: EncFS is an encrypted virtual filesystem for Linux using the FUSE kernel module.

DirNode.cpp  (encfs-1.9.4):DirNode.cpp  (encfs-1.9.5)
skipping to change at line 55 skipping to change at line 55
using namespace std; using namespace std;
namespace encfs { namespace encfs {
class DirDeleter { class DirDeleter {
public: public:
void operator()(DIR *d) { ::closedir(d); } void operator()(DIR *d) { ::closedir(d); }
}; };
DirTraverse::DirTraverse(std::shared_ptr<DIR> _dirPtr, uint64_t _iv, DirTraverse::DirTraverse(std::shared_ptr<DIR> _dirPtr, uint64_t _iv,
std::shared_ptr<NameIO> _naming) std::shared_ptr<NameIO> _naming, bool _root)
: dir(std::move(_dirPtr)), iv(_iv), naming(std::move(_naming)) {} : dir(std::move(_dirPtr)), iv(_iv), naming(std::move(_naming)), root(_root)
{}
DirTraverse &DirTraverse::operator=(const DirTraverse &src) = default; DirTraverse &DirTraverse::operator=(const DirTraverse &src) = default;
DirTraverse::~DirTraverse() { DirTraverse::~DirTraverse() {
dir.reset(); dir.reset();
iv = 0; iv = 0;
naming.reset(); naming.reset();
root = false;
} }
static bool _nextName(struct dirent *&de, const std::shared_ptr<DIR> &dir, static bool _nextName(struct dirent *&de, const std::shared_ptr<DIR> &dir,
int *fileType, ino_t *inode) { int *fileType, ino_t *inode) {
de = ::readdir(dir.get()); de = ::readdir(dir.get());
if (de != nullptr) { if (de != nullptr) {
if (fileType != nullptr) { if (fileType != nullptr) {
#if defined(HAVE_DIRENT_D_TYPE) #if defined(HAVE_DIRENT_D_TYPE)
*fileType = de->d_type; *fileType = de->d_type;
skipping to change at line 93 skipping to change at line 94
} }
if (fileType != nullptr) { if (fileType != nullptr) {
*fileType = 0; *fileType = 0;
} }
return false; return false;
} }
std::string DirTraverse::nextPlaintextName(int *fileType, ino_t *inode) { std::string DirTraverse::nextPlaintextName(int *fileType, ino_t *inode) {
struct dirent *de = nullptr; struct dirent *de = nullptr;
while (_nextName(de, dir, fileType, inode)) { while (_nextName(de, dir, fileType, inode)) {
if (root && (strcmp(".encfs6.xml", de->d_name) == 0)) {
VLOG(1) << "skipping filename: " << de->d_name;
continue;
}
try { try {
uint64_t localIv = iv; uint64_t localIv = iv;
return naming->decodePath(de->d_name, &localIv); return naming->decodePath(de->d_name, &localIv);
} catch (encfs::Error &ex) { } catch (encfs::Error &ex) {
// .. .problem decoding, ignore it and continue on to next name.. // .. .problem decoding, ignore it and continue on to next name..
VLOG(1) << "error decoding filename: " << de->d_name; VLOG(1) << "error decoding filename: " << de->d_name;
} }
} }
return string(); return string();
} }
std::string DirTraverse::nextInvalid() { std::string DirTraverse::nextInvalid() {
struct dirent *de = nullptr; struct dirent *de = nullptr;
// find the first name which produces a decoding error... // find the first name which produces a decoding error...
while (_nextName(de, dir, (int *)nullptr, (ino_t *)nullptr)) { while (_nextName(de, dir, (int *)nullptr, (ino_t *)nullptr)) {
if (root && (strcmp(".encfs6.xml", de->d_name) == 0)) {
VLOG(1) << "skipping filename: " << de->d_name;
continue;
}
try { try {
uint64_t localIv = iv; uint64_t localIv = iv;
naming->decodePath(de->d_name, &localIv); naming->decodePath(de->d_name, &localIv);
continue; continue;
} catch (encfs::Error &ex) { } catch (encfs::Error &ex) {
return string(de->d_name); return string(de->d_name);
} }
} }
return string(); return string();
skipping to change at line 358 skipping to change at line 367
} }
} }
DirTraverse DirNode::openDir(const char *plaintextPath) { DirTraverse DirNode::openDir(const char *plaintextPath) {
string cyName = rootDir + naming->encodePath(plaintextPath); string cyName = rootDir + naming->encodePath(plaintextPath);
DIR *dir = ::opendir(cyName.c_str()); DIR *dir = ::opendir(cyName.c_str());
if (dir == nullptr) { if (dir == nullptr) {
int eno = errno; int eno = errno;
VLOG(1) << "opendir error " << strerror(eno); VLOG(1) << "opendir error " << strerror(eno);
return DirTraverse(shared_ptr<DIR>(), 0, std::shared_ptr<NameIO>()); return DirTraverse(shared_ptr<DIR>(), 0, std::shared_ptr<NameIO>(), false);
} }
std::shared_ptr<DIR> dp(dir, DirDeleter()); std::shared_ptr<DIR> dp(dir, DirDeleter());
uint64_t iv = 0; uint64_t iv = 0;
// if we're using chained IV mode, then compute the IV at this // if we're using chained IV mode, then compute the IV at this
// directory level.. // directory level..
try { try {
if (naming->getChainedNameIV()) { if (naming->getChainedNameIV()) {
naming->encodePath(plaintextPath, &iv); naming->encodePath(plaintextPath, &iv);
} }
} catch (encfs::Error &err) { } catch (encfs::Error &err) {
RLOG(ERROR) << "encode err: " << err.what(); RLOG(ERROR) << "encode err: " << err.what();
} }
return DirTraverse(dp, iv, naming); return DirTraverse(dp, iv, naming, (strlen(plaintextPath) == 1));
} }
bool DirNode::genRenameList(list<RenameEl> &renameList, const char *fromP, bool DirNode::genRenameList(list<RenameEl> &renameList, const char *fromP,
const char *toP) { const char *toP) {
uint64_t fromIV = 0, toIV = 0; uint64_t fromIV = 0, toIV = 0;
// compute the IV for both paths // compute the IV for both paths
string fromCPart = naming->encodePath(fromP, &fromIV); string fromCPart = naming->encodePath(fromP, &fromIV);
string toCPart = naming->encodePath(toP, &toIV); string toCPart = naming->encodePath(toP, &toIV);
skipping to change at line 593 skipping to change at line 602
res = ::rename(fromCName.c_str(), toCName.c_str()); res = ::rename(fromCName.c_str(), toCName.c_str());
if (res == -1) { if (res == -1) {
// undo // undo
res = -errno; res = -errno;
renameNode(toPlaintext, fromPlaintext, false); renameNode(toPlaintext, fromPlaintext, false);
if (renameOp) { if (renameOp) {
renameOp->undo(); renameOp->undo();
} }
} else if (preserve_mtime) { }
struct utimbuf ut; else {
ut.actime = st.st_atime; #ifdef __CYGWIN__
ut.modtime = st.st_mtime; // When renaming a file, Windows first opens it, renames it and then close
::utime(toCName.c_str(), &ut); s it
// We then must decrease the target openFiles count
// We could recreate the source so that close will not (silently) fails,
// however it will update modification time of the file, so break what we
do below.
// Let's simply warn in eraseNode().
if (!isDirectory(toCName.c_str())) {
std::shared_ptr<FileNode> toNode = findOrCreate(toPlaintext);
ctx->eraseNode(toPlaintext, toNode);
//ctx->putNode(fromPlaintext, toNode);
}
#endif
if (preserve_mtime) {
struct utimbuf ut;
ut.actime = st.st_atime;
ut.modtime = st.st_mtime;
::utime(toCName.c_str(), &ut);
}
} }
} catch (encfs::Error &err) { } catch (encfs::Error &err) {
// exception from renameNode, just show the error and continue.. // exception from renameNode, just show the error and continue..
RLOG(WARNING) << err.what(); RLOG(WARNING) << err.what();
res = -EIO; res = -EIO;
} }
if (res != 0) { if (res != 0) {
VLOG(1) << "rename failed: " << strerror(-res); VLOG(1) << "rename failed: " << strerror(-res);
} }
return res; return res;
} }
int DirNode::link(const char *from, const char *to) { int DirNode::link(const char *to, const char *from) {
Lock _lock(mutex); Lock _lock(mutex);
string fromCName = rootDir + naming->encodePath(from);
string toCName = rootDir + naming->encodePath(to); string toCName = rootDir + naming->encodePath(to);
string fromCName = rootDir + naming->encodePath(from);
rAssert(!fromCName.empty());
rAssert(!toCName.empty()); rAssert(!toCName.empty());
rAssert(!fromCName.empty());
VLOG(1) << "link " << fromCName << " -> " << toCName; VLOG(1) << "link " << fromCName << " -> " << toCName;
int res = -EPERM; int res = -EPERM;
if (fsConfig->config->externalIVChaining) { if (fsConfig->config->externalIVChaining) {
VLOG(1) << "hard links not supported with external IV chaining!"; VLOG(1) << "hard links not supported with external IV chaining!";
} else { } else {
res = ::link(fromCName.c_str(), toCName.c_str()); res = ::link(toCName.c_str(), fromCName.c_str());
if (res == -1) { if (res == -1) {
res = -errno; res = -errno;
} else { } else {
res = 0; res = 0;
} }
} }
return res; return res;
} }
skipping to change at line 733 skipping to change at line 757
} }
return std::shared_ptr<FileNode>(); return std::shared_ptr<FileNode>();
} }
int DirNode::unlink(const char *plaintextName) { int DirNode::unlink(const char *plaintextName) {
string cyName = naming->encodePath(plaintextName); string cyName = naming->encodePath(plaintextName);
VLOG(1) << "unlink " << cyName; VLOG(1) << "unlink " << cyName;
Lock _lock(mutex); Lock _lock(mutex);
int res = 0; // Windows does not allow deleting opened files, so no need to check
// There is this "issue" however : https://github.com/billziss-gh/winfsp/issues/
157
#ifndef __CYGWIN__
if ((ctx != nullptr) && ctx->lookupNode(plaintextName)) { if ((ctx != nullptr) && ctx->lookupNode(plaintextName)) {
// If FUSE is running with "hard_remove" option where it doesn't // If FUSE is running with "hard_remove" option where it doesn't
// hide open files for us, then we can't allow an unlink of an open // hide open files for us, then we can't allow an unlink of an open
// file.. // file..
RLOG(WARNING) << "Refusing to unlink open file: " << cyName RLOG(WARNING) << "Refusing to unlink open file: " << cyName
<< ", hard_remove option " << ", hard_remove option "
"is probably in effect"; "is probably in effect";
res = -EBUSY; return -EBUSY;
} else { }
string fullName = rootDir + cyName; #endif
res = ::unlink(fullName.c_str());
if (res == -1) { int res = 0;
res = -errno; string fullName = rootDir + cyName;
VLOG(1) << "unlink error: " << strerror(-res); res = ::unlink(fullName.c_str());
} if (res == -1) {
res = -errno;
VLOG(1) << "unlink error: " << strerror(-res);
} }
return res; return res;
} }
} // namespace encfs } // namespace encfs
 End of changes. 15 change blocks. 
22 lines changed or deleted 54 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)