1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
|
#include "UpdaterOptions.h"
#include "Log.h"
#include "AnyOption/anyoption.h"
#include "FileUtils.h"
#include "Platform.h"
#include "StringUtils.h"
#include <cstdlib>
#include <iostream>
#ifdef PLATFORM_WINDOWS
long long atoll(const char* string)
{
return _atoi64(string);
}
#endif
UpdaterOptions::UpdaterOptions()
: mode(UpdateInstaller::Setup)
, waitPid(0)
, showVersion(false)
, forceElevated(false)
, autoClose(false)
{
}
UpdateInstaller::Mode stringToMode(const std::string& modeStr)
{
if (modeStr == "main")
{
return UpdateInstaller::Main;
}
else
{
if (!modeStr.empty())
{
LOG(Error,"Unknown mode " + modeStr);
}
return UpdateInstaller::Setup;
}
}
void UpdaterOptions::parseOldFormatArg(const std::string& arg, std::string* key, std::string* value)
{
size_t pos = arg.find('=');
if (pos != std::string::npos)
{
*key = arg.substr(0,pos);
*value = arg.substr(pos+1);
}
}
// this is a compatibility function to allow the updater binary
// to be involved by legacy versions of Mendeley Desktop
// which used a different syntax for the updater's command-line
// arguments
void UpdaterOptions::parseOldFormatArgs(int argc, char** argv)
{
for (int i=0; i < argc; i++)
{
std::string key;
std::string value;
parseOldFormatArg(argv[i],&key,&value);
if (key == "CurrentDir")
{
// CurrentDir is the directory containing the main application
// binary. On Mac and Linux this differs from the root of
// the installation directory
#ifdef PLATFORM_LINUX
// the main binary is in lib/mendeleydesktop/libexec,
// go up 3 levels
installDir = FileUtils::canonicalPath((value + "/../../../").c_str());
#elif defined(PLATFORM_MAC)
// the main binary is in Contents/MacOS,
// go up 2 levels
installDir = FileUtils::canonicalPath((value + "/../../").c_str());
#elif defined(PLATFORM_WINDOWS)
// the main binary is in the root of the install directory
installDir = value;
#endif
}
else if (key == "TempDir")
{
packageDir = value;
}
else if (key == "UpdateScriptFileName")
{
scriptPath = value;
}
else if (key == "AppFileName")
{
// TODO - Store app file name
}
else if (key == "PID")
{
waitPid = static_cast<PLATFORM_PID>(atoll(value.c_str()));
}
else if (key == "--main")
{
mode = UpdateInstaller::Main;
}
}
}
void UpdaterOptions::parse(int argc, char** argv)
{
AnyOption parser;
parser.setOption("install-dir");
parser.setOption("package-dir");
parser.setOption("finish-cmd");
parser.setOption("script");
parser.setOption("wait");
parser.setOption("mode");
parser.setFlag("version");
parser.setFlag("force-elevated");
parser.setFlag("auto-close");
parser.processCommandArgs(argc,argv);
if (parser.getValue("mode"))
{
mode = stringToMode(parser.getValue("mode"));
}
if (parser.getValue("install-dir"))
{
installDir = parser.getValue("install-dir");
}
if (parser.getValue("package-dir"))
{
packageDir = parser.getValue("package-dir");
}
if (parser.getValue("script"))
{
scriptPath = parser.getValue("script");
}
if (parser.getValue("wait"))
{
waitPid = static_cast<PLATFORM_PID>(atoll(parser.getValue("wait")));
}
if (parser.getValue("finish-cmd"))
{
finishCmd = parser.getValue("finish-cmd");
}
showVersion = parser.getFlag("version");
forceElevated = parser.getFlag("force-elevated");
autoClose = parser.getFlag("auto-close");
if (installDir.empty())
{
// if no --install-dir argument is present, try parsing
// the command-line arguments in the old format (which uses
// a list of 'Key=Value' args)
parseOldFormatArgs(argc,argv);
}
}
|