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"
76 #include "vlp/QtConfigurationFinder.h"
77 #include "vlp/exception/ConfigFileNotFound.h"
79 #include <sys/prctl.h>
80 /* File resides in top directory (where are Makefiles)*/
81 #include "../../config.h"
87 char CharLine[25] = "________________________";
90 * Event invoked on program close.
91 * Closes application. Displays additional window to confirm exit.
93 void QKernel::closeEvent(QCloseEvent * e)
98 on_actionQuit_triggered();
102 void QKernel::setLocked(bool locked)
106 actionQuit->setDisabled(locked);
108 actionExecute->setDisabled(locked);
109 actionKill->setDisabled(locked);
110 actionMessage->setDisabled(locked);
111 actionConnect->setDisabled(locked);
112 actionDisconnect->setDisabled(locked);
113 actionInfo->setDisabled(locked);
116 /* Enable only menu entry for unlocking */
117 actionEditor->setDisabled(locked);
118 actionOptions->setDisabled(locked);
119 actionLock_console->setDisabled(locked);
120 actionUnlock_console->setDisabled(!locked);
124 * Kernel program constructor.
125 * Prepares everything to work.
127 QKernel::QKernel(int argc, char **argv)
132 for(i = 0; (i < 5) && (i < argc-1); i++) {
133 strcpy(myargs[i], "");
135 strcpy(myargs[i], argv[i+1]);
139 loglan::vlp::QtConfigurationFinder configFinder;
140 configFinder.initSearchDirs();
142 QDir q(getRemoteDir());
145 q.mkpath(getRemoteDir());
148 info_messages = actionInfo_messages->isChecked();
149 wait_for_info = FALSE;
151 setWindowTitle(PACKAGE_NAME);
157 ActiveConnections = 0;
158 strcpy(LockPasswd, "");
160 loadConfig(configFinder.findConfig().c_str());
164 Net_Notify = new QSocketNotifier(net_sock, QSocketNotifier::Read, this);
165 connect(Net_Notify, SIGNAL(activated(int)), this, SLOT(NetMessage()));
167 WriteMessage("\n " PACKAGE_STRING ": READY \n");
170 QString QKernel::getConfigFilePath()
172 return homeDir.absoluteFilePath("vlp.cfg");
175 const char * QKernel::getHomeDir()
177 return homeDir.absolutePath().toStdString().c_str();
180 const char * QKernel::getRemoteDir()
182 return homeDir.absoluteFilePath(REMOTE_PATH).toStdString().c_str();
185 const char * QKernel::getNetModuleSocket()
187 return homeDir.absoluteFilePath(NPATH).toStdString().c_str();
190 const char * QKernel::getGraphModuleSocket()
192 return homeDir.absoluteFilePath(GPATH).toStdString().c_str();
195 void QKernel::loadConfig(const QString & fname)
197 loadConfig(fname.toStdString().c_str());
200 * Loads configuration from the given file.
201 * @param fname Filename of the configuration file.
203 void QKernel::loadConfig(const char * fname)
205 loglan::vlp::Config config;
206 if(config.load(fname)) {
207 NodeNumber = config.getNodeNumber();
208 ConType = config.getConnectionType();
211 std::vector<std::string> hosts = config.getHosts();
212 for (unsigned int i = 0; i < hosts.size(); i++) {
213 ConnectList.append(new ConnectEntry(hosts[i].c_str()));
216 strncpy(progdir, config.getProgramDir(), 256);
218 homeDir = QDir(QCoreApplication::applicationDirPath());
224 * Additional window id displayed to set which code to execute.
226 void QKernel::on_actionExecute_triggered()
228 QString s = QFileDialog::getOpenFileName(this, "Execute", progdir, "*.log");
231 int i = s.indexOf(".log");
236 // @TODO: if no interpreter is running will result in killing app
237 RunIntModule((char*)s.toAscii().data(), 0);
242 * Invokes editor program
244 void QKernel::on_actionEditor_triggered()
246 QString program = getHomeDir();
247 program += "/modules/logedit";
249 fprintf(stderr, "Run EDIT Module: %s, %s\n", program.toStdString().c_str(), getHomeDir());
252 if (execl(program.toStdString().c_str(),
262 WriteMessage("Executing logedit failed!");
266 WriteMessage("fork(logedit) failed!");
267 WriteMessage("Exiting...");
269 on_actionQuit_triggered();
275 * Invokes help program
277 void QKernel::on_actionHelp_triggered()
279 QString program = getHomeDir();
280 program += "/modules/loghelp";
282 QString docDir = getHomeDir();
285 fprintf(stderr, "Run HELP Module: %s, %s\n", program.toStdString().c_str(), docDir.toStdString().c_str());
289 if (execl(program.toStdString().c_str(),
291 docDir.toStdString().c_str(),
300 WriteMessage("Executing loghelp failed!");
304 WriteMessage("fork(loghelp) failed!");
305 WriteMessage("Exiting...");
307 on_actionQuit_triggered();
313 * Invokes graphics module
315 void QKernel::RunGraphModule(char *sk)
317 QString program = getHomeDir();
318 program += "/modules/loggraph";
320 fprintf(stderr, "Run GRAPH Module: %s, %s\n", program.toStdString().c_str(), sk);
324 if (execl(program.toStdString().c_str(),
326 program.toStdString().c_str(),
336 WriteMessage("Executing loggraph failed!");
337 WriteMessage("Exiting...");
339 on_actionQuit_triggered();
343 WriteMessage("fork(loggraph) failed!");
344 WriteMessage("Exiting...");
346 on_actionQuit_triggered();
354 void QKernel::RunNetModule()
357 struct sockaddr_un svr;
362 QString program = getHomeDir();
363 program += "/modules/lognet";
365 fprintf(stderr, "Run NET Module: %s, %s %s\n", program.toStdString().c_str(), getNetModuleSocket(), getConfigFilePath().toStdString().c_str());
368 if (execl(program.toStdString().c_str(),
370 getNetModuleSocket(),
371 getConfigFilePath().toStdString().c_str(),
380 WriteMessage("Executing lognet failed!");
381 WriteMessage("Exiting...");
383 on_actionQuit_triggered();
387 WriteMessage("fork(lognet) failed!");
388 WriteMessage("Exiting...");
390 on_actionQuit_triggered();
394 /* -------- socket for NET module -------- */
395 unlink(getNetModuleSocket());
396 sock = socket(AF_UNIX, SOCK_STREAM, 0);
397 bzero(&svr, sizeof(svr));
398 svr.sun_family = AF_UNIX;
399 strcpy(svr.sun_path, getNetModuleSocket());
400 len = strlen(svr.sun_path) + sizeof(svr.sun_family);
401 bind(sock, (struct sockaddr*)&svr, len);
404 net_sock = accept(sock, (struct sockaddr*)0, (unsigned int*)0);
407 WriteMessage("NETWORK successfully connected");
408 fcntl(net_sock, F_SETFL, O_NONBLOCK|fcntl(net_sock, F_GETFL, 0));
410 setsockopt(net_sock, IPPROTO_TCP, TCP_NODELAY, (char*)&on, sizeof(on));
412 WriteMessage("Cannot connect NETWORK resources");
413 WriteMessage("Exiting...");
415 on_actionQuit_triggered();
420 * Connects to the specified address
421 * Additional window is displayed to connect to the specified address
423 void QKernel::on_actionConnect_triggered()
427 dialog::ConnectDialog dialog(this);
430 m.msg_type = MSG_NET;
431 m.param.pword[0] = NET_CONNECT_TO;
432 strcpy(m.param.pstr, dialog.getAddress().toStdString().c_str());
433 write(net_sock, &m, sizeof(MESSAGE));
438 * Disconnects from virtual machine
440 void QKernel::on_actionDisconnect_triggered()
445 WriteMessage("Disconnecting from virtual machine");
447 msg.msg_type = MSG_NET;
448 msg.param.pword[0] = NET_DISCONNECT;
449 write(net_sock, &msg, sizeof(MESSAGE));
453 * Quits process. Closes VLP. Shows additional window to confirm exit.
455 void QKernel::on_actionQuit_triggered()
459 QMessageBox::StandardButton response = QMessageBox::question(this,
462 QMessageBox::Ok | QMessageBox::Cancel
466 if (response == QMessageBox::Cancel) {
470 msg.msg_type = MSG_NET;
471 msg.param.pword[0] = NET_DISCONNECT;
472 write(net_sock, &msg, sizeof(MESSAGE));*/
475 msg.msg_type = MSG_NET;
476 msg.param.pword[0] = NET_EXIT;
477 write(net_sock, &msg, sizeof(MESSAGE));
478 /* ::close(net_sock);*/
479 QApplication::instance()->quit();
483 * Sends message to node.
484 * Additional window is displayed to set Node Number of node where send message,
485 * and textfield to enter message.
487 void QKernel::on_actionMessage_triggered()
489 dialog::MessageDialog dialog(this);
493 m.msg_type = MSG_NET;
494 m.param.pword[0] = NET_PROPAGATE;
495 m.param.pword[1] = MSG_VLP;
496 m.param.pword[2] = NodeNumber;
497 m.param.pword[4] = dialog.getNodeNumber();
498 m.param.pword[6] = VLP_WRITE;
499 strcpy(m.param.pstr, dialog.getMessage().toStdString().c_str());
500 write(net_sock, &m, sizeof(MESSAGE));
506 * Additional window is displayed to get ID of interpreter which should be
509 void QKernel::on_actionKill_triggered()
511 dialog::KillInterpreterDialog dialog(this);
515 m.msg_type = MSG_INT;
516 m.param.pword[0] = INT_KILL;
518 InterpEntry *interpreter;
519 interpreter = findINTbyID(dialog.getInterpreterId());
521 if (interpreter != NULL) {
522 if (!(interpreter->remote)) {
523 write(interpreter->sock, &m, sizeof(MESSAGE));
526 WriteMessage("This is a remote instance of a program!");
530 WriteMessage("Interpreter not found");
536 * Sends message to the net module.
538 * \todo method needs to be refactored
540 void QKernel::NetMessage()
543 /* TODO: It has to be rewritten */
548 cnt = read(net_sock, &msg, sizeof(MESSAGE));
549 if ((cnt > 0) && (msg.msg_type == MSG_NET)) {
552 switch(msg.param.pword[0]) {
554 WriteMessage(msg.param.pstr);
557 switch(msg.param.pword[1]) {
559 /* pom = find_link_by_ID(msg.param.pword[5]);
560 msg.msg_type = MSG_NET;
561 msg.param.pword[0] = NET_PROPAGATE;
562 send_int(pom, &msg);*/
565 switch(msg.param.pword[6]) {
567 QApplication::beep();
568 WriteMessage(CharLine);
569 WriteMessage("### Incoming Messsage ###");
571 "Mesg from Node %d: %s",
576 WriteMessage(CharLine);
578 case VLP_REMOTE_INSTANCE:
579 sprintf(ss, "%s/%s", getRemoteDir(), msg.param.pstr);
582 WriteMessage("Running program:");
585 pom = RunIntModule(ss, 1);
587 pom->p_ctx.node = msg.param.pword[2];
588 pom->p_ctx.program_id =
590 pom->RInstances[msg.param.pword[2]] = msg.param.pword[7];
593 case VLP_CLOSE_INSTANCE:
594 msg.msg_type = MSG_INT;
595 msg.param.pword[0] = INT_CLOSE_INSTANCE;
596 pom = findINTbyID(msg.param.pword[7]);
598 write(pom->sock, &msg,
601 m1.msg_type = MSG_VLP;
602 m1.param.pword[0] = VLP_INTERPRETER_DOWN;
603 m1.param.pword[1] = pom->ID;
607 WriteMessage("Instance not found");
613 case NET_CONNECTIONS:
614 ActiveConnections = msg.param.pword[1];
615 WriteMessage(msg.param.pstr);
620 /* TODO: It has to be rewritten */
622 QString poms, poms1, poms2;
623 poms.sprintf("%s", msg.param.pstr);
624 while (poms.length() > 0) {
625 cnt = poms.indexOf(';');
627 poms1 = poms.left(cnt);
628 poms = poms.right(poms.length() - cnt - 1);
629 cnt = poms1.indexOf('=');
631 poms2 = poms1.left(cnt);
632 poms1 = poms1.right(poms1.length() - cnt - 1);
633 sprintf(ss, "Node: %s Addr: %s", poms2.toStdString().c_str(), poms1.toStdString().c_str());
641 wait_for_info = FALSE;
642 WriteMessage(CharLine);
649 * Sends message to the interpreter program.
650 * @param sock Interpreter socket to whom the message will be send.
652 void QKernel::IntMessage(int sock)
658 cnt = read(sock, &msg, sizeof(MESSAGE));
659 e = findINTbySocket(sock);
660 if ((cnt > 0) && (e != NULL)) {
661 switch (msg.msg_type) {
663 if (msg.param.pword[0] == GRAPH_ALLOCATE) {
664 fprintf(stderr, "Running graph module with arg: %s\n", msg.param.pstr);
665 RunGraphModule(msg.param.pstr);
669 write(net_sock, &msg, sizeof(MESSAGE));
672 switch(msg.param.pword[0]) {
673 case VLP_REMOTE_INSTANCE_PLEASE:
674 RemoteInstance(e, msg.param.pword[2]);
679 switch(msg.param.pword[0]) {
682 m.msg_type = MSG_VLP;
683 m.param.pword[0] = VLP_INTERPRETER_DOWN;
684 m.param.pword[1] = e->ID;
685 write(net_sock, &m, sizeof(MESSAGE));
690 /* TODO: Check this */
691 Interpreters.removeOne(e);
696 sprintf(ss, "%s : End of program "
697 "execution", msg.param.pstr);
702 msg.msg_type = MSG_INT;
703 msg.param.pword[0] = INT_CTX;
704 msg.param.pword[1] = NodeNumber;
705 msg.param.pword[2] = e->ID;
707 msg.param.pword[3] = e->p_ctx.node;
711 write(sock, &msg, sizeof(MESSAGE));
720 * Writes message to kernel logger.
721 * @parame msg String with message to log
723 void QKernel::WriteMessage(const char *msg)
727 x = desktop->textCursor().blockNumber();
728 // y = desktop->textCursor().columnNumber();
734 desktop->setReadOnly(FALSE);
735 desktop->append(msg);
736 desktop->setReadOnly(TRUE);
738 QTextCursor tmpCursor = desktop->textCursor();
739 tmpCursor.movePosition(QTextCursor::End, QTextCursor::MoveAnchor);
740 desktop->setTextCursor(tmpCursor);
744 if (desktop->document()->blockCount() > 100) {
750 * Adds checkbox to menu item. If it is checked additional info messages are
753 void QKernel::on_actionInfo_messages_triggered()
755 if (toolsMenu != NULL) {
756 info_messages = actionInfo_messages->isChecked();
757 actionInfo_messages->setChecked(info_messages);
762 * Allows to set options in GUI window.
763 * Additional window is displayed to set kernel options which are saved in
764 * vlp.cfg file in kernel executable directory.
766 void QKernel::on_actionOptions_triggered()
768 dialog::OptionsDialog optionsDialog(getConfigFilePath(), this);
769 if (optionsDialog.exec()) {
770 optionsDialog.saveConfig(getConfigFilePath());
772 loadConfig(getConfigFilePath());
777 * Locks kernel program.
778 * Additional window is displayed to enter password and retype it. If both are
779 * same kernel window is locked.
781 void QKernel::on_actionLock_console_triggered()
783 dialog::LockDialog lockDialog(this);
785 if (lockDialog.exec()) {
786 QString password = lockDialog.getPassword();
787 if (lockDialog.getPassword().size() > 0) {
788 strcpy(LockPasswd, password.toStdString().c_str());
791 if (lockDialog.exec()) {
792 password = lockDialog.getPassword();
793 if (password == LockPasswd) {
795 WriteMessage("CONSOLE LOCKED");
797 QMessageBox msg(this);
798 msg.setText("Not matching!");
799 msg.setButtonText(0, "Close");
801 strcpy(LockPasswd, "");
804 strcpy(LockPasswd, "");
811 * Unlocks kernel program.
812 * Additional window is displayed to enter password. If it is correct, kernel
815 void QKernel::on_actionUnlock_console_triggered()
817 dialog::LockDialog lockDialog(this);
819 if (lockDialog.exec()) {
820 QString password = lockDialog.getPassword();
821 if (strcmp(password.toStdString().c_str(), LockPasswd) == 0) {
823 WriteMessage("CONSOLE UNLOCKED");
825 QMessageBox msg(this);
826 msg.setText("Wrong password!");
827 msg.setButtonText(0, "Close");
834 * Finds Interpreter by its socket
835 * @param _id ID of the socket
836 * @return returns pointer to the found interpreter slot. NULL otherwise
838 InterpEntry *QKernel::findINTbySocket(int _id)
840 InterpEntry *pom = NULL;
842 for (auto interpreter : Interpreters) {
843 if (interpreter->sock == _id) {
853 * Finds Interpreter by its ID.
854 * @param _id ID of the interpreter
855 * @return returns pointer to the found interpreter slot. NULL otherwise
857 InterpEntry *QKernel::findINTbyID(int _id)
859 InterpEntry *pom = NULL;
861 for (auto interpreter : Interpreters) {
862 if (interpreter->ID == _id) {
873 * Connects interpreter
874 * @param ss full filepath with filename but without extension of the loglan
876 * @param r Interpreter execution mode. 0 if it will be local instance, 1 if
878 * @return Returns pointer to newly created interpreter slot, or NULL on error.
880 InterpEntry *QKernel::RunIntModule(char *ss, int r)
882 fprintf(stderr, "Run INT Module: %s, %d\n", ss, r);
884 struct sockaddr_un svr;
891 InterpEntry *newINT = NULL;
897 WriteMessage("File not found: no .ccd file");
906 WriteMessage("File not found: no .pcd file");
911 newINT = new InterpEntry;
912 for(i = 0; i < MAXINSTANCES; i++)
913 newINT->RInstances[i] =- 1;
915 strcpy(b, rindex(ss, '/'));
916 for(i = 0; i < strlen(b); i++)
919 sprintf(a, "%s : Start execution", b);
926 strcpy(newINT->shortname, b);
927 strcpy(newINT->fullname, ss);
929 sprintf(a, "%s%d", homeDir.absoluteFilePath(IPATH).toStdString().c_str(), newint);
930 sprintf(cmd, "%s/modules/logint %s %s",
937 // sprintf(b, " %s %s %s %s %s",
938 // myargs[0], myargs[1], myargs[2], myargs[3], myargs[4]);
939 // sprintf(cmd, "%s %s", cmd, b);
941 fprintf(stderr, "%s\n", cmd);
944 sock = socket(AF_UNIX, SOCK_STREAM, 0);
946 bzero(&svr, sizeof(svr));
947 svr.sun_family = AF_UNIX;
948 strcpy(svr.sun_path, a);
949 len = strlen(svr.sun_path)+sizeof(svr.sun_family);
950 bind(sock, (struct sockaddr*)&svr, len);
953 newINT->sock = accept(sock, (struct sockaddr*)0, (unsigned int *)0);
956 if (newINT->sock > 0) {
957 fcntl(newINT->sock, F_SETFL,
958 O_NONBLOCK|fcntl(newINT->sock, F_GETFL, 0));
960 setsockopt(newINT->sock, IPPROTO_TCP, TCP_NODELAY, (char*)&on,
967 bzero(&msg, sizeof(MESSAGE));
968 msg.msg_type = MSG_VLP;
969 msg.param.pword[0] = VLP_REGINT;
970 msg.param.pword[1] = newINT->ID;
971 sprintf(msg.param.pstr, "logi%d.net", newint);
972 write(net_sock, &msg, sizeof(MESSAGE));
974 Interpreters.append(newINT);
975 newINT->notify = new QSocketNotifier(newINT->sock,
976 QSocketNotifier::Read);
977 connect(newINT->notify, SIGNAL(activated(int)), this,
978 SLOT(IntMessage(int)));
980 WriteMessage("INTERPRETER successfully connected");
982 WriteMessage("Cannot connect interpreter");
989 * Allocates remote instance of interpreter
990 * @param interp Interpreter slot
991 * @param on Node Number
993 void QKernel::RemoteInstance(InterpEntry *interp, int on)
997 m.msg_type = MSG_NET;
998 m.param.pword[0] = NET_NODE_EXIST;
999 m.param.pword[1] = on;
1000 m.param.pword[2] = interp->ID;
1001 write(net_sock, &m, sizeof(MESSAGE));
1002 bzero(&m, sizeof(MESSAGE));
1003 while((m.msg_type!=MSG_NET) && (m.param.pword[0]!=NET_NODE_EXIST))
1004 read(net_sock, &m, sizeof(MESSAGE));
1006 /* means node exists */
1007 if (m.param.pword[1] == 1) {
1008 m.msg_type = MSG_NET;
1009 m.param.pword[0] = NET_TRANSMIT_CODE;
1010 m.param.pword[1] = interp->ID;
1011 m.param.pword[2] = on;
1012 strcpy(m.param.pstr, interp->fullname);
1013 write(net_sock, &m, sizeof(MESSAGE));
1015 Net_Notify->setEnabled(FALSE);
1016 while ((m.msg_type != MSG_NET) ||
1017 (m.param.pword[0] != NET_TRANSMITTED))
1018 read(net_sock, &m, sizeof(MESSAGE));
1020 m.msg_type = MSG_NET;
1021 m.param.pword[0] = NET_PROPAGATE;
1022 m.param.pword[1] = MSG_VLP;
1023 m.param.pword[2] = NodeNumber;
1024 m.param.pword[3] = 0;
1025 m.param.pword[4] = on;
1026 m.param.pword[5] = 0;
1027 m.param.pword[6] = VLP_REMOTE_INSTANCE;
1028 m.param.pword[7] = interp->ID;
1029 strcpy(m.param.pstr, interp->shortname);
1030 write(net_sock, &m, sizeof(MESSAGE));
1032 read(net_sock, &m, sizeof(MESSAGE));
1034 if ((m.param.pword[0] == NET_PROPAGATE) &&
1035 (m.param.pword[6] == VLP_REMOTE_INSTANCE_OK)) {
1036 interp->RInstances[on] = m.param.pword[7];
1039 read(net_sock, &m, sizeof(MESSAGE));
1042 Net_Notify->setEnabled(TRUE);
1044 /*bzero(&m, sizeof(MESSAGE));*/
1045 m.msg_type = MSG_VLP;
1046 m.param.pword[0] = VLP_REMOTE_INSTANCE_HERE;
1047 m.param.pword[1] = interp->RInstances[on];
1048 write(interp->sock, &m, sizeof(MESSAGE));
1049 } else { /* There is no such a node! */
1051 sprintf(s, "Warning: Node number %d not found!", on);
1053 WriteMessage("Allocating O-process on the local node");
1054 bzero(&m, sizeof(MESSAGE));
1055 m.msg_type = MSG_VLP;
1056 m.param.pword[0] = VLP_REMOTE_INSTANCE_HERE;
1057 m.param.pword[1] = interp->ID;
1058 write(interp->sock, &m, sizeof(MESSAGE));
1063 * Closes all remote instances
1065 void QKernel::CloseInstances(InterpEntry *e)
1071 WriteMessage("Closing remote instances");
1073 for(i=0; i < MAXINSTANCES; i++)
1074 if (e->RInstances[i]>=0) {
1075 msg.msg_type = MSG_NET;
1076 msg.param.pword[0] = NET_PROPAGATE;
1077 msg.param.pword[1] = MSG_VLP;
1078 msg.param.pword[2] = NodeNumber;
1079 msg.param.pword[4] = i;
1080 msg.param.pword[6] = VLP_CLOSE_INSTANCE;
1081 msg.param.pword[7] = e->RInstances[i];
1082 write(net_sock, &msg, sizeof(MESSAGE));
1087 * Displays information about virtual machine
1089 void QKernel::on_actionInfo_triggered()
1093 WriteMessage(CharLine);
1094 WriteMessage("### Virtual Machine Information ###");
1095 m.msg_type = MSG_NET;
1096 m.param.pword[0] = NET_GET_INFO;
1097 write(net_sock, &m, sizeof(MESSAGE));
1098 wait_for_info = TRUE;
1105 * Program main function
1106 * All program arguments but the first one (argv[0]: program name) are saved and
1107 * passed to all dependent programs on their invocation.
1108 * @param argc Number of program arguments
1109 * @param argv Program arguments
1111 int main(int argc, char **argv)
1115 QApplication * app = new QApplication(argc, argv);
1116 loglan::vlp::QKernel kernel(argc, argv);