bool UninstallAllThread::hasPaidBranch(UserCore::Item::ItemInfoI* item) { for (size_t z=0; z<item->getBranchCount(); z++) { UserCore::Item::BranchInfoI* bi = item->getBranch(z); if (HasAllFlags(bi->getFlags(), UserCore::Item::BranchInfoI::BF_ONACCOUNT) && !HasAnyFlags(bi->getFlags(), UserCore::Item::BranchInfoI::BF_FREE|UserCore::Item::BranchInfoI::BF_DEMO|UserCore::Item::BranchInfoI::BF_TEST)) return true; } return false; }
void InternalLink::showPreorderPrompt(DesuraId id, bool isPreload) { UserCore::Item::ItemInfoI* item = GetUserCore()->getItemManager()->findItemInfo( id ); if (!item) return; UserCore::Item::BranchInfoI* bi = item->getCurrentBranch(); if (!bi) { for (size_t x=0; x<item->getBranchCount(); x++) { UserCore::Item::BranchInfoI *temp = item->getBranch(x); if (temp->isPreOrder()) { bi = temp; break; } } } if (!bi) return; const char* str = bi->getPreOrderExpDate(); uint32 days; uint32 hours; std::string time_available = UTIL::MISC::dateTimeToDisplay(str); UTIL::MISC::getTimeDiffFromNow(str, days, hours); gcString title(Managers::GetString("#IF_PRELOADLAUNCH_TITLE"), item->getName()); gcString msg(Managers::GetString("#IF_PRELOADLAUNCH"), item->getName(), days, Managers::GetString(isPreload?"#IF_PRELOADLAUNCH_PRELOADED":"#IF_PRELOADLAUNCH_PREORDERED"), time_available, Managers::GetString(days == 1 ? "#IF_PRELOADLAUNCH_WORD_DAY":"#IF_PRELOADLAUNCH_WORD_DAYS")); PreloadButtonHelper pobh(id); if (pobh.m_bOtherBranches) msg += gcString(Managers::GetString("#IF_PRELOADLAUNCH_INSTALLOTHER_INFO"), item->getName()); gcMessageBox(g_pMainApp->getMainWindow(), msg, title, wxICON_EXCLAMATION|wxCLOSE, &pobh); }
void CDKInfo::setInfo(DesuraId id, const char* key) { BasePage::setInfo(id); UserCore::Item::ItemInfoI *info = getItemInfo(); if (!info) { GetParent()->Close(); return; } m_butLaunch->Enable(info->isLaunchable()); if (checkForArma(id, key)) return; m_tbCdKey->ChangeValue(key); tokenizeKey(key); UserCore::Item::BranchInfoI* cb = info->getCurrentBranch(); if (cb && cb->isSteamGame()) { m_labInfo->SetLabel(gcWString(Managers::GetString(L"#CDK_INFO_STEAM"), info->getName())); m_labInfo->Wrap(360); m_butActivate = new gcButton(this, wxID_ANY, Managers::GetString(L"#CDK_ACTIVATE")); m_pButtonSizer->Clear(false); m_pButtonSizer->Add( 0, 0, 1, wxEXPAND, 5 ); m_pButtonSizer->Add(m_butActivate, 0, wxTOP|wxBOTTOM|wxLEFT, 5); m_pButtonSizer->Add(m_butLaunch, 0, wxTOP|wxBOTTOM|wxLEFT, 5); m_pButtonSizer->Add(m_butClose, 0, wxALL, 5); Layout(); Refresh(false); setParentSize(-1, 140); } }
void InstallBranch::onChoice(wxCommandEvent& event) { MCFBranch b = getBranch(); if (b == UINT_MAX || b == (UINT_MAX - 1)) { if (b == UINT_MAX) m_butInstall->SetLabel(Managers::GetString(L"#PLAY")); else m_butInstall->SetLabel(Managers::GetString(L"#FIND")); m_butInstall->Enable(true); return; } UserCore::Item::ItemInfoI* pItemInfo = GetUserCore()->getItemManager()->findItemInfo(m_Item); if ((m_bIsMod || m_bIsExpansion) && !m_bSelectBranch) pItemInfo = GetUserCore()->getItemManager()->findItemInfo(pItemInfo->getParentId()); UserCore::Item::BranchInfoI* bi = pItemInfo->getBranchById(b); m_bBuy = (!(bi->getFlags()&UserCore::Item::BranchInfoI::BF_ONACCOUNT) && !(bi->getFlags()&UserCore::Item::BranchInfoI::BF_FREE)); if (m_bBuy) m_butInstall->SetLabel(Managers::GetString(L"#PURCHASE")); else m_butInstall->SetLabel(Managers::GetString(L"#INSTALL")); bool noRelease = HasAllFlags(bi->getFlags(), UserCore::Item::BranchInfoI::BF_NORELEASES); bool isPreorder = bi->isPreOrder(); bool onAccount = HasAllFlags(bi->getFlags(), UserCore::Item::BranchInfoI::BF_ONACCOUNT); m_butInstall->Enable(!(noRelease && isPreorder && onAccount)); }
void UninstallInfoPage::init() { UserCore::Item::ItemInfoI *info = getItemInfo(); if (!info) { Close(); return; } bool hasPaidBranch = false; for (size_t x=0; x<info->getBranchCount(); x++) { UserCore::Item::BranchInfoI* b = info->getBranch(x); if (b && HasAnyFlags(b->getFlags(), UserCore::Item::BranchInfoI::BF_ONACCOUNT) && !HasAnyFlags(b->getFlags(), UserCore::Item::BranchInfoI::BF_DEMO|UserCore::Item::BranchInfoI::BF_FREE|UserCore::Item::BranchInfoI::BF_TEST)) hasPaidBranch = true; } if (hasPaidBranch) { m_cbAccount->Enable(false); m_cbAccount->SetValue(false); } if (info->getId().getType() == DesuraId::TYPE_LINK) { m_cbAccount->Enable(false); m_cbAccount->SetValue(true); m_cbComplete->Enable(false); m_cbComplete->SetValue(true); } m_labInfo->SetLabel(gcWString(Managers::GetString(L"#UNF_CONFIRM"), info->getName())); m_labInfo->Wrap( 360 ); }
bool VerifyServiceTask::checkBranch() { UserCore::Item::ItemInfo* pItem = getItemInfo(); UserCore::Item::BranchInfoI* pBranch = pItem->getCurrentBranch(); if (!pBranch) return false; if (pBranch && pItem->isDownloadable() && !pBranch->isDownloadable()) { finishVerify(UserCore::Misc::VerifyComplete::V_RESET); return true; } if (m_McfBranch != 0 && pBranch && pBranch->getBranchId() != m_McfBranch) { finishVerify(UserCore::Misc::VerifyComplete::V_SWITCHBRANCH); return true; } m_McfBranch = pItem->getCurrentBranch()->getBranchId(); return false; }
int InstallBranch::setInfo(DesuraId id, bool selectBranch) { m_bSelectBranch = selectBranch; UserCore::Item::ItemInfoI* pItemInfo = GetUserCore()->getItemManager()->findItemInfo(id); if (!pItemInfo) return 1; m_bIsMod = id.getType() == DesuraId::TYPE_MOD; m_bIsExpansion = m_bIsMod == false && pItemInfo->getParentId().getType() == DesuraId::TYPE_GAME; m_Item = id; gcWString parName; gcWString itemName = pItemInfo->getName(); DesuraId par = pItemInfo->getParentId(); UserCore::Item::ItemInfoI *parInfo = NULL; if (par.isOk()) { parInfo = GetUserCore()->getItemManager()->findItemInfo(par); if (parInfo) parName = gcWString(parInfo->getName()); } fixName(parName); fixName(itemName); if (selectBranch == false && m_bIsMod) { m_labInfo->SetLabel(gcWString(Managers::GetString(L"#IF_NOTFOUND"), itemName, parName)); m_labInfo->Wrap( 350 ); } else if (selectBranch == false && m_bIsExpansion) { m_labInfo->SetLabel(gcWString(Managers::GetString(L"#IF_NOTFOUND_GAME"), itemName, parName)); m_labInfo->Wrap( 350 ); } else { m_labInfo->SetLabel(gcWString(Managers::GetString(L"#IF_BRANCHINFO"), itemName)); m_labInfo->Wrap( 350 ); } uint32 count = 0; int32 full = -1; uint32 fullReadyCount = 0; m_bBuy = true; UserCore::Item::ItemInfoI *i = pItemInfo; bool isCheckingParent = (m_bIsMod || m_bIsExpansion) && !selectBranch; if (isCheckingParent) { if (!parInfo) { gcMessageBox(GetParent(), Managers::GetString(L"#IF_IIPARENT"), Managers::GetString(L"#IF_IIERRTITLE")); return 1; } i = parInfo; } std::vector<UserCore::Item::BranchInfoI*> bList; for (uint32 x=0; x<i->getBranchCount(); x++) { UserCore::Item::BranchInfoI* bi = i->getBranch(x); if (!bi) continue; uint32 flags = bi->getFlags(); bool noRelease = HasAllFlags(flags, UserCore::Item::BranchInfoI::BF_NORELEASES); bool isPreorder = bi->isPreOrder(); bool isDemo = HasAnyFlags(flags, UserCore::Item::BranchInfoI::BF_DEMO); bool onAccount = HasAllFlags(flags, UserCore::Item::BranchInfoI::BF_ONACCOUNT); bool locked = HasAnyFlags(flags, UserCore::Item::BranchInfoI::BF_MEMBERLOCK|UserCore::Item::BranchInfoI::BF_REGIONLOCK); bool test = HasAnyFlags(flags, UserCore::Item::BranchInfoI::BF_TEST); bool free = HasAnyFlags(flags, UserCore::Item::BranchInfoI::BF_FREE); if (noRelease && !isPreorder) continue; if (!onAccount && locked) continue; if (!selectBranch && (isDemo || test)) continue; if ((free || onAccount) && isPreorder && !selectBranch) continue; bool globalFound = false; for (size_t x=0; x<bList.size(); x++) { if (bList[x]->getGlobalId() == bi->getGlobalId()) { globalFound = true; break; } } if (globalFound) continue; if (isDemo || test) { } else if (full == -1 || ((!m_bBuy || onAccount) && !free)) { if (full == -1 || m_bBuy) { //if this is the first full game or this is the first full game that you dont have to buy m_bBuy = (!onAccount && !free); full = count; } if (onAccount || free) fullReadyCount++; } bList.push_back(bi); count++; } for (size_t x=0; x<bList.size(); x++) { UserCore::Item::BranchInfoI* bi = bList[x]; gcString name = bi->getName(); gcWString title; uint32 flags = bi->getFlags(); bool noRelease = HasAllFlags(flags, UserCore::Item::BranchInfoI::BF_NORELEASES); bool isPreorder = bi->isPreOrder(); bool onAccount = HasAllFlags(flags, UserCore::Item::BranchInfoI::BF_ONACCOUNT); bool free = HasAnyFlags(flags, UserCore::Item::BranchInfoI::BF_FREE); if (!free) title = gcString("{0} - {1}", name, Managers::GetString("#IF_BROUGHT")); else title = gcString("{0} - {1}", name, Managers::GetString("#IF_FREE")); if (!free && !onAccount) { gcWString cost(bi->getCost()); if (cost == "") cost = gcString(Managers::GetString("#TBA")); title = gcString("{0} - {1}", name, cost.c_str()); } else if (isPreorder) { if (noRelease) title = gcString("{0} - {1}", name, Managers::GetString("#IF_PREORDERED_NORELEASE")); else title = gcString("{0} - {1}", name, Managers::GetString("#IF_PREORDERED")); } m_cbBranchList->Append(title, new BranchData(bi->getBranchId(), bi->getGlobalId())); } count = bList.size(); if (full == -1) full = 0; #ifdef WIN32 if (HasAnyFlags(i->getStatus(), UserCore::Item::ItemInfoI::STATUS_ONCOMPUTER)) m_cbBranchList->Append(Managers::GetString("#IF_ONCOMPUTER"), new BranchData(MCFBranch::BranchFromInt(-1), MCFBranch::BranchFromInt(-1))); else m_cbBranchList->Append(Managers::GetString("#IF_FINDONCOMPUTER"), new BranchData(MCFBranch::BranchFromInt(-2), MCFBranch::BranchFromInt(-2))); #endif m_cbBranchList->SetSelection(full); if (pItemInfo->getIcon() && UTIL::FS::isValidFile(UTIL::FS::PathWithFile(pItemInfo->getIcon()))) setIcon(pItemInfo->getIcon()); SetTitle(gcWString(Managers::GetString(L"#IF_BRANCHTITLE"), itemName)); uint32 ret = 0; if (count == 0) { if (!isCheckingParent) gcMessageBox(GetParent(), Managers::GetString(L"#IF_IINOBRANCHES"), Managers::GetString(L"#IF_IIERRTITLE")); else if (selectBranch) ret = 1; } else if ((count == 1 || fullReadyCount == 1) && !m_bBuy) { ret = 1; } else { wxCommandEvent e; onChoice(e); } return ret; }
uint32 GatherInfoTask::validate() { UserCore::Item::ItemInfoI* pItemInfo = getItemHandle()->getItemInfo(); uint32 isValid = 0; if (!pItemInfo) return UserCore::Item::Helper::V_BADINFO; DesuraId par = pItemInfo->getParentId(); UserCore::Item::ItemInfoI *parInfo = nullptr; if (par.isOk()) { parInfo = getUserCore()->getItemManager()->findItemInfo(par); if (!parInfo || !(parInfo->getStatus() & UserCore::Item::ItemInfoI::STATUS_INSTALLED)) isValid |= UserCore::Item::Helper::V_PARENT; } const char* path = pItemInfo->getPath(getMcfBranch()); if (!path) { isValid |= UserCore::Item::Helper::V_BADPATH; } else { const char *comAppPath = getUserCore()->getAppDataPath(); uint64 inFreeSpace = UTIL::OS::getFreeSpace(path); uint64 dlFreeSpace = UTIL::OS::getFreeSpace(comAppPath); //if they are on the same drive: if (strncmp(comAppPath, path, 3) == 0) { if ((inFreeSpace+dlFreeSpace) < (pItemInfo->getDownloadSize()+pItemInfo->getInstallSize())) { isValid |= (UserCore::Item::Helper::V_FREESPACE|UserCore::Item::Helper::V_FREESPACE_DL|UserCore::Item::Helper::V_FREESPACE_INS); } } else { if (dlFreeSpace < pItemInfo->getDownloadSize()) isValid |= UserCore::Item::Helper::V_FREESPACE|UserCore::Item::Helper::V_FREESPACE_DL; if (inFreeSpace < pItemInfo->getInstallSize()) isValid |= UserCore::Item::Helper::V_FREESPACE|UserCore::Item::Helper::V_FREESPACE_INS; } if (pItemInfo->getStatus() & UserCore::Item::ItemInfoI::STATUS_INSTALLCOMPLEX) { const char* primPath = pItemInfo->getInsPrimary(); if (primPath && strcmp(primPath, "") != 0 && UTIL::FS::isValidFolder(primPath) && !UTIL::FS::isFolderEmpty(primPath)) isValid |= UserCore::Item::Helper::V_NONEMPTY; } else if (pItemInfo->getStatus() & UserCore::Item::ItemInfoI::STATUS_DLC) { if (!parInfo || gcString(path) != gcString(parInfo->getPath())) { if (!UTIL::FS::isFolderEmpty(path)) isValid |= UserCore::Item::Helper::V_NONEMPTY; } } else if (!UTIL::FS::isFolderEmpty(path)) { isValid |= UserCore::Item::Helper::V_NONEMPTY; } } #ifdef NIX UserCore::Item::BranchInfoI* bi = pItemInfo->getBranchById(getMcfBranch()); std::vector<DesuraId> toolList; bi->getToolList(toolList); uint32 res = getUserCore()->getToolManager()->hasNonInstallableTool(toolList); switch (res) { case 0: isValid |= UserCore::Item::Helper::V_JAVA_SUN; break; case 1: isValid |= UserCore::Item::Helper::V_JAVA; break; case 2: isValid |= UserCore::Item::Helper::V_MONO; break; case 3: isValid |= UserCore::Item::Helper::V_AIR; break; }; #endif return isValid; }
void GatherInfoTask::checkRequirements() { if (!isValidBranch() && !handleInvalidBranch()) return; MCFBranch branch = getMcfBranch(); UserCore::Item::BranchInfoI* branchInfo = getItemHandle()->getItemInfo()->getBranchById(branch); if (!checkNullBranch(branchInfo)) return; if (m_bCanceled) { completeStage(); return; } if (branchInfo->isPreOrderAndNotPreload()) { //show the preorder prompt getItemHandle()->getInternal()->goToStageLaunch(); return; } uint32 res = validate(); #ifdef NIX UserCore::Item::Helper::TOOL tool = (UserCore::Item::Helper::TOOL)(res>>28); //check tool deps if ( (tool > 0) && (!m_pGIHH || !m_pGIHH->showToolPrompt(tool)) ) { completeStage(); return; } res = (res<<4)>>4; #endif if (res == 0) { getItemHandle()->getItemInfo()->addToAccount(); getItemHandle()->getInternal()->goToStageDownload(branch, getMcfBuild(), HasAnyFlags(m_uiFlags, GI_FLAG_TEST)); } else { if (res == UserCore::Item::Helper::V_NONEMPTY) { if (HasAnyFlags(m_uiFlags, GI_FLAG_UPDATE)) { getItemHandle()->getInternal()->goToStageDownload(branch, getMcfBuild(), false); } else if (getItemHandle()->getItemInfo()->getStatus() & UserCore::Item::ItemInfoI::STATUS_INSTALLCOMPLEX) { if (!m_bCanceled && m_pGIHH && m_pGIHH->showComplexPrompt()) getItemHandle()->getInternal()->goToStageDownload(branch, getMcfBuild(), HasAnyFlags(m_uiFlags, GI_FLAG_TEST)); else resetStage(); } else { UserCore::Item::Helper::ACTION promptRes = UserCore::Item::Helper::C_NONE; if (!m_bCanceled && m_pGIHH) promptRes = m_pGIHH->showInstallPrompt(getItemHandle()->getItemInfo()->getPath(getMcfBranch())); switch (promptRes) { case UserCore::Item::Helper::C_REMOVE: getItemInfo()->addOFlag(UserCore::Item::ItemInfoI::OPTION_REMOVEFILES); case UserCore::Item::Helper::C_INSTALL: getItemInfo()->addToAccount(); getItemHandle()->getInternal()->goToStageDownload(branch, getMcfBuild(), HasAnyFlags(m_uiFlags, GI_FLAG_TEST)); break; case UserCore::Item::Helper::C_VERIFY: getItemInfo()->addToAccount(); getItemInfo()->addSFlag(UserCore::Item::ItemInfoI::STATUS_INSTALLED); getItemInfo()->setInstalledMcf(branch, getMcfBuild()); getItemHandle()->getInternal()->goToStageVerify(branch, getMcfBuild(), true, true, true); break; default: resetStage(); break; } } } else { if (m_bCanceled || !m_pGIHH || m_pGIHH->showError(res)) { resetStage(); } else { getItemHandle()->getItemInfo()->addToAccount(); getItemHandle()->getInternal()->goToStageDownload(branch, getMcfBuild(), HasAnyFlags(m_uiFlags, GI_FLAG_TEST)); } } } }
void ItemHandle::doLaunch(bool useXdgOpen, const char* globalExe, const char* globalArgs) { preLaunchCheck(); UserCore::Item::Misc::ExeInfoI* ei = getItemInfo()->getActiveExe(); gcString e(globalExe); gcString args; gcString ea(ei->getExeArgs()); gcString ua(ei->getUserArgs()); gcString ga(globalArgs); gcString wdp(ei->getExe()); if (!useXdgOpen) { //if we have a valid global exe need to append the local exe as the first arg if (e.size() > 0) args += gcString(ei->getExe()); else globalExe = ei->getExe(); } auto AppendArgs = [&args](const std::string& a) { if (a.size() == 0) return; if (args.size() > 0) args += " "; args += a; }; AppendArgs(ea); AppendArgs(ua); if (!useXdgOpen) AppendArgs(ga); bool res = false; if (useXdgOpen && args.size() != 0) Warning(gcString("Arguments '{1}' are not being passed to non-executable file '{0}'.", ei->getExe(), args)); UserCore::Item::BranchInfoI* branch = getItemInfo()->getCurrentBranch(); #ifdef NIX64 if (!useXdgOpen && branch && branch->is32Bit()) { #ifdef USE_BITTEST int testRet = system("desura_bittest"); if (testRet != 0) throw gcException(ERR_NO32LIBS); #else throw gcException(ERR_NOBITTEST); #endif } #endif gcString libPathA; gcString libPathB; gcString libPath; if (branch) { libPathA = gcString("{0}/{1}/{2}/lib", UTIL::OS::getAppDataPath(), branch->getItemId().getFolderPathExtension(), (uint32)branch->getBranchId()); libPathB = gcString("{0}/lib{1}", getItemInfo()->getPath(), branch->is32Bit()?"32":"64"); libPath = libPathA; if (UTIL::FS::isValidFolder(libPathB.c_str())) { libPath += ":"; libPath += libPathB; } } if (useXdgOpen) { res = UTIL::LIN::launchProcessXDG(ei->getExe(), libPath.c_str()); } else { if (libPathA.size() > 0) { std::vector<DesuraId> toolList; branch->getToolList(toolList); getUserCore()->getToolManager()->symLinkTools(toolList, libPathA.c_str()); } std::map<std::string, std::string> info; info["cla"] = args; info["lp"] = libPath; info["wd"] = UTIL::FS::PathWithFile(wdp.c_str()).getFolderPath(); res = UTIL::LIN::launchProcess(globalExe, info); } if (!res) { ERROR_OUTPUT(gcString("Failed to create {0} process. [{1}: {2}].\n", getItemInfo()->getName(), errno, ei->getExe()).c_str()); throw gcException(ERR_LAUNCH, errno, gcString("Failed to create {0} process. [{1}: {2}].\n", getItemInfo()->getName(), errno, ei->getExe())); } }
void ItemHandle::installLaunchScripts() { UserCore::Item::ItemInfoI* item = getItemInfo(); if (!item) return; UserCore::Item::BranchInfoI* branch = item->getCurrentBranch(); if (!branch) return; std::vector<UserCore::Item::Misc::ExeInfoI*> exeList; item->getExeList(exeList); char* scriptBin = NULL; char* scriptXdg = NULL; try { UTIL::FS::readWholeFile(UTIL::STRING::toStr( UTIL::OS::getDataPath(L"scripts/launch_bin_template.sh")), &scriptBin); UTIL::FS::readWholeFile(UTIL::STRING::toStr( UTIL::OS::getDataPath(L"scripts/launch_xdg_template.sh")), &scriptXdg); } catch (gcException &e) { safe_delete(scriptBin); safe_delete(scriptXdg); Warning(gcString("Failed to read launch script template: {0}\n", e)); return; } gcString globalArgs = getUserCore()->getCVarValue("gc_linux_launch_globalargs"); gcString globalExe = getUserCore()->getCVarValue("gc_linux_launch_globalbin"); if (!UTIL::FS::isValidFile(globalExe.c_str())) globalExe = ""; for (size_t x=0; x<exeList.size(); x++) { UserCore::Item::Misc::ExeInfoI* exe = exeList[x]; if (!exe || !UTIL::FS::isValidFile(exe->getExe())) continue; gcString path("{0}/desura_launch_{1}.sh", item->getPath(), UTIL::LIN::sanitiseFileName(exe->getName())); char magicBytes[5] = {0}; try { UTIL::FS::FileHandle fh(exe->getExe(), UTIL::FS::FILE_READ); fh.read(magicBytes, 5); } catch (gcException& e) { continue; } UTIL::LIN::BinType type = UTIL::LIN::getFileType(magicBytes, 5); try { UTIL::FS::FileHandle fh(path.c_str(), UTIL::FS::FILE_WRITE); if (type == UTIL::LIN::BT_UNKNOWN) { gcString lcmd(scriptXdg, exe->getExe()); fh.write(lcmd.c_str(), lcmd.size()); } else { gcString libPath("\"{0}/{1}/{2}/lib\"", UTIL::OS::getAppDataPath(), branch->getItemId().getFolderPathExtension(), (uint32)branch->getBranchId()); gcString libPathB("{0}/lib{1}", item->getPath(), branch->is32Bit()?"32":"64"); if (UTIL::FS::isValidFolder(libPathB.c_str())) { libPath += ":"; libPath += "\"" + libPathB + "\""; } const char* exePath = exe->getExe(); gcString args; gcString ea(exe->getExeArgs()); if (globalExe.size() > 0) { args += gcString(exePath); exePath = globalExe.c_str(); } if (ea.size() > 0) { if (args.size() > 0) args += " "; args += ea; } if (globalArgs.size() > 0) { if (args.size() > 0) args += " "; args += globalArgs; } gcString lcmd(scriptBin, exePath, args, libPath); fh.write(lcmd.c_str(), lcmd.size()); } } catch (gcException &e) { } chmod(path.c_str(), S_IRWXU|S_IRGRP|S_IROTH); } safe_delete(scriptBin); safe_delete(scriptXdg); }