OpenClonk
C4Update.cpp File Reference
#include "C4Include.h"
#include "c4group/C4Update.h"
#include "C4Version.h"
#include "c4group/C4Components.h"
#include "c4group/C4Group.h"
Include dependency graph for C4Update.cpp:

Go to the source code of this file.

Classes

class  C4GroupEx
 

Functions

C4ConfigGetCfg ()
 
bool C4Group_CopyEntry (C4Group *pFrom, C4Group *pTo, const char *strItemName)
 
bool C4Group_ApplyUpdate (C4Group &hGroup, unsigned long ParentProcessID)
 
void MemScramble (BYTE *, int)
 

Variables

char C4Group_TempPath [_MAX_PATH_LEN]
 

Function Documentation

◆ C4Group_ApplyUpdate()

bool C4Group_ApplyUpdate ( C4Group hGroup,
unsigned long  ParentProcessID 
)

Definition at line 42 of file C4Update.cpp.

43 {
44  // Wait for parent process to terminate (so we can safely replace the executable)
45 #ifdef _WIN32
46  if(ParentProcessID)
47  {
48  HANDLE ParentProcess = OpenProcess(SYNCHRONIZE, FALSE, ParentProcessID);
49  if(ParentProcess)
50  {
51  // If we couldn't find a handle then either
52  // a) the process terminated already, which is great.
53  // b) OpenProcess() failed, which is not so great. But let's still try to do
54  // the update.
55  printf("Waiting for parent process to terminate...");
56  DWORD res = WaitForSingleObject(ParentProcess, 10000);
57  if(res == WAIT_TIMEOUT)
58  fprintf(stderr, "Parent process did not terminate after 10 seconds. Continuing...");
59  }
60  }
61 #else
62  // We could use waitpid on Unix, but we don't need that functionality there anyway...
63 #endif
64 
65  // Process object update group (GRPUP_Entries.txt found)
66  C4UpdatePackage Upd;
67  if (hGroup.FindEntry(C4CFN_UpdateEntries))
68  if (Upd.Load(&hGroup))
69  {
70  // Do update check first (ensure packet has everything it needs in order to perfom the update)
71  int iRes = Upd.Check(&hGroup);
72  switch (iRes)
73  {
74  // Bad version - checks against version of the applying executable (major version must match, minor version must be equal or higher)
76  fprintf(stderr, "This update %s can only be applied using version %d.%d.%d.%d or higher.\n", Upd.Name, Upd.RequireVersion[0], Upd.RequireVersion[1], Upd.RequireVersion[2], Upd.RequireVersion[3]);
77  return false;
78  // Target not found: keep going
80  fprintf(stderr, "Target %s for update %s not found. Ignoring.\n", Upd.DestPath, Upd.Name);
81  return true;
82  // Target mismatch: abort updating
84  fprintf(stderr, "Target %s incorrect version for update %s. Ignoring.\n", Upd.DestPath, Upd.Name);
85  return true;
86  // Target already updated: keep going
88  fprintf(stderr,"Target %s already up-to-date at %s.\n", Upd.DestPath, Upd.Name);
89  return true;
90  // Ok to perform update
91  case C4UPD_CHK_OK:
92  printf("Updating %s to %s... ", Upd.DestPath, Upd.Name);
93  // Make sure the user sees the message while the work is in progress
94  fflush(stdout);
95  // Execute update
96  if (Upd.Execute(&hGroup))
97  {
98  printf("Ok\n");
99  return true;
100  }
101  else
102  {
103  printf("Failed\n");
104  return false;
105  }
106  // Unknown return value from update
107  default:
108  fprintf(stderr,"Unknown error while updating.\n");
109  return false;
110  }
111  }
112 
113  // Process binary update group (AutoUpdate.txt found, additional binary files found)
114  if (hGroup.EntryCount(C4CFN_UpdateCore))
115  if (hGroup.EntryCount() - hGroup.EntryCount(C4CFN_UpdateCore) - hGroup.EntryCount("*.ocu") > 0)
116  {
117  // Notice: AutoUpdate.txt is currently not processed...
118  char strEntry[_MAX_FNAME_LEN] = "";
119  StdStrBuf strList;
120  printf("Updating binaries...\n");
121  hGroup.ResetSearch();
122  // Look for binaries
123  while (hGroup.FindNextEntry("*", strEntry))
124  // Accept everything except *.ocu, AutoUpdate.txt, and c4group.exe (which is assumed not to work under Windows)
125  if (!WildcardMatch("*.ocu", strEntry) && !WildcardMatch(C4CFN_UpdateCore, strEntry) && !WildcardMatch("c4group.exe", strEntry))
126  { strList += strEntry; strList += ";"; }
127  // Extract binaries to current working directory
128  if (!hGroup.Extract(strList.getData()))
129  return false;
130  // If extracted file is a group, explode it (this is meant for Clonk.app on Mac)
131  for (int i = 0; SGetModule(strList.getData(), i, strEntry); i++)
132  if (C4Group_IsGroup(strEntry))
133  {
134  printf("Exploding: %s\n", strEntry);
135  if (!C4Group_ExplodeDirectory(strEntry))
136  return false;
137  }
138  }
139 
140  // Process any child updates (*.ocu)
141  if (hGroup.FindEntry("*.ocu"))
142  {
143  // Process all children
144  char strEntry[_MAX_FNAME_LEN] = "";
145  C4Group hChild;
146  hGroup.ResetSearch();
147  while (hGroup.FindNextEntry("*.ocu", strEntry))
148  if (hChild.OpenAsChild(&hGroup, strEntry))
149  {
150  bool ok = C4Group_ApplyUpdate(hChild, 0);
151  hChild.Close();
152  // Failure on child update
153  if (!ok) return false;
154  }
155  }
156 
157  // Success
158  return true;
159 }
#define C4CFN_UpdateEntries
Definition: C4Components.h:51
#define C4CFN_UpdateCore
Definition: C4Components.h:50
bool C4Group_ExplodeDirectory(const char *filename)
Definition: C4Group.cpp:470
bool C4Group_IsGroup(const char *filename)
Definition: C4Group.cpp:104
bool C4Group_ApplyUpdate(C4Group &hGroup, unsigned long ParentProcessID)
Definition: C4Update.cpp:42
#define C4UPD_CHK_NO_SOURCE
Definition: C4Update.h:41
#define C4UPD_CHK_BAD_VERSION
Definition: C4Update.h:44
#define C4UPD_CHK_ALREADY_UPDATED
Definition: C4Update.h:43
#define C4UPD_CHK_OK
Definition: C4Update.h:40
#define C4UPD_CHK_BAD_SOURCE
Definition: C4Update.h:42
#define _MAX_FNAME_LEN
uint32_t DWORD
bool SGetModule(const char *szList, int iIndex, char *sTarget, int iSize)
Definition: Standard.cpp:539
bool WildcardMatch(const char *szWildcard, const char *szString)
Definition: StdFile.cpp:396
bool FindNextEntry(const char *wildcard, StdStrBuf *filename=nullptr, size_t *size=nullptr, bool start_at_filename=false)
Definition: C4Group.cpp:2217
bool Extract(const char *files, const char *destination=nullptr, const char *exclude=nullptr)
Definition: C4Group.cpp:1808
int EntryCount(const char *wildcard=nullptr)
Definition: C4Group.cpp:2314
bool OpenAsChild(C4Group *mother, const char *entry_name, bool is_exclusive=false, bool do_create=false)
Definition: C4Group.cpp:1952
void ResetSearch(bool reload_contents=false)
Definition: C4Group.cpp:1316
bool Close()
Definition: C4Group.cpp:971
bool FindEntry(const char *wildcard, StdStrBuf *filename=nullptr, size_t *size=nullptr)
Definition: C4Group.cpp:2211
int32_t RequireVersion[4]
Definition: C4Update.h:28
char Name[C4MaxName+1]
Definition: C4Update.h:29
char DestPath[_MAX_PATH_LEN]
Definition: C4Update.h:30
int Check(C4Group *pGroup)
Definition: C4Update.cpp:431
bool Load(C4Group *pGroup)
Definition: C4Update.cpp:280
bool Execute(C4Group *pGroup)
Definition: C4Update.cpp:303
const char * getData() const
Definition: StdBuf.h:442

