diff --git a/src/AppInfo.cpp b/src/AppInfo.cpp index f6094a4..7b6f662 100644 --- a/src/AppInfo.cpp +++ b/src/AppInfo.cpp @@ -3,69 +3,13 @@ #include "FileUtils.h" #include "Platform.h" #include "StringUtils.h" +#include "StandardDirs.h" #include -#ifdef PLATFORM_UNIX - #include - #include -#endif - -#ifdef PLATFORM_WINDOWS -#include -#endif - -#ifdef PLATFORM_UNIX -std::string homeDir() -{ - std::string dir = notNullString(getenv("HOME")); - if (!dir.empty()) - { - return dir; - } - else - { - // note: if this process has been elevated with sudo, - // this will return the home directory of the root user - struct passwd* userData = getpwuid(getuid()); - return notNullString(userData->pw_dir); - } -} -#endif - -std::string appDataPath(const std::string& organizationName, - const std::string& appName) -{ -#ifdef PLATFORM_LINUX - std::string xdgDataHome = notNullString(getenv("XDG_DATA_HOME")); - if (xdgDataHome.empty()) - { - xdgDataHome = homeDir() + "/.local/share"; - } - xdgDataHome += "/data/" + organizationName + '/' + appName; - return xdgDataHome; - -#elif defined(PLATFORM_MAC) - // TODO - Mac implementation - -#elif defined(PLATFORM_WINDOWS) - char buffer[MAX_PATH+1]; - if (SHGetFolderPath(0, CSIDL_LOCAL_APPDATA, 0 /* hToken */, SHGFP_TYPE_CURRENT, buffer) == S_OK) - { - std::string path = FileUtils::toUnixPathSeparators(notNullString(buffer)); - path += '/' + organizationName + '/' + appName; - return path; - } - else - { - return std::string(); - } -#endif -} - std::string AppInfo::logFilePath() { - return appDataPath(organizationName(),appName()) + '/' + "update-log.txt"; + return StandardDirs::appDataPath(organizationName(),appName()) + '/' + "update-log.txt"; } std::string AppInfo::updateErrorMessage(const std::string& details) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index dc6b1c7..7752762 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -29,13 +29,14 @@ set (SOURCES FileUtils.cpp Log.cpp ProcessUtils.cpp + StandardDirs.cpp UpdateInstaller.cpp UpdateScript.cpp UpdaterOptions.cpp ) if (APPLE) - set(SOURCES ${SOURCES} UpdateDialogCocoa.mm) + set(SOURCES ${SOURCES} StandardDirs.mm UpdateDialogCocoa.mm) endif() if (WIN32) set(SOURCES ${SOURCES} UpdateDialogWin32.cpp) @@ -47,6 +48,7 @@ set (HEADERS FileUtils.h Log.h ProcessUtils.h + StandardDirs.h UpdateInstaller.h UpdateScript.h UpdaterOptions.h diff --git a/src/FileUtils.cpp b/src/FileUtils.cpp index 36675a8..94f55bb 100644 --- a/src/FileUtils.cpp +++ b/src/FileUtils.cpp @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -258,16 +259,20 @@ void FileUtils::touch(const char* path) throw (IOException) { #ifdef PLATFORM_UNIX // see http://pubs.opengroup.org/onlinepubs/9699919799/utilities/touch.html + // + // we use utimes/futimes instead of utimensat/futimens for compatibility + // with older Linux and Mac + if (fileExists(path)) { - utimensat(AT_FDCWD,path,0 /* use current date/time */,0); + utimes(path,0 /* use current date/time */); } else { int fd = creat(path,S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); if (fd != -1) { - futimens(fd,0 /* use current date/time */); + futimes(fd,0 /* use current date/time */); close(fd); } else diff --git a/src/ProcessUtils.cpp b/src/ProcessUtils.cpp index 00f1646..2e4cf75 100644 --- a/src/ProcessUtils.cpp +++ b/src/ProcessUtils.cpp @@ -152,7 +152,7 @@ int ProcessUtils::runElevatedLinux(const std::string& executable, #endif #ifdef PLATFORM_MAC -void ProcessUtils::runElevatedMac(const std::string& executable, +int ProcessUtils::runElevatedMac(const std::string& executable, const std::list& args) { // request elevation using the Security Service. diff --git a/src/StandardDirs.cpp b/src/StandardDirs.cpp new file mode 100644 index 0000000..13f991b --- /dev/null +++ b/src/StandardDirs.cpp @@ -0,0 +1,61 @@ +#include "StandardDirs.h" + +#include "StringUtils.h" + +#ifdef PLATFORM_UNIX + #include + #include +#endif + +#ifdef PLATFORM_WINDOWS +#include +#endif + +#ifdef PLATFORM_UNIX +std::string StandardDirs::homeDir() +{ + std::string dir = notNullString(getenv("HOME")); + if (!dir.empty()) + { + return dir; + } + else + { + // note: if this process has been elevated with sudo, + // this will return the home directory of the root user + struct passwd* userData = getpwuid(getuid()); + return notNullString(userData->pw_dir); + } +} +#endif + +std::string StandardDirs::appDataPath(const std::string& organizationName, + const std::string& appName) +{ +#ifdef PLATFORM_LINUX + std::string xdgDataHome = notNullString(getenv("XDG_DATA_HOME")); + if (xdgDataHome.empty()) + { + xdgDataHome = homeDir() + "/.local/share"; + } + xdgDataHome += "/data/" + organizationName + '/' + appName; + return xdgDataHome; + +#elif defined(PLATFORM_MAC) + std::string path = applicationSupportFolderPath(); + path += '/' + appName; + return path; +#elif defined(PLATFORM_WINDOWS) + char buffer[MAX_PATH + 1]; + if (SHGetFolderPath(0, CSIDL_LOCAL_APPDATA, 0 /* hToken */, SHGFP_TYPE_CURRENT, buffer) == S_OK) + { + std::string path = FileUtils::toUnixPathSeparators(notNullString(buffer)); + path += '/' + organizationName + '/' + appName; + return path; + } + else + { + return std::string(); + } +#endif +} diff --git a/src/StandardDirs.h b/src/StandardDirs.h new file mode 100644 index 0000000..1852617 --- /dev/null +++ b/src/StandardDirs.h @@ -0,0 +1,22 @@ +#pragma once + +#include "Platform.h" + +#include + +class StandardDirs +{ + public: + static std::string appDataPath(const std::string& organizationName, + const std::string& appName); + + private: +#ifdef PLATFORM_UNIX + static std::string homeDir(); +#endif + +#ifdef PLATFORM_MAC + static std::string applicationSupportFolderPath(); +#endif +}; + diff --git a/src/StandardDirs.mm b/src/StandardDirs.mm new file mode 100644 index 0000000..53eecd4 --- /dev/null +++ b/src/StandardDirs.mm @@ -0,0 +1,18 @@ +#include + +#include "StandardDirs.h" + +std::string StandardDirs::applicationSupportFolderPath() +{ + NSArray* paths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, + NSUserDomainMask, + true /* expand tildes */); + + for (unsigned int i=0; i < [paths count]; i++) + { + NSString* path = [paths objectAtIndex:i]; + return std::string([path UTF8String]); + } + return std::string(); +} + diff --git a/src/main.cpp b/src/main.cpp index 6b5be74..db775f3 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -52,6 +52,10 @@ void runUpdaterThread(void* arg) int main(int argc, char** argv) { +#ifdef PLATFORM_MAC + void* pool = UpdateDialogCocoa::createAutoreleasePool(); +#endif + Log::instance()->open(AppInfo::logFilePath()); UpdaterOptions options; options.parse(argc,argv); @@ -85,6 +89,10 @@ int main(int argc, char** argv) installer.run(); } +#ifdef PLATFORM_MAC + UpdateDialogCocoa::releaseAutoreleasePool(pool); +#endif + return 0; } diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt index 3bf9d57..48f0d3b 100644 --- a/src/tests/CMakeLists.txt +++ b/src/tests/CMakeLists.txt @@ -37,3 +37,8 @@ target_link_libraries(TestUpdaterOptions updatershared ) +if (APPLE) + set_target_properties(TestUpdateScript PROPERTIES LINK_FLAGS "-framework Security -framework Cocoa") + set_target_properties(TestUpdaterOptions PROPERTIES LINK_FLAGS "-framework Security -framework Cocoa") +endif() +