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 ************************************************************/
34 //#include <qwindow.h>
35 #include <QtGui/QApplication>
36 #include <QtGui/QMainWindow>
38 //#include <qmlined.h>
39 //#include <qpainter.h>
40 #include <QtGui/QTextEdit>
43 #include <QtGui/QMenuBar>
44 //#include <qmenubar.h>
45 //#include <qpopmenu.h>
47 #include <QtGui/QMessageBox>
48 //#include <qmsgbox.h>
49 //#include <qfiledlg.h>
50 #include <QtGui/QFileDialog>
51 #include <QtGui/QDialog>
52 //#include <qtabdlg.h>
55 //#include <qdialog.h>
56 //#include <qbttngrp.h>
57 #include <QtGui/QLabel>
58 #include <QtGui/QLineEdit>
59 #include <QtGui/QPushButton>
60 #include <QtGui/QRadioButton>
61 #include <QtGui/QGroupBox>
62 #include <QtGui/QVBoxLayout>
64 //#include <qlistbox.h>
65 //#include <qpushbt.h>
66 //#include <qradiobt.h>
68 #include <QtCore/QList>
69 #include <QtGui/QListWidget>
73 //#include <qsocknot.h>
74 #include <QtCore/QSocketNotifier>
76 #include <qwindowsstyle.h>
86 #include <netinet/in.h>
88 #include <libconfig.h>
90 /* File resides in top directory (where are Makefiles)*/
91 #include "../../config.h"
96 #define REMOTE_PATH "REMOTE"
98 #define MAXINSTANCES 256
106 char CharLine[25] = "________________________";
114 /** Interpreter identifier */
116 /** Defines if interpreter is remote or not */
124 QSocketNotifier *notify;
125 /* IDs of my remote INT modules */
126 int RInstances[MAXINSTANCES];
127 /* Parent interpreter info */
138 ConnectEntry(char *s) {
148 class QKernel : public QMainWindow {
162 virtual void resizeEvent(QResizeEvent *ev);
164 void WriteMessage(char* msg);
176 void UnlockConsole();
177 void MessageToNode();
180 void IntMessage(int);
181 void KillInterpreter();
188 virtual void closeEvent (QCloseEvent * e);
191 QList<InterpEntry*> Interpreters;
192 QList<ConnectEntry*> ConnectList;
193 QListWidget *connections;
196 * number of working interpreters
201 * number of connected VLPs
203 int ActiveConnections;
221 QSocketNotifier *Net_Notify;
225 void LoadConfig(char *);
226 void RunGraphModule(char*);
228 InterpEntry *findINTbySocket(int);
229 InterpEntry *findINTbyID(int);
230 InterpEntry *RunIntModule(char *ss, int r);
231 void RemoteInstance(InterpEntry*, int);
232 void CloseInstances(InterpEntry*);
236 * Event invoked on program close.
237 * Closes application. Displays additional window to confirm exit.
239 void QKernel::closeEvent(QCloseEvent * e)
245 * Kernel program constructor.
246 * Prepares everything to work.
250 // QFont f("Helvetica", 10, QFont::Bold);
251 // QFont f1("Helvetica", 10, QFont::Normal);
252 // QFont f2("Times Roman", 10, QFont::Normal);
257 sprintf(ss, "mkdir %s", REMOTE_PATH);
261 info_messages = TRUE;
262 wait_for_info = FALSE;
264 setWindowTitle(PACKAGE_NAME);
265 // setBackgroundColor(white);
267 // bar = new QMenuBar(this);
269 // p = new QPopupMenu();
270 QMenu * programMenu = NULL;
272 programMenu = menuBar()->addMenu("&Program");
273 // prid = bar->insertItem("&Program", p);
274 programMenu->addAction("Execute", this, SLOT(Run_Prog()));
275 programMenu->addAction("Kill", this, SLOT(KillInterpreter()));
278 // mid = bar->insertItem("&Machine", p1);
279 machineMenu = menuBar()->addMenu("&Machine");
280 // p1 = new QPopupMenu();
281 machineMenu->addAction("Message", this, SLOT(MessageToNode()));
282 machineMenu->addSeparator();
283 machineMenu->addAction("Connect", this, SLOT(Connect()));
284 machineMenu->addAction("Disconnect", this, SLOT(Disconnect()));
285 machineMenu->addAction("Info", this, SLOT(Info()));
286 // machineMenu->setFont(f);
288 // toolsid = bar->insertItem("&Tools", p2);
290 // p2 = new QPopupMenu();
291 toolsMenu = menuBar()->addMenu("&Tools");
292 cwid = toolsMenu->addAction("Editor", this, SLOT(Edit()));
293 hid = toolsMenu->addAction("Help", this, SLOT(Help()));
294 toolsMenu->addSeparator();
295 optid = toolsMenu->addAction("Options", this, SLOT(SetOptions()));
296 msgid = toolsMenu->addAction("Info messages", this, SLOT(SetMessages()));
297 msgid->setCheckable(TRUE);
298 msgid->setChecked(TRUE);
299 // toolsMenu->setItemChecked(msgid, TRUE);
300 toolsMenu->addSeparator();
301 lockid = toolsMenu->addAction("Lock console", this, SLOT(LockConsole()));
302 unlockid = toolsMenu->addAction("Unlock console", this,
303 SLOT(UnlockConsole()));
304 // toolsMenu->setItemEnabled(unlockid, FALSE);
305 unlockid->setDisabled(TRUE);
309 qid = menuBar()->addAction("&Quit", this, SLOT(QuitProc()));
312 desktop = new QTextEdit(this);
313 // desktop->setAutoUpdate(TRUE);
314 desktop->setReadOnly(TRUE);
315 // desktop->setFont(f1);
316 QVBoxLayout * layout = new QVBoxLayout();
317 layout->setContentsMargins (3, 0, 3, 0);
318 layout->addWidget(desktop);
319 // layout->addWidget(msg);
320 QWidget *window = new QWidget();
321 window->setLayout(layout);
322 setCentralWidget(window);
327 ActiveConnections = 0;
328 strcpy(LockPasswd, "");
329 LoadConfig("vlp.cfg");
332 Net_Notify = new QSocketNotifier(net_sock, QSocketNotifier::Read, this);
333 connect(Net_Notify, SIGNAL(activated(int)), this, SLOT(NetMessage()));
337 * Event invoked on resizing kernel application window.
338 * @copydoc QWidget::resizeEvent(QResizeEvent*)
340 void QKernel::resizeEvent(QResizeEvent *ev)
342 // QFrame::resizeEvent(ev);
344 // desktop->setGeometry(0, bar->height(), width(),
345 // height() - bar->height());
349 * Displays window with information about not implemented functionality.
351 void QKernel::n_impl()
353 QMessageBox::information(this, "Function info", "This function is not "
354 "implemented yet...", "Ok");
358 * Loads configuration from the given file.
359 * @param fname Filename of the configuration file.
361 void QKernel::LoadConfig(char * fname)
364 config_setting_t *setting;
367 /* Hack for checking if file exists without using external libs.*/
368 FILE * file = fopen(fname, "rt");
370 fprintf(stderr, "Error: Cannot load configuration file %s!\n",
374 /* File exists, so file has been locked. Release it. */
378 /* Read the file. If there is an error, report it and exit. */
379 if (!config_read(&cfg, file)) {
380 fprintf(stderr, "%s! In file %s, line %d\n",
381 config_error_text(&cfg),
382 config_error_file(&cfg),
383 config_error_line(&cfg));
384 config_destroy(&cfg);
386 exit(3);/* from original code. */
389 setting = config_lookup(&cfg, "node_number");
391 NodeNumber = config_setting_get_int(setting);
393 fprintf(stderr, "%s! In file %s, '%s' was not found.\n",
394 "Warning", fname, "node_number");
395 config_destroy(&cfg);
400 setting = config_lookup(&cfg, "type");
402 /* same as strcmp(..) == 0 */
403 if (!strcmp(config_setting_get_string(setting), "explicit")) {
409 fprintf(stderr, "%s! In file %s, '%s' was not found.\n",
410 "Warning", fname, "type");
413 setting = config_lookup(&cfg, "host");
415 switch(config_setting_type(setting)) {
416 /* TODO: Deprecated. Made for back compatibility. */
417 case CONFIG_TYPE_STRING:
418 ConnectList.append(new ConnectEntry((char*)
419 config_setting_get_string(setting)));
421 case CONFIG_TYPE_ARRAY: {
422 int size = config_setting_length(setting);
423 for (int i = 0; i < size; i++) {
424 ConnectList.append(new ConnectEntry((char*)
425 config_setting_get_string_elem(setting,
431 fprintf(stderr, "%s! In file %s, bad entry type for %s."
432 " Will not be read.\n",
433 "Error", fname, "host");
436 fprintf(stderr, "%s! In file %s, '%s' was not found.\n",
437 "Warning", fname, "host");
440 setting = config_lookup(&cfg, "progdir");
442 strncpy(progdir, config_setting_get_string(setting), 256);
444 fprintf(stderr, "%s! In file %s, '%s' was not found.\n",
445 "Warning", fname, "progdir");
448 setting = config_lookup(&cfg, "homedir");
450 strncpy(HomeDir, config_setting_get_string(setting), 255);
452 fprintf(stderr, "%s! In file %s, '%s' was not found.\n",
453 "Warning", fname, "homedir");
456 config_destroy(&cfg);
462 * Additional window id displayed to set which code to execute.
464 void QKernel::Run_Prog()
467 QString s = QFileDialog::getOpenFileName(this, "Execute", progdir, "*.log");
470 i = s.indexOf(".log");
475 RunIntModule((char*)s.toAscii().data(), 0);
480 * Invokes editor program
485 sprintf(cmd, "%s/modules/logedit %s %s %s %s %s %s &", HomeDir, HomeDir,
486 myargs[0], myargs[1], myargs[2], myargs[3], myargs[4]);
491 * Invokes help program
496 sprintf(cmd, "%s/modules/loghelp %s/doc %s %s %s %s %s &", HomeDir,
497 HomeDir, myargs[0], myargs[1], myargs[2], myargs[3], myargs[4]);
502 * Invokes graphics module
504 void QKernel::RunGraphModule(char *sk)
508 sprintf(cmd, "%s/modules/loggraph %s %s %s %s %s %s", HomeDir, sk,
509 myargs[0], myargs[1], myargs[2], myargs[3], myargs[4]);
512 if (system(cmd) != 0)
513 WriteMessage("Cannot connect GRAPH resources");
519 void QKernel::RunNetModule()
521 struct sockaddr_un svr;
525 sprintf(cmd, "%s/modules/lognet %s %s %s %s %s %s", HomeDir, NPATH,
526 myargs[0], myargs[1], myargs[2], myargs[3], myargs[4]);
529 /* -------- socket for NET module -------- */
531 sock = socket(AF_UNIX, SOCK_STREAM, 0);
532 bzero(&svr, sizeof(svr));
533 svr.sun_family = AF_UNIX;
534 strcpy(svr.sun_path, NPATH);
535 len = strlen(svr.sun_path) + sizeof(svr.sun_family);
536 bind(sock, (struct sockaddr*)&svr, len);
539 if (system(cmd) == 0) {
540 net_sock = accept(sock, (struct sockaddr*)0, (unsigned int*)0);
543 WriteMessage("NETWORK successfully connected");
544 fcntl(net_sock, F_SETFL, O_NONBLOCK|fcntl(net_sock,
547 setsockopt(net_sock, IPPROTO_TCP, TCP_NODELAY,
548 (char*)&on, sizeof(on));
550 WriteMessage("Cannot connect NETWORK resources");
551 WriteMessage("Exiting...");
557 WriteMessage("Cannot connect NETWORK resources");
558 WriteMessage("Exiting...");
565 * Connects to the specified address
566 * Additional window is displayed to connect to the specified address
568 void QKernel::Connect()
570 QDialog d(this, Qt::Dialog);
571 QLabel lab("IP Address:", &d);
572 QLineEdit ed("", &d);
573 QPushButton ob("", &d);
574 QPushButton cb("", &d);
577 // d.setFont(QFont("Helvetica", 12, QFont::Bold));
578 ob.setGeometry(30, 60, 80, 30);
581 lab.setGeometry(10, 10, 60, 30);
582 lab.setText("Address");
583 ed.setGeometry(70, 10, 140, 30);
584 cb.setGeometry(130, 60, 80, 30);
585 cb.setText("Cancel");
588 connect(&ob, SIGNAL(clicked()), &d, SLOT(accept()));
589 connect(&cb, SIGNAL(clicked()), &d, SLOT(reject()));
591 m.msg_type = MSG_NET;
592 m.param.pword[0] = NET_CONNECT_TO;
593 strcpy(m.param.pstr, ed.text().toAscii().data());
594 write(net_sock, &m, sizeof(MESSAGE));
599 * Disconnects from virtual machine
601 void QKernel::Disconnect()
606 WriteMessage("Disconnecting from virtual machine");
608 msg.msg_type = MSG_NET;
609 msg.param.pword[0] = NET_DISCONNECT;
610 write(net_sock, &msg, sizeof(MESSAGE));
614 * Quits process. Closes VLP. Shows additional window to confirm exit.
616 void QKernel::QuitProc()
620 if (QMessageBox::question(this, "Close VLP", "Terminate VLP ?",
621 QMessageBox::Yes, QMessageBox::No, 0) == QMessageBox::No) {
627 msg.msg_type = MSG_NET;
628 msg.param.pword[0] = NET_DISCONNECT;
629 write(net_sock, &msg, sizeof(MESSAGE));*/
632 msg.msg_type = MSG_NET;
633 msg.param.pword[0] = NET_EXIT;
634 write(net_sock, &msg, sizeof(MESSAGE));
635 /* ::close(net_sock);*/
641 * Adds IP address to the configuration.
642 * Additional window is displayed to add address to the list
644 void QKernel::AddAddress()
646 QDialog d(this, Qt::Dialog);
647 QLabel lab("IP Address:", &d);
648 QLineEdit ed("", &d);
649 QPushButton ob("", &d);
650 QPushButton cb("", &d);
653 ob.setGeometry(30, 60, 80, 30);
656 lab.setGeometry(10, 10, 60, 30);
657 lab.setText("Address");
658 ed.setGeometry(70, 10, 140, 30);
659 cb.setGeometry(130, 60, 80, 30);
660 cb.setText("Cancel");
662 connect(&ob, SIGNAL(clicked()), &d, SLOT(accept()));
663 connect(&cb, SIGNAL(clicked()), &d, SLOT(reject()));
665 if (strcmp(ed.text().toAscii().data(), "") != 0) {
666 connections->addItem(ed.text());
672 * Deletes current address from available connections.
674 void QKernel::DelAddress()
677 if (connections->currentRow() != -1) {
678 /* TODO: Checki if this work correctly after porting */
679 connections->removeItemWidget(connections->currentItem());
685 * Sends message to node.
686 * Additional window is displayed to set Node Number of node where send message,
687 * and textfield to enter message.
689 void QKernel::MessageToNode()
695 dlg = new QDialog(this, Qt::Dialog);
696 dlg->setWindowTitle("Send message to node");
698 nodenr = new QLineEdit("number", dlg);
699 nodenr->setGeometry(90, 10, 50, 30);
703 tmpQLabel = new QLabel("Node number:", dlg);
704 tmpQLabel->setGeometry(10, 10, 77, 30);
706 tmpQLabel = new QLabel("Message:", dlg);
707 tmpQLabel->setGeometry(10, 50, 70, 30);
710 msg = new QLineEdit("", dlg);
711 msg->setGeometry(80, 60, 330, 30);
714 ob = new QPushButton("Send", dlg);
715 ob->setGeometry(230, 10, 80, 30);
716 ob->setDefault(TRUE);
719 cb = new QPushButton("Cancel", dlg);
720 cb->setGeometry(330, 10, 80, 30);
721 dlg->resize(430, 110);
722 connect(ob, SIGNAL(clicked()), dlg, SLOT(accept()));
723 connect(cb, SIGNAL(clicked()), dlg, SLOT(reject()));
726 m.msg_type = MSG_NET;
727 m.param.pword[0] = NET_PROPAGATE;
728 m.param.pword[1] = MSG_VLP;
729 m.param.pword[2] = NodeNumber;
730 m.param.pword[4] = atoi(nodenr->text().toAscii().data());
731 m.param.pword[6] = VLP_WRITE;
732 strcpy(m.param.pstr, msg->text().toAscii().data());
733 write(net_sock, &m, sizeof(MESSAGE));
739 * Additional window is displayed to get ID of interpreter which should be
742 void QKernel::KillInterpreter()
749 dlg = new QDialog(this, Qt::Dialog);
750 dlg->setWindowTitle("Kill interpreter");
752 nodenr = new QLineEdit("", dlg);
753 nodenr->setGeometry(90, 10, 50, 30);
755 QLabel * tmpQLabel = new QLabel("Interp. ID:", dlg);
756 tmpQLabel->setGeometry(10, 10, 77, 30);
758 QPushButton * ob = new QPushButton("Kill", dlg);
759 ob->setGeometry( 160, 10, 80, 30);
760 ob->setDefault(TRUE);
762 QPushButton * cb = new QPushButton("Cancel", dlg);
763 cb->setGeometry(260, 10, 80, 30);
764 dlg->resize(360, 50);
766 connect(ob, SIGNAL(clicked()), dlg, SLOT(accept()));
767 connect(cb, SIGNAL(clicked()), dlg, SLOT(reject()));
770 m.msg_type = MSG_INT;
771 m.param.pword[0] = INT_KILL;
772 pom = findINTbyID(atoi(nodenr->text().toAscii().data()));
775 write(pom->sock, &m, sizeof(MESSAGE));
777 WriteMessage("This is a remote instance of "
781 WriteMessage("Interpreter not found");
787 * Sends message to the net module.
789 void QKernel::NetMessage()
792 /* TODO: It has to be rewritten */
798 cnt = read(net_sock, &msg, sizeof(MESSAGE));
799 if ((cnt > 0) && (msg.msg_type == MSG_NET)) {
800 switch(msg.param.pword[0]) {
802 WriteMessage(msg.param.pstr);
805 switch(msg.param.pword[1]) {
807 /* pom = find_link_by_ID(msg.param.pword[5]);
808 msg.msg_type = MSG_NET;
809 msg.param.pword[0] = NET_PROPAGATE;
810 send_int(pom, &msg);*/
813 switch(msg.param.pword[6]) {
815 QApplication::beep();
816 WriteMessage(CharLine);
818 "### Incoming Messsage ###");
819 sprintf(ss, "Mesg from Node %d: %s",
823 WriteMessage(CharLine);
825 case VLP_REMOTE_INSTANCE:
826 sprintf(ss, "%s/%s", REMOTE_PATH,
830 WriteMessage("Running program:");
833 pom = RunIntModule(ss, 1);
835 pom->p_ctx.node = msg.param.pword[2];
836 pom->p_ctx.program_id =
838 pom->RInstances[msg.param.pword[2]] = msg.param.pword[7];
841 case VLP_CLOSE_INSTANCE:
842 msg.msg_type = MSG_INT;
843 msg.param.pword[0] = INT_CLOSE_INSTANCE;
844 pom = findINTbyID(msg.param.pword[7]);
846 write(pom->sock, &msg,
849 m1.msg_type = MSG_VLP;
850 m1.param.pword[0] = VLP_INTERPRETER_DOWN;
851 m1.param.pword[1] = pom->ID;
855 WriteMessage("Instance not found");
861 case NET_CONNECTIONS:
862 ActiveConnections = msg.param.pword[1];
863 WriteMessage(msg.param.pstr);
868 /* TODO: It has to be rewritten */
870 QString poms, poms1, poms2;
871 poms.sprintf("%s", msg.param.pstr);
872 while (poms.length() > 0) {
873 cnt = poms.indexOf(';');
875 poms1 = poms.left(cnt);
876 poms = poms.right(poms.length() - cnt - 1);
877 cnt = poms1.indexOf('=');
879 poms2 = poms1.left(cnt);
883 sprintf(ss, "Node: %s Addr: %s", poms2.data(), poms1.data());
891 wait_for_info = FALSE;
892 WriteMessage(CharLine);
899 * Sends message to the interpreter program.
900 * @param sock Interpreter socket to whom the message will be send.
902 void QKernel::IntMessage(int sock)
908 cnt = read(sock, &msg, sizeof(MESSAGE));
909 e = findINTbySocket(sock);
910 if ((cnt > 0) && (e != NULL)) {
911 switch (msg.msg_type) {
913 if (msg.param.pword[0] == GRAPH_ALLOCATE) {
914 RunGraphModule(msg.param.pstr);
918 write(net_sock, &msg, sizeof(MESSAGE));
921 switch(msg.param.pword[0]) {
922 case VLP_REMOTE_INSTANCE_PLEASE:
923 RemoteInstance(e, msg.param.pword[2]);
928 switch(msg.param.pword[0]) {
933 m.msg_type = MSG_VLP;
934 m.param.pword[0] = VLP_INTERPRETER_DOWN;
935 m.param.pword[1] = e->ID;
936 write(net_sock, &m, sizeof(MESSAGE));
941 /* TODO: Check this */
942 Interpreters.removeOne(e);
946 sprintf(ss, "%s : End of program "
947 "execution", msg.param.pstr);
952 msg.msg_type = MSG_INT;
953 msg.param.pword[0] = INT_CTX;
954 msg.param.pword[1] = NodeNumber;
955 msg.param.pword[2] = e->ID;
957 msg.param.pword[3] = e->p_ctx.node;
961 write(sock, &msg, sizeof(MESSAGE));
970 * Writes message to kernel logger.
971 * @parame msg String with message to log
973 void QKernel::WriteMessage(char *msg)
977 x = desktop->textCursor().blockNumber();
978 y = desktop->textCursor().columnNumber();
984 desktop->setReadOnly(FALSE);
985 desktop->append(msg);
986 desktop->setReadOnly(TRUE);
987 // desktop->setCursorPosition(desktop->blockCount(), 1);
988 QTextCursor tmpCursor = desktop->textCursor();
989 tmpCursor.movePosition(QTextCursor::End, QTextCursor::MoveAnchor);
990 desktop->setTextCursor(tmpCursor);
994 if (desktop->document()->blockCount() > 100) {
1000 * Adds checkbox to menu item. If it is checked additional info messages are
1003 void QKernel::SetMessages()
1005 if (toolsMenu != NULL) {
1006 if (msgid->isChecked()) {
1007 msgid->setChecked(FALSE);
1008 info_messages = FALSE;
1010 msgid->setChecked(TRUE);
1011 info_messages = TRUE;
1014 /* bar->repaint(); */
1018 * Allows to set options in GUI window.
1019 * Additional window is displayed to set kernel options which are saved in
1020 * vlp.cfg file in kernel executable directory.
1022 void QKernel::SetOptions()
1024 QDialog dlg(this, Qt::Dialog);
1025 dlg.setWindowTitle("Options");
1030 progs = new QLineEdit(progdir, &dlg);
1031 progs->setGeometry(150, 20, 180, 30);
1034 tmpQLabel = new QLabel("Programs directory", &dlg);
1035 tmpQLabel->setGeometry(30, 20, 120, 30);
1038 tmpQFrame = new QFrame(&dlg);
1039 tmpQFrame->setGeometry(10, 60, 380, 30);
1040 tmpQFrame->setFrameStyle(52);
1042 tmpQLabel = new QLabel("Virtual Processor properties (activated after "
1043 "restarting VLP):", &dlg);
1044 tmpQLabel->setGeometry(10, 80, 340, 30);
1048 sprintf(nns, "%d", NodeNumber);
1049 nn = new QLineEdit(nns, &dlg);
1050 nn->setGeometry(110, 110, 40, 30);
1052 tmpQLabel = new QLabel("Node number:", &dlg);
1053 tmpQLabel->setGeometry(20, 110, 90, 30);
1055 QRadioButton *exp, *reg;
1056 exp = new QRadioButton("Explicit", &dlg);
1057 exp->setGeometry(30, 170, 100, 30);
1058 exp->setChecked(TRUE);
1060 reg = new QRadioButton("Registration", &dlg);
1061 reg->setGeometry(30, 200, 100, 30);
1062 reg->setEnabled(FALSE);
1064 connections = new QListWidget(&dlg);
1065 connections->setGeometry(170, 140, 130, 100);
1067 for (int i = 0; i < ConnectList.size(); i++) {
1068 e = ConnectList.at(i);
1069 connections->addItem(e->addr);
1072 tmpQLabel = new QLabel("Connection list:", &dlg);
1073 tmpQLabel->setGeometry(170, 110, 100, 30);
1075 QPushButton *addbtn;
1076 QPushButton *delbtn;
1078 QPushButton *cancelbtn;
1079 addbtn = new QPushButton("Add", &dlg);
1080 addbtn->setGeometry(310, 150, 60, 30);
1081 connect(addbtn, SIGNAL(clicked()), this, SLOT(AddAddress()));
1083 delbtn = new QPushButton("Del", &dlg);
1084 delbtn->setGeometry(310, 200, 60, 30);
1085 connect(delbtn, SIGNAL(clicked()), this, SLOT(DelAddress()));
1087 okbtn = new QPushButton("Ok", &dlg);
1088 okbtn->setGeometry(80, 260, 100, 30);
1089 okbtn->setDefault(TRUE);
1090 connect(okbtn, SIGNAL(clicked()), &dlg, SLOT(accept()));
1092 cancelbtn = new QPushButton("Cancel", &dlg);
1093 cancelbtn->setGeometry(210, 260, 100, 30);
1094 connect(cancelbtn, SIGNAL(clicked()), &dlg, SLOT(reject()));
1097 group = new QGroupBox("Connection type", &dlg);
1098 group->setGeometry(20, 150, 120, 90);
1099 group->setAlignment(Qt::AlignLeft);
1102 QVBoxLayout *vbox = new QVBoxLayout();
1103 vbox->addWidget(exp);
1104 vbox->addWidget(reg);
1105 vbox->addStretch(1);
1106 group->setLayout(vbox);
1108 dlg.resize(400, 310);
1111 config_setting_t *root;
1112 config_setting_t *setting;
1115 root = config_root_setting(&cfg);
1117 setting = config_setting_add(root, "progdir",
1118 CONFIG_TYPE_STRING);
1119 config_setting_set_string(setting, progs->text().toAscii().data());
1120 strcpy(progdir, progs->text().toAscii().data());
1122 setting = config_setting_add(root, "node_number",
1124 config_setting_set_int(setting, atoi(nn->text().toAscii().data()));
1126 setting = config_setting_add(root, "homedir",
1127 CONFIG_TYPE_STRING);
1128 config_setting_set_string(setting, HomeDir);
1130 setting = config_setting_add(root, "type",
1131 CONFIG_TYPE_STRING);
1132 if (exp->isChecked()) {
1133 config_setting_set_string(setting, "explicit");
1135 config_setting_t *hosts = NULL;
1136 hosts = config_setting_add(root, "host",
1138 for(i = 0; i < connections->count(); i++) {
1139 setting = config_setting_add(hosts, NULL,
1140 CONFIG_TYPE_STRING);
1141 config_setting_set_string(setting,
1142 connections->item(i)->text().toAscii().data());
1145 config_setting_set_string(setting, "register");
1148 if (!config_write_file(&cfg, "vlp.cfg")) {
1149 fprintf(stderr, "Error while writing to file: %s.\n",
1152 config_destroy(&cfg);
1157 * Locks kernel program.
1158 * Additional window is displayed to enter password and retype it. If both are
1159 * same kernel window is locked.
1161 void QKernel::LockConsole()
1163 QDialog d(this, Qt::Dialog);
1164 d.setWindowTitle("Lock console");
1166 QPushButton ob("Ok", &d);
1167 ob.setGeometry(30, 60, 80, 30);
1168 ob.setDefault(TRUE);
1169 connect(&ob, SIGNAL(clicked()), &d, SLOT(accept()));
1171 QLabel lab("Password:", &d);
1172 lab.setGeometry(10, 10, 60, 30);
1174 QLineEdit ed("", &d);
1175 ed.setGeometry(70, 10, 140, 30);
1176 ed.setEchoMode(QLineEdit::Password);
1178 QPushButton cb("Cancel", &d);
1179 cb.setGeometry(130, 60, 80, 30);
1180 connect(&cb, SIGNAL(clicked()), &d, SLOT(reject()));
1185 if (strcmp(ed.text().toAscii().data(), "") != 0) {
1186 strcpy(LockPasswd, ed.text().toAscii().data());
1187 lab.setText("Retype:");
1190 if (strcmp(ed.text().toAscii().data(), LockPasswd)==0) {
1191 qid->setEnabled(FALSE);
1192 prid->setEnabled(FALSE);
1193 mid->setEnabled(FALSE);
1194 unlockid->setEnabled(TRUE);
1195 lockid->setEnabled(FALSE);
1196 cwid->setEnabled(FALSE);
1197 optid->setEnabled(FALSE);
1198 // menuBar()->setItemEnabled(qid, FALSE);
1199 // bar->setItemEnabled(prid, FALSE);
1200 // bar->setItemEnabled(mid, FALSE);
1201 // p2->setItemEnabled(unlockid, TRUE);
1202 // p2->setItemEnabled(lockid, FALSE);
1203 // p2->setItemEnabled(cwid, FALSE);
1204 // p2->setItemEnabled(optid, FALSE);
1206 WriteMessage("CONSOLE LOCKED");
1209 QMessageBox msg(this);
1210 msg.setText("Not matching!");
1211 msg.setButtonText(0, "Close");
1215 strcpy(LockPasswd, "");
1222 * Unlocks kernel program.
1223 * Additional window is displayed to enter password. If it is correct, kernel
1224 * window is unlocked
1226 void QKernel::UnlockConsole()
1228 QDialog d(this, Qt::Dialog);
1229 d.setWindowTitle("Enter password");
1231 QLabel lab("Password:", &d);
1232 lab.setGeometry(10, 10, 60, 30);
1234 QLineEdit ed("", &d);
1235 ed.setGeometry(70, 10, 140, 30);
1236 ed.setEchoMode(QLineEdit::Password);
1238 QPushButton ob("Ok", &d);
1239 ob.setGeometry(30, 60, 80, 30);
1240 ob.setDefault(TRUE);
1241 connect(&ob, SIGNAL(clicked()), &d, SLOT(accept()));
1243 QPushButton cb("Cancel", &d);
1244 cb.setGeometry(130, 60, 80, 30);
1245 connect(&cb, SIGNAL(clicked()), &d, SLOT(reject()));
1250 if (strcmp(ed.text().toAscii().data(), LockPasswd) == 0) {
1251 qid->setEnabled(TRUE);
1252 prid->setEnabled(TRUE);
1253 mid->setEnabled(TRUE);
1254 unlockid->setEnabled(FALSE);
1255 lockid->setEnabled(TRUE);
1256 cwid->setEnabled(TRUE);
1257 optid->setEnabled(TRUE);
1258 // bar->setItemEnabled(qid, TRUE);
1259 // bar->setItemEnabled(prid, TRUE);
1260 // bar->setItemEnabled(mid, TRUE);
1261 // p2->setItemEnabled(unlockid, FALSE);
1262 // p2->setItemEnabled(lockid, TRUE);
1263 // p2->setItemEnabled(cwid, TRUE);
1264 // p2->setItemEnabled(optid, TRUE);
1266 WriteMessage("CONSOLE UNLOCKED");
1269 QMessageBox msg(this);
1270 msg.setText("Wrong password!");
1271 msg.setButtonText(0, "Close");
1278 * Writes init message in kernel
1280 void QKernel::InitMessage()
1282 WriteMessage("\n " PACKAGE_STRING ": READY \n");
1286 * Finds Interpreter by its socket
1287 * @param _id ID of the socket
1288 * @return returns pointer to the found interpreter slot. NULL otherwise
1290 InterpEntry *QKernel::findINTbySocket(int _id)
1292 InterpEntry *pom = NULL;
1294 for (int i = 0; i < Interpreters.size(); i++) {
1295 if (Interpreters.at(i)->sock == _id) {
1296 pom = Interpreters.at(i);
1305 * Finds Interpreter by its ID.
1306 * @param _id ID of the interpreter
1307 * @return returns pointer to the found interpreter slot. NULL otherwise
1309 InterpEntry *QKernel::findINTbyID(int _id)
1311 InterpEntry *pom = NULL;
1313 for (int i = 0; i < Interpreters.size(); i++) {
1314 if (Interpreters.at(i)->ID == _id) {
1315 pom = Interpreters.at(i);
1325 * Connects interpreter
1326 * @param ss full filepath with filename but without extension of the loglan
1328 * @param r Interpreter execution mode. 0 if it will be local instance, 1 if
1330 * @return Returns pointer to newly created interpreter slot, or NULL on error.
1332 InterpEntry *QKernel::RunIntModule(char *ss, int r)
1334 char a[256], b[255];
1335 struct sockaddr_un svr;
1336 int len, sock, i, on;
1341 InterpEntry *newINT = NULL;
1347 WriteMessage("File not found: no .ccd file");
1356 WriteMessage("File not found: no .pcd file");
1361 newINT = new InterpEntry;
1362 for(i = 0; i < MAXINSTANCES; i++)
1363 newINT->RInstances[i] =- 1;
1365 strcpy(b, rindex(ss, '/'));
1366 for(i = 0; i < strlen(b); i++)
1368 if (info_messages) {
1369 sprintf(a, "%s : Start execution", b);
1375 newINT->ID = newint;
1376 strcpy(newINT->shortname, b);
1377 strcpy(newINT->fullname, ss);
1379 sprintf(a, "%s%d", IPATH, newint);
1380 sprintf(cmd, "%s/modules/logint %s %s", HomeDir, a, ss);
1383 sprintf(b, " %s %s %s %s %s", myargs[0], myargs[1], myargs[2],
1384 myargs[3], myargs[4]);
1388 sock = socket(AF_UNIX, SOCK_STREAM, 0);
1390 bzero(&svr, sizeof(svr));
1391 svr.sun_family = AF_UNIX;
1392 strcpy(svr.sun_path, a);
1393 len = strlen(svr.sun_path)+sizeof(svr.sun_family);
1394 bind(sock, (struct sockaddr*)&svr, len);
1397 newINT->sock = accept(sock, (struct sockaddr*)0, (unsigned int *)0);
1400 if (newINT->sock > 0) {
1401 fcntl(newINT->sock, F_SETFL,
1402 O_NONBLOCK|fcntl(newINT->sock, F_GETFL, 0));
1404 setsockopt(newINT->sock, IPPROTO_TCP, TCP_NODELAY, (char*)&on,
1411 bzero(&msg, sizeof(MESSAGE));
1412 msg.msg_type = MSG_VLP;
1413 msg.param.pword[0] = VLP_REGINT;
1414 msg.param.pword[1] = newINT->ID;
1415 sprintf(msg.param.pstr, "logi%d.net", newint);
1416 write(net_sock, &msg, sizeof(MESSAGE));
1418 Interpreters.append(newINT);
1419 newINT->notify = new QSocketNotifier(newINT->sock,
1420 QSocketNotifier::Read);
1421 connect(newINT->notify, SIGNAL(activated(int)), this,
1422 SLOT(IntMessage(int)));
1424 WriteMessage("INTERPRETER successfully connected");
1426 WriteMessage("Cannot connect interpreter");
1433 * Allocates remote instance of interpreter
1434 * @param interp Interpreter slot
1435 * @param on Node Number
1437 void QKernel::RemoteInstance(InterpEntry *interp, int on)
1442 m.msg_type = MSG_NET;
1443 m.param.pword[0] = NET_NODE_EXIST;
1444 m.param.pword[1] = on;
1445 m.param.pword[2] = interp->ID;
1446 write(net_sock, &m, sizeof(MESSAGE));
1447 bzero(&m, sizeof(MESSAGE));
1448 while((m.msg_type!=MSG_NET) && (m.param.pword[0]!=NET_NODE_EXIST))
1449 read(net_sock, &m, sizeof(MESSAGE));
1451 /* means node exists */
1452 if (m.param.pword[1] == 1) {
1453 m.msg_type = MSG_NET;
1454 m.param.pword[0] = NET_TRANSMIT_CODE;
1455 m.param.pword[1] = interp->ID;
1456 m.param.pword[2] = on;
1457 strcpy(m.param.pstr, interp->fullname);
1458 write(net_sock, &m, sizeof(MESSAGE));
1460 Net_Notify->setEnabled(FALSE);
1461 while ((m.msg_type != MSG_NET) ||
1462 (m.param.pword[0] != NET_TRANSMITTED))
1463 read(net_sock, &m, sizeof(MESSAGE));
1465 m.msg_type = MSG_NET;
1466 m.param.pword[0] = NET_PROPAGATE;
1467 m.param.pword[1] = MSG_VLP;
1468 m.param.pword[2] = NodeNumber;
1469 m.param.pword[3] = 0;
1470 m.param.pword[4] = on;
1471 m.param.pword[5] = 0;
1472 m.param.pword[6] = VLP_REMOTE_INSTANCE;
1473 m.param.pword[7] = interp->ID;
1474 strcpy(m.param.pstr, interp->shortname);
1475 write(net_sock, &m, sizeof(MESSAGE));
1477 read(net_sock, &m, sizeof(MESSAGE));
1479 if ((m.param.pword[0] == NET_PROPAGATE) &&
1480 (m.param.pword[6] == VLP_REMOTE_INSTANCE_OK)) {
1481 interp->RInstances[on] = m.param.pword[7];
1484 read(net_sock, &m, sizeof(MESSAGE));
1487 Net_Notify->setEnabled(TRUE);
1489 /*bzero(&m, sizeof(MESSAGE));*/
1490 m.msg_type = MSG_VLP;
1491 m.param.pword[0] = VLP_REMOTE_INSTANCE_HERE;
1492 m.param.pword[1] = interp->RInstances[on];
1493 write(interp->sock, &m, sizeof(MESSAGE));
1494 } else { /* There is no such a node! */
1495 sprintf(s, "Warning: Node number %d not found!", on);
1497 WriteMessage("Allocating O-process on the local node");
1498 bzero(&m, sizeof(MESSAGE));
1499 m.msg_type = MSG_VLP;
1500 m.param.pword[0] = VLP_REMOTE_INSTANCE_HERE;
1501 m.param.pword[1] = interp->ID;
1502 write(interp->sock, &m, sizeof(MESSAGE));
1507 * Closes all remote instances
1509 void QKernel::CloseInstances(InterpEntry *e)
1515 WriteMessage("Closing remote instances");
1517 for(i=0; i < MAXINSTANCES; i++)
1518 if (e->RInstances[i]>=0) {
1519 msg.msg_type = MSG_NET;
1520 msg.param.pword[0] = NET_PROPAGATE;
1521 msg.param.pword[1] = MSG_VLP;
1522 msg.param.pword[2] = NodeNumber;
1523 msg.param.pword[4] = i;
1524 msg.param.pword[6] = VLP_CLOSE_INSTANCE;
1525 msg.param.pword[7] = e->RInstances[i];
1526 write(net_sock, &msg, sizeof(MESSAGE));
1531 * Displays information about virtual machine
1533 void QKernel::Info()
1537 WriteMessage(CharLine);
1538 WriteMessage("### Virtual Machine Information ###");
1539 m.msg_type = MSG_NET;
1540 m.param.pword[0] = NET_GET_INFO;
1541 write(net_sock, &m, sizeof(MESSAGE));
1542 wait_for_info = TRUE;
1545 #include "kernel.moc"
1548 * Program main function
1549 * All program arguments but the first one (argv[0]: program name) are saved and
1550 * passed to all dependent programs on their invocation.
1551 * @param argc Number of program arguments
1552 * @param argv Program arguments
1554 int main(int argc, char **argv)
1557 for(i = 0; i < 5; i++) {
1558 strcpy(myargs[i], "");
1560 for(i = 1; i < argc; i++) {
1561 strcpy(myargs[i - 1], argv[i]);
1564 app = new QApplication(argc, argv);
1565 // app->setStyle(new QWindowsStyle());
1567 // app->setCentralWidget(&kernel);
1569 kernel.InitMessage();