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"
70 /* File resides in top directory (where are Makefiles)*/
71 #include "../../config.h"
74 char CharLine[25] = "________________________";
80 * Event invoked on program close.
81 * Closes application. Displays additional window to confirm exit.
83 void QKernel::closeEvent(QCloseEvent * e)
92 void QKernel::setLocked(bool locked)
96 actionExecute->setDisabled(locked);
97 actionKill->setDisabled(locked);
98 actionConnect->setDisabled(locked);
99 actionDisconnect->setDisabled(locked);
100 actionInfo_messages->setDisabled(locked);
101 actionMessage->setDisabled(locked);
103 /* Enable only menu entry for unlocking */
104 actionEditor->setDisabled(locked);
105 actionOptions->setDisabled(locked);
106 actionLock_Console->setDisabled(locked);
107 actionUnlock_console->setEnabled(locked);
111 * Kernel program constructor.
112 * Prepares everything to work.
114 QKernel::QKernel(QWidget *parent)
115 : QMainWindow(parent)
123 sprintf(ss, "mkdir %s", REMOTE_PATH);
127 info_messages = TRUE;
128 wait_for_info = FALSE;
130 setWindowTitle(PACKAGE_NAME);
135 ActiveConnections = 0;
136 strcpy(LockPasswd, "");
137 LoadConfig("vlp.cfg");
140 Net_Notify = new QSocketNotifier(net_sock, QSocketNotifier::Read, this);
141 connect(Net_Notify, SIGNAL(activated(int)), this, SLOT(NetMessage()));
145 * Displays window with information about not implemented functionality.
147 void QKernel::n_impl()
149 QMessageBox::information(this, "Function info", "This function is not "
150 "implemented yet...", "Ok");
154 * Loads configuration from the given file.
155 * @param fname Filename of the configuration file.
157 void QKernel::LoadConfig(char * fname)
160 config_setting_t *setting;
163 /* Hack for checking if file exists without using external libs.*/
164 FILE * file = fopen(fname, "rt");
166 fprintf(stderr, "Error: Cannot load configuration file %s!\n",
170 /* File exists, so file has been locked. Release it. */
174 /* Read the file. If there is an error, report it and exit. */
175 if (!config_read(&cfg, file)) {
176 fprintf(stderr, "%s! In file %s, line %d\n",
177 config_error_text(&cfg),
178 config_error_file(&cfg),
179 config_error_line(&cfg));
180 config_destroy(&cfg);
185 setting = config_lookup(&cfg, "node_number");
187 NodeNumber = config_setting_get_int(setting);
189 fprintf(stderr, "%s! In file %s, '%s' was not found.\n",
190 "Warning", fname, "node_number");
191 config_destroy(&cfg);
196 setting = config_lookup(&cfg, "type");
198 /* same as strcmp(..) == 0 */
199 if (!strcmp(config_setting_get_string(setting), "explicit")) {
205 fprintf(stderr, "%s! In file %s, '%s' was not found.\n",
206 "Warning", fname, "type");
209 setting = config_lookup(&cfg, "host");
211 switch(config_setting_type(setting)) {
212 /* TODO: Deprecated. Made for back compatibility. */
213 case CONFIG_TYPE_STRING:
214 ConnectList.append(new ConnectEntry((char*)
215 config_setting_get_string(setting)));
217 case CONFIG_TYPE_ARRAY: {
218 int size = config_setting_length(setting);
219 for (int i = 0; i < size; i++) {
220 ConnectList.append(new ConnectEntry((char*)
221 config_setting_get_string_elem(setting,
227 fprintf(stderr, "%s! In file %s, bad entry type for %s."
228 " Will not be read.\n",
229 "Error", fname, "host");
232 fprintf(stderr, "%s! In file %s, '%s' was not found.\n",
233 "Warning", fname, "host");
236 setting = config_lookup(&cfg, "progdir");
238 strncpy(progdir, config_setting_get_string(setting), 256);
240 fprintf(stderr, "%s! In file %s, '%s' was not found.\n",
241 "Warning", fname, "progdir");
244 setting = config_lookup(&cfg, "homedir");
246 strncpy(HomeDir, config_setting_get_string(setting), 255);
248 fprintf(stderr, "%s! In file %s, '%s' was not found.\n",
249 "Warning", fname, "homedir");
252 config_destroy(&cfg);
258 * Additional window id displayed to set which code to execute.
260 void QKernel::on_actionExecute_triggered()
263 QString s = QFileDialog::getOpenFileName(this, "Execute", progdir, "*.log");
266 i = s.indexOf(".log");
271 RunIntModule((char*)s.toAscii().data(), 0);
276 * Invokes editor program
278 void QKernel::on_actionEditor_triggered()
281 sprintf(cmd, "%s/modules/logedit %s %s %s %s %s %s &", HomeDir, HomeDir,
282 myargs[0], myargs[1], myargs[2], myargs[3], myargs[4]);
287 * Invokes help program
289 void QKernel::on_actionHelp_triggered()
292 sprintf(cmd, "%s/modules/loghelp %s/doc %s %s %s %s %s &", HomeDir,
293 HomeDir, myargs[0], myargs[1], myargs[2], myargs[3], myargs[4]);
298 * Invokes graphics module
300 void QKernel::RunGraphModule(char *sk)
304 sprintf(cmd, "%s/modules/loggraph %s %s %s %s %s %s &", HomeDir,
305 sk, myargs[0], myargs[1], myargs[2], myargs[3], myargs[4]);
307 if (system(cmd) != 0)
308 WriteMessage("Cannot connect GRAPH resources");
314 void QKernel::RunNetModule()
316 struct sockaddr_un svr;
320 sprintf(cmd, "%s/modules/lognet %s %s %s %s %s %s &", HomeDir,
321 NPATH, myargs[0], myargs[1], myargs[2], myargs[3], myargs[4]);
323 /* -------- socket for NET module -------- */
325 sock = socket(AF_UNIX, SOCK_STREAM, 0);
326 bzero(&svr, sizeof(svr));
327 svr.sun_family = AF_UNIX;
328 strcpy(svr.sun_path, NPATH);
329 len = strlen(svr.sun_path) + sizeof(svr.sun_family);
330 bind(sock, (struct sockaddr*)&svr, len);
333 if (system(cmd) == 0) {
334 net_sock = accept(sock, (struct sockaddr*)0, (unsigned int*)0);
337 WriteMessage("NETWORK successfully connected");
338 fcntl(net_sock, F_SETFL, O_NONBLOCK|fcntl(net_sock,
341 setsockopt(net_sock, IPPROTO_TCP, TCP_NODELAY,
342 (char*)&on, sizeof(on));
344 WriteMessage("Cannot connect NETWORK resources");
345 WriteMessage("Exiting...");
351 WriteMessage("Cannot connect NETWORK resources");
352 WriteMessage("Exiting...");
359 * Connects to the specified address
360 * Additional window is displayed to connect to the specified address
362 void QKernel::on_actionConnect_triggered()
364 QDialog d(this, Qt::Dialog);
365 QLabel lab("IP Address:", &d);
366 QLineEdit ed("", &d);
367 QPushButton ob("", &d);
368 QPushButton cb("", &d);
371 ob.setGeometry(30, 60, 80, 30);
374 lab.setGeometry(10, 10, 60, 30);
375 lab.setText("Address");
376 ed.setGeometry(70, 10, 140, 30);
377 cb.setGeometry(130, 60, 80, 30);
378 cb.setText("Cancel");
381 connect(&ob, SIGNAL(clicked()), &d, SLOT(accept()));
382 connect(&cb, SIGNAL(clicked()), &d, SLOT(reject()));
384 m.msg_type = MSG_NET;
385 m.param.pword[0] = NET_CONNECT_TO;
386 strcpy(m.param.pstr, ed.text().toAscii().data());
387 write(net_sock, &m, sizeof(MESSAGE));
392 * Disconnects from virtual machine
394 void QKernel::on_actionDisconnect_triggered()
399 WriteMessage("Disconnecting from virtual machine");
401 msg.msg_type = MSG_NET;
402 msg.param.pword[0] = NET_DISCONNECT;
403 write(net_sock, &msg, sizeof(MESSAGE));
407 * Quits process. Closes VLP. Shows additional window to confirm exit.
409 void QKernel::QuitProc()
413 QMessageBox::StandardButton response;
414 response = QMessageBox::question(this, "Close VLP", "Terminate VLP ?",
415 QMessageBox::Ok | QMessageBox::Cancel);
418 if (response == QMessageBox::Cancel) {
422 msg.msg_type = MSG_NET;
423 msg.param.pword[0] = NET_DISCONNECT;
424 write(net_sock, &msg, sizeof(MESSAGE));*/
427 msg.msg_type = MSG_NET;
428 msg.param.pword[0] = NET_EXIT;
429 write(net_sock, &msg, sizeof(MESSAGE));
430 /* ::close(net_sock);*/
431 QApplication::instance()->quit();
435 * Adds IP address to the configuration.
436 * Additional window is displayed to add address to the list
438 void QKernel::AddAddress()
440 QDialog d(this, Qt::Dialog);
441 QLabel lab("IP Address:", &d);
442 QLineEdit ed("", &d);
443 QPushButton ob("", &d);
444 QPushButton cb("", &d);
447 ob.setGeometry(30, 60, 80, 30);
450 lab.setGeometry(10, 10, 60, 30);
451 lab.setText("Address");
452 ed.setGeometry(70, 10, 140, 30);
453 cb.setGeometry(130, 60, 80, 30);
454 cb.setText("Cancel");
456 connect(&ob, SIGNAL(clicked()), &d, SLOT(accept()));
457 connect(&cb, SIGNAL(clicked()), &d, SLOT(reject()));
459 if (strcmp(ed.text().toAscii().data(), "") != 0) {
460 connections->addItem(ed.text());
466 * Deletes current address from available connections.
468 void QKernel::DelAddress()
471 if (connections->currentRow() != -1) {
472 /* TODO: Checki if this work correctly after porting */
473 connections->removeItemWidget(connections->currentItem());
479 * Sends message to node.
480 * Additional window is displayed to set Node Number of node where send message,
481 * and textfield to enter message.
483 void QKernel::on_actionMessage_triggered()
486 SendMessageDialog *dlg;
487 dlg = new SendMessageDialog(this, Qt::Dialog);
490 m.msg_type = MSG_NET;
491 m.param.pword[0] = NET_PROPAGATE;
492 m.param.pword[1] = MSG_VLP;
493 m.param.pword[2] = NodeNumber;
494 m.param.pword[4] = dlg->getNodeNumber();
495 m.param.pword[6] = VLP_WRITE;
496 strcpy(m.param.pstr, dlg->getMessage().toAscii().data());
497 write(net_sock, &m, sizeof(MESSAGE));
503 * Additional window is displayed to get ID of interpreter which should be
506 void QKernel::on_actionKill_triggered()
510 KillInterpreterDialog *dlg;
512 dlg = new KillInterpreterDialog(this, Qt::Dialog);
515 m.msg_type = MSG_INT;
516 m.param.pword[0] = INT_KILL;
517 pom = findINTbyID(dlg->getNodeNumber());
520 write(pom->sock, &m, sizeof(MESSAGE));
522 WriteMessage("This is a remote instance of "
526 WriteMessage("Interpreter not found");
532 * Sends message to the net module.
534 void QKernel::NetMessage()
537 /* TODO: It has to be rewritten */
543 cnt = read(net_sock, &msg, sizeof(MESSAGE));
544 if ((cnt > 0) && (msg.msg_type == MSG_NET)) {
545 switch(msg.param.pword[0]) {
547 WriteMessage(msg.param.pstr);
550 switch(msg.param.pword[1]) {
552 /* pom = find_link_by_ID(msg.param.pword[5]);
553 msg.msg_type = MSG_NET;
554 msg.param.pword[0] = NET_PROPAGATE;
555 send_int(pom, &msg);*/
558 switch(msg.param.pword[6]) {
560 QApplication::beep();
561 WriteMessage(CharLine);
563 "### Incoming Messsage ###");
564 sprintf(ss, "Mesg from Node %d: %s",
568 WriteMessage(CharLine);
570 case VLP_REMOTE_INSTANCE:
571 sprintf(ss, "%s/%s", REMOTE_PATH,
575 WriteMessage("Running program:");
578 pom = RunIntModule(ss, 1);
580 pom->p_ctx.node = msg.param.pword[2];
581 pom->p_ctx.program_id =
583 pom->RInstances[msg.param.pword[2]] = msg.param.pword[7];
586 case VLP_CLOSE_INSTANCE:
587 msg.msg_type = MSG_INT;
588 msg.param.pword[0] = INT_CLOSE_INSTANCE;
589 pom = findINTbyID(msg.param.pword[7]);
591 write(pom->sock, &msg,
594 m1.msg_type = MSG_VLP;
595 m1.param.pword[0] = VLP_INTERPRETER_DOWN;
596 m1.param.pword[1] = pom->ID;
600 WriteMessage("Instance not found");
606 case NET_CONNECTIONS:
607 ActiveConnections = msg.param.pword[1];
608 WriteMessage(msg.param.pstr);
613 /* TODO: It has to be rewritten */
615 QString poms, poms1, poms2;
616 poms.sprintf("%s", msg.param.pstr);
617 while (poms.length() > 0) {
618 cnt = poms.indexOf(';');
620 poms1 = poms.left(cnt);
621 poms = poms.right(poms.length() - cnt - 1);
622 cnt = poms1.indexOf('=');
624 poms2 = poms1.left(cnt);
628 sprintf(ss, "Node: %s Addr: %s", poms2.data(), poms1.data());
636 wait_for_info = FALSE;
637 WriteMessage(CharLine);
644 * Sends message to the interpreter program.
645 * @param sock Interpreter socket to whom the message will be send.
647 void QKernel::IntMessage(int sock)
653 cnt = read(sock, &msg, sizeof(MESSAGE));
654 e = findINTbySocket(sock);
655 if ((cnt > 0) && (e != NULL)) {
656 switch (msg.msg_type) {
658 if (msg.param.pword[0] == GRAPH_ALLOCATE) {
659 RunGraphModule(msg.param.pstr);
663 write(net_sock, &msg, sizeof(MESSAGE));
666 switch(msg.param.pword[0]) {
667 case VLP_REMOTE_INSTANCE_PLEASE:
668 RemoteInstance(e, msg.param.pword[2]);
673 switch(msg.param.pword[0]) {
678 m.msg_type = MSG_VLP;
679 m.param.pword[0] = VLP_INTERPRETER_DOWN;
680 m.param.pword[1] = e->ID;
681 write(net_sock, &m, sizeof(MESSAGE));
686 /* TODO: Check this */
687 Interpreters.removeOne(e);
691 sprintf(ss, "%s : End of program "
692 "execution", msg.param.pstr);
697 msg.msg_type = MSG_INT;
698 msg.param.pword[0] = INT_CTX;
699 msg.param.pword[1] = NodeNumber;
700 msg.param.pword[2] = e->ID;
702 msg.param.pword[3] = e->p_ctx.node;
706 write(sock, &msg, sizeof(MESSAGE));
715 * Writes message to kernel logger.
716 * @parame msg String with message to log
718 void QKernel::WriteMessage(char *msg)
722 x = desktop->textCursor().blockNumber();
723 y = desktop->textCursor().columnNumber();
729 desktop->setReadOnly(FALSE);
730 desktop->append(msg);
731 desktop->setReadOnly(TRUE);
733 QTextCursor tmpCursor = desktop->textCursor();
734 tmpCursor.movePosition(QTextCursor::End, QTextCursor::MoveAnchor);
735 desktop->setTextCursor(tmpCursor);
739 if (desktop->document()->blockCount() > 100) {
745 * Adds checkbox to menu item. If it is checked additional info messages are
748 void QKernel::on_actionInfo_messages_triggered()
750 if (menuTools != NULL) {
751 info_messages = actionInfo_messages->isChecked();
756 * Allows to set options in GUI window.
757 * Additional window is displayed to set kernel options which are saved in
758 * vlp.cfg file in kernel executable directory.
760 void QKernel::on_actionOptions_triggered()
762 QDialog dlg(this, Qt::Dialog);
763 dlg.setWindowTitle("Options");
768 progs = new QLineEdit(progdir, &dlg);
769 progs->setGeometry(150, 20, 180, 30);
772 tmpQLabel = new QLabel("Programs directory", &dlg);
773 tmpQLabel->setGeometry(30, 20, 120, 30);
776 tmpQFrame = new QFrame(&dlg);
777 tmpQFrame->setGeometry(10, 60, 380, 30);
778 tmpQFrame->setFrameStyle(52);
780 tmpQLabel = new QLabel("Virtual Processor properties (activated after "
781 "restarting VLP):", &dlg);
782 tmpQLabel->setGeometry(10, 80, 340, 30);
786 sprintf(nns, "%d", NodeNumber);
787 nn = new QLineEdit(nns, &dlg);
788 nn->setGeometry(110, 110, 40, 30);
790 tmpQLabel = new QLabel("Node number:", &dlg);
791 tmpQLabel->setGeometry(20, 110, 90, 30);
793 QRadioButton *exp, *reg;
794 exp = new QRadioButton("Explicit", &dlg);
795 exp->setGeometry(30, 170, 100, 30);
796 exp->setChecked(TRUE);
798 reg = new QRadioButton("Registration", &dlg);
799 reg->setGeometry(30, 200, 100, 30);
800 reg->setEnabled(FALSE);
802 connections = new QListWidget(&dlg);
803 connections->setGeometry(170, 140, 130, 100);
805 for (int i = 0; i < ConnectList.size(); i++) {
806 e = ConnectList.at(i);
807 connections->addItem(e->addr);
810 tmpQLabel = new QLabel("Connection list:", &dlg);
811 tmpQLabel->setGeometry(170, 110, 100, 30);
816 QPushButton *cancelbtn;
817 addbtn = new QPushButton("Add", &dlg);
818 addbtn->setGeometry(310, 150, 60, 30);
819 connect(addbtn, SIGNAL(clicked()), this, SLOT(AddAddress()));
821 delbtn = new QPushButton("Del", &dlg);
822 delbtn->setGeometry(310, 200, 60, 30);
823 connect(delbtn, SIGNAL(clicked()), this, SLOT(DelAddress()));
825 okbtn = new QPushButton("Ok", &dlg);
826 okbtn->setGeometry(80, 260, 100, 30);
827 okbtn->setDefault(TRUE);
828 connect(okbtn, SIGNAL(clicked()), &dlg, SLOT(accept()));
830 cancelbtn = new QPushButton("Cancel", &dlg);
831 cancelbtn->setGeometry(210, 260, 100, 30);
832 connect(cancelbtn, SIGNAL(clicked()), &dlg, SLOT(reject()));
835 group = new QGroupBox("Connection type", &dlg);
836 group->setGeometry(20, 150, 120, 90);
837 group->setAlignment(Qt::AlignLeft);
840 QVBoxLayout *vbox = new QVBoxLayout();
841 vbox->addWidget(exp);
842 vbox->addWidget(reg);
844 group->setLayout(vbox);
846 dlg.resize(400, 310);
849 config_setting_t *root;
850 config_setting_t *setting;
853 root = config_root_setting(&cfg);
855 setting = config_setting_add(root, "progdir",
857 config_setting_set_string(setting, progs->text().toAscii().data());
858 strcpy(progdir, progs->text().toAscii().data());
860 setting = config_setting_add(root, "node_number",
862 config_setting_set_int(setting, atoi(nn->text().toAscii().data()));
864 setting = config_setting_add(root, "homedir",
866 config_setting_set_string(setting, HomeDir);
868 setting = config_setting_add(root, "type",
870 if (exp->isChecked()) {
871 config_setting_set_string(setting, "explicit");
873 config_setting_t *hosts = NULL;
874 hosts = config_setting_add(root, "host",
876 for(i = 0; i < connections->count(); i++) {
877 setting = config_setting_add(hosts, NULL,
879 config_setting_set_string(setting,
880 connections->item(i)->text().toAscii().data());
883 config_setting_set_string(setting, "register");
886 if (!config_write_file(&cfg, "vlp.cfg")) {
887 fprintf(stderr, "Error while writing to file: %s.\n",
890 config_destroy(&cfg);
895 * Locks kernel program.
896 * Additional window is displayed to enter password and retype it. If both are
897 * same kernel window is locked.
899 void QKernel::on_actionLock_Console_triggered()
901 QDialog d(this, Qt::Dialog);
902 d.setWindowTitle("Lock console");
904 QPushButton ob("Ok", &d);
905 ob.setGeometry(30, 60, 80, 30);
907 connect(&ob, SIGNAL(clicked()), &d, SLOT(accept()));
909 QLabel lab("Password:", &d);
910 lab.setGeometry(10, 10, 60, 30);
912 QLineEdit ed("", &d);
913 ed.setGeometry(70, 10, 140, 30);
914 ed.setEchoMode(QLineEdit::Password);
916 QPushButton cb("Cancel", &d);
917 cb.setGeometry(130, 60, 80, 30);
918 connect(&cb, SIGNAL(clicked()), &d, SLOT(reject()));
923 if (strcmp(ed.text().toAscii().data(), "") != 0) {
924 strcpy(LockPasswd, ed.text().toAscii().data());
925 lab.setText("Retype:");
928 * Following exec(), could produce error:
929 * X Error: BadWindow (invalid Window parameter) 3
930 * Major opcode: 3 (X_GetWindowAttributes)
932 * This is not error in our code. Basing on:
933 * https://bugreports.qt-project.org/browse/QTBUG-1782
934 * this happens only on Qt 4.3 - 4.4.
937 if (strcmp(ed.text().toAscii().data(), LockPasswd) == 0) {
939 WriteMessage("CONSOLE LOCKED");
941 QMessageBox msg(this);
942 msg.setText("Not matching!");
943 msg.setButtonText(0, "Close");
947 strcpy(LockPasswd, "");
954 * Unlocks kernel program.
955 * Additional window is displayed to enter password. If it is correct, kernel
958 void QKernel::on_actionUnlock_console_triggered()
960 QDialog d(this, Qt::Dialog);
961 d.setWindowTitle("Enter password");
963 QLabel lab("Password:", &d);
964 lab.setGeometry(10, 10, 60, 30);
966 QLineEdit ed("", &d);
967 ed.setGeometry(70, 10, 140, 30);
968 ed.setEchoMode(QLineEdit::Password);
970 QPushButton ob("Ok", &d);
971 ob.setGeometry(30, 60, 80, 30);
973 connect(&ob, SIGNAL(clicked()), &d, SLOT(accept()));
975 QPushButton cb("Cancel", &d);
976 cb.setGeometry(130, 60, 80, 30);
977 connect(&cb, SIGNAL(clicked()), &d, SLOT(reject()));
982 if (strcmp(ed.text().toAscii().data(), LockPasswd) == 0) {
984 WriteMessage("CONSOLE UNLOCKED");
986 QMessageBox msg(this);
987 msg.setText("Wrong password!");
988 msg.setButtonText(0, "Close");
995 * Writes init message in kernel
997 void QKernel::InitMessage()
999 WriteMessage("\n " PACKAGE_STRING ": READY \n");
1003 * Finds Interpreter by its socket
1004 * @param _id ID of the socket
1005 * @return returns pointer to the found interpreter slot. NULL otherwise
1007 InterpEntry *QKernel::findINTbySocket(int _id)
1009 InterpEntry *pom = NULL;
1011 for (int i = 0; i < Interpreters.size(); i++) {
1012 if (Interpreters.at(i)->sock == _id) {
1013 pom = Interpreters.at(i);
1022 * Finds Interpreter by its ID.
1023 * @param _id ID of the interpreter
1024 * @return returns pointer to the found interpreter slot. NULL otherwise
1026 InterpEntry *QKernel::findINTbyID(int _id)
1028 InterpEntry *pom = NULL;
1030 for (int i = 0; i < Interpreters.size(); i++) {
1031 if (Interpreters.at(i)->ID == _id) {
1032 pom = Interpreters.at(i);
1042 * Connects interpreter
1043 * @param ss full filepath with filename but without extension of the loglan
1045 * @param r Interpreter execution mode. 0 if it will be local instance, 1 if
1047 * @return Returns pointer to newly created interpreter slot, or NULL on error.
1049 InterpEntry *QKernel::RunIntModule(char *ss, int r)
1051 char a[256], b[255];
1052 struct sockaddr_un svr;
1053 int len, sock, i, on;
1058 InterpEntry *newINT = NULL;
1064 WriteMessage("File not found: no .ccd file");
1073 WriteMessage("File not found: no .pcd file");
1078 newINT = new InterpEntry;
1079 for(i = 0; i < MAXINSTANCES; i++)
1080 newINT->RInstances[i] =- 1;
1082 strcpy(b, rindex(ss, '/'));
1083 for(i = 0; i < strlen(b); i++)
1085 if (info_messages) {
1086 sprintf(a, "%s : Start execution", b);
1092 newINT->ID = newint;
1093 strcpy(newINT->shortname, b);
1094 strcpy(newINT->fullname, ss);
1096 sprintf(a, "%s%d", IPATH, newint);
1097 sprintf(cmd, "%s/modules/logint %s %s", HomeDir, a, ss);
1100 sprintf(b, " %s %s %s %s %s", myargs[0], myargs[1], myargs[2],
1101 myargs[3], myargs[4]);
1105 sock = socket(AF_UNIX, SOCK_STREAM, 0);
1107 bzero(&svr, sizeof(svr));
1108 svr.sun_family = AF_UNIX;
1109 strcpy(svr.sun_path, a);
1110 len = strlen(svr.sun_path)+sizeof(svr.sun_family);
1111 bind(sock, (struct sockaddr*)&svr, len);
1114 newINT->sock = accept(sock, (struct sockaddr*)0, (unsigned int *)0);
1117 if (newINT->sock > 0) {
1118 fcntl(newINT->sock, F_SETFL,
1119 O_NONBLOCK|fcntl(newINT->sock, F_GETFL, 0));
1121 setsockopt(newINT->sock, IPPROTO_TCP, TCP_NODELAY, (char*)&on,
1128 bzero(&msg, sizeof(MESSAGE));
1129 msg.msg_type = MSG_VLP;
1130 msg.param.pword[0] = VLP_REGINT;
1131 msg.param.pword[1] = newINT->ID;
1132 sprintf(msg.param.pstr, "logi%d.net", newint);
1133 write(net_sock, &msg, sizeof(MESSAGE));
1135 Interpreters.append(newINT);
1136 newINT->notify = new QSocketNotifier(newINT->sock,
1137 QSocketNotifier::Read);
1138 connect(newINT->notify, SIGNAL(activated(int)), this,
1139 SLOT(IntMessage(int)));
1141 WriteMessage("INTERPRETER successfully connected");
1143 WriteMessage("Cannot connect interpreter");
1150 * Allocates remote instance of interpreter
1151 * @param interp Interpreter slot
1152 * @param on Node Number
1154 void QKernel::RemoteInstance(InterpEntry *interp, int on)
1159 m.msg_type = MSG_NET;
1160 m.param.pword[0] = NET_NODE_EXIST;
1161 m.param.pword[1] = on;
1162 m.param.pword[2] = interp->ID;
1163 write(net_sock, &m, sizeof(MESSAGE));
1164 bzero(&m, sizeof(MESSAGE));
1165 while((m.msg_type!=MSG_NET) && (m.param.pword[0]!=NET_NODE_EXIST))
1166 read(net_sock, &m, sizeof(MESSAGE));
1168 /* means node exists */
1169 if (m.param.pword[1] == 1) {
1170 m.msg_type = MSG_NET;
1171 m.param.pword[0] = NET_TRANSMIT_CODE;
1172 m.param.pword[1] = interp->ID;
1173 m.param.pword[2] = on;
1174 strcpy(m.param.pstr, interp->fullname);
1175 write(net_sock, &m, sizeof(MESSAGE));
1177 Net_Notify->setEnabled(FALSE);
1178 while ((m.msg_type != MSG_NET) ||
1179 (m.param.pword[0] != NET_TRANSMITTED))
1180 read(net_sock, &m, sizeof(MESSAGE));
1182 m.msg_type = MSG_NET;
1183 m.param.pword[0] = NET_PROPAGATE;
1184 m.param.pword[1] = MSG_VLP;
1185 m.param.pword[2] = NodeNumber;
1186 m.param.pword[3] = 0;
1187 m.param.pword[4] = on;
1188 m.param.pword[5] = 0;
1189 m.param.pword[6] = VLP_REMOTE_INSTANCE;
1190 m.param.pword[7] = interp->ID;
1191 strcpy(m.param.pstr, interp->shortname);
1192 write(net_sock, &m, sizeof(MESSAGE));
1194 read(net_sock, &m, sizeof(MESSAGE));
1196 if ((m.param.pword[0] == NET_PROPAGATE) &&
1197 (m.param.pword[6] == VLP_REMOTE_INSTANCE_OK)) {
1198 interp->RInstances[on] = m.param.pword[7];
1201 read(net_sock, &m, sizeof(MESSAGE));
1204 Net_Notify->setEnabled(TRUE);
1206 /*bzero(&m, sizeof(MESSAGE));*/
1207 m.msg_type = MSG_VLP;
1208 m.param.pword[0] = VLP_REMOTE_INSTANCE_HERE;
1209 m.param.pword[1] = interp->RInstances[on];
1210 write(interp->sock, &m, sizeof(MESSAGE));
1211 } else { /* There is no such a node! */
1212 sprintf(s, "Warning: Node number %d not found!", on);
1214 WriteMessage("Allocating O-process on the local node");
1215 bzero(&m, sizeof(MESSAGE));
1216 m.msg_type = MSG_VLP;
1217 m.param.pword[0] = VLP_REMOTE_INSTANCE_HERE;
1218 m.param.pword[1] = interp->ID;
1219 write(interp->sock, &m, sizeof(MESSAGE));
1224 * Closes all remote instances
1226 void QKernel::CloseInstances(InterpEntry *e)
1232 WriteMessage("Closing remote instances");
1234 for(i=0; i < MAXINSTANCES; i++)
1235 if (e->RInstances[i]>=0) {
1236 msg.msg_type = MSG_NET;
1237 msg.param.pword[0] = NET_PROPAGATE;
1238 msg.param.pword[1] = MSG_VLP;
1239 msg.param.pword[2] = NodeNumber;
1240 msg.param.pword[4] = i;
1241 msg.param.pword[6] = VLP_CLOSE_INSTANCE;
1242 msg.param.pword[7] = e->RInstances[i];
1243 write(net_sock, &msg, sizeof(MESSAGE));
1248 * Displays information about virtual machine
1250 void QKernel::on_actionInfo_triggered()
1254 WriteMessage(CharLine);
1255 WriteMessage("### Virtual Machine Information ###");
1256 m.msg_type = MSG_NET;
1257 m.param.pword[0] = NET_GET_INFO;
1258 write(net_sock, &m, sizeof(MESSAGE));
1259 wait_for_info = TRUE;
1263 * Program main function
1264 * All program arguments but the first one (argv[0]: program name) are saved and
1265 * passed to all dependent programs on their invocation.
1266 * @param argc Number of program arguments
1267 * @param argv Program arguments
1269 int main(int argc, char **argv)
1272 for(i = 0; i < 5; i++) {
1273 strcpy(myargs[i], "");
1275 for(i = 1; i < argc; i++) {
1276 strcpy(myargs[i - 1], argv[i]);
1279 QApplication * app = new QApplication(argc, argv);
1284 kernel.InitMessage();