00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <config.h>
00021 #include "SyncEvolutionUtil.h"
00022 #include "EvolutionSyncClient.h"
00023 #include <base/test.h>
00024
00025 #include <boost/scoped_array.hpp>
00026 #include <boost/foreach.hpp>
00027 #include <fstream>
00028
00029 #include <errno.h>
00030 #include <unistd.h>
00031 #include <sys/stat.h>
00032 #include <sys/types.h>
00033 #include <dirent.h>
00034
00035 #ifdef ENABLE_UNIT_TESTS
00036 CPPUNIT_REGISTRY_ADD_TO_DEFAULT("SyncEvolution");
00037 #endif
00038
00039 string normalizePath(const string &path)
00040 {
00041 string res;
00042
00043 res.reserve(path.size());
00044 size_t index = 0;
00045 while (index < path.size()) {
00046 char curr = path[index];
00047 res += curr;
00048 index++;
00049 if (curr == '/') {
00050 while (index < path.size() &&
00051 (path[index] == '/' ||
00052 (path[index] == '.' &&
00053 index + 1 < path.size() &&
00054 (path[index + 1] == '.' ||
00055 path[index + 1] == '/')))) {
00056 index++;
00057 }
00058 }
00059 }
00060 if (!res.empty() && res[res.size() - 1] == '/') {
00061 res.resize(res.size() - 1);
00062 }
00063 return res;
00064 }
00065
00066 void mkdir_p(const string &path)
00067 {
00068 boost::scoped_array<char> dirs(new char[path.size() + 1]);
00069 char *curr = dirs.get();
00070 strcpy(curr, path.c_str());
00071 do {
00072 char *nextdir = strchr(curr, '/');
00073 if (nextdir) {
00074 *nextdir = 0;
00075 nextdir++;
00076 }
00077 if (*curr) {
00078 if (access(dirs.get(),
00079 nextdir ? (R_OK|X_OK) : (R_OK|X_OK|W_OK)) &&
00080 (errno != ENOENT ||
00081 mkdir(dirs.get(), 0777))) {
00082 EvolutionSyncClient::throwError(string(dirs.get()), errno);
00083 }
00084 }
00085 if (nextdir) {
00086 nextdir[-1] = '/';
00087 }
00088 curr = nextdir;
00089 } while (curr);
00090 }
00091
00092 void rm_r(const string &path)
00093 {
00094 struct stat buffer;
00095 if (lstat(path.c_str(), &buffer)) {
00096 if (errno == ENOENT) {
00097 return;
00098 } else {
00099 EvolutionSyncClient::throwError(path, errno);
00100 }
00101 }
00102
00103 if (!S_ISDIR(buffer.st_mode)) {
00104 if (!unlink(path.c_str())) {
00105 return;
00106 } else {
00107 EvolutionSyncClient::throwError(path, errno);
00108 }
00109 }
00110
00111 ReadDir dir(path);
00112 BOOST_FOREACH(const string &entry, dir) {
00113 rm_r(path + "/" + entry);
00114 }
00115 if (rmdir(path.c_str())) {
00116 EvolutionSyncClient::throwError(path, errno);
00117 }
00118 }
00119
00120 bool isDir(const string &path)
00121 {
00122 DIR *dir = opendir(path.c_str());
00123 if (dir) {
00124 closedir(dir);
00125 return true;
00126 } else if (errno != ENOTDIR && errno != ENOENT) {
00127 EvolutionSyncClient::throwError(path, errno);
00128 }
00129
00130 return false;
00131 }
00132
00133 UUID::UUID()
00134 {
00135 static class InitSRand {
00136 public:
00137 InitSRand() {
00138 ifstream seedsource("/dev/urandom");
00139 unsigned int seed;
00140 if (!seedsource.get((char *)&seed, sizeof(seed))) {
00141 seed = time(NULL);
00142 }
00143 srand(seed);
00144 }
00145 } initSRand;
00146
00147 char buffer[16 * 4 + 5];
00148 sprintf(buffer, "%08x-%04x-%04x-%02x%02x-%08x%04x",
00149 rand() & 0xFFFFFFFF,
00150 rand() & 0xFFFF,
00151 rand() & 0x0FFF | 0x4000 ,
00152 rand() & 0xBF | 0x80 ,
00153 rand() & 0xFF,
00154 rand() & 0xFFFFFFFF,
00155 rand() & 0xFFFF
00156 );
00157 this->assign(buffer);
00158 }
00159
00160
00161 ReadDir::ReadDir(const string &path) : m_path(path)
00162 {
00163 DIR *dir = NULL;
00164
00165 try {
00166 dir = opendir(path.c_str());
00167 if (!dir) {
00168 EvolutionSyncClient::throwError(path, errno);
00169 }
00170 errno = 0;
00171 struct dirent *entry = readdir(dir);
00172 while (entry) {
00173 if (strcmp(entry->d_name, ".") &&
00174 strcmp(entry->d_name, "..")) {
00175 m_entries.push_back(entry->d_name);
00176 }
00177 entry = readdir(dir);
00178 }
00179 if (errno) {
00180 EvolutionSyncClient::throwError(path, errno);
00181 }
00182 } catch(...) {
00183 if (dir) {
00184 closedir(dir);
00185 }
00186 throw;
00187 }
00188
00189 closedir(dir);
00190 }