summaryrefslogtreecommitdiff
path: root/cpp/src/IceGrid/Util.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'cpp/src/IceGrid/Util.cpp')
-rw-r--r--cpp/src/IceGrid/Util.cpp312
1 files changed, 312 insertions, 0 deletions
diff --git a/cpp/src/IceGrid/Util.cpp b/cpp/src/IceGrid/Util.cpp
index b77215d8de9..f9dfe622877 100644
--- a/cpp/src/IceGrid/Util.cpp
+++ b/cpp/src/IceGrid/Util.cpp
@@ -7,10 +7,52 @@
#include <IceGrid/Admin.h>
#include <IceGrid/Internal.h>
+#include <IceUtil/FileUtil.h>
+#ifdef _WIN32
+# include <direct.h>
+# include <io.h>
+#else
+# include <unistd.h>
+# include <dirent.h>
+#endif
+
using namespace std;
using namespace Ice;
using namespace IceGrid;
+namespace
+{
+
+bool
+isRoot(const string& pa)
+{
+ string path = simplify(pa);
+#ifdef _WIN32
+ return path == "/" || path.size() == 3 && IceUtilInternal::isAlpha(path[0]) && path[1] == ':' &&
+ path[2] == '/';
+#else
+ return path == "/";
+#endif
+}
+
+string
+getDirname(const string& pa)
+{
+ const string path = simplify(pa);
+
+ string::size_type pos = path.rfind('/');
+ if(pos == string::npos)
+ {
+ return string();
+ }
+ else
+ {
+ return path.substr(0, pos);
+ }
+}
+
+}
+
string
IceGrid::toString(const vector<string>& v, const string& sep)
{
@@ -324,3 +366,273 @@ IceGrid::getMMVersion(const string& o)
return ver;
}
+
+string
+IceGrid::simplify(const string& path)
+{
+ string result = path;
+
+ string::size_type pos;
+
+#ifdef _WIN32
+ pos = 0;
+ if(result.find("\\\\") == 0)
+ {
+ pos = 2;
+ }
+
+ for(; pos < result.size(); ++pos)
+ {
+ if(result[pos] == '\\')
+ {
+ result[pos] = '/';
+ }
+ }
+#endif
+
+ pos = 0;
+ while((pos = result.find("//", pos)) != string::npos)
+ {
+ result.erase(pos, 1);
+ }
+
+ pos = 0;
+ while((pos = result.find("/./", pos)) != string::npos)
+ {
+ result.erase(pos, 2);
+ }
+
+ while(result.substr(0, 4) == "/../")
+ {
+ result.erase(0, 3);
+ }
+
+ if(result.substr(0, 2) == "./")
+ {
+ result.erase(0, 2);
+ }
+
+ if(result == "/." ||
+ (result.size() == 4 && IceUtilInternal::isAlpha(result[0]) && result[1] == ':' &&
+ result[2] == '/' && result[3] == '.'))
+ {
+ return result.substr(0, result.size() - 1);
+ }
+
+ if(result.size() >= 2 && result.substr(result.size() - 2, 2) == "/.")
+ {
+ result.erase(result.size() - 2, 2);
+ }
+
+ if(result == "/" || (result.size() == 3 && IceUtilInternal::isAlpha(result[0]) && result[1] == ':' &&
+ result[2] == '/'))
+ {
+ return result;
+ }
+
+ if(result.size() >= 1 && result[result.size() - 1] == '/')
+ {
+ result.erase(result.size() - 1);
+ }
+
+ if(result == "/..")
+ {
+ result = "/";
+ }
+
+ return result;
+}
+
+void
+IceGrid::remove(const string& pa)
+{
+ const string path = simplify(pa);
+
+ IceUtilInternal::structstat buf;
+ if(IceUtilInternal::stat(path, &buf) == -1)
+ {
+ throw runtime_error("cannot stat `" + path + "':\n" + IceUtilInternal::lastErrorToString());
+ }
+
+ if(S_ISDIR(buf.st_mode))
+ {
+ if(IceUtilInternal::rmdir(path) == -1)
+ {
+ if(errno == EACCES)
+ {
+ assert(false);
+ }
+ throw runtime_error("cannot remove directory `" + path + "':\n" + IceUtilInternal::lastErrorToString());
+ }
+ }
+ else
+ {
+ if(IceUtilInternal::remove(path) == -1)
+ {
+ throw runtime_error("cannot remove file `" + path + "':\n" + IceUtilInternal::lastErrorToString());
+ }
+ }
+}
+
+void
+IceGrid::removeRecursive(const string& pa)
+{
+ const string path = simplify(pa);
+
+ IceUtilInternal::structstat buf;
+ if(IceUtilInternal::stat(path, &buf) == -1)
+ {
+ throw runtime_error("cannot stat `" + path + "':\n" + IceUtilInternal::lastErrorToString());
+ }
+
+ if(S_ISDIR(buf.st_mode))
+ {
+ StringSeq paths = readDirectory(path);
+ for(StringSeq::const_iterator p = paths.begin(); p != paths.end(); ++p)
+ {
+ removeRecursive(path + '/' + *p);
+ }
+
+ if(!isRoot(path))
+ {
+ if(IceUtilInternal::rmdir(path) == -1)
+ {
+ throw runtime_error("cannot remove directory `" + path + "':\n" + IceUtilInternal::lastErrorToString());
+ }
+ }
+ }
+ else
+ {
+ if(IceUtilInternal::remove(path) == -1)
+ {
+ throw runtime_error("cannot remove file `" + path + "':\n" + IceUtilInternal::lastErrorToString());
+ }
+ }
+}
+
+StringSeq
+IceGrid::readDirectory(const string& pa)
+{
+ const string path = simplify(pa);
+
+#ifdef _WIN32
+
+ //
+ // IceGrid doesn't support to use string converters, so don't need to use
+ // any string converter in stringToWstring or wstringToString conversions.
+ //
+ StringSeq result;
+ const wstring fs = IceUtil::stringToWstring(simplify(path + "/*"));
+
+ struct _wfinddata_t data;
+ intptr_t h = _wfindfirst(fs.c_str(), &data);
+ if(h == -1)
+ {
+ throw runtime_error("cannot read directory `" + path + "':\n" + IceUtilInternal::lastErrorToString());
+ }
+
+ while(true)
+ {
+ string name = wstringToString(data.name);
+ assert(!name.empty());
+
+ if(name != ".." && name != ".")
+ {
+ result.push_back(name);
+ }
+
+ if(_wfindnext(h, &data) == -1)
+ {
+ if(errno == ENOENT)
+ {
+ break;
+ }
+ string reason = "cannot read directory `" + path + "':\n" + IceUtilInternal::lastErrorToString();
+ _findclose(h);
+ throw runtime_error(reason);
+ }
+ }
+
+ _findclose(h);
+
+ sort(result.begin(), result.end());
+ return result;
+
+#else
+
+ struct dirent **namelist;
+ int n = scandir(path.c_str(), &namelist, 0, alphasort);
+
+ if(n < 0)
+ {
+ throw runtime_error("cannot read directory `" + path + "':\n" + IceUtilInternal::lastErrorToString());
+ }
+
+ StringSeq result;
+ assert(n >= 2);
+ result.reserve(static_cast<size_t>(n - 2));
+
+ for(int i = 0; i < n; ++i)
+ {
+ string name = namelist[i]->d_name;
+ assert(!name.empty());
+
+ free(namelist[i]);
+
+ if(name != ".." && name != ".")
+ {
+ result.push_back(name);
+ }
+ }
+
+ free(namelist);
+ return result;
+
+#endif
+}
+
+void
+IceGrid::createDirectory(const string& pa)
+{
+ const string path = simplify(pa);
+
+ if(IceUtilInternal::mkdir(path, 0777) == -1)
+ {
+ if(errno != EEXIST)
+ {
+ throw runtime_error("cannot create directory `" + path + "':\n" + IceUtilInternal::lastErrorToString());
+ }
+ }
+}
+
+void
+IceGrid::createDirectoryRecursive(const string& pa)
+{
+ const string path = simplify(pa);
+
+ string dir = getDirname(path);
+ if(!dir.empty())
+ {
+ createDirectoryRecursive(dir);
+ }
+
+ if(!isRoot(path + "/"))
+ {
+ IceUtilInternal::structstat buf;
+ if(IceUtilInternal::stat(path, &buf) != -1)
+ {
+ if(S_ISDIR(buf.st_mode))
+ {
+ return;
+ }
+ }
+
+ if(IceUtilInternal::mkdir(path, 0777) == -1)
+ {
+ if(errno != EEXIST)
+ {
+ throw runtime_error("cannot create directory `" + path + "':\n" + IceUtilInternal::lastErrorToString());
+ }
+ }
+ }
+}