31 #include <netinet/in.h>
32 #include <arpa/inet.h>
36 int C4UpdateDlg::c4group_output[2];
37 bool C4UpdateDlg::succeeded;
42 C4UpdateDlg::C4UpdateDlg() :
C4GUI::InfoDialog(
LoadResStr(
"IDS_TYPE_UPDATE"), 10)
50 void C4UpdateDlg::UserClose(
bool fOK)
59 Dialog::UserClose(fOK);
70 void C4UpdateDlg::UpdateText()
75 AddLine(
"Win32 is currently not using the C4UpdateDlg!");
76 UpdateRunning =
false;
78 char c4group_output_buf[513];
81 amount_read = read(c4group_output[0], c4group_output_buf, 512);
83 if (amount_read == -1)
89 AddLine(Errormessage.
getData());
90 UpdateRunning =
false;
94 else if (amount_read == 0)
97 close(c4group_output[0]);
100 if (waitpid(pid, &child_status, WNOHANG) == -1)
102 LogF(
"error in waitpid: %s", strerror(errno));
103 AddLineFmt(
"error in waitpid: %s", strerror(errno));
107 else if (WIFEXITED(child_status) && WEXITSTATUS(child_status))
109 LogF(
"c4group returned status %d", WEXITSTATUS(child_status));
110 AddLineFmt(
"c4group returned status %d", WEXITSTATUS(child_status));
113 else if (WIFSIGNALED(child_status))
115 LogF(
"c4group killed with signal %d", WTERMSIG(child_status));
116 AddLineFmt(
"c4group killed with signal %d", WTERMSIG(child_status));
124 UpdateRunning =
false;
128 c4group_output_buf[amount_read] = 0;
130 LogF(
"%s", c4group_output_buf);
131 AddLineFmt(
"%s", c4group_output_buf);
138 pTextWin->UpdateHeight();
139 pTextWin->ScrollToBottom();
146 void C4UpdateDlg::RedirectToDownloadPage()
148 OpenURL(
"http://www.openclonk.org/download");
151 bool C4UpdateDlg::DoUpdate(
const char *szUpdateURL,
C4GUI::Screen *pScreen)
153 if(szUpdateURL ==
nullptr || strlen(szUpdateURL) == 0)
156 RedirectToDownloadPage();
164 strRemoteURL.Replace(
"http://",
"");
169 RedirectToDownloadPage();
175 return ApplyUpdate(strLocalFilename.getData(),
true, pScreen);
178 bool C4UpdateDlg::ApplyUpdate(
const char *strUpdateFile,
bool fDeleteUpdate,
C4GUI::Screen *pScreen)
182 StdStrBuf strUpdateProgEx, strUpdateArgs;
195 strUpdateProg +=
".exe";
202 if (!UpdateGroup.
Open(strUpdateFile))
204 LogF(
"Error opening \"%s\": %s", strUpdateFile, UpdateGroup.
GetError());
218 DWORD ProcessID = GetCurrentProcessId();
220 strUpdateArgs.
Format(
"\"%s\" %s %lu", strUpdateFile, fDeleteUpdate ?
"-yd" :
"-y", (
unsigned long)ProcessID);
228 strUpdateArgs.
Copy(strUpdateProgEx);
235 strUpdateProgEx = strUpdateFile;
248 int iError = (intptr_t)ShellExecute(
nullptr, L
"runas", strUpdateProgEx.GetWideChar(), strUpdateArgs.GetWideChar(),
Config.
General.
ExePath.GetWideChar(), SW_SHOW);
249 if (iError <= 32)
return false;
254 if (pipe(c4group_output) == -1)
256 Log(
"Error creating pipe");
259 switch (pid = fork())
263 Log(
"Error creating update child process.");
268 close(c4group_output[0]);
270 dup2(c4group_output[1], STDOUT_FILENO);
271 dup2(c4group_output[1], STDERR_FILENO);
272 if (c4group_output[1] != STDOUT_FILENO && c4group_output[1] != STDERR_FILENO)
273 close(c4group_output[1]);
277 execl(strUpdateFile, strUpdateFile,
static_cast<char *
>(0));
278 printf(
"execl failed: %s\n", strerror(errno));
283 close(c4group_output[1]);
285 fcntl(c4group_output[0], F_SETFL, O_NONBLOCK);
295 bool C4UpdateDlg::IsValidUpdate(
const char *szVersion)
298 if (szVersion ==
nullptr || strlen(szVersion) == 0)
return false;
299 return strcmp(szVersion,strVersion.
getData()) != 0;
302 bool C4UpdateDlg::CheckForUpdates(
C4GUI::Screen *pScreen,
bool fAutomatic)
306 if (time(
nullptr) -
Config.
Network.LastUpdateTime < 60 * 60 * 24)
319 bool fSuccess =
false, fAborted =
false;
327 while (UpdateClient.
isBusy())
332 if (pWaitDlg)
if (!pWaitDlg->
IsShown()) { fAborted =
true;
break; }
336 fSuccess = UpdateClient.
GetVersion(&VersionInfo);
352 const char *szErrMsg = UpdateClient.
GetError();
362 if (C4UpdateDlg::IsValidUpdate(VersionInfo.
getData()))
367 if (!DoUpdate(UpdateURL.
getData(), pScreen))
bool OpenURL(const char *szURL)
#define C4CFN_UpdateProgram
#define C4CFN_UpdateProgramLibs
#define C4CFN_UpdateGroupExtension
C4Application Application
const char * LoadResStr(const char *id)
bool Log(const char *szMessage)
bool LogF(const char *strMessage,...)
void SCopy(const char *szSource, char *sTarget, size_t iMaxL)
bool SEqualNoCase(const char *szStr1, const char *szStr2, int iLen)
StdStrBuf FormatString(const char *szFmt,...)
char * GetExtension(char *szFilename)
char * GetFilename(char *szPath)
C4InteractiveThread InteractiveThread
char TempUpdatePath[CFG_MaxString+1]
const char * AtTempPath(const char *filename)
const char * MakeTempUpdateFolder()
const char * AtTempUpdatePath(const char *filename)
static bool DownloadFile(const char *szDLType, C4GUI::Screen *pScreen, const char *szURL, const char *szSaveAsFilename, const char *szNotFoundMessage=nullptr)
void SetDelOnClose(bool fToVal=true)
void ShowDialog(Dialog *pDlg, bool fFade)
bool ShowRemoveDlg(Dialog *pDlg)
bool ShowMessageModal(const char *szMessage, const char *szCaption, DWORD dwButtons, Icons icoIcon, int32_t *piConfigDontShowAgainSetting=nullptr)
bool ShowMessage(const char *szMessage, const char *szCaption, Icons icoIcon, int32_t *piConfigDontShowAgainSetting=nullptr)
bool Extract(const char *files, const char *destination=nullptr, const char *exclude=nullptr)
bool ExtractEntry(const char *filename, const char *destination=nullptr)
bool Open(const char *group_name, bool do_create=false)
virtual const char * GetError() const
bool SetServer(const char *szServerAddress)
void SetNotify(class C4InteractiveThread *pnNotify)
void RemoveProc(StdSchedulerProc *pProc)
bool AddProc(StdSchedulerProc *pProc)
bool GetVersion(StdStrBuf *pVersion)
bool GetUpdateURL(StdStrBuf *pUpdateURL)
bool Close(StdBuf **ppMemory=nullptr)
bool Create(const char *szFileName, bool fCompressed=false, bool fExecutable=false, bool fMemory=false)
bool WriteString(const char *szStr)
bool ScheduleProcs(int iTimeout=1000/36)
const char * getData() const
void Append(const char *pnData, size_t iChars)
void Format(const char *szFmt,...) GNUC_FORMAT_ATTRIBUTE_O