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 ************************************************************/
33 #include <QtGui/QApplication>
34 #include <QtGui/QMainWindow>
35 #include <QtGui/QTextEdit>
36 #include <QtGui/QMenuBar>
37 #include <QtGui/QMessageBox>
38 #include <QtGui/QFileDialog>
39 #include <QtGui/QDialog>
40 #include <QtCore/QString>
41 #include <QtGui/QLabel>
42 #include <QtGui/QLineEdit>
43 #include <QtGui/QPushButton>
44 #include <QtGui/QRadioButton>
45 #include <QtGui/QGroupBox>
46 #include <QtGui/QVBoxLayout>
47 #include <QtCore/QList>
48 #include <QtGui/QListWidget>
51 #include <QtCore/QSocketNotifier>
52 #include <QtGui/QCloseEvent>
62 #include <netinet/in.h>
64 #include <libconfig.h>
67 #include "kernelwindow.h"
71 /* File resides in top directory (where are Makefiles)*/
72 #include "../../config.h"
75 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.
126 sprintf(ss, "mkdir %s", REMOTE_PATH);
130 info_messages = TRUE;
131 wait_for_info = FALSE;
133 setWindowTitle(PACKAGE_NAME);
139 ActiveConnections = 0;
140 strcpy(LockPasswd, "");
141 LoadConfig("vlp.cfg");
144 Net_Notify = new QSocketNotifier(net_sock, QSocketNotifier::Read, this);
145 connect(Net_Notify, SIGNAL(activated(int)), this, SLOT(NetMessage()));
149 * Displays window with information about not implemented functionality.
151 void QKernel::n_impl()
153 QMessageBox::information(this, "Function info", "This function is not "
154 "implemented yet...", "Ok");
158 * Loads configuration from the given file.
159 * @param fname Filename of the configuration file.
161 void QKernel::LoadConfig(char * fname)
164 config_setting_t *setting;
167 /* Hack for checking if file exists without using external libs.*/
168 FILE * file = fopen(fname, "rt");
170 fprintf(stderr, "Error: Cannot load configuration file %s!\n",
174 /* File exists, so file has been locked. Release it. */
178 /* Read the file. If there is an error, report it and exit. */
179 if (!config_read(&cfg, file)) {
180 fprintf(stderr, "%s! In file %s, line %d\n",
181 config_error_text(&cfg),
182 config_error_file(&cfg),
183 config_error_line(&cfg));
184 config_destroy(&cfg);
189 setting = config_lookup(&cfg, "node_number");
191 NodeNumber = config_setting_get_int(setting);
193 fprintf(stderr, "%s! In file %s, '%s' was not found.\n",
194 "Warning", fname, "node_number");
195 config_destroy(&cfg);
200 setting = config_lookup(&cfg, "type");
202 /* same as strcmp(..) == 0 */
203 if (!strcmp(config_setting_get_string(setting), "explicit")) {
209 fprintf(stderr, "%s! In file %s, '%s' was not found.\n",
210 "Warning", fname, "type");
213 setting = config_lookup(&cfg, "host");
215 switch(config_setting_type(setting)) {
216 /* TODO: Deprecated. Made for back compatibility. */
217 case CONFIG_TYPE_STRING:
218 ConnectList.append(new ConnectEntry((char*)
219 config_setting_get_string(setting)));
221 case CONFIG_TYPE_ARRAY: {
222 int size = config_setting_length(setting);
223 for (int i = 0; i < size; i++) {
224 ConnectList.append(new ConnectEntry((char*)
225 config_setting_get_string_elem(setting,
231 fprintf(stderr, "%s! In file %s, bad entry type for %s."
232 " Will not be read.\n",
233 "Error", fname, "host");
236 fprintf(stderr, "%s! In file %s, '%s' was not found.\n",
237 "Warning", fname, "host");
240 setting = config_lookup(&cfg, "progdir");
242 strncpy(progdir, config_setting_get_string(setting), 256);
244 fprintf(stderr, "%s! In file %s, '%s' was not found.\n",
245 "Warning", fname, "progdir");
248 setting = config_lookup(&cfg, "homedir");
250 strncpy(HomeDir, config_setting_get_string(setting), 255);
252 fprintf(stderr, "%s! In file %s, '%s' was not found.\n",
253 "Warning", fname, "homedir");
256 config_destroy(&cfg);
262 * Additional window id displayed to set which code to execute.
264 void QKernel::on_actionExecute_triggered()
267 QString s = QFileDialog::getOpenFileName(this, "Execute", progdir, "*.log");
270 i = s.indexOf(".log");
275 RunIntModule((char*)s.toAscii().data(), 0);
280 * Invokes editor program
282 void QKernel::on_actionEditor_triggered()
285 sprintf(cmd, "%s/modules/logedit %s %s %s %s %s %s &", HomeDir, HomeDir,
286 myargs[0], myargs[1], myargs[2], myargs[3], myargs[4]);
291 * Invokes help program
293 void QKernel::on_actionHelp_triggered()
296 sprintf(cmd, "%s/modules/loghelp %s/doc %s %s %s %s %s &", HomeDir,
297 HomeDir, myargs[0], myargs[1], myargs[2], myargs[3], myargs[4]);
302 * Invokes graphics module
304 void QKernel::RunGraphModule(char *sk)
308 sprintf(cmd, "%s/modules/loggraph %s %s %s %s %s %s &", HomeDir,
309 sk, myargs[0], myargs[1], myargs[2], myargs[3], myargs[4]);
311 if (system(cmd) != 0)
312 WriteMessage("Cannot connect GRAPH resources");
318 void QKernel::RunNetModule()
320 struct sockaddr_un svr;
324 sprintf(cmd, "%s/modules/lognet %s %s %s %s %s %s &", HomeDir,
325 NPATH, myargs[0], myargs[1], myargs[2], myargs[3], myargs[4]);
327 /* -------- socket for NET module -------- */
329 sock = socket(AF_UNIX, SOCK_STREAM, 0);
330 bzero(&svr, sizeof(svr));
331 svr.sun_family = AF_UNIX;
332 strcpy(svr.sun_path, NPATH);
333 len = strlen(svr.sun_path) + sizeof(svr.sun_family);
334 bind(sock, (struct sockaddr*)&svr, len);
337 if (system(cmd) == 0) {
338 net_sock = accept(sock, (struct sockaddr*)0, (unsigned int*)0);
341 WriteMessage("NETWORK successfully connected");
342 fcntl(net_sock, F_SETFL, O_NONBLOCK|fcntl(net_sock,
345 setsockopt(net_sock, IPPROTO_TCP, TCP_NODELAY,
346 (char*)&on, sizeof(on));
348 WriteMessage("Cannot connect NETWORK resources");
349 WriteMessage("Exiting...");
351 on_actionQuit_triggered();
355 WriteMessage("Cannot connect NETWORK resources");
356 WriteMessage("Exiting...");
358 on_actionQuit_triggered();
363 * Connects to the specified address
364 * Additional window is displayed to connect to the specified address
366 void QKernel::on_actionConnect_triggered()
368 QDialog d(this, Qt::Dialog);
369 QLabel lab("IP Address:", &d);
370 QLineEdit ed("", &d);
371 QPushButton ob("", &d);
372 QPushButton cb("", &d);
375 ob.setGeometry(30, 60, 80, 30);
378 lab.setGeometry(10, 10, 60, 30);
379 lab.setText("Address");
380 ed.setGeometry(70, 10, 140, 30);
381 cb.setGeometry(130, 60, 80, 30);
382 cb.setText("Cancel");
385 connect(&ob, SIGNAL(clicked()), &d, SLOT(accept()));
386 connect(&cb, SIGNAL(clicked()), &d, SLOT(reject()));
388 m.msg_type = MSG_NET;
389 m.param.pword[0] = NET_CONNECT_TO;
390 strcpy(m.param.pstr, ed.text().toAscii().data());
391 write(net_sock, &m, sizeof(MESSAGE));
396 * Disconnects from virtual machine
398 void QKernel::on_actionDisconnect_triggered()
403 WriteMessage("Disconnecting from virtual machine");
405 msg.msg_type = MSG_NET;
406 msg.param.pword[0] = NET_DISCONNECT;
407 write(net_sock, &msg, sizeof(MESSAGE));
411 * Quits process. Closes VLP. Shows additional window to confirm exit.
413 void QKernel::on_actionQuit_triggered()
417 QMessageBox::StandardButton response = QMessageBox::question(this,
420 QMessageBox::Ok | QMessageBox::Cancel
424 if (response == QMessageBox::Cancel) {
428 msg.msg_type = MSG_NET;
429 msg.param.pword[0] = NET_DISCONNECT;
430 write(net_sock, &msg, sizeof(MESSAGE));*/
433 msg.msg_type = MSG_NET;
434 msg.param.pword[0] = NET_EXIT;
435 write(net_sock, &msg, sizeof(MESSAGE));
436 /* ::close(net_sock);*/
437 QApplication::instance()->quit();
441 * Sends message to node.
442 * Additional window is displayed to set Node Number of node where send message,
443 * and textfield to enter message.
445 void QKernel::on_actionMessage_triggered()
451 dlg = new QDialog(this, Qt::Dialog);
452 dlg->setWindowTitle("Send message to node");
454 nodenr = new QLineEdit("number", dlg);
455 nodenr->setGeometry(90, 10, 50, 30);
459 tmpQLabel = new QLabel("Node number:", dlg);
460 tmpQLabel->setGeometry(10, 10, 77, 30);
462 tmpQLabel = new QLabel("Message:", dlg);
463 tmpQLabel->setGeometry(10, 50, 70, 30);
466 msg = new QLineEdit("", dlg);
467 msg->setGeometry(80, 60, 330, 30);
470 ob = new QPushButton("Send", dlg);
471 ob->setGeometry(230, 10, 80, 30);
472 ob->setDefault(TRUE);
475 cb = new QPushButton("Cancel", dlg);
476 cb->setGeometry(330, 10, 80, 30);
477 dlg->resize(430, 110);
478 connect(ob, SIGNAL(clicked()), dlg, SLOT(accept()));
479 connect(cb, SIGNAL(clicked()), dlg, SLOT(reject()));
482 m.msg_type = MSG_NET;
483 m.param.pword[0] = NET_PROPAGATE;
484 m.param.pword[1] = MSG_VLP;
485 m.param.pword[2] = NodeNumber;
486 m.param.pword[4] = atoi(nodenr->text().toAscii().data());
487 m.param.pword[6] = VLP_WRITE;
488 strcpy(m.param.pstr, msg->text().toAscii().data());
489 write(net_sock, &m, sizeof(MESSAGE));
495 * Additional window is displayed to get ID of interpreter which should be
498 void QKernel::on_actionKill_triggered()
505 dlg = new QDialog(this, Qt::Dialog);
506 dlg->setWindowTitle("Kill interpreter");
508 nodenr = new QLineEdit("", dlg);
509 nodenr->setGeometry(90, 10, 50, 30);
511 QLabel * tmpQLabel = new QLabel("Interp. ID:", dlg);
512 tmpQLabel->setGeometry(10, 10, 77, 30);
514 QPushButton * ob = new QPushButton("Kill", dlg);
515 ob->setGeometry( 160, 10, 80, 30);
516 ob->setDefault(TRUE);
518 QPushButton * cb = new QPushButton("Cancel", dlg);
519 cb->setGeometry(260, 10, 80, 30);
520 dlg->resize(360, 50);
522 connect(ob, SIGNAL(clicked()), dlg, SLOT(accept()));
523 connect(cb, SIGNAL(clicked()), dlg, SLOT(reject()));
526 m.msg_type = MSG_INT;
527 m.param.pword[0] = INT_KILL;
528 pom = findINTbyID(atoi(nodenr->text().toAscii().data()));
531 write(pom->sock, &m, sizeof(MESSAGE));
533 WriteMessage("This is a remote instance of "
537 WriteMessage("Interpreter not found");
543 * Sends message to the net module.
545 void QKernel::NetMessage()
548 /* TODO: It has to be rewritten */
554 cnt = read(net_sock, &msg, sizeof(MESSAGE));
555 if ((cnt > 0) && (msg.msg_type == MSG_NET)) {
556 switch(msg.param.pword[0]) {
558 WriteMessage(msg.param.pstr);
561 switch(msg.param.pword[1]) {
563 /* pom = find_link_by_ID(msg.param.pword[5]);
564 msg.msg_type = MSG_NET;
565 msg.param.pword[0] = NET_PROPAGATE;
566 send_int(pom, &msg);*/
569 switch(msg.param.pword[6]) {
571 QApplication::beep();
572 WriteMessage(CharLine);
574 "### Incoming Messsage ###");
575 sprintf(ss, "Mesg from Node %d: %s",
579 WriteMessage(CharLine);
581 case VLP_REMOTE_INSTANCE:
582 sprintf(ss, "%s/%s", REMOTE_PATH,
586 WriteMessage("Running program:");
589 pom = RunIntModule(ss, 1);
591 pom->p_ctx.node = msg.param.pword[2];
592 pom->p_ctx.program_id =
594 pom->RInstances[msg.param.pword[2]] = msg.param.pword[7];
597 case VLP_CLOSE_INSTANCE:
598 msg.msg_type = MSG_INT;
599 msg.param.pword[0] = INT_CLOSE_INSTANCE;
600 pom = findINTbyID(msg.param.pword[7]);
602 write(pom->sock, &msg,
605 m1.msg_type = MSG_VLP;
606 m1.param.pword[0] = VLP_INTERPRETER_DOWN;
607 m1.param.pword[1] = pom->ID;
611 WriteMessage("Instance not found");
617 case NET_CONNECTIONS:
618 ActiveConnections = msg.param.pword[1];
619 WriteMessage(msg.param.pstr);
624 /* TODO: It has to be rewritten */
626 QString poms, poms1, poms2;
627 poms.sprintf("%s", msg.param.pstr);
628 while (poms.length() > 0) {
629 cnt = poms.indexOf(';');
631 poms1 = poms.left(cnt);
632 poms = poms.right(poms.length() - cnt - 1);
633 cnt = poms1.indexOf('=');
635 poms2 = poms1.left(cnt);
636 poms1 = poms1.right(poms1.length() - cnt - 1);
637 sprintf(ss, "Node: %s Addr: %s", poms2.toStdString().c_str(), poms1.toStdString().c_str());
645 wait_for_info = FALSE;
646 WriteMessage(CharLine);
653 * Sends message to the interpreter program.
654 * @param sock Interpreter socket to whom the message will be send.
656 void QKernel::IntMessage(int sock)
662 cnt = read(sock, &msg, sizeof(MESSAGE));
663 e = findINTbySocket(sock);
664 if ((cnt > 0) && (e != NULL)) {
665 switch (msg.msg_type) {
667 if (msg.param.pword[0] == GRAPH_ALLOCATE) {
668 RunGraphModule(msg.param.pstr);
672 write(net_sock, &msg, sizeof(MESSAGE));
675 switch(msg.param.pword[0]) {
676 case VLP_REMOTE_INSTANCE_PLEASE:
677 RemoteInstance(e, msg.param.pword[2]);
682 switch(msg.param.pword[0]) {
687 m.msg_type = MSG_VLP;
688 m.param.pword[0] = VLP_INTERPRETER_DOWN;
689 m.param.pword[1] = e->ID;
690 write(net_sock, &m, sizeof(MESSAGE));
695 /* TODO: Check this */
696 Interpreters.removeOne(e);
700 sprintf(ss, "%s : End of program "
701 "execution", msg.param.pstr);
706 msg.msg_type = MSG_INT;
707 msg.param.pword[0] = INT_CTX;
708 msg.param.pword[1] = NodeNumber;
709 msg.param.pword[2] = e->ID;
711 msg.param.pword[3] = e->p_ctx.node;
715 write(sock, &msg, sizeof(MESSAGE));
724 * Writes message to kernel logger.
725 * @parame msg String with message to log
727 void QKernel::WriteMessage(char *msg)
731 x = desktop->textCursor().blockNumber();
732 y = desktop->textCursor().columnNumber();
738 desktop->setReadOnly(FALSE);
739 desktop->append(msg);
740 desktop->setReadOnly(TRUE);
742 QTextCursor tmpCursor = desktop->textCursor();
743 tmpCursor.movePosition(QTextCursor::End, QTextCursor::MoveAnchor);
744 desktop->setTextCursor(tmpCursor);
748 if (desktop->document()->blockCount() > 100) {
754 * Adds checkbox to menu item. If it is checked additional info messages are
757 void QKernel::on_actionInfo_messages_triggered()
759 if (toolsMenu != NULL) {
760 info_messages = !actionInfo_messages->isChecked();
761 actionInfo_messages->setChecked(info_messages);
762 fprintf(stderr, "Info is checked? %s\n", info_messages ? "yes" : "no");
767 * Allows to set options in GUI window.
768 * Additional window is displayed to set kernel options which are saved in
769 * vlp.cfg file in kernel executable directory.
771 void QKernel::on_actionOptions_triggered()
773 OptionsDialog optionsDialog(this);
774 if (optionsDialog.exec()) {
775 optionsDialog.saveConfig("vlp.cfg");
776 LoadConfig("vlp.cfg");
781 * Locks kernel program.
782 * Additional window is displayed to enter password and retype it. If both are
783 * same kernel window is locked.
785 void QKernel::on_actionLock_console_triggered()
787 LockDialog lockDialog(this);
789 if (lockDialog.exec()) {
790 QString password = lockDialog.getPassword();
791 if (lockDialog.getPassword().size() > 0) {
792 strcpy(LockPasswd, password.toAscii().data());
795 if (lockDialog.exec()) {
796 password = lockDialog.getPassword();
797 if (password == LockPasswd) {
799 WriteMessage("CONSOLE LOCKED");
801 QMessageBox msg(this);
802 msg.setText("Not matching!");
803 msg.setButtonText(0, "Close");
805 strcpy(LockPasswd, "");
808 strcpy(LockPasswd, "");
815 * Unlocks kernel program.
816 * Additional window is displayed to enter password. If it is correct, kernel
819 void QKernel::on_actionUnlock_console_triggered()
821 QDialog d(this, Qt::Dialog);
822 d.setWindowTitle("Enter password");
824 QLabel lab("Password:", &d);
825 lab.setGeometry(10, 10, 60, 30);
827 QLineEdit ed("", &d);
828 ed.setGeometry(70, 10, 140, 30);
829 ed.setEchoMode(QLineEdit::Password);
831 QPushButton ob("Ok", &d);
832 ob.setGeometry(30, 60, 80, 30);
834 connect(&ob, SIGNAL(clicked()), &d, SLOT(accept()));
836 QPushButton cb("Cancel", &d);
837 cb.setGeometry(130, 60, 80, 30);
838 connect(&cb, SIGNAL(clicked()), &d, SLOT(reject()));
843 if (strcmp(ed.text().toAscii().data(), LockPasswd) == 0) {
845 WriteMessage("CONSOLE UNLOCKED");
847 QMessageBox msg(this);
848 msg.setText("Wrong password!");
849 msg.setButtonText(0, "Close");
856 * Writes init message in kernel
858 void QKernel::InitMessage()
860 WriteMessage("\n " PACKAGE_STRING ": READY \n");
864 * Finds Interpreter by its socket
865 * @param _id ID of the socket
866 * @return returns pointer to the found interpreter slot. NULL otherwise
868 InterpEntry *QKernel::findINTbySocket(int _id)
870 InterpEntry *pom = NULL;
872 for (int i = 0; i < Interpreters.size(); i++) {
873 if (Interpreters.at(i)->sock == _id) {
874 pom = Interpreters.at(i);
883 * Finds Interpreter by its ID.
884 * @param _id ID of the interpreter
885 * @return returns pointer to the found interpreter slot. NULL otherwise
887 InterpEntry *QKernel::findINTbyID(int _id)
889 InterpEntry *pom = NULL;
891 for (int i = 0; i < Interpreters.size(); i++) {
892 if (Interpreters.at(i)->ID == _id) {
893 pom = Interpreters.at(i);
903 * Connects interpreter
904 * @param ss full filepath with filename but without extension of the loglan
906 * @param r Interpreter execution mode. 0 if it will be local instance, 1 if
908 * @return Returns pointer to newly created interpreter slot, or NULL on error.
910 InterpEntry *QKernel::RunIntModule(char *ss, int r)
913 struct sockaddr_un svr;
920 InterpEntry *newINT = NULL;
926 WriteMessage("File not found: no .ccd file");
935 WriteMessage("File not found: no .pcd file");
940 newINT = new InterpEntry;
941 for(i = 0; i < MAXINSTANCES; i++)
942 newINT->RInstances[i] =- 1;
944 strcpy(b, rindex(ss, '/'));
945 for(i = 0; i < strlen(b); i++)
948 sprintf(a, "%s : Start execution", b);
955 strcpy(newINT->shortname, b);
956 strcpy(newINT->fullname, ss);
958 sprintf(a, "%s%d", IPATH, newint);
959 sprintf(cmd, "%s/modules/logint %s %s", HomeDir, a, ss);
962 sprintf(b, " %s %s %s %s %s", myargs[0], myargs[1], myargs[2],
963 myargs[3], myargs[4]);
967 sock = socket(AF_UNIX, SOCK_STREAM, 0);
969 bzero(&svr, sizeof(svr));
970 svr.sun_family = AF_UNIX;
971 strcpy(svr.sun_path, a);
972 len = strlen(svr.sun_path)+sizeof(svr.sun_family);
973 bind(sock, (struct sockaddr*)&svr, len);
976 newINT->sock = accept(sock, (struct sockaddr*)0, (unsigned int *)0);
979 if (newINT->sock > 0) {
980 fcntl(newINT->sock, F_SETFL,
981 O_NONBLOCK|fcntl(newINT->sock, F_GETFL, 0));
983 setsockopt(newINT->sock, IPPROTO_TCP, TCP_NODELAY, (char*)&on,
990 bzero(&msg, sizeof(MESSAGE));
991 msg.msg_type = MSG_VLP;
992 msg.param.pword[0] = VLP_REGINT;
993 msg.param.pword[1] = newINT->ID;
994 sprintf(msg.param.pstr, "logi%d.net", newint);
995 write(net_sock, &msg, sizeof(MESSAGE));
997 Interpreters.append(newINT);
998 newINT->notify = new QSocketNotifier(newINT->sock,
999 QSocketNotifier::Read);
1000 connect(newINT->notify, SIGNAL(activated(int)), this,
1001 SLOT(IntMessage(int)));
1003 WriteMessage("INTERPRETER successfully connected");
1005 WriteMessage("Cannot connect interpreter");
1012 * Allocates remote instance of interpreter
1013 * @param interp Interpreter slot
1014 * @param on Node Number
1016 void QKernel::RemoteInstance(InterpEntry *interp, int on)
1021 m.msg_type = MSG_NET;
1022 m.param.pword[0] = NET_NODE_EXIST;
1023 m.param.pword[1] = on;
1024 m.param.pword[2] = interp->ID;
1025 write(net_sock, &m, sizeof(MESSAGE));
1026 bzero(&m, sizeof(MESSAGE));
1027 while((m.msg_type!=MSG_NET) && (m.param.pword[0]!=NET_NODE_EXIST))
1028 read(net_sock, &m, sizeof(MESSAGE));
1030 /* means node exists */
1031 if (m.param.pword[1] == 1) {
1032 m.msg_type = MSG_NET;
1033 m.param.pword[0] = NET_TRANSMIT_CODE;
1034 m.param.pword[1] = interp->ID;
1035 m.param.pword[2] = on;
1036 strcpy(m.param.pstr, interp->fullname);
1037 write(net_sock, &m, sizeof(MESSAGE));
1039 Net_Notify->setEnabled(FALSE);
1040 while ((m.msg_type != MSG_NET) ||
1041 (m.param.pword[0] != NET_TRANSMITTED))
1042 read(net_sock, &m, sizeof(MESSAGE));
1044 m.msg_type = MSG_NET;
1045 m.param.pword[0] = NET_PROPAGATE;
1046 m.param.pword[1] = MSG_VLP;
1047 m.param.pword[2] = NodeNumber;
1048 m.param.pword[3] = 0;
1049 m.param.pword[4] = on;
1050 m.param.pword[5] = 0;
1051 m.param.pword[6] = VLP_REMOTE_INSTANCE;
1052 m.param.pword[7] = interp->ID;
1053 strcpy(m.param.pstr, interp->shortname);
1054 write(net_sock, &m, sizeof(MESSAGE));
1056 read(net_sock, &m, sizeof(MESSAGE));
1058 if ((m.param.pword[0] == NET_PROPAGATE) &&
1059 (m.param.pword[6] == VLP_REMOTE_INSTANCE_OK)) {
1060 interp->RInstances[on] = m.param.pword[7];
1063 read(net_sock, &m, sizeof(MESSAGE));
1066 Net_Notify->setEnabled(TRUE);
1068 /*bzero(&m, sizeof(MESSAGE));*/
1069 m.msg_type = MSG_VLP;
1070 m.param.pword[0] = VLP_REMOTE_INSTANCE_HERE;
1071 m.param.pword[1] = interp->RInstances[on];
1072 write(interp->sock, &m, sizeof(MESSAGE));
1073 } else { /* There is no such a node! */
1074 sprintf(s, "Warning: Node number %d not found!", on);
1076 WriteMessage("Allocating O-process on the local node");
1077 bzero(&m, sizeof(MESSAGE));
1078 m.msg_type = MSG_VLP;
1079 m.param.pword[0] = VLP_REMOTE_INSTANCE_HERE;
1080 m.param.pword[1] = interp->ID;
1081 write(interp->sock, &m, sizeof(MESSAGE));
1086 * Closes all remote instances
1088 void QKernel::CloseInstances(InterpEntry *e)
1094 WriteMessage("Closing remote instances");
1096 for(i=0; i < MAXINSTANCES; i++)
1097 if (e->RInstances[i]>=0) {
1098 msg.msg_type = MSG_NET;
1099 msg.param.pword[0] = NET_PROPAGATE;
1100 msg.param.pword[1] = MSG_VLP;
1101 msg.param.pword[2] = NodeNumber;
1102 msg.param.pword[4] = i;
1103 msg.param.pword[6] = VLP_CLOSE_INSTANCE;
1104 msg.param.pword[7] = e->RInstances[i];
1105 write(net_sock, &msg, sizeof(MESSAGE));
1110 * Displays information about virtual machine
1112 void QKernel::on_actionInfo_triggered()
1116 WriteMessage(CharLine);
1117 WriteMessage("### Virtual Machine Information ###");
1118 m.msg_type = MSG_NET;
1119 m.param.pword[0] = NET_GET_INFO;
1120 write(net_sock, &m, sizeof(MESSAGE));
1121 wait_for_info = TRUE;
1125 * Program main function
1126 * All program arguments but the first one (argv[0]: program name) are saved and
1127 * passed to all dependent programs on their invocation.
1128 * @param argc Number of program arguments
1129 * @param argv Program arguments
1131 int main(int argc, char **argv)
1134 for(i = 0; i < 5; i++) {
1135 strcpy(myargs[i], "");
1137 for(i = 1; i < argc; i++) {
1138 strcpy(myargs[i - 1], argv[i]);
1141 QApplication * app = new QApplication(argc, argv);
1144 kernel.InitMessage();