aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/common
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/common')
-rw-r--r--src/lib/common/CMakeLists.txt16
-rw-r--r--src/lib/common/DataDirectories.h41
-rw-r--r--src/lib/common/DataDirectories_static.cpp23
-rw-r--r--src/lib/common/PathUtilities.cpp75
-rw-r--r--src/lib/common/PathUtilities.h31
-rw-r--r--src/lib/common/unix/DataDirectories.cpp114
-rw-r--r--src/lib/common/win32/DataDirectories.cpp81
7 files changed, 381 insertions, 0 deletions
diff --git a/src/lib/common/CMakeLists.txt b/src/lib/common/CMakeLists.txt
index 56d9fc9..b3791c1 100644
--- a/src/lib/common/CMakeLists.txt
+++ b/src/lib/common/CMakeLists.txt
@@ -17,8 +17,24 @@
file(GLOB headers "*.h")
file(GLOB sources "*.cpp")
+if (WIN32)
+ file(GLOB arch_headers "win32/*.h")
+ file(GLOB arch_sources "win32/*.cpp")
+elseif (UNIX)
+ file(GLOB arch_headers "unix/*.h")
+ file(GLOB arch_sources "unix/*.cpp")
+endif()
+
+list(APPEND headers ${arch_headers})
+list(APPEND sources ${arch_sources})
+
if (BARRIER_ADD_HEADERS)
list(APPEND sources ${headers})
endif()
add_library(common STATIC ${sources})
+
+if (HAVE_GETPWUID_R)
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DHAVE_GETPWUID_R=1")
+endif()
+
diff --git a/src/lib/common/DataDirectories.h b/src/lib/common/DataDirectories.h
new file mode 100644
index 0000000..6b990c2
--- /dev/null
+++ b/src/lib/common/DataDirectories.h
@@ -0,0 +1,41 @@
+/*
+* barrier -- mouse and keyboard sharing utility
+* Copyright (C) 2018 Debauchee Open Source Group
+*
+* This package is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* found in the file LICENSE that should have accompanied this file.
+*
+* This package 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 General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#pragma once
+
+#include <string>
+
+class DataDirectories
+{
+public:
+ static const std::string& profile();
+ static const std::string& profile(const std::string& path);
+
+ static const std::string& global();
+ static const std::string& global(const std::string& path);
+
+ static const std::string& systemconfig();
+ static const std::string& systemconfig(const std::string& path);
+
+private:
+ // static class
+ DataDirectories() {}
+
+ static std::string _profile;
+ static std::string _global;
+ static std::string _systemconfig;
+};
diff --git a/src/lib/common/DataDirectories_static.cpp b/src/lib/common/DataDirectories_static.cpp
new file mode 100644
index 0000000..48dccb6
--- /dev/null
+++ b/src/lib/common/DataDirectories_static.cpp
@@ -0,0 +1,23 @@
+/*
+* barrier -- mouse and keyboard sharing utility
+* Copyright (C) 2018 Debauchee Open Source Group
+*
+* This package is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* found in the file LICENSE that should have accompanied this file.
+*
+* This package 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 General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "DataDirectories.h"
+
+// static member
+std::string DataDirectories::_profile;
+std::string DataDirectories::_global;
+std::string DataDirectories::_systemconfig;
diff --git a/src/lib/common/PathUtilities.cpp b/src/lib/common/PathUtilities.cpp
new file mode 100644
index 0000000..a2ab38a
--- /dev/null
+++ b/src/lib/common/PathUtilities.cpp
@@ -0,0 +1,75 @@
+/*
+* barrier -- mouse and keyboard sharing utility
+* Copyright (C) 2018 Debauchee Open Source Group
+*
+* This package is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* found in the file LICENSE that should have accompanied this file.
+*
+* This package 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 General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/*
+
+These functions cover the vast majority of cases for different paths across
+windows and unixes. They are not, however, fullproof and probably don't cover
+fringe cases very well. The library below might be used as an alternative if
+these implementations prove to be insufficient. As the library's readme states
+it is simply a temporary band-aid until std::filesystem is integrated (C++17
+has it in std::experimental) and this class should also be treated as such.
+
+https://github.com/wjakob/filesystem/
+
+*/
+
+#include "PathUtilities.h"
+
+// keep the default platform delimiter as the first in the list
+#ifdef _WIN32
+static const char *Delimiters = "\\/";
+#else
+static const char *Delimiters = "/";
+#endif
+
+static const char DefaultDelimiter = Delimiters[0];
+
+std::string PathUtilities::basename(const std::string& path)
+{
+ return path.substr(path.find_last_of(Delimiters) + 1);
+}
+
+std::string PathUtilities::concat(const std::string& left, const std::string& right)
+{
+ // although npos is usually (-1) we can't count on that so handle it explicitly
+ auto leftEnd = left.find_last_not_of(Delimiters);
+ if (leftEnd == std::string::npos)
+ leftEnd = 0;
+ else
+ ++leftEnd;
+ auto rightStart = right.find_first_not_of(Delimiters, 0);
+ if (rightStart == std::string::npos) {
+ // both left/right are empty
+ if (left.size() == 0 && right.size() == 0)
+ return "";
+ // right is full of delims, left is okay
+ if (leftEnd > 0)
+ return left.substr(0, leftEnd);
+ // both left/right useless but at least one has delims
+ return std::string(1, DefaultDelimiter);
+ }
+ if (leftEnd == 0) {
+ // right is okay and not prefixed with delims, left is empty
+ if (left.size() == 0 && rightStart == 0)
+ return right.substr(rightStart);
+ // (right is okay and prefixed with delims) OR left is full of delims
+ return DefaultDelimiter + right.substr(rightStart);
+ }
+ // concatenation using both left and right
+ return left.substr(0, leftEnd) + DefaultDelimiter + right.substr(rightStart);
+}
diff --git a/src/lib/common/PathUtilities.h b/src/lib/common/PathUtilities.h
new file mode 100644
index 0000000..70b85b4
--- /dev/null
+++ b/src/lib/common/PathUtilities.h
@@ -0,0 +1,31 @@
+/*
+* barrier -- mouse and keyboard sharing utility
+* Copyright (C) 2018 Debauchee Open Source Group
+*
+* This package is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* found in the file LICENSE that should have accompanied this file.
+*
+* This package 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 General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#pragma once
+
+#include <string>
+
+class PathUtilities
+{
+public:
+ static std::string basename(const std::string& path);
+ static std::string concat(const std::string& left, const std::string& right);
+
+private:
+ // static class
+ PathUtilities() {}
+};
diff --git a/src/lib/common/unix/DataDirectories.cpp b/src/lib/common/unix/DataDirectories.cpp
new file mode 100644
index 0000000..72e510a
--- /dev/null
+++ b/src/lib/common/unix/DataDirectories.cpp
@@ -0,0 +1,114 @@
+/*
+* barrier -- mouse and keyboard sharing utility
+* Copyright (C) 2018 Debauchee Open Source Group
+*
+* This package is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* found in the file LICENSE that should have accompanied this file.
+*
+* This package 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 General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "../DataDirectories.h"
+
+#include <unistd.h> // sysconf
+#include <stdlib.h> // getenv
+#include <sys/types.h> // getpwuid(_r)
+#include <pwd.h> // getpwuid(_r)
+
+const std::string ProfileSubdir = "/barrier";
+
+static std::string pw_dir(struct passwd* pwentp)
+{
+ if (pwentp != NULL && pwentp->pw_dir != NULL)
+ return pwentp->pw_dir;
+ return "";
+}
+
+#ifdef HAVE_GETPWUID_R
+
+static std::string unix_home()
+{
+ long size = -1;
+#if defined(_SC_GETPW_R_SIZE_MAX)
+ size = sysconf(_SC_GETPW_R_SIZE_MAX);
+#endif
+ if (size == -1)
+ size = BUFSIZ;
+
+ struct passwd pwent;
+ struct passwd* pwentp;
+ std::string buffer(size, 0);
+ getpwuid_r(getuid(), &pwent, &buffer[0], size, &pwentp);
+ return pw_dir(pwentp);
+}
+
+#else // not HAVE_GETPWUID_R
+
+static std::string unix_home()
+{
+ return pw_dir(getpwuid(getuid()));
+}
+
+#endif // HAVE_GETPWUID_R
+
+static std::string profile_basedir()
+{
+#ifdef WINAPI_XWINDOWS
+ // linux/bsd adheres to freedesktop standards
+ // https://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html
+ const char* dir = getenv("XDG_DATA_HOME");
+ if (dir != NULL)
+ return dir;
+ return unix_home() + "/.local/share";
+#else
+ // macos has its own standards
+ // https://developer.apple.com/library/content/documentation/General/Conceptual/MOSXAppProgrammingGuide/AppRuntime/AppRuntime.html
+ return unix_home() + "/Library/Application Support";
+#endif
+}
+
+const std::string& DataDirectories::profile()
+{
+ if (_profile.empty())
+ _profile = profile_basedir() + ProfileSubdir;
+ return _profile;
+}
+const std::string& DataDirectories::profile(const std::string& path)
+{
+ _profile = path;
+ return _profile;
+}
+
+const std::string& DataDirectories::global()
+{
+ if (_global.empty())
+ // TODO: where on a unix system should public/global shared data go?
+ // as of march 2018 global() is not used for unix
+ _global = "/tmp";
+ return _global;
+}
+const std::string& DataDirectories::global(const std::string& path)
+{
+ _global = path;
+ return _global;
+}
+
+const std::string& DataDirectories::systemconfig()
+{
+ if (_systemconfig.empty())
+ _systemconfig = "/etc";
+ return _systemconfig;
+}
+
+const std::string& DataDirectories::systemconfig(const std::string& path)
+{
+ _systemconfig = path;
+ return _systemconfig;
+}
diff --git a/src/lib/common/win32/DataDirectories.cpp b/src/lib/common/win32/DataDirectories.cpp
new file mode 100644
index 0000000..15cb64e
--- /dev/null
+++ b/src/lib/common/win32/DataDirectories.cpp
@@ -0,0 +1,81 @@
+/*
+* barrier -- mouse and keyboard sharing utility
+* Copyright (C) 2018 Debauchee Open Source Group
+*
+* This package is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* found in the file LICENSE that should have accompanied this file.
+*
+* This package 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 General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "../DataDirectories.h"
+
+#include <Shlobj.h>
+
+std::string unicode_to_mb(const WCHAR* utfStr)
+{
+ int utfLength = lstrlenW(utfStr);
+ int mbLength = WideCharToMultiByte(CP_UTF8, 0, utfStr, utfLength, NULL, 0, NULL, NULL);
+ std::string mbStr(mbLength, 0);
+ WideCharToMultiByte(CP_UTF8, 0, utfStr, utfLength, &mbStr[0], mbLength, NULL, NULL);
+ return mbStr;
+}
+
+std::string known_folder_path(const KNOWNFOLDERID& id)
+{
+ std::string path;
+ WCHAR* buffer;
+ HRESULT result = SHGetKnownFolderPath(id, 0, NULL, &buffer);
+ if (result == S_OK) {
+ path = unicode_to_mb(buffer);
+ CoTaskMemFree(buffer);
+ }
+ return path;
+}
+
+const std::string& DataDirectories::profile()
+{
+ if (_profile.empty())
+ _profile = known_folder_path(FOLDERID_LocalAppData) + "\\Barrier";
+ return _profile;
+}
+const std::string& DataDirectories::profile(const std::string& path)
+{
+ _profile = path;
+ return _profile;
+}
+
+const std::string& DataDirectories::global()
+{
+ if (_global.empty())
+ _global = known_folder_path(FOLDERID_ProgramData) + "\\Barrier";
+ return _global;
+}
+const std::string& DataDirectories::global(const std::string& path)
+{
+ _global = path;
+ return _global;
+}
+
+const std::string& DataDirectories::systemconfig()
+{
+ // systemconfig() is a special case in that it will track the current value
+ // of global() unless and until it is explictly set otherwise
+ // previously it would default to the windows folder which was horrible!
+ if (_systemconfig.empty())
+ return global();
+ return _systemconfig;
+}
+
+const std::string& DataDirectories::systemconfig(const std::string& path)
+{
+ _systemconfig = path;
+ return _systemconfig;
+}