2008-03-25 22:54:05 +01:00
|
|
|
/*
|
|
|
|
* Copyright (C) 2008 Patrick Ohly
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <config.h>
|
|
|
|
#include "SyncEvolutionUtil.h"
|
2008-03-28 23:31:21 +01:00
|
|
|
#include "EvolutionSyncClient.h"
|
2008-03-25 22:54:05 +01:00
|
|
|
#include <base/test.h>
|
|
|
|
|
2008-03-28 23:31:21 +01:00
|
|
|
#include <boost/scoped_array.hpp>
|
2008-07-11 22:25:02 +02:00
|
|
|
#include <boost/foreach.hpp>
|
2008-07-08 10:46:09 +02:00
|
|
|
#include <fstream>
|
2008-03-28 23:31:21 +01:00
|
|
|
|
|
|
|
#include <errno.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <sys/stat.h>
|
|
|
|
#include <sys/types.h>
|
|
|
|
#include <dirent.h>
|
|
|
|
|
2008-04-19 10:02:42 +02:00
|
|
|
#ifdef ENABLE_UNIT_TESTS
|
2008-03-25 22:54:05 +01:00
|
|
|
CPPUNIT_REGISTRY_ADD_TO_DEFAULT("SyncEvolution");
|
2008-04-19 10:02:42 +02:00
|
|
|
#endif
|
2008-03-28 23:31:21 +01:00
|
|
|
|
|
|
|
string normalizePath(const string &path)
|
|
|
|
{
|
|
|
|
string res;
|
|
|
|
|
|
|
|
res.reserve(path.size());
|
|
|
|
size_t index = 0;
|
|
|
|
while (index < path.size()) {
|
|
|
|
char curr = path[index];
|
|
|
|
res += curr;
|
|
|
|
index++;
|
|
|
|
if (curr == '/') {
|
|
|
|
while (index < path.size() &&
|
|
|
|
(path[index] == '/' ||
|
|
|
|
(path[index] == '.' &&
|
|
|
|
index + 1 < path.size() &&
|
|
|
|
(path[index + 1] == '.' ||
|
|
|
|
path[index + 1] == '/')))) {
|
|
|
|
index++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!res.empty() && res[res.size() - 1] == '/') {
|
|
|
|
res.resize(res.size() - 1);
|
|
|
|
}
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
void mkdir_p(const string &path)
|
|
|
|
{
|
|
|
|
boost::scoped_array<char> dirs(new char[path.size() + 1]);
|
|
|
|
char *curr = dirs.get();
|
|
|
|
strcpy(curr, path.c_str());
|
|
|
|
do {
|
|
|
|
char *nextdir = strchr(curr, '/');
|
|
|
|
if (nextdir) {
|
|
|
|
*nextdir = 0;
|
|
|
|
nextdir++;
|
|
|
|
}
|
|
|
|
if (*curr) {
|
|
|
|
if (access(dirs.get(),
|
|
|
|
nextdir ? (R_OK|X_OK) : (R_OK|X_OK|W_OK)) &&
|
|
|
|
(errno != ENOENT ||
|
|
|
|
mkdir(dirs.get(), 0777))) {
|
2008-08-09 12:26:52 +02:00
|
|
|
EvolutionSyncClient::throwError(string(dirs.get()), errno);
|
2008-03-28 23:31:21 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if (nextdir) {
|
|
|
|
nextdir[-1] = '/';
|
|
|
|
}
|
|
|
|
curr = nextdir;
|
|
|
|
} while (curr);
|
|
|
|
}
|
|
|
|
|
|
|
|
void rm_r(const string &path)
|
|
|
|
{
|
2008-10-11 11:40:16 +02:00
|
|
|
struct stat buffer;
|
|
|
|
if (lstat(path.c_str(), &buffer)) {
|
|
|
|
if (errno == ENOENT) {
|
|
|
|
return;
|
|
|
|
} else {
|
|
|
|
EvolutionSyncClient::throwError(path, errno);
|
|
|
|
}
|
2008-03-28 23:31:21 +01:00
|
|
|
}
|
|
|
|
|
2008-10-11 11:40:16 +02:00
|
|
|
if (!S_ISDIR(buffer.st_mode)) {
|
|
|
|
if (!unlink(path.c_str())) {
|
|
|
|
return;
|
|
|
|
} else {
|
|
|
|
EvolutionSyncClient::throwError(path, errno);
|
|
|
|
}
|
2008-03-28 23:31:21 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
ReadDir dir(path);
|
2008-07-11 22:25:02 +02:00
|
|
|
BOOST_FOREACH(const string &entry, dir) {
|
|
|
|
rm_r(path + "/" + entry);
|
2008-03-28 23:31:21 +01:00
|
|
|
}
|
|
|
|
if (rmdir(path.c_str())) {
|
2008-08-09 12:26:52 +02:00
|
|
|
EvolutionSyncClient::throwError(path, errno);
|
2008-03-28 23:31:21 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-03-29 15:16:34 +01:00
|
|
|
bool isDir(const string &path)
|
|
|
|
{
|
|
|
|
DIR *dir = opendir(path.c_str());
|
|
|
|
if (dir) {
|
|
|
|
closedir(dir);
|
|
|
|
return true;
|
|
|
|
} else if (errno != ENOTDIR && errno != ENOENT) {
|
2008-08-09 12:26:52 +02:00
|
|
|
EvolutionSyncClient::throwError(path, errno);
|
2008-03-29 15:16:34 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2008-03-30 20:02:32 +02:00
|
|
|
UUID::UUID()
|
|
|
|
{
|
|
|
|
static class InitSRand {
|
|
|
|
public:
|
|
|
|
InitSRand() {
|
2008-07-07 20:01:13 +02:00
|
|
|
ifstream seedsource("/dev/urandom");
|
|
|
|
unsigned int seed;
|
|
|
|
if (!seedsource.get((char *)&seed, sizeof(seed))) {
|
|
|
|
seed = time(NULL);
|
|
|
|
}
|
|
|
|
srand(seed);
|
2008-03-30 20:02:32 +02:00
|
|
|
}
|
|
|
|
} initSRand;
|
|
|
|
|
|
|
|
char buffer[16 * 4 + 5];
|
|
|
|
sprintf(buffer, "%08x-%04x-%04x-%02x%02x-%08x%04x",
|
|
|
|
rand() & 0xFFFFFFFF,
|
|
|
|
rand() & 0xFFFF,
|
|
|
|
rand() & 0x0FFF | 0x4000 /* RFC 4122 time_hi_and_version */,
|
|
|
|
rand() & 0xBF | 0x80 /* clock_seq_hi_and_reserved */,
|
|
|
|
rand() & 0xFF,
|
|
|
|
rand() & 0xFFFFFFFF,
|
|
|
|
rand() & 0xFFFF
|
|
|
|
);
|
|
|
|
this->assign(buffer);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-03-28 23:31:21 +01:00
|
|
|
ReadDir::ReadDir(const string &path) : m_path(path)
|
|
|
|
{
|
|
|
|
DIR *dir = NULL;
|
|
|
|
|
|
|
|
try {
|
|
|
|
dir = opendir(path.c_str());
|
|
|
|
if (!dir) {
|
2008-08-09 12:26:52 +02:00
|
|
|
EvolutionSyncClient::throwError(path, errno);
|
2008-03-28 23:31:21 +01:00
|
|
|
}
|
|
|
|
errno = 0;
|
|
|
|
struct dirent *entry = readdir(dir);
|
|
|
|
while (entry) {
|
|
|
|
if (strcmp(entry->d_name, ".") &&
|
|
|
|
strcmp(entry->d_name, "..")) {
|
|
|
|
m_entries.push_back(entry->d_name);
|
|
|
|
}
|
|
|
|
entry = readdir(dir);
|
|
|
|
}
|
|
|
|
if (errno) {
|
2008-08-09 12:26:52 +02:00
|
|
|
EvolutionSyncClient::throwError(path, errno);
|
2008-03-28 23:31:21 +01:00
|
|
|
}
|
|
|
|
} catch(...) {
|
|
|
|
if (dir) {
|
|
|
|
closedir(dir);
|
|
|
|
}
|
|
|
|
throw;
|
|
|
|
}
|
|
|
|
|
|
|
|
closedir(dir);
|
|
|
|
}
|