#include "daemon.h" #include "shared.h" #include "pisysteminfo.h" extern PIScreen screen; Daemon::Daemon(): PIPeer("_pisd_" + PISystemInfo::instance()->hostname + "_" + PIString(rand() % 100)), fm(this) { setName("Daemon"); timer.setName("__S__Daemon_timer"); mode = offset = cur = height = 0; CONNECTU(&screen, keyPressed, this, keyEvent) CONNECTU(&timer, tickEvent, this, timerEvent) CONNECTU(&fm, tileKey, this, fmKeyEvent) timer.addDelimiter(5); timer.start(200); //CONNECTU(&console, keyPressed, this, keyEvent) //dir.setDir("/home/peri4/Documents"); //TileSimple * tl; tile_root = new PIScreenTile(); tile_root->direction = Vertical; tile_header = new TileSimple("daemon header"); tile_header->size_policy = Fixed; list_daemons = new TileList("daemons list"); list_daemons->hide(); list_actions = new TileList("actions list"); list_actions->hide(); list_actions->content << TileList::Row("Information", CellFormat()); list_actions->content << TileList::Row("File manager", CellFormat()); list_actions->content << TileList::Row("Shell", CellFormat()); tile_info = new TileSimple("daemon info"); tile_info->hide(); fm.setRemote(true); tile_fm = fm.tile(); tile_fm->hide(); tile_root->addTile(tile_header); tile_root->addTile(list_daemons); tile_root->addTile(list_actions); tile_root->addTile(tile_info); tile_root->addTile(tile_fm); CONNECTU(&screen, tileEvent, this, tileEvent) } Daemon::~Daemon() { PIVector rl = remotes.values(); piForeach (Remote * r, rl) delete r; remotes.clear(); } PIScreenTile * Daemon::tile() const { return tile_root; } void Daemon::hideAll() { list_actions->hide(); tile_info->hide(); list_daemons->hide(); tile_fm->hide(); } void Daemon::showTile(PIScreenTile * t, const PIString & header) { hideAll(); t->show(); t->setFocus(); tile_header->content.resize(1); tile_header->content[0].first = header; tile_header->content[0].second.flags = Bold; lock(); if (!conn_name.isEmpty()) tile_header->content[0].first.insert(0, PIString("Daemon \"") + connectedDaemon() + "\": "); /*PIString s; if (!conn_name.isEmpty()) s = "Daemon \"" + connectedDaemon() + "\": "; s += header; tile_header->content.resize(1); tile_header->content[0].first = s; tile_header->content[0].second.flags = Bold;*/ unlock(); } void Daemon::fillInfoTile(const Daemon::HostInfo & hi) { screen.lock(); tile_info->content.clear(); tile_info->content << TileSimple::Row("Exec command: " + hi.execCommand, CellFormat()); tile_info->content << TileSimple::Row(" Executed on " + hi.execDateTime.toString(), CellFormat()); tile_info->content << TileSimple::Row(" Hostname: " + hi.hostname, CellFormat()); tile_info->content << TileSimple::Row(" Username: " + hi.user, CellFormat()); tile_info->content << TileSimple::Row(" OS name: " + hi.OS_name, CellFormat()); tile_info->content << TileSimple::Row(" OS version: " + hi.OS_version, CellFormat()); tile_info->content << TileSimple::Row("Architecture: " + hi.architecture, CellFormat()); tile_info->content << TileSimple::Row(" CPU count: " + PIString::fromNumber(hi.processorsCount), CellFormat()); screen.unlock(); } void Daemon::tileEvent(PIScreenTile * t, TileEvent e) { if (t == list_daemons) { if (e.type == TileList::RowPressed) { connectToDaemon(list_daemons->content[e.data.toInt()].first); showActionList(); } return; } if (t == list_actions) { if (e.type == TileList::RowPressed) { switch (e.data.toInt()) { case 0: mode = 2; showTile(tile_info, "Information"); break; case 1: mode = 3; showTile(tile_fm, "File manager"); requestChDir("."); break; default: break; } } return; } } void Daemon::keyEvent(PIKbdListener::KeyEvent key) { if (!tile_root->visible) return; if (screen.dialogTile()) return; switch (key.key) { case PIKbdListener::Esc: if (mode == 0) menuRequest(); else { if (mode > 1) { mode = 1; screen.lock(); tile_info->content.clear(); screen.unlock(); showActionList(); } else disconnect(); } break; default: break; } } void Daemon::fmKeyEvent(PIKbdListener::KeyEvent key) { PIByteArray ba; //Remote * r = remotes.value(conn_name); piCout << key.key << key.modifiers; switch (key.key) { case PIKbdListener::Return: { PIFile::FileInfo fi = fm.currentRemoteEntry(); if (!fi.isDir()) break; requestChDir(fi.name()); } break; case 'R': requestChDir("."); break; default: break; } } void Daemon::timerEvent(void * _d, int delim) { screen.lock(); list_daemons->content.clear(); availableDaemons(); piForeachC (PIString & i, available_daemons) list_daemons->content << TileList::Row(i, CellFormat()); screen.unlock(); if (delim == 5 && mode == 2) { if (conn_name.isEmpty()) return; PIByteArray ba; ba << int(RequestHostInfo); send(conn_name, ba); //std::cout << "send " << std::hex << ba; } } PIStringList Daemon::availableDaemons() { available_daemons.clear(); lock(); piForeachC (PIPeer::PeerInfo & p, allPeers()) { if (!p.name.startsWith("_pisd_")) continue; available_daemons << p.name.mid(6); } unlock(); return available_daemons; } void Daemon::connectToDaemon(const PIString & dn) { if (dn.isEmpty()) return; conn_name = "_pisd_" + dn; mode = 1; } void Daemon::disconnect() { conn_name.clear(); mode = 0; showMainList(); } PIString Daemon::connectedDaemon() const { return conn_name.mid(6); } void Daemon::peerConnected(const PIString & name) { /*piCout << "connected" << name; mode = 2; conn_name = name;*/ Remote * r = new Remote(name); CONNECTU(&(r->dt), sendRequest, this, dtSendRequest) CONNECTU(&(r->dt), receiveFinished, this, dtReceived) remotes.insert(name, r); } void Daemon::peerDisconnected(const PIString & name) { if (name == conn_name) { disconnect(); } Remote * dt = remotes.value(name); if (dt) delete dt; remotes.remove(name); } void Daemon::dtSendRequest(PIByteArray & data) { PIDataTransfer * dt = (PIDataTransfer*)emitter(); if (!dt) return; PIByteArray hdr; hdr << int(DataTransfer); data.insert(0, hdr); send(dt->name(), data); } void Daemon::dtReceived(bool ok) { if (!ok) return; PIDataTransfer * dt = (PIDataTransfer*)emitter(); if (!dt) return; dataReceived(emitter()->name(), dt->data()); } void Daemon::dataReceived(const PIString & from, const PIByteArray & data) { //if (conn_name != from) return; if (data.size() < 4) return; PIByteArray ba(data), rba; Remote * r(0); PIString dir; int type; ba >> type; //piCout << "rec from " << from << type; switch (type) { case RequestHostInfo: makeMyHostInfo(); rba << int(ReplyHostInfo) << info_my; break; case RequestChangeDir: r = remotes.value(from); if (!r) break; ba >> dir; r->dir_my.cd(dir); { PIVector fil = r->dir_my.entries(); piForeach (PIFile::FileInfo & f, fil) f.path = f.name(); rba << int(ReplyChangeDir) << r->dir_my.absolutePath() << fil; piCout << "cd to" << dir << ", abs =" << r->dir_my.absolutePath(); } break; case ReplyHostInfo: ba >> info_other; makeOtherHostInfo(); fillInfoTile(info_other); break; case ReplyChangeDir: r = remotes.value(from); if (!r) break; { PIVector fil; ba >> dir >> fil; r->dir_remote.setDir(dir); fm.setRemoteDir(dir); fm.setRemoteContent(fil); fm.remoteRestoreDir(); } break; case DataTransfer: r = remotes.value(from); if (r) r->dt.received(ba); break; }; if (!rba.isEmpty()) send(from, rba); } void Daemon::makeMyHostInfo() { info_my.execCommand = PISystemInfo::instance()->execCommand; info_my.hostname = PISystemInfo::instance()->hostname; info_my.user = PISystemInfo::instance()->user; info_my.OS_name = PISystemInfo::instance()->OS_name; info_my.OS_version = PISystemInfo::instance()->OS_version; info_my.architecture = PISystemInfo::instance()->architecture; info_my.execDateTime = PISystemInfo::instance()->execDateTime; info_my.processorsCount = PISystemInfo::instance()->processorsCount; info_my.ID = sys_mon.statistic().ID; info_my.threads = sys_mon.statistic().threads; info_my.priority = sys_mon.statistic().priority; info_my.physical_memsize = sys_mon.statistic().physical_memsize; info_my.share_memsize = sys_mon.statistic().share_memsize; info_my.cpu_load_system = sys_mon.statistic().cpu_load_system; info_my.cpu_load_user = sys_mon.statistic().cpu_load_user; } void Daemon::makeOtherHostInfo() { PISystemMonitor::ProcessStats & ps(const_cast(sys_mon_other.statistic())); ps.ID = info_other.ID; ps.threads = info_other.threads; ps.priority = info_other.priority; ps.physical_memsize = info_other.physical_memsize; ps.share_memsize = info_other.share_memsize; ps.cpu_load_system = info_other.cpu_load_system; ps.cpu_load_user = info_other.cpu_load_user; sys_mon_other.setStatistic(ps); } void Daemon::updateConsole() { switch (mode) { case 0: tabConnect(); break; case 1: tabFeature(); break; case RequestHostInfo: tabInfo(); break; } } void Daemon::tabConnectedHeader(int cols) { /*console.addString("Connected to: " + connectedDaemon(), 1, PIConsole::BackGreen | PIConsole::Bold); for (int i = 2; i <= cols; ++i) console.addString(" ", i, PIConsole::Green | PIConsole::Inverse);*/ } void Daemon::tabConnect() { /*startTab(); console.addString("Available daemons:"); int num = 0; dnames.clear(); PIStringList adl = availableDaemons(); piForeachC (PIString & p, adl) { dnames[num] = p; console.addString(" " + PIString(num++) + " - " + p); } finishTab();*/ } void Daemon::tabFeature() { /*startTab(); tabConnectedHeader(); console.addString("What do you wish to do with this daemon?"); console.addString(" 0 - show host info"); console.addString(" 1 - file manager"); console.addString(" 2 - execute command"); finishTab();*/ } void Daemon::tabInfo() { /*startTab(2); tabConnectedHeader(2); console.addString("Exec command: " + info_other.execCommand); console.addString(" Executed on " + info_other.execDateTime.toString()); console.addString(" Hostname: " + info_other.hostname); console.addString(" Username: " + info_other.user); console.addString(" OS name: " + info_other.OS_name); console.addString(" OS version: " + info_other.OS_version); console.addString("Architecture: " + info_other.architecture); console.addString(" CPU count: " + PIString::fromNumber(info_other.processorsCount)); console.addVariable("of this process", &sys_mon_other, 2); finishTab();*/ } void Daemon::requestChDir(const PIString & d) { if (d.isEmpty()) return; fm.remoteSaveDir(); fm.readingRemote(); PIByteArray ba; ba << int(RequestChangeDir) << d; send(conn_name, ba); //piCout << "request chdir" << d; }