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"
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)
87 on_actionQuit_triggered();
91 void QKernel::setLocked(bool locked)
95 actionQuit->setDisabled(locked);
97 actionExecute->setDisabled(locked);
98 actionKill->setDisabled(locked);
99 actionMessage->setDisabled(locked);
100 actionConnect->setDisabled(locked);
101 actionDisconnect->setDisabled(locked);
102 actionInfo->setDisabled(locked);
105 /* Enable only menu entry for unlocking */
106 actionEditor->setDisabled(locked);
107 actionOptions->setDisabled(locked);
108 actionLock_console->setDisabled(locked);
109 actionUnlock_console->setDisabled(!locked);
113 * Kernel program constructor.
114 * Prepares everything to work.
124 sprintf(ss, "mkdir %s", REMOTE_PATH);
128 info_messages = TRUE;
129 wait_for_info = FALSE;
131 setWindowTitle(PACKAGE_NAME);
135 desktop = new QTextEdit(this);
136 desktop->setReadOnly(TRUE);
137 QVBoxLayout * layout = new QVBoxLayout();
138 layout->setContentsMargins (3, 0, 3, 0);
139 layout->addWidget(desktop);
140 QWidget *window = new QWidget();
141 window->setLayout(layout);
142 setCentralWidget(window);
147 ActiveConnections = 0;
148 strcpy(LockPasswd, "");
149 LoadConfig("vlp.cfg");
152 Net_Notify = new QSocketNotifier(net_sock, QSocketNotifier::Read, this);
153 connect(Net_Notify, SIGNAL(activated(int)), this, SLOT(NetMessage()));
157 * Event invoked on resizing kernel application window.
158 * @copydoc QWidget::resizeEvent(QResizeEvent*)
160 void QKernel::resizeEvent(QResizeEvent *ev)
162 // QFrame::resizeEvent(ev);
164 // desktop->setGeometry(0, bar->height(), width(),
165 // height() - bar->height());
169 * Displays window with information about not implemented functionality.
171 void QKernel::n_impl()
173 QMessageBox::information(this, "Function info", "This function is not "
174 "implemented yet...", "Ok");
178 * Loads configuration from the given file.
179 * @param fname Filename of the configuration file.
181 void QKernel::LoadConfig(char * fname)
184 config_setting_t *setting;
187 /* Hack for checking if file exists without using external libs.*/
188 FILE * file = fopen(fname, "rt");
190 fprintf(stderr, "Error: Cannot load configuration file %s!\n",
194 /* File exists, so file has been locked. Release it. */
198 /* Read the file. If there is an error, report it and exit. */
199 if (!config_read(&cfg, file)) {
200 fprintf(stderr, "%s! In file %s, line %d\n",
201 config_error_text(&cfg),
202 config_error_file(&cfg),
203 config_error_line(&cfg));
204 config_destroy(&cfg);
209 setting = config_lookup(&cfg, "node_number");
211 NodeNumber = config_setting_get_int(setting);
213 fprintf(stderr, "%s! In file %s, '%s' was not found.\n",
214 "Warning", fname, "node_number");
215 config_destroy(&cfg);
220 setting = config_lookup(&cfg, "type");
222 /* same as strcmp(..) == 0 */
223 if (!strcmp(config_setting_get_string(setting), "explicit")) {
229 fprintf(stderr, "%s! In file %s, '%s' was not found.\n",
230 "Warning", fname, "type");
233 setting = config_lookup(&cfg, "host");
235 switch(config_setting_type(setting)) {
236 /* TODO: Deprecated. Made for back compatibility. */
237 case CONFIG_TYPE_STRING:
238 ConnectList.append(new ConnectEntry((char*)
239 config_setting_get_string(setting)));
241 case CONFIG_TYPE_ARRAY: {
242 int size = config_setting_length(setting);
243 for (int i = 0; i < size; i++) {
244 ConnectList.append(new ConnectEntry((char*)
245 config_setting_get_string_elem(setting,
251 fprintf(stderr, "%s! In file %s, bad entry type for %s."
252 " Will not be read.\n",
253 "Error", fname, "host");
256 fprintf(stderr, "%s! In file %s, '%s' was not found.\n",
257 "Warning", fname, "host");
260 setting = config_lookup(&cfg, "progdir");
262 strncpy(progdir, config_setting_get_string(setting), 256);
264 fprintf(stderr, "%s! In file %s, '%s' was not found.\n",
265 "Warning", fname, "progdir");
268 setting = config_lookup(&cfg, "homedir");
270 strncpy(HomeDir, config_setting_get_string(setting), 255);
272 fprintf(stderr, "%s! In file %s, '%s' was not found.\n",
273 "Warning", fname, "homedir");
276 config_destroy(&cfg);
282 * Additional window id displayed to set which code to execute.
284 void QKernel::on_actionExecute_triggered()
287 QString s = QFileDialog::getOpenFileName(this, "Execute", progdir, "*.log");
290 i = s.indexOf(".log");
295 RunIntModule((char*)s.toAscii().data(), 0);
300 * Invokes editor program
302 void QKernel::on_actionEditor_triggered()
305 sprintf(cmd, "%s/modules/logedit %s %s %s %s %s %s &", HomeDir, HomeDir,
306 myargs[0], myargs[1], myargs[2], myargs[3], myargs[4]);
311 * Invokes help program
313 void QKernel::on_actionHelp_triggered()
316 sprintf(cmd, "%s/modules/loghelp %s/doc %s %s %s %s %s &", HomeDir,
317 HomeDir, myargs[0], myargs[1], myargs[2], myargs[3], myargs[4]);
322 * Invokes graphics module
324 void QKernel::RunGraphModule(char *sk)
328 sprintf(cmd, "%s/modules/loggraph %s %s %s %s %s %s &", HomeDir,
329 sk, myargs[0], myargs[1], myargs[2], myargs[3], myargs[4]);
331 if (system(cmd) != 0)
332 WriteMessage("Cannot connect GRAPH resources");
338 void QKernel::RunNetModule()
340 struct sockaddr_un svr;
344 sprintf(cmd, "%s/modules/lognet %s %s %s %s %s %s &", HomeDir,
345 NPATH, myargs[0], myargs[1], myargs[2], myargs[3], myargs[4]);
347 /* -------- socket for NET module -------- */
349 sock = socket(AF_UNIX, SOCK_STREAM, 0);
350 bzero(&svr, sizeof(svr));
351 svr.sun_family = AF_UNIX;
352 strcpy(svr.sun_path, NPATH);
353 len = strlen(svr.sun_path) + sizeof(svr.sun_family);
354 bind(sock, (struct sockaddr*)&svr, len);
357 if (system(cmd) == 0) {
358 net_sock = accept(sock, (struct sockaddr*)0, (unsigned int*)0);
361 WriteMessage("NETWORK successfully connected");
362 fcntl(net_sock, F_SETFL, O_NONBLOCK|fcntl(net_sock,
365 setsockopt(net_sock, IPPROTO_TCP, TCP_NODELAY,
366 (char*)&on, sizeof(on));
368 WriteMessage("Cannot connect NETWORK resources");
369 WriteMessage("Exiting...");
371 on_actionQuit_triggered();
375 WriteMessage("Cannot connect NETWORK resources");
376 WriteMessage("Exiting...");
378 on_actionQuit_triggered();
383 * Connects to the specified address
384 * Additional window is displayed to connect to the specified address
386 void QKernel::on_actionConnect_triggered()
388 QDialog d(this, Qt::Dialog);
389 QLabel lab("IP Address:", &d);
390 QLineEdit ed("", &d);
391 QPushButton ob("", &d);
392 QPushButton cb("", &d);
395 ob.setGeometry(30, 60, 80, 30);
398 lab.setGeometry(10, 10, 60, 30);
399 lab.setText("Address");
400 ed.setGeometry(70, 10, 140, 30);
401 cb.setGeometry(130, 60, 80, 30);
402 cb.setText("Cancel");
405 connect(&ob, SIGNAL(clicked()), &d, SLOT(accept()));
406 connect(&cb, SIGNAL(clicked()), &d, SLOT(reject()));
408 m.msg_type = MSG_NET;
409 m.param.pword[0] = NET_CONNECT_TO;
410 strcpy(m.param.pstr, ed.text().toAscii().data());
411 write(net_sock, &m, sizeof(MESSAGE));
416 * Disconnects from virtual machine
418 void QKernel::on_actionDisconnect_triggered()
423 WriteMessage("Disconnecting from virtual machine");
425 msg.msg_type = MSG_NET;
426 msg.param.pword[0] = NET_DISCONNECT;
427 write(net_sock, &msg, sizeof(MESSAGE));
431 * Quits process. Closes VLP. Shows additional window to confirm exit.
433 void QKernel::on_actionQuit_triggered()
437 QMessageBox::StandardButton response;
438 response = QMessageBox::question(this, "Close VLP", "Terminate VLP ?",
439 QMessageBox::Ok | QMessageBox::Cancel);
442 if (response == QMessageBox::Cancel) {
446 msg.msg_type = MSG_NET;
447 msg.param.pword[0] = NET_DISCONNECT;
448 write(net_sock, &msg, sizeof(MESSAGE));*/
451 msg.msg_type = MSG_NET;
452 msg.param.pword[0] = NET_EXIT;
453 write(net_sock, &msg, sizeof(MESSAGE));
454 /* ::close(net_sock);*/
455 QApplication::instance()->quit();
459 * Adds IP address to the configuration.
460 * Additional window is displayed to add address to the list
462 void QKernel::AddAddress()
464 QDialog d(this, Qt::Dialog);
465 QLabel lab("IP Address:", &d);
466 QLineEdit ed("", &d);
467 QPushButton ob("", &d);
468 QPushButton cb("", &d);
471 ob.setGeometry(30, 60, 80, 30);
474 lab.setGeometry(10, 10, 60, 30);
475 lab.setText("Address");
476 ed.setGeometry(70, 10, 140, 30);
477 cb.setGeometry(130, 60, 80, 30);
478 cb.setText("Cancel");
480 connect(&ob, SIGNAL(clicked()), &d, SLOT(accept()));
481 connect(&cb, SIGNAL(clicked()), &d, SLOT(reject()));
483 if (strcmp(ed.text().toAscii().data(), "") != 0) {
484 connections->addItem(ed.text());
490 * Deletes current address from available connections.
492 void QKernel::DelAddress()
495 if (connections->currentRow() != -1) {
496 /* TODO: Checki if this work correctly after porting */
497 connections->removeItemWidget(connections->currentItem());
503 * Sends message to node.
504 * Additional window is displayed to set Node Number of node where send message,
505 * and textfield to enter message.
507 void QKernel::on_actionMessage_triggered()
513 dlg = new QDialog(this, Qt::Dialog);
514 dlg->setWindowTitle("Send message to node");
516 nodenr = new QLineEdit("number", dlg);
517 nodenr->setGeometry(90, 10, 50, 30);
521 tmpQLabel = new QLabel("Node number:", dlg);
522 tmpQLabel->setGeometry(10, 10, 77, 30);
524 tmpQLabel = new QLabel("Message:", dlg);
525 tmpQLabel->setGeometry(10, 50, 70, 30);
528 msg = new QLineEdit("", dlg);
529 msg->setGeometry(80, 60, 330, 30);
532 ob = new QPushButton("Send", dlg);
533 ob->setGeometry(230, 10, 80, 30);
534 ob->setDefault(TRUE);
537 cb = new QPushButton("Cancel", dlg);
538 cb->setGeometry(330, 10, 80, 30);
539 dlg->resize(430, 110);
540 connect(ob, SIGNAL(clicked()), dlg, SLOT(accept()));
541 connect(cb, SIGNAL(clicked()), dlg, SLOT(reject()));
544 m.msg_type = MSG_NET;
545 m.param.pword[0] = NET_PROPAGATE;
546 m.param.pword[1] = MSG_VLP;
547 m.param.pword[2] = NodeNumber;
548 m.param.pword[4] = atoi(nodenr->text().toAscii().data());
549 m.param.pword[6] = VLP_WRITE;
550 strcpy(m.param.pstr, msg->text().toAscii().data());
551 write(net_sock, &m, sizeof(MESSAGE));
557 * Additional window is displayed to get ID of interpreter which should be
560 void QKernel::on_actionKill_triggered()
567 dlg = new QDialog(this, Qt::Dialog);
568 dlg->setWindowTitle("Kill interpreter");
570 nodenr = new QLineEdit("", dlg);
571 nodenr->setGeometry(90, 10, 50, 30);
573 QLabel * tmpQLabel = new QLabel("Interp. ID:", dlg);
574 tmpQLabel->setGeometry(10, 10, 77, 30);
576 QPushButton * ob = new QPushButton("Kill", dlg);
577 ob->setGeometry( 160, 10, 80, 30);
578 ob->setDefault(TRUE);
580 QPushButton * cb = new QPushButton("Cancel", dlg);
581 cb->setGeometry(260, 10, 80, 30);
582 dlg->resize(360, 50);
584 connect(ob, SIGNAL(clicked()), dlg, SLOT(accept()));
585 connect(cb, SIGNAL(clicked()), dlg, SLOT(reject()));
588 m.msg_type = MSG_INT;
589 m.param.pword[0] = INT_KILL;
590 pom = findINTbyID(atoi(nodenr->text().toAscii().data()));
593 write(pom->sock, &m, sizeof(MESSAGE));
595 WriteMessage("This is a remote instance of "
599 WriteMessage("Interpreter not found");
605 * Sends message to the net module.
607 void QKernel::NetMessage()
610 /* TODO: It has to be rewritten */
616 cnt = read(net_sock, &msg, sizeof(MESSAGE));
617 if ((cnt > 0) && (msg.msg_type == MSG_NET)) {
618 switch(msg.param.pword[0]) {
620 WriteMessage(msg.param.pstr);
623 switch(msg.param.pword[1]) {
625 /* pom = find_link_by_ID(msg.param.pword[5]);
626 msg.msg_type = MSG_NET;
627 msg.param.pword[0] = NET_PROPAGATE;
628 send_int(pom, &msg);*/
631 switch(msg.param.pword[6]) {
633 QApplication::beep();
634 WriteMessage(CharLine);
636 "### Incoming Messsage ###");
637 sprintf(ss, "Mesg from Node %d: %s",
641 WriteMessage(CharLine);
643 case VLP_REMOTE_INSTANCE:
644 sprintf(ss, "%s/%s", REMOTE_PATH,
648 WriteMessage("Running program:");
651 pom = RunIntModule(ss, 1);
653 pom->p_ctx.node = msg.param.pword[2];
654 pom->p_ctx.program_id =
656 pom->RInstances[msg.param.pword[2]] = msg.param.pword[7];
659 case VLP_CLOSE_INSTANCE:
660 msg.msg_type = MSG_INT;
661 msg.param.pword[0] = INT_CLOSE_INSTANCE;
662 pom = findINTbyID(msg.param.pword[7]);
664 write(pom->sock, &msg,
667 m1.msg_type = MSG_VLP;
668 m1.param.pword[0] = VLP_INTERPRETER_DOWN;
669 m1.param.pword[1] = pom->ID;
673 WriteMessage("Instance not found");
679 case NET_CONNECTIONS:
680 ActiveConnections = msg.param.pword[1];
681 WriteMessage(msg.param.pstr);
686 /* TODO: It has to be rewritten */
688 QString poms, poms1, poms2;
689 poms.sprintf("%s", msg.param.pstr);
690 while (poms.length() > 0) {
691 cnt = poms.indexOf(';');
693 poms1 = poms.left(cnt);
694 poms = poms.right(poms.length() - cnt - 1);
695 cnt = poms1.indexOf('=');
697 poms2 = poms1.left(cnt);
701 sprintf(ss, "Node: %s Addr: %s", poms2.data(), poms1.data());
709 wait_for_info = FALSE;
710 WriteMessage(CharLine);
717 * Sends message to the interpreter program.
718 * @param sock Interpreter socket to whom the message will be send.
720 void QKernel::IntMessage(int sock)
726 cnt = read(sock, &msg, sizeof(MESSAGE));
727 e = findINTbySocket(sock);
728 if ((cnt > 0) && (e != NULL)) {
729 switch (msg.msg_type) {
731 if (msg.param.pword[0] == GRAPH_ALLOCATE) {
732 RunGraphModule(msg.param.pstr);
736 write(net_sock, &msg, sizeof(MESSAGE));
739 switch(msg.param.pword[0]) {
740 case VLP_REMOTE_INSTANCE_PLEASE:
741 RemoteInstance(e, msg.param.pword[2]);
746 switch(msg.param.pword[0]) {
751 m.msg_type = MSG_VLP;
752 m.param.pword[0] = VLP_INTERPRETER_DOWN;
753 m.param.pword[1] = e->ID;
754 write(net_sock, &m, sizeof(MESSAGE));
759 /* TODO: Check this */
760 Interpreters.removeOne(e);
764 sprintf(ss, "%s : End of program "
765 "execution", msg.param.pstr);
770 msg.msg_type = MSG_INT;
771 msg.param.pword[0] = INT_CTX;
772 msg.param.pword[1] = NodeNumber;
773 msg.param.pword[2] = e->ID;
775 msg.param.pword[3] = e->p_ctx.node;
779 write(sock, &msg, sizeof(MESSAGE));
788 * Writes message to kernel logger.
789 * @parame msg String with message to log
791 void QKernel::WriteMessage(char *msg)
795 x = desktop->textCursor().blockNumber();
796 y = desktop->textCursor().columnNumber();
802 desktop->setReadOnly(FALSE);
803 desktop->append(msg);
804 desktop->setReadOnly(TRUE);
806 QTextCursor tmpCursor = desktop->textCursor();
807 tmpCursor.movePosition(QTextCursor::End, QTextCursor::MoveAnchor);
808 desktop->setTextCursor(tmpCursor);
812 if (desktop->document()->blockCount() > 100) {
818 * Adds checkbox to menu item. If it is checked additional info messages are
821 void QKernel::on_actionInfo_messages_triggered()
823 if (toolsMenu != NULL) {
824 actionInfo_messages->setChecked(!actionInfo_messages->isChecked());
825 // actionInfo_messages->toggle();
826 info_messages = actionInfo_messages->isChecked();
827 fprintf(stderr, "Info is checked? %s\n", actionInfo_messages->isChecked() ? "yes" : "no");
829 // menuBar()->repaint();
833 * Allows to set options in GUI window.
834 * Additional window is displayed to set kernel options which are saved in
835 * vlp.cfg file in kernel executable directory.
837 void QKernel::on_actionOptions_triggered()
839 QDialog dlg(this, Qt::Dialog);
840 dlg.setWindowTitle("Options");
845 progs = new QLineEdit(progdir, &dlg);
846 progs->setGeometry(150, 20, 180, 30);
849 tmpQLabel = new QLabel("Programs directory", &dlg);
850 tmpQLabel->setGeometry(30, 20, 120, 30);
853 tmpQFrame = new QFrame(&dlg);
854 tmpQFrame->setGeometry(10, 60, 380, 30);
855 tmpQFrame->setFrameStyle(52);
857 tmpQLabel = new QLabel("Virtual Processor properties (activated after "
858 "restarting VLP):", &dlg);
859 tmpQLabel->setGeometry(10, 80, 340, 30);
863 sprintf(nns, "%d", NodeNumber);
864 nn = new QLineEdit(nns, &dlg);
865 nn->setGeometry(110, 110, 40, 30);
867 tmpQLabel = new QLabel("Node number:", &dlg);
868 tmpQLabel->setGeometry(20, 110, 90, 30);
870 QRadioButton *exp, *reg;
871 exp = new QRadioButton("Explicit", &dlg);
872 exp->setGeometry(30, 170, 100, 30);
873 exp->setChecked(TRUE);
875 reg = new QRadioButton("Registration", &dlg);
876 reg->setGeometry(30, 200, 100, 30);
877 reg->setEnabled(FALSE);
879 connections = new QListWidget(&dlg);
880 connections->setGeometry(170, 140, 130, 100);
882 for (int i = 0; i < ConnectList.size(); i++) {
883 e = ConnectList.at(i);
884 connections->addItem(e->addr);
887 tmpQLabel = new QLabel("Connection list:", &dlg);
888 tmpQLabel->setGeometry(170, 110, 100, 30);
893 QPushButton *cancelbtn;
894 addbtn = new QPushButton("Add", &dlg);
895 addbtn->setGeometry(310, 150, 60, 30);
896 connect(addbtn, SIGNAL(clicked()), this, SLOT(AddAddress()));
898 delbtn = new QPushButton("Del", &dlg);
899 delbtn->setGeometry(310, 200, 60, 30);
900 connect(delbtn, SIGNAL(clicked()), this, SLOT(DelAddress()));
902 okbtn = new QPushButton("Ok", &dlg);
903 okbtn->setGeometry(80, 260, 100, 30);
904 okbtn->setDefault(TRUE);
905 connect(okbtn, SIGNAL(clicked()), &dlg, SLOT(accept()));
907 cancelbtn = new QPushButton("Cancel", &dlg);
908 cancelbtn->setGeometry(210, 260, 100, 30);
909 connect(cancelbtn, SIGNAL(clicked()), &dlg, SLOT(reject()));
912 group = new QGroupBox("Connection type", &dlg);
913 group->setGeometry(20, 150, 120, 90);
914 group->setAlignment(Qt::AlignLeft);
917 QVBoxLayout *vbox = new QVBoxLayout();
918 vbox->addWidget(exp);
919 vbox->addWidget(reg);
921 group->setLayout(vbox);
923 dlg.resize(400, 310);
926 config_setting_t *root;
927 config_setting_t *setting;
930 root = config_root_setting(&cfg);
932 setting = config_setting_add(root, "progdir",
934 config_setting_set_string(setting, progs->text().toAscii().data());
935 strcpy(progdir, progs->text().toAscii().data());
937 setting = config_setting_add(root, "node_number",
939 config_setting_set_int(setting, atoi(nn->text().toAscii().data()));
941 setting = config_setting_add(root, "homedir",
943 config_setting_set_string(setting, HomeDir);
945 setting = config_setting_add(root, "type",
947 if (exp->isChecked()) {
948 config_setting_set_string(setting, "explicit");
950 config_setting_t *hosts = NULL;
951 hosts = config_setting_add(root, "host",
953 for(i = 0; i < connections->count(); i++) {
954 setting = config_setting_add(hosts, NULL,
956 config_setting_set_string(setting,
957 connections->item(i)->text().toAscii().data());
960 config_setting_set_string(setting, "register");
963 if (!config_write_file(&cfg, "vlp.cfg")) {
964 fprintf(stderr, "Error while writing to file: %s.\n",
967 config_destroy(&cfg);
972 * Locks kernel program.
973 * Additional window is displayed to enter password and retype it. If both are
974 * same kernel window is locked.
976 void QKernel::on_actionLock_console_triggered()
978 QDialog d(this, Qt::Dialog);
979 d.setWindowTitle("Lock console");
981 QPushButton ob("Ok", &d);
982 ob.setGeometry(30, 60, 80, 30);
984 connect(&ob, SIGNAL(clicked()), &d, SLOT(accept()));
986 QLabel lab("Password:", &d);
987 lab.setGeometry(10, 10, 60, 30);
989 QLineEdit ed("", &d);
990 ed.setGeometry(70, 10, 140, 30);
991 ed.setEchoMode(QLineEdit::Password);
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(), "") != 0) {
1001 strcpy(LockPasswd, ed.text().toAscii().data());
1002 lab.setText("Retype:");
1005 * Following exec(), could produce error:
1006 * X Error: BadWindow (invalid Window parameter) 3
1007 * Major opcode: 3 (X_GetWindowAttributes)
1009 * This is not error in our code. Basing on:
1010 * https://bugreports.qt-project.org/browse/QTBUG-1782
1011 * this happens only on Qt 4.3 - 4.4.
1014 if (strcmp(ed.text().toAscii().data(), LockPasswd) == 0) {
1016 WriteMessage("CONSOLE LOCKED");
1018 QMessageBox msg(this);
1019 msg.setText("Not matching!");
1020 msg.setButtonText(0, "Close");
1024 strcpy(LockPasswd, "");
1031 * Unlocks kernel program.
1032 * Additional window is displayed to enter password. If it is correct, kernel
1033 * window is unlocked
1035 void QKernel::on_actionUnlock_console_triggered()
1037 QDialog d(this, Qt::Dialog);
1038 d.setWindowTitle("Enter password");
1040 QLabel lab("Password:", &d);
1041 lab.setGeometry(10, 10, 60, 30);
1043 QLineEdit ed("", &d);
1044 ed.setGeometry(70, 10, 140, 30);
1045 ed.setEchoMode(QLineEdit::Password);
1047 QPushButton ob("Ok", &d);
1048 ob.setGeometry(30, 60, 80, 30);
1049 ob.setDefault(TRUE);
1050 connect(&ob, SIGNAL(clicked()), &d, SLOT(accept()));
1052 QPushButton cb("Cancel", &d);
1053 cb.setGeometry(130, 60, 80, 30);
1054 connect(&cb, SIGNAL(clicked()), &d, SLOT(reject()));
1059 if (strcmp(ed.text().toAscii().data(), LockPasswd) == 0) {
1061 WriteMessage("CONSOLE UNLOCKED");
1063 QMessageBox msg(this);
1064 msg.setText("Wrong password!");
1065 msg.setButtonText(0, "Close");
1072 * Writes init message in kernel
1074 void QKernel::InitMessage()
1076 WriteMessage("\n " PACKAGE_STRING ": READY \n");
1080 * Finds Interpreter by its socket
1081 * @param _id ID of the socket
1082 * @return returns pointer to the found interpreter slot. NULL otherwise
1084 InterpEntry *QKernel::findINTbySocket(int _id)
1086 InterpEntry *pom = NULL;
1088 for (int i = 0; i < Interpreters.size(); i++) {
1089 if (Interpreters.at(i)->sock == _id) {
1090 pom = Interpreters.at(i);
1099 * Finds Interpreter by its ID.
1100 * @param _id ID of the interpreter
1101 * @return returns pointer to the found interpreter slot. NULL otherwise
1103 InterpEntry *QKernel::findINTbyID(int _id)
1105 InterpEntry *pom = NULL;
1107 for (int i = 0; i < Interpreters.size(); i++) {
1108 if (Interpreters.at(i)->ID == _id) {
1109 pom = Interpreters.at(i);
1119 * Connects interpreter
1120 * @param ss full filepath with filename but without extension of the loglan
1122 * @param r Interpreter execution mode. 0 if it will be local instance, 1 if
1124 * @return Returns pointer to newly created interpreter slot, or NULL on error.
1126 InterpEntry *QKernel::RunIntModule(char *ss, int r)
1128 char a[256], b[255];
1129 struct sockaddr_un svr;
1130 int len, sock, i, on;
1135 InterpEntry *newINT = NULL;
1141 WriteMessage("File not found: no .ccd file");
1150 WriteMessage("File not found: no .pcd file");
1155 newINT = new InterpEntry;
1156 for(i = 0; i < MAXINSTANCES; i++)
1157 newINT->RInstances[i] =- 1;
1159 strcpy(b, rindex(ss, '/'));
1160 for(i = 0; i < strlen(b); i++)
1162 if (info_messages) {
1163 sprintf(a, "%s : Start execution", b);
1169 newINT->ID = newint;
1170 strcpy(newINT->shortname, b);
1171 strcpy(newINT->fullname, ss);
1173 sprintf(a, "%s%d", IPATH, newint);
1174 sprintf(cmd, "%s/modules/logint %s %s", HomeDir, a, ss);
1177 sprintf(b, " %s %s %s %s %s", myargs[0], myargs[1], myargs[2],
1178 myargs[3], myargs[4]);
1182 sock = socket(AF_UNIX, SOCK_STREAM, 0);
1184 bzero(&svr, sizeof(svr));
1185 svr.sun_family = AF_UNIX;
1186 strcpy(svr.sun_path, a);
1187 len = strlen(svr.sun_path)+sizeof(svr.sun_family);
1188 bind(sock, (struct sockaddr*)&svr, len);
1191 newINT->sock = accept(sock, (struct sockaddr*)0, (unsigned int *)0);
1194 if (newINT->sock > 0) {
1195 fcntl(newINT->sock, F_SETFL,
1196 O_NONBLOCK|fcntl(newINT->sock, F_GETFL, 0));
1198 setsockopt(newINT->sock, IPPROTO_TCP, TCP_NODELAY, (char*)&on,
1205 bzero(&msg, sizeof(MESSAGE));
1206 msg.msg_type = MSG_VLP;
1207 msg.param.pword[0] = VLP_REGINT;
1208 msg.param.pword[1] = newINT->ID;
1209 sprintf(msg.param.pstr, "logi%d.net", newint);
1210 write(net_sock, &msg, sizeof(MESSAGE));
1212 Interpreters.append(newINT);
1213 newINT->notify = new QSocketNotifier(newINT->sock,
1214 QSocketNotifier::Read);
1215 connect(newINT->notify, SIGNAL(activated(int)), this,
1216 SLOT(IntMessage(int)));
1218 WriteMessage("INTERPRETER successfully connected");
1220 WriteMessage("Cannot connect interpreter");
1227 * Allocates remote instance of interpreter
1228 * @param interp Interpreter slot
1229 * @param on Node Number
1231 void QKernel::RemoteInstance(InterpEntry *interp, int on)
1236 m.msg_type = MSG_NET;
1237 m.param.pword[0] = NET_NODE_EXIST;
1238 m.param.pword[1] = on;
1239 m.param.pword[2] = interp->ID;
1240 write(net_sock, &m, sizeof(MESSAGE));
1241 bzero(&m, sizeof(MESSAGE));
1242 while((m.msg_type!=MSG_NET) && (m.param.pword[0]!=NET_NODE_EXIST))
1243 read(net_sock, &m, sizeof(MESSAGE));
1245 /* means node exists */
1246 if (m.param.pword[1] == 1) {
1247 m.msg_type = MSG_NET;
1248 m.param.pword[0] = NET_TRANSMIT_CODE;
1249 m.param.pword[1] = interp->ID;
1250 m.param.pword[2] = on;
1251 strcpy(m.param.pstr, interp->fullname);
1252 write(net_sock, &m, sizeof(MESSAGE));
1254 Net_Notify->setEnabled(FALSE);
1255 while ((m.msg_type != MSG_NET) ||
1256 (m.param.pword[0] != NET_TRANSMITTED))
1257 read(net_sock, &m, sizeof(MESSAGE));
1259 m.msg_type = MSG_NET;
1260 m.param.pword[0] = NET_PROPAGATE;
1261 m.param.pword[1] = MSG_VLP;
1262 m.param.pword[2] = NodeNumber;
1263 m.param.pword[3] = 0;
1264 m.param.pword[4] = on;
1265 m.param.pword[5] = 0;
1266 m.param.pword[6] = VLP_REMOTE_INSTANCE;
1267 m.param.pword[7] = interp->ID;
1268 strcpy(m.param.pstr, interp->shortname);
1269 write(net_sock, &m, sizeof(MESSAGE));
1271 read(net_sock, &m, sizeof(MESSAGE));
1273 if ((m.param.pword[0] == NET_PROPAGATE) &&
1274 (m.param.pword[6] == VLP_REMOTE_INSTANCE_OK)) {
1275 interp->RInstances[on] = m.param.pword[7];
1278 read(net_sock, &m, sizeof(MESSAGE));
1281 Net_Notify->setEnabled(TRUE);
1283 /*bzero(&m, sizeof(MESSAGE));*/
1284 m.msg_type = MSG_VLP;
1285 m.param.pword[0] = VLP_REMOTE_INSTANCE_HERE;
1286 m.param.pword[1] = interp->RInstances[on];
1287 write(interp->sock, &m, sizeof(MESSAGE));
1288 } else { /* There is no such a node! */
1289 sprintf(s, "Warning: Node number %d not found!", on);
1291 WriteMessage("Allocating O-process on the local node");
1292 bzero(&m, sizeof(MESSAGE));
1293 m.msg_type = MSG_VLP;
1294 m.param.pword[0] = VLP_REMOTE_INSTANCE_HERE;
1295 m.param.pword[1] = interp->ID;
1296 write(interp->sock, &m, sizeof(MESSAGE));
1301 * Closes all remote instances
1303 void QKernel::CloseInstances(InterpEntry *e)
1309 WriteMessage("Closing remote instances");
1311 for(i=0; i < MAXINSTANCES; i++)
1312 if (e->RInstances[i]>=0) {
1313 msg.msg_type = MSG_NET;
1314 msg.param.pword[0] = NET_PROPAGATE;
1315 msg.param.pword[1] = MSG_VLP;
1316 msg.param.pword[2] = NodeNumber;
1317 msg.param.pword[4] = i;
1318 msg.param.pword[6] = VLP_CLOSE_INSTANCE;
1319 msg.param.pword[7] = e->RInstances[i];
1320 write(net_sock, &msg, sizeof(MESSAGE));
1325 * Displays information about virtual machine
1327 void QKernel::on_actionInfo_triggered()
1331 WriteMessage(CharLine);
1332 WriteMessage("### Virtual Machine Information ###");
1333 m.msg_type = MSG_NET;
1334 m.param.pword[0] = NET_GET_INFO;
1335 write(net_sock, &m, sizeof(MESSAGE));
1336 wait_for_info = TRUE;
1340 * Program main function
1341 * All program arguments but the first one (argv[0]: program name) are saved and
1342 * passed to all dependent programs on their invocation.
1343 * @param argc Number of program arguments
1344 * @param argv Program arguments
1346 int main(int argc, char **argv)
1349 for(i = 0; i < 5; i++) {
1350 strcpy(myargs[i], "");
1352 for(i = 1; i < argc; i++) {
1353 strcpy(myargs[i - 1], argv[i]);
1356 QApplication * app = new QApplication(argc, argv);
1359 kernel.InitMessage();