If the --script argument passed to the updater is relative, interpret it as being relative to the package dir rather than the directory that the updater is run from.

Mendeley Desktop <= 1.0 clients pass a relative path for the script argument but
run the updater from the directory containing the main application binary instead
of the package dir.  The script argument, if relative, is therefore treated as
relative to the package directory.
This commit is contained in:
Robert Knight 2011-09-01 20:31:51 +01:00
parent 1fb6d03886
commit 6ca00a6449
6 changed files with 85 additions and 10 deletions

View file

@ -9,12 +9,6 @@
#include <string.h> #include <string.h>
bool endsWith(const std::string& str, const char* text)
{
size_t length = strlen(text);
return str.find(text,str.size() - length) != 0;
}
DirIterator::DirIterator(const char* path) DirIterator::DirIterator(const char* path)
{ {
m_path = path; m_path = path;

View file

@ -410,3 +410,49 @@ std::string FileUtils::tempPath()
#endif #endif
} }
bool startsWithDriveLetter(const char* path)
{
return strlen(path) >= 2 &&
(path[0] >= 'A' && path[0] <= 'Z') &&
path[1] == ':';
}
bool FileUtils::isRelative(const char* path)
{
#ifdef PLATFORM_UNIX
return strlen(path) == 0 || path[0] != '/';
#else
// on Windows, a path is relative if it does not start with:
// - '\\' (a UNC name)
// - '[Drive Letter]:\'
// - A single backslash
//
// the input path is assumed to have already been converted to use
// Unix-style path separators
std::string pathStr(path);
if ((!pathStr.empty() && pathStr.at(0) == '/') ||
(startsWith(pathStr,"//")) ||
(startsWithDriveLetter(pathStr.c_str())))
{
return false;
}
else
{
return true;
}
#endif
}
std::string FileUtils::makeAbsolute(const char* path, const char* basePath)
{
if (isRelative(path))
{
return std::string(basePath) + '/' + std::string(path);
}
else
{
return path;
}
}

View file

@ -7,6 +7,9 @@
/** A set of functions for performing common operations /** A set of functions for performing common operations
* on files, throwing exceptions if an operation fails. * on files, throwing exceptions if an operation fails.
*
* Path arguments to FileUtils functions should use Unix-style path
* separators.
*/ */
class FileUtils class FileUtils
{ {
@ -102,6 +105,18 @@ class FileUtils
*/ */
static std::string toUnixPathSeparators(const std::string& str); static std::string toUnixPathSeparators(const std::string& str);
/** Returns true if the provided path is relative.
* Or false if absolute.
*/
static bool isRelative(const char* path);
/** Converts @p path to an absolute path. If @p path is already absolute,
* just returns @p path, otherwise prefixes it with @p basePath to make it absolute.
*
* @p basePath should be absolute.
*/
static std::string makeAbsolute(const char* path, const char* basePath);
private: private:
static int toUnixPermissions(int qtPermissions); static int toUnixPermissions(int qtPermissions);
}; };

View file

@ -1,5 +1,6 @@
#pragma once #pragma once
#include <string.h>
#include <string> #include <string>
#include <sstream> #include <sstream>
#include <stdlib.h> #include <stdlib.h>
@ -32,3 +33,14 @@ inline const char* notNullString(const char* text)
} }
} }
inline bool endsWith(const std::string& str, const char* text)
{
size_t length = strlen(text);
return str.find(text,str.size() - length) != 0;
}
inline bool startsWith(const std::string& str, const char* text)
{
return str.find(text,0) == 0;
}

View file

@ -1,4 +1,5 @@
#include "AppInfo.h" #include "AppInfo.h"
#include "FileUtils.h"
#include "Log.h" #include "Log.h"
#include "Platform.h" #include "Platform.h"
#include "ProcessUtils.h" #include "ProcessUtils.h"
@ -63,7 +64,7 @@ int main(int argc, char** argv)
if (!options.scriptPath.empty()) if (!options.scriptPath.empty())
{ {
script.parse(options.scriptPath); script.parse(FileUtils::makeAbsolute(options.scriptPath.c_str(),options.packageDir.c_str()));
} }
LOG(Info,"started updater. install-dir: " + options.installDir LOG(Info,"started updater. install-dir: " + options.installDir

View file

@ -3,8 +3,8 @@
require 'fileutils.rb' require 'fileutils.rb'
require 'rbconfig' require 'rbconfig'
INSTALL_DIR = "install-dir/" INSTALL_DIR = File.expand_path("install-dir/")
PACKAGE_DIR = "package-dir/" PACKAGE_DIR = File.expand_path("package-dir/")
if (RbConfig::CONFIG['host_os'] =~ /mswin|mingw/) if (RbConfig::CONFIG['host_os'] =~ /mswin|mingw/)
OLDAPP_NAME = "oldapp.exe" OLDAPP_NAME = "oldapp.exe"
@ -61,7 +61,14 @@ replace_vars("file_list.xml","#{PACKAGE_DIR}/file_list.xml",file_list_vars)
FileUtils.cp("../#{UPDATER_NAME}","#{PACKAGE_DIR}/#{UPDATER_NAME}") FileUtils.cp("../#{UPDATER_NAME}","#{PACKAGE_DIR}/#{UPDATER_NAME}")
# Run the updater using the new syntax # Run the updater using the new syntax
system("#{PACKAGE_DIR}/#{UPDATER_NAME} --install-dir #{INSTALL_DIR} --package-dir #{PACKAGE_DIR} --script #{PACKAGE_DIR}/file_list.xml") #
# Run the application from the install directory to
# make sure that it looks in the correct directory for
# the file_list.xml file and packages
#
Dir.chdir(INSTALL_DIR) do
system("#{PACKAGE_DIR}/#{UPDATER_NAME} --install-dir #{INSTALL_DIR} --package-dir #{PACKAGE_DIR} --script file_list.xml")
end
# TODO - Correctly wait until updater has finished # TODO - Correctly wait until updater has finished
sleep(1) sleep(1)