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>
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 "send-message.h"
68 #include "kill-interpreter.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)
93 void QKernel::setLocked(bool locked)
97 actionExecute->setDisabled(locked);
98 actionKill->setDisabled(locked);
99 actionConnect->setDisabled(locked);
100 actionDisconnect->setDisabled(locked);
101 actionInfo_messages->setDisabled(locked);
102 actionMessage->setDisabled(locked);
104 /* Enable only menu entry for unlocking */
105 actionEditor->setDisabled(locked);
106 actionOptions->setDisabled(locked);
107 actionLock_Console->setDisabled(locked);
108 actionUnlock_console->setEnabled(locked);
112 * Kernel program constructor.
113 * Prepares everything to work.
115 QKernel::QKernel(QWidget *parent)
116 : QMainWindow(parent)
124 sprintf(ss, "mkdir %s", REMOTE_PATH);
128 info_messages = TRUE;
129 wait_for_info = FALSE;
131 setWindowTitle(PACKAGE_NAME);
136 ActiveConnections = 0;
137 strcpy(LockPasswd, "");
138 LoadConfig("vlp.cfg");
141 Net_Notify = new QSocketNotifier(net_sock, QSocketNotifier::Read, this);
142 connect(Net_Notify, SIGNAL(activated(int)), this, SLOT(NetMessage()));
146 * Displays window with information about not implemented functionality.
148 void QKernel::n_impl()
150 QMessageBox::information(this, "Function info", "This function is not "
151 "implemented yet...", "Ok");
155 * Loads configuration from the given file.
156 * @param fname Filename of the configuration file.
158 void QKernel::LoadConfig(char * fname)
161 config_setting_t *setting;
164 /* Hack for checking if file exists without using external libs.*/
165 FILE * file = fopen(fname, "rt");
167 fprintf(stderr, "Error: Cannot load configuration file %s!\n",
171 /* File exists, so file has been locked. Release it. */
175 /* Read the file. If there is an error, report it and exit. */
176 if (!config_read(&cfg, file)) {
177 fprintf(stderr, "%s! In file %s, line %d\n",
178 config_error_text(&cfg),
179 config_error_file(&cfg),
180 config_error_line(&cfg));
181 config_destroy(&cfg);
186 setting = config_lookup(&cfg, "node_number");
188 NodeNumber = config_setting_get_int(setting);
190 fprintf(stderr, "%s! In file %s, '%s' was not found.\n",
191 "Warning", fname, "node_number");
192 config_destroy(&cfg);
197 setting = config_lookup(&cfg, "type");
199 /* same as strcmp(..) == 0 */
200 if (!strcmp(config_setting_get_string(setting), "explicit")) {
206 fprintf(stderr, "%s! In file %s, '%s' was not found.\n",
207 "Warning", fname, "type");
210 setting = config_lookup(&cfg, "host");
212 switch(config_setting_type(setting)) {
213 /* TODO: Deprecated. Made for back compatibility. */
214 case CONFIG_TYPE_STRING:
215 ConnectList.append(new ConnectEntry((char*)
216 config_setting_get_string(setting)));
218 case CONFIG_TYPE_ARRAY: {
219 int size = config_setting_length(setting);
220 for (int i = 0; i < size; i++) {
221 ConnectList.append(new ConnectEntry((char*)
222 config_setting_get_string_elem(setting,
228 fprintf(stderr, "%s! In file %s, bad entry type for %s."
229 " Will not be read.\n",
230 "Error", fname, "host");
233 fprintf(stderr, "%s! In file %s, '%s' was not found.\n",
234 "Warning", fname, "host");
237 setting = config_lookup(&cfg, "progdir");
239 strncpy(progdir, config_setting_get_string(setting), 256);
241 fprintf(stderr, "%s! In file %s, '%s' was not found.\n",
242 "Warning", fname, "progdir");
245 setting = config_lookup(&cfg, "homedir");
247 strncpy(HomeDir, config_setting_get_string(setting), 255);
249 fprintf(stderr, "%s! In file %s, '%s' was not found.\n",
250 "Warning", fname, "homedir");
253 config_destroy(&cfg);
259 * Additional window id displayed to set which code to execute.
261 void QKernel::on_actionExecute_triggered()
264 QString s = QFileDialog::getOpenFileName(this, "Execute", progdir, "*.log");
267 i = s.indexOf(".log");
272 RunIntModule((char*)s.toAscii().data(), 0);
277 * Invokes editor program
279 void QKernel::on_actionEditor_triggered()
282 sprintf(cmd, "%s/modules/logedit %s %s %s %s %s %s &", HomeDir, HomeDir,
283 myargs[0], myargs[1], myargs[2], myargs[3], myargs[4]);
288 * Invokes help program
290 void QKernel::on_actionHelp_triggered()
293 sprintf(cmd, "%s/modules/loghelp %s/doc %s %s %s %s %s &", HomeDir,
294 HomeDir, myargs[0], myargs[1], myargs[2], myargs[3], myargs[4]);
299 * Invokes graphics module
301 void QKernel::RunGraphModule(char *sk)
305 sprintf(cmd, "%s/modules/loggraph %s %s %s %s %s %s &", HomeDir,
306 sk, myargs[0], myargs[1], myargs[2], myargs[3], myargs[4]);
308 if (system(cmd) != 0)
309 WriteMessage("Cannot connect GRAPH resources");
315 void QKernel::RunNetModule()
317 struct sockaddr_un svr;
321 sprintf(cmd, "%s/modules/lognet %s %s %s %s %s %s &", HomeDir,
322 NPATH, myargs[0], myargs[1], myargs[2], myargs[3], myargs[4]);
324 /* -------- socket for NET module -------- */
326 sock = socket(AF_UNIX, SOCK_STREAM, 0);
327 bzero(&svr, sizeof(svr));
328 svr.sun_family = AF_UNIX;
329 strcpy(svr.sun_path, NPATH);
330 len = strlen(svr.sun_path) + sizeof(svr.sun_family);
331 bind(sock, (struct sockaddr*)&svr, len);
334 if (system(cmd) == 0) {
335 net_sock = accept(sock, (struct sockaddr*)0, (unsigned int*)0);
338 WriteMessage("NETWORK successfully connected");
339 fcntl(net_sock, F_SETFL, O_NONBLOCK|fcntl(net_sock,
342 setsockopt(net_sock, IPPROTO_TCP, TCP_NODELAY,
343 (char*)&on, sizeof(on));
345 WriteMessage("Cannot connect NETWORK resources");
346 WriteMessage("Exiting...");
352 WriteMessage("Cannot connect NETWORK resources");
353 WriteMessage("Exiting...");
360 * Connects to the specified address
361 * Additional window is displayed to connect to the specified address
363 void QKernel::on_actionConnect_triggered()
365 QDialog d(this, Qt::Dialog);
366 QLabel lab("IP Address:", &d);
367 QLineEdit ed("", &d);
368 QPushButton ob("", &d);
369 QPushButton cb("", &d);
372 ob.setGeometry(30, 60, 80, 30);
375 lab.setGeometry(10, 10, 60, 30);
376 lab.setText("Address");
377 ed.setGeometry(70, 10, 140, 30);
378 cb.setGeometry(130, 60, 80, 30);
379 cb.setText("Cancel");
382 connect(&ob, SIGNAL(clicked()), &d, SLOT(accept()));
383 connect(&cb, SIGNAL(clicked()), &d, SLOT(reject()));
385 m.msg_type = MSG_NET;
386 m.param.pword[0] = NET_CONNECT_TO;
387 strcpy(m.param.pstr, ed.text().toAscii().data());
388 write(net_sock, &m, sizeof(MESSAGE));
393 * Disconnects from virtual machine
395 void QKernel::on_actionDisconnect_triggered()
400 WriteMessage("Disconnecting from virtual machine");
402 msg.msg_type = MSG_NET;
403 msg.param.pword[0] = NET_DISCONNECT;
404 write(net_sock, &msg, sizeof(MESSAGE));
408 * Quits process. Closes VLP. Shows additional window to confirm exit.
410 void QKernel::QuitProc()
414 QMessageBox::StandardButton response;
415 response = QMessageBox::question(this, "Close VLP", "Terminate VLP ?",
416 QMessageBox::Ok | QMessageBox::Cancel);
419 if (response == QMessageBox::Cancel) {
423 msg.msg_type = MSG_NET;
424 msg.param.pword[0] = NET_DISCONNECT;
425 write(net_sock, &msg, sizeof(MESSAGE));*/
428 msg.msg_type = MSG_NET;
429 msg.param.pword[0] = NET_EXIT;
430 write(net_sock, &msg, sizeof(MESSAGE));
431 /* ::close(net_sock);*/
432 QApplication::instance()->quit();
436 * Sends message to node.
437 * Additional window is displayed to set Node Number of node where send message,
438 * and textfield to enter message.
440 void QKernel::on_actionMessage_triggered()
443 SendMessageDialog *dlg;
444 dlg = new SendMessageDialog(this, Qt::Dialog);
447 m.msg_type = MSG_NET;
448 m.param.pword[0] = NET_PROPAGATE;
449 m.param.pword[1] = MSG_VLP;
450 m.param.pword[2] = NodeNumber;
451 m.param.pword[4] = dlg->getNodeNumber();
452 m.param.pword[6] = VLP_WRITE;
453 strcpy(m.param.pstr, dlg->getMessage().toAscii().data());
454 write(net_sock, &m, sizeof(MESSAGE));
460 * Additional window is displayed to get ID of interpreter which should be
463 void QKernel::on_actionKill_triggered()
467 KillInterpreterDialog *dlg;
469 dlg = new KillInterpreterDialog(this, Qt::Dialog);
472 m.msg_type = MSG_INT;
473 m.param.pword[0] = INT_KILL;
474 pom = findINTbyID(dlg->getNodeNumber());
477 write(pom->sock, &m, sizeof(MESSAGE));
479 WriteMessage("This is a remote instance of "
483 WriteMessage("Interpreter not found");
489 * Sends message to the net module.
491 void QKernel::NetMessage()
494 /* TODO: It has to be rewritten */
500 cnt = read(net_sock, &msg, sizeof(MESSAGE));
501 if ((cnt > 0) && (msg.msg_type == MSG_NET)) {
502 switch(msg.param.pword[0]) {
504 WriteMessage(msg.param.pstr);
507 switch(msg.param.pword[1]) {
509 /* pom = find_link_by_ID(msg.param.pword[5]);
510 msg.msg_type = MSG_NET;
511 msg.param.pword[0] = NET_PROPAGATE;
512 send_int(pom, &msg);*/
515 switch(msg.param.pword[6]) {
517 QApplication::beep();
518 WriteMessage(CharLine);
520 "### Incoming Messsage ###");
521 sprintf(ss, "Mesg from Node %d: %s",
525 WriteMessage(CharLine);
527 case VLP_REMOTE_INSTANCE:
528 sprintf(ss, "%s/%s", REMOTE_PATH,
532 WriteMessage("Running program:");
535 pom = RunIntModule(ss, 1);
537 pom->p_ctx.node = msg.param.pword[2];
538 pom->p_ctx.program_id =
540 pom->RInstances[msg.param.pword[2]] = msg.param.pword[7];
543 case VLP_CLOSE_INSTANCE:
544 msg.msg_type = MSG_INT;
545 msg.param.pword[0] = INT_CLOSE_INSTANCE;
546 pom = findINTbyID(msg.param.pword[7]);
548 write(pom->sock, &msg,
551 m1.msg_type = MSG_VLP;
552 m1.param.pword[0] = VLP_INTERPRETER_DOWN;
553 m1.param.pword[1] = pom->ID;
557 WriteMessage("Instance not found");
563 case NET_CONNECTIONS:
564 ActiveConnections = msg.param.pword[1];
565 WriteMessage(msg.param.pstr);
570 /* TODO: It has to be rewritten */
572 QString poms, poms1, poms2;
573 poms.sprintf("%s", msg.param.pstr);
574 while (poms.length() > 0) {
575 cnt = poms.indexOf(';');
577 poms1 = poms.left(cnt);
578 poms = poms.right(poms.length() - cnt - 1);
579 cnt = poms1.indexOf('=');
581 poms2 = poms1.left(cnt);
585 sprintf(ss, "Node: %s Addr: %s", poms2.data(), poms1.data());
593 wait_for_info = FALSE;
594 WriteMessage(CharLine);
601 * Sends message to the interpreter program.
602 * @param sock Interpreter socket to whom the message will be send.
604 void QKernel::IntMessage(int sock)
610 cnt = read(sock, &msg, sizeof(MESSAGE));
611 e = findINTbySocket(sock);
612 if ((cnt > 0) && (e != NULL)) {
613 switch (msg.msg_type) {
615 if (msg.param.pword[0] == GRAPH_ALLOCATE) {
616 RunGraphModule(msg.param.pstr);
620 write(net_sock, &msg, sizeof(MESSAGE));
623 switch(msg.param.pword[0]) {
624 case VLP_REMOTE_INSTANCE_PLEASE:
625 RemoteInstance(e, msg.param.pword[2]);
630 switch(msg.param.pword[0]) {
635 m.msg_type = MSG_VLP;
636 m.param.pword[0] = VLP_INTERPRETER_DOWN;
637 m.param.pword[1] = e->ID;
638 write(net_sock, &m, sizeof(MESSAGE));
643 /* TODO: Check this */
644 Interpreters.removeOne(e);
648 sprintf(ss, "%s : End of program "
649 "execution", msg.param.pstr);
654 msg.msg_type = MSG_INT;
655 msg.param.pword[0] = INT_CTX;
656 msg.param.pword[1] = NodeNumber;
657 msg.param.pword[2] = e->ID;
659 msg.param.pword[3] = e->p_ctx.node;
663 write(sock, &msg, sizeof(MESSAGE));
672 * Writes message to kernel logger.
673 * @parame msg String with message to log
675 void QKernel::WriteMessage(char *msg)
679 x = desktop->textCursor().blockNumber();
680 y = desktop->textCursor().columnNumber();
686 desktop->setReadOnly(FALSE);
687 desktop->append(msg);
688 desktop->setReadOnly(TRUE);
690 QTextCursor tmpCursor = desktop->textCursor();
691 tmpCursor.movePosition(QTextCursor::End, QTextCursor::MoveAnchor);
692 desktop->setTextCursor(tmpCursor);
696 if (desktop->document()->blockCount() > 100) {
702 * Adds checkbox to menu item. If it is checked additional info messages are
705 void QKernel::on_actionInfo_messages_triggered()
707 if (menuTools != NULL) {
708 info_messages = actionInfo_messages->isChecked();
713 * Allows to set options in GUI window.
714 * Additional window is displayed to set kernel options which are saved in
715 * vlp.cfg file in kernel executable directory.
717 void QKernel::on_actionOptions_triggered()
719 OptionsDialog * dlg = new OptionsDialog(this, Qt::Dialog);
721 QListWidget *connections;
724 dlg->setDefaultNodeNumber(NodeNumber);
725 dlg->setDefaultProgramsDirectory(progdir);
727 for (i = 0; i < ConnectList.size(); i++) {
728 e = ConnectList.at(i);
729 dlg->addConnection(e);
734 config_setting_t *root;
735 config_setting_t *setting;
738 root = config_root_setting(&cfg);
740 setting = config_setting_add(root, "progdir",
742 strcpy(progdir, dlg->getProgramsDirectory().toAscii().data());
743 config_setting_set_string(setting, progdir);
745 setting = config_setting_add(root, "node_number",
747 config_setting_set_int(setting, dlg->getNodeNumber());
749 setting = config_setting_add(root, "homedir",
751 config_setting_set_string(setting, HomeDir);
753 setting = config_setting_add(root, "type",
755 if (strcmp(dlg->getConnectionType().toLower().toAscii().data(),
757 config_setting_set_string(setting, "explicit");
759 config_setting_t *hosts = NULL;
760 hosts = config_setting_add(root, "host",
763 connections = dlg->getConnectionList();
764 for(i = 0; i < connections->count(); i++) {
765 setting = config_setting_add(hosts, NULL,
767 config_setting_set_string(setting,
768 connections->item(i)->text().toAscii().data());
771 config_setting_set_string(setting, "register");
774 if (!config_write_file(&cfg, "vlp.cfg")) {
775 fprintf(stderr, "Error while writing to file: %s.\n",
778 config_destroy(&cfg);
783 * Locks kernel program.
784 * Additional window is displayed to enter password and retype it. If both are
785 * same kernel window is locked.
787 void QKernel::on_actionLock_Console_triggered()
789 QDialog d(this, Qt::Dialog);
790 d.setWindowTitle("Lock console");
792 QPushButton ob("Ok", &d);
793 ob.setGeometry(30, 60, 80, 30);
795 connect(&ob, SIGNAL(clicked()), &d, SLOT(accept()));
797 QLabel lab("Password:", &d);
798 lab.setGeometry(10, 10, 60, 30);
800 QLineEdit ed("", &d);
801 ed.setGeometry(70, 10, 140, 30);
802 ed.setEchoMode(QLineEdit::Password);
804 QPushButton cb("Cancel", &d);
805 cb.setGeometry(130, 60, 80, 30);
806 connect(&cb, SIGNAL(clicked()), &d, SLOT(reject()));
811 if (strcmp(ed.text().toAscii().data(), "") != 0) {
812 strcpy(LockPasswd, ed.text().toAscii().data());
813 lab.setText("Retype:");
816 * Following exec(), could produce error:
817 * X Error: BadWindow (invalid Window parameter) 3
818 * Major opcode: 3 (X_GetWindowAttributes)
820 * This is not error in our code. Basing on:
821 * https://bugreports.qt-project.org/browse/QTBUG-1782
822 * this happens only on Qt 4.3 - 4.4.
825 if (strcmp(ed.text().toAscii().data(), LockPasswd) == 0) {
827 WriteMessage("CONSOLE LOCKED");
829 QMessageBox msg(this);
830 msg.setText("Not matching!");
831 msg.setButtonText(0, "Close");
835 strcpy(LockPasswd, "");
842 * Unlocks kernel program.
843 * Additional window is displayed to enter password. If it is correct, kernel
846 void QKernel::on_actionUnlock_console_triggered()
848 QDialog d(this, Qt::Dialog);
849 d.setWindowTitle("Enter password");
851 QLabel lab("Password:", &d);
852 lab.setGeometry(10, 10, 60, 30);
854 QLineEdit ed("", &d);
855 ed.setGeometry(70, 10, 140, 30);
856 ed.setEchoMode(QLineEdit::Password);
858 QPushButton ob("Ok", &d);
859 ob.setGeometry(30, 60, 80, 30);
861 connect(&ob, SIGNAL(clicked()), &d, SLOT(accept()));
863 QPushButton cb("Cancel", &d);
864 cb.setGeometry(130, 60, 80, 30);
865 connect(&cb, SIGNAL(clicked()), &d, SLOT(reject()));
870 if (strcmp(ed.text().toAscii().data(), LockPasswd) == 0) {
872 WriteMessage("CONSOLE UNLOCKED");
874 QMessageBox msg(this);
875 msg.setText("Wrong password!");
876 msg.setButtonText(0, "Close");
883 * Writes init message in kernel
885 void QKernel::InitMessage()
887 WriteMessage("\n " PACKAGE_STRING ": READY \n");
891 * Finds Interpreter by its socket
892 * @param _id ID of the socket
893 * @return returns pointer to the found interpreter slot. NULL otherwise
895 InterpEntry *QKernel::findINTbySocket(int _id)
897 InterpEntry *pom = NULL;
899 for (int i = 0; i < Interpreters.size(); i++) {
900 if (Interpreters.at(i)->sock == _id) {
901 pom = Interpreters.at(i);
910 * Finds Interpreter by its ID.
911 * @param _id ID of the interpreter
912 * @return returns pointer to the found interpreter slot. NULL otherwise
914 InterpEntry *QKernel::findINTbyID(int _id)
916 InterpEntry *pom = NULL;
918 for (int i = 0; i < Interpreters.size(); i++) {
919 if (Interpreters.at(i)->ID == _id) {
920 pom = Interpreters.at(i);
930 * Connects interpreter
931 * @param ss full filepath with filename but without extension of the loglan
933 * @param r Interpreter execution mode. 0 if it will be local instance, 1 if
935 * @return Returns pointer to newly created interpreter slot, or NULL on error.
937 InterpEntry *QKernel::RunIntModule(char *ss, int r)
940 struct sockaddr_un svr;
941 int len, sock, i, on;
946 InterpEntry *newINT = NULL;
952 WriteMessage("File not found: no .ccd file");
961 WriteMessage("File not found: no .pcd file");
966 newINT = new InterpEntry;
967 for(i = 0; i < MAXINSTANCES; i++)
968 newINT->RInstances[i] =- 1;
970 strcpy(b, rindex(ss, '/'));
971 for(i = 0; i < strlen(b); i++)
974 sprintf(a, "%s : Start execution", b);
981 strcpy(newINT->shortname, b);
982 strcpy(newINT->fullname, ss);
984 sprintf(a, "%s%d", IPATH, newint);
985 sprintf(cmd, "%s/modules/logint %s %s", HomeDir, a, ss);
988 sprintf(b, " %s %s %s %s %s", myargs[0], myargs[1], myargs[2],
989 myargs[3], myargs[4]);
993 sock = socket(AF_UNIX, SOCK_STREAM, 0);
995 bzero(&svr, sizeof(svr));
996 svr.sun_family = AF_UNIX;
997 strcpy(svr.sun_path, a);
998 len = strlen(svr.sun_path)+sizeof(svr.sun_family);
999 bind(sock, (struct sockaddr*)&svr, len);
1002 newINT->sock = accept(sock, (struct sockaddr*)0, (unsigned int *)0);
1005 if (newINT->sock > 0) {
1006 fcntl(newINT->sock, F_SETFL,
1007 O_NONBLOCK|fcntl(newINT->sock, F_GETFL, 0));
1009 setsockopt(newINT->sock, IPPROTO_TCP, TCP_NODELAY, (char*)&on,
1016 bzero(&msg, sizeof(MESSAGE));
1017 msg.msg_type = MSG_VLP;
1018 msg.param.pword[0] = VLP_REGINT;
1019 msg.param.pword[1] = newINT->ID;
1020 sprintf(msg.param.pstr, "logi%d.net", newint);
1021 write(net_sock, &msg, sizeof(MESSAGE));
1023 Interpreters.append(newINT);
1024 newINT->notify = new QSocketNotifier(newINT->sock,
1025 QSocketNotifier::Read);
1026 connect(newINT->notify, SIGNAL(activated(int)), this,
1027 SLOT(IntMessage(int)));
1029 WriteMessage("INTERPRETER successfully connected");
1031 WriteMessage("Cannot connect interpreter");
1038 * Allocates remote instance of interpreter
1039 * @param interp Interpreter slot
1040 * @param on Node Number
1042 void QKernel::RemoteInstance(InterpEntry *interp, int on)
1047 m.msg_type = MSG_NET;
1048 m.param.pword[0] = NET_NODE_EXIST;
1049 m.param.pword[1] = on;
1050 m.param.pword[2] = interp->ID;
1051 write(net_sock, &m, sizeof(MESSAGE));
1052 bzero(&m, sizeof(MESSAGE));
1053 while((m.msg_type!=MSG_NET) && (m.param.pword[0]!=NET_NODE_EXIST))
1054 read(net_sock, &m, sizeof(MESSAGE));
1056 /* means node exists */
1057 if (m.param.pword[1] == 1) {
1058 m.msg_type = MSG_NET;
1059 m.param.pword[0] = NET_TRANSMIT_CODE;
1060 m.param.pword[1] = interp->ID;
1061 m.param.pword[2] = on;
1062 strcpy(m.param.pstr, interp->fullname);
1063 write(net_sock, &m, sizeof(MESSAGE));
1065 Net_Notify->setEnabled(FALSE);
1066 while ((m.msg_type != MSG_NET) ||
1067 (m.param.pword[0] != NET_TRANSMITTED))
1068 read(net_sock, &m, sizeof(MESSAGE));
1070 m.msg_type = MSG_NET;
1071 m.param.pword[0] = NET_PROPAGATE;
1072 m.param.pword[1] = MSG_VLP;
1073 m.param.pword[2] = NodeNumber;
1074 m.param.pword[3] = 0;
1075 m.param.pword[4] = on;
1076 m.param.pword[5] = 0;
1077 m.param.pword[6] = VLP_REMOTE_INSTANCE;
1078 m.param.pword[7] = interp->ID;
1079 strcpy(m.param.pstr, interp->shortname);
1080 write(net_sock, &m, sizeof(MESSAGE));
1082 read(net_sock, &m, sizeof(MESSAGE));
1084 if ((m.param.pword[0] == NET_PROPAGATE) &&
1085 (m.param.pword[6] == VLP_REMOTE_INSTANCE_OK)) {
1086 interp->RInstances[on] = m.param.pword[7];
1089 read(net_sock, &m, sizeof(MESSAGE));
1092 Net_Notify->setEnabled(TRUE);
1094 /*bzero(&m, sizeof(MESSAGE));*/
1095 m.msg_type = MSG_VLP;
1096 m.param.pword[0] = VLP_REMOTE_INSTANCE_HERE;
1097 m.param.pword[1] = interp->RInstances[on];
1098 write(interp->sock, &m, sizeof(MESSAGE));
1099 } else { /* There is no such a node! */
1100 sprintf(s, "Warning: Node number %d not found!", on);
1102 WriteMessage("Allocating O-process on the local node");
1103 bzero(&m, sizeof(MESSAGE));
1104 m.msg_type = MSG_VLP;
1105 m.param.pword[0] = VLP_REMOTE_INSTANCE_HERE;
1106 m.param.pword[1] = interp->ID;
1107 write(interp->sock, &m, sizeof(MESSAGE));
1112 * Closes all remote instances
1114 void QKernel::CloseInstances(InterpEntry *e)
1120 WriteMessage("Closing remote instances");
1122 for(i=0; i < MAXINSTANCES; i++)
1123 if (e->RInstances[i]>=0) {
1124 msg.msg_type = MSG_NET;
1125 msg.param.pword[0] = NET_PROPAGATE;
1126 msg.param.pword[1] = MSG_VLP;
1127 msg.param.pword[2] = NodeNumber;
1128 msg.param.pword[4] = i;
1129 msg.param.pword[6] = VLP_CLOSE_INSTANCE;
1130 msg.param.pword[7] = e->RInstances[i];
1131 write(net_sock, &msg, sizeof(MESSAGE));
1136 * Displays information about virtual machine
1138 void QKernel::on_actionInfo_triggered()
1142 WriteMessage(CharLine);
1143 WriteMessage("### Virtual Machine Information ###");
1144 m.msg_type = MSG_NET;
1145 m.param.pword[0] = NET_GET_INFO;
1146 write(net_sock, &m, sizeof(MESSAGE));
1147 wait_for_info = TRUE;
1151 * Program main function
1152 * All program arguments but the first one (argv[0]: program name) are saved and
1153 * passed to all dependent programs on their invocation.
1154 * @param argc Number of program arguments
1155 * @param argv Program arguments
1157 int main(int argc, char **argv)
1160 for(i = 0; i < 5; i++) {
1161 strcpy(myargs[i], "");
1163 for(i = 1; i < argc; i++) {
1164 strcpy(myargs[i - 1], argv[i]);
1167 QApplication * app = new QApplication(argc, argv);
1172 kernel.InitMessage();