Planeshift
updaterengine.h
Go to the documentation of this file.
1 /*
2 * updaterengine.h - Author: Mike Gist
3 *
4 * Copyright (C) 2007 Atomic Blue (info@planeshift.it, http://www.atomicblue.org)
5 *
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation (version 2 of the License)
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 *
18 */
19 
20 #ifndef __UPDATERENGINE_H__
21 #define __UPDATERENGINE_H__
22 
23 #include <iutil/objreg.h>
24 #include <iutil/vfs.h>
25 #include <iutil/cfgmgr.h>
26 #include <csutil/csstring.h>
27 #include <iutil/document.h>
28 #include <csutil/threading/thread.h>
29 #include <csutil/list.h>
30 
31 
32 #include "download.h"
33 #include "util/fileutil.h"
34 #include "util/singleton.h"
35 
36 /* To be incremented every time we want to make an update. */
37 #define UPDATER_VERSION 3.07
38 
39 struct iConfigManager;
40 struct iVFS;
41 
42 #define UPDATER_VERSION_MAJOR 3
43 #define UPDATER_VERSION_MINOR 07
44 
45 #ifdef CS_PLATFORM_WIN32
46  #define SELFUPDATER_TEMPFILE_POSTFIX ".tmp.exe"
47  #define SELFUPDATER_POSTFIX ".exe"
48 #else
49  #define SELFUPDATER_TEMPFILE_POSTFIX ".tmp.bin"
50  #define SELFUPDATER_POSTFIX ".bin"
51 #endif
52 
53 
54 class InfoShare
55 {
56 private:
57  /* Set to true if we want the GUI to exit. */
58  volatile bool exitGUI;
59 
60  /* Set to true to cancel the updater. */
61  volatile bool cancelUpdater;
62 
63  /* Set to true if we need to tell the GUI that an update is pending. */
64  volatile bool updateNeeded;
65 
66  /* Set to true if an update is available but admin permissions are needed. */
67  volatile bool updateAdminNeeded;
68 
69  /* If true, then it's okay to perform the update. */
70  volatile bool performUpdate;
71 
72  /* Set to true to perform an integrity check. */
73  volatile bool checkIntegrity;
74 
75  /* Set to true once we have checked for an update. */
76  volatile bool updateChecked;
77 
78  /* Set to true if the updaterinfo.xml gets out of sync. */
79  volatile bool outOfSync;
80 
81  csString currentClientVersion;
82  /* Safety. */
83  CS::Threading::Mutex mutex;
84 
85  /* Sync condition */
86  CS::Threading::Condition synched;
87  bool synching;
88 
89  /* Array to store console output. */
90  csList<csString> consoleOut;
91 public:
92 
94  {
95  exitGUI = false;
96  performUpdate = false;
97  updateNeeded = false;
98  updateAdminNeeded = false;
99  checkIntegrity = false;
100  updateChecked = false;
101  cancelUpdater = false;
102  outOfSync = false;
103  synching = false;
104  mutex.Initialize();
105  }
106 
107  inline void SetExitGUI(bool v) { exitGUI = v; }
108  inline void SetUpdateNeeded(bool v) { updateNeeded = v; }
109  inline void SetUpdateAdminNeeded(bool v) { updateAdminNeeded = v; }
110  inline void SetPerformUpdate(bool v) { performUpdate = v; }
111  inline void SetCheckIntegrity(bool v) { checkIntegrity = v; }
112  inline void SetCancelUpdater(bool v) { cancelUpdater = v; }
113  inline void SetOutOfSync(bool v) { outOfSync = v; }
114  inline void SetUpdateChecked(bool v) { updateChecked = v; }
115  inline void SetCurrentClientVersion(csString v) { currentClientVersion = v; }
116  inline void Sync()
117  {
118  CS::Threading::MutexScopedLock lock(mutex);
119  if(!synching)
120  {
121  synching = true;
122  synched.Wait(mutex);
123  }
124  else
125  {
126  synched.NotifyAll();
127  synching = false;
128  }
129  }
130 
131  inline bool GetExitGUI() { return exitGUI; }
132  inline bool GetUpdateNeeded() { return updateNeeded; }
133  inline bool GetUpdateAdminNeeded() { return updateAdminNeeded; }
134  inline bool GetPerformUpdate() { return performUpdate; }
135  inline bool GetCheckIntegrity() { return checkIntegrity; }
136  inline bool GetCancelUpdater() { return cancelUpdater; }
137  inline bool GetOutOfSync() { return outOfSync; }
138  inline bool GetUpdateChecked() { return updateChecked; }
139  inline csString GetCurrentClientVersion() { return currentClientVersion; }
140 
141  inline void EmptyConsole()
142  {
143  CS::Threading::MutexScopedLock lock(mutex);
144  consoleOut.DeleteAll();
145  }
146 
147  inline void ConsolePush(csString str)
148  {
149  CS::Threading::MutexScopedLock lock(mutex);
150  consoleOut.PushBack(str);
151  }
152 
153  inline csString ConsolePop()
154  {
155  CS::Threading::MutexScopedLock lock(mutex);
156  csString ret = consoleOut.Front();
157  consoleOut.PopFront();
158  return ret;
159  }
160 
161  inline bool ConsoleIsEmpty()
162  {
163  return consoleOut.IsEmpty();
164  }
165 };
166 
167 class UpdaterEngine : public CS::Threading::Runnable, public Singleton<UpdaterEngine>
168 {
169 private:
170  iObjectRegistry* object_reg;
171 
172  /* VFS to manage our zips */
173  csRef<iVFS> vfs;
174 
175  /* File utilities */
176  FileUtil* fileUtil;
177 
178  /* Downloader */
179  Downloader* downloader;
180 
181  /* Config file; check for proxy and clean update. */
182  UpdaterConfig* config;
183 
184  /* Real name of the app (e.g. updater, pslaunch, etc.) */
185  csString appName;
186 
187 
188  /* Info shared with other threads. */
189  InfoShare *infoShare;
190 
191  /* True if we're using a GUI. */
192  bool hasGUI;
193 
194  /* Output console prints to file. */
195  csRef<iFile> log;
196 
197  /* Function shared by ctors */
198  void Init(csStringArray& args, iObjectRegistry* _object_reg, const char* _appName,
199  InfoShare *infoshare);
200 
201  void CheckAndUpdate(iDocumentNode* md5sums, csString baseurl, bool accepted = false);
202  void CheckMD5s(iDocumentNode* md5sums, csString baseurl, bool accepted, csRefArray<iDocumentNode> *failed);
203  bool UpdateFile(csString baseurl, csString mountPath, csString filePath, bool failedEx = false, bool inZipFile = false);
204 
205  csString GetMD5OfFile(csString filePath);
206 
207 public:
208  UpdaterEngine(csStringArray& args, iObjectRegistry* _object_reg, const char* _appName);
209  UpdaterEngine(csStringArray& args, iObjectRegistry* _object_reg, const char* _appName,
210  InfoShare *infoshare);
211  ~UpdaterEngine();
212 
213  /* Return the config object */
214  UpdaterConfig* GetConfig() const { return config; }
215 
216  /* Return VFS */
217  iVFS* GetVFS() const { return vfs; }
218 
219  csString GetCurrentClientVersion();
220 
221  // Find the config node given an xml file name.
222  csPtr<iDocumentNode> GetRootNode(const char* fileName, csRef<iDocument>* document = 0);
223 
224  /*
225  * Starts and finishes a self update
226  * Returns true if a restart is needed (MSVC compiled)
227  */
228  bool SelfUpdate(int selfUpdating);
229 
230  /* Starts a general update */
231  void GeneralUpdate();
232 
233  /* Check for any updates */
234  void CheckForUpdates();
235 
236  /* Check for updater/launcher updates */
237  bool CheckUpdater();
238 
239  /* Check for 'general' updates */
240  bool CheckGeneral();
241 
242  /* Check the integrity of the install */
243  void CheckIntegrity(bool automatic = false);
244 
245  /* Switch updater mirror. */
246  bool SwitchMirror();
247 
248  /* Check if a quit event has been triggered. */
249  inline bool CheckQuit() { return infoShare->GetCancelUpdater(); }
250 
251  /* Print to console and save to array for GUI output. */
252  void PrintOutput(const char* string, ...);
253 
254  /* Run updater thread. */
255  void Run();
256 };
257 
258 #endif // __UPDATERENGINE_H__
bool GetCheckIntegrity()
void Sync()
csString GetCurrentClientVersion()
void SetOutOfSync(bool v)
void SetPerformUpdate(bool v)
bool GetUpdateNeeded()
void EmptyConsole()
void SetCancelUpdater(bool v)
void SetCurrentClientVersion(csString v)
csString ConsolePop()
bool GetOutOfSync()
bool GetUpdateAdminNeeded()
bool ConsoleIsEmpty()
UpdaterConfig * GetConfig() const
void SetUpdateAdminNeeded(bool v)
bool GetPerformUpdate()
bool GetCancelUpdater()
iVFS * GetVFS() const
void SetUpdateNeeded(bool v)
void SetUpdateChecked(bool v)
bool GetExitGUI()
void SetExitGUI(bool v)
void ConsolePush(csString str)
bool GetUpdateChecked()
void SetCheckIntegrity(bool v)