bool Srv::projectattach(const char* url, const char* prjname, const char* email, const char* pass, std::string& errmsg) //подключить проект { //расчитать хэш md5 от pass+email unsigned char md5digest[MD5_DIGEST_LENGTH]; MD5_CTX c; MD5_Init(&c); MD5_Update(&c, pass , strlen(pass)); MD5_Update(&c, email, strlen(email)); MD5_Final(md5digest,&c); char shash[1024]; //строковое представление хэша for (int i=0;i<MD5_DIGEST_LENGTH;i++) sprintf(shash+i*2,"%02x",md5digest[i]); //формируем запрос для получения authenticator char sreq[1024]; snprintf(sreq,sizeof(sreq),"<lookup_account>\n<url>%s</url>\n<email_addr>%s</email_addr>\n<passwd_hash>%s</passwd_hash>\n</lookup_account>\n",url,email,shash); Item* res = req(sreq); if (res == NULL) return false; kLogPrintf("request=\n %s\n\n answer=\n%s\n",sreq, res->toxmlstring().c_str()); free(res); int count = 30; //не больше 30 запросов snprintf(sreq,sizeof(sreq),"<lookup_account_poll/>"); std::string sauthenticator; bool done = false; do { res = req(sreq); if (res == NULL) return false; kLogPrintf("request=\n %s\n\n answer=\n%s\n",sreq, res->toxmlstring().c_str()); Item* error_num = res->findItem("error_num"); if ((error_num != NULL)&&(error_num->getivalue() != ERR_IN_PROGRESS)) { Item* error_msg = res->findItem("error_msg"); if (error_msg != NULL) errmsg = error_msg->getsvalue(); //возврат строки ошибки return false; } Item* authenticator = res->findItem("authenticator"); if (authenticator != NULL) { sauthenticator = authenticator->getsvalue(); done = true; } free(res); sleep(1); //ждем 1 сек } while((count--)&&(!done)); if (!done) return false; //формируем запрос для подключения к проекту snprintf(sreq,sizeof(sreq),"<project_attach>\n<project_url>%s</project_url>\n<authenticator>%s</authenticator>\n<project_name>%s</project_name>\n</project_attach>\n",url,sauthenticator.c_str(),prjname); res = req(sreq); if (res == NULL) return false; kLogPrintf("request=\n %s\n\n answer=\n%s\n",sreq, res->toxmlstring().c_str()); bool result = (res->findItem("success") != NULL); free(res); return result; }
void Config::load() { isdefault = true; if (fullname == NULL) { generatedefault(); return; } struct stat st; int retcode = lstat(fullname, &st); if (retcode != 0) //файла нет? { //делаем дефолтный generatedefault(); return; } //читаем файл FILE* pfile; pfile = fopen(fullname,"r"); if (pfile!=NULL) { kLogPrintf("SIZE=%ld\n",st.st_size); char* buf = (char*)malloc(st.st_size + 1); size_t n = fread (buf,1,st.st_size,pfile); buf[n]=0; kLogPrintf("%s\n",buf); root = xmlparse(buf, st.st_size, errmsg); if (!errmsg.empty()) errmsg = fullname + std::string("\n") + errmsg; fclose (pfile); isdefault = false; } }
AddProjectForm::AddProjectForm(int rows, int cols, Srv* srv, const char* projname, bool userexist) : NForm(rows,cols) { this->srv = srv; settitle(projname); this->projname = projname; this->userexist = userexist; Item* project = NULL; if (srv !=NULL) project = srv->findprojectbynamefromall(projname); int row = 0; //поля try { genfields(row,project); } catch(const char* err) { kLogPrintf("ERROR EXCAPTION %s\n",err); } //пересчитываем высоту формы, чтобы влезли все поля и центрируем int r,c =0; scale_form(frm, &r, &c); kLogPrintf("field_count=%d scale_form()->%d,%d\n", field_count(frm), r, c); resize(r+3,c+2); post_form(frm); this->refresh(); }
bool Srv::accountmanager(const char* url, const char* username, const char* pass, bool useconfigfile, std::string& errmsg) //подключить аккаунт менеджер { if (strlen(url) > 0) { //получить конфиг (не знаю зачем!!!) if (!getprojectconfig(url,errmsg)) { errmsg = "Can't get config"; return false; } } char sreq[1024]; //формируем запрос if (useconfigfile) snprintf(sreq,sizeof(sreq),"<acct_mgr_rpc>\n<use_config_file/>\n</acct_mgr_rpc>\n"); else snprintf(sreq,sizeof(sreq),"<acct_mgr_rpc>\n<url>%s</url>\n<name>%s</name>\n<password>%s</password>\n</acct_mgr_rpc>\n",url,username,pass); Item* res = req(sreq); if (res == NULL) return false; kLogPrintf("request=\n %s\n\n answer=\n%s\n",sreq, res->toxmlstring().c_str()); //ждем завершения snprintf(sreq,sizeof(sreq),"<acct_mgr_rpc_poll/>"); bool done = false; int count = 30; //не больше 30 запросов do { res = req(sreq); if (res == NULL) return false; kLogPrintf("request=\n %s\n\n answer=\n%s\n",sreq, res->toxmlstring().c_str()); Item* error_num = res->findItem("error_num"); if (error_num != NULL) { int errnum = error_num->getivalue(); if (errnum == BOINC_SUCCESS) //успешно done = true; else if (errnum != ERR_IN_PROGRESS) //ошибка выходим { Item* message = res->findItem("message"); if (message != NULL) errmsg = message->getsvalue(); //возврат строки ошибки free(res); return false; } else sleep(1); //ERR_IN_PROGRESS ждем 1 сек } free(res); } while((count--)&&(!done)); acctmgrinfodom.needupdate = true; //чтобы тред обновил данные sleep(1); //даем треду 1 сек на обновление kLogPrintf("RET %b\n",done); return done; }
void AddProjectForm::eventhandle(NEvent* ev) //обработчик событий { if ( ev->done ) return; NMouseEvent* mevent = (NMouseEvent*)ev; if ( ev->type == NEvent::evMOUSE) { NForm::eventhandle(ev); //предок } if ( ev->type == NEvent::evKB ) { ev->done = true; switch(ev->keycode) { case KEY_ENTER: case '\n': //ENTER { form_driver(frm, REQ_NEXT_FIELD); //костыль чтобы текущее поле не потеряло значение char* email = strlowcase(rtrim(field_buffer(fields[emailfield],0))); char* passw = rtrim(field_buffer(fields[passwfield],0)); kLogPrintf("AddProjectForm OK name=[%s] url=[%s] email=[%s]\n passw=[%s]\n", projname.c_str(), projurl.c_str(), email, passw); if (srv!=NULL) { std::string errmsg; bool success = true; if (!userexist) //если аккаунта еще нет то создаем { char* username = strlowcase(rtrim(field_buffer(fields[usernamefield],0))); char* teamname = rtrim(field_buffer(fields[teamfield],0)); success = srv->createaccount(projurl.c_str(),email,passw, username, teamname, errmsg); } if (success) success = srv->projectattach(projurl.c_str(), projname.c_str(), email, passw, errmsg); //подключить проект if (success) putevent(new TuiEvent(evADDPROJECT)); //создаем событие чтобы закрыть форму else { //СООБЩЕНИЕ ОБ ОШИБКЕ errmsg = " Error: " + errmsg; set_field_buffer(fields[errmsgfield], 0, errmsg.c_str()); field_opts_on(fields[errmsgfield], O_VISIBLE); //делаем видимой строку ошибки this->refresh(); } } break; } case 27: putevent(new TuiEvent(evADDPROJECT)); //код закрытия окна break; default: kLogPrintf("AddProjectForm::KEYCODE=%d\n", ev->keycode); ev->done = false; NForm::eventhandle(ev); //предок break; } //switch } }
bool Srv::createaccount(const char* url, const char* email, const char* pass, const char* username, const char* teamname, std::string& errmsg) //создать аккаунт { kLogPrintf("createaccount(url=%s, email=%s, pass=%s, username=%s, teamname=%s)\n", url, email, pass, username, teamname); //расчитать хэш md5 от pass+email unsigned char md5digest[MD5_DIGEST_LENGTH]; MD5_CTX c; MD5_Init(&c); MD5_Update(&c, pass , strlen(pass)); MD5_Update(&c, email, strlen(email)); MD5_Final(md5digest,&c); char shash[1024]; //строковое представление хэша for (int i=0;i<MD5_DIGEST_LENGTH;i++) sprintf(shash+i*2,"%02x",md5digest[i]); //формируем запрос для создания аккаунта char sreq[1024]; snprintf(sreq,sizeof(sreq), "<create_account>\n" " <url>%s</url>\n" " <email_addr>%s</email_addr>\n" " <passwd_hash>%s</passwd_hash>\n" " <user_name>%s</user_name>\n" " <team_name>%s</team_name>\n" "</create_account>\n", url,email,shash,username,teamname); Item* res = req(sreq); if (res == NULL) return false; kLogPrintf("request=\n %s\n\n answer=\n%s\n",sreq, res->toxmlstring().c_str()); free(res); //ждем завершения int count = 30; //не больше 30 запросов snprintf(sreq,sizeof(sreq),"<create_account_poll/>"); bool done = false; do { res = req(sreq); if (res == NULL) return false; kLogPrintf("request=\n %s\n\n answer=\n%s\n",sreq, res->toxmlstring().c_str()); Item* error_num = res->findItem("error_num"); if ((error_num != NULL)&&(error_num->getivalue() != ERR_IN_PROGRESS)) { Item* error_msg = res->findItem("error_msg"); if (error_msg != NULL) errmsg = error_msg->getsvalue(); //возврат строки ошибки return false; } if (res->findItem("authenticator") != NULL) done = true; free(res); sleep(1); //ждем 1 сек } while((count--)&&(!done)); return true; }
void SrvList::clear() //удалить все соединения { kLogPrintf("SrvList::clear()\n"); std::list<Srv*>::iterator it; cursrv = servers.begin(); for (it = servers.begin(); it != servers.end(); it++) //чистим все соединения { kLogPrintf("+delete server\n"); delete (*it); kLogPrintf("-server deleted success\n"); } servers.clear(); }
Srv::~Srv() { kLogPrintf("+Srv::~Srv() host=%s:%s\n",shost,sport); if (isactive()) { setactive(false); //завершаем опросный тред (если он есть) kLogPrintf("waiting stop...\n"); pthread_join(thread, NULL); //ждем пока тред остановится } if (allprojectsdom != NULL) delete allprojectsdom; if (pwd != NULL) delete pwd; pthread_mutex_destroy(&mutex); kLogPrintf("-Srv::~Srv()\n"); }
void NMButton::eventhandle(NEvent* ev) //обработчик событий { NStaticText::eventhandle(ev); //предок if ( ev->done ) return; //одиночный или двойной клик NMouseEvent* mevent = (NMouseEvent*)ev; if (( ev->type == NEvent::evMOUSE ) && (mevent->cmdcode & (BUTTON1_CLICKED | BUTTON1_DOUBLE_CLICKED))) { if (isinside(mevent->row, mevent->col)) { ev->done = true; NEvent* tmp = pevent; pevent = NULL; putevent(tmp); //активируем событие связанное с этой кнопкой } } //клавиатура if ( ev->type == NEvent::evKB ) { if ( keys.end() != std::find(keys.begin(), keys.end(), ev->cmdcode) ) { kLogPrintf("NMButton::eventhandle() got '%c' key\n", ev->cmdcode); if (pevent) { ev->done = true; NEvent* tmp = pevent; pevent = NULL; putevent(tmp); //активируем событие связанное с этой кнопкой } } } }
void Config::generatedefault() { kLogPrintf("generatedafault()\n"); root = new Item(""); //корневой Item* cfg = new Item("boinctui_cfg"); root->addsubitem(cfg); addhost("127.0.0.1","31416",""); }
bool Srv::getprojectconfig(const char* url, std::string& errmsg) //получить c сервера файл конфигурации { //запрос на начало передачи Item* res = req("<get_project_config>\n<url>%s</url></get_project_config>\n", url); if (res == NULL) return false; kLogPrintf("request=\n ?\n\n answer=\n%s\n", res->toxmlstring().c_str()); free(res); //ждем завершения bool done = false; int count = 30; //не больше 30 запросов do { res = req("<get_project_config_poll/>"); if (res == NULL) return false; kLogPrintf("request=\n ?\n\n answer=\n%s\n", res->toxmlstring().c_str()); Item* error_num = res->findItem("error_num"); if (error_num != NULL) { int errnum = error_num->getivalue(); if (errnum == ERR_IN_PROGRESS) //ждать? sleep(1); //ERR_IN_PROGRESS ждем 1 сек else { free(res); break; } } else { Item* project_config = res->findItem("project_config"); if (project_config != NULL) done = true; else { free(res); break; } } free(res); } while((count--)&&(!done)); return done; }
PtrList::~PtrList() { kLogPrintf("PtrList::~PtrList() list.size()=%d\n",list.size()); while(!list.empty()) { delete list.front(); list.erase(list.begin()); } pthread_mutex_destroy(&mutex); }
void Config::save() { if (!errmsg.empty()) return; //если была ошибка при загрузке то файл не перезаписываем if (fullname == NULL) return; if (root == NULL) return; kLogPrintf("Save Config to FULLCFGPATH=%s\n",fullname); Item* cfg = root->findItem("boinctui_cfg"); if (cfg == NULL) return; std::string configxml = cfg->toxmlstring(); kLogPrintf("\n%s\n",cfg->toxmlstring().c_str()); FILE* pfile = fopen(fullname,"w"); if (pfile!=NULL) { fwrite(cfg->toxmlstring().c_str(),1, strlen(cfg->toxmlstring().c_str()),pfile); fclose (pfile); } }
void* Srv::updatethread(void* args) //трейд опрашивающий сервер { Srv* me = (Srv*)args; kLogPrintf("%s:%s::updatethread() started\n",me->gethost(),me->getport()); me->takt = 0; while(me->active) { //get data from remote server if ( me->statedom.empty() || ( (me->takt % STATE_TIME_INTERVAL) == 0 ) ) me->updatestate(); //<get_state> if (me->isconnected()&&(!me->loginfail)) //если нет коннекта то пропускаем прочие запросы { if ( me->msgdom.empty() || ( (me->takt % MSG_TIME_INTERVAL) == 0 ) ) me->updatemsgs(); //<get_message_count>/<get_messages> if ( me->statisticsdom.empty() || ( (me->takt % STATISTICS_TIME_INTERVAL) == 0 ) ) me->updatestatistics(); //<get_statistics> if ( me->dusagedom.empty() || ( (me->takt % DISKUSAGE_TIME_INTERVAL) == 0 ) ) me->updatediskusage(); //<get_disk_usage> if ( me->ccstatusdom.empty() || ( (me->takt % CCSTATUS_TIME_INTERVAL) == 0 ) || me->ccstatusdomneedupdate ) { me->updateccstatus(); //<get_cc_status> me->ccstatusdomneedupdate = false; } if (me->acctmgrinfodom.needupdate) me->updateacctmgrinfo(); //ин-я по аккаунт менеджеру } //спим 1 секунду проверяя me->ccstatusdomneedupdate for (int i = 0; i < 10; i++) { usleep(100000); //100 milisec if (me->ccstatusdomneedupdate) break; //прервать сон если нужен срочный апдейт } me->takt++; } kLogPrintf("%s:%s::updatethread() stoped\n",me->gethost(),me->getport()); return NULL; }
void Srv::setactive(bool b) //включить/выключить тред обновления данных { if (isactive() != b) if (b) { active = true; if ( 0 != pthread_create(&thread, NULL, updatethread, this)) kLogPrintf("pthread_create() error\n"); } else { active = false; //сигнализирует треду остановиться } }
bool Srv::login() //авторизоваться на сервере { bool result = false; // if (strlen(pwd) == 0) // return true; //пароль не задан (считаем что логин серверу не требуется) //получить случайную строку (nonce) Item* r1 = req("<auth1/>"); if (r1 == NULL) return result; kLogPrintf("login() nonce='%s'\n", r1->toxmlstring().c_str()); Item* nonce = r1->findItem("nonce"); if ( nonce == NULL ) { delete r1; return result; } const char* snonce = r1->findItem("nonce")->getsvalue(); //расчитать хэш md5 от nonce+pwd unsigned char md5digest[MD5_DIGEST_LENGTH]; MD5_CTX c; MD5_Init(&c); MD5_Update(&c, snonce, strlen(snonce)); MD5_Update(&c, pwd , strlen(pwd)); MD5_Final(md5digest,&c); char shash[1024]; //строковое представление хэша for (int i=0;i<MD5_DIGEST_LENGTH;i++) sprintf(shash+i*2,"%02x",md5digest[i]); kLogPrintf("login() md5_hash '%s%s' = %d\n",snonce,pwd,shash); //вторая фаза авторизации Item* r2 = req("<auth2>\n<nonce_hash>%s</nonce_hash>\n</auth2>",shash); kLogPrintf("login() Boinc answer ---\n%s\n", r2->toxmlstring().c_str()); if ( r2->findItem("unauthorized") != NULL ) //авторизация неуспешна result = true; delete r2; return result; }
Config::Config(const char* filename) { root = NULL; //полный путь к конфигу if (filename == NULL) fullname = NULL; else { //хоум каталог const char* homepath = getenv("HOME"); //полный путь fullname = (char*)malloc(strlen(homepath)+strlen(filename)+2); sprintf(fullname,"%s/%s",homepath,filename); kLogPrintf("FULLCFGPATH=%s\n",fullname); fflush(stdout); } //загружаем если файл уже есть или генерируем дефолтный load(); asciilinedraw = getivalue("line_draw_mode"); }
int main(int argc, char ** argv) { MainProg* mainprog; kLogOpen("boinctui.log"); initcurses(); #ifdef DEBUG struct mallinfo minf1 = mallinfo(); #endif mainprog = new MainProg(); mainprog->refresh(); mainprog->mainloop(); //запускаем осн. цикл событий delete mainprog; #ifdef DEBUG struct mallinfo minf2 = mallinfo(); kLogPrintf("mallinfo.uordblks= %d-%d = %d (bytes leak)\n",minf1.uordblks,minf2.uordblks, minf2.uordblks-minf1.uordblks); //malloc_stats(); #endif donecurses(); kLogClose(); exit(EXIT_SUCCESS); }
Item* xmlparse(const char* xml, int len, std::string& errmsg) //xml строка с xml len ее размер в байтах { XML_Parser parser; void* ret; parser = XML_ParserCreate(NULL/*"UTF-8"*/); XML_SetUserData(parser, (void*) &ret); XML_SetElementHandler(parser, callbackStartElement, callbackEndElement); //устанавливаем колбэки XML_SetCharacterDataHandler(parser, callbackData); Item* roottree = new Item(""); //создаем корневой эл-т дерева curitem.push(roottree); //и делаем его текущим int retcode = XML_Parse(parser, xml, len, XML_TRUE); //собственно парсинг if (retcode == XML_STATUS_ERROR) { kLogPrintf("XML Error: %s\n", XML_ErrorString(XML_GetErrorCode(parser))); errmsg = std::string("XML error:") + std::string(XML_ErrorString(XML_GetErrorCode(parser))); } XML_ParserFree(parser); while (!curitem.empty()) curitem.pop(); //очищаем стек return roottree; //возвращаем постороенное дерево }
AddAccMgrForm::AddAccMgrForm(int rows, int cols, Srv* srv, const char* mgrname) : NForm(rows,cols) { this->srv = srv; settitle(mgrname); this->mgrname = mgrname; Item* account_manager = NULL; if (srv !=NULL) account_manager = srv->findaccountmanager(mgrname); //поля int row = 0; genfields(row,account_manager); //пересчитываем высоту формы, чтобы влезли все поля и центрируем int r,c =0; scale_form(frm, &r, &c); kLogPrintf("field_count=%d scale_form()->%d,%d\n", field_count(frm), r, c); resize(r+3,c+2); set_current_field(frm, fields[0]); //фокус на поле post_form(frm); this->refresh(); }
void AddAccMgrForm::eventhandle(NEvent* ev) //обработчик событий { if ( ev->done ) return; NMouseEvent* mevent = (NMouseEvent*)ev; if ( ev->type == NEvent::evMOUSE) { NForm::eventhandle(ev); //предок } if ( ev->type == NEvent::evKB ) { ev->done = true; switch(ev->keycode) { case KEY_ENTER: case '\n': //ENTER { form_driver(frm, REQ_NEXT_FIELD); //костыль чтобы текущее поле не потеряло значение char* username = rtrim(field_buffer(fields[usernamefield],0)); char* passw = rtrim(field_buffer(fields[passwfield],0)); mgrurl = rtrim(field_buffer(fields[urlfield],0)); char* mgrname = rtrim(field_buffer(fields[namefield],0)); kLogPrintf("AddAccMgrForm OK username=[%s] passw=[%s]\n", username, passw); if (srv!=NULL) { std::string errmsg; bool success = srv->accountmanager(mgrurl.c_str(), username, passw, false, errmsg); if (success) { Item* account_manager = NULL; if (srv !=NULL) account_manager = srv->findaccountmanager(mgrname); if (account_manager == NULL) //для кастомных менеджеров сохраняем в конфигах { //проверить есть-ли уже в конфиге такой аккаунт менеджер //то обновляем существующую запись, иначе добавляем новую bool exist = false; Item* boinctui_cfg = gCfg->getcfgptr(); if (boinctui_cfg != NULL) { std::vector<Item*> mgrlist = boinctui_cfg->getItems("accmgr"); std::vector<Item*>::iterator it; for (it = mgrlist.begin(); it != mgrlist.end(); it++) { Item* namecfg = (*it)->findItem("name"); Item* urlcfg = (*it)->findItem("url"); if (namecfg != NULL) if (strcmp(namecfg->getsvalue(),mgrname) == 0) { exist = true; //обновить значение url в конфиге Item* urlcfg = (*it)->findItem("url"); if (urlcfg != NULL) urlcfg->setsvalue(mgrurl.c_str()); } if (urlcfg != NULL) { if (strcmp(urlcfg->getsvalue(),mgrurl.c_str()) == 0) { exist = true; //обновить значение имени в конфиге Item* namecfg = (*it)->findItem("name"); if (namecfg != NULL) namecfg->setsvalue(mgrname); } } if (exist) break; } if (!exist) { //записать в конфиг как новый Item* accmgr = new Item("accmgr"); boinctui_cfg->addsubitem(accmgr); Item* name = new Item("name"); name->setsvalue(mgrname); Item* url = new Item("url"); url->setsvalue(mgrurl.c_str()); accmgr->addsubitem(name); accmgr->addsubitem(url); } } } putevent(new TuiEvent(evADDACCMGR)); //создаем событие чтобы закрыть форму } else { //СООБЩЕНИЕ ОБ ОШИБКЕ errmsg = " Error: " + errmsg; set_field_buffer(fields[errmsgfield], 0, errmsg.c_str()); field_opts_on(fields[errmsgfield], O_VISIBLE); //делаем видимой строку ошибки this->refresh(); } } break; } case 27: putevent(new TuiEvent(evADDACCMGR, srv, mgrname.c_str())); //код закрытия окна break; default: kLogPrintf("AddAccMgrForm::KEYCODE=%d\n", ev->keycode); ev->done = false; NForm::eventhandle(ev); //предок break; } //switch } }
void MainProg::eventhandle(NEvent* ev) //обработчик событий КОРНЕВОЙ! { NProgram::eventhandle(ev); if (ev->done) //если событие не обработано обработать здесь return; if (ev->type == NEvent::evKB) //клавиатурные { switch(ev->keycode) { case 'q': case 'Q': done = true; //выходим break; case 'n': case 'N': menu->disable(); gsrvlist->nextserver(); wmain->setserver(gsrvlist->getcursrv()); menu->setserver(gsrvlist->getcursrv()); evtimertime = 0; //для перезапуска таймера для форсированонй перерисовки wmain->updatecaption(); break; case 'c': case 'C': if (getitembyid(typeid(CfgForm).name()) == NULL) { menu->disable(); CfgForm* cfgform = new CfgForm(15,54/*,cfg*/); insert(cfgform); cfgform->settitle("Configuration"); cfgform->refresh(); uistate = uistate | stUIMODALFORM; updatestatuslinecontent(); } break; case 'S': case 's': { TaskInfo* tinfo = (TaskInfo*)wmain->wtask->getselectedobj(); if (tinfo) //только если есть выделенный эл-т gsrvlist->getcursrv()->optask(tinfo->projecturl.c_str(), tinfo->taskname.c_str(),"suspend_result"); break; } case 'R': case 'r': { TaskInfo* tinfo = (TaskInfo*)wmain->wtask->getselectedobj(); if (tinfo) //только если есть выделенный эл-т gsrvlist->getcursrv()->optask(tinfo->projecturl.c_str(), tinfo->taskname.c_str(),"resume_result"); break; } case 'A': case 'a': { TaskInfo* tinfo = (TaskInfo*)wmain->wtask->getselectedobj(); if (tinfo) //только если есть выделенный эл-т { TuiEvent* ev = new TuiEvent(evABORTRES); ev->bdata1 = false; putevent(ev); //создаем событие с кодом 2 "abort_result" } break; } case 27: menu->disable(); //деструктим все какие есть модельные окна destroybyid(typeid(CfgForm).name()); //деструктим форму destroybyid(typeid(NMessageBox).name()); //деструктим форму if (destroybyid(typeid(TaskInfoWin).name())) //деструктим форму { wmain->wtask->setselectorenable(true); uistate = uistate & ~stUITASKINFO; } uistate = uistate & ~stUIMODALFORM; updatestatuslinecontent(); break; case KEY_F(9): if (!menu->isenable()) { menu->enable(); menu->action(); } else menu->disable(); break; default: kLogPrintf("KEYCODE=%d\n", ev->keycode); break; } //switch } if (ev->type == NEvent::evPROG) //прграммные { switch(ev->cmdcode) { case evCFGCH: //событие при изменении конфига { menu->disable(); destroybyid(typeid(CfgForm).name()); //деструктим форму //реакция на изменение конфига gsrvlist->refreshcfg(); wmain->setserver(gsrvlist->getcursrv()); //отображать первый в списке сервер menu->setserver(gsrvlist->getcursrv()); //отображать первый в списке сервер wmain->updatecaption(); evtimertime = 0; //для перезапуска таймера для форсированонй перерисовки break; } case evABOUT: //событие About win { if (!destroybyid(typeid(AboutWin).name())) { AboutWin* about = new AboutWin(2,40); insert(about); about->move(getmaxy(stdscr)/2-about->getheight()/2,getmaxx(stdscr)/2-about->getwidth()/2); //центрируем uistate = uistate | stUIMODALFORM; } else uistate = uistate & ~stUIMODALFORM; updatestatuslinecontent(); break; } case evKEYBIND: //событие KeyBinding win { if (!destroybyid(typeid(HelpWin).name())) { HelpWin* help = new HelpWin(2,40); insert(help); help->move(getmaxy(stdscr)/2-help->getheight()/2,getmaxx(stdscr)/2-help->getwidth()/2); //центрируем uistate = uistate | stUIMODALFORM; } else uistate = uistate & ~stUIMODALFORM; updatestatuslinecontent(); break; } case evBENCHMARK: //запустить бенчмарк { Srv* srv = gsrvlist->getcursrv(); if (srv != NULL) srv->runbenchmarks(); break; } case evADDPROJECT: //добавить проект { if (!destroybyid(typeid(AddProjectForm).name())) { TuiEvent* ev1 = (TuiEvent*)ev; Srv* srv = gsrvlist->getcursrv(); if (ev1->srv != NULL) { AddProjectForm* addform = new AddProjectForm(30,65,ev1->srv,ev1->sdata1.c_str(),ev1->bdata1); insert(addform); addform->move(getmaxy(stdscr)/2-addform->getheight()/2,getmaxx(stdscr)/2-addform->getwidth()/2); //центрируем uistate = uistate | stUIMODALFORM; } } else uistate = uistate & ~stUIMODALFORM; updatestatuslinecontent(); break; } case evADDACCMGR: //добавить акк менеджер { if (!destroybyid(typeid(AddAccMgrForm).name())) { TuiEvent* ev1 = (TuiEvent*)ev; Srv* srv = gsrvlist->getcursrv(); if (ev1->srv != NULL) { AddAccMgrForm* addmgrform = new AddAccMgrForm(30,65,ev1->srv,ev1->sdata1.c_str()); insert(addmgrform); addmgrform->move(getmaxy(stdscr)/2-addmgrform->getheight()/2,getmaxx(stdscr)/2-addmgrform->getwidth()/2); //центрируем uistate = uistate | stUIMODALFORM; } } else uistate = uistate & ~stUIMODALFORM; updatestatuslinecontent(); break; } case evPROJECTOP: //операции над проектом { TuiEvent* ev1 = (TuiEvent*)ev; const char* projname = ev1->sdata1.c_str(); const char* projop = ev1->sdata2.c_str(); if (!ev1->bdata1) //если нет флага подтвержденного события, то не выполняем а спрашиваем юзера { menu->disable(); //выключаем меню //создаем окно сообщения с подтверждением std::stringstream s; s << "Please Confirm\n\n" << "Project : "<< projname << "\nOperation : " << projop; NMessageBox* mbox = new NMessageBox(s.str().c_str()); TuiEvent* buttonYev = new TuiEvent(evPROJECTOP, ev1->srv, projname, projop); //событие для кнопки Y buttonYev->bdata1 = true; //флаг подтвержденности mbox->addbutton(new NMButton("Yes",buttonYev, 'Y','y',0)); NEvent* buttonNev = new NEvent(NEvent::evKB, 27); //событие для кнопки N mbox->addbutton(new NMButton("No",buttonNev, 'N','n',27,0)); insert(mbox); uistate = uistate | stUIMODALFORM; } else { kLogPrintf("evPROJECT confirmed event detected\n"); ev1->srv->opproject(projname, projop); //выполняем действие if (destroybyid(typeid(NMessageBox).name())) //удаляем окно подтверждения (если есть) uistate = uistate & ~stUIMODALFORM; } updatestatuslinecontent(); break; } case evABORTRES: //событие действий над проектами "abort_result" и.т.д. { TaskInfo* tinfo = (TaskInfo*)wmain->wtask->getselectedobj(); if (tinfo) //только если есть выделенный эл-т { TuiEvent* ev1 = (TuiEvent*)ev; if (!ev1->bdata1) //если нет флага подтвержденного события, то не выполняем а спрашиваем юзера { menu->disable(); //выключаем меню //создаем окно сообщения с подтверждением std::stringstream s; s << "Please Confirm\n\n" << "Task : " << tinfo->taskname << "\nOperation : " << "Abort"; NMessageBox* mbox = new NMessageBox(s.str().c_str()); TuiEvent* buttonYev = new TuiEvent(evABORTRES); //событие для кнопки Y buttonYev->bdata1 = true; //флаг подтвержденности mbox->addbutton(new NMButton("Yes",buttonYev, 'Y','y',0)); NEvent* buttonNev = new NEvent(NEvent::evKB, 27); //событие для кнопки N mbox->addbutton(new NMButton("No",buttonNev, 'N','n',27,0)); insert(mbox); uistate = uistate | stUIMODALFORM; } else { kLogPrintf("evABORTRES confirmed event detected\n"); Srv* srv = gsrvlist->getcursrv(); srv->optask(tinfo->projecturl.c_str(), tinfo->taskname.c_str(),"abort_result"); //выполняем действие if (destroybyid(typeid(NMessageBox).name())) //удаляем окно подтверждения (если есть) uistate = uistate & ~stUIMODALFORM; } updatestatuslinecontent(); break; } } case evTASKSELECTORON: { uistate = uistate | stUISELECTOR; updatestatuslinecontent(); break; } case evTASKSELECTOROFF: { uistate = uistate & ~stUISELECTOR; updatestatuslinecontent(); break; } case evTASKINFO: { TaskInfo* tinfo = (TaskInfo*)wmain->wtask->getselectedobj(); if (tinfo) //только если есть выделенный эл-т { wmain->wtask->setselectorenable(false); TaskInfoWin* taskinfowin = new TaskInfoWin("Task Info Raw View", gsrvlist->getcursrv(), tinfo->projecturl.c_str(), tinfo->taskname.c_str()); insert(taskinfowin); taskinfowin->move(getmaxy(stdscr)/2-taskinfowin->getheight()/2,getmaxx(stdscr)/2-taskinfowin->getwidth()/2); //центрируем uistate = uistate | stUITASKINFO; updatestatuslinecontent(); } } case evASCIIMODECHANGE: { gCfg->setivalue("line_draw_mode",asciilinedraw); refresh(); break; } } //switch } }
bool MainProg::mainloop() //основной цикл порождающий события { sigset_t newset; sigemptyset(&newset); sigaddset(&newset, SIGWINCH); //маска для сигнала if (gCfg->isdefault) //если конфига нет то открыть форму putevent(new NEvent(NEvent::evKB, 'C')); //создаем событие иммитирующее нажатие 'C' do { //блокировка сигнала изменения окна SIGWINCH на время отрисовки (из-за нереентерабельности курсес) sigprocmask(SIG_BLOCK, &newset, 0); //если нужен ресайз - перерисовать полностью if (MainProg::needresize) { smartresize(); refresh(); menu->refresh(); //wmain->erase(); wstatus->erase(); wmain->refresh(); wstatus->refresh(); } #ifndef EVENTTHREAD //если настало время посылаем evTIMER if (time(NULL) - evtimertime > EVTIMERINTERVAL) { NEvent* event = new NEvent(NEvent::evTIMER, 0); //создаем событие таймера putevent(event); //отправить в очередь time(&evtimertime); } //есть символ в буфере -> нужно создать событие int ic; if ( (ic = getch()) != ERR ) //символ(ы) есть? { NEvent* event = NULL; if (KEY_MOUSE == ic) { // mouse event MEVENT mevent; if (OK == getmouse(&mevent)) event = new NMouseEvent(mevent.bstate, mevent.y, mevent.x); //создаем мышиное событие else kLogPrintf("getmouse() err\n"); } else // keyboard event event = new NEvent(NEvent::evKB, ic); //создаем клавиатурное событие if (event != NULL) putevent(event); //отправить в очередь } #endif //есть события в очереди - выполняем while(!evqueueempty()) { NEvent* event = popevent(); //получить первое событие из очереди this->eventhandle(event); //отправить событие обработчику #ifdef DEBUG if ((event->type != NEvent::evTIMER)&&(!event->done)) kLogPrintf("WARNING! lost event %s\n", event->tostring().c_str()); #endif delete event; //удаляем отработанное событие //обновляем экран update_panels(); doupdate(); //физически выполняет перерисовку } //разблокируем SIGWINCH sigprocmask(SIG_UNBLOCK, &newset, 0); #ifdef EVENTTHREAD usleep(10000); //10 milisec #endif } while(!done); }
SrvList::~SrvList() { kLogPrintf("SrvList::~SrvList() servers.size()=%d\n",servers.size()); clear(); }