1 /**************************************************************
3 Copyright (C) 1997 Oskar Swida
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License
7 as published by the Free Software Foundation; either version 2
8 of the License, or (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 NOTE: This software is using the free software license of
23 the QT library v.1.30 from Troll Tech AS.
24 See the file LICENSE.QT.
27 To contact the author, write:
28 e-mail: swida@aragorn.pb.bialystok.pl
30 ************************************************************/
32 #include <QtGui/QApplication>
33 #include <QtGui/QMainWindow>
34 #include <QtGui/QTextEdit>
35 #include <QtGui/QMenuBar>
36 #include <QtGui/QMessageBox>
37 #include <QtGui/QFileDialog>
38 #include <QtGui/QDialog>
39 #include <QtCore/QString>
40 #include <QtGui/QLabel>
41 #include <QtGui/QLineEdit>
42 #include <QtGui/QPushButton>
43 #include <QtGui/QRadioButton>
44 #include <QtGui/QGroupBox>
45 #include <QtGui/QVBoxLayout>
46 #include <QtCore/QList>
47 #include <QtGui/QListWidget>
50 #include <QtCore/QSocketNotifier>
51 #include <QtGui/QCloseEvent>
52 #include <QtCore/QDir>
53 #include <QtCore/QProcess>
62 #include <netinet/in.h>
64 #include <libconfig.h>
68 #include "ui/KernelWindow.h"
69 #include "ConnectDialog.h"
70 #include "KillDialog.h"
71 #include "LockDialog.h"
72 #include "OptionsDialog.h"
73 #include "MessageDialog.h"
75 #include "vlp/config.h"
77 #include <sys/prctl.h>
78 /* File resides in top directory (where are Makefiles)*/
79 #include "../../config.h"
85 char CharLine[25] = "________________________";
88 * Event invoked on program close.
89 * Closes application. Displays additional window to confirm exit.
91 void QKernel::closeEvent(QCloseEvent * e)
96 on_actionQuit_triggered();
100 void QKernel::setLocked(bool locked)
104 actionQuit->setDisabled(locked);
106 actionExecute->setDisabled(locked);
107 actionKill->setDisabled(locked);
108 actionMessage->setDisabled(locked);
109 actionConnect->setDisabled(locked);
110 actionDisconnect->setDisabled(locked);
111 actionInfo->setDisabled(locked);
114 /* Enable only menu entry for unlocking */
115 actionEditor->setDisabled(locked);
116 actionOptions->setDisabled(locked);
117 actionLock_console->setDisabled(locked);
118 actionUnlock_console->setDisabled(!locked);
122 * Kernel program constructor.
123 * Prepares everything to work.
125 QKernel::QKernel(int argc, char **argv)
129 QString arg0(argv[0]);
131 homeDir = QDir(arg0);
136 for(i = 0; (i < 5) && (i < argc-1); i++) {
137 strcpy(myargs[i], "");
139 strcpy(myargs[i], argv[i+1]);
143 QDir q(getRemoteDir());
146 q.mkpath(getRemoteDir());
149 info_messages = actionInfo_messages->isChecked();
150 wait_for_info = FALSE;
152 setWindowTitle(PACKAGE_NAME);
158 ActiveConnections = 0;
159 strcpy(LockPasswd, "");
161 loadConfig(getConfigFilePath());
165 Net_Notify = new QSocketNotifier(net_sock, QSocketNotifier::Read, this);
166 connect(Net_Notify, SIGNAL(activated(int)), this, SLOT(NetMessage()));
168 WriteMessage("\n " PACKAGE_STRING ": READY \n");
171 QString QKernel::getConfigFilePath()
173 return homeDir.absoluteFilePath("vlp.cfg");
176 const char * QKernel::getHomeDir()
178 return homeDir.absolutePath().toStdString().c_str();
181 const char * QKernel::getRemoteDir()
183 return homeDir.absoluteFilePath(REMOTE_PATH).toStdString().c_str();
186 const char * QKernel::getNetModuleSocket()
188 return homeDir.absoluteFilePath(NPATH).toStdString().c_str();
191 const char * QKernel::getGraphModuleSocket()
193 return homeDir.absoluteFilePath(GPATH).toStdString().c_str();
196 void QKernel::loadConfig(const QString & fname)
198 loadConfig(fname.toStdString().c_str());
201 * Loads configuration from the given file.
202 * @param fname Filename of the configuration file.
204 void QKernel::loadConfig(const char * fname)
206 loglan::vlp::Config config;
207 if(config.load(fname)) {
208 NodeNumber = config.getNodeNumber();
209 ConType = config.getConnectionType();
212 std::vector<std::string> hosts = config.getHosts();
213 for (unsigned int i = 0; i < hosts.size(); i++) {
214 ConnectList.append(new ConnectEntry(hosts[i].c_str()));
217 strncpy(progdir, config.getProgramDir(), 256);
223 * Additional window id displayed to set which code to execute.
225 void QKernel::on_actionExecute_triggered()
227 QString s = QFileDialog::getOpenFileName(this, "Execute", progdir, "*.log");
230 int i = s.indexOf(".log");
235 // @TODO: if no interpreter is running will result in killing app
236 RunIntModule((char*)s.toAscii().data(), 0);
241 * Invokes editor program
243 void QKernel::on_actionEditor_triggered()
245 QString program = getHomeDir();
246 program += "/modules/logedit";
248 fprintf(stderr, "Run EDIT Module: %s, %s\n", program.toStdString().c_str(), getHomeDir());
251 if (execl(program.toStdString().c_str(),
260 WriteMessage("Executing logedit failed!");
264 WriteMessage("fork(logedit) failed!");
265 WriteMessage("Exiting...");
267 on_actionQuit_triggered();
273 * Invokes help program
275 void QKernel::on_actionHelp_triggered()
277 QString program = getHomeDir();
278 program += "/modules/loghelp";
280 QString docDir = getHomeDir();
283 fprintf(stderr, "Run HELP Module: %s, %s\n", program.toStdString().c_str(), docDir.toStdString().c_str());
287 if (execl(program.toStdString().c_str(),
288 docDir.toStdString().c_str(),
297 WriteMessage("Executing loghelp failed!");
301 WriteMessage("fork(loghelp) failed!");
302 WriteMessage("Exiting...");
304 on_actionQuit_triggered();
310 * Invokes graphics module
312 void QKernel::RunGraphModule(char *sk)
314 QString program = getHomeDir();
315 program += "/modules/loggraph";
317 fprintf(stderr, "Run GRAPH Module: %s, %s\n", program.toStdString().c_str(), sk);
321 if (execl(program.toStdString().c_str(),
322 program.toStdString().c_str(),
332 WriteMessage("Executing loggraph failed!");
333 WriteMessage("Exiting...");
335 on_actionQuit_triggered();
339 WriteMessage("fork(loggraph) failed!");
340 WriteMessage("Exiting...");
342 on_actionQuit_triggered();
350 void QKernel::RunNetModule()
353 struct sockaddr_un svr;
358 QString program = getHomeDir();
359 program += "/modules/lognet";
361 fprintf(stderr, "Run NET Module: %s, %s %s\n", program.toStdString().c_str(), getNetModuleSocket(), getConfigFilePath().toStdString().c_str());
364 if (execl(program.toStdString().c_str(),
365 program.toStdString().c_str(),
366 getNetModuleSocket(),
367 getConfigFilePath().toStdString().c_str(),
376 WriteMessage("Executing lognet failed!");
377 WriteMessage("Exiting...");
379 on_actionQuit_triggered();
383 WriteMessage("fork(lognet) failed!");
384 WriteMessage("Exiting...");
386 on_actionQuit_triggered();
390 /* -------- socket for NET module -------- */
391 unlink(getNetModuleSocket());
392 sock = socket(AF_UNIX, SOCK_STREAM, 0);
393 bzero(&svr, sizeof(svr));
394 svr.sun_family = AF_UNIX;
395 strcpy(svr.sun_path, getNetModuleSocket());
396 len = strlen(svr.sun_path) + sizeof(svr.sun_family);
397 bind(sock, (struct sockaddr*)&svr, len);
400 net_sock = accept(sock, (struct sockaddr*)0, (unsigned int*)0);
403 WriteMessage("NETWORK successfully connected");
404 fcntl(net_sock, F_SETFL, O_NONBLOCK|fcntl(net_sock, F_GETFL, 0));
406 setsockopt(net_sock, IPPROTO_TCP, TCP_NODELAY, (char*)&on, sizeof(on));
408 WriteMessage("Cannot connect NETWORK resources");
409 WriteMessage("Exiting...");
411 on_actionQuit_triggered();
416 * Connects to the specified address
417 * Additional window is displayed to connect to the specified address
419 void QKernel::on_actionConnect_triggered()
423 dialog::ConnectDialog dialog(this);
426 m.msg_type = MSG_NET;
427 m.param.pword[0] = NET_CONNECT_TO;
428 strcpy(m.param.pstr, dialog.getAddress().toStdString().c_str());
429 write(net_sock, &m, sizeof(MESSAGE));
434 * Disconnects from virtual machine
436 void QKernel::on_actionDisconnect_triggered()
441 WriteMessage("Disconnecting from virtual machine");
443 msg.msg_type = MSG_NET;
444 msg.param.pword[0] = NET_DISCONNECT;
445 write(net_sock, &msg, sizeof(MESSAGE));
449 * Quits process. Closes VLP. Shows additional window to confirm exit.
451 void QKernel::on_actionQuit_triggered()
455 QMessageBox::StandardButton response = QMessageBox::question(this,
458 QMessageBox::Ok | QMessageBox::Cancel
462 if (response == QMessageBox::Cancel) {
466 msg.msg_type = MSG_NET;
467 msg.param.pword[0] = NET_DISCONNECT;
468 write(net_sock, &msg, sizeof(MESSAGE));*/
471 msg.msg_type = MSG_NET;
472 msg.param.pword[0] = NET_EXIT;
473 write(net_sock, &msg, sizeof(MESSAGE));
474 /* ::close(net_sock);*/
475 QApplication::instance()->quit();
479 * Sends message to node.
480 * Additional window is displayed to set Node Number of node where send message,
481 * and textfield to enter message.
483 void QKernel::on_actionMessage_triggered()
485 dialog::MessageDialog dialog(this);
489 m.msg_type = MSG_NET;
490 m.param.pword[0] = NET_PROPAGATE;
491 m.param.pword[1] = MSG_VLP;
492 m.param.pword[2] = NodeNumber;
493 m.param.pword[4] = dialog.getNodeNumber();
494 m.param.pword[6] = VLP_WRITE;
495 strcpy(m.param.pstr, dialog.getMessage().toStdString().c_str());
496 write(net_sock, &m, sizeof(MESSAGE));
502 * Additional window is displayed to get ID of interpreter which should be
505 void QKernel::on_actionKill_triggered()
507 dialog::KillInterpreterDialog dialog(this);
511 m.msg_type = MSG_INT;
512 m.param.pword[0] = INT_KILL;
514 InterpEntry *interpreter;
515 interpreter = findINTbyID(dialog.getInterpreterId());
517 if (interpreter != NULL) {
518 if (!(interpreter->remote)) {
519 write(interpreter->sock, &m, sizeof(MESSAGE));
522 WriteMessage("This is a remote instance of a program!");
526 WriteMessage("Interpreter not found");
532 * Sends message to the net module.
534 * \todo method needs to be refactored
536 void QKernel::NetMessage()
539 /* TODO: It has to be rewritten */
544 cnt = read(net_sock, &msg, sizeof(MESSAGE));
545 if ((cnt > 0) && (msg.msg_type == MSG_NET)) {
548 switch(msg.param.pword[0]) {
550 WriteMessage(msg.param.pstr);
553 switch(msg.param.pword[1]) {
555 /* pom = find_link_by_ID(msg.param.pword[5]);
556 msg.msg_type = MSG_NET;
557 msg.param.pword[0] = NET_PROPAGATE;
558 send_int(pom, &msg);*/
561 switch(msg.param.pword[6]) {
563 QApplication::beep();
564 WriteMessage(CharLine);
565 WriteMessage("### Incoming Messsage ###");
567 "Mesg from Node %d: %s",
572 WriteMessage(CharLine);
574 case VLP_REMOTE_INSTANCE:
575 sprintf(ss, "%s/%s", getRemoteDir(), msg.param.pstr);
578 WriteMessage("Running program:");
581 pom = RunIntModule(ss, 1);
583 pom->p_ctx.node = msg.param.pword[2];
584 pom->p_ctx.program_id =
586 pom->RInstances[msg.param.pword[2]] = msg.param.pword[7];
589 case VLP_CLOSE_INSTANCE:
590 msg.msg_type = MSG_INT;
591 msg.param.pword[0] = INT_CLOSE_INSTANCE;
592 pom = findINTbyID(msg.param.pword[7]);
594 write(pom->sock, &msg,
597 m1.msg_type = MSG_VLP;
598 m1.param.pword[0] = VLP_INTERPRETER_DOWN;
599 m1.param.pword[1] = pom->ID;
603 WriteMessage("Instance not found");
609 case NET_CONNECTIONS:
610 ActiveConnections = msg.param.pword[1];
611 WriteMessage(msg.param.pstr);
616 /* TODO: It has to be rewritten */
618 QString poms, poms1, poms2;
619 poms.sprintf("%s", msg.param.pstr);
620 while (poms.length() > 0) {
621 cnt = poms.indexOf(';');
623 poms1 = poms.left(cnt);
624 poms = poms.right(poms.length() - cnt - 1);
625 cnt = poms1.indexOf('=');
627 poms2 = poms1.left(cnt);
628 poms1 = poms1.right(poms1.length() - cnt - 1);
629 sprintf(ss, "Node: %s Addr: %s", poms2.toStdString().c_str(), poms1.toStdString().c_str());
637 wait_for_info = FALSE;
638 WriteMessage(CharLine);
645 * Sends message to the interpreter program.
646 * @param sock Interpreter socket to whom the message will be send.
648 void QKernel::IntMessage(int sock)
654 cnt = read(sock, &msg, sizeof(MESSAGE));
655 e = findINTbySocket(sock);
656 if ((cnt > 0) && (e != NULL)) {
657 switch (msg.msg_type) {
659 if (msg.param.pword[0] == GRAPH_ALLOCATE) {
660 fprintf(stderr, "Running graph module with arg: %s\n", msg.param.pstr);
661 RunGraphModule(msg.param.pstr);
665 write(net_sock, &msg, sizeof(MESSAGE));
668 switch(msg.param.pword[0]) {
669 case VLP_REMOTE_INSTANCE_PLEASE:
670 RemoteInstance(e, msg.param.pword[2]);
675 switch(msg.param.pword[0]) {
680 m.msg_type = MSG_VLP;
681 m.param.pword[0] = VLP_INTERPRETER_DOWN;
682 m.param.pword[1] = e->ID;
683 write(net_sock, &m, sizeof(MESSAGE));
688 /* TODO: Check this */
689 Interpreters.removeOne(e);
693 sprintf(ss, "%s : End of program "
694 "execution", msg.param.pstr);
699 msg.msg_type = MSG_INT;
700 msg.param.pword[0] = INT_CTX;
701 msg.param.pword[1] = NodeNumber;
702 msg.param.pword[2] = e->ID;
704 msg.param.pword[3] = e->p_ctx.node;
708 write(sock, &msg, sizeof(MESSAGE));
717 * Writes message to kernel logger.
718 * @parame msg String with message to log
720 void QKernel::WriteMessage(const char *msg)
724 x = desktop->textCursor().blockNumber();
725 // y = desktop->textCursor().columnNumber();
731 desktop->setReadOnly(FALSE);
732 desktop->append(msg);
733 desktop->setReadOnly(TRUE);
735 QTextCursor tmpCursor = desktop->textCursor();
736 tmpCursor.movePosition(QTextCursor::End, QTextCursor::MoveAnchor);
737 desktop->setTextCursor(tmpCursor);
741 if (desktop->document()->blockCount() > 100) {
747 * Adds checkbox to menu item. If it is checked additional info messages are
750 void QKernel::on_actionInfo_messages_triggered()
752 if (toolsMenu != NULL) {
753 info_messages = actionInfo_messages->isChecked();
754 actionInfo_messages->setChecked(info_messages);
759 * Allows to set options in GUI window.
760 * Additional window is displayed to set kernel options which are saved in
761 * vlp.cfg file in kernel executable directory.
763 void QKernel::on_actionOptions_triggered()
765 dialog::OptionsDialog optionsDialog(getConfigFilePath(), this);
766 if (optionsDialog.exec()) {
767 optionsDialog.saveConfig(getConfigFilePath());
769 loadConfig(getConfigFilePath());
774 * Locks kernel program.
775 * Additional window is displayed to enter password and retype it. If both are
776 * same kernel window is locked.
778 void QKernel::on_actionLock_console_triggered()
780 dialog::LockDialog lockDialog(this);
782 if (lockDialog.exec()) {
783 QString password = lockDialog.getPassword();
784 if (lockDialog.getPassword().size() > 0) {
785 strcpy(LockPasswd, password.toStdString().c_str());
788 if (lockDialog.exec()) {
789 password = lockDialog.getPassword();
790 if (password == LockPasswd) {
792 WriteMessage("CONSOLE LOCKED");
794 QMessageBox msg(this);
795 msg.setText("Not matching!");
796 msg.setButtonText(0, "Close");
798 strcpy(LockPasswd, "");
801 strcpy(LockPasswd, "");
808 * Unlocks kernel program.
809 * Additional window is displayed to enter password. If it is correct, kernel
812 void QKernel::on_actionUnlock_console_triggered()
814 dialog::LockDialog lockDialog(this);
816 if (lockDialog.exec()) {
817 QString password = lockDialog.getPassword();
818 if (strcmp(password.toStdString().c_str(), LockPasswd) == 0) {
820 WriteMessage("CONSOLE UNLOCKED");
822 QMessageBox msg(this);
823 msg.setText("Wrong password!");
824 msg.setButtonText(0, "Close");
831 * Finds Interpreter by its socket
832 * @param _id ID of the socket
833 * @return returns pointer to the found interpreter slot. NULL otherwise
835 InterpEntry *QKernel::findINTbySocket(int _id)
837 InterpEntry *pom = NULL;
839 for (auto interpreter : Interpreters) {
840 if (interpreter->sock == _id) {
850 * Finds Interpreter by its ID.
851 * @param _id ID of the interpreter
852 * @return returns pointer to the found interpreter slot. NULL otherwise
854 InterpEntry *QKernel::findINTbyID(int _id)
856 InterpEntry *pom = NULL;
858 for (auto interpreter : Interpreters) {
859 if (interpreter->ID == _id) {
870 * Connects interpreter
871 * @param ss full filepath with filename but without extension of the loglan
873 * @param r Interpreter execution mode. 0 if it will be local instance, 1 if
875 * @return Returns pointer to newly created interpreter slot, or NULL on error.
877 InterpEntry *QKernel::RunIntModule(char *ss, int r)
879 fprintf(stderr, "Run INT Module: %s, %d\n", ss, r);
881 struct sockaddr_un svr;
888 InterpEntry *newINT = NULL;
894 WriteMessage("File not found: no .ccd file");
903 WriteMessage("File not found: no .pcd file");
908 newINT = new InterpEntry;
909 for(i = 0; i < MAXINSTANCES; i++)
910 newINT->RInstances[i] =- 1;
912 strcpy(b, rindex(ss, '/'));
913 for(i = 0; i < strlen(b); i++)
916 sprintf(a, "%s : Start execution", b);
923 strcpy(newINT->shortname, b);
924 strcpy(newINT->fullname, ss);
926 sprintf(a, "%s%d", IPATH, newint);
927 sprintf(cmd, "%s/modules/logint %s %s",
934 sprintf(b, " %s %s %s %s %s",
935 myargs[0], myargs[1], myargs[2], myargs[3], myargs[4]);
939 sock = socket(AF_UNIX, SOCK_STREAM, 0);
941 bzero(&svr, sizeof(svr));
942 svr.sun_family = AF_UNIX;
943 strcpy(svr.sun_path, a);
944 len = strlen(svr.sun_path)+sizeof(svr.sun_family);
945 bind(sock, (struct sockaddr*)&svr, len);
948 newINT->sock = accept(sock, (struct sockaddr*)0, (unsigned int *)0);
951 if (newINT->sock > 0) {
952 fcntl(newINT->sock, F_SETFL,
953 O_NONBLOCK|fcntl(newINT->sock, F_GETFL, 0));
955 setsockopt(newINT->sock, IPPROTO_TCP, TCP_NODELAY, (char*)&on,
962 bzero(&msg, sizeof(MESSAGE));
963 msg.msg_type = MSG_VLP;
964 msg.param.pword[0] = VLP_REGINT;
965 msg.param.pword[1] = newINT->ID;
966 sprintf(msg.param.pstr, "logi%d.net", newint);
967 write(net_sock, &msg, sizeof(MESSAGE));
969 Interpreters.append(newINT);
970 newINT->notify = new QSocketNotifier(newINT->sock,
971 QSocketNotifier::Read);
972 connect(newINT->notify, SIGNAL(activated(int)), this,
973 SLOT(IntMessage(int)));
975 WriteMessage("INTERPRETER successfully connected");
977 WriteMessage("Cannot connect interpreter");
984 * Allocates remote instance of interpreter
985 * @param interp Interpreter slot
986 * @param on Node Number
988 void QKernel::RemoteInstance(InterpEntry *interp, int on)
992 m.msg_type = MSG_NET;
993 m.param.pword[0] = NET_NODE_EXIST;
994 m.param.pword[1] = on;
995 m.param.pword[2] = interp->ID;
996 write(net_sock, &m, sizeof(MESSAGE));
997 bzero(&m, sizeof(MESSAGE));
998 while((m.msg_type!=MSG_NET) && (m.param.pword[0]!=NET_NODE_EXIST))
999 read(net_sock, &m, sizeof(MESSAGE));
1001 /* means node exists */
1002 if (m.param.pword[1] == 1) {
1003 m.msg_type = MSG_NET;
1004 m.param.pword[0] = NET_TRANSMIT_CODE;
1005 m.param.pword[1] = interp->ID;
1006 m.param.pword[2] = on;
1007 strcpy(m.param.pstr, interp->fullname);
1008 write(net_sock, &m, sizeof(MESSAGE));
1010 Net_Notify->setEnabled(FALSE);
1011 while ((m.msg_type != MSG_NET) ||
1012 (m.param.pword[0] != NET_TRANSMITTED))
1013 read(net_sock, &m, sizeof(MESSAGE));
1015 m.msg_type = MSG_NET;
1016 m.param.pword[0] = NET_PROPAGATE;
1017 m.param.pword[1] = MSG_VLP;
1018 m.param.pword[2] = NodeNumber;
1019 m.param.pword[3] = 0;
1020 m.param.pword[4] = on;
1021 m.param.pword[5] = 0;
1022 m.param.pword[6] = VLP_REMOTE_INSTANCE;
1023 m.param.pword[7] = interp->ID;
1024 strcpy(m.param.pstr, interp->shortname);
1025 write(net_sock, &m, sizeof(MESSAGE));
1027 read(net_sock, &m, sizeof(MESSAGE));
1029 if ((m.param.pword[0] == NET_PROPAGATE) &&
1030 (m.param.pword[6] == VLP_REMOTE_INSTANCE_OK)) {
1031 interp->RInstances[on] = m.param.pword[7];
1034 read(net_sock, &m, sizeof(MESSAGE));
1037 Net_Notify->setEnabled(TRUE);
1039 /*bzero(&m, sizeof(MESSAGE));*/
1040 m.msg_type = MSG_VLP;
1041 m.param.pword[0] = VLP_REMOTE_INSTANCE_HERE;
1042 m.param.pword[1] = interp->RInstances[on];
1043 write(interp->sock, &m, sizeof(MESSAGE));
1044 } else { /* There is no such a node! */
1046 sprintf(s, "Warning: Node number %d not found!", on);
1048 WriteMessage("Allocating O-process on the local node");
1049 bzero(&m, sizeof(MESSAGE));
1050 m.msg_type = MSG_VLP;
1051 m.param.pword[0] = VLP_REMOTE_INSTANCE_HERE;
1052 m.param.pword[1] = interp->ID;
1053 write(interp->sock, &m, sizeof(MESSAGE));
1058 * Closes all remote instances
1060 void QKernel::CloseInstances(InterpEntry *e)
1066 WriteMessage("Closing remote instances");
1068 for(i=0; i < MAXINSTANCES; i++)
1069 if (e->RInstances[i]>=0) {
1070 msg.msg_type = MSG_NET;
1071 msg.param.pword[0] = NET_PROPAGATE;
1072 msg.param.pword[1] = MSG_VLP;
1073 msg.param.pword[2] = NodeNumber;
1074 msg.param.pword[4] = i;
1075 msg.param.pword[6] = VLP_CLOSE_INSTANCE;
1076 msg.param.pword[7] = e->RInstances[i];
1077 write(net_sock, &msg, sizeof(MESSAGE));
1082 * Displays information about virtual machine
1084 void QKernel::on_actionInfo_triggered()
1088 WriteMessage(CharLine);
1089 WriteMessage("### Virtual Machine Information ###");
1090 m.msg_type = MSG_NET;
1091 m.param.pword[0] = NET_GET_INFO;
1092 write(net_sock, &m, sizeof(MESSAGE));
1093 wait_for_info = TRUE;
1100 * Program main function
1101 * All program arguments but the first one (argv[0]: program name) are saved and
1102 * passed to all dependent programs on their invocation.
1103 * @param argc Number of program arguments
1104 * @param argv Program arguments
1106 int main(int argc, char **argv)
1110 QApplication * app = new QApplication(argc, argv);
1111 loglan::vlp::QKernel kernel(argc, argv);