bool C4TableGraph::DumpToFile(const StdStrBuf &rszFilename, bool fAppend) const { assert(!!rszFilename); // nothing to write? if (!fWrapped && !iBackLogPos) return false; // try append if desired; create if unsuccessful CStdFile out; if (fAppend) if (!out.Append(rszFilename.getData())) fAppend = false; if (!fAppend) { if (!out.Create(rszFilename.getData())) return false; // print header out.WriteString("t\tv\n\r"); } // write out current timeframe int iEndTime = GetEndTime(); StdStrBuf buf; for (int iWriteTime = GetStartTime(); iWriteTime < iEndTime; ++iWriteTime) { buf.Format("%d\t%d\n\r", (int)iWriteTime, (int)GetValue(iWriteTime)); out.WriteString(buf.getData()); } return true; }
bool C4UpdateDlg::ApplyUpdate(const char *strUpdateFile, bool fDeleteUpdate, C4GUI::Screen *pScreen) { // Apply update: If the update file is a .ocu, it will extract c4group and apply the update. // If the update file is an installer, it will just launch that installer. StdStrBuf strUpdateProgEx, strUpdateArgs; bool fIsGroupUpdate = SEqualNoCase(GetExtension(strUpdateFile), C4CFN_UpdateGroupExtension+1); // Is this an update executable or an update group? if (fIsGroupUpdate) { // This is an update group (.ocu). Extract c4group and run it. // Find a place to extract the update Config.MakeTempUpdateFolder(); // Determine name of update program StdStrBuf strUpdateProg; strUpdateProg.Copy(C4CFN_UpdateProgram); // Windows: manually append extension because ExtractEntry() cannot properly glob and Extract() doesn't return failure values #ifdef _WIN32 strUpdateProg += ".exe"; #endif // Determine name of local extract of update program strUpdateProgEx.Copy(Config.AtTempUpdatePath(strUpdateProg.getData())); // Extract update program (the update should be applied using the new version) C4Group UpdateGroup; if (!UpdateGroup.Open(strUpdateFile)) { LogF("Error opening \"%s\": %s", strUpdateFile, UpdateGroup.GetError()); return false; } // Look for update program at top level if (!UpdateGroup.ExtractEntry(strUpdateProg.getData(), strUpdateProgEx.getData())) { LogF("Error extracting \"%s\": %s", strUpdateProg.getData(), UpdateGroup.GetError()); return false; } // Extract any needed library files UpdateGroup.Extract(C4CFN_UpdateProgramLibs, Config.AtTempUpdatePath(""), C4CFN_UpdateProgram); UpdateGroup.Close(); #ifdef _WIN32 // Notice: even if the update program and update group are in the temp path, they must be executed in our working directory DWORD ProcessID = GetCurrentProcessId(); //strUpdateArgs.Format("\"%s\" \"%s\" %s %lu", strUpdateProgEx.getData(), strUpdateFile, fDeleteUpdate ? "-yd" : "-y", (unsigned long)ProcessID); strUpdateArgs.Format("\"%s\" %s %lu", strUpdateFile, fDeleteUpdate ? "-yd" : "-y", (unsigned long)ProcessID); #if 0 // debug code to reroute updating via batch file CStdFile f; - reroute via vi f.Create(Config.AtTempUpdatePath("update.bat")); f.WriteString(FormatString("%s %s\npause\n", strUpdateProgEx.getData(), strUpdateArgs.getData()).getData()); f.Close(); strUpdateProgEx.Copy(Config.AtTempUpdatePath("update.bat")); strUpdateArgs.Copy(strUpdateProgEx); #endif #endif } else { // This "update" is actually an installer. Just run it. strUpdateProgEx = strUpdateFile; strUpdateArgs = ""; // if group was downloaded to temp path, delete it from there if (fDeleteUpdate) SCopy(strUpdateProgEx.getData(), Config.General.TempUpdatePath, CFG_MaxString); } // Execute update program Log(LoadResStr("IDS_PRC_LAUNCHINGUPDATE")); succeeded = true; #ifdef _WIN32 // Notice: even if the update program and update group are in the temp path, they must be executed in our working directory // the magic verb "runas" opens the update program in a shell requesting elevation int iError = (intptr_t)ShellExecute(NULL, L"runas", strUpdateProgEx.GetWideChar(), strUpdateArgs.GetWideChar(), Config.General.ExePath.GetWideChar(), SW_SHOW); if (iError <= 32) return false; // must quit ourselves for update program to work if (succeeded) Application.Quit(); #else if (pipe(c4group_output) == -1) { Log("Error creating pipe"); return false; } switch (pid = fork()) { // Error case -1: Log("Error creating update child process."); return false; // Child process case 0: // Close unused read end close(c4group_output[0]); // redirect stdout and stderr to the parent dup2(c4group_output[1], STDOUT_FILENO); dup2(c4group_output[1], STDERR_FILENO); if (c4group_output[1] != STDOUT_FILENO && c4group_output[1] != STDERR_FILENO) close(c4group_output[1]); if (fIsGroupUpdate) execl(C4CFN_UpdateProgram, C4CFN_UpdateProgram, "-v", strUpdateFile, (fDeleteUpdate ? "-yd" : "-y"), static_cast<char *>(0)); else execl(strUpdateFile, strUpdateFile, static_cast<char *>(0)); printf("execl failed: %s\n", strerror(errno)); exit(1); // Parent process default: // Close unused write end close(c4group_output[1]); // disable blocking fcntl(c4group_output[0], F_SETFL, O_NONBLOCK); // Open the update log dialog (this will update itself automatically from c4group_output) pScreen->ShowRemoveDlg(new C4UpdateDlg()); break; } #endif // done return succeeded; }