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"
69 /* File resides in top directory (where are Makefiles)*/
70 #include "../../config.h"
73 char CharLine[25] = "________________________";
79 * Event invoked on program close.
80 * Closes application. Displays additional window to confirm exit.
82 void QKernel::closeEvent(QCloseEvent * e)
91 void QKernel::setLocked(bool locked)
95 actionExecute->setDisabled(locked);
96 actionKill->setDisabled(locked);
97 actionConnect->setDisabled(locked);
98 actionDisconnect->setDisabled(locked);
99 actionInfo_messages->setDisabled(locked);
100 actionMessage->setDisabled(locked);
102 /* Enable only menu entry for unlocking */
103 actionEditor->setDisabled(locked);
104 actionOptions->setDisabled(locked);
105 actionLock_Console->setDisabled(locked);
106 actionUnlock_console->setEnabled(locked);
110 * Kernel program constructor.
111 * Prepares everything to work.
113 QKernel::QKernel(QWidget *parent)
114 : QMainWindow(parent)
122 sprintf(ss, "mkdir %s", REMOTE_PATH);
126 info_messages = TRUE;
127 wait_for_info = FALSE;
129 setWindowTitle(PACKAGE_NAME);
134 ActiveConnections = 0;
135 strcpy(LockPasswd, "");
136 LoadConfig("vlp.cfg");
139 Net_Notify = new QSocketNotifier(net_sock, QSocketNotifier::Read, this);
140 connect(Net_Notify, SIGNAL(activated(int)), this, SLOT(NetMessage()));
144 * Displays window with information about not implemented functionality.
146 void QKernel::n_impl()
148 QMessageBox::information(this, "Function info", "This function is not "
149 "implemented yet...", "Ok");
153 * Loads configuration from the given file.
154 * @param fname Filename of the configuration file.
156 void QKernel::LoadConfig(char * fname)
159 config_setting_t *setting;
162 /* Hack for checking if file exists without using external libs.*/
163 FILE * file = fopen(fname, "rt");
165 fprintf(stderr, "Error: Cannot load configuration file %s!\n",
169 /* File exists, so file has been locked. Release it. */
173 /* Read the file. If there is an error, report it and exit. */
174 if (!config_read(&cfg, file)) {
175 fprintf(stderr, "%s! In file %s, line %d\n",
176 config_error_text(&cfg),
177 config_error_file(&cfg),
178 config_error_line(&cfg));
179 config_destroy(&cfg);
184 setting = config_lookup(&cfg, "node_number");
186 NodeNumber = config_setting_get_int(setting);
188 fprintf(stderr, "%s! In file %s, '%s' was not found.\n",
189 "Warning", fname, "node_number");
190 config_destroy(&cfg);
195 setting = config_lookup(&cfg, "type");
197 /* same as strcmp(..) == 0 */
198 if (!strcmp(config_setting_get_string(setting), "explicit")) {
204 fprintf(stderr, "%s! In file %s, '%s' was not found.\n",
205 "Warning", fname, "type");
208 setting = config_lookup(&cfg, "host");
210 switch(config_setting_type(setting)) {
211 /* TODO: Deprecated. Made for back compatibility. */
212 case CONFIG_TYPE_STRING:
213 ConnectList.append(new ConnectEntry((char*)
214 config_setting_get_string(setting)));
216 case CONFIG_TYPE_ARRAY: {
217 int size = config_setting_length(setting);
218 for (int i = 0; i < size; i++) {
219 ConnectList.append(new ConnectEntry((char*)
220 config_setting_get_string_elem(setting,
226 fprintf(stderr, "%s! In file %s, bad entry type for %s."
227 " Will not be read.\n",
228 "Error", fname, "host");
231 fprintf(stderr, "%s! In file %s, '%s' was not found.\n",
232 "Warning", fname, "host");
235 setting = config_lookup(&cfg, "progdir");
237 strncpy(progdir, config_setting_get_string(setting), 256);
239 fprintf(stderr, "%s! In file %s, '%s' was not found.\n",
240 "Warning", fname, "progdir");
243 setting = config_lookup(&cfg, "homedir");
245 strncpy(HomeDir, config_setting_get_string(setting), 255);
247 fprintf(stderr, "%s! In file %s, '%s' was not found.\n",
248 "Warning", fname, "homedir");
251 config_destroy(&cfg);
257 * Additional window id displayed to set which code to execute.
259 void QKernel::on_actionExecute_triggered()
262 QString s = QFileDialog::getOpenFileName(this, "Execute", progdir, "*.log");
265 i = s.indexOf(".log");
270 RunIntModule((char*)s.toAscii().data(), 0);
275 * Invokes editor program
277 void QKernel::on_actionEditor_triggered()
280 sprintf(cmd, "%s/modules/logedit %s %s %s %s %s %s &", HomeDir, HomeDir,
281 myargs[0], myargs[1], myargs[2], myargs[3], myargs[4]);
286 * Invokes help program
288 void QKernel::on_actionHelp_triggered()
291 sprintf(cmd, "%s/modules/loghelp %s/doc %s %s %s %s %s &", HomeDir,
292 HomeDir, myargs[0], myargs[1], myargs[2], myargs[3], myargs[4]);
297 * Invokes graphics module
299 void QKernel::RunGraphModule(char *sk)
303 sprintf(cmd, "%s/modules/loggraph %s %s %s %s %s %s &", HomeDir,
304 sk, myargs[0], myargs[1], myargs[2], myargs[3], myargs[4]);
306 if (system(cmd) != 0)
307 WriteMessage("Cannot connect GRAPH resources");
313 void QKernel::RunNetModule()
315 struct sockaddr_un svr;
319 sprintf(cmd, "%s/modules/lognet %s %s %s %s %s %s &", HomeDir,
320 NPATH, myargs[0], myargs[1], myargs[2], myargs[3], myargs[4]);
322 /* -------- socket for NET module -------- */
324 sock = socket(AF_UNIX, SOCK_STREAM, 0);
325 bzero(&svr, sizeof(svr));
326 svr.sun_family = AF_UNIX;
327 strcpy(svr.sun_path, NPATH);
328 len = strlen(svr.sun_path) + sizeof(svr.sun_family);
329 bind(sock, (struct sockaddr*)&svr, len);
332 if (system(cmd) == 0) {
333 net_sock = accept(sock, (struct sockaddr*)0, (unsigned int*)0);
336 WriteMessage("NETWORK successfully connected");
337 fcntl(net_sock, F_SETFL, O_NONBLOCK|fcntl(net_sock,
340 setsockopt(net_sock, IPPROTO_TCP, TCP_NODELAY,
341 (char*)&on, sizeof(on));
343 WriteMessage("Cannot connect NETWORK resources");
344 WriteMessage("Exiting...");
350 WriteMessage("Cannot connect NETWORK resources");
351 WriteMessage("Exiting...");
358 * Connects to the specified address
359 * Additional window is displayed to connect to the specified address
361 void QKernel::on_actionConnect_triggered()
363 QDialog d(this, Qt::Dialog);
364 QLabel lab("IP Address:", &d);
365 QLineEdit ed("", &d);
366 QPushButton ob("", &d);
367 QPushButton cb("", &d);
370 ob.setGeometry(30, 60, 80, 30);
373 lab.setGeometry(10, 10, 60, 30);
374 lab.setText("Address");
375 ed.setGeometry(70, 10, 140, 30);
376 cb.setGeometry(130, 60, 80, 30);
377 cb.setText("Cancel");
380 connect(&ob, SIGNAL(clicked()), &d, SLOT(accept()));
381 connect(&cb, SIGNAL(clicked()), &d, SLOT(reject()));
383 m.msg_type = MSG_NET;
384 m.param.pword[0] = NET_CONNECT_TO;
385 strcpy(m.param.pstr, ed.text().toAscii().data());
386 write(net_sock, &m, sizeof(MESSAGE));
391 * Disconnects from virtual machine
393 void QKernel::on_actionDisconnect_triggered()
398 WriteMessage("Disconnecting from virtual machine");
400 msg.msg_type = MSG_NET;
401 msg.param.pword[0] = NET_DISCONNECT;
402 write(net_sock, &msg, sizeof(MESSAGE));
406 * Quits process. Closes VLP. Shows additional window to confirm exit.
408 void QKernel::QuitProc()
412 QMessageBox::StandardButton response;
413 response = QMessageBox::question(this, "Close VLP", "Terminate VLP ?",
414 QMessageBox::Ok | QMessageBox::Cancel);
417 if (response == QMessageBox::Cancel) {
421 msg.msg_type = MSG_NET;
422 msg.param.pword[0] = NET_DISCONNECT;
423 write(net_sock, &msg, sizeof(MESSAGE));*/
426 msg.msg_type = MSG_NET;
427 msg.param.pword[0] = NET_EXIT;
428 write(net_sock, &msg, sizeof(MESSAGE));
429 /* ::close(net_sock);*/
430 QApplication::instance()->quit();
434 * Adds IP address to the configuration.
435 * Additional window is displayed to add address to the list
437 void QKernel::AddAddress()
439 QDialog d(this, Qt::Dialog);
440 QLabel lab("IP Address:", &d);
441 QLineEdit ed("", &d);
442 QPushButton ob("", &d);
443 QPushButton cb("", &d);
446 ob.setGeometry(30, 60, 80, 30);
449 lab.setGeometry(10, 10, 60, 30);
450 lab.setText("Address");
451 ed.setGeometry(70, 10, 140, 30);
452 cb.setGeometry(130, 60, 80, 30);
453 cb.setText("Cancel");
455 connect(&ob, SIGNAL(clicked()), &d, SLOT(accept()));
456 connect(&cb, SIGNAL(clicked()), &d, SLOT(reject()));
458 if (strcmp(ed.text().toAscii().data(), "") != 0) {
459 connections->addItem(ed.text());
465 * Deletes current address from available connections.
467 void QKernel::DelAddress()
470 if (connections->currentRow() != -1) {
471 /* TODO: Checki if this work correctly after porting */
472 connections->removeItemWidget(connections->currentItem());
478 * Sends message to node.
479 * Additional window is displayed to set Node Number of node where send message,
480 * and textfield to enter message.
482 void QKernel::on_actionMessage_triggered()
485 SendMessageDialog *dlg;
486 dlg = new SendMessageDialog(this);
489 m.msg_type = MSG_NET;
490 m.param.pword[0] = NET_PROPAGATE;
491 m.param.pword[1] = MSG_VLP;
492 m.param.pword[2] = NodeNumber;
493 m.param.pword[4] = dlg->getNodeNumber();
494 m.param.pword[6] = VLP_WRITE;
495 strcpy(m.param.pstr, dlg->getMessage().toAscii().data());
496 write(net_sock, &m, sizeof(MESSAGE));
502 * Additional window is displayed to get ID of interpreter which should be
505 void QKernel::on_actionKill_triggered()
512 dlg = new QDialog(this, Qt::Dialog);
513 dlg->setWindowTitle("Kill interpreter");
515 nodenr = new QLineEdit("", dlg);
516 nodenr->setGeometry(90, 10, 50, 30);
518 QLabel * tmpQLabel = new QLabel("Interp. ID:", dlg);
519 tmpQLabel->setGeometry(10, 10, 77, 30);
521 QPushButton * ob = new QPushButton("Kill", dlg);
522 ob->setGeometry( 160, 10, 80, 30);
523 ob->setDefault(TRUE);
525 QPushButton * cb = new QPushButton("Cancel", dlg);
526 cb->setGeometry(260, 10, 80, 30);
527 dlg->resize(360, 50);
529 connect(ob, SIGNAL(clicked()), dlg, SLOT(accept()));
530 connect(cb, SIGNAL(clicked()), dlg, SLOT(reject()));
533 m.msg_type = MSG_INT;
534 m.param.pword[0] = INT_KILL;
535 pom = findINTbyID(atoi(nodenr->text().toAscii().data()));
538 write(pom->sock, &m, sizeof(MESSAGE));
540 WriteMessage("This is a remote instance of "
544 WriteMessage("Interpreter not found");
550 * Sends message to the net module.
552 void QKernel::NetMessage()
555 /* TODO: It has to be rewritten */
561 cnt = read(net_sock, &msg, sizeof(MESSAGE));
562 if ((cnt > 0) && (msg.msg_type == MSG_NET)) {
563 switch(msg.param.pword[0]) {
565 WriteMessage(msg.param.pstr);
568 switch(msg.param.pword[1]) {
570 /* pom = find_link_by_ID(msg.param.pword[5]);
571 msg.msg_type = MSG_NET;
572 msg.param.pword[0] = NET_PROPAGATE;
573 send_int(pom, &msg);*/
576 switch(msg.param.pword[6]) {
578 QApplication::beep();
579 WriteMessage(CharLine);
581 "### Incoming Messsage ###");
582 sprintf(ss, "Mesg from Node %d: %s",
586 WriteMessage(CharLine);
588 case VLP_REMOTE_INSTANCE:
589 sprintf(ss, "%s/%s", REMOTE_PATH,
593 WriteMessage("Running program:");
596 pom = RunIntModule(ss, 1);
598 pom->p_ctx.node = msg.param.pword[2];
599 pom->p_ctx.program_id =
601 pom->RInstances[msg.param.pword[2]] = msg.param.pword[7];
604 case VLP_CLOSE_INSTANCE:
605 msg.msg_type = MSG_INT;
606 msg.param.pword[0] = INT_CLOSE_INSTANCE;
607 pom = findINTbyID(msg.param.pword[7]);
609 write(pom->sock, &msg,
612 m1.msg_type = MSG_VLP;
613 m1.param.pword[0] = VLP_INTERPRETER_DOWN;
614 m1.param.pword[1] = pom->ID;
618 WriteMessage("Instance not found");
624 case NET_CONNECTIONS:
625 ActiveConnections = msg.param.pword[1];
626 WriteMessage(msg.param.pstr);
631 /* TODO: It has to be rewritten */
633 QString poms, poms1, poms2;
634 poms.sprintf("%s", msg.param.pstr);
635 while (poms.length() > 0) {
636 cnt = poms.indexOf(';');
638 poms1 = poms.left(cnt);
639 poms = poms.right(poms.length() - cnt - 1);
640 cnt = poms1.indexOf('=');
642 poms2 = poms1.left(cnt);
646 sprintf(ss, "Node: %s Addr: %s", poms2.data(), poms1.data());
654 wait_for_info = FALSE;
655 WriteMessage(CharLine);
662 * Sends message to the interpreter program.
663 * @param sock Interpreter socket to whom the message will be send.
665 void QKernel::IntMessage(int sock)
671 cnt = read(sock, &msg, sizeof(MESSAGE));
672 e = findINTbySocket(sock);
673 if ((cnt > 0) && (e != NULL)) {
674 switch (msg.msg_type) {
676 if (msg.param.pword[0] == GRAPH_ALLOCATE) {
677 RunGraphModule(msg.param.pstr);
681 write(net_sock, &msg, sizeof(MESSAGE));
684 switch(msg.param.pword[0]) {
685 case VLP_REMOTE_INSTANCE_PLEASE:
686 RemoteInstance(e, msg.param.pword[2]);
691 switch(msg.param.pword[0]) {
696 m.msg_type = MSG_VLP;
697 m.param.pword[0] = VLP_INTERPRETER_DOWN;
698 m.param.pword[1] = e->ID;
699 write(net_sock, &m, sizeof(MESSAGE));
704 /* TODO: Check this */
705 Interpreters.removeOne(e);
709 sprintf(ss, "%s : End of program "
710 "execution", msg.param.pstr);
715 msg.msg_type = MSG_INT;
716 msg.param.pword[0] = INT_CTX;
717 msg.param.pword[1] = NodeNumber;
718 msg.param.pword[2] = e->ID;
720 msg.param.pword[3] = e->p_ctx.node;
724 write(sock, &msg, sizeof(MESSAGE));
733 * Writes message to kernel logger.
734 * @parame msg String with message to log
736 void QKernel::WriteMessage(char *msg)
740 x = desktop->textCursor().blockNumber();
741 y = desktop->textCursor().columnNumber();
747 desktop->setReadOnly(FALSE);
748 desktop->append(msg);
749 desktop->setReadOnly(TRUE);
751 QTextCursor tmpCursor = desktop->textCursor();
752 tmpCursor.movePosition(QTextCursor::End, QTextCursor::MoveAnchor);
753 desktop->setTextCursor(tmpCursor);
757 if (desktop->document()->blockCount() > 100) {
763 * Adds checkbox to menu item. If it is checked additional info messages are
766 void QKernel::on_actionInfo_messages_triggered()
768 if (menuTools != NULL) {
769 info_messages = actionInfo_messages->isChecked();
774 * Allows to set options in GUI window.
775 * Additional window is displayed to set kernel options which are saved in
776 * vlp.cfg file in kernel executable directory.
778 void QKernel::on_actionOptions_triggered()
780 QDialog dlg(this, Qt::Dialog);
781 dlg.setWindowTitle("Options");
786 progs = new QLineEdit(progdir, &dlg);
787 progs->setGeometry(150, 20, 180, 30);
790 tmpQLabel = new QLabel("Programs directory", &dlg);
791 tmpQLabel->setGeometry(30, 20, 120, 30);
794 tmpQFrame = new QFrame(&dlg);
795 tmpQFrame->setGeometry(10, 60, 380, 30);
796 tmpQFrame->setFrameStyle(52);
798 tmpQLabel = new QLabel("Virtual Processor properties (activated after "
799 "restarting VLP):", &dlg);
800 tmpQLabel->setGeometry(10, 80, 340, 30);
804 sprintf(nns, "%d", NodeNumber);
805 nn = new QLineEdit(nns, &dlg);
806 nn->setGeometry(110, 110, 40, 30);
808 tmpQLabel = new QLabel("Node number:", &dlg);
809 tmpQLabel->setGeometry(20, 110, 90, 30);
811 QRadioButton *exp, *reg;
812 exp = new QRadioButton("Explicit", &dlg);
813 exp->setGeometry(30, 170, 100, 30);
814 exp->setChecked(TRUE);
816 reg = new QRadioButton("Registration", &dlg);
817 reg->setGeometry(30, 200, 100, 30);
818 reg->setEnabled(FALSE);
820 connections = new QListWidget(&dlg);
821 connections->setGeometry(170, 140, 130, 100);
823 for (int i = 0; i < ConnectList.size(); i++) {
824 e = ConnectList.at(i);
825 connections->addItem(e->addr);
828 tmpQLabel = new QLabel("Connection list:", &dlg);
829 tmpQLabel->setGeometry(170, 110, 100, 30);
834 QPushButton *cancelbtn;
835 addbtn = new QPushButton("Add", &dlg);
836 addbtn->setGeometry(310, 150, 60, 30);
837 connect(addbtn, SIGNAL(clicked()), this, SLOT(AddAddress()));
839 delbtn = new QPushButton("Del", &dlg);
840 delbtn->setGeometry(310, 200, 60, 30);
841 connect(delbtn, SIGNAL(clicked()), this, SLOT(DelAddress()));
843 okbtn = new QPushButton("Ok", &dlg);
844 okbtn->setGeometry(80, 260, 100, 30);
845 okbtn->setDefault(TRUE);
846 connect(okbtn, SIGNAL(clicked()), &dlg, SLOT(accept()));
848 cancelbtn = new QPushButton("Cancel", &dlg);
849 cancelbtn->setGeometry(210, 260, 100, 30);
850 connect(cancelbtn, SIGNAL(clicked()), &dlg, SLOT(reject()));
853 group = new QGroupBox("Connection type", &dlg);
854 group->setGeometry(20, 150, 120, 90);
855 group->setAlignment(Qt::AlignLeft);
858 QVBoxLayout *vbox = new QVBoxLayout();
859 vbox->addWidget(exp);
860 vbox->addWidget(reg);
862 group->setLayout(vbox);
864 dlg.resize(400, 310);
867 config_setting_t *root;
868 config_setting_t *setting;
871 root = config_root_setting(&cfg);
873 setting = config_setting_add(root, "progdir",
875 config_setting_set_string(setting, progs->text().toAscii().data());
876 strcpy(progdir, progs->text().toAscii().data());
878 setting = config_setting_add(root, "node_number",
880 config_setting_set_int(setting, atoi(nn->text().toAscii().data()));
882 setting = config_setting_add(root, "homedir",
884 config_setting_set_string(setting, HomeDir);
886 setting = config_setting_add(root, "type",
888 if (exp->isChecked()) {
889 config_setting_set_string(setting, "explicit");
891 config_setting_t *hosts = NULL;
892 hosts = config_setting_add(root, "host",
894 for(i = 0; i < connections->count(); i++) {
895 setting = config_setting_add(hosts, NULL,
897 config_setting_set_string(setting,
898 connections->item(i)->text().toAscii().data());
901 config_setting_set_string(setting, "register");
904 if (!config_write_file(&cfg, "vlp.cfg")) {
905 fprintf(stderr, "Error while writing to file: %s.\n",
908 config_destroy(&cfg);
913 * Locks kernel program.
914 * Additional window is displayed to enter password and retype it. If both are
915 * same kernel window is locked.
917 void QKernel::on_actionLock_Console_triggered()
919 QDialog d(this, Qt::Dialog);
920 d.setWindowTitle("Lock console");
922 QPushButton ob("Ok", &d);
923 ob.setGeometry(30, 60, 80, 30);
925 connect(&ob, SIGNAL(clicked()), &d, SLOT(accept()));
927 QLabel lab("Password:", &d);
928 lab.setGeometry(10, 10, 60, 30);
930 QLineEdit ed("", &d);
931 ed.setGeometry(70, 10, 140, 30);
932 ed.setEchoMode(QLineEdit::Password);
934 QPushButton cb("Cancel", &d);
935 cb.setGeometry(130, 60, 80, 30);
936 connect(&cb, SIGNAL(clicked()), &d, SLOT(reject()));
941 if (strcmp(ed.text().toAscii().data(), "") != 0) {
942 strcpy(LockPasswd, ed.text().toAscii().data());
943 lab.setText("Retype:");
946 * Following exec(), could produce error:
947 * X Error: BadWindow (invalid Window parameter) 3
948 * Major opcode: 3 (X_GetWindowAttributes)
950 * This is not error in our code. Basing on:
951 * https://bugreports.qt-project.org/browse/QTBUG-1782
952 * this happens only on Qt 4.3 - 4.4.
955 if (strcmp(ed.text().toAscii().data(), LockPasswd) == 0) {
957 WriteMessage("CONSOLE LOCKED");
959 QMessageBox msg(this);
960 msg.setText("Not matching!");
961 msg.setButtonText(0, "Close");
965 strcpy(LockPasswd, "");
972 * Unlocks kernel program.
973 * Additional window is displayed to enter password. If it is correct, kernel
976 void QKernel::on_actionUnlock_console_triggered()
978 QDialog d(this, Qt::Dialog);
979 d.setWindowTitle("Enter password");
981 QLabel lab("Password:", &d);
982 lab.setGeometry(10, 10, 60, 30);
984 QLineEdit ed("", &d);
985 ed.setGeometry(70, 10, 140, 30);
986 ed.setEchoMode(QLineEdit::Password);
988 QPushButton ob("Ok", &d);
989 ob.setGeometry(30, 60, 80, 30);
991 connect(&ob, SIGNAL(clicked()), &d, SLOT(accept()));
993 QPushButton cb("Cancel", &d);
994 cb.setGeometry(130, 60, 80, 30);
995 connect(&cb, SIGNAL(clicked()), &d, SLOT(reject()));
1000 if (strcmp(ed.text().toAscii().data(), LockPasswd) == 0) {
1002 WriteMessage("CONSOLE UNLOCKED");
1004 QMessageBox msg(this);
1005 msg.setText("Wrong password!");
1006 msg.setButtonText(0, "Close");
1013 * Writes init message in kernel
1015 void QKernel::InitMessage()
1017 WriteMessage("\n " PACKAGE_STRING ": READY \n");
1021 * Finds Interpreter by its socket
1022 * @param _id ID of the socket
1023 * @return returns pointer to the found interpreter slot. NULL otherwise
1025 InterpEntry *QKernel::findINTbySocket(int _id)
1027 InterpEntry *pom = NULL;
1029 for (int i = 0; i < Interpreters.size(); i++) {
1030 if (Interpreters.at(i)->sock == _id) {
1031 pom = Interpreters.at(i);
1040 * Finds Interpreter by its ID.
1041 * @param _id ID of the interpreter
1042 * @return returns pointer to the found interpreter slot. NULL otherwise
1044 InterpEntry *QKernel::findINTbyID(int _id)
1046 InterpEntry *pom = NULL;
1048 for (int i = 0; i < Interpreters.size(); i++) {
1049 if (Interpreters.at(i)->ID == _id) {
1050 pom = Interpreters.at(i);
1060 * Connects interpreter
1061 * @param ss full filepath with filename but without extension of the loglan
1063 * @param r Interpreter execution mode. 0 if it will be local instance, 1 if
1065 * @return Returns pointer to newly created interpreter slot, or NULL on error.
1067 InterpEntry *QKernel::RunIntModule(char *ss, int r)
1069 char a[256], b[255];
1070 struct sockaddr_un svr;
1071 int len, sock, i, on;
1076 InterpEntry *newINT = NULL;
1082 WriteMessage("File not found: no .ccd file");
1091 WriteMessage("File not found: no .pcd file");
1096 newINT = new InterpEntry;
1097 for(i = 0; i < MAXINSTANCES; i++)
1098 newINT->RInstances[i] =- 1;
1100 strcpy(b, rindex(ss, '/'));
1101 for(i = 0; i < strlen(b); i++)
1103 if (info_messages) {
1104 sprintf(a, "%s : Start execution", b);
1110 newINT->ID = newint;
1111 strcpy(newINT->shortname, b);
1112 strcpy(newINT->fullname, ss);
1114 sprintf(a, "%s%d", IPATH, newint);
1115 sprintf(cmd, "%s/modules/logint %s %s", HomeDir, a, ss);
1118 sprintf(b, " %s %s %s %s %s", myargs[0], myargs[1], myargs[2],
1119 myargs[3], myargs[4]);
1123 sock = socket(AF_UNIX, SOCK_STREAM, 0);
1125 bzero(&svr, sizeof(svr));
1126 svr.sun_family = AF_UNIX;
1127 strcpy(svr.sun_path, a);
1128 len = strlen(svr.sun_path)+sizeof(svr.sun_family);
1129 bind(sock, (struct sockaddr*)&svr, len);
1132 newINT->sock = accept(sock, (struct sockaddr*)0, (unsigned int *)0);
1135 if (newINT->sock > 0) {
1136 fcntl(newINT->sock, F_SETFL,
1137 O_NONBLOCK|fcntl(newINT->sock, F_GETFL, 0));
1139 setsockopt(newINT->sock, IPPROTO_TCP, TCP_NODELAY, (char*)&on,
1146 bzero(&msg, sizeof(MESSAGE));
1147 msg.msg_type = MSG_VLP;
1148 msg.param.pword[0] = VLP_REGINT;
1149 msg.param.pword[1] = newINT->ID;
1150 sprintf(msg.param.pstr, "logi%d.net", newint);
1151 write(net_sock, &msg, sizeof(MESSAGE));
1153 Interpreters.append(newINT);
1154 newINT->notify = new QSocketNotifier(newINT->sock,
1155 QSocketNotifier::Read);
1156 connect(newINT->notify, SIGNAL(activated(int)), this,
1157 SLOT(IntMessage(int)));
1159 WriteMessage("INTERPRETER successfully connected");
1161 WriteMessage("Cannot connect interpreter");
1168 * Allocates remote instance of interpreter
1169 * @param interp Interpreter slot
1170 * @param on Node Number
1172 void QKernel::RemoteInstance(InterpEntry *interp, int on)
1177 m.msg_type = MSG_NET;
1178 m.param.pword[0] = NET_NODE_EXIST;
1179 m.param.pword[1] = on;
1180 m.param.pword[2] = interp->ID;
1181 write(net_sock, &m, sizeof(MESSAGE));
1182 bzero(&m, sizeof(MESSAGE));
1183 while((m.msg_type!=MSG_NET) && (m.param.pword[0]!=NET_NODE_EXIST))
1184 read(net_sock, &m, sizeof(MESSAGE));
1186 /* means node exists */
1187 if (m.param.pword[1] == 1) {
1188 m.msg_type = MSG_NET;
1189 m.param.pword[0] = NET_TRANSMIT_CODE;
1190 m.param.pword[1] = interp->ID;
1191 m.param.pword[2] = on;
1192 strcpy(m.param.pstr, interp->fullname);
1193 write(net_sock, &m, sizeof(MESSAGE));
1195 Net_Notify->setEnabled(FALSE);
1196 while ((m.msg_type != MSG_NET) ||
1197 (m.param.pword[0] != NET_TRANSMITTED))
1198 read(net_sock, &m, sizeof(MESSAGE));
1200 m.msg_type = MSG_NET;
1201 m.param.pword[0] = NET_PROPAGATE;
1202 m.param.pword[1] = MSG_VLP;
1203 m.param.pword[2] = NodeNumber;
1204 m.param.pword[3] = 0;
1205 m.param.pword[4] = on;
1206 m.param.pword[5] = 0;
1207 m.param.pword[6] = VLP_REMOTE_INSTANCE;
1208 m.param.pword[7] = interp->ID;
1209 strcpy(m.param.pstr, interp->shortname);
1210 write(net_sock, &m, sizeof(MESSAGE));
1212 read(net_sock, &m, sizeof(MESSAGE));
1214 if ((m.param.pword[0] == NET_PROPAGATE) &&
1215 (m.param.pword[6] == VLP_REMOTE_INSTANCE_OK)) {
1216 interp->RInstances[on] = m.param.pword[7];
1219 read(net_sock, &m, sizeof(MESSAGE));
1222 Net_Notify->setEnabled(TRUE);
1224 /*bzero(&m, sizeof(MESSAGE));*/
1225 m.msg_type = MSG_VLP;
1226 m.param.pword[0] = VLP_REMOTE_INSTANCE_HERE;
1227 m.param.pword[1] = interp->RInstances[on];
1228 write(interp->sock, &m, sizeof(MESSAGE));
1229 } else { /* There is no such a node! */
1230 sprintf(s, "Warning: Node number %d not found!", on);
1232 WriteMessage("Allocating O-process on the local node");
1233 bzero(&m, sizeof(MESSAGE));
1234 m.msg_type = MSG_VLP;
1235 m.param.pword[0] = VLP_REMOTE_INSTANCE_HERE;
1236 m.param.pword[1] = interp->ID;
1237 write(interp->sock, &m, sizeof(MESSAGE));
1242 * Closes all remote instances
1244 void QKernel::CloseInstances(InterpEntry *e)
1250 WriteMessage("Closing remote instances");
1252 for(i=0; i < MAXINSTANCES; i++)
1253 if (e->RInstances[i]>=0) {
1254 msg.msg_type = MSG_NET;
1255 msg.param.pword[0] = NET_PROPAGATE;
1256 msg.param.pword[1] = MSG_VLP;
1257 msg.param.pword[2] = NodeNumber;
1258 msg.param.pword[4] = i;
1259 msg.param.pword[6] = VLP_CLOSE_INSTANCE;
1260 msg.param.pword[7] = e->RInstances[i];
1261 write(net_sock, &msg, sizeof(MESSAGE));
1266 * Displays information about virtual machine
1268 void QKernel::on_actionInfo_triggered()
1272 WriteMessage(CharLine);
1273 WriteMessage("### Virtual Machine Information ###");
1274 m.msg_type = MSG_NET;
1275 m.param.pword[0] = NET_GET_INFO;
1276 write(net_sock, &m, sizeof(MESSAGE));
1277 wait_for_info = TRUE;
1281 * Program main function
1282 * All program arguments but the first one (argv[0]: program name) are saved and
1283 * passed to all dependent programs on their invocation.
1284 * @param argc Number of program arguments
1285 * @param argv Program arguments
1287 int main(int argc, char **argv)
1290 for(i = 0; i < 5; i++) {
1291 strcpy(myargs[i], "");
1293 for(i = 1; i < argc; i++) {
1294 strcpy(myargs[i - 1], argv[i]);
1297 QApplication * app = new QApplication(argc, argv);
1302 kernel.InitMessage();