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 /* File resides in top directory (where are Makefiles)*/
75 #include "../../config.h"
78 char CharLine[25] = "________________________";
81 * Event invoked on program close.
82 * Closes application. Displays additional window to confirm exit.
84 void QKernel::closeEvent(QCloseEvent * e)
89 on_actionQuit_triggered();
93 void QKernel::setLocked(bool locked)
97 actionQuit->setDisabled(locked);
99 actionExecute->setDisabled(locked);
100 actionKill->setDisabled(locked);
101 actionMessage->setDisabled(locked);
102 actionConnect->setDisabled(locked);
103 actionDisconnect->setDisabled(locked);
104 actionInfo->setDisabled(locked);
107 /* Enable only menu entry for unlocking */
108 actionEditor->setDisabled(locked);
109 actionOptions->setDisabled(locked);
110 actionLock_console->setDisabled(locked);
111 actionUnlock_console->setDisabled(!locked);
115 * Kernel program constructor.
116 * Prepares everything to work.
118 QKernel::QKernel(int argc, char **argv)
122 QString arg0(argv[0]);
124 homeDir = QDir(arg0);
129 for(i = 0; (i < 5) && (i < argc-1); i++) {
130 strcpy(myargs[i], "");
132 strcpy(myargs[i], argv[i+1]);
136 QDir q(getRemoteDir());
139 q.mkpath(getRemoteDir());
142 info_messages = actionInfo_messages->isChecked();
143 wait_for_info = FALSE;
145 setWindowTitle(PACKAGE_NAME);
151 ActiveConnections = 0;
152 strcpy(LockPasswd, "");
154 loadConfig(getConfigFilePath());
158 Net_Notify = new QSocketNotifier(net_sock, QSocketNotifier::Read, this);
159 connect(Net_Notify, SIGNAL(activated(int)), this, SLOT(NetMessage()));
161 WriteMessage("\n " PACKAGE_STRING ": READY \n");
164 QString QKernel::getConfigFilePath()
166 return homeDir.absoluteFilePath("vlp.cfg");
169 const char * QKernel::getHomeDir()
171 return homeDir.absolutePath().toStdString().c_str();
174 const char * QKernel::getRemoteDir()
176 return homeDir.absoluteFilePath(REMOTE_PATH).toStdString().c_str();
179 const char * QKernel::getNetModuleSocket()
181 return homeDir.absoluteFilePath(NPATH).toStdString().c_str();
184 const char * QKernel::getGraphModuleSocket()
186 return homeDir.absoluteFilePath(GPATH).toStdString().c_str();
189 void QKernel::loadConfig(const QString & fname)
191 loadConfig(fname.toStdString().c_str());
194 * Loads configuration from the given file.
195 * @param fname Filename of the configuration file.
197 void QKernel::loadConfig(const char * fname)
200 config_setting_t *setting;
202 /* Hack for checking if file exists without using external libs.*/
204 FILE * file = fopen(fname, "rt");
206 fprintf(stderr, "Error: Cannot load configuration file: %s!\n",
210 /* File exists, so file has been locked. Release it. */
214 /* Read the file. If there is an error, report it and exit. */
215 if (!config_read(&cfg, file)) {
216 fprintf(stderr, "%s! In file %s, line %d\n",
217 config_error_text(&cfg),
218 config_error_file(&cfg),
219 config_error_line(&cfg));
220 config_destroy(&cfg);
225 setting = config_lookup(&cfg, "node_number");
227 NodeNumber = config_setting_get_int(setting);
229 fprintf(stderr, "%s! In file %s, '%s' was not found.\n",
230 "Warning", fname, "node_number");
231 config_destroy(&cfg);
236 setting = config_lookup(&cfg, "type");
238 /* same as strcmp(..) == 0 */
239 if (!strcmp(config_setting_get_string(setting), "explicit")) {
245 fprintf(stderr, "%s! In file %s, '%s' was not found.\n",
246 "Warning", fname, "type");
249 setting = config_lookup(&cfg, "host");
251 switch(config_setting_type(setting)) {
252 /* TODO: Deprecated. Made for back compatibility. */
253 case CONFIG_TYPE_STRING:
254 ConnectList.append(new ConnectEntry((char*)
255 config_setting_get_string(setting)));
257 case CONFIG_TYPE_ARRAY: {
258 int size = config_setting_length(setting);
259 for (int i = 0; i < size; i++) {
260 ConnectList.append(new ConnectEntry((char*)
261 config_setting_get_string_elem(setting,
267 fprintf(stderr, "%s! In file %s, bad entry type for %s."
268 " Will not be read.\n",
269 "Error", fname, "host");
272 fprintf(stderr, "%s! In file %s, '%s' was not found.\n",
273 "Warning", fname, "host");
276 setting = config_lookup(&cfg, "progdir");
278 strncpy(progdir, config_setting_get_string(setting), 256);
280 fprintf(stderr, "%s! In file %s, '%s' was not found.\n",
281 "Warning", fname, "progdir");
284 config_destroy(&cfg);
290 * Additional window id displayed to set which code to execute.
292 void QKernel::on_actionExecute_triggered()
295 QString s = QFileDialog::getOpenFileName(this, "Execute", progdir, "*.log");
298 i = s.indexOf(".log");
303 // @TODO: if no interpreter is running will result in killing app
304 RunIntModule((char*)s.toAscii().data(), 0);
309 * Invokes editor program
311 void QKernel::on_actionEditor_triggered()
313 QString program = getHomeDir();
314 program += "/modules/logedit";
318 if (execl(program.toStdString().c_str(),
327 WriteMessage("Executing logedit failed!");
331 WriteMessage("fork(logedit) failed!");
332 WriteMessage("Exiting...");
334 on_actionQuit_triggered();
340 * Invokes help program
342 void QKernel::on_actionHelp_triggered()
344 QString program = getHomeDir();
345 program += "/modules/loghelp";
347 QString docDir = getHomeDir();
352 if (execl(program.toStdString().c_str(),
353 docDir.toStdString().c_str(),
362 WriteMessage("Executing loghelp failed!");
366 WriteMessage("fork(loghelp) failed!");
367 WriteMessage("Exiting...");
369 on_actionQuit_triggered();
375 * Invokes graphics module
377 void QKernel::RunGraphModule(char *sk)
381 QString program = getHomeDir();
382 program += "/modules/loggraph";
386 if (execl(program.toStdString().c_str(),
387 program.toStdString().c_str(),
397 WriteMessage("Executing loggraph failed!");
398 WriteMessage("Exiting...");
400 on_actionQuit_triggered();
404 WriteMessage("fork(loggraph) failed!");
405 WriteMessage("Exiting...");
407 on_actionQuit_triggered();
415 void QKernel::RunNetModule()
417 struct sockaddr_un svr;
422 QString program = getHomeDir();
423 program += "/modules/lognet";
427 if (execl(program.toStdString().c_str(),
428 program.toStdString().c_str(),
429 getNetModuleSocket(),
430 getConfigFilePath().toStdString().c_str(),
439 WriteMessage("Executing lognet failed!");
440 WriteMessage("Exiting...");
442 on_actionQuit_triggered();
446 WriteMessage("fork(lognet) failed!");
447 WriteMessage("Exiting...");
449 on_actionQuit_triggered();
453 /* -------- socket for NET module -------- */
454 unlink(getNetModuleSocket());
455 sock = socket(AF_UNIX, SOCK_STREAM, 0);
456 bzero(&svr, sizeof(svr));
457 svr.sun_family = AF_UNIX;
458 strcpy(svr.sun_path, getNetModuleSocket());
459 len = strlen(svr.sun_path) + sizeof(svr.sun_family);
460 bind(sock, (struct sockaddr*)&svr, len);
463 net_sock = accept(sock, (struct sockaddr*)0, (unsigned int*)0);
466 WriteMessage("NETWORK successfully connected");
467 fcntl(net_sock, F_SETFL, O_NONBLOCK|fcntl(net_sock, F_GETFL, 0));
469 setsockopt(net_sock, IPPROTO_TCP, TCP_NODELAY, (char*)&on, sizeof(on));
471 WriteMessage("Cannot connect NETWORK resources");
472 WriteMessage("Exiting...");
474 on_actionQuit_triggered();
479 * Connects to the specified address
480 * Additional window is displayed to connect to the specified address
482 void QKernel::on_actionConnect_triggered()
486 ConnectDialog dialog(this);
487 dialog.setWindowTitle("IP Address:");
490 m.msg_type = MSG_NET;
491 m.param.pword[0] = NET_CONNECT_TO;
492 strcpy(m.param.pstr, dialog.getAddress().toStdString().c_str());
493 write(net_sock, &m, sizeof(MESSAGE));
498 * Disconnects from virtual machine
500 void QKernel::on_actionDisconnect_triggered()
505 WriteMessage("Disconnecting from virtual machine");
507 msg.msg_type = MSG_NET;
508 msg.param.pword[0] = NET_DISCONNECT;
509 write(net_sock, &msg, sizeof(MESSAGE));
513 * Quits process. Closes VLP. Shows additional window to confirm exit.
515 void QKernel::on_actionQuit_triggered()
519 QMessageBox::StandardButton response = QMessageBox::question(this,
522 QMessageBox::Ok | QMessageBox::Cancel
526 if (response == QMessageBox::Cancel) {
530 msg.msg_type = MSG_NET;
531 msg.param.pword[0] = NET_DISCONNECT;
532 write(net_sock, &msg, sizeof(MESSAGE));*/
535 msg.msg_type = MSG_NET;
536 msg.param.pword[0] = NET_EXIT;
537 write(net_sock, &msg, sizeof(MESSAGE));
538 /* ::close(net_sock);*/
539 QApplication::instance()->quit();
543 * Sends message to node.
544 * Additional window is displayed to set Node Number of node where send message,
545 * and textfield to enter message.
547 void QKernel::on_actionMessage_triggered()
553 dlg = new QDialog(this, Qt::Dialog);
554 dlg->setWindowTitle("Send message to node");
556 nodenr = new QLineEdit("number", dlg);
557 nodenr->setGeometry(90, 10, 50, 30);
561 tmpQLabel = new QLabel("Node number:", dlg);
562 tmpQLabel->setGeometry(10, 10, 77, 30);
564 tmpQLabel = new QLabel("Message:", dlg);
565 tmpQLabel->setGeometry(10, 50, 70, 30);
568 msg = new QLineEdit("", dlg);
569 msg->setGeometry(80, 60, 330, 30);
572 ob = new QPushButton("Send", dlg);
573 ob->setGeometry(230, 10, 80, 30);
574 ob->setDefault(TRUE);
577 cb = new QPushButton("Cancel", dlg);
578 cb->setGeometry(330, 10, 80, 30);
579 dlg->resize(430, 110);
580 connect(ob, SIGNAL(clicked()), dlg, SLOT(accept()));
581 connect(cb, SIGNAL(clicked()), dlg, SLOT(reject()));
584 m.msg_type = MSG_NET;
585 m.param.pword[0] = NET_PROPAGATE;
586 m.param.pword[1] = MSG_VLP;
587 m.param.pword[2] = NodeNumber;
588 m.param.pword[4] = atoi(nodenr->text().toAscii().data());
589 m.param.pword[6] = VLP_WRITE;
590 strcpy(m.param.pstr, msg->text().toAscii().data());
591 write(net_sock, &m, sizeof(MESSAGE));
597 * Additional window is displayed to get ID of interpreter which should be
600 void QKernel::on_actionKill_triggered()
602 KillInterpreterDialog dialog(this);
603 dialog.setWindowTitle("Kill interpreter");
606 InterpEntry *interpreter;
609 m.msg_type = MSG_INT;
610 m.param.pword[0] = INT_KILL;
611 interpreter = findINTbyID(dialog.getInterpreterId());
612 if (interpreter != NULL) {
613 if (!(interpreter->remote))
614 write(interpreter->sock, &m, sizeof(MESSAGE));
616 WriteMessage("This is a remote instance of a program!");
619 WriteMessage("Interpreter not found");
625 * Sends message to the net module.
627 void QKernel::NetMessage()
630 /* TODO: It has to be rewritten */
636 cnt = read(net_sock, &msg, sizeof(MESSAGE));
637 if ((cnt > 0) && (msg.msg_type == MSG_NET)) {
638 switch(msg.param.pword[0]) {
640 WriteMessage(msg.param.pstr);
643 switch(msg.param.pword[1]) {
645 /* pom = find_link_by_ID(msg.param.pword[5]);
646 msg.msg_type = MSG_NET;
647 msg.param.pword[0] = NET_PROPAGATE;
648 send_int(pom, &msg);*/
651 switch(msg.param.pword[6]) {
653 QApplication::beep();
654 WriteMessage(CharLine);
656 "### Incoming Messsage ###");
657 sprintf(ss, "Mesg from Node %d: %s",
661 WriteMessage(CharLine);
663 case VLP_REMOTE_INSTANCE:
664 sprintf(ss, "%s/%s", getRemoteDir(),
668 WriteMessage("Running program:");
671 pom = RunIntModule(ss, 1);
673 pom->p_ctx.node = msg.param.pword[2];
674 pom->p_ctx.program_id =
676 pom->RInstances[msg.param.pword[2]] = msg.param.pword[7];
679 case VLP_CLOSE_INSTANCE:
680 msg.msg_type = MSG_INT;
681 msg.param.pword[0] = INT_CLOSE_INSTANCE;
682 pom = findINTbyID(msg.param.pword[7]);
684 write(pom->sock, &msg,
687 m1.msg_type = MSG_VLP;
688 m1.param.pword[0] = VLP_INTERPRETER_DOWN;
689 m1.param.pword[1] = pom->ID;
693 WriteMessage("Instance not found");
699 case NET_CONNECTIONS:
700 ActiveConnections = msg.param.pword[1];
701 WriteMessage(msg.param.pstr);
706 /* TODO: It has to be rewritten */
708 QString poms, poms1, poms2;
709 poms.sprintf("%s", msg.param.pstr);
710 while (poms.length() > 0) {
711 cnt = poms.indexOf(';');
713 poms1 = poms.left(cnt);
714 poms = poms.right(poms.length() - cnt - 1);
715 cnt = poms1.indexOf('=');
717 poms2 = poms1.left(cnt);
718 poms1 = poms1.right(poms1.length() - cnt - 1);
719 sprintf(ss, "Node: %s Addr: %s", poms2.toStdString().c_str(), poms1.toStdString().c_str());
727 wait_for_info = FALSE;
728 WriteMessage(CharLine);
735 * Sends message to the interpreter program.
736 * @param sock Interpreter socket to whom the message will be send.
738 void QKernel::IntMessage(int sock)
744 cnt = read(sock, &msg, sizeof(MESSAGE));
745 e = findINTbySocket(sock);
746 if ((cnt > 0) && (e != NULL)) {
747 switch (msg.msg_type) {
749 if (msg.param.pword[0] == GRAPH_ALLOCATE) {
750 RunGraphModule(msg.param.pstr);
754 write(net_sock, &msg, sizeof(MESSAGE));
757 switch(msg.param.pword[0]) {
758 case VLP_REMOTE_INSTANCE_PLEASE:
759 RemoteInstance(e, msg.param.pword[2]);
764 switch(msg.param.pword[0]) {
769 m.msg_type = MSG_VLP;
770 m.param.pword[0] = VLP_INTERPRETER_DOWN;
771 m.param.pword[1] = e->ID;
772 write(net_sock, &m, sizeof(MESSAGE));
777 /* TODO: Check this */
778 Interpreters.removeOne(e);
782 sprintf(ss, "%s : End of program "
783 "execution", msg.param.pstr);
788 msg.msg_type = MSG_INT;
789 msg.param.pword[0] = INT_CTX;
790 msg.param.pword[1] = NodeNumber;
791 msg.param.pword[2] = e->ID;
793 msg.param.pword[3] = e->p_ctx.node;
797 write(sock, &msg, sizeof(MESSAGE));
806 * Writes message to kernel logger.
807 * @parame msg String with message to log
809 void QKernel::WriteMessage(char *msg)
813 x = desktop->textCursor().blockNumber();
814 y = desktop->textCursor().columnNumber();
820 desktop->setReadOnly(FALSE);
821 desktop->append(msg);
822 desktop->setReadOnly(TRUE);
824 QTextCursor tmpCursor = desktop->textCursor();
825 tmpCursor.movePosition(QTextCursor::End, QTextCursor::MoveAnchor);
826 desktop->setTextCursor(tmpCursor);
830 if (desktop->document()->blockCount() > 100) {
836 * Adds checkbox to menu item. If it is checked additional info messages are
839 void QKernel::on_actionInfo_messages_triggered()
841 if (toolsMenu != NULL) {
842 info_messages = actionInfo_messages->isChecked();
843 actionInfo_messages->setChecked(info_messages);
848 * Allows to set options in GUI window.
849 * Additional window is displayed to set kernel options which are saved in
850 * vlp.cfg file in kernel executable directory.
852 void QKernel::on_actionOptions_triggered()
854 OptionsDialog optionsDialog(getConfigFilePath(), this);
855 if (optionsDialog.exec()) {
856 optionsDialog.saveConfig(getConfigFilePath());
858 loadConfig(getConfigFilePath());
863 * Locks kernel program.
864 * Additional window is displayed to enter password and retype it. If both are
865 * same kernel window is locked.
867 void QKernel::on_actionLock_console_triggered()
869 LockDialog lockDialog(this);
871 if (lockDialog.exec()) {
872 QString password = lockDialog.getPassword();
873 if (lockDialog.getPassword().size() > 0) {
874 strcpy(LockPasswd, password.toStdString().c_str());
877 if (lockDialog.exec()) {
878 password = lockDialog.getPassword();
879 if (password == LockPasswd) {
881 WriteMessage("CONSOLE LOCKED");
883 QMessageBox msg(this);
884 msg.setText("Not matching!");
885 msg.setButtonText(0, "Close");
887 strcpy(LockPasswd, "");
890 strcpy(LockPasswd, "");
897 * Unlocks kernel program.
898 * Additional window is displayed to enter password. If it is correct, kernel
901 void QKernel::on_actionUnlock_console_triggered()
903 LockDialog lockDialog(this);
905 if (lockDialog.exec()) {
906 QString password = lockDialog.getPassword();
907 if (strcmp(password.toStdString().c_str(), LockPasswd) == 0) {
909 WriteMessage("CONSOLE UNLOCKED");
911 QMessageBox msg(this);
912 msg.setText("Wrong password!");
913 msg.setButtonText(0, "Close");
920 * Finds Interpreter by its socket
921 * @param _id ID of the socket
922 * @return returns pointer to the found interpreter slot. NULL otherwise
924 InterpEntry *QKernel::findINTbySocket(int _id)
926 InterpEntry *pom = NULL;
928 for (int i = 0; i < Interpreters.size(); i++) {
929 if (Interpreters.at(i)->sock == _id) {
930 pom = Interpreters.at(i);
939 * Finds Interpreter by its ID.
940 * @param _id ID of the interpreter
941 * @return returns pointer to the found interpreter slot. NULL otherwise
943 InterpEntry *QKernel::findINTbyID(int _id)
945 InterpEntry *pom = NULL;
947 for (int i = 0; i < Interpreters.size(); i++) {
948 if (Interpreters.at(i)->ID == _id) {
949 pom = Interpreters.at(i);
959 * Connects interpreter
960 * @param ss full filepath with filename but without extension of the loglan
962 * @param r Interpreter execution mode. 0 if it will be local instance, 1 if
964 * @return Returns pointer to newly created interpreter slot, or NULL on error.
966 InterpEntry *QKernel::RunIntModule(char *ss, int r)
969 struct sockaddr_un svr;
976 InterpEntry *newINT = NULL;
982 WriteMessage("File not found: no .ccd file");
991 WriteMessage("File not found: no .pcd file");
996 newINT = new InterpEntry;
997 for(i = 0; i < MAXINSTANCES; i++)
998 newINT->RInstances[i] =- 1;
1000 strcpy(b, rindex(ss, '/'));
1001 for(i = 0; i < strlen(b); i++)
1003 if (info_messages) {
1004 sprintf(a, "%s : Start execution", b);
1010 newINT->ID = newint;
1011 strcpy(newINT->shortname, b);
1012 strcpy(newINT->fullname, ss);
1014 sprintf(a, "%s%d", IPATH, newint);
1015 sprintf(cmd, "%s/modules/logint %s %s",
1022 sprintf(b, " %s %s %s %s %s",
1023 myargs[0], myargs[1], myargs[2], myargs[3], myargs[4]);
1027 sock = socket(AF_UNIX, SOCK_STREAM, 0);
1029 bzero(&svr, sizeof(svr));
1030 svr.sun_family = AF_UNIX;
1031 strcpy(svr.sun_path, a);
1032 len = strlen(svr.sun_path)+sizeof(svr.sun_family);
1033 bind(sock, (struct sockaddr*)&svr, len);
1036 newINT->sock = accept(sock, (struct sockaddr*)0, (unsigned int *)0);
1039 if (newINT->sock > 0) {
1040 fcntl(newINT->sock, F_SETFL,
1041 O_NONBLOCK|fcntl(newINT->sock, F_GETFL, 0));
1043 setsockopt(newINT->sock, IPPROTO_TCP, TCP_NODELAY, (char*)&on,
1050 bzero(&msg, sizeof(MESSAGE));
1051 msg.msg_type = MSG_VLP;
1052 msg.param.pword[0] = VLP_REGINT;
1053 msg.param.pword[1] = newINT->ID;
1054 sprintf(msg.param.pstr, "logi%d.net", newint);
1055 write(net_sock, &msg, sizeof(MESSAGE));
1057 Interpreters.append(newINT);
1058 newINT->notify = new QSocketNotifier(newINT->sock,
1059 QSocketNotifier::Read);
1060 connect(newINT->notify, SIGNAL(activated(int)), this,
1061 SLOT(IntMessage(int)));
1063 WriteMessage("INTERPRETER successfully connected");
1065 WriteMessage("Cannot connect interpreter");
1072 * Allocates remote instance of interpreter
1073 * @param interp Interpreter slot
1074 * @param on Node Number
1076 void QKernel::RemoteInstance(InterpEntry *interp, int on)
1081 m.msg_type = MSG_NET;
1082 m.param.pword[0] = NET_NODE_EXIST;
1083 m.param.pword[1] = on;
1084 m.param.pword[2] = interp->ID;
1085 write(net_sock, &m, sizeof(MESSAGE));
1086 bzero(&m, sizeof(MESSAGE));
1087 while((m.msg_type!=MSG_NET) && (m.param.pword[0]!=NET_NODE_EXIST))
1088 read(net_sock, &m, sizeof(MESSAGE));
1090 /* means node exists */
1091 if (m.param.pword[1] == 1) {
1092 m.msg_type = MSG_NET;
1093 m.param.pword[0] = NET_TRANSMIT_CODE;
1094 m.param.pword[1] = interp->ID;
1095 m.param.pword[2] = on;
1096 strcpy(m.param.pstr, interp->fullname);
1097 write(net_sock, &m, sizeof(MESSAGE));
1099 Net_Notify->setEnabled(FALSE);
1100 while ((m.msg_type != MSG_NET) ||
1101 (m.param.pword[0] != NET_TRANSMITTED))
1102 read(net_sock, &m, sizeof(MESSAGE));
1104 m.msg_type = MSG_NET;
1105 m.param.pword[0] = NET_PROPAGATE;
1106 m.param.pword[1] = MSG_VLP;
1107 m.param.pword[2] = NodeNumber;
1108 m.param.pword[3] = 0;
1109 m.param.pword[4] = on;
1110 m.param.pword[5] = 0;
1111 m.param.pword[6] = VLP_REMOTE_INSTANCE;
1112 m.param.pword[7] = interp->ID;
1113 strcpy(m.param.pstr, interp->shortname);
1114 write(net_sock, &m, sizeof(MESSAGE));
1116 read(net_sock, &m, sizeof(MESSAGE));
1118 if ((m.param.pword[0] == NET_PROPAGATE) &&
1119 (m.param.pword[6] == VLP_REMOTE_INSTANCE_OK)) {
1120 interp->RInstances[on] = m.param.pword[7];
1123 read(net_sock, &m, sizeof(MESSAGE));
1126 Net_Notify->setEnabled(TRUE);
1128 /*bzero(&m, sizeof(MESSAGE));*/
1129 m.msg_type = MSG_VLP;
1130 m.param.pword[0] = VLP_REMOTE_INSTANCE_HERE;
1131 m.param.pword[1] = interp->RInstances[on];
1132 write(interp->sock, &m, sizeof(MESSAGE));
1133 } else { /* There is no such a node! */
1134 sprintf(s, "Warning: Node number %d not found!", on);
1136 WriteMessage("Allocating O-process on the local node");
1137 bzero(&m, sizeof(MESSAGE));
1138 m.msg_type = MSG_VLP;
1139 m.param.pword[0] = VLP_REMOTE_INSTANCE_HERE;
1140 m.param.pword[1] = interp->ID;
1141 write(interp->sock, &m, sizeof(MESSAGE));
1146 * Closes all remote instances
1148 void QKernel::CloseInstances(InterpEntry *e)
1154 WriteMessage("Closing remote instances");
1156 for(i=0; i < MAXINSTANCES; i++)
1157 if (e->RInstances[i]>=0) {
1158 msg.msg_type = MSG_NET;
1159 msg.param.pword[0] = NET_PROPAGATE;
1160 msg.param.pword[1] = MSG_VLP;
1161 msg.param.pword[2] = NodeNumber;
1162 msg.param.pword[4] = i;
1163 msg.param.pword[6] = VLP_CLOSE_INSTANCE;
1164 msg.param.pword[7] = e->RInstances[i];
1165 write(net_sock, &msg, sizeof(MESSAGE));
1170 * Displays information about virtual machine
1172 void QKernel::on_actionInfo_triggered()
1176 WriteMessage(CharLine);
1177 WriteMessage("### Virtual Machine Information ###");
1178 m.msg_type = MSG_NET;
1179 m.param.pword[0] = NET_GET_INFO;
1180 write(net_sock, &m, sizeof(MESSAGE));
1181 wait_for_info = TRUE;
1185 * Program main function
1186 * All program arguments but the first one (argv[0]: program name) are saved and
1187 * passed to all dependent programs on their invocation.
1188 * @param argc Number of program arguments
1189 * @param argv Program arguments
1191 int main(int argc, char **argv)
1195 QApplication * app = new QApplication(argc, argv);
1196 QKernel kernel(argc, argv);