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>
62 #include <netinet/in.h>
64 #include <libconfig.h>
66 /* File resides in top directory (where are Makefiles)*/
67 #include "../../config.h"
72 #define REMOTE_PATH "REMOTE"
74 #define MAXINSTANCES 256
82 char CharLine[25] = "________________________";
90 /** Interpreter identifier */
92 /** Defines if interpreter is remote or not */
100 QSocketNotifier *notify;
101 /* IDs of my remote INT modules */
102 int RInstances[MAXINSTANCES];
103 /* Parent interpreter info */
114 ConnectEntry(char *s) {
124 class QKernel : public QMainWindow {
138 virtual void resizeEvent(QResizeEvent *ev);
140 void WriteMessage(char* msg);
152 void UnlockConsole();
153 void MessageToNode();
156 void IntMessage(int);
157 void KillInterpreter();
164 virtual void closeEvent (QCloseEvent * e);
167 QList<InterpEntry*> Interpreters;
168 QList<ConnectEntry*> ConnectList;
169 QListWidget *connections;
172 * number of working interpreters
173 * @attention Currently not in use
178 * number of connected VLPs
180 int ActiveConnections;
198 QSocketNotifier *Net_Notify;
202 void LoadConfig(char *);
203 void RunGraphModule(char*);
205 InterpEntry *findINTbySocket(int);
206 InterpEntry *findINTbyID(int);
207 InterpEntry *RunIntModule(char *ss, int r);
208 void RemoteInstance(InterpEntry*, int);
209 void CloseInstances(InterpEntry*);
213 * Event invoked on program close.
214 * Closes application. Displays additional window to confirm exit.
216 void QKernel::closeEvent(QCloseEvent * e)
222 * Kernel program constructor.
223 * Prepares everything to work.
231 sprintf(ss, "mkdir %s", REMOTE_PATH);
235 info_messages = TRUE;
236 wait_for_info = FALSE;
238 setWindowTitle(PACKAGE_NAME);
240 QMenu * programMenu = NULL;
241 programMenu = menuBar()->addMenu("&Program");
242 programMenu->addAction("Execute", this, SLOT(Run_Prog()));
243 programMenu->addAction("Kill", this, SLOT(KillInterpreter()));
246 machineMenu = menuBar()->addMenu("&Machine");
247 machineMenu->addAction("Message", this, SLOT(MessageToNode()));
248 machineMenu->addSeparator();
249 machineMenu->addAction("Connect", this, SLOT(Connect()));
250 machineMenu->addAction("Disconnect", this, SLOT(Disconnect()));
251 machineMenu->addAction("Info", this, SLOT(Info()));
253 toolsMenu = menuBar()->addMenu("&Tools");
254 cwid = toolsMenu->addAction("Editor", this, SLOT(Edit()));
255 hid = toolsMenu->addAction("Help", this, SLOT(Help()));
256 toolsMenu->addSeparator();
257 optid = toolsMenu->addAction("Options", this, SLOT(SetOptions()));
258 msgid = toolsMenu->addAction("Info messages", this, SLOT(SetMessages()));
259 msgid->setCheckable(TRUE);
260 msgid->setChecked(TRUE);
261 toolsMenu->addSeparator();
262 lockid = toolsMenu->addAction("Lock console", this, SLOT(LockConsole()));
263 unlockid = toolsMenu->addAction("Unlock console", this,
264 SLOT(UnlockConsole()));
265 unlockid->setDisabled(TRUE);
268 qid = menuBar()->addAction("&Quit", this, SLOT(QuitProc()));
270 desktop = new QTextEdit(this);
271 desktop->setReadOnly(TRUE);
272 QVBoxLayout * layout = new QVBoxLayout();
273 layout->setContentsMargins (3, 0, 3, 0);
274 layout->addWidget(desktop);
275 QWidget *window = new QWidget();
276 window->setLayout(layout);
277 setCentralWidget(window);
282 ActiveConnections = 0;
283 strcpy(LockPasswd, "");
284 LoadConfig("vlp.cfg");
287 Net_Notify = new QSocketNotifier(net_sock, QSocketNotifier::Read, this);
288 connect(Net_Notify, SIGNAL(activated(int)), this, SLOT(NetMessage()));
292 * Event invoked on resizing kernel application window.
293 * @copydoc QWidget::resizeEvent(QResizeEvent*)
295 void QKernel::resizeEvent(QResizeEvent *ev)
297 // QFrame::resizeEvent(ev);
299 // desktop->setGeometry(0, bar->height(), width(),
300 // height() - bar->height());
304 * Displays window with information about not implemented functionality.
306 void QKernel::n_impl()
308 QMessageBox::information(this, "Function info", "This function is not "
309 "implemented yet...", "Ok");
313 * Loads configuration from the given file.
314 * @param fname Filename of the configuration file.
316 void QKernel::LoadConfig(char * fname)
319 config_setting_t *setting;
322 /* Hack for checking if file exists without using external libs.*/
323 FILE * file = fopen(fname, "rt");
325 fprintf(stderr, "Error: Cannot load configuration file %s!\n",
329 /* File exists, so file has been locked. Release it. */
333 /* Read the file. If there is an error, report it and exit. */
334 if (!config_read(&cfg, file)) {
335 fprintf(stderr, "%s! In file %s, line %d\n",
336 config_error_text(&cfg),
337 config_error_file(&cfg),
338 config_error_line(&cfg));
339 config_destroy(&cfg);
341 exit(3);/* from original code. */
344 setting = config_lookup(&cfg, "node_number");
346 NodeNumber = config_setting_get_int(setting);
348 fprintf(stderr, "%s! In file %s, '%s' was not found.\n",
349 "Warning", fname, "node_number");
350 config_destroy(&cfg);
355 setting = config_lookup(&cfg, "type");
357 /* same as strcmp(..) == 0 */
358 if (!strcmp(config_setting_get_string(setting), "explicit")) {
364 fprintf(stderr, "%s! In file %s, '%s' was not found.\n",
365 "Warning", fname, "type");
368 setting = config_lookup(&cfg, "host");
370 switch(config_setting_type(setting)) {
371 /* TODO: Deprecated. Made for back compatibility. */
372 case CONFIG_TYPE_STRING:
373 ConnectList.append(new ConnectEntry((char*)
374 config_setting_get_string(setting)));
376 case CONFIG_TYPE_ARRAY: {
377 int size = config_setting_length(setting);
378 for (int i = 0; i < size; i++) {
379 ConnectList.append(new ConnectEntry((char*)
380 config_setting_get_string_elem(setting,
386 fprintf(stderr, "%s! In file %s, bad entry type for %s."
387 " Will not be read.\n",
388 "Error", fname, "host");
391 fprintf(stderr, "%s! In file %s, '%s' was not found.\n",
392 "Warning", fname, "host");
395 setting = config_lookup(&cfg, "progdir");
397 strncpy(progdir, config_setting_get_string(setting), 256);
399 fprintf(stderr, "%s! In file %s, '%s' was not found.\n",
400 "Warning", fname, "progdir");
403 setting = config_lookup(&cfg, "homedir");
405 strncpy(HomeDir, config_setting_get_string(setting), 255);
407 fprintf(stderr, "%s! In file %s, '%s' was not found.\n",
408 "Warning", fname, "homedir");
411 config_destroy(&cfg);
417 * Additional window id displayed to set which code to execute.
419 void QKernel::Run_Prog()
422 QString s = QFileDialog::getOpenFileName(this, "Execute", progdir, "*.log");
425 i = s.indexOf(".log");
430 RunIntModule((char*)s.toAscii().data(), 0);
435 * Invokes editor program
440 sprintf(cmd, "%s/modules/logedit %s %s %s %s %s %s &", HomeDir, HomeDir,
441 myargs[0], myargs[1], myargs[2], myargs[3], myargs[4]);
446 * Invokes help program
451 sprintf(cmd, "%s/modules/loghelp %s/doc %s %s %s %s %s &", HomeDir,
452 HomeDir, myargs[0], myargs[1], myargs[2], myargs[3], myargs[4]);
457 * Invokes graphics module
459 void QKernel::RunGraphModule(char *sk)
463 sprintf(cmd, "%s/modules/loggraph %s %s %s %s %s %s", HomeDir, sk,
464 myargs[0], myargs[1], myargs[2], myargs[3], myargs[4]);
467 if (system(cmd) != 0)
468 WriteMessage("Cannot connect GRAPH resources");
474 void QKernel::RunNetModule()
476 struct sockaddr_un svr;
480 sprintf(cmd, "%s/modules/lognet %s %s %s %s %s %s", HomeDir, NPATH,
481 myargs[0], myargs[1], myargs[2], myargs[3], myargs[4]);
484 /* -------- socket for NET module -------- */
486 sock = socket(AF_UNIX, SOCK_STREAM, 0);
487 bzero(&svr, sizeof(svr));
488 svr.sun_family = AF_UNIX;
489 strcpy(svr.sun_path, NPATH);
490 len = strlen(svr.sun_path) + sizeof(svr.sun_family);
491 bind(sock, (struct sockaddr*)&svr, len);
494 if (system(cmd) == 0) {
495 net_sock = accept(sock, (struct sockaddr*)0, (unsigned int*)0);
498 WriteMessage("NETWORK successfully connected");
499 fcntl(net_sock, F_SETFL, O_NONBLOCK|fcntl(net_sock,
502 setsockopt(net_sock, IPPROTO_TCP, TCP_NODELAY,
503 (char*)&on, sizeof(on));
505 WriteMessage("Cannot connect NETWORK resources");
506 WriteMessage("Exiting...");
512 WriteMessage("Cannot connect NETWORK resources");
513 WriteMessage("Exiting...");
520 * Connects to the specified address
521 * Additional window is displayed to connect to the specified address
523 void QKernel::Connect()
525 QDialog d(this, Qt::Dialog);
526 QLabel lab("IP Address:", &d);
527 QLineEdit ed("", &d);
528 QPushButton ob("", &d);
529 QPushButton cb("", &d);
532 ob.setGeometry(30, 60, 80, 30);
535 lab.setGeometry(10, 10, 60, 30);
536 lab.setText("Address");
537 ed.setGeometry(70, 10, 140, 30);
538 cb.setGeometry(130, 60, 80, 30);
539 cb.setText("Cancel");
542 connect(&ob, SIGNAL(clicked()), &d, SLOT(accept()));
543 connect(&cb, SIGNAL(clicked()), &d, SLOT(reject()));
545 m.msg_type = MSG_NET;
546 m.param.pword[0] = NET_CONNECT_TO;
547 strcpy(m.param.pstr, ed.text().toAscii().data());
548 write(net_sock, &m, sizeof(MESSAGE));
553 * Disconnects from virtual machine
555 void QKernel::Disconnect()
560 WriteMessage("Disconnecting from virtual machine");
562 msg.msg_type = MSG_NET;
563 msg.param.pword[0] = NET_DISCONNECT;
564 write(net_sock, &msg, sizeof(MESSAGE));
568 * Quits process. Closes VLP. Shows additional window to confirm exit.
570 void QKernel::QuitProc()
574 if (QMessageBox::question(this, "Close VLP", "Terminate VLP ?",
575 QMessageBox::Yes, QMessageBox::No, 0) == QMessageBox::No) {
581 msg.msg_type = MSG_NET;
582 msg.param.pword[0] = NET_DISCONNECT;
583 write(net_sock, &msg, sizeof(MESSAGE));*/
586 msg.msg_type = MSG_NET;
587 msg.param.pword[0] = NET_EXIT;
588 write(net_sock, &msg, sizeof(MESSAGE));
589 /* ::close(net_sock);*/
595 * Adds IP address to the configuration.
596 * Additional window is displayed to add address to the list
598 void QKernel::AddAddress()
600 QDialog d(this, Qt::Dialog);
601 QLabel lab("IP Address:", &d);
602 QLineEdit ed("", &d);
603 QPushButton ob("", &d);
604 QPushButton cb("", &d);
607 ob.setGeometry(30, 60, 80, 30);
610 lab.setGeometry(10, 10, 60, 30);
611 lab.setText("Address");
612 ed.setGeometry(70, 10, 140, 30);
613 cb.setGeometry(130, 60, 80, 30);
614 cb.setText("Cancel");
616 connect(&ob, SIGNAL(clicked()), &d, SLOT(accept()));
617 connect(&cb, SIGNAL(clicked()), &d, SLOT(reject()));
619 if (strcmp(ed.text().toAscii().data(), "") != 0) {
620 connections->addItem(ed.text());
626 * Deletes current address from available connections.
628 void QKernel::DelAddress()
631 if (connections->currentRow() != -1) {
632 /* TODO: Checki if this work correctly after porting */
633 connections->removeItemWidget(connections->currentItem());
639 * Sends message to node.
640 * Additional window is displayed to set Node Number of node where send message,
641 * and textfield to enter message.
643 void QKernel::MessageToNode()
649 dlg = new QDialog(this, Qt::Dialog);
650 dlg->setWindowTitle("Send message to node");
652 nodenr = new QLineEdit("number", dlg);
653 nodenr->setGeometry(90, 10, 50, 30);
657 tmpQLabel = new QLabel("Node number:", dlg);
658 tmpQLabel->setGeometry(10, 10, 77, 30);
660 tmpQLabel = new QLabel("Message:", dlg);
661 tmpQLabel->setGeometry(10, 50, 70, 30);
664 msg = new QLineEdit("", dlg);
665 msg->setGeometry(80, 60, 330, 30);
668 ob = new QPushButton("Send", dlg);
669 ob->setGeometry(230, 10, 80, 30);
670 ob->setDefault(TRUE);
673 cb = new QPushButton("Cancel", dlg);
674 cb->setGeometry(330, 10, 80, 30);
675 dlg->resize(430, 110);
676 connect(ob, SIGNAL(clicked()), dlg, SLOT(accept()));
677 connect(cb, SIGNAL(clicked()), dlg, SLOT(reject()));
680 m.msg_type = MSG_NET;
681 m.param.pword[0] = NET_PROPAGATE;
682 m.param.pword[1] = MSG_VLP;
683 m.param.pword[2] = NodeNumber;
684 m.param.pword[4] = atoi(nodenr->text().toAscii().data());
685 m.param.pword[6] = VLP_WRITE;
686 strcpy(m.param.pstr, msg->text().toAscii().data());
687 write(net_sock, &m, sizeof(MESSAGE));
693 * Additional window is displayed to get ID of interpreter which should be
696 void QKernel::KillInterpreter()
703 dlg = new QDialog(this, Qt::Dialog);
704 dlg->setWindowTitle("Kill interpreter");
706 nodenr = new QLineEdit("", dlg);
707 nodenr->setGeometry(90, 10, 50, 30);
709 QLabel * tmpQLabel = new QLabel("Interp. ID:", dlg);
710 tmpQLabel->setGeometry(10, 10, 77, 30);
712 QPushButton * ob = new QPushButton("Kill", dlg);
713 ob->setGeometry( 160, 10, 80, 30);
714 ob->setDefault(TRUE);
716 QPushButton * cb = new QPushButton("Cancel", dlg);
717 cb->setGeometry(260, 10, 80, 30);
718 dlg->resize(360, 50);
720 connect(ob, SIGNAL(clicked()), dlg, SLOT(accept()));
721 connect(cb, SIGNAL(clicked()), dlg, SLOT(reject()));
724 m.msg_type = MSG_INT;
725 m.param.pword[0] = INT_KILL;
726 pom = findINTbyID(atoi(nodenr->text().toAscii().data()));
729 write(pom->sock, &m, sizeof(MESSAGE));
731 WriteMessage("This is a remote instance of "
735 WriteMessage("Interpreter not found");
741 * Sends message to the net module.
743 void QKernel::NetMessage()
746 /* TODO: It has to be rewritten */
752 cnt = read(net_sock, &msg, sizeof(MESSAGE));
753 if ((cnt > 0) && (msg.msg_type == MSG_NET)) {
754 switch(msg.param.pword[0]) {
756 WriteMessage(msg.param.pstr);
759 switch(msg.param.pword[1]) {
761 /* pom = find_link_by_ID(msg.param.pword[5]);
762 msg.msg_type = MSG_NET;
763 msg.param.pword[0] = NET_PROPAGATE;
764 send_int(pom, &msg);*/
767 switch(msg.param.pword[6]) {
769 QApplication::beep();
770 WriteMessage(CharLine);
772 "### Incoming Messsage ###");
773 sprintf(ss, "Mesg from Node %d: %s",
777 WriteMessage(CharLine);
779 case VLP_REMOTE_INSTANCE:
780 sprintf(ss, "%s/%s", REMOTE_PATH,
784 WriteMessage("Running program:");
787 pom = RunIntModule(ss, 1);
789 pom->p_ctx.node = msg.param.pword[2];
790 pom->p_ctx.program_id =
792 pom->RInstances[msg.param.pword[2]] = msg.param.pword[7];
795 case VLP_CLOSE_INSTANCE:
796 msg.msg_type = MSG_INT;
797 msg.param.pword[0] = INT_CLOSE_INSTANCE;
798 pom = findINTbyID(msg.param.pword[7]);
800 write(pom->sock, &msg,
803 m1.msg_type = MSG_VLP;
804 m1.param.pword[0] = VLP_INTERPRETER_DOWN;
805 m1.param.pword[1] = pom->ID;
809 WriteMessage("Instance not found");
815 case NET_CONNECTIONS:
816 ActiveConnections = msg.param.pword[1];
817 WriteMessage(msg.param.pstr);
822 /* TODO: It has to be rewritten */
824 QString poms, poms1, poms2;
825 poms.sprintf("%s", msg.param.pstr);
826 while (poms.length() > 0) {
827 cnt = poms.indexOf(';');
829 poms1 = poms.left(cnt);
830 poms = poms.right(poms.length() - cnt - 1);
831 cnt = poms1.indexOf('=');
833 poms2 = poms1.left(cnt);
837 sprintf(ss, "Node: %s Addr: %s", poms2.data(), poms1.data());
845 wait_for_info = FALSE;
846 WriteMessage(CharLine);
853 * Sends message to the interpreter program.
854 * @param sock Interpreter socket to whom the message will be send.
856 void QKernel::IntMessage(int sock)
862 cnt = read(sock, &msg, sizeof(MESSAGE));
863 e = findINTbySocket(sock);
864 if ((cnt > 0) && (e != NULL)) {
865 switch (msg.msg_type) {
867 if (msg.param.pword[0] == GRAPH_ALLOCATE) {
868 RunGraphModule(msg.param.pstr);
872 write(net_sock, &msg, sizeof(MESSAGE));
875 switch(msg.param.pword[0]) {
876 case VLP_REMOTE_INSTANCE_PLEASE:
877 RemoteInstance(e, msg.param.pword[2]);
882 switch(msg.param.pword[0]) {
887 m.msg_type = MSG_VLP;
888 m.param.pword[0] = VLP_INTERPRETER_DOWN;
889 m.param.pword[1] = e->ID;
890 write(net_sock, &m, sizeof(MESSAGE));
895 /* TODO: Check this */
896 Interpreters.removeOne(e);
900 sprintf(ss, "%s : End of program "
901 "execution", msg.param.pstr);
906 msg.msg_type = MSG_INT;
907 msg.param.pword[0] = INT_CTX;
908 msg.param.pword[1] = NodeNumber;
909 msg.param.pword[2] = e->ID;
911 msg.param.pword[3] = e->p_ctx.node;
915 write(sock, &msg, sizeof(MESSAGE));
924 * Writes message to kernel logger.
925 * @parame msg String with message to log
927 void QKernel::WriteMessage(char *msg)
931 x = desktop->textCursor().blockNumber();
932 y = desktop->textCursor().columnNumber();
938 desktop->setReadOnly(FALSE);
939 desktop->append(msg);
940 desktop->setReadOnly(TRUE);
942 QTextCursor tmpCursor = desktop->textCursor();
943 tmpCursor.movePosition(QTextCursor::End, QTextCursor::MoveAnchor);
944 desktop->setTextCursor(tmpCursor);
948 if (desktop->document()->blockCount() > 100) {
954 * Adds checkbox to menu item. If it is checked additional info messages are
957 void QKernel::SetMessages()
959 if (toolsMenu != NULL) {
960 if (msgid->isChecked()) {
961 msgid->setChecked(FALSE);
962 info_messages = FALSE;
964 msgid->setChecked(TRUE);
965 info_messages = TRUE;
968 /* bar->repaint(); */
972 * Allows to set options in GUI window.
973 * Additional window is displayed to set kernel options which are saved in
974 * vlp.cfg file in kernel executable directory.
976 void QKernel::SetOptions()
978 QDialog dlg(this, Qt::Dialog);
979 dlg.setWindowTitle("Options");
984 progs = new QLineEdit(progdir, &dlg);
985 progs->setGeometry(150, 20, 180, 30);
988 tmpQLabel = new QLabel("Programs directory", &dlg);
989 tmpQLabel->setGeometry(30, 20, 120, 30);
992 tmpQFrame = new QFrame(&dlg);
993 tmpQFrame->setGeometry(10, 60, 380, 30);
994 tmpQFrame->setFrameStyle(52);
996 tmpQLabel = new QLabel("Virtual Processor properties (activated after "
997 "restarting VLP):", &dlg);
998 tmpQLabel->setGeometry(10, 80, 340, 30);
1002 sprintf(nns, "%d", NodeNumber);
1003 nn = new QLineEdit(nns, &dlg);
1004 nn->setGeometry(110, 110, 40, 30);
1006 tmpQLabel = new QLabel("Node number:", &dlg);
1007 tmpQLabel->setGeometry(20, 110, 90, 30);
1009 QRadioButton *exp, *reg;
1010 exp = new QRadioButton("Explicit", &dlg);
1011 exp->setGeometry(30, 170, 100, 30);
1012 exp->setChecked(TRUE);
1014 reg = new QRadioButton("Registration", &dlg);
1015 reg->setGeometry(30, 200, 100, 30);
1016 reg->setEnabled(FALSE);
1018 connections = new QListWidget(&dlg);
1019 connections->setGeometry(170, 140, 130, 100);
1021 for (int i = 0; i < ConnectList.size(); i++) {
1022 e = ConnectList.at(i);
1023 connections->addItem(e->addr);
1026 tmpQLabel = new QLabel("Connection list:", &dlg);
1027 tmpQLabel->setGeometry(170, 110, 100, 30);
1029 QPushButton *addbtn;
1030 QPushButton *delbtn;
1032 QPushButton *cancelbtn;
1033 addbtn = new QPushButton("Add", &dlg);
1034 addbtn->setGeometry(310, 150, 60, 30);
1035 connect(addbtn, SIGNAL(clicked()), this, SLOT(AddAddress()));
1037 delbtn = new QPushButton("Del", &dlg);
1038 delbtn->setGeometry(310, 200, 60, 30);
1039 connect(delbtn, SIGNAL(clicked()), this, SLOT(DelAddress()));
1041 okbtn = new QPushButton("Ok", &dlg);
1042 okbtn->setGeometry(80, 260, 100, 30);
1043 okbtn->setDefault(TRUE);
1044 connect(okbtn, SIGNAL(clicked()), &dlg, SLOT(accept()));
1046 cancelbtn = new QPushButton("Cancel", &dlg);
1047 cancelbtn->setGeometry(210, 260, 100, 30);
1048 connect(cancelbtn, SIGNAL(clicked()), &dlg, SLOT(reject()));
1051 group = new QGroupBox("Connection type", &dlg);
1052 group->setGeometry(20, 150, 120, 90);
1053 group->setAlignment(Qt::AlignLeft);
1056 QVBoxLayout *vbox = new QVBoxLayout();
1057 vbox->addWidget(exp);
1058 vbox->addWidget(reg);
1059 vbox->addStretch(1);
1060 group->setLayout(vbox);
1062 dlg.resize(400, 310);
1065 config_setting_t *root;
1066 config_setting_t *setting;
1069 root = config_root_setting(&cfg);
1071 setting = config_setting_add(root, "progdir",
1072 CONFIG_TYPE_STRING);
1073 config_setting_set_string(setting, progs->text().toAscii().data());
1074 strcpy(progdir, progs->text().toAscii().data());
1076 setting = config_setting_add(root, "node_number",
1078 config_setting_set_int(setting, atoi(nn->text().toAscii().data()));
1080 setting = config_setting_add(root, "homedir",
1081 CONFIG_TYPE_STRING);
1082 config_setting_set_string(setting, HomeDir);
1084 setting = config_setting_add(root, "type",
1085 CONFIG_TYPE_STRING);
1086 if (exp->isChecked()) {
1087 config_setting_set_string(setting, "explicit");
1089 config_setting_t *hosts = NULL;
1090 hosts = config_setting_add(root, "host",
1092 for(i = 0; i < connections->count(); i++) {
1093 setting = config_setting_add(hosts, NULL,
1094 CONFIG_TYPE_STRING);
1095 config_setting_set_string(setting,
1096 connections->item(i)->text().toAscii().data());
1099 config_setting_set_string(setting, "register");
1102 if (!config_write_file(&cfg, "vlp.cfg")) {
1103 fprintf(stderr, "Error while writing to file: %s.\n",
1106 config_destroy(&cfg);
1111 * Locks kernel program.
1112 * Additional window is displayed to enter password and retype it. If both are
1113 * same kernel window is locked.
1115 void QKernel::LockConsole()
1117 QDialog d(this, Qt::Dialog);
1118 d.setWindowTitle("Lock console");
1120 QPushButton ob("Ok", &d);
1121 ob.setGeometry(30, 60, 80, 30);
1122 ob.setDefault(TRUE);
1123 connect(&ob, SIGNAL(clicked()), &d, SLOT(accept()));
1125 QLabel lab("Password:", &d);
1126 lab.setGeometry(10, 10, 60, 30);
1128 QLineEdit ed("", &d);
1129 ed.setGeometry(70, 10, 140, 30);
1130 ed.setEchoMode(QLineEdit::Password);
1132 QPushButton cb("Cancel", &d);
1133 cb.setGeometry(130, 60, 80, 30);
1134 connect(&cb, SIGNAL(clicked()), &d, SLOT(reject()));
1139 if (strcmp(ed.text().toAscii().data(), "") != 0) {
1140 strcpy(LockPasswd, ed.text().toAscii().data());
1141 lab.setText("Retype:");
1144 if (strcmp(ed.text().toAscii().data(), LockPasswd)==0) {
1145 qid->setEnabled(FALSE);
1146 prid->setEnabled(FALSE);
1147 mid->setEnabled(FALSE);
1148 unlockid->setEnabled(TRUE);
1149 lockid->setEnabled(FALSE);
1150 cwid->setEnabled(FALSE);
1151 optid->setEnabled(FALSE);
1152 WriteMessage("CONSOLE LOCKED");
1155 QMessageBox msg(this);
1156 msg.setText("Not matching!");
1157 msg.setButtonText(0, "Close");
1161 strcpy(LockPasswd, "");
1168 * Unlocks kernel program.
1169 * Additional window is displayed to enter password. If it is correct, kernel
1170 * window is unlocked
1172 void QKernel::UnlockConsole()
1174 QDialog d(this, Qt::Dialog);
1175 d.setWindowTitle("Enter password");
1177 QLabel lab("Password:", &d);
1178 lab.setGeometry(10, 10, 60, 30);
1180 QLineEdit ed("", &d);
1181 ed.setGeometry(70, 10, 140, 30);
1182 ed.setEchoMode(QLineEdit::Password);
1184 QPushButton ob("Ok", &d);
1185 ob.setGeometry(30, 60, 80, 30);
1186 ob.setDefault(TRUE);
1187 connect(&ob, SIGNAL(clicked()), &d, SLOT(accept()));
1189 QPushButton cb("Cancel", &d);
1190 cb.setGeometry(130, 60, 80, 30);
1191 connect(&cb, SIGNAL(clicked()), &d, SLOT(reject()));
1196 if (strcmp(ed.text().toAscii().data(), LockPasswd) == 0) {
1197 qid->setEnabled(TRUE);
1198 prid->setEnabled(TRUE);
1199 mid->setEnabled(TRUE);
1200 unlockid->setEnabled(FALSE);
1201 lockid->setEnabled(TRUE);
1202 cwid->setEnabled(TRUE);
1203 optid->setEnabled(TRUE);
1204 WriteMessage("CONSOLE UNLOCKED");
1207 QMessageBox msg(this);
1208 msg.setText("Wrong password!");
1209 msg.setButtonText(0, "Close");
1216 * Writes init message in kernel
1218 void QKernel::InitMessage()
1220 WriteMessage("\n " PACKAGE_STRING ": READY \n");
1224 * Finds Interpreter by its socket
1225 * @param _id ID of the socket
1226 * @return returns pointer to the found interpreter slot. NULL otherwise
1228 InterpEntry *QKernel::findINTbySocket(int _id)
1230 InterpEntry *pom = NULL;
1232 for (int i = 0; i < Interpreters.size(); i++) {
1233 if (Interpreters.at(i)->sock == _id) {
1234 pom = Interpreters.at(i);
1243 * Finds Interpreter by its ID.
1244 * @param _id ID of the interpreter
1245 * @return returns pointer to the found interpreter slot. NULL otherwise
1247 InterpEntry *QKernel::findINTbyID(int _id)
1249 InterpEntry *pom = NULL;
1251 for (int i = 0; i < Interpreters.size(); i++) {
1252 if (Interpreters.at(i)->ID == _id) {
1253 pom = Interpreters.at(i);
1263 * Connects interpreter
1264 * @param ss full filepath with filename but without extension of the loglan
1266 * @param r Interpreter execution mode. 0 if it will be local instance, 1 if
1268 * @return Returns pointer to newly created interpreter slot, or NULL on error.
1270 InterpEntry *QKernel::RunIntModule(char *ss, int r)
1272 char a[256], b[255];
1273 struct sockaddr_un svr;
1274 int len, sock, i, on;
1279 InterpEntry *newINT = NULL;
1285 WriteMessage("File not found: no .ccd file");
1294 WriteMessage("File not found: no .pcd file");
1299 newINT = new InterpEntry;
1300 for(i = 0; i < MAXINSTANCES; i++)
1301 newINT->RInstances[i] =- 1;
1303 strcpy(b, rindex(ss, '/'));
1304 for(i = 0; i < strlen(b); i++)
1306 if (info_messages) {
1307 sprintf(a, "%s : Start execution", b);
1313 newINT->ID = newint;
1314 strcpy(newINT->shortname, b);
1315 strcpy(newINT->fullname, ss);
1317 sprintf(a, "%s%d", IPATH, newint);
1318 sprintf(cmd, "%s/modules/logint %s %s", HomeDir, a, ss);
1321 sprintf(b, " %s %s %s %s %s", myargs[0], myargs[1], myargs[2],
1322 myargs[3], myargs[4]);
1326 sock = socket(AF_UNIX, SOCK_STREAM, 0);
1328 bzero(&svr, sizeof(svr));
1329 svr.sun_family = AF_UNIX;
1330 strcpy(svr.sun_path, a);
1331 len = strlen(svr.sun_path)+sizeof(svr.sun_family);
1332 bind(sock, (struct sockaddr*)&svr, len);
1335 newINT->sock = accept(sock, (struct sockaddr*)0, (unsigned int *)0);
1338 if (newINT->sock > 0) {
1339 fcntl(newINT->sock, F_SETFL,
1340 O_NONBLOCK|fcntl(newINT->sock, F_GETFL, 0));
1342 setsockopt(newINT->sock, IPPROTO_TCP, TCP_NODELAY, (char*)&on,
1349 bzero(&msg, sizeof(MESSAGE));
1350 msg.msg_type = MSG_VLP;
1351 msg.param.pword[0] = VLP_REGINT;
1352 msg.param.pword[1] = newINT->ID;
1353 sprintf(msg.param.pstr, "logi%d.net", newint);
1354 write(net_sock, &msg, sizeof(MESSAGE));
1356 Interpreters.append(newINT);
1357 newINT->notify = new QSocketNotifier(newINT->sock,
1358 QSocketNotifier::Read);
1359 connect(newINT->notify, SIGNAL(activated(int)), this,
1360 SLOT(IntMessage(int)));
1362 WriteMessage("INTERPRETER successfully connected");
1364 WriteMessage("Cannot connect interpreter");
1371 * Allocates remote instance of interpreter
1372 * @param interp Interpreter slot
1373 * @param on Node Number
1375 void QKernel::RemoteInstance(InterpEntry *interp, int on)
1380 m.msg_type = MSG_NET;
1381 m.param.pword[0] = NET_NODE_EXIST;
1382 m.param.pword[1] = on;
1383 m.param.pword[2] = interp->ID;
1384 write(net_sock, &m, sizeof(MESSAGE));
1385 bzero(&m, sizeof(MESSAGE));
1386 while((m.msg_type!=MSG_NET) && (m.param.pword[0]!=NET_NODE_EXIST))
1387 read(net_sock, &m, sizeof(MESSAGE));
1389 /* means node exists */
1390 if (m.param.pword[1] == 1) {
1391 m.msg_type = MSG_NET;
1392 m.param.pword[0] = NET_TRANSMIT_CODE;
1393 m.param.pword[1] = interp->ID;
1394 m.param.pword[2] = on;
1395 strcpy(m.param.pstr, interp->fullname);
1396 write(net_sock, &m, sizeof(MESSAGE));
1398 Net_Notify->setEnabled(FALSE);
1399 while ((m.msg_type != MSG_NET) ||
1400 (m.param.pword[0] != NET_TRANSMITTED))
1401 read(net_sock, &m, sizeof(MESSAGE));
1403 m.msg_type = MSG_NET;
1404 m.param.pword[0] = NET_PROPAGATE;
1405 m.param.pword[1] = MSG_VLP;
1406 m.param.pword[2] = NodeNumber;
1407 m.param.pword[3] = 0;
1408 m.param.pword[4] = on;
1409 m.param.pword[5] = 0;
1410 m.param.pword[6] = VLP_REMOTE_INSTANCE;
1411 m.param.pword[7] = interp->ID;
1412 strcpy(m.param.pstr, interp->shortname);
1413 write(net_sock, &m, sizeof(MESSAGE));
1415 read(net_sock, &m, sizeof(MESSAGE));
1417 if ((m.param.pword[0] == NET_PROPAGATE) &&
1418 (m.param.pword[6] == VLP_REMOTE_INSTANCE_OK)) {
1419 interp->RInstances[on] = m.param.pword[7];
1422 read(net_sock, &m, sizeof(MESSAGE));
1425 Net_Notify->setEnabled(TRUE);
1427 /*bzero(&m, sizeof(MESSAGE));*/
1428 m.msg_type = MSG_VLP;
1429 m.param.pword[0] = VLP_REMOTE_INSTANCE_HERE;
1430 m.param.pword[1] = interp->RInstances[on];
1431 write(interp->sock, &m, sizeof(MESSAGE));
1432 } else { /* There is no such a node! */
1433 sprintf(s, "Warning: Node number %d not found!", on);
1435 WriteMessage("Allocating O-process on the local node");
1436 bzero(&m, sizeof(MESSAGE));
1437 m.msg_type = MSG_VLP;
1438 m.param.pword[0] = VLP_REMOTE_INSTANCE_HERE;
1439 m.param.pword[1] = interp->ID;
1440 write(interp->sock, &m, sizeof(MESSAGE));
1445 * Closes all remote instances
1447 void QKernel::CloseInstances(InterpEntry *e)
1453 WriteMessage("Closing remote instances");
1455 for(i=0; i < MAXINSTANCES; i++)
1456 if (e->RInstances[i]>=0) {
1457 msg.msg_type = MSG_NET;
1458 msg.param.pword[0] = NET_PROPAGATE;
1459 msg.param.pword[1] = MSG_VLP;
1460 msg.param.pword[2] = NodeNumber;
1461 msg.param.pword[4] = i;
1462 msg.param.pword[6] = VLP_CLOSE_INSTANCE;
1463 msg.param.pword[7] = e->RInstances[i];
1464 write(net_sock, &msg, sizeof(MESSAGE));
1469 * Displays information about virtual machine
1471 void QKernel::Info()
1475 WriteMessage(CharLine);
1476 WriteMessage("### Virtual Machine Information ###");
1477 m.msg_type = MSG_NET;
1478 m.param.pword[0] = NET_GET_INFO;
1479 write(net_sock, &m, sizeof(MESSAGE));
1480 wait_for_info = TRUE;
1483 #include "kernel.moc"
1486 * Program main function
1487 * All program arguments but the first one (argv[0]: program name) are saved and
1488 * passed to all dependent programs on their invocation.
1489 * @param argc Number of program arguments
1490 * @param argv Program arguments
1492 int main(int argc, char **argv)
1495 for(i = 0; i < 5; i++) {
1496 strcpy(myargs[i], "");
1498 for(i = 1; i < argc; i++) {
1499 strcpy(myargs[i - 1], argv[i]);
1502 app = new QApplication(argc, argv);
1505 kernel.InitMessage();