Planeshift

updaterengine.h

Go to the documentation of this file.
00001 /*
00002 * updaterengine.h - Author: Mike Gist
00003 *
00004 * Copyright (C) 2007 Atomic Blue ([email protected], http://www.atomicblue.org)
00005 *
00006 *
00007 * This program is free software; you can redistribute it and/or
00008 * modify it under the terms of the GNU General Public License
00009 * as published by the Free Software Foundation (version 2 of the License)
00010 * This program is distributed in the hope that it will be useful,
00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 * GNU General Public License for more details.
00014 * You should have received a copy of the GNU General Public License
00015 * along with this program; if not, write to the Free Software
00016 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00017 *
00018 */
00019 
00020 #ifndef __UPDATERENGINE_H__
00021 #define __UPDATERENGINE_H__
00022 
00023 #include <iutil/objreg.h>
00024 #include <iutil/vfs.h>
00025 #include <iutil/cfgmgr.h>
00026 #include <csutil/csstring.h>
00027 #include <iutil/document.h>
00028 #include <csutil/threading/thread.h>
00029 #include <csutil/list.h>
00030 
00031 
00032 #include "download.h"
00033 #include "util/fileutil.h"
00034 #include "util/singleton.h"
00035 
00036 /* To be incremented every time we want to make an update. */
00037 #define UPDATER_VERSION 3.07
00038 
00039 struct iConfigManager;
00040 struct iVFS;
00041 
00042 #define UPDATER_VERSION_MAJOR 3
00043 #define UPDATER_VERSION_MINOR 07
00044 
00045 #ifdef CS_PLATFORM_WIN32
00046         #define SELFUPDATER_TEMPFILE_POSTFIX ".tmp.exe"
00047         #define SELFUPDATER_POSTFIX              ".exe"
00048 #else
00049         #define SELFUPDATER_TEMPFILE_POSTFIX ".tmp.bin"
00050         #define SELFUPDATER_POSTFIX              ".bin"
00051 #endif
00052 
00053 
00054 class InfoShare
00055 {
00056 private:
00057     /* Set to true if we want the GUI to exit. */
00058     volatile bool exitGUI;
00059 
00060     /* Set to true to cancel the updater. */
00061     volatile bool cancelUpdater;
00062 
00063     /* Set to true if we need to tell the GUI that an update is pending. */
00064     volatile bool updateNeeded;
00065 
00066     /* Set to true if an update is available but admin permissions are needed. */
00067     volatile bool updateAdminNeeded;
00068 
00069     /* If true, then it's okay to perform the update. */
00070     volatile bool performUpdate;
00071 
00072     /* Set to true to perform an integrity check. */
00073     volatile bool checkIntegrity;
00074 
00075     /* Set to true once we have checked for an update. */
00076     volatile bool updateChecked;
00077 
00078     /* Set to true if the updaterinfo.xml gets out of sync. */
00079     volatile bool outOfSync;
00080 
00081     csString currentClientVersion;
00082     /* Safety. */
00083     CS::Threading::Mutex mutex;
00084 
00085     /* Sync condition */
00086     CS::Threading::Condition synched;
00087     bool synching;
00088 
00089     /* Array to store console output. */
00090     csList<csString> consoleOut;
00091 public:
00092 
00093     InfoShare()
00094     {
00095         exitGUI = false;
00096         performUpdate = false;
00097         updateNeeded = false;
00098         updateAdminNeeded = false;
00099         checkIntegrity = false;
00100         updateChecked = false;
00101         cancelUpdater = false;
00102         outOfSync = false;
00103         synching = false;
00104         mutex.Initialize();
00105     }
00106 
00107     inline void SetExitGUI(bool v) { exitGUI = v; }
00108     inline void SetUpdateNeeded(bool v) { updateNeeded = v; }
00109     inline void SetUpdateAdminNeeded(bool v) { updateAdminNeeded = v; }
00110     inline void SetPerformUpdate(bool v) { performUpdate = v; }
00111     inline void SetCheckIntegrity(bool v) { checkIntegrity = v; }
00112     inline void SetCancelUpdater(bool v) { cancelUpdater = v; }
00113     inline void SetOutOfSync(bool v) { outOfSync = v; }
00114     inline void SetUpdateChecked(bool v) { updateChecked = v; }
00115     inline void SetCurrentClientVersion(csString v) { currentClientVersion = v; }
00116     inline void Sync()
00117     {
00118         CS::Threading::MutexScopedLock lock(mutex);
00119         if(!synching)
00120         {
00121             synching = true;
00122             synched.Wait(mutex);
00123         }
00124         else
00125         {
00126             synched.NotifyAll();
00127             synching = false;
00128         }
00129     }
00130 
00131     inline bool GetExitGUI() { return exitGUI; }
00132     inline bool GetUpdateNeeded() { return updateNeeded; }
00133     inline bool GetUpdateAdminNeeded() { return updateAdminNeeded; }
00134     inline bool GetPerformUpdate() { return performUpdate; }
00135     inline bool GetCheckIntegrity() { return checkIntegrity; }
00136     inline bool GetCancelUpdater() { return cancelUpdater; }
00137     inline bool GetOutOfSync() { return outOfSync; }
00138     inline bool GetUpdateChecked() { return updateChecked; }
00139     inline csString GetCurrentClientVersion() { return currentClientVersion; }
00140 
00141     inline void EmptyConsole()
00142     {
00143         CS::Threading::MutexScopedLock lock(mutex);
00144         consoleOut.DeleteAll();
00145     }
00146 
00147     inline void ConsolePush(csString str)
00148     {
00149         CS::Threading::MutexScopedLock lock(mutex);
00150         consoleOut.PushBack(str);
00151     }
00152 
00153     inline csString ConsolePop()
00154     {
00155         CS::Threading::MutexScopedLock lock(mutex);
00156         csString ret = consoleOut.Front();
00157         consoleOut.PopFront();
00158         return ret;
00159     }
00160 
00161     inline bool ConsoleIsEmpty()
00162     {
00163         return consoleOut.IsEmpty();
00164     }
00165 };
00166 
00167 class UpdaterEngine : public CS::Threading::Runnable, public Singleton<UpdaterEngine>
00168 {
00169 private:
00170     iObjectRegistry* object_reg;
00171 
00172     /* VFS to manage our zips */
00173     csRef<iVFS> vfs;
00174 
00175     /* File utilities */
00176     FileUtil* fileUtil;
00177 
00178     /* Downloader */
00179     Downloader* downloader;
00180 
00181     /* Config file; check for proxy and clean update. */
00182     UpdaterConfig* config;
00183 
00184     /* Real name of the app (e.g. updater, pslaunch, etc.) */
00185     csString appName;
00186 
00187 
00188     /* Info shared with other threads. */
00189     InfoShare *infoShare;
00190 
00191     /* True if we're using a GUI. */
00192     bool hasGUI;
00193 
00194     /* Output console prints to file. */
00195     csRef<iFile> log;
00196 
00197     /* Function shared by ctors */
00198     void Init(csStringArray& args, iObjectRegistry* _object_reg, const char* _appName,
00199               InfoShare *infoshare);
00200 
00201     void CheckAndUpdate(iDocumentNode* md5sums, csString baseurl, bool accepted = false);
00202     void CheckMD5s(iDocumentNode* md5sums, csString baseurl, bool accepted, csRefArray<iDocumentNode> *failed);
00203     bool UpdateFile(csString baseurl, csString mountPath, csString filePath, bool failedEx = false, bool inZipFile = false);
00204 
00205     csString GetMD5OfFile(csString filePath);
00206 
00207 public:
00208     UpdaterEngine(csStringArray& args, iObjectRegistry* _object_reg, const char* _appName);
00209     UpdaterEngine(csStringArray& args, iObjectRegistry* _object_reg, const char* _appName,
00210                   InfoShare *infoshare);
00211     ~UpdaterEngine();
00212 
00213     /* Return the config object */
00214     UpdaterConfig* GetConfig() const { return config; }
00215 
00216     /* Return VFS */
00217     iVFS* GetVFS() const { return vfs; }
00218 
00219     csString GetCurrentClientVersion();
00220 
00221     // Find the config node given an xml file name.
00222     csPtr<iDocumentNode> GetRootNode(const char* fileName, csRef<iDocument>* document = 0);
00223 
00224     /*
00225     * Starts and finishes a self update
00226     * Returns true if a restart is needed (MSVC compiled)
00227     */
00228     bool SelfUpdate(int selfUpdating);
00229 
00230     /* Starts a general update */
00231     void GeneralUpdate();
00232 
00233     /* Check for any updates */
00234     void CheckForUpdates();
00235 
00236     /* Check for updater/launcher updates */
00237     bool CheckUpdater();
00238 
00239     /* Check for 'general' updates */
00240     bool CheckGeneral();
00241 
00242     /* Check the integrity of the install */
00243     void CheckIntegrity(bool automatic = false);
00244 
00245     /* Switch updater mirror. */
00246     bool SwitchMirror();
00247 
00248     /* Check if a quit event has been triggered. */
00249     inline bool CheckQuit() { return infoShare->GetCancelUpdater(); }
00250 
00251     /* Print to console and save to array for GUI output. */
00252     void PrintOutput(const char* string, ...);
00253 
00254     /* Run updater thread. */
00255     void Run();
00256 };
00257 
00258 #endif // __UPDATERENGINE_H__