code format

This commit is contained in:
2022-12-14 14:13:52 +03:00
parent 430a41fefc
commit c2b8a8d6da
297 changed files with 27331 additions and 24162 deletions

View File

@@ -1,885 +1,880 @@
#include "daemon.h"
#include "shared.h"
#include "pisysteminfo.h"
#include "picrypt.h"
const char self_name[] = "__self__";
extern PIScreen * screen;
extern PISystemMonitor sys_mon;
Daemon::Remote::Remote(const PIString & n): PIThread() {
setName(n);
term = 0;
ft.setName(n);
ft.setPacketSize(3984);
ft.setCRCEnabled(false);
CONNECTU(&ft, sendRequest, this, ftSendRequest)
CONNECTU(&ft, receiveFilesFinished, this, ftReceived)
CONNECTU(&ft, sendFilesFinished, this, ftSended)
CONNECTU(&term_timer, tickEvent, this, termTimerTick)
dir_my = PIDir::current();
}
Daemon::Remote::~Remote() {
shellClose();
ft.stop();
stopAndWait();
}
void Daemon::Remote::shellOpen() {
if (term) return;
piCoutObj << "shell open";
term = new PITerminal();
term->initialize();
term_timer.start(50);
}
void Daemon::Remote::shellClose() {
if (!term) return;
piCoutObj << "shell close";
term_timer.stop();
term->destroy();
delete term;
term = 0;
//piCoutObj << "shellClose ok";
}
void Daemon::Remote::shellResize(int w, int h) {
if (!term) return;
term->resize(w, h);
}
void Daemon::Remote::shellKeySend(PIKbdListener::KeyEvent k) {
if (!term) return;
term->write(k);
}
void Daemon::Remote::termTimerTick() {
if (!term) return;
PIVector<PIVector<PIScreenTypes::Cell> > cells = term->content();
if (pcells == cells) return;
pcells = cells;
PIByteArray ba;
ba << int(ShellContent) << cells;
//piCout << ba.size_s() << pcells.back().back().symbol.unicode16Code() << cells.back().back().symbol.unicode16Code();
sendRequest(name(), ba);
}
void Daemon::Remote::startAction(Daemon::PacketType a, const PIString & dir, const PIStringList & fl) {
_fl = fl;
if (!dir.isEmpty())
piForeach (PIString & s, _fl)
s.prepend(dir);
//piCout << "send" << _fl;
action = a;
startOnce();
}
void Daemon::Remote::run() {
PIDir d(dir_my);
switch (action) {
case CopyFiles:
ft.send(_fl);
break;
case RemoveFiles:
::removeFiles(d, _fl);
updateDirEntries();
changeDirFinished(name(), d.absolutePath());
break;
case RequestChangeDir:
updateDirEntries();
changeDirFinished(name(), d.absolutePath());
break;
case MkDir:
if (!_fl.isEmpty()) PIDir::make(d.absolutePath() + PIDir::separator + _fl.at(0));
updateDirEntries();
changeDirFinished(name(), d.absolutePath());
break;
case CryptFiles:
piCoutObj << "CryptFiles";
if (!_fl.isEmpty()) {
PIString p = askUserInput("Password:");
::cryptFiles(d, _fl, PICrypt::hash(p));
}
updateDirEntries();
changeDirFinished(name(), d.absolutePath());
break;
default: break;
};
}
void Daemon::Remote::updateDirEntries() {
//piCout << dir_my;
if (!dir_my.isExists()) dir_my = PIDir::current();
my_filelist = dir_my.entries();
piForeach (PIFile::FileInfo & f, my_filelist) f.path = f.name();
}
Daemon::TileFileProgress::TileFileProgress(): PIScreenTile() {
size_policy = PIScreenTypes::Fixed;
ft = 0;
rec = false;
setMargins(1, 1, 1, 1);
spacing = 1;
back_format.color_back = Yellow;
label_file = new TileSimple();
label_speed = new TileSimple();
label_cnt = new TileSimple();
prog_file = new TileProgress();
prog_all = new TileProgress();
buttons = new TileButtons("fd_buttons");
buttons->content << TileButtons::Button("Pause", CellFormat());
buttons->content << TileButtons::Button("Cancel", CellFormat());
label_file->content.resize(1);
label_speed->content.resize(1);
label_cnt->content.resize(1);
buttons->back_format.color_back = Yellow;
label_file->back_format.color_back = label_speed->back_format.color_back = label_cnt->back_format.color_back = Yellow;
label_file->content[0].second = label_speed->content[0].second = label_cnt->content[0].second = CellFormat(Black, Transparent);
addTile(label_file);
addTile(label_speed);
addTile(label_cnt);
addTile(prog_file);
addTile(prog_all);
addTile(buttons);
CONNECTU((::screen), tileEvent, this, tileEvent)
}
void Daemon::TileFileProgress::resizeEvent(int w, int h) {
PIScreenTile::resizeEvent(w, h);
w = ::screen->windowWidth() / 1.4;
minimumWidth = maximumWidth = w;
}
void Daemon::TileFileProgress::sizeHint(int & w, int & h) const {
PIScreenTile::sizeHint(w, h);
w = ::screen->windowWidth() / 1.4;
}
void Daemon::TileFileProgress::drawEvent(PIScreenDrawer * d) {
if (ft) {
label_file->content[0].first = ft->stateString() + " " + ft->curFile();
if (!label_file->content[0].first.isEmpty())
label_file->content[0].first[0] = label_file->content[0].first[0].toUpper();
PIString spd("Speed: "), cnt;
if (ft->isReceiving()) spd = ft->diagnostic().receiveSpeed();
else spd = ft->diagnostic().sendSpeed().expandRightTo(10, ' ');
spd += " ETA: ";
if (!ft->isReceiving() && !ft->isSending()) {
tm.reset();
spd += "-";
} else {
double el = tm.elapsed_s();
int cb = ft->bytesCur();
if ((el <= 0.) || (cb <= 0)) spd += "-";
else {
double s = (el / cb) * (ft->bytesAll() - cb);
spd += readableTime(PITime::fromSystemTime(PISystemTime::fromSeconds(s)));
}
}
spd += " Elapsed: " + readableTime(PITime::fromSystemTime(PISystemTime::fromSeconds(tme.elapsed_s())));
label_speed->content[0].first = spd;
cnt = "File: " + PIString::readableSize(ft->bytesFileCur()).expandLeftTo(8, ' ');
cnt += " / " + PIString::readableSize(ft->bytesFileAll()).expandLeftTo(8, ' ');
cnt += " All: " + PIString::readableSize(ft->bytesCur()).expandLeftTo(8, ' ');
cnt += " / " + PIString::readableSize(ft->bytesAll()).expandLeftTo(8, ' ');
label_cnt->content[0].first = cnt;
if (ft->bytesFileAll() > 0)
prog_file->value = piRoundd(ft->bytesFileCur() / double(ft->bytesFileAll()) * 100.);
if (ft->bytesAll() > 0)
prog_all->value = piRoundd(ft->bytesCur() / double(ft->bytesAll()) * 100.);
}
PIScreenTile::drawEvent(d);
}
void Daemon::TileFileProgress::show(PIFileTransfer * f) {
ft = f;
if (ft) {
conn_name = ft->name();
::screen->setDialogTile(this);
label_file->content[0].first = "Preparing ...";
prog_file->value = prog_all->value = 0;
buttons->cur = 0;
buttons->setFocus();
tm.reset();
tme.reset();
}
}
void Daemon::TileFileProgress::close(bool ok) {
buttons->content[0].first = "Pause";
ft = 0;
::screen->setDialogTile(0);
if (!ok) {
piCout << "file transfer aborted";
showInfo("Error while file transfer, files may be invalid");
}
}
void Daemon::TileFileProgress::tileEvent(PIScreenTile * t, TileEvent e) {
if (t->name() == "fd_buttons") {
if (e.type != TileButtons::ButtonSelected || !ft) return;
switch (e.data.toInt()) {
case 0:
if (buttons->content[0].first == "Pause") {
buttons->content[0].first = "Resume";
ft->pause();
} else {
buttons->content[0].first = "Pause";
ft->resume();
}
break;
case 1:
ft->stop();
close();
break;
};
}
}
Daemon::Daemon(): PIPeer(pisd_prefix + PISystemInfo::instance()->hostname + "_" + PIString::fromNumber(randomi() % 100)) {
// setName("Daemon");
dtimer.setName("__S__Daemon_timer");
mode = rmNone;
offset = cur = height = 0;
CONNECTU(screen, keyPressed, this, keyEvent)
CONNECTU(&dtimer, tickEvent, this, timerEvent)
CONNECTU(&fm, tileKey, this, fmKeyEvent)
CONNECTU(&fm, actionRequest, this, fmActionRequest)
_self = new Remote(self_name);
CONNECTU(_self, sendRequest, this, localSend)
CONNECTU(_self, receiveFinished, this, closeFileDialog)
CONNECTU(_self, sendFinished, this, closeFileDialog)
CONNECTU(_self, changeDirFinished, this, dirChanged)
localft.setName(self_name);
localft.setCRCEnabled(false);
CONNECTU(&localft, sendRequest, _self, received)
dtimer.addDelimiter(5);
dtimer.start(200);
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();
tile_fm = fm.tile();
tile_fm->hide();
tile_file_progress = new TileFileProgress();
tile_shell = new TileTerminal("shell");
tile_shell->hide();
CONNECTU(tile_shell, resizeRequest, this, shResizeRequest)
CONNECTU(tile_shell, keyPressed, this, shKeyEvent)
CONNECTU(tile_shell, closeRequest, this, requestCloseShell)
CONNECTU(tile_shell, closeRequest, this, escPressed)
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);
tile_root->addTile(tile_shell);
CONNECTU(screen, tileEvent, this, tileEvent)
reinit();
inited__ = true;
}
Daemon::~Daemon() {
requestCloseShell();
PIVector<Remote*> rl = remotes.values();
piForeach (Remote * r, rl) {
r->shellClose();
delete r;
}
remotes.clear();
delete _self;
}
PIScreenTile * Daemon::tile() const {
return tile_root;
}
void Daemon::escPressed() {
if (mode == rmNone || mode == rmLocalFileManager)
menuRequest();
else {
if (mode > rmSelectMode) {
mode = rmSelectMode;
screen->lock();
tile_info->content.clear();
screen->unlock();
showActionList();
} else
disconnect();
}
}
void Daemon::shResizeRequest() {
Remote * r = remotes.value(conn_name, 0);
if (!r) return;
PIByteArray ba;
ba << int(ShellResizeRequest) << int(tile_shell->width()) << int(tile_shell->height());
send(conn_name, ba);
}
void Daemon::shKeyEvent(PIKbdListener::KeyEvent k) {
Remote * r = remotes.value(conn_name, 0);
if (!r) return;
PIByteArray ba;
ba << int(ShellKeyEvent) << k;
send(conn_name, ba);
}
void Daemon::localSend(const PIString & p_name, const PIByteArray & data) {
//piCoutObj << "localSend" << localft.stateString();
PIByteArray h; h << int(FileTransfer);
PIByteArray ba = data;
ba.remove(0, h.size());
localft.received(ba);
}
void Daemon::hideAll() {
list_actions->hide();
tile_info->hide();
list_daemons->hide();
tile_fm->hide();
tile_shell->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() + "\": ");
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) {
PIMutexLocker ml(remote_mutex);
connectToDaemon(list_daemons->content[e.data.toInt()].first);
showActionList();
}
return;
}
if (t == list_actions) {
if (e.type == TileList::RowPressed) {
PIMutexLocker ml(remote_mutex);
switch (e.data.toInt()) {
case 0:
mode = rmInformation;
showTile(tile_info, "Information");
break;
case 1:
mode = rmFileManager;
showTile(tile_fm, "File manager");
requestChDir(".");
break;
case 2:
mode = rmShell;
showTile(tile_shell, "Shell");
requestOpenShell();
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:
escPressed();
break;
default: break;
}
}
void Daemon::fmKeyEvent(PIKbdListener::KeyEvent key) {
PIMutexLocker ml(remote_mutex);
// piCoutObj << 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::fmActionRequest(bool remote_tile, FileManager::Action type, PIVariant data) {
Remote * r = 0;
r = remotes.value(conn_name, 0);
if (!r && type != FileManager::LocalCopy && type != FileManager::LocalCrypt) return;
switch (type) {
case FileManager::Copy:
if (remote_tile) {
PIByteArray ba;
//piCout << fm.selectedRemote();
ba << int(CopyFiles) << fm.selectedRemote();
r->ft.setDirectory(fm.localDir());
send(conn_name, ba);
tile_file_progress->rec = true;
tile_file_progress->show(&(r->ft));
} else {
r->sendFiles(fm.localDir() + PIDir::separator, data.toStringList());
tile_file_progress->rec = false;
tile_file_progress->show(&(r->ft));
}
break;
case FileManager::Remove:
if (remote_tile) {
PIByteArray ba;
ba << int(RemoveFiles) << fm.selectedRemote();
send(conn_name, ba);
}
break;
case FileManager::MkDir:
if (remote_tile) {
PIByteArray ba;
ba << int(MkDir) << data.toString();
send(conn_name, ba);
}
break;
case FileManager::LocalCopy:
//piCoutObj << "localCopy";
if (remote_tile) {
localft.setDirectory(fm.localDir());
_self->sendFiles(fm.remoteDir() + PIDir::separator, data.toStringList());
} else {
localft.setDirectory(fm.remoteDir());
_self->sendFiles(fm.localDir() + PIDir::separator, data.toStringList());
}
tile_file_progress->rec = false;
tile_file_progress->show(&(_self->ft));
case FileManager::Crypt:
if (remote_tile) {
PIByteArray ba;
ba << int(CryptFiles) << fm.selectedRemote();
send(conn_name, ba);
} else {
_self->dir_my.setDir(fm.localDir());
_self->cryptFiles(data.toStringList());
}
break;
case FileManager::LocalCrypt:
piCoutObj << "LocalCrypt";
if (remote_tile) {
_self->dir_my.setDir(fm.remoteDir());
} else {
_self->dir_my.setDir(fm.localDir());
}
_self->cryptFiles(data.toStringList());
break;
default: break;
};
//piCout << remote_tile << type << data;
}
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 == rmInformation) {
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_prefix)) continue;
available_daemons << p.name.mid(6);
}
unlock();
return available_daemons;
}
void Daemon::connectToDaemon(const PIString & dn) {
if (dn.isEmpty()) return;
conn_name = pisd_prefix + dn;
mode = rmSelectMode;
}
void Daemon::disconnect() {
screen->enableExitCapture(PIKbdListener::F10);
conn_name.clear();
mode = rmNone;
showMainList();
}
PIString Daemon::connectedDaemon() const {
return conn_name.mid(6);
}
void Daemon::peerConnected(const PIString & p_name) {
while (!inited__) piMSleep(PIP_MIN_MSLEEP*5);
if (!p_name.startsWith(pisd_prefix)) return;
Remote * r = new Remote(p_name);
piCoutObj << "peer connected" << p_name;
CONNECTU(r, sendRequest, this, sendRequest)
CONNECTU(r, receiveFinished, this, filesReceived)
CONNECTU(r, sendFinished, this, filesSended)
CONNECTU(r, changeDirFinished, this, dirChanged)
PIMutexLocker ml2(remote_mutex);
remotes.insert(p_name, r);
}
void Daemon::peerDisconnected(const PIString & p_name) {
while (!inited__) piMSleep(PIP_MIN_MSLEEP*5);
piCoutObj << "peer disconnect" << p_name;
if (p_name == conn_name) {
disconnect();
}
PIMutexLocker ml(remote_mutex);
Remote * dt = remotes.value(p_name, 0);
if (!dt) return;
dt->shellClose();
if (tile_file_progress->ft == &(dt->ft)) {
tile_file_progress->close(false);
}
remotes.remove(p_name);
delete dt;
}
void Daemon::filesReceived(const PIString & p_name, bool ok) {
if (ok) {
piCout << "files received from" << p_name;
} else {
piCout << "warning, files not received fromsended" << p_name;
}
closeFileDialog(p_name, ok);
Remote * r = remotes.value(p_name, 0);
if (!r) return;
r->updateDir();
}
void Daemon::filesSended(const PIString & p_name, bool ok) {
if (ok) {
piCout << "files sended to" << p_name;
} else {
piCout << "warning, files not sended to" << p_name;
}
closeFileDialog(p_name, ok);
}
void Daemon::dirChanged(const PIString & p_name, const PIString & dir) {
if (p_name == self_name) {
fm.clearSelectionLocal();
fm.clearSelectionRemote();
fm.updateLocalDir();
fm.updateRemoteDir();
return;
}
PIMutexLocker ml(remote_mutex);
Remote * r = remotes.value(p_name, 0);
if (!r) return;
if (r->dir_my.absolutePath() != dir) return;
sendDirToRemote(r);
}
void Daemon::closeFileDialog(const PIString & p_name, bool ok) {
//piCout << "CLOSE" << tile_file_progress->conn_name << name << ok;
if (p_name == self_name) {
tile_file_progress->close(ok);
fm.clearSelectionLocal();
fm.clearSelectionRemote();
fm.updateLocalDir();
fm.updateRemoteDir();
return;
}
//piCout << "file transfer with" << p_name << (ok ? "success" : "failure");
if (tile_file_progress->conn_name != p_name) return;
tile_file_progress->close(ok);
if (tile_file_progress->rec) {
fm.remoteTile()->setFocus();
fm.clearSelectionRemote();
fm.updateLocalDir();
} else {
fm.localTile()->setFocus();
fm.clearSelectionLocal();
requestChDir(".");
}
}
void Daemon::dataReceived(const PIString & from, const PIByteArray & data) {
// piCout << "rec" << data.size();
if (data.size() < 4) return;
PIMutexLocker ml(remote_mutex);
// piCout << "lock in dataReceived";
PIByteArray ba(data), rba;
Remote * r = remotes.value(from);
PIString dir;
int type; ba >> type;
//piCout << "rec from " << from << type << r;
switch (type) {
case RequestHostInfo:
makeMyHostInfo();
rba << int(ReplyHostInfo) << info_my;
break;
case RequestChangeDir:
if (!r) break;
ba >> dir;
r->dir_my.cd(dir);
r->ft.setDirectory(r->dir_my);
//piCout << "store to" << r->dir_my.absolutePath();
piCoutObj << "cd to" << r->dir_my.absolutePath();
r->updateDir();
break;
case ReplyHostInfo:
ba >> info_other;
makeOtherHostInfo();
fillInfoTile(info_other);
break;
case ReplyChangeDir:
if (!r) break;
{
PIVector<PIFile::FileInfo> fil;
ba >> dir >> fil;
fm.setRemoteDir(dir);
fm.setRemoteContent(fil);
fm.remoteRestoreDir();
}
break;
case CopyFiles:
if (!r) return;
if (r->isRunning()) return;
{
PIStringList files;
ba >> files;
//piCout << "send" << files << "from" << r->dir_my.absolutePath();
r->sendFiles(r->dir_my.absolutePath() + PIDir::separator, files);
}
break;
case RemoveFiles:
if (!r) return;
if (r->isRunning()) return;
{
PIStringList files;
ba >> files;
//piCout << "send" << files << "from" << r->dir_my.absolutePath();
r->removeFiles(files);
}
break;
case MkDir:
if (!r) return;
{
PIString dn;
ba >> dn;
//piCout << "send" << files << "from" << r->dir_my.absolutePath();
r->makeDir(dn);
}
break;
case FileTransfer:
if (r) r->received(ba);
break;
case CryptFiles:
if (!r) return;
if (r->isRunning()) return;
{
PIStringList files;
ba >> files;
r->cryptFiles(files);
}
break;
case ShellOpen:
if (!r) return;
r->shellOpen();
break;
case ShellClose:
if (!r) return;
r->shellClose();
break;
case ShellContent: {
if (!r) return;
PIVector<PIVector<PIScreenTypes::Cell> > cells;
ba >> cells;
tile_shell->setContent(cells);
} break;
case ShellResizeRequest: {
if (!r) return;
int w, h;
ba >> w >> h;
r->shellResize(w, h);
} break;
case ShellKeyEvent: {
if (!r) return;
PIKbdListener::KeyEvent k;
ba >> k;
r->shellKeySend(k);
} break;
};
if (!rba.isEmpty()) send(from, rba);
}
void Daemon::sendDirToRemote(Remote * r) {
if (!r) return;
PIVector<PIFile::FileInfo> fil = r->my_filelist;
PIByteArray ba;
ba << int(ReplyChangeDir) << r->dir_my.absolutePath() << fil;
send(r->name(), ba);
}
void Daemon::requestOpenShell() {
Remote * r = remotes.value(conn_name, 0);
if (!r) return;
screen->disableExitCapture();
PIByteArray ba;
ba << int(ShellOpen);
send(conn_name, ba);
executeQueued(this, "shResizeRequest");
}
void Daemon::requestCloseShell() {
Remote * r = remotes.value(conn_name, 0);
if (!r) return;
screen->enableExitCapture(PIKbdListener::F10);
PIByteArray ba;
ba << int(ShellClose);
send(conn_name, ba);
}
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(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::requestChDir(const PIString & d) {
if (d.isEmpty()) return;
Remote * r = remotes.value(conn_name, 0);
if (!r) return;
fm.remoteSaveDir();
fm.readingRemote();
PIByteArray ba;
ba << int(RequestChangeDir) << d;
send(conn_name, ba);
}
#include "daemon.h"
#include "picrypt.h"
#include "pisysteminfo.h"
#include "shared.h"
const char self_name[] = "__self__";
extern PIScreen * screen;
extern PISystemMonitor sys_mon;
Daemon::Remote::Remote(const PIString & n): PIThread() {
setName(n);
term = 0;
ft.setName(n);
ft.setPacketSize(3984);
ft.setCRCEnabled(false);
CONNECTU(&ft, sendRequest, this, ftSendRequest)
CONNECTU(&ft, receiveFilesFinished, this, ftReceived)
CONNECTU(&ft, sendFilesFinished, this, ftSended)
CONNECTU(&term_timer, tickEvent, this, termTimerTick)
dir_my = PIDir::current();
}
Daemon::Remote::~Remote() {
shellClose();
ft.stop();
stopAndWait();
}
void Daemon::Remote::shellOpen() {
if (term) return;
piCoutObj << "shell open";
term = new PITerminal();
term->initialize();
term_timer.start(50);
}
void Daemon::Remote::shellClose() {
if (!term) return;
piCoutObj << "shell close";
term_timer.stop();
term->destroy();
delete term;
term = 0;
// piCoutObj << "shellClose ok";
}
void Daemon::Remote::shellResize(int w, int h) {
if (!term) return;
term->resize(w, h);
}
void Daemon::Remote::shellKeySend(PIKbdListener::KeyEvent k) {
if (!term) return;
term->write(k);
}
void Daemon::Remote::termTimerTick() {
if (!term) return;
PIVector<PIVector<PIScreenTypes::Cell>> cells = term->content();
if (pcells == cells) return;
pcells = cells;
PIByteArray ba;
ba << int(ShellContent) << cells;
// piCout << ba.size_s() << pcells.back().back().symbol.unicode16Code() << cells.back().back().symbol.unicode16Code();
sendRequest(name(), ba);
}
void Daemon::Remote::startAction(Daemon::PacketType a, const PIString & dir, const PIStringList & fl) {
_fl = fl;
if (!dir.isEmpty())
piForeach(PIString & s, _fl)
s.prepend(dir);
// piCout << "send" << _fl;
action = a;
startOnce();
}
void Daemon::Remote::run() {
PIDir d(dir_my);
switch (action) {
case CopyFiles: ft.send(_fl); break;
case RemoveFiles:
::removeFiles(d, _fl);
updateDirEntries();
changeDirFinished(name(), d.absolutePath());
break;
case RequestChangeDir:
updateDirEntries();
changeDirFinished(name(), d.absolutePath());
break;
case MkDir:
if (!_fl.isEmpty()) PIDir::make(d.absolutePath() + PIDir::separator + _fl.at(0));
updateDirEntries();
changeDirFinished(name(), d.absolutePath());
break;
case CryptFiles:
piCoutObj << "CryptFiles";
if (!_fl.isEmpty()) {
PIString p = askUserInput("Password:");
::cryptFiles(d, _fl, PICrypt::hash(p));
}
updateDirEntries();
changeDirFinished(name(), d.absolutePath());
break;
default: break;
};
}
void Daemon::Remote::updateDirEntries() {
// piCout << dir_my;
if (!dir_my.isExists()) dir_my = PIDir::current();
my_filelist = dir_my.entries();
piForeach(PIFile::FileInfo & f, my_filelist)
f.path = f.name();
}
Daemon::TileFileProgress::TileFileProgress(): PIScreenTile() {
size_policy = PIScreenTypes::Fixed;
ft = 0;
rec = false;
setMargins(1, 1, 1, 1);
spacing = 1;
back_format.color_back = Yellow;
label_file = new TileSimple();
label_speed = new TileSimple();
label_cnt = new TileSimple();
prog_file = new TileProgress();
prog_all = new TileProgress();
buttons = new TileButtons("fd_buttons");
buttons->content << TileButtons::Button("Pause", CellFormat());
buttons->content << TileButtons::Button("Cancel", CellFormat());
label_file->content.resize(1);
label_speed->content.resize(1);
label_cnt->content.resize(1);
buttons->back_format.color_back = Yellow;
label_file->back_format.color_back = label_speed->back_format.color_back = label_cnt->back_format.color_back = Yellow;
label_file->content[0].second = label_speed->content[0].second = label_cnt->content[0].second = CellFormat(Black, Transparent);
addTile(label_file);
addTile(label_speed);
addTile(label_cnt);
addTile(prog_file);
addTile(prog_all);
addTile(buttons);
CONNECTU((::screen), tileEvent, this, tileEvent)
}
void Daemon::TileFileProgress::resizeEvent(int w, int h) {
PIScreenTile::resizeEvent(w, h);
w = ::screen->windowWidth() / 1.4;
minimumWidth = maximumWidth = w;
}
void Daemon::TileFileProgress::sizeHint(int & w, int & h) const {
PIScreenTile::sizeHint(w, h);
w = ::screen->windowWidth() / 1.4;
}
void Daemon::TileFileProgress::drawEvent(PIScreenDrawer * d) {
if (ft) {
label_file->content[0].first = ft->stateString() + " " + ft->curFile();
if (!label_file->content[0].first.isEmpty()) label_file->content[0].first[0] = label_file->content[0].first[0].toUpper();
PIString spd("Speed: "), cnt;
if (ft->isReceiving())
spd = ft->diagnostic().receiveSpeed();
else
spd = ft->diagnostic().sendSpeed().expandRightTo(10, ' ');
spd += " ETA: ";
if (!ft->isReceiving() && !ft->isSending()) {
tm.reset();
spd += "-";
} else {
double el = tm.elapsed_s();
int cb = ft->bytesCur();
if ((el <= 0.) || (cb <= 0))
spd += "-";
else {
double s = (el / cb) * (ft->bytesAll() - cb);
spd += readableTime(PITime::fromSystemTime(PISystemTime::fromSeconds(s)));
}
}
spd += " Elapsed: " + readableTime(PITime::fromSystemTime(PISystemTime::fromSeconds(tme.elapsed_s())));
label_speed->content[0].first = spd;
cnt = "File: " + PIString::readableSize(ft->bytesFileCur()).expandLeftTo(8, ' ');
cnt += " / " + PIString::readableSize(ft->bytesFileAll()).expandLeftTo(8, ' ');
cnt += " All: " + PIString::readableSize(ft->bytesCur()).expandLeftTo(8, ' ');
cnt += " / " + PIString::readableSize(ft->bytesAll()).expandLeftTo(8, ' ');
label_cnt->content[0].first = cnt;
if (ft->bytesFileAll() > 0) prog_file->value = piRoundd(ft->bytesFileCur() / double(ft->bytesFileAll()) * 100.);
if (ft->bytesAll() > 0) prog_all->value = piRoundd(ft->bytesCur() / double(ft->bytesAll()) * 100.);
}
PIScreenTile::drawEvent(d);
}
void Daemon::TileFileProgress::show(PIFileTransfer * f) {
ft = f;
if (ft) {
conn_name = ft->name();
::screen->setDialogTile(this);
label_file->content[0].first = "Preparing ...";
prog_file->value = prog_all->value = 0;
buttons->cur = 0;
buttons->setFocus();
tm.reset();
tme.reset();
}
}
void Daemon::TileFileProgress::close(bool ok) {
buttons->content[0].first = "Pause";
ft = 0;
::screen->setDialogTile(0);
if (!ok) {
piCout << "file transfer aborted";
showInfo("Error while file transfer, files may be invalid");
}
}
void Daemon::TileFileProgress::tileEvent(PIScreenTile * t, TileEvent e) {
if (t->name() == "fd_buttons") {
if (e.type != TileButtons::ButtonSelected || !ft) return;
switch (e.data.toInt()) {
case 0:
if (buttons->content[0].first == "Pause") {
buttons->content[0].first = "Resume";
ft->pause();
} else {
buttons->content[0].first = "Pause";
ft->resume();
}
break;
case 1:
ft->stop();
close();
break;
};
}
}
Daemon::Daemon(): PIPeer(pisd_prefix + PISystemInfo::instance()->hostname + "_" + PIString::fromNumber(randomi() % 100)) {
// setName("Daemon");
dtimer.setName("__S__Daemon_timer");
mode = rmNone;
offset = cur = height = 0;
CONNECTU(screen, keyPressed, this, keyEvent)
CONNECTU(&dtimer, tickEvent, this, timerEvent)
CONNECTU(&fm, tileKey, this, fmKeyEvent)
CONNECTU(&fm, actionRequest, this, fmActionRequest)
_self = new Remote(self_name);
CONNECTU(_self, sendRequest, this, localSend)
CONNECTU(_self, receiveFinished, this, closeFileDialog)
CONNECTU(_self, sendFinished, this, closeFileDialog)
CONNECTU(_self, changeDirFinished, this, dirChanged)
localft.setName(self_name);
localft.setCRCEnabled(false);
CONNECTU(&localft, sendRequest, _self, received)
dtimer.addDelimiter(5);
dtimer.start(200);
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();
tile_fm = fm.tile();
tile_fm->hide();
tile_file_progress = new TileFileProgress();
tile_shell = new TileTerminal("shell");
tile_shell->hide();
CONNECTU(tile_shell, resizeRequest, this, shResizeRequest)
CONNECTU(tile_shell, keyPressed, this, shKeyEvent)
CONNECTU(tile_shell, closeRequest, this, requestCloseShell)
CONNECTU(tile_shell, closeRequest, this, escPressed)
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);
tile_root->addTile(tile_shell);
CONNECTU(screen, tileEvent, this, tileEvent)
reinit();
inited__ = true;
}
Daemon::~Daemon() {
requestCloseShell();
PIVector<Remote *> rl = remotes.values();
piForeach(Remote * r, rl) {
r->shellClose();
delete r;
}
remotes.clear();
delete _self;
}
PIScreenTile * Daemon::tile() const {
return tile_root;
}
void Daemon::escPressed() {
if (mode == rmNone || mode == rmLocalFileManager)
menuRequest();
else {
if (mode > rmSelectMode) {
mode = rmSelectMode;
screen->lock();
tile_info->content.clear();
screen->unlock();
showActionList();
} else
disconnect();
}
}
void Daemon::shResizeRequest() {
Remote * r = remotes.value(conn_name, 0);
if (!r) return;
PIByteArray ba;
ba << int(ShellResizeRequest) << int(tile_shell->width()) << int(tile_shell->height());
send(conn_name, ba);
}
void Daemon::shKeyEvent(PIKbdListener::KeyEvent k) {
Remote * r = remotes.value(conn_name, 0);
if (!r) return;
PIByteArray ba;
ba << int(ShellKeyEvent) << k;
send(conn_name, ba);
}
void Daemon::localSend(const PIString & p_name, const PIByteArray & data) {
// piCoutObj << "localSend" << localft.stateString();
PIByteArray h;
h << int(FileTransfer);
PIByteArray ba = data;
ba.remove(0, h.size());
localft.received(ba);
}
void Daemon::hideAll() {
list_actions->hide();
tile_info->hide();
list_daemons->hide();
tile_fm->hide();
tile_shell->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() + "\": ");
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) {
PIMutexLocker ml(remote_mutex);
connectToDaemon(list_daemons->content[e.data.toInt()].first);
showActionList();
}
return;
}
if (t == list_actions) {
if (e.type == TileList::RowPressed) {
PIMutexLocker ml(remote_mutex);
switch (e.data.toInt()) {
case 0:
mode = rmInformation;
showTile(tile_info, "Information");
break;
case 1:
mode = rmFileManager;
showTile(tile_fm, "File manager");
requestChDir(".");
break;
case 2:
mode = rmShell;
showTile(tile_shell, "Shell");
requestOpenShell();
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: escPressed(); break;
default: break;
}
}
void Daemon::fmKeyEvent(PIKbdListener::KeyEvent key) {
PIMutexLocker ml(remote_mutex);
// piCoutObj << 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::fmActionRequest(bool remote_tile, FileManager::Action type, PIVariant data) {
Remote * r = 0;
r = remotes.value(conn_name, 0);
if (!r && type != FileManager::LocalCopy && type != FileManager::LocalCrypt) return;
switch (type) {
case FileManager::Copy:
if (remote_tile) {
PIByteArray ba;
// piCout << fm.selectedRemote();
ba << int(CopyFiles) << fm.selectedRemote();
r->ft.setDirectory(fm.localDir());
send(conn_name, ba);
tile_file_progress->rec = true;
tile_file_progress->show(&(r->ft));
} else {
r->sendFiles(fm.localDir() + PIDir::separator, data.toStringList());
tile_file_progress->rec = false;
tile_file_progress->show(&(r->ft));
}
break;
case FileManager::Remove:
if (remote_tile) {
PIByteArray ba;
ba << int(RemoveFiles) << fm.selectedRemote();
send(conn_name, ba);
}
break;
case FileManager::MkDir:
if (remote_tile) {
PIByteArray ba;
ba << int(MkDir) << data.toString();
send(conn_name, ba);
}
break;
case FileManager::LocalCopy:
// piCoutObj << "localCopy";
if (remote_tile) {
localft.setDirectory(fm.localDir());
_self->sendFiles(fm.remoteDir() + PIDir::separator, data.toStringList());
} else {
localft.setDirectory(fm.remoteDir());
_self->sendFiles(fm.localDir() + PIDir::separator, data.toStringList());
}
tile_file_progress->rec = false;
tile_file_progress->show(&(_self->ft));
case FileManager::Crypt:
if (remote_tile) {
PIByteArray ba;
ba << int(CryptFiles) << fm.selectedRemote();
send(conn_name, ba);
} else {
_self->dir_my.setDir(fm.localDir());
_self->cryptFiles(data.toStringList());
}
break;
case FileManager::LocalCrypt:
piCoutObj << "LocalCrypt";
if (remote_tile) {
_self->dir_my.setDir(fm.remoteDir());
} else {
_self->dir_my.setDir(fm.localDir());
}
_self->cryptFiles(data.toStringList());
break;
default: break;
};
// piCout << remote_tile << type << data;
}
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 == rmInformation) {
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_prefix)) continue;
available_daemons << p.name.mid(6);
}
unlock();
return available_daemons;
}
void Daemon::connectToDaemon(const PIString & dn) {
if (dn.isEmpty()) return;
conn_name = pisd_prefix + dn;
mode = rmSelectMode;
}
void Daemon::disconnect() {
screen->enableExitCapture(PIKbdListener::F10);
conn_name.clear();
mode = rmNone;
showMainList();
}
PIString Daemon::connectedDaemon() const {
return conn_name.mid(6);
}
void Daemon::peerConnected(const PIString & p_name) {
while (!inited__)
piMSleep(PIP_MIN_MSLEEP * 5);
if (!p_name.startsWith(pisd_prefix)) return;
Remote * r = new Remote(p_name);
piCoutObj << "peer connected" << p_name;
CONNECTU(r, sendRequest, this, sendRequest)
CONNECTU(r, receiveFinished, this, filesReceived)
CONNECTU(r, sendFinished, this, filesSended)
CONNECTU(r, changeDirFinished, this, dirChanged)
PIMutexLocker ml2(remote_mutex);
remotes.insert(p_name, r);
}
void Daemon::peerDisconnected(const PIString & p_name) {
while (!inited__)
piMSleep(PIP_MIN_MSLEEP * 5);
piCoutObj << "peer disconnect" << p_name;
if (p_name == conn_name) {
disconnect();
}
PIMutexLocker ml(remote_mutex);
Remote * dt = remotes.value(p_name, 0);
if (!dt) return;
dt->shellClose();
if (tile_file_progress->ft == &(dt->ft)) {
tile_file_progress->close(false);
}
remotes.remove(p_name);
delete dt;
}
void Daemon::filesReceived(const PIString & p_name, bool ok) {
if (ok) {
piCout << "files received from" << p_name;
} else {
piCout << "warning, files not received fromsended" << p_name;
}
closeFileDialog(p_name, ok);
Remote * r = remotes.value(p_name, 0);
if (!r) return;
r->updateDir();
}
void Daemon::filesSended(const PIString & p_name, bool ok) {
if (ok) {
piCout << "files sended to" << p_name;
} else {
piCout << "warning, files not sended to" << p_name;
}
closeFileDialog(p_name, ok);
}
void Daemon::dirChanged(const PIString & p_name, const PIString & dir) {
if (p_name == self_name) {
fm.clearSelectionLocal();
fm.clearSelectionRemote();
fm.updateLocalDir();
fm.updateRemoteDir();
return;
}
PIMutexLocker ml(remote_mutex);
Remote * r = remotes.value(p_name, 0);
if (!r) return;
if (r->dir_my.absolutePath() != dir) return;
sendDirToRemote(r);
}
void Daemon::closeFileDialog(const PIString & p_name, bool ok) {
// piCout << "CLOSE" << tile_file_progress->conn_name << name << ok;
if (p_name == self_name) {
tile_file_progress->close(ok);
fm.clearSelectionLocal();
fm.clearSelectionRemote();
fm.updateLocalDir();
fm.updateRemoteDir();
return;
}
// piCout << "file transfer with" << p_name << (ok ? "success" : "failure");
if (tile_file_progress->conn_name != p_name) return;
tile_file_progress->close(ok);
if (tile_file_progress->rec) {
fm.remoteTile()->setFocus();
fm.clearSelectionRemote();
fm.updateLocalDir();
} else {
fm.localTile()->setFocus();
fm.clearSelectionLocal();
requestChDir(".");
}
}
void Daemon::dataReceived(const PIString & from, const PIByteArray & data) {
// piCout << "rec" << data.size();
if (data.size() < 4) return;
PIMutexLocker ml(remote_mutex);
// piCout << "lock in dataReceived";
PIByteArray ba(data), rba;
Remote * r = remotes.value(from);
PIString dir;
int type;
ba >> type;
// piCout << "rec from " << from << type << r;
switch (type) {
case RequestHostInfo:
makeMyHostInfo();
rba << int(ReplyHostInfo) << info_my;
break;
case RequestChangeDir:
if (!r) break;
ba >> dir;
r->dir_my.cd(dir);
r->ft.setDirectory(r->dir_my);
// piCout << "store to" << r->dir_my.absolutePath();
piCoutObj << "cd to" << r->dir_my.absolutePath();
r->updateDir();
break;
case ReplyHostInfo:
ba >> info_other;
makeOtherHostInfo();
fillInfoTile(info_other);
break;
case ReplyChangeDir:
if (!r) break;
{
PIVector<PIFile::FileInfo> fil;
ba >> dir >> fil;
fm.setRemoteDir(dir);
fm.setRemoteContent(fil);
fm.remoteRestoreDir();
}
break;
case CopyFiles:
if (!r) return;
if (r->isRunning()) return;
{
PIStringList files;
ba >> files;
// piCout << "send" << files << "from" << r->dir_my.absolutePath();
r->sendFiles(r->dir_my.absolutePath() + PIDir::separator, files);
}
break;
case RemoveFiles:
if (!r) return;
if (r->isRunning()) return;
{
PIStringList files;
ba >> files;
// piCout << "send" << files << "from" << r->dir_my.absolutePath();
r->removeFiles(files);
}
break;
case MkDir:
if (!r) return;
{
PIString dn;
ba >> dn;
// piCout << "send" << files << "from" << r->dir_my.absolutePath();
r->makeDir(dn);
}
break;
case FileTransfer:
if (r) r->received(ba);
break;
case CryptFiles:
if (!r) return;
if (r->isRunning()) return;
{
PIStringList files;
ba >> files;
r->cryptFiles(files);
}
break;
case ShellOpen:
if (!r) return;
r->shellOpen();
break;
case ShellClose:
if (!r) return;
r->shellClose();
break;
case ShellContent: {
if (!r) return;
PIVector<PIVector<PIScreenTypes::Cell>> cells;
ba >> cells;
tile_shell->setContent(cells);
} break;
case ShellResizeRequest: {
if (!r) return;
int w, h;
ba >> w >> h;
r->shellResize(w, h);
} break;
case ShellKeyEvent: {
if (!r) return;
PIKbdListener::KeyEvent k;
ba >> k;
r->shellKeySend(k);
} break;
};
if (!rba.isEmpty()) send(from, rba);
}
void Daemon::sendDirToRemote(Remote * r) {
if (!r) return;
PIVector<PIFile::FileInfo> fil = r->my_filelist;
PIByteArray ba;
ba << int(ReplyChangeDir) << r->dir_my.absolutePath() << fil;
send(r->name(), ba);
}
void Daemon::requestOpenShell() {
Remote * r = remotes.value(conn_name, 0);
if (!r) return;
screen->disableExitCapture();
PIByteArray ba;
ba << int(ShellOpen);
send(conn_name, ba);
executeQueued(this, "shResizeRequest");
}
void Daemon::requestCloseShell() {
Remote * r = remotes.value(conn_name, 0);
if (!r) return;
screen->enableExitCapture(PIKbdListener::F10);
PIByteArray ba;
ba << int(ShellClose);
send(conn_name, ba);
}
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(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::requestChDir(const PIString & d) {
if (d.isEmpty()) return;
Remote * r = remotes.value(conn_name, 0);
if (!r) return;
fm.remoteSaveDir();
fm.readingRemote();
PIByteArray ba;
ba << int(RequestChangeDir) << d;
send(conn_name, ba);
}

View File

@@ -1,215 +1,219 @@
#ifndef DAEMON_H
#define DAEMON_H
#include "piscreentiles.h"
#include "pipeer.h"
#include "pisystemmonitor.h"
#include "pidatatransfer.h"
#include "pifiletransfer.h"
#include "file_manager.h"
#include "terminal_tile.h"
#include "piterminal.h"
extern PISystemMonitor sys_mon;
class Daemon: public PIPeer {
PIOBJECT_SUBCLASS(Daemon, PIPeer)
public:
Daemon();
~Daemon();
struct HostInfo {
HostInfo() {
processorsCount = ID = threads = priority = -1;
physical_memsize = share_memsize = 0;
cpu_load_system = cpu_load_user = 0.;
}
PIString execCommand;
PIString hostname;
PIString user;
PIString OS_name;
PIString OS_version;
PIString architecture;
PIDateTime execDateTime;
int processorsCount;
int ID;
int threads;
int priority;
ulong physical_memsize;
ulong share_memsize;
float cpu_load_system;
float cpu_load_user;
};
void showMainList() {showTile(list_daemons, "Select daemon");}
void showActionList() {showTile(list_actions, "Select action");}
void showLocalFilemanager() {mode = rmLocalFileManager; showTile(tile_fm, "File manager");}
PIStringList availableDaemons();
void connectToDaemon(const PIString & dn);
void disconnect();
PIString connectedDaemon() const;
PIString thisDaemonName() const {return selfInfo().name.mid(6);}
PIScreenTile * tile() const;
FileManager fm;
private:
enum PacketType {
RequestHostInfo = 10,
RequestChangeDir,
ReplyHostInfo = 20,
ReplyChangeDir,
CopyFiles,
RemoveFiles,
MkDir,
CryptFiles,
FileTransfer = 30,
ShellOpen = 40,
ShellClose,
ShellContent,
ShellResizeRequest,
ShellKeyEvent
};
enum RemoteMode {
rmNone,
rmLocalFileManager,
rmSelectMode,
rmInformation,
rmFileManager,
rmShell
};
class Remote: public PIThread {
PIOBJECT_SUBCLASS(Remote, PIThread)
public:
explicit Remote(const PIString & n = PIString());
~Remote();
void sendFiles(const PIString & dir, const PIStringList & fl) {startAction(Daemon::CopyFiles, dir, fl);}
void removeFiles(const PIStringList & fl) {startAction(Daemon::RemoveFiles, PIString(), fl);}
void updateDir() {startAction(Daemon::RequestChangeDir, PIString(), PIStringList());}
void makeDir(const PIString & dir) {startAction(Daemon::MkDir, dir, PIStringList() << "");}
void cryptFiles(const PIStringList & fl) {startAction(Daemon::CryptFiles, PIString(), fl);}
void shellOpen();
void shellClose();
void shellResize(int w, int h);
void shellKeySend(PIKbdListener::KeyEvent k);
EVENT_HANDLER1(void, ftSendRequest, PIByteArray &, data) {PIByteArray h; h << int(FileTransfer); data.insert(0, h); sendRequest(name(), data);}
EVENT_HANDLER1(void, ftReceived, bool, ok) {receiveFinished(name(), ok);}
EVENT_HANDLER1(void, ftSended, bool, ok) {sendFinished(name(), ok);}
EVENT2(sendRequest, const PIString &, p_name, const PIByteArray &, data)
EVENT2(receiveFinished, const PIString & , p_name, bool, ok)
EVENT2(sendFinished, const PIString & , p_name, bool, ok)
EVENT2(changeDirFinished, const PIString & , p_name, const PIString & , dir)
EVENT_HANDLER1(void, received, PIByteArray & , data) {ft.received(data);}
EVENT_HANDLER(void, termTimerTick);
void startAction(PacketType a, const PIString & dir, const PIStringList & fl);
void run() override;
PIDir dir_my;
PIVector<PIFile::FileInfo> my_filelist;
PIVector<PIVector<PIScreenTypes::Cell> > pcells;
PIFileTransfer ft;
PIStringList _fl;
PacketType action;
PITimer term_timer;
PITerminal * term;
private:
void updateDirEntries();
};
class TileFileProgress: public PIScreenTile {
PIOBJECT_SUBCLASS(TileFileProgress, PIScreenTile)
public:
TileFileProgress();
void show(PIFileTransfer * f);
void close(bool ok = true);
TileSimple * label_file, * label_speed, * label_cnt;
TileProgress * prog_file, * prog_all;
TileButtons * buttons;
PIFileTransfer * ft;
PITimeMeasurer tm, tme;
void resizeEvent(int w, int h) override;
void sizeHint(int & w, int & h) const override;
void drawEvent(PIScreenDrawer * d) override;
bool rec;
PIString conn_name;
EVENT_HANDLER2(void, tileEvent, PIScreenTile *, t, PIScreenTypes::TileEvent, e);
};
EVENT_HANDLER2(void, tileEvent, PIScreenTile *, t, PIScreenTypes::TileEvent, e);
EVENT_HANDLER1(void, keyEvent, PIKbdListener::KeyEvent, key);
EVENT_HANDLER2(void, sendRequest, const PIString &, p_name, const PIByteArray &, data) {send(p_name, data);}
EVENT_HANDLER1(void, fmKeyEvent, PIKbdListener::KeyEvent, key);
EVENT_HANDLER3(void, fmActionRequest, bool, remote_tile, FileManager::Action, type, PIVariant, data);
EVENT_HANDLER (void, shResizeRequest);
EVENT_HANDLER1(void, shKeyEvent, PIKbdListener::KeyEvent, k);
EVENT_HANDLER2(void, timerEvent, void * , _d, int, delim);
EVENT_HANDLER2(void, filesReceived, const PIString & , p_name, bool, ok);
EVENT_HANDLER2(void, filesSended, const PIString & , p_name, bool, ok);
EVENT_HANDLER2(void, dirChanged, const PIString & , p_name, const PIString & , dir);
EVENT_HANDLER2(void, closeFileDialog, const PIString & , p_name, bool, ok);
EVENT_HANDLER2(void, localSend, const PIString & , p_name, const PIByteArray &, data);
EVENT_HANDLER (void, escPressed);
EVENT_HANDLER (void, requestOpenShell);
EVENT_HANDLER (void, requestCloseShell);
EVENT(menuRequest)
void hideAll();
void showTile(PIScreenTile * t, const PIString & header = PIString());
void fillInfoTile(const HostInfo & hi);
void peerConnected(const PIString & p_name) override;
void peerDisconnected(const PIString & p_name) override;
void dataReceived(const PIString & from, const PIByteArray & data) override;
void makeMyHostInfo();
void makeOtherHostInfo();
void requestChDir(const PIString & d);
void sendDirToRemote(Remote * r);
mutable PIStringList available_daemons;
PITimer dtimer;
PIString conn_name;
PIMutex remote_mutex;
PIMap<PIString, Remote*> remotes;
PISystemMonitor sys_mon_other;
HostInfo info_my, info_other;
PIScreenTile * tile_root, * tile_fm;
TileSimple * tile_info, * tile_header;
TileList * list_daemons, * list_actions;
TileFileProgress * tile_file_progress;
TileTerminal * tile_shell;
PIFileTransfer localft;
Remote * _self;
RemoteMode mode;
int offset, cur, height;
};
BINARY_STREAM_WRITE(Daemon::HostInfo) {
s << v.execCommand << v.hostname << v.user << v.OS_name
<< v.OS_version << v.architecture << v.execDateTime
<< v.processorsCount << v.ID << v.threads << v.priority
<< v.physical_memsize << v.share_memsize
<< v.cpu_load_system << v.cpu_load_user;
return s;
}
BINARY_STREAM_READ (Daemon::HostInfo) {
s >> v.execCommand >> v.hostname >> v.user >> v.OS_name
>> v.OS_version >> v.architecture >> v.execDateTime
>> v.processorsCount >> v.ID >> v.threads >> v.priority
>> v.physical_memsize >> v.share_memsize
>> v.cpu_load_system >> v.cpu_load_user;
return s;
}
#endif // DAEMON_H
#ifndef DAEMON_H
#define DAEMON_H
#include "file_manager.h"
#include "pidatatransfer.h"
#include "pifiletransfer.h"
#include "pipeer.h"
#include "piscreentiles.h"
#include "pisystemmonitor.h"
#include "piterminal.h"
#include "terminal_tile.h"
extern PISystemMonitor sys_mon;
class Daemon: public PIPeer {
PIOBJECT_SUBCLASS(Daemon, PIPeer)
public:
Daemon();
~Daemon();
struct HostInfo {
HostInfo() {
processorsCount = ID = threads = priority = -1;
physical_memsize = share_memsize = 0;
cpu_load_system = cpu_load_user = 0.;
}
PIString execCommand;
PIString hostname;
PIString user;
PIString OS_name;
PIString OS_version;
PIString architecture;
PIDateTime execDateTime;
int processorsCount;
int ID;
int threads;
int priority;
ulong physical_memsize;
ulong share_memsize;
float cpu_load_system;
float cpu_load_user;
};
void showMainList() { showTile(list_daemons, "Select daemon"); }
void showActionList() { showTile(list_actions, "Select action"); }
void showLocalFilemanager() {
mode = rmLocalFileManager;
showTile(tile_fm, "File manager");
}
PIStringList availableDaemons();
void connectToDaemon(const PIString & dn);
void disconnect();
PIString connectedDaemon() const;
PIString thisDaemonName() const { return selfInfo().name.mid(6); }
PIScreenTile * tile() const;
FileManager fm;
private:
enum PacketType {
RequestHostInfo = 10,
RequestChangeDir,
ReplyHostInfo = 20,
ReplyChangeDir,
CopyFiles,
RemoveFiles,
MkDir,
CryptFiles,
FileTransfer = 30,
ShellOpen = 40,
ShellClose,
ShellContent,
ShellResizeRequest,
ShellKeyEvent
};
enum RemoteMode {
rmNone,
rmLocalFileManager,
rmSelectMode,
rmInformation,
rmFileManager,
rmShell
};
class Remote: public PIThread {
PIOBJECT_SUBCLASS(Remote, PIThread)
public:
explicit Remote(const PIString & n = PIString());
~Remote();
void sendFiles(const PIString & dir, const PIStringList & fl) { startAction(Daemon::CopyFiles, dir, fl); }
void removeFiles(const PIStringList & fl) { startAction(Daemon::RemoveFiles, PIString(), fl); }
void updateDir() { startAction(Daemon::RequestChangeDir, PIString(), PIStringList()); }
void makeDir(const PIString & dir) { startAction(Daemon::MkDir, dir, PIStringList() << ""); }
void cryptFiles(const PIStringList & fl) { startAction(Daemon::CryptFiles, PIString(), fl); }
void shellOpen();
void shellClose();
void shellResize(int w, int h);
void shellKeySend(PIKbdListener::KeyEvent k);
EVENT_HANDLER1(void, ftSendRequest, PIByteArray &, data) {
PIByteArray h;
h << int(FileTransfer);
data.insert(0, h);
sendRequest(name(), data);
}
EVENT_HANDLER1(void, ftReceived, bool, ok) { receiveFinished(name(), ok); }
EVENT_HANDLER1(void, ftSended, bool, ok) { sendFinished(name(), ok); }
EVENT2(sendRequest, const PIString &, p_name, const PIByteArray &, data)
EVENT2(receiveFinished, const PIString &, p_name, bool, ok)
EVENT2(sendFinished, const PIString &, p_name, bool, ok)
EVENT2(changeDirFinished, const PIString &, p_name, const PIString &, dir)
EVENT_HANDLER1(void, received, PIByteArray &, data) { ft.received(data); }
EVENT_HANDLER(void, termTimerTick);
void startAction(PacketType a, const PIString & dir, const PIStringList & fl);
void run() override;
PIDir dir_my;
PIVector<PIFile::FileInfo> my_filelist;
PIVector<PIVector<PIScreenTypes::Cell>> pcells;
PIFileTransfer ft;
PIStringList _fl;
PacketType action;
PITimer term_timer;
PITerminal * term;
private:
void updateDirEntries();
};
class TileFileProgress: public PIScreenTile {
PIOBJECT_SUBCLASS(TileFileProgress, PIScreenTile)
public:
TileFileProgress();
void show(PIFileTransfer * f);
void close(bool ok = true);
TileSimple *label_file, *label_speed, *label_cnt;
TileProgress *prog_file, *prog_all;
TileButtons * buttons;
PIFileTransfer * ft;
PITimeMeasurer tm, tme;
void resizeEvent(int w, int h) override;
void sizeHint(int & w, int & h) const override;
void drawEvent(PIScreenDrawer * d) override;
bool rec;
PIString conn_name;
EVENT_HANDLER2(void, tileEvent, PIScreenTile *, t, PIScreenTypes::TileEvent, e);
};
EVENT_HANDLER2(void, tileEvent, PIScreenTile *, t, PIScreenTypes::TileEvent, e);
EVENT_HANDLER1(void, keyEvent, PIKbdListener::KeyEvent, key);
EVENT_HANDLER2(void, sendRequest, const PIString &, p_name, const PIByteArray &, data) { send(p_name, data); }
EVENT_HANDLER1(void, fmKeyEvent, PIKbdListener::KeyEvent, key);
EVENT_HANDLER3(void, fmActionRequest, bool, remote_tile, FileManager::Action, type, PIVariant, data);
EVENT_HANDLER(void, shResizeRequest);
EVENT_HANDLER1(void, shKeyEvent, PIKbdListener::KeyEvent, k);
EVENT_HANDLER2(void, timerEvent, void *, _d, int, delim);
EVENT_HANDLER2(void, filesReceived, const PIString &, p_name, bool, ok);
EVENT_HANDLER2(void, filesSended, const PIString &, p_name, bool, ok);
EVENT_HANDLER2(void, dirChanged, const PIString &, p_name, const PIString &, dir);
EVENT_HANDLER2(void, closeFileDialog, const PIString &, p_name, bool, ok);
EVENT_HANDLER2(void, localSend, const PIString &, p_name, const PIByteArray &, data);
EVENT_HANDLER(void, escPressed);
EVENT_HANDLER(void, requestOpenShell);
EVENT_HANDLER(void, requestCloseShell);
EVENT(menuRequest)
void hideAll();
void showTile(PIScreenTile * t, const PIString & header = PIString());
void fillInfoTile(const HostInfo & hi);
void peerConnected(const PIString & p_name) override;
void peerDisconnected(const PIString & p_name) override;
void dataReceived(const PIString & from, const PIByteArray & data) override;
void makeMyHostInfo();
void makeOtherHostInfo();
void requestChDir(const PIString & d);
void sendDirToRemote(Remote * r);
mutable PIStringList available_daemons;
PITimer dtimer;
PIString conn_name;
PIMutex remote_mutex;
PIMap<PIString, Remote *> remotes;
PISystemMonitor sys_mon_other;
HostInfo info_my, info_other;
PIScreenTile *tile_root, *tile_fm;
TileSimple *tile_info, *tile_header;
TileList *list_daemons, *list_actions;
TileFileProgress * tile_file_progress;
TileTerminal * tile_shell;
PIFileTransfer localft;
Remote * _self;
RemoteMode mode;
int offset, cur, height;
};
BINARY_STREAM_WRITE(Daemon::HostInfo) {
s << v.execCommand << v.hostname << v.user << v.OS_name << v.OS_version << v.architecture << v.execDateTime << v.processorsCount << v.ID
<< v.threads << v.priority << v.physical_memsize << v.share_memsize << v.cpu_load_system << v.cpu_load_user;
return s;
}
BINARY_STREAM_READ(Daemon::HostInfo) {
s >> v.execCommand >> v.hostname >> v.user >> v.OS_name >> v.OS_version >> v.architecture >> v.execDateTime >> v.processorsCount >>
v.ID >> v.threads >> v.priority >> v.physical_memsize >> v.share_memsize >> v.cpu_load_system >> v.cpu_load_user;
return s;
}
#endif // DAEMON_H

View File

@@ -1,340 +1,342 @@
#include "file_manager.h"
#include "shared.h"
FileManager::TileDir::TileDir(): TileList() {
label_path = 0;
selection_mode = TileList::MultiSelection;
dir = PIDir::current();
resized = is_right = remote_mode = false;
}
PIStringList FileManager::TileDir::selectedNames() const {
PIStringList ret;
PIMutexLocker ml(e_mutex);
PIVector<int> sind = selected.toVector();
piForeachC (int i, sind)
ret << entries[i].name();
ret.removeOne("..");
return ret;
}
bool FileManager::TileDir::keyEvent(PIKbdListener::KeyEvent key) {
bool pass = false;
PIString nd;
switch (key.key) {
case 'R': if (!(is_right && remote_mode)) updateDir(); pass = true; break;
case PIKbdListener::F5:
if (selected.isEmpty())
selected << cur;
if (!askQuestion("Copy selected files?")) return true;
setFocus();
//piCoutObj << "remote" << remote_mode;
if (remote_mode) actionRequest(is_right, Copy, selectedNames());
else actionRequest(is_right, LocalCopy, selectedNames());
break;
case PIKbdListener::F6:
if (key.modifiers[PIKbdListener::Shift]) {
if (selected.isEmpty())
selected << cur;
if (!askQuestion("Crypt selected files?")) return true;
setFocus();
if (remote_mode) actionRequest(is_right, Crypt, selectedNames());
else actionRequest(is_right, LocalCrypt, selectedNames());
}
break;
case PIKbdListener::F7:
nd = askUserInput("Enter new directory name:");
setFocus();
if (nd.isEmpty()) return true;
if (is_right && remote_mode)
actionRequest(is_right, MkDir, nd);
else {
PIDir::make(dir.absolutePath() + PIDir::separator + nd);
updateDir();
}
pass = true;
break;
case PIKbdListener::F8:
if (selected.isEmpty())
selected << cur;
if (!askQuestion("Delete selected?")) {
setFocus();
return false;
}
setFocus();
if (is_right && remote_mode) {
actionRequest(is_right, Remove, selectedNames());
} else {
removeFiles(dir, selectedNames());
selected.clear();
updateDir();
}
pass = true;
break;
case PIKbdListener::Return:
{
e_mutex.lock();
bool ud = false;
if (cur < entries.size_s() && cur >= 0) {
if (!(is_right && remote_mode)) {
//piCout << entries[cur];
if (entries[cur].isDir()) {
prev_pos[dir.path()] = PIPair<int, int>(cur, offset);
dir.cd(entries[cur].name());
PIPair<int, int> cp = prev_pos.value(dir.path());
cur = cp.first;
offset = cp.second;
selected.clear();
ud = true;
}
}
pass = true;
}
e_mutex.unlock();
if (ud) updateDir();
}
break;
}
// piCout << is_right << remote_mode << pass;
if (is_right && remote_mode && pass) {
((void(*)(void*,PIKbdListener::KeyEvent))key_func)(fm, key);
return true;
}
return TileList::keyEvent(key);
}
void FileManager::TileDir::lock() {
if (screen && !resized) ((PIScreen*)screen)->lock();
}
void FileManager::TileDir::unlock() {
if (screen && !resized) ((PIScreen*)screen)->unlock();
}
void FileManager::TileDir::showReading() {
PIMutexLocker ml(e_mutex);
cur = -1;
offset = 0;
entries.clear();
content.resize(1);
content[0] = Row("... Reading ...", CellFormat());
}
void FileManager::TileDir::setContent(const PIVector<PIFile::FileInfo> & l) {
PIMutexLocker ml(e_mutex);
PIVector<PIFile::FileInfo> fl, dl;
entries.clear();
if (l.isEmpty()) {
PIFile::FileInfo fi;
fi.path = "..";
fi.flags |= PIFile::FileInfo::DotDot | PIFile::FileInfo::Dir;
entries << fi;
} else {
bool root = dir.path() == PIDir::separator;
for (int i = 0; i < l.size_s(); ++i) {
if (l[i].name() == ".") continue;
if (l[i].name() == "..") {
if (!root) dl.push_front(l[i]);
continue;
}
if (l[i].isDir()) dl << l[i];
else fl << l[i];
}
entries << dl << fl;
}
}
void FileManager::TileDir::updateDir() {
lock();
int pc = cur, po = offset;
showReading();
unlock();
setContent(dir.entries());
if (label_path) {
label_path->content.resize(1);
label_path->content[0].first = dir.absolutePath();
}
cur = pc;
offset = po;
buildNames();
}
void FileManager::TileDir::buildNames() {
lock();
PIMutexLocker ml(e_mutex);
content.clear();
PIChar t;
CharFlags cf = 0;
Color cc = Default;
PIString fcol, scol;
piForeachC (PIFile::FileInfo & e, entries) {
if (e.isDir()) {
t = '/';
cf = Bold;
scol = " dir";
} else {
if (e.perm_user.exec || e.perm_group.exec || e.perm_other.exec) {
cf = Bold;
cc = Green;
t = '*';
} else {
t = ' ';
cc = Default;
cf = 0;
}
scol = PIString::readableSize(e.size);
}
if (e.isSymbolicLink() && (t != '*')) t = '~';
scol = scol.expandRightTo(9, ' ') + "| " + e.time_modification.toString("dd.MM hh:mm:ss") + " | "
+ e.perm_user.toString() + " " + e.perm_group.toString() + " " + e.perm_other.toString();
fcol = t + e.name();
if (fcol.size_s() >= width_ - 2 - scol.size_s())
fcol = fcol.left(width_ - 5 - scol.size_s()) + "...";
fcol.expandRightTo(width_ - 1 - scol.size_s(), ' ');
content << Row(fcol + scol, CellFormat(cc, Transparent, cf));
}
unlock();
}
void FileManager::TileDir::sizeHint(int & w, int & h) const {
w = h = 4;
}
void FileManager::TileDir::resizeEvent(int w, int h) {
resized = true;
buildNames();
resized = false;
TileList::resizeEvent(w, h);
}
FileManager::FileManager() {
setName("FileManager");
TileSimple * tl;
tile_root = new PIScreenTile();
tile_root->direction = Vertical;
PIScreenTile * pt = new PIScreenTile();
pt->direction = Horizontal;
pt->spacing = 1;
pt->back_format.color_back = Cyan;
for (int i = 0; i < 2; ++i) {
PIScreenTile * panel = new PIScreenTile();
TileSimple * plabel = new TileSimple();
plabel->size_policy = Fixed;
plabel->maximumWidth = 1;
panel->direction = Vertical;
panels[i] = new TileDir();
panels[i]->fm = this;
panels[i]->key_func = (void*)tileKey_s;
panels[i]->setName("file panel " + PIString::fromNumber(i));
panels[i]->label_path = plabel;
CONNECTU(panels[i], actionRequest, this, actionRequest)
panel->addTile(plabel);
panel->addTile(panels[i]);
panels[i]->updateDir();
pt->addTile(panel);
}
panels[1]->is_right = true;
tile_root->addTile(pt);
PIScreenTile * labels = new PIScreenTile();
labels->size_policy = Fixed;
labels->direction = Horizontal;
PIVector<SSPair> ll;
ll << SSPair(" Esc", "Exit") << SSPair(" F5", "Copy") << SSPair(" F6", "Move") << SSPair(" F7", "MkDir") << SSPair(" F8", "Delete");
piForeachC (SSPair & l, ll) {
tl = new TileSimple(); labels->addTile(tl);
tl->content << TileSimple::Row(l.first, CellFormat(White, Transparent, Bold));
tl = new TileSimple(); labels->addTile(tl);
tl->content << TileSimple::Row(l.second, CellFormat(Black, Cyan));
}
tl = new TileSimple(); labels->addTile(tl);
tl->size_policy = Expanding;
tile_root->addTile(labels);
}
PIScreenTile * FileManager::tile() const {
return tile_root;
}
void FileManager::setLocal() {
if (panels[1]->remote_mode) setRemoteDir(panels[0]->dir.absolutePath());
panels[0]->remote_mode = panels[1]->remote_mode = false;
}
void FileManager::setRemote() {
panels[0]->remote_mode = panels[1]->remote_mode = true;
}
void FileManager::setRemoteDir(const PIString & d) {
panels[1]->dir.setDir(d);
if (panels[1]->label_path) {
panels[1]->label_path->content.resize(1);
panels[1]->label_path->content[0].first = panels[1]->dir.path();
}
}
void FileManager::setRemoteContent(const PIVector< PIFile::FileInfo > & el) {
panels[1]->setContent(el);
panels[1]->buildNames();
}
int FileManager::selectedPanel() const {
for (int i = 0; i < 2; i++)
if (panels[i]->hasFocus()) return i;
return -1;
}
PIStringList FileManager::selectedRemote() const {
PIStringList ret;
panels[1]->lock();
PIVector<int> sil = panels[1]->selected.toVector();
piForeachC (int i, sil)
ret << panels[1]->entries[i].path;
panels[1]->unlock();
return ret;
}
PIFile::FileInfo FileManager::currentRemoteEntry() const {
if ((panels[1]->cur < 0) || (panels[1]->cur >= panels[1]->content.size_s())) return PIFile::FileInfo();
return panels[1]->entries[panels[1]->cur];
}
void FileManager::remoteSaveDir() {
panels[1]->prev_pos[panels[1]->dir.path()] = PIPair<int, int>(panels[1]->cur, panels[1]->offset);
}
void FileManager::remoteRestoreDir() {
PIPair<int, int> cp = panels[1]->prev_pos.value(panels[1]->dir.path());
panels[1]->selected.clear();
panels[1]->cur = cp.first;
panels[1]->offset = cp.second;
if ((panels[1]->cur < 0) || (panels[1]->cur >= panels[1]->content.size_s()))
panels[1]->cur = 0;
}
#include "file_manager.h"
#include "shared.h"
FileManager::TileDir::TileDir(): TileList() {
label_path = 0;
selection_mode = TileList::MultiSelection;
dir = PIDir::current();
resized = is_right = remote_mode = false;
}
PIStringList FileManager::TileDir::selectedNames() const {
PIStringList ret;
PIMutexLocker ml(e_mutex);
PIVector<int> sind = selected.toVector();
piForeachC(int i, sind)
ret << entries[i].name();
ret.removeOne("..");
return ret;
}
bool FileManager::TileDir::keyEvent(PIKbdListener::KeyEvent key) {
bool pass = false;
PIString nd;
switch (key.key) {
case 'R':
if (!(is_right && remote_mode)) updateDir();
pass = true;
break;
case PIKbdListener::F5:
if (selected.isEmpty()) selected << cur;
if (!askQuestion("Copy selected files?")) return true;
setFocus();
// piCoutObj << "remote" << remote_mode;
if (remote_mode)
actionRequest(is_right, Copy, selectedNames());
else
actionRequest(is_right, LocalCopy, selectedNames());
break;
case PIKbdListener::F6:
if (key.modifiers[PIKbdListener::Shift]) {
if (selected.isEmpty()) selected << cur;
if (!askQuestion("Crypt selected files?")) return true;
setFocus();
if (remote_mode)
actionRequest(is_right, Crypt, selectedNames());
else
actionRequest(is_right, LocalCrypt, selectedNames());
}
break;
case PIKbdListener::F7:
nd = askUserInput("Enter new directory name:");
setFocus();
if (nd.isEmpty()) return true;
if (is_right && remote_mode)
actionRequest(is_right, MkDir, nd);
else {
PIDir::make(dir.absolutePath() + PIDir::separator + nd);
updateDir();
}
pass = true;
break;
case PIKbdListener::F8:
if (selected.isEmpty()) selected << cur;
if (!askQuestion("Delete selected?")) {
setFocus();
return false;
}
setFocus();
if (is_right && remote_mode) {
actionRequest(is_right, Remove, selectedNames());
} else {
removeFiles(dir, selectedNames());
selected.clear();
updateDir();
}
pass = true;
break;
case PIKbdListener::Return: {
e_mutex.lock();
bool ud = false;
if (cur < entries.size_s() && cur >= 0) {
if (!(is_right && remote_mode)) {
// piCout << entries[cur];
if (entries[cur].isDir()) {
prev_pos[dir.path()] = PIPair<int, int>(cur, offset);
dir.cd(entries[cur].name());
PIPair<int, int> cp = prev_pos.value(dir.path());
cur = cp.first;
offset = cp.second;
selected.clear();
ud = true;
}
}
pass = true;
}
e_mutex.unlock();
if (ud) updateDir();
} break;
}
// piCout << is_right << remote_mode << pass;
if (is_right && remote_mode && pass) {
((void (*)(void *, PIKbdListener::KeyEvent))key_func)(fm, key);
return true;
}
return TileList::keyEvent(key);
}
void FileManager::TileDir::lock() {
if (screen && !resized) ((PIScreen *)screen)->lock();
}
void FileManager::TileDir::unlock() {
if (screen && !resized) ((PIScreen *)screen)->unlock();
}
void FileManager::TileDir::showReading() {
PIMutexLocker ml(e_mutex);
cur = -1;
offset = 0;
entries.clear();
content.resize(1);
content[0] = Row("... Reading ...", CellFormat());
}
void FileManager::TileDir::setContent(const PIVector<PIFile::FileInfo> & l) {
PIMutexLocker ml(e_mutex);
PIVector<PIFile::FileInfo> fl, dl;
entries.clear();
if (l.isEmpty()) {
PIFile::FileInfo fi;
fi.path = "..";
fi.flags |= PIFile::FileInfo::DotDot | PIFile::FileInfo::Dir;
entries << fi;
} else {
bool root = dir.path() == PIDir::separator;
for (int i = 0; i < l.size_s(); ++i) {
if (l[i].name() == ".") continue;
if (l[i].name() == "..") {
if (!root) dl.push_front(l[i]);
continue;
}
if (l[i].isDir())
dl << l[i];
else
fl << l[i];
}
entries << dl << fl;
}
}
void FileManager::TileDir::updateDir() {
lock();
int pc = cur, po = offset;
showReading();
unlock();
setContent(dir.entries());
if (label_path) {
label_path->content.resize(1);
label_path->content[0].first = dir.absolutePath();
}
cur = pc;
offset = po;
buildNames();
}
void FileManager::TileDir::buildNames() {
lock();
PIMutexLocker ml(e_mutex);
content.clear();
PIChar t;
CharFlags cf = 0;
Color cc = Default;
PIString fcol, scol;
piForeachC(PIFile::FileInfo & e, entries) {
if (e.isDir()) {
t = '/';
cf = Bold;
scol = " dir";
} else {
if (e.perm_user.exec || e.perm_group.exec || e.perm_other.exec) {
cf = Bold;
cc = Green;
t = '*';
} else {
t = ' ';
cc = Default;
cf = 0;
}
scol = PIString::readableSize(e.size);
}
if (e.isSymbolicLink() && (t != '*')) t = '~';
scol = scol.expandRightTo(9, ' ') + "| " + e.time_modification.toString("dd.MM hh:mm:ss") + " | " + e.perm_user.toString() + " " +
e.perm_group.toString() + " " + e.perm_other.toString();
fcol = t + e.name();
if (fcol.size_s() >= width_ - 2 - scol.size_s()) fcol = fcol.left(width_ - 5 - scol.size_s()) + "...";
fcol.expandRightTo(width_ - 1 - scol.size_s(), ' ');
content << Row(fcol + scol, CellFormat(cc, Transparent, cf));
}
unlock();
}
void FileManager::TileDir::sizeHint(int & w, int & h) const {
w = h = 4;
}
void FileManager::TileDir::resizeEvent(int w, int h) {
resized = true;
buildNames();
resized = false;
TileList::resizeEvent(w, h);
}
FileManager::FileManager() {
setName("FileManager");
TileSimple * tl;
tile_root = new PIScreenTile();
tile_root->direction = Vertical;
PIScreenTile * pt = new PIScreenTile();
pt->direction = Horizontal;
pt->spacing = 1;
pt->back_format.color_back = Cyan;
for (int i = 0; i < 2; ++i) {
PIScreenTile * panel = new PIScreenTile();
TileSimple * plabel = new TileSimple();
plabel->size_policy = Fixed;
plabel->maximumWidth = 1;
panel->direction = Vertical;
panels[i] = new TileDir();
panels[i]->fm = this;
panels[i]->key_func = (void *)tileKey_s;
panels[i]->setName("file panel " + PIString::fromNumber(i));
panels[i]->label_path = plabel;
CONNECTU(panels[i], actionRequest, this, actionRequest)
panel->addTile(plabel);
panel->addTile(panels[i]);
panels[i]->updateDir();
pt->addTile(panel);
}
panels[1]->is_right = true;
tile_root->addTile(pt);
PIScreenTile * labels = new PIScreenTile();
labels->size_policy = Fixed;
labels->direction = Horizontal;
PIVector<SSPair> ll;
ll << SSPair(" Esc", "Exit") << SSPair(" F5", "Copy") << SSPair(" F6", "Move") << SSPair(" F7", "MkDir") << SSPair(" F8", "Delete");
piForeachC(SSPair & l, ll) {
tl = new TileSimple();
labels->addTile(tl);
tl->content << TileSimple::Row(l.first, CellFormat(White, Transparent, Bold));
tl = new TileSimple();
labels->addTile(tl);
tl->content << TileSimple::Row(l.second, CellFormat(Black, Cyan));
}
tl = new TileSimple();
labels->addTile(tl);
tl->size_policy = Expanding;
tile_root->addTile(labels);
}
PIScreenTile * FileManager::tile() const {
return tile_root;
}
void FileManager::setLocal() {
if (panels[1]->remote_mode) setRemoteDir(panels[0]->dir.absolutePath());
panels[0]->remote_mode = panels[1]->remote_mode = false;
}
void FileManager::setRemote() {
panels[0]->remote_mode = panels[1]->remote_mode = true;
}
void FileManager::setRemoteDir(const PIString & d) {
panels[1]->dir.setDir(d);
if (panels[1]->label_path) {
panels[1]->label_path->content.resize(1);
panels[1]->label_path->content[0].first = panels[1]->dir.path();
}
}
void FileManager::setRemoteContent(const PIVector<PIFile::FileInfo> & el) {
panels[1]->setContent(el);
panels[1]->buildNames();
}
int FileManager::selectedPanel() const {
for (int i = 0; i < 2; i++)
if (panels[i]->hasFocus()) return i;
return -1;
}
PIStringList FileManager::selectedRemote() const {
PIStringList ret;
panels[1]->lock();
PIVector<int> sil = panels[1]->selected.toVector();
piForeachC(int i, sil)
ret << panels[1]->entries[i].path;
panels[1]->unlock();
return ret;
}
PIFile::FileInfo FileManager::currentRemoteEntry() const {
if ((panels[1]->cur < 0) || (panels[1]->cur >= panels[1]->content.size_s())) return PIFile::FileInfo();
return panels[1]->entries[panels[1]->cur];
}
void FileManager::remoteSaveDir() {
panels[1]->prev_pos[panels[1]->dir.path()] = PIPair<int, int>(panels[1]->cur, panels[1]->offset);
}
void FileManager::remoteRestoreDir() {
PIPair<int, int> cp = panels[1]->prev_pos.value(panels[1]->dir.path());
panels[1]->selected.clear();
panels[1]->cur = cp.first;
panels[1]->offset = cp.second;
if ((panels[1]->cur < 0) || (panels[1]->cur >= panels[1]->content.size_s())) panels[1]->cur = 0;
}

View File

@@ -1,74 +1,83 @@
#ifndef FILE_MANAGER_H
#define FILE_MANAGER_H
#include "piscreentiles.h"
#include "pidir.h"
class FileManager: public PIObject {
PIOBJECT(FileManager)
public:
FileManager();
PIScreenTile * tile() const;
PIScreenTile * localTile() const {return panels[0];}
PIScreenTile * remoteTile() const {return panels[1];}
enum Action {MkDir, Remove, Copy, Move, LocalCopy, Crypt, LocalCrypt};
void setLocal();
void setRemote();
void setRemoteDir(const PIString & d);
void setRemoteContent(const PIVector<PIFile::FileInfo> & el);
PIString remoteDir() const {return panels[1]->dir.absolutePath();}
PIString localDir() const {return panels[0]->dir.absolutePath();}
int selectedPanel() const;
PIStringList selectedRemote() const;
PIFile::FileInfo currentRemoteEntry() const;
PIFile::FileInfo selectedRemoteEntry(int index) const {return panels[1]->entries[index];}
void remoteSaveDir();
void remoteRestoreDir();
void readingRemote() const {panels[1]->showReading();}
void updateLocalDir() {panels[0]->updateDir();}
void updateRemoteDir() {panels[1]->updateDir();}
void clearSelectionLocal() {panels[0]->selected.clear();}
void clearSelectionRemote() {panels[1]->selected.clear();}
EVENT3(actionRequest, bool, remote_tile, FileManager::Action, type, PIVariant, data)
private:
class TileDir: public TileList {
PIOBJECT_SUBCLASS(TileDir, TileList)
public:
TileDir();
void updateDir();
void buildNames();
bool keyEvent(PIKbdListener::KeyEvent key) override;
void sizeHint(int & w, int & h) const override;
void resizeEvent(int w, int h) override;
void lock();
void unlock();
void showReading();
void setContent(const PIVector<PIFile::FileInfo> & l);
PIStringList selectedNames() const;
TileSimple * label_path;
PIVector<PIFile::FileInfo> entries;
PIDir dir;
PIMap<PIString, PIPair<int, int> > prev_pos;
mutable PIMutex e_mutex;
bool resized, is_right, remote_mode;
void * fm, * key_func;
EVENT3(actionRequest, bool, remote_tile, FileManager::Action, type, PIVariant, data)
};
EVENT1(tileKey, PIKbdListener::KeyEvent, key)
static void tileKey_s(void * fm, PIKbdListener::KeyEvent key) {((FileManager*)fm)->tileKey(key);}
TileDir * panels[2];
PIScreenTile * tile_root;
typedef PIPair<PIString, PIString> SSPair;
};
#endif // FILE_MANAGER_H
#ifndef FILE_MANAGER_H
#define FILE_MANAGER_H
#include "pidir.h"
#include "piscreentiles.h"
class FileManager: public PIObject {
PIOBJECT(FileManager)
public:
FileManager();
PIScreenTile * tile() const;
PIScreenTile * localTile() const { return panels[0]; }
PIScreenTile * remoteTile() const { return panels[1]; }
enum Action {
MkDir,
Remove,
Copy,
Move,
LocalCopy,
Crypt,
LocalCrypt
};
void setLocal();
void setRemote();
void setRemoteDir(const PIString & d);
void setRemoteContent(const PIVector<PIFile::FileInfo> & el);
PIString remoteDir() const { return panels[1]->dir.absolutePath(); }
PIString localDir() const { return panels[0]->dir.absolutePath(); }
int selectedPanel() const;
PIStringList selectedRemote() const;
PIFile::FileInfo currentRemoteEntry() const;
PIFile::FileInfo selectedRemoteEntry(int index) const { return panels[1]->entries[index]; }
void remoteSaveDir();
void remoteRestoreDir();
void readingRemote() const { panels[1]->showReading(); }
void updateLocalDir() { panels[0]->updateDir(); }
void updateRemoteDir() { panels[1]->updateDir(); }
void clearSelectionLocal() { panels[0]->selected.clear(); }
void clearSelectionRemote() { panels[1]->selected.clear(); }
EVENT3(actionRequest, bool, remote_tile, FileManager::Action, type, PIVariant, data)
private:
class TileDir: public TileList {
PIOBJECT_SUBCLASS(TileDir, TileList)
public:
TileDir();
void updateDir();
void buildNames();
bool keyEvent(PIKbdListener::KeyEvent key) override;
void sizeHint(int & w, int & h) const override;
void resizeEvent(int w, int h) override;
void lock();
void unlock();
void showReading();
void setContent(const PIVector<PIFile::FileInfo> & l);
PIStringList selectedNames() const;
TileSimple * label_path;
PIVector<PIFile::FileInfo> entries;
PIDir dir;
PIMap<PIString, PIPair<int, int>> prev_pos;
mutable PIMutex e_mutex;
bool resized, is_right, remote_mode;
void *fm, *key_func;
EVENT3(actionRequest, bool, remote_tile, FileManager::Action, type, PIVariant, data)
};
EVENT1(tileKey, PIKbdListener::KeyEvent, key)
static void tileKey_s(void * fm, PIKbdListener::KeyEvent key) { ((FileManager *)fm)->tileKey(key); }
TileDir * panels[2];
PIScreenTile * tile_root;
typedef PIPair<PIString, PIString> SSPair;
};
#endif // FILE_MANAGER_H

View File

@@ -1,414 +1,435 @@
/*
PIP - Platform Independent Primitives
PIP System Daemon
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "pisingleapplication.h"
#include "pisystemmonitor.h"
#include "pisysteminfo.h"
#include "piprocess.h"
#include "picli.h"
#include "file_manager.h"
#include "daemon.h"
#include "shared.h"
#include "piintrospection_server.h"
class _Init {
public:
_Init() {randomize();}
};
_Init _pisd_init;
PISystemMonitor sys_mon;
PIScreen * screen = 0;
class MainMenu: public PITimer {
PIOBJECT_SUBCLASS(MainMenu, PITimer)
public:
MainMenu(Daemon & d): daemon_(d) {
cur_peer = -1;
title = new TileSimple("title");
updateTitle(title);
title->back_format.color_back = Yellow;
title->size_policy = Fixed;
screen->rootTile()->addTile(title);
PIScreenTile * center = new PIScreenTile("center");
center->back_format.color_back = Cyan;
center->size_policy = Expanding;
center->setMargins(2, 2, 1, 1);
screen->rootTile()->addTile(center);
PIScreenTile * mt = tmenu = menuTile();
mt->show(); mt->name() = "main menu";
center->addTile(mt); mtiles << mt;
mt = tinfo = infoTile();
mt->hide(); mt->name() = "local info";
center->addTile(mt); mtiles << mt;
mt = tdaemon = daemon_.tile();
mt->hide(); mt->name() = "daemon";
center->addTile(mt); mtiles << mt;
mt = tpeer = peerTile();
mt->hide(); mt->name() = "peer info";
center->addTile(mt); mtiles << mt;
mt = tpeerdiag = peerDiagTile();
mt->hide(); mt->name() = "peer diag";
center->addTile(mt); mtiles << mt;
tpicout = new TilePICout();
tpicout->hide();
tpicout->size_policy = PIScreenTypes::Expanding;
screen->rootTile()->addTile(tpicout);
CONNECTU(screen, tileEvent, this, tileEvent)
CONNECTU(screen, keyPressed, this, keyEvent)
CONNECTU(&daemon_, menuRequest, this, menuRequest)
start(25);
}
PIScreenTile * menuTile() {
TileList * ret = new TileList();
ret->content << TileList::Row("Show local info", CellFormat());
ret->content << TileList::Row("Local file manager", CellFormat());
ret->content << TileList::Row("Connect to another daemon", CellFormat());
ret->content << TileList::Row("Peer info", CellFormat());
ret->content << TileList::Row("Peer reinit", CellFormat());
ret->content << TileList::Row("Peer diagnostics", CellFormat());
ret->content << TileList::Row("Peer change self name", CellFormat());
ret->content << TileList::Row("Exit", CellFormat());
ret->selection_mode = TileList::NoSelection;
return ret;
}
PIScreenTile * infoTile() {
TileList * ret = new TileList();
local_info_base << TileList::Row("Exec command: " + PISystemInfo::instance()->execCommand, CellFormat());
local_info_base << TileList::Row(" Executed on " + PISystemInfo::instance()->execDateTime.toString(), CellFormat());
local_info_base << TileList::Row(" Hostname: " + PISystemInfo::instance()->hostname, CellFormat());
local_info_base << TileList::Row(" Username: " + PISystemInfo::instance()->user, CellFormat());
local_info_base << TileList::Row(" OS name: " + PISystemInfo::instance()->OS_name, CellFormat());
local_info_base << TileList::Row(" OS version: " + PISystemInfo::instance()->OS_version, CellFormat());
local_info_base << TileList::Row("Architecture: " + PISystemInfo::instance()->architecture, CellFormat());
local_info_base << TileList::Row(" CPU count: " + PIString::fromNumber(PISystemInfo::instance()->processorsCount), CellFormat());
local_info_base << TileList::Row("", CellFormat());
return ret;
}
PIScreenTile * peerDiagTile() {
PIScreenTile * ret = new PIScreenTile();
TileSimple * htl = new TileSimple();
htl->size_policy = PIScreenTypes::Fixed;
ret->direction = PIScreenTypes::Vertical;
htl->content << TileSimple::Row("Peer: " + daemon_.name() + " | " + daemon_.selfInfo().name, CellFormat(PIScreenTypes::Default, PIScreenTypes::Default, PIScreenTypes::Bold));
PIScreenTile * diag = new PIScreenTile();
diag->direction = PIScreenTypes::Horizontal;
peerdiagdata_tl = new TileSimple();
peerdiagservice_tl = new TileSimple();
ret->addTile(htl);
ret->addTile(diag);
diag->addTile(peerdiagdata_tl);
diag->addTile(peerdiagservice_tl);
return ret;
}
PIScreenTile * peerTile() {
PIScreenTile* ret = new PIScreenTile();
ret->direction = PIScreenTypes::Vertical;
peerinfo_header = new TileSimple();
peerinfo_header->size_policy = PIScreenTypes::Fixed;
peerinfo_header->content << TileSimple::Row("Peer: " + daemon_.name() + " | " + daemon_.selfInfo().name, CellFormat(PIScreenTypes::Default, PIScreenTypes::Default, PIScreenTypes::Bold));
addrs_tl = new TileList();
peers_tl = new TileList();
peerinfo_tl = new TileSimple();
peermap_tl = new TileList();
peerinfo_tl->size_policy = PIScreenTypes::Fixed;
ret->addTile(peerinfo_header);
ret->addTile(peers_tl);
ret->addTile(peerinfo_tl);
ret->addTile(addrs_tl);
ret->addTile(peermap_tl);
return ret;
}
void updateTitle(TileSimple * tl) {
tl->content.clear();
tl->content << TileSimple::Row("pisd (PI System Daemon, PIP version " + PIPVersion() + ")", CellFormat(Black, Transparent));
tl->content << TileSimple::Row("This daemon: \"" + daemon_.thisDaemonName() + "\"", CellFormat(Black, Transparent));
}
void updatePeerDiag(TileSimple * tl, const PIDiagnostics & diag) {
tl->content.clear();
PIDiagnostics::State ds = diag.state();
tl->content << TileSimple::Row(diag.name() + " diagnostics", CellFormat(PIScreenTypes::Default, PIScreenTypes::Default, PIScreenTypes::Bold));
tl->content << TileSimple::Row("Received count: " + PIString::fromNumber(ds.received_packets), CellFormat());
tl->content << TileSimple::Row("Invalid count: " + PIString::fromNumber(ds.received_packets_wrong), CellFormat());
tl->content << TileSimple::Row("Sended count: " + PIString::fromNumber(ds.sended_packets), CellFormat());
tl->content << TileSimple::Row("Immediate Frequency, Hz: " + PIString::fromNumber(ds.immediate_freq), CellFormat());
tl->content << TileSimple::Row("Integral Frequency, Hz: " + PIString::fromNumber(ds.integral_freq), CellFormat());
tl->content << TileSimple::Row("Receive speed: " + ds.receive_speed, CellFormat());
tl->content << TileSimple::Row("Send speed: " + ds.send_speed, CellFormat());
tl->content << TileSimple::Row("Quality: " + PIString::fromNumber((int)ds.quality), CellFormat());
}
void updatePeerInfo() {
// bool pm = daemon_.lockedPeers();
screen->lock();
daemon_.lock();
peers_tl->content.clear();
addrs_tl->content.clear();
peerinfo_tl->content.clear();
peermap_tl->content.clear();
peers_tl->content << TileList::Row("this | 0 | 0 | " + PIString::fromNumber(daemon_.allPeers().size_s())
// + " [em = " + PIString::fromBool(daemon_.lockedEth()) + ", "
// "mm = " + PIString::fromBool(daemon_.lockedMBcasts()) + ", "
// "sm = " + PIString::fromBool(daemon_.lockedSends()) + ", "
// "ms = " + PIString::fromBool(daemon_.lockedMCSends()) + ", "
// "pm = " + PIString::fromBool(pm) + "]"
, CellFormat());
piForeachC(PIPeer::PeerInfo &p , daemon_.allPeers())
peers_tl->content << TileList::Row(p.name + " | d = " + PIString::fromNumber(p.dist) +
" | p = " + PIString::fromNumber(p.ping()) +
" | n = " + PIString::fromBool(p.isNeighbour())
, CellFormat());
PIPeer::PeerInfo pi = daemon_.selfInfo();
if (cur_peer >= 0 && cur_peer < daemon_.allPeers().size_s()) pi = daemon_.allPeers()[cur_peer];
peerinfo_tl->content << TileSimple::Row("Name: " + pi.name, CellFormat());
peerinfo_tl->content << TileSimple::Row("Addreses: " + PIString::fromNumber(pi.addresses.size()), CellFormat());
peerinfo_tl->content << TileSimple::Row("Neighbours: " + pi.neighbours.join(", "), CellFormat());
piForeachC(PIPeer::PeerInfo::PeerAddress &a , pi.addresses)
addrs_tl->content << TileList::Row(a.address.toString() +
" | p = " + PIString::fromNumber(a.ping) +
" | a = " + PIString::fromBool(a.isAvailable()), CellFormat());
PIStringList peermap;
for (auto p = daemon_._peerMap().begin(); p != daemon_._peerMap().end(); p++) {
PIString s = p.key() + " | ";
piForeachCR(PIPeer::PeerInfo * pp, p.value()) s += " -> " + pp->name;
peermap << s;
}
piForeachC(PIString &s , peermap)
peermap_tl->content << TileList::Row(s, CellFormat());
updatePeerDiag(peerdiagdata_tl, daemon_.diagnosticData());
updatePeerDiag(peerdiagservice_tl, daemon_.diagnosticService());
daemon_.unlock();
screen->unlock();
}
void updateSysMon() {
TileList * tile = (TileList*)tinfo;
PIVector<PISystemMonitor::ThreadStats> ts = sys_mon.threadsStatistic();
screen->lock();
tile->content = local_info_base;
int num = 0, maxlen = 0;
PIString line = "Process load: k ";
PIString ns = PIString::fromNumber(sys_mon.statistic().cpu_load_system, 'f', 2);
line += ns.expandLeftTo(5, ' ') + " %, u ";
ns = PIString::fromNumber(sys_mon.statistic().cpu_load_user, 'f', 2);
line += ns.expandLeftTo(5, ' ') + " %";
tile->content << TileList::Row("PID: " + PIString::fromNumber(sys_mon.statistic().ID), CellFormat());
tile->content << TileList::Row(line, CellFormat());
tile->content << TileList::Row("Threads:", CellFormat());
piForeachC (PISystemMonitor::ThreadStats & t, ts)
maxlen = piMaxi(maxlen, t.name.length());
piForeachC (PISystemMonitor::ThreadStats & t, ts) {
line = PIString::fromNumber(++num).expandLeftTo(2, ' ') + ": ";
line += PIString(t.name).expandRightTo(maxlen, ' ') + ": k ";
PIString ns = PIString::fromNumber(t.cpu_load_kernel, 'f', 2);
line += ns.expandLeftTo(5, ' ') + " %, u ";
ns = PIString::fromNumber(t.cpu_load_user, 'f', 2);
line += ns.expandLeftTo(5, ' ') + " %";
tile->content << TileList::Row(line, CellFormat());
}
screen->unlock();
}
void tick(void* data_, int delimiter) override {
if (tpeerdiag->visible || tpeer->visible)
updatePeerInfo();
if (tinfo->visible)
updateSysMon();
}
EVENT_HANDLER(void, menuRequest) {
piForeach (PIScreenTile * t, mtiles)
t->hide();
daemon_.disconnect();
tmenu->show();
tmenu->setFocus();
}
EVENT_HANDLER2(void, tileEvent, PIScreenTile *, t, PIScreenTypes::TileEvent, e) {
if (t == tmenu) {
if (e.type == TileList::RowPressed) {
piForeach (PIScreenTile * t, mtiles)
t->hide();
switch (e.data.toInt()) {
case 0: tinfo->show(); break;
case 1: daemon_.fm.setLocal(); daemon_.showLocalFilemanager(); tdaemon->show(); break;
case 2: daemon_.fm.setRemote(); daemon_.showMainList(); tdaemon->show(); break;
case 3: tpeer->show(); peers_tl->setFocus(); break;
case 4: daemon_.reinit(); tmenu->show(); break;
case 5: tpeerdiag->show(); break;
case 6:
{
PIString nn = askUserInput("Peer name:");
if (!nn.isEmpty()) {
daemon_.changeName(pisd_prefix + nn);
peerinfo_header->content.clear();
peerinfo_header->content << TileSimple::Row("Peer: " + daemon_.name() + " | " + daemon_.selfInfo().name, CellFormat(PIScreenTypes::Default, PIScreenTypes::Default, PIScreenTypes::Bold));
updateTitle(title);
}
menuRequest();
}
break;
case 7: PIKbdListener::exiting = true; break;
}
}
return;
}
if (t == peers_tl) {
if (e.type == TileList::RowPressed) {
cur_peer = e.data.toInt() - 1;
updatePeerInfo();
}
return;
}
}
EVENT_HANDLER1(void, keyEvent, PIKbdListener::KeyEvent, e) {
if (e.key == PIKbdListener::F9) {
tpicout->visible = !tpicout->visible;
return;
}
if (e.key == PIKbdListener::Esc && e.modifiers[PIKbdListener::Shift]) {
PIKbdListener::exiting = true;
return;
}
if (screen->dialogTile()) return;
if (tpeer->visible || tinfo->visible || tpeerdiag->visible)
if (e.key == PIKbdListener::Esc) menuRequest();
//piCout << "key" << e.key;
}
EVENT_HANDLER1(void, messageFromApp, PIByteArray, m) {
if (m[0] == 'k') PIKbdListener::exiting = true;
}
Daemon & daemon_;
PIScreenTile * tmenu, * tinfo, * tfm, * tdaemon, * tpeer, * tpeerdiag;
TileList * peers_tl, * addrs_tl, * peermap_tl;
TilePICout * tpicout;
TileSimple * title;
TileSimple * peerinfo_tl, * peerinfo_header;
TileSimple * peerdiagdata_tl, * peerdiagservice_tl;
PIVector<PIScreenTile * > mtiles;
PIDeque<TileList::Row> local_info_base;
int cur_peer;
};
void usage() {
piCout << PICoutManipulators::Bold << "PIP System Daemon";
piCout << PICoutManipulators::Cyan << "Version" << PICoutManipulators::Bold << PIPVersion() << PICoutManipulators::NewLine;
piCout << PICoutManipulators::Green << PICoutManipulators::Bold << "Usage:" << PICoutManipulators::Default
<< "\"pisd [-1hdfk] [-n <name>] [-a <ip>]\"" << PICoutManipulators::NewLine;
piCout << PICoutManipulators::Green << PICoutManipulators::Bold << "Details:";
piCout << "-h --help " << PICoutManipulators::Green << "- display this message and exit";
piCout << "-d --daemon " << PICoutManipulators::Green << "- start as daemon";
piCout << "-k --kill " << PICoutManipulators::Green << "- kill daemon";
piCout << "-f --force " << PICoutManipulators::Green << "- don`t check for another running instance";
piCout << "-n --name <name> " << PICoutManipulators::Green << "- set daemon name";
piCout << "-a --address <ip>" << PICoutManipulators::Green << "- connect to remote daemon via tcp";
piCout << "-s --silent " << PICoutManipulators::Green << "- run without user interfase";
}
int main(int argc, char * argv[]) {
sys_mon.startOnSelf();
//piDebug = false;
PICLI cli(argc, argv);
cli.addArgument("help");
cli.addArgument("daemon");
cli.addArgument("force");
cli.addArgument("kill");
cli.addArgument("1");
cli.addArgument("silent");
cli.addArgument("name", true);
cli.addArgument("address", true);
if (cli.hasArgument("help")) {
usage();
return 0;
}
PIString name = cli.argumentValue("name");
PIString sip = cli.argumentValue("address");
PISingleApplication * sapp = 0;
if ((cli.hasArgument("1") && !cli.hasArgument("force")) || cli.hasArgument("kill")) {
sapp = new PISingleApplication("pisd");
if (cli.hasArgument("1")) {
if (!sapp->isFirst()) {
piCout << "Another pisd is running, exit";
delete sapp;
return 0;
}
}
if (cli.hasArgument("kill")) {
sapp->sendMessage(PIByteArray("k", 1));
delete sapp;
return 0;
}
}
PIINTROSPECTION_START(pisd)
if (cli.hasArgument("daemon")) {
PIStringList args;
args << "-1" << "-s";
if (cli.hasArgument("force"))
args << "-f";
if (cli.hasArgument("address"))
args << "-a" << sip;
if (!name.isEmpty())
args << "-n" << name;
PIString exe;
#ifdef WINDOWS
exe = PISystemInfo::instance()->execCommand;
#else
exe = PIProcess::getEnvironmentVariable("_");
#endif
piCout << "start in background:" << exe;// << "; with args" << args;
PIProcess::execIndependent(exe, args);
return 0;
}
screen = new PIScreen(false);
screen->setMouseEnabled(true);
Daemon * daemon = new Daemon();
if (!sip.isEmpty()) daemon->setTcpServerIP(sip);
screen->enableExitCapture(PIKbdListener::F10);
if (!name.isEmpty())
daemon->changeName(pisd_prefix + name);
MainMenu * menu = new MainMenu(*daemon);
if (sapp) CONNECTU(sapp, messageReceived, menu, messageFromApp);
if (cli.hasArgument("silent")) {
PICout::setOutputDevices(PICout::StdOut);
PIKbdListener ls;
ls.enableExitCapture(PIKbdListener::F10);
ls.start();
WAIT_FOR_EXIT
ls.stop();
} else {
screen->start();
screen->waitForFinish();
screen->stop(true);
}
sys_mon.stop();
delete menu;
delete daemon;
delete screen;
if (sapp) delete sapp;
return 0;
}
/*
PIP - Platform Independent Primitives
PIP System Daemon
Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "daemon.h"
#include "file_manager.h"
#include "picli.h"
#include "piintrospection_server.h"
#include "piprocess.h"
#include "pisingleapplication.h"
#include "pisysteminfo.h"
#include "pisystemmonitor.h"
#include "shared.h"
class _Init {
public:
_Init() { randomize(); }
};
_Init _pisd_init;
PISystemMonitor sys_mon;
PIScreen * screen = 0;
class MainMenu: public PITimer {
PIOBJECT_SUBCLASS(MainMenu, PITimer)
public:
MainMenu(Daemon & d): daemon_(d) {
cur_peer = -1;
title = new TileSimple("title");
updateTitle(title);
title->back_format.color_back = Yellow;
title->size_policy = Fixed;
screen->rootTile()->addTile(title);
PIScreenTile * center = new PIScreenTile("center");
center->back_format.color_back = Cyan;
center->size_policy = Expanding;
center->setMargins(2, 2, 1, 1);
screen->rootTile()->addTile(center);
PIScreenTile * mt = tmenu = menuTile();
mt->show();
mt->name() = "main menu";
center->addTile(mt);
mtiles << mt;
mt = tinfo = infoTile();
mt->hide();
mt->name() = "local info";
center->addTile(mt);
mtiles << mt;
mt = tdaemon = daemon_.tile();
mt->hide();
mt->name() = "daemon";
center->addTile(mt);
mtiles << mt;
mt = tpeer = peerTile();
mt->hide();
mt->name() = "peer info";
center->addTile(mt);
mtiles << mt;
mt = tpeerdiag = peerDiagTile();
mt->hide();
mt->name() = "peer diag";
center->addTile(mt);
mtiles << mt;
tpicout = new TilePICout();
tpicout->hide();
tpicout->size_policy = PIScreenTypes::Expanding;
screen->rootTile()->addTile(tpicout);
CONNECTU(screen, tileEvent, this, tileEvent)
CONNECTU(screen, keyPressed, this, keyEvent)
CONNECTU(&daemon_, menuRequest, this, menuRequest)
start(25);
}
PIScreenTile * menuTile() {
TileList * ret = new TileList();
ret->content << TileList::Row("Show local info", CellFormat());
ret->content << TileList::Row("Local file manager", CellFormat());
ret->content << TileList::Row("Connect to another daemon", CellFormat());
ret->content << TileList::Row("Peer info", CellFormat());
ret->content << TileList::Row("Peer reinit", CellFormat());
ret->content << TileList::Row("Peer diagnostics", CellFormat());
ret->content << TileList::Row("Peer change self name", CellFormat());
ret->content << TileList::Row("Exit", CellFormat());
ret->selection_mode = TileList::NoSelection;
return ret;
}
PIScreenTile * infoTile() {
TileList * ret = new TileList();
local_info_base << TileList::Row("Exec command: " + PISystemInfo::instance()->execCommand, CellFormat());
local_info_base << TileList::Row(" Executed on " + PISystemInfo::instance()->execDateTime.toString(), CellFormat());
local_info_base << TileList::Row(" Hostname: " + PISystemInfo::instance()->hostname, CellFormat());
local_info_base << TileList::Row(" Username: " + PISystemInfo::instance()->user, CellFormat());
local_info_base << TileList::Row(" OS name: " + PISystemInfo::instance()->OS_name, CellFormat());
local_info_base << TileList::Row(" OS version: " + PISystemInfo::instance()->OS_version, CellFormat());
local_info_base << TileList::Row("Architecture: " + PISystemInfo::instance()->architecture, CellFormat());
local_info_base << TileList::Row(" CPU count: " + PIString::fromNumber(PISystemInfo::instance()->processorsCount), CellFormat());
local_info_base << TileList::Row("", CellFormat());
return ret;
}
PIScreenTile * peerDiagTile() {
PIScreenTile * ret = new PIScreenTile();
TileSimple * htl = new TileSimple();
htl->size_policy = PIScreenTypes::Fixed;
ret->direction = PIScreenTypes::Vertical;
htl->content << TileSimple::Row("Peer: " + daemon_.name() + " | " + daemon_.selfInfo().name,
CellFormat(PIScreenTypes::Default, PIScreenTypes::Default, PIScreenTypes::Bold));
PIScreenTile * diag = new PIScreenTile();
diag->direction = PIScreenTypes::Horizontal;
peerdiagdata_tl = new TileSimple();
peerdiagservice_tl = new TileSimple();
ret->addTile(htl);
ret->addTile(diag);
diag->addTile(peerdiagdata_tl);
diag->addTile(peerdiagservice_tl);
return ret;
}
PIScreenTile * peerTile() {
PIScreenTile * ret = new PIScreenTile();
ret->direction = PIScreenTypes::Vertical;
peerinfo_header = new TileSimple();
peerinfo_header->size_policy = PIScreenTypes::Fixed;
peerinfo_header->content << TileSimple::Row("Peer: " + daemon_.name() + " | " + daemon_.selfInfo().name,
CellFormat(PIScreenTypes::Default, PIScreenTypes::Default, PIScreenTypes::Bold));
addrs_tl = new TileList();
peers_tl = new TileList();
peerinfo_tl = new TileSimple();
peermap_tl = new TileList();
peerinfo_tl->size_policy = PIScreenTypes::Fixed;
ret->addTile(peerinfo_header);
ret->addTile(peers_tl);
ret->addTile(peerinfo_tl);
ret->addTile(addrs_tl);
ret->addTile(peermap_tl);
return ret;
}
void updateTitle(TileSimple * tl) {
tl->content.clear();
tl->content << TileSimple::Row("pisd (PI System Daemon, PIP version " + PIPVersion() + ")", CellFormat(Black, Transparent));
tl->content << TileSimple::Row("This daemon: \"" + daemon_.thisDaemonName() + "\"", CellFormat(Black, Transparent));
}
void updatePeerDiag(TileSimple * tl, const PIDiagnostics & diag) {
tl->content.clear();
PIDiagnostics::State ds = diag.state();
tl->content << TileSimple::Row(diag.name() + " diagnostics",
CellFormat(PIScreenTypes::Default, PIScreenTypes::Default, PIScreenTypes::Bold));
tl->content << TileSimple::Row("Received count: " + PIString::fromNumber(ds.received_packets), CellFormat());
tl->content << TileSimple::Row("Invalid count: " + PIString::fromNumber(ds.received_packets_wrong), CellFormat());
tl->content << TileSimple::Row("Sended count: " + PIString::fromNumber(ds.sended_packets), CellFormat());
tl->content << TileSimple::Row("Immediate Frequency, Hz: " + PIString::fromNumber(ds.immediate_freq), CellFormat());
tl->content << TileSimple::Row("Integral Frequency, Hz: " + PIString::fromNumber(ds.integral_freq), CellFormat());
tl->content << TileSimple::Row("Receive speed: " + ds.receive_speed, CellFormat());
tl->content << TileSimple::Row("Send speed: " + ds.send_speed, CellFormat());
tl->content << TileSimple::Row("Quality: " + PIString::fromNumber((int)ds.quality), CellFormat());
}
void updatePeerInfo() {
// bool pm = daemon_.lockedPeers();
screen->lock();
daemon_.lock();
peers_tl->content.clear();
addrs_tl->content.clear();
peerinfo_tl->content.clear();
peermap_tl->content.clear();
peers_tl->content << TileList::Row("this | 0 | 0 | " + PIString::fromNumber(daemon_.allPeers().size_s())
// + " [em = " + PIString::fromBool(daemon_.lockedEth()) + ",
//" "mm = " + PIString::fromBool(daemon_.lockedMBcasts()) + ", " "sm = " +
//PIString::fromBool(daemon_.lockedSends()) + ", " "ms = " +
//PIString::fromBool(daemon_.lockedMCSends()) + ", " "pm = " + PIString::fromBool(pm) + "]"
,
CellFormat());
piForeachC(PIPeer::PeerInfo & p, daemon_.allPeers())
peers_tl->content << TileList::Row(p.name + " | d = " + PIString::fromNumber(p.dist) + " | p = " +
PIString::fromNumber(p.ping()) + " | n = " + PIString::fromBool(p.isNeighbour()),
CellFormat());
PIPeer::PeerInfo pi = daemon_.selfInfo();
if (cur_peer >= 0 && cur_peer < daemon_.allPeers().size_s()) pi = daemon_.allPeers()[cur_peer];
peerinfo_tl->content << TileSimple::Row("Name: " + pi.name, CellFormat());
peerinfo_tl->content << TileSimple::Row("Addreses: " + PIString::fromNumber(pi.addresses.size()), CellFormat());
peerinfo_tl->content << TileSimple::Row("Neighbours: " + pi.neighbours.join(", "), CellFormat());
piForeachC(PIPeer::PeerInfo::PeerAddress & a, pi.addresses)
addrs_tl->content << TileList::Row(a.address.toString() + " | p = " + PIString::fromNumber(a.ping) +
" | a = " + PIString::fromBool(a.isAvailable()),
CellFormat());
PIStringList peermap;
for (auto p = daemon_._peerMap().begin(); p != daemon_._peerMap().end(); p++) {
PIString s = p.key() + " | ";
piForeachCR(PIPeer::PeerInfo * pp, p.value())
s += " -> " + pp->name;
peermap << s;
}
piForeachC(PIString & s, peermap)
peermap_tl->content << TileList::Row(s, CellFormat());
updatePeerDiag(peerdiagdata_tl, daemon_.diagnosticData());
updatePeerDiag(peerdiagservice_tl, daemon_.diagnosticService());
daemon_.unlock();
screen->unlock();
}
void updateSysMon() {
TileList * tile = (TileList *)tinfo;
PIVector<PISystemMonitor::ThreadStats> ts = sys_mon.threadsStatistic();
screen->lock();
tile->content = local_info_base;
int num = 0, maxlen = 0;
PIString line = "Process load: k ";
PIString ns = PIString::fromNumber(sys_mon.statistic().cpu_load_system, 'f', 2);
line += ns.expandLeftTo(5, ' ') + " %, u ";
ns = PIString::fromNumber(sys_mon.statistic().cpu_load_user, 'f', 2);
line += ns.expandLeftTo(5, ' ') + " %";
tile->content << TileList::Row("PID: " + PIString::fromNumber(sys_mon.statistic().ID), CellFormat());
tile->content << TileList::Row(line, CellFormat());
tile->content << TileList::Row("Threads:", CellFormat());
piForeachC(PISystemMonitor::ThreadStats & t, ts)
maxlen = piMaxi(maxlen, t.name.length());
piForeachC(PISystemMonitor::ThreadStats & t, ts) {
line = PIString::fromNumber(++num).expandLeftTo(2, ' ') + ": ";
line += PIString(t.name).expandRightTo(maxlen, ' ') + ": k ";
PIString ns = PIString::fromNumber(t.cpu_load_kernel, 'f', 2);
line += ns.expandLeftTo(5, ' ') + " %, u ";
ns = PIString::fromNumber(t.cpu_load_user, 'f', 2);
line += ns.expandLeftTo(5, ' ') + " %";
tile->content << TileList::Row(line, CellFormat());
}
screen->unlock();
}
void tick(void * data_, int delimiter) override {
if (tpeerdiag->visible || tpeer->visible) updatePeerInfo();
if (tinfo->visible) updateSysMon();
}
EVENT_HANDLER(void, menuRequest) {
piForeach(PIScreenTile * t, mtiles)
t->hide();
daemon_.disconnect();
tmenu->show();
tmenu->setFocus();
}
EVENT_HANDLER2(void, tileEvent, PIScreenTile *, t, PIScreenTypes::TileEvent, e) {
if (t == tmenu) {
if (e.type == TileList::RowPressed) {
piForeach(PIScreenTile * t, mtiles)
t->hide();
switch (e.data.toInt()) {
case 0: tinfo->show(); break;
case 1:
daemon_.fm.setLocal();
daemon_.showLocalFilemanager();
tdaemon->show();
break;
case 2:
daemon_.fm.setRemote();
daemon_.showMainList();
tdaemon->show();
break;
case 3:
tpeer->show();
peers_tl->setFocus();
break;
case 4:
daemon_.reinit();
tmenu->show();
break;
case 5: tpeerdiag->show(); break;
case 6: {
PIString nn = askUserInput("Peer name:");
if (!nn.isEmpty()) {
daemon_.changeName(pisd_prefix + nn);
peerinfo_header->content.clear();
peerinfo_header->content
<< TileSimple::Row("Peer: " + daemon_.name() + " | " + daemon_.selfInfo().name,
CellFormat(PIScreenTypes::Default, PIScreenTypes::Default, PIScreenTypes::Bold));
updateTitle(title);
}
menuRequest();
} break;
case 7: PIKbdListener::exiting = true; break;
}
}
return;
}
if (t == peers_tl) {
if (e.type == TileList::RowPressed) {
cur_peer = e.data.toInt() - 1;
updatePeerInfo();
}
return;
}
}
EVENT_HANDLER1(void, keyEvent, PIKbdListener::KeyEvent, e) {
if (e.key == PIKbdListener::F9) {
tpicout->visible = !tpicout->visible;
return;
}
if (e.key == PIKbdListener::Esc && e.modifiers[PIKbdListener::Shift]) {
PIKbdListener::exiting = true;
return;
}
if (screen->dialogTile()) return;
if (tpeer->visible || tinfo->visible || tpeerdiag->visible)
if (e.key == PIKbdListener::Esc) menuRequest();
// piCout << "key" << e.key;
}
EVENT_HANDLER1(void, messageFromApp, PIByteArray, m) {
if (m[0] == 'k') PIKbdListener::exiting = true;
}
Daemon & daemon_;
PIScreenTile *tmenu, *tinfo, *tfm, *tdaemon, *tpeer, *tpeerdiag;
TileList *peers_tl, *addrs_tl, *peermap_tl;
TilePICout * tpicout;
TileSimple * title;
TileSimple *peerinfo_tl, *peerinfo_header;
TileSimple *peerdiagdata_tl, *peerdiagservice_tl;
PIVector<PIScreenTile *> mtiles;
PIDeque<TileList::Row> local_info_base;
int cur_peer;
};
void usage() {
piCout << PICoutManipulators::Bold << "PIP System Daemon";
piCout << PICoutManipulators::Cyan << "Version" << PICoutManipulators::Bold << PIPVersion() << PICoutManipulators::NewLine;
piCout << PICoutManipulators::Green << PICoutManipulators::Bold << "Usage:" << PICoutManipulators::Default
<< "\"pisd [-1hdfk] [-n <name>] [-a <ip>]\"" << PICoutManipulators::NewLine;
piCout << PICoutManipulators::Green << PICoutManipulators::Bold << "Details:";
piCout << "-h --help " << PICoutManipulators::Green << "- display this message and exit";
piCout << "-d --daemon " << PICoutManipulators::Green << "- start as daemon";
piCout << "-k --kill " << PICoutManipulators::Green << "- kill daemon";
piCout << "-f --force " << PICoutManipulators::Green << "- don`t check for another running instance";
piCout << "-n --name <name> " << PICoutManipulators::Green << "- set daemon name";
piCout << "-a --address <ip>" << PICoutManipulators::Green << "- connect to remote daemon via tcp";
piCout << "-s --silent " << PICoutManipulators::Green << "- run without user interfase";
}
int main(int argc, char * argv[]) {
sys_mon.startOnSelf();
// piDebug = false;
PICLI cli(argc, argv);
cli.addArgument("help");
cli.addArgument("daemon");
cli.addArgument("force");
cli.addArgument("kill");
cli.addArgument("1");
cli.addArgument("silent");
cli.addArgument("name", true);
cli.addArgument("address", true);
if (cli.hasArgument("help")) {
usage();
return 0;
}
PIString name = cli.argumentValue("name");
PIString sip = cli.argumentValue("address");
PISingleApplication * sapp = 0;
if ((cli.hasArgument("1") && !cli.hasArgument("force")) || cli.hasArgument("kill")) {
sapp = new PISingleApplication("pisd");
if (cli.hasArgument("1")) {
if (!sapp->isFirst()) {
piCout << "Another pisd is running, exit";
delete sapp;
return 0;
}
}
if (cli.hasArgument("kill")) {
sapp->sendMessage(PIByteArray("k", 1));
delete sapp;
return 0;
}
}
PIINTROSPECTION_START(pisd)
if (cli.hasArgument("daemon")) {
PIStringList args;
args << "-1"
<< "-s";
if (cli.hasArgument("force")) args << "-f";
if (cli.hasArgument("address")) args << "-a" << sip;
if (!name.isEmpty()) args << "-n" << name;
PIString exe;
#ifdef WINDOWS
exe = PISystemInfo::instance()->execCommand;
#else
exe = PIProcess::getEnvironmentVariable("_");
#endif
piCout << "start in background:" << exe; // << "; with args" << args;
PIProcess::execIndependent(exe, args);
return 0;
}
screen = new PIScreen(false);
screen->setMouseEnabled(true);
Daemon * daemon = new Daemon();
if (!sip.isEmpty()) daemon->setTcpServerIP(sip);
screen->enableExitCapture(PIKbdListener::F10);
if (!name.isEmpty()) daemon->changeName(pisd_prefix + name);
MainMenu * menu = new MainMenu(*daemon);
if (sapp) CONNECTU(sapp, messageReceived, menu, messageFromApp);
if (cli.hasArgument("silent")) {
PICout::setOutputDevices(PICout::StdOut);
PIKbdListener ls;
ls.enableExitCapture(PIKbdListener::F10);
ls.start();
WAIT_FOR_EXIT
ls.stop();
} else {
screen->start();
screen->waitForFinish();
screen->stop(true);
}
sys_mon.stop();
delete menu;
delete daemon;
delete screen;
if (sapp) delete sapp;
return 0;
}

View File

@@ -1,176 +1,181 @@
#include "shared.h"
#include "picrypt.h"
extern PIScreen * screen;
class DlgWatcher: public PIThread {
PIOBJECT(DlgWatcher)
public:
DlgWatcher() {close = ok = false;}
EVENT_HANDLER2(void, tileEvent, PIScreenTile * , tile, PIScreenTypes::TileEvent, e) {
if (e.type == TileButtons::ButtonSelected) {
ok = e.data.toInt() == 0;
close = true;
}
}
EVENT_HANDLER1(void, keyPressed, PIKbdListener::KeyEvent, key) {
if (key.key == PIKbdListener::Return) {
ok = true;
close = true;
}
if (key.key == PIKbdListener::Esc) {
ok = false;
close = true;
}
}
bool ok;
bool close;
};
PIString readableTime(const PITime & t) {
PIString ret;
bool pt = false;
if (t.hours > 0) {ret += PIString::fromNumber(t.hours).expandLeftTo(2, '0') + " h "; pt = true;}
if ((t.minutes > 0) || pt) {ret += PIString::fromNumber(t.minutes).expandLeftTo(2, '0') + " m "; pt = true;}
if ((t.seconds > 0) || pt) ret += PIString::fromNumber(t.seconds).expandLeftTo(2, '0') + " s";
return ret;
}
PIString askUserInput(const PIString & desc) {
PIScreenTile dlg;
dlg.setMargins(1, 1, 1, 1);
dlg.spacing = 1;
dlg.back_format.color_back = Yellow;
TileSimple * lbl = new TileSimple();
TileInput * input = new TileInput();
TileButtons * btns = new TileButtons();
lbl->back_format.color_back = Yellow;
btns->back_format.color_back = Yellow;
lbl->content << TileSimple::Row(desc, CellFormat(Black, Transparent));
btns->content << TileButtons::Button(" Ok ", CellFormat());
btns->content << TileButtons::Button("Cancel", CellFormat());
dlg.addTile(lbl);
dlg.addTile(input);
dlg.addTile(btns);
DlgWatcher w;
CONNECTU(screen, keyPressed, &w, keyPressed)
CONNECTU(screen, tileEvent, &w, tileEvent)
screen->setDialogTile(&dlg);
while (!w.close) {
PIKbdListener::instance()->readKeyboard();
piMSleep(10);
}
if (!w.ok) return PIString();
return input->text;
}
bool askQuestion(const PIString & t) {
PIScreenTile dlg;
dlg.setMargins(1, 1, 1, 1);
dlg.spacing = 1;
dlg.back_format.color_back = Yellow;
TileSimple * lbl = new TileSimple();
TileButtons * btns = new TileButtons();
lbl->back_format.color_back = Yellow;
btns->back_format.color_back = Yellow;
lbl->content << TileSimple::Row(t, CellFormat(Black, Transparent));
btns->content << TileButtons::Button(" Ok ", CellFormat());
btns->content << TileButtons::Button("Cancel", CellFormat());
dlg.addTile(lbl);
dlg.addTile(btns);
DlgWatcher w;
CONNECTU(screen, keyPressed, &w, keyPressed)
CONNECTU(screen, tileEvent, &w, tileEvent)
screen->setDialogTile(&dlg);
while (!w.close) {
PIKbdListener::instance()->readKeyboard();
piMSleep(10);
}
return w.ok;
}
void showInfo(const PIString & t) {
PIScreenTile dlg;
dlg.setMargins(1, 1, 1, 1);
dlg.spacing = 1;
dlg.back_format.color_back = Yellow;
TileSimple * lbl = new TileSimple();
TileButtons * btns = new TileButtons();
lbl->back_format.color_back = Yellow;
btns->back_format.color_back = Yellow;
lbl->content << TileSimple::Row(t, CellFormat(Black, Transparent));
btns->content << TileButtons::Button(" Ok ", CellFormat());
dlg.addTile(lbl);
dlg.addTile(btns);
DlgWatcher w;
CONNECTU(screen, keyPressed, &w, keyPressed)
CONNECTU(screen, tileEvent, &w, tileEvent)
screen->setDialogTile(&dlg);
while (!w.close) {
PIKbdListener::instance()->readKeyboard();
piMSleep(10);
}
}
void removeFiles(const PIDir & dir, PIStringList l) {
l.removeAll("..");
PIString ap = dir.absolutePath();
//piCout << "remove from" << ap;
piForeachC (PIString & s, l) {
PIFile::FileInfo fi = PIFile::fileInfo(ap + PIDir::separator + s);
if (fi.isDir()) {
PIVector<PIFile::FileInfo> el = PIDir::allEntries(fi.path);
piForeachCR (PIFile::FileInfo & e, el) {
//piCout << "remove" << e.path;
PIFile::remove(e.path);
}
}
//piCout << "remove" << fi.path;
PIFile::remove(fi.path);
}
}
bool cryptFiles(const PIDir & dir, PIStringList l, const PIByteArray & secret) {
if (secret.size() != PICrypt::sizeKey() || secret.isEmpty()) return false;
l.removeAll("..");
PIString ap = dir.absolutePath();
piForeachC (PIString & s, l) {
PIFile::FileInfo fi = PIFile::fileInfo(ap + PIDir::separator + s);
if (fi.isDir()) {
PIVector<PIFile::FileInfo> el = PIDir::allEntries(fi.path);
piForeachCR (PIFile::FileInfo & e, el) {
if (e.size != 0)
cryptFile(e.path, secret);
}
}
if (fi.size != 0)
cryptFile(fi.path, secret);
}
return false;
}
bool cryptFile(const PIString & path, const PIByteArray & secret){
PIFile inf;
PIByteArray ba;
PICrypt crypt;
if (!crypt.setKey(secret)) return false;
if (!inf.open(path, PIIODevice::ReadOnly)) return false;
ba = inf.readAll();
ba = crypt.crypt(ba);
if (ba.isEmpty()) return false;
PIFile outf;
if (!outf.open(path + ".crypt", PIIODevice::ReadWrite)) return false;
outf.resize(0);
outf.write(ba);
outf.close();
return true;
}
#include "shared.h"
#include "picrypt.h"
extern PIScreen * screen;
class DlgWatcher: public PIThread {
PIOBJECT(DlgWatcher)
public:
DlgWatcher() { close = ok = false; }
EVENT_HANDLER2(void, tileEvent, PIScreenTile *, tile, PIScreenTypes::TileEvent, e) {
if (e.type == TileButtons::ButtonSelected) {
ok = e.data.toInt() == 0;
close = true;
}
}
EVENT_HANDLER1(void, keyPressed, PIKbdListener::KeyEvent, key) {
if (key.key == PIKbdListener::Return) {
ok = true;
close = true;
}
if (key.key == PIKbdListener::Esc) {
ok = false;
close = true;
}
}
bool ok;
bool close;
};
PIString readableTime(const PITime & t) {
PIString ret;
bool pt = false;
if (t.hours > 0) {
ret += PIString::fromNumber(t.hours).expandLeftTo(2, '0') + " h ";
pt = true;
}
if ((t.minutes > 0) || pt) {
ret += PIString::fromNumber(t.minutes).expandLeftTo(2, '0') + " m ";
pt = true;
}
if ((t.seconds > 0) || pt) ret += PIString::fromNumber(t.seconds).expandLeftTo(2, '0') + " s";
return ret;
}
PIString askUserInput(const PIString & desc) {
PIScreenTile dlg;
dlg.setMargins(1, 1, 1, 1);
dlg.spacing = 1;
dlg.back_format.color_back = Yellow;
TileSimple * lbl = new TileSimple();
TileInput * input = new TileInput();
TileButtons * btns = new TileButtons();
lbl->back_format.color_back = Yellow;
btns->back_format.color_back = Yellow;
lbl->content << TileSimple::Row(desc, CellFormat(Black, Transparent));
btns->content << TileButtons::Button(" Ok ", CellFormat());
btns->content << TileButtons::Button("Cancel", CellFormat());
dlg.addTile(lbl);
dlg.addTile(input);
dlg.addTile(btns);
DlgWatcher w;
CONNECTU(screen, keyPressed, &w, keyPressed)
CONNECTU(screen, tileEvent, &w, tileEvent)
screen->setDialogTile(&dlg);
while (!w.close) {
PIKbdListener::instance()->readKeyboard();
piMSleep(10);
}
if (!w.ok) return PIString();
return input->text;
}
bool askQuestion(const PIString & t) {
PIScreenTile dlg;
dlg.setMargins(1, 1, 1, 1);
dlg.spacing = 1;
dlg.back_format.color_back = Yellow;
TileSimple * lbl = new TileSimple();
TileButtons * btns = new TileButtons();
lbl->back_format.color_back = Yellow;
btns->back_format.color_back = Yellow;
lbl->content << TileSimple::Row(t, CellFormat(Black, Transparent));
btns->content << TileButtons::Button(" Ok ", CellFormat());
btns->content << TileButtons::Button("Cancel", CellFormat());
dlg.addTile(lbl);
dlg.addTile(btns);
DlgWatcher w;
CONNECTU(screen, keyPressed, &w, keyPressed)
CONNECTU(screen, tileEvent, &w, tileEvent)
screen->setDialogTile(&dlg);
while (!w.close) {
PIKbdListener::instance()->readKeyboard();
piMSleep(10);
}
return w.ok;
}
void showInfo(const PIString & t) {
PIScreenTile dlg;
dlg.setMargins(1, 1, 1, 1);
dlg.spacing = 1;
dlg.back_format.color_back = Yellow;
TileSimple * lbl = new TileSimple();
TileButtons * btns = new TileButtons();
lbl->back_format.color_back = Yellow;
btns->back_format.color_back = Yellow;
lbl->content << TileSimple::Row(t, CellFormat(Black, Transparent));
btns->content << TileButtons::Button(" Ok ", CellFormat());
dlg.addTile(lbl);
dlg.addTile(btns);
DlgWatcher w;
CONNECTU(screen, keyPressed, &w, keyPressed)
CONNECTU(screen, tileEvent, &w, tileEvent)
screen->setDialogTile(&dlg);
while (!w.close) {
PIKbdListener::instance()->readKeyboard();
piMSleep(10);
}
}
void removeFiles(const PIDir & dir, PIStringList l) {
l.removeAll("..");
PIString ap = dir.absolutePath();
// piCout << "remove from" << ap;
piForeachC(PIString & s, l) {
PIFile::FileInfo fi = PIFile::fileInfo(ap + PIDir::separator + s);
if (fi.isDir()) {
PIVector<PIFile::FileInfo> el = PIDir::allEntries(fi.path);
piForeachCR(PIFile::FileInfo & e, el) {
// piCout << "remove" << e.path;
PIFile::remove(e.path);
}
}
// piCout << "remove" << fi.path;
PIFile::remove(fi.path);
}
}
bool cryptFiles(const PIDir & dir, PIStringList l, const PIByteArray & secret) {
if (secret.size() != PICrypt::sizeKey() || secret.isEmpty()) return false;
l.removeAll("..");
PIString ap = dir.absolutePath();
piForeachC(PIString & s, l) {
PIFile::FileInfo fi = PIFile::fileInfo(ap + PIDir::separator + s);
if (fi.isDir()) {
PIVector<PIFile::FileInfo> el = PIDir::allEntries(fi.path);
piForeachCR(PIFile::FileInfo & e, el) {
if (e.size != 0) cryptFile(e.path, secret);
}
}
if (fi.size != 0) cryptFile(fi.path, secret);
}
return false;
}
bool cryptFile(const PIString & path, const PIByteArray & secret) {
PIFile inf;
PIByteArray ba;
PICrypt crypt;
if (!crypt.setKey(secret)) return false;
if (!inf.open(path, PIIODevice::ReadOnly)) return false;
ba = inf.readAll();
ba = crypt.crypt(ba);
if (ba.isEmpty()) return false;
PIFile outf;
if (!outf.open(path + ".crypt", PIIODevice::ReadWrite)) return false;
outf.resize(0);
outf.write(ba);
outf.close();
return true;
}

View File

@@ -1,21 +1,21 @@
#ifndef SHARED_H
#define SHARED_H
#include "pidir.h"
#include "piscreen.h"
#include "piscreentiles.h"
static const char pisd_prefix[] = "_pisd_";
using namespace PIScreenTypes;
PIString readableTime(const PITime & t);
PIString askUserInput(const PIString &desc);
bool askQuestion(const PIString & t);
void showInfo(const PIString & t);
void removeFiles(const PIDir & dir, PIStringList l);
bool cryptFiles(const PIDir & dir, PIStringList l, const PIByteArray & secret);
bool cryptFile(const PIString & path, const PIByteArray & secret);
#endif // SHARED_H
#ifndef SHARED_H
#define SHARED_H
#include "pidir.h"
#include "piscreen.h"
#include "piscreentiles.h"
static const char pisd_prefix[] = "_pisd_";
using namespace PIScreenTypes;
PIString readableTime(const PITime & t);
PIString askUserInput(const PIString & desc);
bool askQuestion(const PIString & t);
void showInfo(const PIString & t);
void removeFiles(const PIDir & dir, PIStringList l);
bool cryptFiles(const PIDir & dir, PIStringList l, const PIByteArray & secret);
bool cryptFile(const PIString & path, const PIByteArray & secret);
#endif // SHARED_H

View File

@@ -1,34 +1,35 @@
#include "terminal_tile.h"
#include "piscreendrawer.h"
TileTerminal::TileTerminal(const PIString & n): PIScreenTile(n) {
focus_flags = PIScreenTypes::CanHasFocus;
size_policy = PIScreenTypes::Expanding;
lastp[0] = lastp[1] = lastp[2] = 0;
}
void TileTerminal::drawEvent(PIScreenDrawer * d) {
//piCout << "draw" << visible;
d->fillRect(x_, y_, x_ + width_, y_ + height_, cells);
}
bool TileTerminal::keyEvent(PIKbdListener::KeyEvent key) {
lastp[0] = lastp[1];
lastp[1] = lastp[2];
lastp[2] = char(key.key);
if (lastp[0] == '\e' && lastp[1] == '~' && lastp[2] == '.') {
closeRequest();
return true;
}
//piCout << "key";
keyPressed(key);
return true;
}
void TileTerminal::resizeEvent(int w, int h) {
resizeRequest();
}
#include "terminal_tile.h"
#include "piscreendrawer.h"
TileTerminal::TileTerminal(const PIString & n): PIScreenTile(n) {
focus_flags = PIScreenTypes::CanHasFocus;
size_policy = PIScreenTypes::Expanding;
lastp[0] = lastp[1] = lastp[2] = 0;
}
void TileTerminal::drawEvent(PIScreenDrawer * d) {
// piCout << "draw" << visible;
d->fillRect(x_, y_, x_ + width_, y_ + height_, cells);
}
bool TileTerminal::keyEvent(PIKbdListener::KeyEvent key) {
lastp[0] = lastp[1];
lastp[1] = lastp[2];
lastp[2] = char(key.key);
if (lastp[0] == '\e' && lastp[1] == '~' && lastp[2] == '.') {
closeRequest();
return true;
}
// piCout << "key";
keyPressed(key);
return true;
}
void TileTerminal::resizeEvent(int w, int h) {
resizeRequest();
}

View File

@@ -1,30 +1,30 @@
#ifndef TERMINAL_TILE_H
#define TERMINAL_TILE_H
#include "piscreentile.h"
#include "pikbdlistener.h"
class TileTerminal: public PIScreenTile {
PIOBJECT_SUBCLASS(TileTerminal, PIScreenTile)
public:
TileTerminal(const PIString & n);
void setContent(const PIVector<PIVector<PIScreenTypes::Cell> > & c) {cells = c;}
EVENT(resizeRequest)
EVENT1(keyPressed, PIKbdListener::KeyEvent, k)
EVENT(closeRequest)
private:
void drawEvent(PIScreenDrawer * d) override;
bool keyEvent(PIKbdListener::KeyEvent key) override;
void resizeEvent(int w, int h) override;
PIVector<PIVector<PIScreenTypes::Cell> > cells;
char lastp[3];
};
#endif // TERMINAL_TILE_H
#ifndef TERMINAL_TILE_H
#define TERMINAL_TILE_H
#include "pikbdlistener.h"
#include "piscreentile.h"
class TileTerminal: public PIScreenTile {
PIOBJECT_SUBCLASS(TileTerminal, PIScreenTile)
public:
TileTerminal(const PIString & n);
void setContent(const PIVector<PIVector<PIScreenTypes::Cell>> & c) { cells = c; }
EVENT(resizeRequest)
EVENT1(keyPressed, PIKbdListener::KeyEvent, k)
EVENT(closeRequest)
private:
void drawEvent(PIScreenDrawer * d) override;
bool keyEvent(PIKbdListener::KeyEvent key) override;
void resizeEvent(int w, int h) override;
PIVector<PIVector<PIScreenTypes::Cell>> cells;
char lastp[3];
};
#endif // TERMINAL_TILE_H