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"
71 #include "kill_interpreter_dialog.h"
72 #include "connect_dialog.h"
74 #include "vlp/config.h"
76 /* File resides in top directory (where are Makefiles)*/
77 #include "../../config.h"
83 char CharLine[25] = "________________________";
86 * Event invoked on program close.
87 * Closes application. Displays additional window to confirm exit.
89 void QKernel::closeEvent(QCloseEvent * e)
94 on_actionQuit_triggered();
98 void QKernel::setLocked(bool locked)
102 actionQuit->setDisabled(locked);
104 actionExecute->setDisabled(locked);
105 actionKill->setDisabled(locked);
106 actionMessage->setDisabled(locked);
107 actionConnect->setDisabled(locked);
108 actionDisconnect->setDisabled(locked);
109 actionInfo->setDisabled(locked);
112 /* Enable only menu entry for unlocking */
113 actionEditor->setDisabled(locked);
114 actionOptions->setDisabled(locked);
115 actionLock_console->setDisabled(locked);
116 actionUnlock_console->setDisabled(!locked);
120 * Kernel program constructor.
121 * Prepares everything to work.
123 QKernel::QKernel(int argc, char **argv)
127 QString arg0(argv[0]);
129 homeDir = QDir(arg0);
134 for(i = 0; (i < 5) && (i < argc-1); i++) {
135 strcpy(myargs[i], "");
137 strcpy(myargs[i], argv[i+1]);
141 QDir q(getRemoteDir());
144 q.mkpath(getRemoteDir());
147 info_messages = actionInfo_messages->isChecked();
148 wait_for_info = FALSE;
150 setWindowTitle(PACKAGE_NAME);
156 ActiveConnections = 0;
157 strcpy(LockPasswd, "");
159 loadConfig(getConfigFilePath());
163 Net_Notify = new QSocketNotifier(net_sock, QSocketNotifier::Read, this);
164 connect(Net_Notify, SIGNAL(activated(int)), this, SLOT(NetMessage()));
166 WriteMessage("\n " PACKAGE_STRING ": READY \n");
169 QString QKernel::getConfigFilePath()
171 return homeDir.absoluteFilePath("vlp.cfg");
174 const char * QKernel::getHomeDir()
176 return homeDir.absolutePath().toStdString().c_str();
179 const char * QKernel::getRemoteDir()
181 return homeDir.absoluteFilePath(REMOTE_PATH).toStdString().c_str();
184 const char * QKernel::getNetModuleSocket()
186 return homeDir.absoluteFilePath(NPATH).toStdString().c_str();
189 const char * QKernel::getGraphModuleSocket()
191 return homeDir.absoluteFilePath(GPATH).toStdString().c_str();
194 void QKernel::loadConfig(const QString & fname)
196 loadConfig(fname.toStdString().c_str());
199 * Loads configuration from the given file.
200 * @param fname Filename of the configuration file.
202 void QKernel::loadConfig(const char * fname)
204 loglan::vlp::Config config;
205 if(config.load(fname)) {
206 NodeNumber = config.getNodeNumber();
207 ConType = config.getConnectionType();
210 std::vector<std::string> hosts = config.getHosts();
211 for (unsigned int i = 0; i < hosts.size(); i++) {
212 ConnectList.append(new ConnectEntry(hosts[i].c_str()));
215 strncpy(progdir, config.getProgramDir(), 256);
221 * Additional window id displayed to set which code to execute.
223 void QKernel::on_actionExecute_triggered()
225 QString s = QFileDialog::getOpenFileName(this, "Execute", progdir, "*.log");
228 int i = s.indexOf(".log");
233 // @TODO: if no interpreter is running will result in killing app
234 RunIntModule((char*)s.toAscii().data(), 0);
239 * Invokes editor program
241 void QKernel::on_actionEditor_triggered()
243 QString program = getHomeDir();
244 program += "/modules/logedit";
248 if (execl(program.toStdString().c_str(),
257 WriteMessage("Executing logedit failed!");
261 WriteMessage("fork(logedit) failed!");
262 WriteMessage("Exiting...");
264 on_actionQuit_triggered();
270 * Invokes help program
272 void QKernel::on_actionHelp_triggered()
274 QString program = getHomeDir();
275 program += "/modules/loghelp";
277 QString docDir = getHomeDir();
282 if (execl(program.toStdString().c_str(),
283 docDir.toStdString().c_str(),
292 WriteMessage("Executing loghelp failed!");
296 WriteMessage("fork(loghelp) failed!");
297 WriteMessage("Exiting...");
299 on_actionQuit_triggered();
305 * Invokes graphics module
307 void QKernel::RunGraphModule(char *sk)
309 QString program = getHomeDir();
310 program += "/modules/loggraph";
314 if (execl(program.toStdString().c_str(),
315 program.toStdString().c_str(),
325 WriteMessage("Executing loggraph failed!");
326 WriteMessage("Exiting...");
328 on_actionQuit_triggered();
332 WriteMessage("fork(loggraph) failed!");
333 WriteMessage("Exiting...");
335 on_actionQuit_triggered();
343 void QKernel::RunNetModule()
345 struct sockaddr_un svr;
350 QString program = getHomeDir();
351 program += "/modules/lognet";
355 if (execl(program.toStdString().c_str(),
356 program.toStdString().c_str(),
357 getNetModuleSocket(),
358 getConfigFilePath().toStdString().c_str(),
367 WriteMessage("Executing lognet failed!");
368 WriteMessage("Exiting...");
370 on_actionQuit_triggered();
374 WriteMessage("fork(lognet) failed!");
375 WriteMessage("Exiting...");
377 on_actionQuit_triggered();
381 /* -------- socket for NET module -------- */
382 unlink(getNetModuleSocket());
383 sock = socket(AF_UNIX, SOCK_STREAM, 0);
384 bzero(&svr, sizeof(svr));
385 svr.sun_family = AF_UNIX;
386 strcpy(svr.sun_path, getNetModuleSocket());
387 len = strlen(svr.sun_path) + sizeof(svr.sun_family);
388 bind(sock, (struct sockaddr*)&svr, len);
391 net_sock = accept(sock, (struct sockaddr*)0, (unsigned int*)0);
394 WriteMessage("NETWORK successfully connected");
395 fcntl(net_sock, F_SETFL, O_NONBLOCK|fcntl(net_sock, F_GETFL, 0));
397 setsockopt(net_sock, IPPROTO_TCP, TCP_NODELAY, (char*)&on, sizeof(on));
399 WriteMessage("Cannot connect NETWORK resources");
400 WriteMessage("Exiting...");
402 on_actionQuit_triggered();
407 * Connects to the specified address
408 * Additional window is displayed to connect to the specified address
410 void QKernel::on_actionConnect_triggered()
414 dialog::ConnectDialog dialog(this);
415 dialog.setWindowTitle("IP Address:");
418 m.msg_type = MSG_NET;
419 m.param.pword[0] = NET_CONNECT_TO;
420 strcpy(m.param.pstr, dialog.getAddress().toStdString().c_str());
421 write(net_sock, &m, sizeof(MESSAGE));
426 * Disconnects from virtual machine
428 void QKernel::on_actionDisconnect_triggered()
433 WriteMessage("Disconnecting from virtual machine");
435 msg.msg_type = MSG_NET;
436 msg.param.pword[0] = NET_DISCONNECT;
437 write(net_sock, &msg, sizeof(MESSAGE));
441 * Quits process. Closes VLP. Shows additional window to confirm exit.
443 void QKernel::on_actionQuit_triggered()
447 QMessageBox::StandardButton response = QMessageBox::question(this,
450 QMessageBox::Ok | QMessageBox::Cancel
454 if (response == QMessageBox::Cancel) {
458 msg.msg_type = MSG_NET;
459 msg.param.pword[0] = NET_DISCONNECT;
460 write(net_sock, &msg, sizeof(MESSAGE));*/
463 msg.msg_type = MSG_NET;
464 msg.param.pword[0] = NET_EXIT;
465 write(net_sock, &msg, sizeof(MESSAGE));
466 /* ::close(net_sock);*/
467 QApplication::instance()->quit();
471 * Sends message to node.
472 * Additional window is displayed to set Node Number of node where send message,
473 * and textfield to enter message.
475 void QKernel::on_actionMessage_triggered()
481 dlg = new QDialog(this, Qt::Dialog);
482 dlg->setWindowTitle("Send message to node");
484 nodenr = new QLineEdit("number", dlg);
485 nodenr->setGeometry(90, 10, 50, 30);
489 tmpQLabel = new QLabel("Node number:", dlg);
490 tmpQLabel->setGeometry(10, 10, 77, 30);
492 tmpQLabel = new QLabel("Message:", dlg);
493 tmpQLabel->setGeometry(10, 50, 70, 30);
496 msg = new QLineEdit("", dlg);
497 msg->setGeometry(80, 60, 330, 30);
500 ob = new QPushButton("Send", dlg);
501 ob->setGeometry(230, 10, 80, 30);
502 ob->setDefault(TRUE);
505 cb = new QPushButton("Cancel", dlg);
506 cb->setGeometry(330, 10, 80, 30);
507 dlg->resize(430, 110);
508 connect(ob, SIGNAL(clicked()), dlg, SLOT(accept()));
509 connect(cb, SIGNAL(clicked()), dlg, SLOT(reject()));
512 m.msg_type = MSG_NET;
513 m.param.pword[0] = NET_PROPAGATE;
514 m.param.pword[1] = MSG_VLP;
515 m.param.pword[2] = NodeNumber;
516 m.param.pword[4] = atoi(nodenr->text().toAscii().data());
517 m.param.pword[6] = VLP_WRITE;
518 strcpy(m.param.pstr, msg->text().toAscii().data());
519 write(net_sock, &m, sizeof(MESSAGE));
525 * Additional window is displayed to get ID of interpreter which should be
528 void QKernel::on_actionKill_triggered()
530 dialog::KillInterpreterDialog dialog(this);
531 dialog.setWindowTitle("Kill interpreter");
535 m.msg_type = MSG_INT;
536 m.param.pword[0] = INT_KILL;
538 InterpEntry *interpreter;
539 interpreter = findINTbyID(dialog.getInterpreterId());
541 if (interpreter != NULL) {
542 if (!(interpreter->remote)) {
543 write(interpreter->sock, &m, sizeof(MESSAGE));
546 WriteMessage("This is a remote instance of a program!");
550 WriteMessage("Interpreter not found");
556 * Sends message to the net module.
558 void QKernel::NetMessage()
561 /* TODO: It has to be rewritten */
566 cnt = read(net_sock, &msg, sizeof(MESSAGE));
567 if ((cnt > 0) && (msg.msg_type == MSG_NET)) {
570 switch(msg.param.pword[0]) {
572 WriteMessage(msg.param.pstr);
575 switch(msg.param.pword[1]) {
577 /* pom = find_link_by_ID(msg.param.pword[5]);
578 msg.msg_type = MSG_NET;
579 msg.param.pword[0] = NET_PROPAGATE;
580 send_int(pom, &msg);*/
583 switch(msg.param.pword[6]) {
585 QApplication::beep();
586 WriteMessage(CharLine);
588 "### Incoming Messsage ###");
589 sprintf(ss, "Mesg from Node %d: %s",
593 WriteMessage(CharLine);
595 case VLP_REMOTE_INSTANCE:
596 sprintf(ss, "%s/%s", getRemoteDir(),
600 WriteMessage("Running program:");
603 pom = RunIntModule(ss, 1);
605 pom->p_ctx.node = msg.param.pword[2];
606 pom->p_ctx.program_id =
608 pom->RInstances[msg.param.pword[2]] = msg.param.pword[7];
611 case VLP_CLOSE_INSTANCE:
612 msg.msg_type = MSG_INT;
613 msg.param.pword[0] = INT_CLOSE_INSTANCE;
614 pom = findINTbyID(msg.param.pword[7]);
616 write(pom->sock, &msg,
619 m1.msg_type = MSG_VLP;
620 m1.param.pword[0] = VLP_INTERPRETER_DOWN;
621 m1.param.pword[1] = pom->ID;
625 WriteMessage("Instance not found");
631 case NET_CONNECTIONS:
632 ActiveConnections = msg.param.pword[1];
633 WriteMessage(msg.param.pstr);
638 /* TODO: It has to be rewritten */
640 QString poms, poms1, poms2;
641 poms.sprintf("%s", msg.param.pstr);
642 while (poms.length() > 0) {
643 cnt = poms.indexOf(';');
645 poms1 = poms.left(cnt);
646 poms = poms.right(poms.length() - cnt - 1);
647 cnt = poms1.indexOf('=');
649 poms2 = poms1.left(cnt);
650 poms1 = poms1.right(poms1.length() - cnt - 1);
651 sprintf(ss, "Node: %s Addr: %s", poms2.toStdString().c_str(), poms1.toStdString().c_str());
659 wait_for_info = FALSE;
660 WriteMessage(CharLine);
667 * Sends message to the interpreter program.
668 * @param sock Interpreter socket to whom the message will be send.
670 void QKernel::IntMessage(int sock)
676 cnt = read(sock, &msg, sizeof(MESSAGE));
677 e = findINTbySocket(sock);
678 if ((cnt > 0) && (e != NULL)) {
679 switch (msg.msg_type) {
681 if (msg.param.pword[0] == GRAPH_ALLOCATE) {
682 RunGraphModule(msg.param.pstr);
686 write(net_sock, &msg, sizeof(MESSAGE));
689 switch(msg.param.pword[0]) {
690 case VLP_REMOTE_INSTANCE_PLEASE:
691 RemoteInstance(e, msg.param.pword[2]);
696 switch(msg.param.pword[0]) {
701 m.msg_type = MSG_VLP;
702 m.param.pword[0] = VLP_INTERPRETER_DOWN;
703 m.param.pword[1] = e->ID;
704 write(net_sock, &m, sizeof(MESSAGE));
709 /* TODO: Check this */
710 Interpreters.removeOne(e);
714 sprintf(ss, "%s : End of program "
715 "execution", msg.param.pstr);
720 msg.msg_type = MSG_INT;
721 msg.param.pword[0] = INT_CTX;
722 msg.param.pword[1] = NodeNumber;
723 msg.param.pword[2] = e->ID;
725 msg.param.pword[3] = e->p_ctx.node;
729 write(sock, &msg, sizeof(MESSAGE));
738 * Writes message to kernel logger.
739 * @parame msg String with message to log
741 void QKernel::WriteMessage(const char *msg)
745 x = desktop->textCursor().blockNumber();
746 // y = desktop->textCursor().columnNumber();
752 desktop->setReadOnly(FALSE);
753 desktop->append(msg);
754 desktop->setReadOnly(TRUE);
756 QTextCursor tmpCursor = desktop->textCursor();
757 tmpCursor.movePosition(QTextCursor::End, QTextCursor::MoveAnchor);
758 desktop->setTextCursor(tmpCursor);
762 if (desktop->document()->blockCount() > 100) {
768 * Adds checkbox to menu item. If it is checked additional info messages are
771 void QKernel::on_actionInfo_messages_triggered()
773 if (toolsMenu != NULL) {
774 info_messages = actionInfo_messages->isChecked();
775 actionInfo_messages->setChecked(info_messages);
780 * Allows to set options in GUI window.
781 * Additional window is displayed to set kernel options which are saved in
782 * vlp.cfg file in kernel executable directory.
784 void QKernel::on_actionOptions_triggered()
786 dialog::OptionsDialog optionsDialog(getConfigFilePath(), this);
787 if (optionsDialog.exec()) {
788 optionsDialog.saveConfig(getConfigFilePath());
790 loadConfig(getConfigFilePath());
795 * Locks kernel program.
796 * Additional window is displayed to enter password and retype it. If both are
797 * same kernel window is locked.
799 void QKernel::on_actionLock_console_triggered()
801 dialog::LockDialog lockDialog(this);
803 if (lockDialog.exec()) {
804 QString password = lockDialog.getPassword();
805 if (lockDialog.getPassword().size() > 0) {
806 strcpy(LockPasswd, password.toStdString().c_str());
809 if (lockDialog.exec()) {
810 password = lockDialog.getPassword();
811 if (password == LockPasswd) {
813 WriteMessage("CONSOLE LOCKED");
815 QMessageBox msg(this);
816 msg.setText("Not matching!");
817 msg.setButtonText(0, "Close");
819 strcpy(LockPasswd, "");
822 strcpy(LockPasswd, "");
829 * Unlocks kernel program.
830 * Additional window is displayed to enter password. If it is correct, kernel
833 void QKernel::on_actionUnlock_console_triggered()
835 dialog::LockDialog lockDialog(this);
837 if (lockDialog.exec()) {
838 QString password = lockDialog.getPassword();
839 if (strcmp(password.toStdString().c_str(), LockPasswd) == 0) {
841 WriteMessage("CONSOLE UNLOCKED");
843 QMessageBox msg(this);
844 msg.setText("Wrong password!");
845 msg.setButtonText(0, "Close");
852 * Finds Interpreter by its socket
853 * @param _id ID of the socket
854 * @return returns pointer to the found interpreter slot. NULL otherwise
856 InterpEntry *QKernel::findINTbySocket(int _id)
858 InterpEntry *pom = NULL;
860 for (auto interpreter : Interpreters) {
861 if (interpreter->sock == _id) {
871 * Finds Interpreter by its ID.
872 * @param _id ID of the interpreter
873 * @return returns pointer to the found interpreter slot. NULL otherwise
875 InterpEntry *QKernel::findINTbyID(int _id)
877 InterpEntry *pom = NULL;
879 for (auto interpreter : Interpreters) {
880 if (interpreter->ID == _id) {
891 * Connects interpreter
892 * @param ss full filepath with filename but without extension of the loglan
894 * @param r Interpreter execution mode. 0 if it will be local instance, 1 if
896 * @return Returns pointer to newly created interpreter slot, or NULL on error.
898 InterpEntry *QKernel::RunIntModule(char *ss, int r)
901 struct sockaddr_un svr;
908 InterpEntry *newINT = NULL;
914 WriteMessage("File not found: no .ccd file");
923 WriteMessage("File not found: no .pcd file");
928 newINT = new InterpEntry;
929 for(i = 0; i < MAXINSTANCES; i++)
930 newINT->RInstances[i] =- 1;
932 strcpy(b, rindex(ss, '/'));
933 for(i = 0; i < strlen(b); i++)
936 sprintf(a, "%s : Start execution", b);
943 strcpy(newINT->shortname, b);
944 strcpy(newINT->fullname, ss);
946 sprintf(a, "%s%d", IPATH, newint);
947 sprintf(cmd, "%s/modules/logint %s %s",
954 sprintf(b, " %s %s %s %s %s",
955 myargs[0], myargs[1], myargs[2], myargs[3], myargs[4]);
959 sock = socket(AF_UNIX, SOCK_STREAM, 0);
961 bzero(&svr, sizeof(svr));
962 svr.sun_family = AF_UNIX;
963 strcpy(svr.sun_path, a);
964 len = strlen(svr.sun_path)+sizeof(svr.sun_family);
965 bind(sock, (struct sockaddr*)&svr, len);
968 newINT->sock = accept(sock, (struct sockaddr*)0, (unsigned int *)0);
971 if (newINT->sock > 0) {
972 fcntl(newINT->sock, F_SETFL,
973 O_NONBLOCK|fcntl(newINT->sock, F_GETFL, 0));
975 setsockopt(newINT->sock, IPPROTO_TCP, TCP_NODELAY, (char*)&on,
982 bzero(&msg, sizeof(MESSAGE));
983 msg.msg_type = MSG_VLP;
984 msg.param.pword[0] = VLP_REGINT;
985 msg.param.pword[1] = newINT->ID;
986 sprintf(msg.param.pstr, "logi%d.net", newint);
987 write(net_sock, &msg, sizeof(MESSAGE));
989 Interpreters.append(newINT);
990 newINT->notify = new QSocketNotifier(newINT->sock,
991 QSocketNotifier::Read);
992 connect(newINT->notify, SIGNAL(activated(int)), this,
993 SLOT(IntMessage(int)));
995 WriteMessage("INTERPRETER successfully connected");
997 WriteMessage("Cannot connect interpreter");
1004 * Allocates remote instance of interpreter
1005 * @param interp Interpreter slot
1006 * @param on Node Number
1008 void QKernel::RemoteInstance(InterpEntry *interp, int on)
1012 m.msg_type = MSG_NET;
1013 m.param.pword[0] = NET_NODE_EXIST;
1014 m.param.pword[1] = on;
1015 m.param.pword[2] = interp->ID;
1016 write(net_sock, &m, sizeof(MESSAGE));
1017 bzero(&m, sizeof(MESSAGE));
1018 while((m.msg_type!=MSG_NET) && (m.param.pword[0]!=NET_NODE_EXIST))
1019 read(net_sock, &m, sizeof(MESSAGE));
1021 /* means node exists */
1022 if (m.param.pword[1] == 1) {
1023 m.msg_type = MSG_NET;
1024 m.param.pword[0] = NET_TRANSMIT_CODE;
1025 m.param.pword[1] = interp->ID;
1026 m.param.pword[2] = on;
1027 strcpy(m.param.pstr, interp->fullname);
1028 write(net_sock, &m, sizeof(MESSAGE));
1030 Net_Notify->setEnabled(FALSE);
1031 while ((m.msg_type != MSG_NET) ||
1032 (m.param.pword[0] != NET_TRANSMITTED))
1033 read(net_sock, &m, sizeof(MESSAGE));
1035 m.msg_type = MSG_NET;
1036 m.param.pword[0] = NET_PROPAGATE;
1037 m.param.pword[1] = MSG_VLP;
1038 m.param.pword[2] = NodeNumber;
1039 m.param.pword[3] = 0;
1040 m.param.pword[4] = on;
1041 m.param.pword[5] = 0;
1042 m.param.pword[6] = VLP_REMOTE_INSTANCE;
1043 m.param.pword[7] = interp->ID;
1044 strcpy(m.param.pstr, interp->shortname);
1045 write(net_sock, &m, sizeof(MESSAGE));
1047 read(net_sock, &m, sizeof(MESSAGE));
1049 if ((m.param.pword[0] == NET_PROPAGATE) &&
1050 (m.param.pword[6] == VLP_REMOTE_INSTANCE_OK)) {
1051 interp->RInstances[on] = m.param.pword[7];
1054 read(net_sock, &m, sizeof(MESSAGE));
1057 Net_Notify->setEnabled(TRUE);
1059 /*bzero(&m, sizeof(MESSAGE));*/
1060 m.msg_type = MSG_VLP;
1061 m.param.pword[0] = VLP_REMOTE_INSTANCE_HERE;
1062 m.param.pword[1] = interp->RInstances[on];
1063 write(interp->sock, &m, sizeof(MESSAGE));
1064 } else { /* There is no such a node! */
1066 sprintf(s, "Warning: Node number %d not found!", on);
1068 WriteMessage("Allocating O-process on the local node");
1069 bzero(&m, sizeof(MESSAGE));
1070 m.msg_type = MSG_VLP;
1071 m.param.pword[0] = VLP_REMOTE_INSTANCE_HERE;
1072 m.param.pword[1] = interp->ID;
1073 write(interp->sock, &m, sizeof(MESSAGE));
1078 * Closes all remote instances
1080 void QKernel::CloseInstances(InterpEntry *e)
1086 WriteMessage("Closing remote instances");
1088 for(i=0; i < MAXINSTANCES; i++)
1089 if (e->RInstances[i]>=0) {
1090 msg.msg_type = MSG_NET;
1091 msg.param.pword[0] = NET_PROPAGATE;
1092 msg.param.pword[1] = MSG_VLP;
1093 msg.param.pword[2] = NodeNumber;
1094 msg.param.pword[4] = i;
1095 msg.param.pword[6] = VLP_CLOSE_INSTANCE;
1096 msg.param.pword[7] = e->RInstances[i];
1097 write(net_sock, &msg, sizeof(MESSAGE));
1102 * Displays information about virtual machine
1104 void QKernel::on_actionInfo_triggered()
1108 WriteMessage(CharLine);
1109 WriteMessage("### Virtual Machine Information ###");
1110 m.msg_type = MSG_NET;
1111 m.param.pword[0] = NET_GET_INFO;
1112 write(net_sock, &m, sizeof(MESSAGE));
1113 wait_for_info = TRUE;
1120 * Program main function
1121 * All program arguments but the first one (argv[0]: program name) are saved and
1122 * passed to all dependent programs on their invocation.
1123 * @param argc Number of program arguments
1124 * @param argv Program arguments
1126 int main(int argc, char **argv)
1130 QApplication * app = new QApplication(argc, argv);
1131 loglan::vlp::QKernel kernel(argc, argv);