void DocSettings::Load(const XMLNode& node) { CString strTagName = MakeCString(node.tagName); if (strTagName != pszTagSettings && strTagName != pszTagContent) return; if (strTagName == pszTagSettings) { node.GetIntAttribute(pszAttrStartPage, nPage); node.GetLongAttribute(pszAttrOffsetX, ptOffset.x); node.GetLongAttribute(pszAttrOffsetY, ptOffset.y); node.GetIntAttribute(pszAttrZoomType, nZoomType); node.GetDoubleAttribute(pszAttrZoom, fZoom); node.GetIntAttribute(pszAttrLayout, nLayout); node.GetIntAttribute(pszAttrDisplayMode, nDisplayMode); node.GetIntAttribute(pszAttrRotate, nRotate); node.GetIntAttribute(pszAttrOpenSidebarTab, nOpenSidebarTab); int nFirstPage; if (node.GetIntAttribute(pszAttrFirstPage, nFirstPage)) bFirstPageAlone = (nFirstPage != 0); int nRightToLeft; if (node.GetIntAttribute(pszAttrRightToLeft, nRightToLeft)) bRightToLeft = (nRightToLeft != 0); } pageSettings.clear(); bookmarks.clear(); list<XMLNode>::const_iterator it; for (it = node.childElements.begin(); it != node.childElements.end(); ++it) { const XMLNode& child = *it; if (MakeCString(child.tagName) == pszTagPageSettings) { int pageNo; if (!child.GetIntAttribute(pszAttrNumber, pageNo)) continue; PageSettings& data = pageSettings[pageNo - 1]; data.Load(child); } else if (MakeCString(child.tagName) == pszTagBookmarks) { list<XMLNode>::const_iterator it; for (it = child.childElements.begin(); it != child.childElements.end(); ++it) { const XMLNode& bmNode = *it; if (MakeCString(bmNode.tagName) == pszTagBookmark) { bookmarks.push_back(Bookmark()); Bookmark& bookmark = bookmarks.back(); bookmark.Load(bmNode); } } } } }
void CInstaller::SetTitle(const std::string &t) { int w = m_pTitle->w(), h = 0; int minheaderh = (m_pLogoBox) ? (m_pLogoBox->y() + m_pLogoBox->h() + HeaderSpacing()) : 50; fl_font(m_pTitle->labelfont(), m_pTitle->labelsize()); fl_measure(t.c_str(), w, h); minheaderh = std::max(minheaderh, h); m_pTitle->size(m_pTitle->w(), minheaderh); m_pTitle->label(MakeCString(t)); if (m_pHeaderGroup->h() != minheaderh) { // Center logo (if any) if (m_pLogoBox) { const int y = ((minheaderh - m_pLogoBox->h()) / 2); m_pLogoBox->position(m_pLogoBox->x(), y); } m_pHeaderGroup->size(m_pHeaderGroup->w(), minheaderh); m_pWizard->size(m_pWizard->w(), m_pCancelButton->y()-minheaderh-ButtonHSpacing()); } }
void CPipedCMD::Close(bool canthrow) { if (!m_ChildPID) return; if (canthrow) ::Close(m_iPipeFD[0]); else close(m_iPipeFD[0]); pid_t ret; int stat; do { ret = (canthrow) ? WaitPID(m_ChildPID, &stat, 0) : waitpid(m_ChildPID, &stat, 0); } while ((ret == -1) && (errno == EINTR)); m_ChildPID = 0; if (canthrow) { if (!WIFEXITED(stat) || (WEXITSTATUS(stat) == 127)) throw Exceptions::CExCommand(MakeCString(m_szCommand)); } }
void Bookmark::Load(const XMLNode& node) { if (MakeCString(node.tagName) != pszTagBookmark) return; wstring str; if (node.GetAttribute(pszAttrTitle, str)) strTitle = MakeUTF8String(str); node.GetIntAttribute(pszAttrType, nLinkType); if (nLinkType == URL) { if (node.GetAttribute(pszAttrURL, str)) strURL = MakeUTF8String(str); } else if (nLinkType == Page || nLinkType == View) { node.GetIntAttribute(pszAttrPage, nPage); if (nLinkType == View) { node.GetLongAttribute(pszAttrOffsetX, ptOffset.x); node.GetLongAttribute(pszAttrOffsetY, ptOffset.y); int nMargin; if (node.GetIntAttribute(pszAttrMargin, nMargin)) bMargin = (nMargin != 0); } } list<XMLNode>::const_iterator it; for (it = node.childElements.begin(); it != node.childElements.end(); ++it) { const XMLNode& child = *it; if (MakeCString(child.tagName) == pszTagBookmark) { children.push_back(Bookmark()); Bookmark& bookmark = children.back(); bookmark.Load(child); } } }
void PageSettings::Load(const XMLNode& node) { if (MakeCString(node.tagName) != pszTagPageSettings) return; list<XMLNode>::const_iterator it; for (it = node.childElements.begin(); it != node.childElements.end(); ++it) { const XMLNode& child = *it; if (MakeCString(child.tagName) == pszTagAnnotation) { anno.push_back(Annotation()); Annotation& annotation = anno.back(); annotation.Load(child); if (annotation.rects.empty()) anno.pop_back(); } } }
void CLuaDirSelector::BrowseCB(Fl_Widget *w, void *p) { CLuaDirSelector *dirsel = static_cast<CLuaDirSelector *>(p); CFLTKDirDialog dialog("~", "*", (Fl_File_Chooser::DIRECTORY | Fl_File_Chooser::CREATE), GetTranslation("Select a directory")); dialog.Value(MakeCString(GetFirstValidDir(dirsel->m_pDirInput->value()))); dialog.Run(); const char *dir = dialog.Value(); if (dir && *dir) { dirsel->m_pDirInput->value(dir); dirsel->LuaDataChanged(); } }
CLuaMenu::CLuaMenu(const char *desc, const TOptions &l) : CBaseLuaWidget(desc), CBaseLuaMenu(l), m_iCurValue(-1) { m_pMenu = new Fl_Hold_Browser(0, 0, 0, GroupHeight()); m_pMenu->callback(SelectionCB, this); for (TOptions::const_iterator it=l.begin(); it!=l.end(); it++) m_pMenu->add(MakeTranslation(*it), MakeCString(*it)); if (m_pMenu->size() > 0) { m_pMenu->value(1); m_iCurValue = 1; } GetGroup()->add(m_pMenu); }
void CButtonBar::AddButton(const char *button, const char *desc) { if (!m_pCurrentBarEntry) m_pCurrentBarEntry = new bar_entry_s; std::string txt = std::string(" </B/16>") + GetTranslation(button) + "<!16!B>: </B/8>" + GetTranslation(desc) + "<!8!B> "; const int l = strlen(button) + strlen(desc) + 4; // 4 extra chars: 3 spaces and an ':' if ((getmaxx(MainWin)-2) < (m_pCurrentBarEntry->iCurTextLength + l)) { m_pCurrentBarEntry->Texts.push_back(MakeCString(m_pCurrentBarEntry->szCurrentText)); m_pCurrentBarEntry->szCurrentText = txt; m_pCurrentBarEntry->iCurTextLength = l; } else { m_pCurrentBarEntry->szCurrentText += txt; m_pCurrentBarEntry->iCurTextLength += l; } }
void DictionaryInfo::ReadLocalizedStrings(vector<LocalizedString>& loc, const XMLNode& node) { list<XMLNode>::const_iterator it; for (it = node.childElements.begin(); it != node.childElements.end(); ++it) { const XMLNode& child = *it; if (MakeCString(child.tagName) == pszTagString) { DWORD code; if (!child.GetHexAttribute(pszAttrLocalization, code)) continue; wstring value; if (!child.GetAttribute(pszAttrValue, value)) continue; loc.push_back(make_pair(code, MakeUTF8String(value))); } } }
void CLuaInputField::UpdateSize() { m_pPack->size(GetGroup()->w(), m_pPack->h()); if (GetLabel().empty() || !m_pLabel) { m_pInputField->size(GetGroup()->w(), m_pInputField->h()); return; } std::string label = GetTranslation(GetLabel()); TSTLStrSize max = SafeConvert<TSTLStrSize>(GetLabelWidth()), length = label.length(); if (length > max) m_pLabel->label(MakeCString(label.substr(0, max))); fl_font(m_pLabel->labelfont(), m_pLabel->labelsize()); int w = static_cast<int>(fl_width(' ')) * GetLabelWidth(); m_pLabel->size(w, m_pLabel->h()); m_pInputField->size(GetGroup()->w() - PackSpacing() - w, m_pInputField->h()); }
CAppManager::CAppManager() { const int mainw = 560, mainh = 330; m_pMainWindow = new Fl_Window(mainw, mainh, "Nixstaller - App Manager"); m_pAppList = new Fl_Hold_Browser(20, 40, 180, 240, "Installed applications"); m_pAppList->align(FL_ALIGN_TOP); GetRegisterEntries(&m_AppVec); for (std::vector<app_entry_s *>::iterator it=m_AppVec.begin(); it!=m_AppVec.end(); it++) m_pAppList->add(MakeCString((*it)->name)); m_pAppList->callback(AppListCB, this); m_pAppList->value(1); Fl_Tabs *pTabs = new Fl_Tabs((m_pAppList->x()+m_pAppList->w())+20, 20, 300, 260); Fl_Group *pInfoTab = new Fl_Group((m_pAppList->x()+m_pAppList->w())+20, 40, 300, 260, "Info"); m_pInfoOutput = new Fl_Help_View((m_pAppList->x()+m_pAppList->w())+20, 40, 300, 240); m_pInfoOutput->align(FL_ALIGN_TOP); pInfoTab->end(); Fl_Group *pFilesTab = new Fl_Group((m_pAppList->x()+m_pAppList->w())+20, 40, 300, 260, "Files"); m_pFilesTextDisplay = new Fl_Text_Display((m_pAppList->x()+m_pAppList->w())+20, 40, 300, 240); m_pFilesTextBuffer = new Fl_Text_Buffer; m_pFilesTextDisplay->buffer(m_pFilesTextBuffer); pFilesTab->end(); pTabs->end(); m_pUninstallButton = new Fl_Button(20, (m_pAppList->y()+m_pAppList->h())+20, 120, 25, "Uninstall"); m_pUninstallButton->callback(UninstallCB, this); m_pExitButton = new Fl_Button((mainw-140), (m_pAppList->y()+m_pAppList->h())+20, 120, 25, "Exit"); m_pExitButton->callback(ExitCB); UpdateInfo(true); m_pUninstallWindow = new CUninstallWindow(this); m_pMainWindow->end(); }
void CButtonBar::Draw() { if (!m_pCurrentBarEntry) return; if (!m_pCurrentBarEntry->szCurrentText.empty()) { m_pCurrentBarEntry->Texts.push_back(MakeCString(m_pCurrentBarEntry->szCurrentText)); m_pCurrentBarEntry->szCurrentText.clear(); m_pCurrentBarEntry->iCurTextLength = 0; } if (m_pCurrentBarEntry->Texts.empty()) return; if (m_pLabel) delete m_pLabel; // CDK has no propper way to change text... m_pLabel = new CCDKLabel(CDKScreen, CENTER, BOTTOM, &m_pCurrentBarEntry->Texts[0], m_pCurrentBarEntry->Texts.size()); if (!m_pLabel) throwerror(false, "Could not create button bar"); m_pLabel->SetBgColor(24); m_pLabel->Draw(); refreshCDKScreen(CDKScreen); }
bool SelectLanguage() { if (InstallInfo.languages.size() == 1) { InstallInfo.cur_lang = InstallInfo.languages.front(); if (!ReadLang()) throwerror(true, "Could not load language file for %s", InstallInfo.cur_lang.c_str()); return true; } char title[] = "<C></B/29>Please select a language<!29!B>"; std::vector<char *> LangItems; ButtonBar.Clear(); ButtonBar.AddButton("Arrows", "Navigate menu"); ButtonBar.AddButton("A", "About"); ButtonBar.AddButton("ESC", "Exit program"); ButtonBar.Draw(); for (std::list<std::string>::iterator p=InstallInfo.languages.begin();p!=InstallInfo.languages.end();p++) LangItems.push_back(MakeCString(*p)); CCDKScroll ScrollList(CDKScreen, CENTER, CENTER, GetMaxHeight(20), GetMaxWidth(45), RIGHT, title, &LangItems[0], LangItems.size()); ScrollList.SetBgColor(5); ScrollList.Bind('a', ShowAboutK); int selection = ScrollList.Activate(); if (ScrollList.ExitType() == vNORMAL) { InstallInfo.cur_lang = LangItems[selection]; ReadLang(); } else return false; return true; }
object call_c(int func, object proc_ad, object arg_list) /* Call a WIN32 or Linux C function in a DLL or shared library. Alternatively, call a machine-code routine at a given address. */ { volatile unsigned long arg; // !!!! magic var to push values on the stack volatile int argsize; // !!!! number of bytes to pop s1_ptr arg_list_ptr, arg_size_ptr; object_ptr next_arg_ptr, next_size_ptr; object next_arg, next_size; int iresult, i; double dbl_arg, dresult; float flt_arg, fresult; unsigned long size; int proc_index; int cdecl_call; int (*int_proc_address)(); unsigned return_type; char NameBuff[100]; // Setup and Check for Errors proc_index = get_pos_int("c_proc/c_func", proc_ad); if ((unsigned)proc_index >= c_routine_next) { sprintf(TempBuff, "c_proc/c_func: bad routine number (%d)", proc_index); RTFatal(TempBuff); } int_proc_address = c_routine[proc_index].address; #if defined(EWINDOWS) && !defined(EWATCOM) cdecl_call = c_routine[proc_index].convention; #endif if (IS_ATOM(arg_list)) { RTFatal("c_proc/c_func: argument list must be a sequence"); } arg_list_ptr = SEQ_PTR(arg_list); next_arg_ptr = arg_list_ptr->base + arg_list_ptr->length; // only look at length of arg size sequence for now arg_size_ptr = c_routine[proc_index].arg_size; next_size_ptr = arg_size_ptr->base + arg_size_ptr->length; return_type = c_routine[proc_index].return_size; // will be INT if (func && return_type == 0 || !func && return_type != 0) { if (c_routine[proc_index].name->length < 100) MakeCString(NameBuff, MAKE_SEQ(c_routine[proc_index].name)); else NameBuff[0] = '\0'; sprintf(TempBuff, func ? "%s does not return a value" : "%s returns a value", NameBuff); RTFatal(TempBuff); } if (arg_list_ptr->length != arg_size_ptr->length) { if (c_routine[proc_index].name->length < 100) MakeCString(NameBuff, MAKE_SEQ(c_routine[proc_index].name)); else NameBuff[0] = '\0'; sprintf(TempBuff, "C routine %s() needs %d argument%s, not %d", NameBuff, arg_size_ptr->length, (arg_size_ptr->length == 1) ? "" : "s", arg_list_ptr->length); RTFatal(TempBuff); } argsize = arg_list_ptr->length << 2; // Push the Arguments for (i = 1; i <= arg_list_ptr->length; i++) { next_arg = *next_arg_ptr--; next_size = *next_size_ptr--; if (IS_ATOM_INT(next_size)) size = INT_VAL(next_size); else if (IS_ATOM(next_size)) size = (unsigned long)DBL_PTR(next_size)->dbl; else RTFatal("This C routine was defined using an invalid argument type"); if (size == C_DOUBLE || size == C_FLOAT) { /* push 8-byte double or 4-byte float */ if (IS_ATOM_INT(next_arg)) dbl_arg = (double)next_arg; else if (IS_ATOM(next_arg)) dbl_arg = DBL_PTR(next_arg)->dbl; else { arg = arg+argsize+9999; // 9999 = 270f hex - just a marker for asm code RTFatal("arguments to C routines must be atoms"); } if (size == C_DOUBLE) { arg = *(1+(unsigned long *)&dbl_arg); push(); // push high-order half first argsize += 4; arg = *(unsigned long *)&dbl_arg; push(); // don't combine this with the push() below - Lcc bug } else { /* C_FLOAT */ flt_arg = (float)dbl_arg; arg = *(unsigned long *)&flt_arg; push(); } } else { /* push 4-byte integer */ if (size >= E_INTEGER) { if (IS_ATOM_INT(next_arg)) { if (size == E_SEQUENCE) RTFatal("passing an integer where a sequence is required"); } else { if (IS_SEQUENCE(next_arg)) { if (size != E_SEQUENCE && size != E_OBJECT) RTFatal("passing a sequence where an atom is required"); } else { if (size == E_SEQUENCE) RTFatal("passing an atom where a sequence is required"); } RefDS(next_arg); } arg = next_arg; push(); } else if (IS_ATOM_INT(next_arg)) { arg = next_arg; push(); } else if (IS_ATOM(next_arg)) { // atoms are rounded to integers arg = (unsigned long)DBL_PTR(next_arg)->dbl; //correct // if it's a -ve f.p. number, Watcom converts it to int and // then to unsigned int. This is exactly what we want. // Works with the others too. push(); } else { arg = arg+argsize+9999; // just a marker for asm code RTFatal("arguments to C routines must be atoms"); } } } // Make the Call - The C compiler thinks it's a 0-argument call // might be VOID C routine, but shouldn't crash if (return_type == C_DOUBLE) { // expect double to be returned from C routine #if defined(EWINDOWS) && !defined(EWATCOM) if (cdecl_call) { dresult = (*((double ( __cdecl *)())int_proc_address))(); pop(); } else #endif dresult = (*((double (__stdcall *)())int_proc_address))(); #ifdef ELINUX pop(); #endif return NewDouble(dresult); } else if (return_type == C_FLOAT) { // expect float to be returned from C routine #if defined(EWINDOWS) && !defined(EWATCOM) if (cdecl_call) { fresult = (*((float ( __cdecl *)())int_proc_address))(); pop(); } else #endif fresult = (*((float (__stdcall *)())int_proc_address))(); #ifdef ELINUX pop(); #endif return NewDouble((double)fresult); } else { // expect integer to be returned #if defined(EWINDOWS) && !defined(EWATCOM) if (cdecl_call) { iresult = (*((int ( __cdecl *)())int_proc_address))(); pop(); } else #endif iresult = (*((int (__stdcall *)())int_proc_address))(); #ifdef ELINUX pop(); #endif if ((return_type & 0x000000FF) == 04) { /* 4-byte integer - usual case */ // check if unsigned result is required if ((return_type & C_TYPE) == 0x02000000) { // unsigned integer result if ((unsigned)iresult <= (unsigned)MAXINT) { return iresult; } else return NewDouble((double)(unsigned)iresult); } else { // signed integer result if (return_type >= E_INTEGER || (iresult >= MININT && iresult <= MAXINT)) { return iresult; } else return NewDouble((double)iresult); } } else if (return_type == 0) { return 0; /* void - procedure */ } /* less common cases */ else if (return_type == C_UCHAR) { return (unsigned char)iresult; } else if (return_type == C_CHAR) { return (signed char)iresult; } else if (return_type == C_USHORT) { return (unsigned short)iresult; } else if (return_type == C_SHORT) { return (short)iresult; } else return 0; // unknown function return type } }
void Annotation::Load(const XMLNode& node) { if (MakeCString(node.tagName) != pszTagAnnotation) return; int borderType; if (node.GetIntAttribute(pszAttrBorder, borderType)) { if (borderType >= BorderNone && borderType <= BorderXOR) nBorderType = borderType; } COLORREF color; if (node.GetColorAttribute(pszAttrBorderColor, color)) crBorder = color; int nHideBorder; if (node.GetIntAttribute(pszAttrBorderHideInactive, nHideBorder)) bHideInactiveBorder = !!nHideBorder; int fillType; if (node.GetIntAttribute(pszAttrFill, fillType)) { if (fillType >= FillNone && fillType <= FillXOR) nFillType = fillType; } if (node.GetColorAttribute(pszAttrFillColor, color)) crFill = color; int nPercent; if (node.GetIntAttribute(pszAttrFillTransparency, nPercent)) { if (nPercent >= 0 && nPercent <= 100) fTransparency = nPercent / 100.0; } int nHideFill; if (node.GetIntAttribute(pszAttrFillHideInactive, nHideFill)) bHideInactiveFill = !!nHideFill; wstring str; if (node.GetAttribute(pszAttrComment, str)) strComment = MakeUTF8String(str); int nShowComment; if (node.GetIntAttribute(pszAttrCommentAlwaysShow, nShowComment)) bAlwaysShowComment = !!nShowComment; if (node.GetAttribute(pszAttrURL, str)) strURL = MakeUTF8String(str); rects.clear(); list<XMLNode>::const_iterator it; for (it = node.childElements.begin(); it != node.childElements.end(); ++it) { const XMLNode& child = *it; if (MakeCString(child.tagName) == pszTagRect) { GRect rect; if (!child.GetIntAttribute(pszAttrLeft, rect.xmin) || !child.GetIntAttribute(pszAttrTop, rect.ymin) || !child.GetIntAttribute(pszAttrRight, rect.xmax) || !child.GetIntAttribute(pszAttrBottom, rect.ymax)) continue; rects.push_back(rect); } } UpdateBounds(); }
bool InstallFiles() { ButtonBar.Clear(); ButtonBar.AddButton("C", "Cancel"); ButtonBar.Draw(); char *msg; char *dbuttons[2] = { GetTranslation("Continue"), GetTranslation("Exit program") }; if ((InstallInfo.dest_dir_type == DEST_SELECT) || (InstallInfo.dest_dir_type == DEST_DEFAULT)) { msg = CreateText(GetTranslation("This will install %s to the following directory:\n%s\nContinue?"), InstallInfo.program_name.c_str(), MakeCString(InstallInfo.dest_dir)); } else { msg = CreateText(GetTranslation("This will install %s\nContinue?"), InstallInfo.program_name.c_str()); } CCDKDialog Diag(CDKScreen, CENTER, CENTER, msg, dbuttons, 2); Diag.SetBgColor(26); int sel = Diag.Activate(); Diag.Destroy(); refreshCDKScreen(CDKScreen); if (sel == 1) return false; CCDKSWindow InstallOutput(CDKScreen, 0, 6, GetDefaultHeight()-5, -1, CreateText("<C></29/B>%s", GetTranslation("Install output")), 2000); InstallOutput.SetBgColor(5); nodelay(WindowOf(InstallOutput.GetSWin()), true); // Make sure input doesn't block const int maxx = getmaxx(InstallOutput.GetSWin()->win); CCDKSWindow ProggWindow(CDKScreen, 0, 2, 5, maxx, NULL, 4); ProggWindow.SetBgColor(5); ProggWindow.AddText(""); ProggWindow.AddText(CreateText("</B/29>%s:<!29!B>", GetTranslation("Status"))); ProggWindow.AddText(CreateText("%s (1/%d)", GetTranslation("Extracting files"), InstallInfo.command_entries.size()+1), true, BOTTOM, 24); CCDKHistogram ProgressBar(CDKScreen, 25, 3, 1, maxx-29, HORIZONTAL, CreateText("<C></29/B>%s", GetTranslation("Progress")), false); ProgressBar.SetBgColor(5); ProgressBar.SetHistogram(vPERCENT, TOP, 0, 100, 0, COLOR_PAIR (24) | A_REVERSE | ' ', A_BOLD); setCDKSwindowLLChar(ProggWindow.GetSWin(), ACS_LTEE); setCDKSwindowLRChar(ProggWindow.GetSWin(), ACS_RTEE); InstallOutput.Draw(); ProggWindow.Draw(); // Check if we need root access char *passwd = NULL; LIBSU::CLibSU SuHandler; SuHandler.SetUser("root"); SuHandler.SetTerminalOutput(false); bool askpass = false; for (std::list<command_entry_s *>::iterator it=InstallInfo.command_entries.begin(); it!=InstallInfo.command_entries.end(); it++) { if ((*it)->need_root != NO_ROOT) { // Command may need root permission, check if it is so if ((*it)->need_root == DEPENDED_ROOT) { param_entry_s *p = GetParamByVar((*it)->dep_param); if (p && !WriteAccess(p->value)) { (*it)->need_root = NEED_ROOT; if (!askpass) askpass = true; } } else if (!askpass) askpass = true; } } if (!askpass) askpass = !WriteAccess(InstallInfo.dest_dir); // Ask root password if one of the command entries need root access and root isn't passwordless if (askpass && SuHandler.NeedPassword()) { CCDKEntry entry(CDKScreen, CENTER, CENTER, GetTranslation("This installation requires root(administrator) privileges in order to continue\n" "Please enter the password of the root user"), "", 60, 0, 256, vHMIXED); entry.SetHiddenChar('*'); entry.SetBgColor(26); while(1) { char *sz = entry.Activate(); if ((entry.ExitType() != vNORMAL) || !sz || !sz[0]) { if (YesNoBox(GetTranslation("Root access is required to continue\nAbort installation?"))) EndProg(); refreshCDKScreen(CDKScreen); } else { if (SuHandler.TestSU(sz)) { passwd = strdup(sz); for (short s=0;s<strlen(sz);s++) sz[s] = 0; break; } for (short s=0;s<strlen(sz);s++) sz[s] = 0; entry.Clean(); // Some error appeared if (SuHandler.GetError() == LIBSU::CLibSU::SU_ERROR_INCORRECTPASS) { WarningBox(GetTranslation("Incorrect password given for root user\nPlease retype")); } else { throwerror(true, GetTranslation("Could not use su to gain root access\n" "Make sure you can use su(adding the current user to the wheel group may help)")); } } } // Restore screen entry.Destroy(); refreshCDKScreen(CDKScreen); } short percent = 0; bool alwaysroot = false; if (!WriteAccess(InstallInfo.dest_dir)) { CExtractAsRootFunctor Extracter; Extracter.SetUpdateProgFunc(SUUpdateProgress, &ProgressBar); Extracter.SetUpdateTextFunc(SUUpdateText, &InstallOutput); if (!Extracter(passwd)) { CleanPasswdString(passwd); passwd = NULL; throwerror(true, "Error during extracting files"); } InstallOutput.AddText("Done!\n"); alwaysroot = true; // Install commands need root now too } else { while(percent<100) { std::string curfile; percent = ExtractArchive(curfile); InstallOutput.AddText("Extracting file: " + curfile, false); if (percent==100) InstallOutput.AddText("Done!", false); else if (percent==-1) throwerror(true, "Error during extracting files"); ProgressBar.SetValue(0, 100, percent/(1+InstallInfo.command_entries.size())); ProgressBar.Draw(); chtype input = getch(); if (input == 'c') { if (YesNoBox(GetTranslation("Install commands are still running\n" "If you abort now this may lead to a broken installation\n" "Are you sure?"))) { CleanPasswdString(passwd); passwd = NULL; EndProg(); } } } } SuHandler.SetThinkFunc(InstThinkFunc, passwd); SuHandler.SetOutputFunc(PrintInstOutput, &InstallOutput); percent = 100/(1+InstallInfo.command_entries.size()); // Convert to overall progress short step = 2; // Not 1, because extracting files is also a step for (std::list<command_entry_s*>::iterator it=InstallInfo.command_entries.begin(); it!=InstallInfo.command_entries.end(); it++, step++) { if ((*it)->command.empty()) continue; ProggWindow.Clear(); ProggWindow.AddText(""); ProggWindow.AddText(CreateText("</B/29>%s:<!29!B>", GetTranslation("Status"))); ProggWindow.AddText(CreateText("%s (%d/%d)", GetTranslation((*it)->description.c_str()), step, InstallInfo.command_entries.size()+1), true, BOTTOM, 24); ProgressBar.Draw(); std::string command = (*it)->command + " " + GetParameters(*it); InstallOutput.AddText(""); InstallOutput.AddText(CreateText("Execute: %s", command.c_str())); InstallOutput.AddText(""); InstallOutput.AddText(""); if (((*it)->need_root == NEED_ROOT) || alwaysroot) { SuHandler.SetPath((*it)->path.c_str()); SuHandler.SetCommand(command); if (!SuHandler.ExecuteCommand(passwd)) { if ((*it)->exit_on_failure) { CleanPasswdString(passwd); passwd = NULL; throwerror(true, "%s\n('%s')", GetTranslation("Failed to execute install command"), SuHandler.GetErrorMsgC()); } } } else { // Redirect stderr to stdout, so that errors will be displayed too command += " 2>&1"; setenv("PATH", (*it)->path.c_str(), 1); FILE *pipe = popen(command.c_str(), "r"); char term[1024]; if (pipe) { while (fgets(term, sizeof(term), pipe)) { InstallOutput.AddText(term); chtype input = getch(); if (input == 'c') /*injectCDKSwindow(InstallOutput.GetSWin(), input);*/ { if (YesNoBox(GetTranslation("Install commands are still running\n" "If you abort now this may lead to a broken installation\n" "Are you sure?"))) { CleanPasswdString(passwd); passwd = NULL; EndProg(); } } } // Check if command exitted normally and close pipe int state = pclose(pipe); if (!WIFEXITED(state) || (WEXITSTATUS(state) == 127)) // SH returns 127 if command execution failes { if ((*it)->exit_on_failure) { CleanPasswdString(passwd); passwd = NULL; throwerror(true, "Failed to execute install command"); } } } else { CleanPasswdString(passwd); passwd = NULL; throwerror(true, "Could not execute installation commands (could not open pipe)"); } #if 0 // Need to find a good way to safely suspend a process...this code doesn't always work :( int pipefd[2]; pipe(pipefd); pid_t pid = fork(); if (pid == -1) throwerror(true, "Error during command execution: Could not fork process"); else if (pid) // Parent process { close(pipefd[1]); // We're not going to write here std::string out; char c; int compid = -1; // PID of the executed command while(read(pipefd[0], &c, sizeof(c)) > 0) { out += c; if (c == '\n') { if (compid == -1) { compid = atoi(out.c_str()); InstallOutput.AddText(CreateText("pid: %d compid: %d", pid, compid), false); } else InstallOutput.AddText(out, false); out.clear(); } chtype input = getch(); if (input != ERR) /*injectCDKSwindow(InstallOutput.GetSWin(), input);*/ { if (kill(compid, SIGTSTP) < 0) // Pause command execution WarningBox("PID Error: %s\n", strerror(errno)); char *buttons[2] = { GetTranslation("Yes"), GetTranslation("No") }; CCharListHelper msg; msg.AddItem(GetTranslation("This will abort the installation")); msg.AddItem(GetTranslation("Are you sure?")); CCDKDialog dialog(CDKScreen, CENTER, CENTER, msg, msg.Count(), buttons, 2); dialog.SetBgColor(26); int ret = dialog.Activate(); bool cont = ((ret == 1) || (dialog.ExitType() != vNORMAL)); dialog.Destroy(); refreshCDKScreen(CDKScreen); if (!cont) { kill(pid, SIGTERM); EndProg(); } kill(compid, SIGCONT); // Continue command execution } } close (pipefd[0]); int status; //waitpid(pid, &status, 0); } else // Child process { // Redirect stdout to pipe close(STDOUT_FILENO); dup (pipefd[1]); close (pipefd[0]); // No need to read here // Make sure no errors are printed and write pid of new command command += " 2> /dev/null & echo $!"; execl("/bin/sh", "sh", "-c", command.c_str(), NULL); system(CreateText("echo %s", strerror(errno))); _exit(1); } #endif } percent += (1.0f/((float)InstallInfo.command_entries.size()+1.0f))*100.0f; ProgressBar.SetValue(0, 100, percent); } ProgressBar.SetValue(0, 100, 100); ProgressBar.Draw(); CleanPasswdString(passwd); passwd = NULL; ButtonBar.Clear(); ButtonBar.AddButton("Arrows", "Scroll install output"); ButtonBar.AddButton("Enter", (FileExists(InstallInfo.own_dir + "/config/finish")) ? "Continue" : "Finish"); // HACK ButtonBar.Draw(); WarningBox("Installation of %s complete!", InstallInfo.program_name.c_str()); InstallOutput.Activate(); return (InstallOutput.ExitType() == vNORMAL); }
bool ConfParams() { param_entry_s *pFirstParam = NULL; std::vector<char *> ParamItems; for (std::list<command_entry_s *>::iterator p=InstallInfo.command_entries.begin();p!=InstallInfo.command_entries.end(); p++) { for (std::map<std::string, param_entry_s *>::iterator p2=(*p)->parameter_entries.begin(); p2!=(*p)->parameter_entries.end();p2++) { if (!pFirstParam) pFirstParam = p2->second; ParamItems.push_back(MakeCString(p2->first)); } } if (!pFirstParam) return true; // No command entries...no need for this screen char *title = CreateText("<C></B/29>%s<!29!B>", GetTranslation("Configure parameters")); char *buttons[3] = { GetTranslation("Edit parameter"), GetTranslation("Continue"), GetTranslation("Cancel") }; ButtonBar.Clear(); ButtonBar.AddButton("TAB", "Next button"); ButtonBar.AddButton("ENTER", "Activate button"); ButtonBar.AddButton("Arrows", "Navigate menu"); ButtonBar.AddButton("A", "About"); ButtonBar.AddButton("ESC", "Exit program"); ButtonBar.Draw(); CCDKButtonBox ButtonBox(CDKScreen, CENTER, GetDefaultHeight()-1, 1, GetDefaultWidth(), 0, 1, 3, buttons, 3); ButtonBox.SetBgColor(5); CCDKScroll ScrollList(CDKScreen, getbegx(ButtonBox.GetBBox()->win), 2, getbegy(ButtonBox.GetBBox()->win)-1, GetDefaultWidth()/2, RIGHT, title, &ParamItems[0], ParamItems.size()); ScrollList.SetBgColor(5); ScrollList.Bind('a', ShowAboutK); const int defh = 3; CCDKSWindow DescWindow(CDKScreen, (getbegx(ScrollList.GetScroll()->win) + getmaxx(ScrollList.GetScroll()->win))-1, 2, getmaxy(ScrollList.GetScroll()->win)-defh-1, (GetDefaultWidth()/2)+1, CreateText("<C></B/29>%s<!29!B>", GetTranslation("Description")), 30); DescWindow.SetBgColor(5); DescWindow.AddText(GetTranslation(pFirstParam->description)); CCDKSWindow DefWindow(CDKScreen, (getbegx(ScrollList.GetScroll()->win) + getmaxx(ScrollList.GetScroll()->win))-1, getmaxy(DescWindow.GetSWin()->win), defh, (GetDefaultWidth()/2)+1, NULL, 4); DefWindow.SetBgColor(5); const char *str = pFirstParam->defaultval.c_str(); if (pFirstParam->param_type == PTYPE_BOOL) { if (!strcmp(str, "true")) str = GetTranslation("Enabled"); else str = GetTranslation("Disabled"); } DefWindow.AddText(CreateText("</B/29>%s:<!29!B> %s", GetTranslation("Default"), str), false); DefWindow.AddText(CreateText("</B/29>%s:<!29!B> %s", GetTranslation("Current"), str), false); setCDKScrollLLChar(ScrollList.GetScroll(), ACS_LTEE); setCDKScrollLRChar(ScrollList.GetScroll(), ACS_BTEE); setCDKScrollURChar(ScrollList.GetScroll(), ACS_TTEE); setCDKSwindowULChar(DescWindow.GetSWin(), ACS_TTEE); setCDKSwindowLLChar(DescWindow.GetSWin(), ACS_LTEE); setCDKSwindowLRChar(DescWindow.GetSWin(), ACS_RTEE); setCDKSwindowURChar(DefWindow.GetSWin(), ACS_RTEE); setCDKSwindowLRChar(DefWindow.GetSWin(), ACS_RTEE); setCDKButtonboxULChar(ButtonBox.GetBBox(), ACS_LTEE); setCDKButtonboxURChar(ButtonBox.GetBBox(), ACS_RTEE); ButtonBox.Draw(); DescWindow.Draw(); DefWindow.Draw(); void *Data[4] = { &DescWindow, &DefWindow, &ScrollList, &ParamItems }; setCDKScrollPreProcess(ScrollList.GetScroll(), ScrollParamMenuK, &Data); ScrollList.Bind(KEY_TAB, SwitchButtonK, ButtonBox.GetBBox()); bool success = false; while(1) { int selection = ScrollList.Activate(); if (ScrollList.ExitType() == vNORMAL) { if (ButtonBox.GetCurrent() == 1) { success = true; break; } else if (ButtonBox.GetCurrent() == 2) { success = false; break; } param_entry_s *pParam = GetParamByName(ParamItems[selection]); if (pParam->param_type == PTYPE_DIR) { CFileDialog filedialog(GetFirstValidDir(pParam->value), CreateText("<C>%s", GetTranslation("Select a directory")), true, false); if (filedialog.Activate()) pParam->value = filedialog.Result(); filedialog.Destroy(); refreshCDKScreen(CDKScreen); } else if (pParam->param_type == PTYPE_STRING) { CCDKEntry entry(CDKScreen, CENTER, CENTER, GetTranslation("Please enter new value"), "", 40, 0, 256); entry.SetBgColor(26); entry.SetValue(pParam->value); const char *newval = entry.Activate(); if ((entry.ExitType() == vNORMAL) && newval) pParam->value = newval; // Restore screen entry.Destroy(); refreshCDKScreen(CDKScreen); } else { std::vector<char *> chitems; int cur = 0; if (pParam->param_type == PTYPE_BOOL) { chitems.push_back(GetTranslation("Disable")); chitems.push_back(GetTranslation("Enable")); cur = (pParam->value == "true") ? 1 : 0; } else { int i = 0; for (std::list<std::string>::iterator it=pParam->options.begin(); it!=pParam->options.end();it++, i++) { chitems.push_back(GetTranslation(MakeCString(*it))); if (*it == pParam->value) cur = i; } } CCDKScroll chScrollList(CDKScreen, CENTER, CENTER, 6, 30, RIGHT, GetTranslation("Please choose new value"), &chitems[0], chitems.size()); chScrollList.SetBgColor(26); chScrollList.SetCurrent(cur); int chsel = chScrollList.Activate(); if (chScrollList.ExitType() == vNORMAL) { if (pParam->param_type == PTYPE_BOOL) { if (!strcmp(chitems[chsel], GetTranslation("Enable"))) pParam->value = "true"; else pParam->value = "false"; } else pParam->value = chitems[chsel]; } chScrollList.Destroy(); refreshCDKScreen(CDKScreen); } DefWindow.Clear(); DefWindow.AddText(CreateText("</B/29>%s:<!29!B> %s", GetTranslation("Default"), GetParamDefault(pParam)), false); DefWindow.AddText(CreateText("</B/29>%s:<!29!B> %s", GetTranslation("Current"), GetParamValue(pParam)), false); } else { success = false; break; } } return success; }