2013-01-29 04:07:54 +01:00
|
|
|
/*****************************************************************************
|
|
|
|
* Author: Valient Gough <vgough@pobox.com>
|
|
|
|
*
|
|
|
|
*****************************************************************************
|
|
|
|
* Copyright (c) 2007, Valient Gough
|
|
|
|
*
|
|
|
|
* This program is free software: you can redistribute it and/or modify it
|
|
|
|
* under the terms of the GNU Lesser General Public License as published by the
|
|
|
|
* Free Software Foundation, either version 3 of the License, or (at your
|
2013-10-20 00:35:26 +02:00
|
|
|
* option) any later version.
|
2013-01-29 04:07:54 +01:00
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
|
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
|
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
|
|
|
* for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Lesser General Public License
|
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
2013-03-05 07:36:32 +01:00
|
|
|
#include "fs/Context.h"
|
|
|
|
|
2013-01-29 04:07:54 +01:00
|
|
|
#include "base/Error.h"
|
|
|
|
#include "fs/FileNode.h"
|
|
|
|
#include "fs/FileUtils.h"
|
|
|
|
#include "fs/DirNode.h"
|
|
|
|
|
2013-03-05 07:29:58 +01:00
|
|
|
namespace encfs {
|
2013-01-29 04:07:54 +01:00
|
|
|
|
2013-10-20 00:35:26 +02:00
|
|
|
EncFS_Context::EncFS_Context() {
|
2013-03-05 07:36:32 +01:00
|
|
|
#ifdef CMAKE_USE_PTHREADS_INIT
|
2013-10-20 00:35:26 +02:00
|
|
|
pthread_cond_init(&wakeupCond, 0);
|
2013-03-05 07:36:32 +01:00
|
|
|
#endif
|
2013-01-29 04:07:54 +01:00
|
|
|
|
|
|
|
usageCount = 0;
|
|
|
|
}
|
|
|
|
|
2013-10-20 00:35:26 +02:00
|
|
|
EncFS_Context::~EncFS_Context() {
|
2013-03-05 07:36:32 +01:00
|
|
|
#ifdef CMAKE_USE_PTHREADS_INIT
|
2013-10-20 00:35:26 +02:00
|
|
|
pthread_cond_destroy(&wakeupCond);
|
2013-03-05 07:36:32 +01:00
|
|
|
#endif
|
2013-01-29 04:07:54 +01:00
|
|
|
|
|
|
|
// release all entries from map
|
|
|
|
openFiles.clear();
|
|
|
|
}
|
|
|
|
|
2013-10-20 00:35:26 +02:00
|
|
|
shared_ptr<DirNode> EncFS_Context::getRoot(int *errCode) {
|
2013-01-29 04:07:54 +01:00
|
|
|
shared_ptr<DirNode> ret;
|
2013-10-20 00:35:26 +02:00
|
|
|
do {
|
2013-01-29 04:07:54 +01:00
|
|
|
{
|
2013-10-20 00:35:26 +02:00
|
|
|
Lock lock(contextMutex);
|
2013-01-29 04:07:54 +01:00
|
|
|
ret = root;
|
|
|
|
++usageCount;
|
|
|
|
}
|
|
|
|
|
2013-10-20 00:35:26 +02:00
|
|
|
if (!ret) {
|
|
|
|
int res = remountFS(this);
|
|
|
|
if (res != 0) {
|
2013-01-29 04:07:54 +01:00
|
|
|
*errCode = res;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2013-10-20 00:35:26 +02:00
|
|
|
} while (!ret);
|
2013-01-29 04:07:54 +01:00
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2013-10-20 00:35:26 +02:00
|
|
|
void EncFS_Context::setRoot(const shared_ptr<DirNode> &r) {
|
|
|
|
Lock lock(contextMutex);
|
2013-01-29 04:07:54 +01:00
|
|
|
|
|
|
|
root = r;
|
2013-10-20 00:35:26 +02:00
|
|
|
if (r) rootCipherDir = r->rootDirectory();
|
2013-01-29 04:07:54 +01:00
|
|
|
}
|
|
|
|
|
2013-10-20 00:35:26 +02:00
|
|
|
bool EncFS_Context::isMounted() { return root; }
|
2013-01-29 04:07:54 +01:00
|
|
|
|
2013-10-20 00:35:26 +02:00
|
|
|
int EncFS_Context::getAndResetUsageCounter() {
|
|
|
|
Lock lock(contextMutex);
|
2013-01-29 04:07:54 +01:00
|
|
|
|
|
|
|
int count = usageCount;
|
|
|
|
usageCount = 0;
|
|
|
|
|
|
|
|
return count;
|
|
|
|
}
|
|
|
|
|
2013-10-20 00:35:26 +02:00
|
|
|
int EncFS_Context::openFileCount() const {
|
|
|
|
Lock lock(contextMutex);
|
2013-01-29 04:07:54 +01:00
|
|
|
|
|
|
|
return openFiles.size();
|
|
|
|
}
|
|
|
|
|
2013-10-20 00:35:26 +02:00
|
|
|
shared_ptr<FileNode> EncFS_Context::lookupNode(const char *path) {
|
|
|
|
Lock lock(contextMutex);
|
2013-01-29 04:07:54 +01:00
|
|
|
|
2013-10-20 00:35:26 +02:00
|
|
|
FileMap::iterator it = openFiles.find(std::string(path));
|
|
|
|
if (it != openFiles.end()) {
|
2013-01-29 04:07:54 +01:00
|
|
|
// all the items in the set point to the same node.. so just use the
|
|
|
|
// first
|
|
|
|
return (*it->second.begin())->node;
|
2013-10-20 00:35:26 +02:00
|
|
|
} else {
|
2013-01-29 04:07:54 +01:00
|
|
|
return shared_ptr<FileNode>();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-10-20 00:35:26 +02:00
|
|
|
void EncFS_Context::renameNode(const char *from, const char *to) {
|
|
|
|
Lock lock(contextMutex);
|
2013-01-29 04:07:54 +01:00
|
|
|
|
2013-10-20 00:35:26 +02:00
|
|
|
FileMap::iterator it = openFiles.find(std::string(from));
|
|
|
|
if (it != openFiles.end()) {
|
2013-01-29 04:07:54 +01:00
|
|
|
std::set<Placeholder *> val = it->second;
|
|
|
|
openFiles.erase(it);
|
2013-10-20 00:35:26 +02:00
|
|
|
openFiles[std::string(to)] = val;
|
2013-01-29 04:07:54 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-10-20 00:35:26 +02:00
|
|
|
shared_ptr<FileNode> EncFS_Context::getNode(void *pl) {
|
|
|
|
Placeholder *ph = (Placeholder *)pl;
|
2013-01-29 04:07:54 +01:00
|
|
|
return ph->node;
|
|
|
|
}
|
|
|
|
|
2013-10-20 00:35:26 +02:00
|
|
|
void *EncFS_Context::putNode(const char *path,
|
|
|
|
const shared_ptr<FileNode> &node) {
|
|
|
|
Lock lock(contextMutex);
|
|
|
|
Placeholder *pl = new Placeholder(node);
|
|
|
|
openFiles[std::string(path)].insert(pl);
|
2013-01-29 04:07:54 +01:00
|
|
|
|
|
|
|
return (void *)pl;
|
|
|
|
}
|
|
|
|
|
2013-10-20 00:35:26 +02:00
|
|
|
void EncFS_Context::eraseNode(const char *path, void *pl) {
|
|
|
|
Lock lock(contextMutex);
|
2013-01-29 04:07:54 +01:00
|
|
|
|
|
|
|
Placeholder *ph = (Placeholder *)pl;
|
|
|
|
|
2013-10-20 00:35:26 +02:00
|
|
|
FileMap::iterator it = openFiles.find(std::string(path));
|
2013-01-29 04:07:54 +01:00
|
|
|
rAssert(it != openFiles.end());
|
|
|
|
|
2013-10-20 00:35:26 +02:00
|
|
|
int rmCount = it->second.erase(ph);
|
2013-01-29 04:07:54 +01:00
|
|
|
|
|
|
|
rAssert(rmCount == 1);
|
|
|
|
|
|
|
|
// if no more references to this file, remove the record all together
|
2013-10-20 00:35:26 +02:00
|
|
|
if (it->second.empty()) {
|
2013-01-29 04:07:54 +01:00
|
|
|
// attempts to make use of shallow copy to clear memory used to hold
|
|
|
|
// unencrypted filenames.. not sure this does any good..
|
|
|
|
std::string storedName = it->first;
|
2013-10-20 00:35:26 +02:00
|
|
|
openFiles.erase(it);
|
|
|
|
storedName.assign(storedName.length(), '\0');
|
2013-01-29 04:07:54 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
delete ph;
|
|
|
|
}
|
|
|
|
|
2013-03-05 07:29:58 +01:00
|
|
|
} // namespace encfs
|