References _MAX_FNAME_LEN, C4CFN_UpdateCore, C4CFN_UpdateEntries, C4Group_ExplodeDirectory(), C4Group_IsGroup(), C4UPD_CHK_ALREADY_UPDATED, C4UPD_CHK_BAD_SOURCE, C4UPD_CHK_BAD_VERSION, C4UPD_CHK_NO_SOURCE, C4UPD_CHK_OK, C4UpdatePackage::Check(), C4Group::Close(), C4UpdatePackageCore::DestPath, C4Group::EntryCount(), C4UpdatePackage::Execute(), C4Group::Extract(), C4Group::FindEntry(), C4Group::FindNextEntry(), StdStrBuf::getData(), C4UpdatePackage::Load(), C4UpdatePackageCore::Name, C4Group::OpenAsChild(), C4UpdatePackageCore::RequireVersion, C4Group::ResetSearch(), SGetModule(), and WildcardMatch().

Referenced by ProcessGroup().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ C4Group_CopyEntry()

bool C4Group_CopyEntry ( C4Group pFrom,
C4Group pTo,
const char *  strItemName 
)

Definition at line 31 of file C4Update.cpp.

32 {
33  // read entry
34  char *pData; size_t iSize;
35  if (!pFrom->LoadEntry(strItemName, &pData, &iSize))
36  return false;
37  if (!pTo->Add(strItemName, pData, iSize, false, true))
38  return false;
39  return true;
40 }
int iSize
Definition: TstC4NetIO.cpp:32
bool Add(const char *filename, const char *entry_name)
Definition: C4Group.cpp:1621
bool LoadEntry(const char *entry_name, char **buffer, size_t *size_info=nullptr, int zeros_to_append=0)
Definition: C4Group.cpp:2375

References C4Group::Add(), iSize, and C4Group::LoadEntry().

Referenced by C4UpdatePackage::DoUpdate(), and C4UpdatePackage::MkUp().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GetCfg()

C4Config* GetCfg ( )

◆ MemScramble()

void MemScramble ( BYTE buffer,
int  size 
)

Definition at line 534 of file C4Group.cpp.

535 {
536  // XOR deface
537  for (int cnt = 0; cnt < size; cnt++)
538  {
539  buffer[cnt] ^= 237;
540  }
541  // BYTE swap
542  for (int cnt = 0; cnt + 2 < size; cnt += 3)
543  {
544  BYTE temp = buffer[cnt];
545  buffer[cnt] = buffer[cnt + 2];
546  buffer[cnt + 2] = temp;
547  }
548 }
uint8_t BYTE

Referenced by C4UpdatePackage::MakeUpdate(), C4Group::OpenAsChild(), and C4Group::Save().

Here is the caller graph for this function:

Variable Documentation

◆ C4Group_TempPath