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>
62 #include <qwindowsstyle.h>
72 #include <netinet/in.h>
74 #include <libconfig.h>
76 /* File resides in top directory (where are Makefiles)*/
77 #include "../../config.h"
82 #define REMOTE_PATH "REMOTE"
84 #define MAXINSTANCES 256
92 char CharLine[25] = "________________________";
100 /** Interpreter identifier */
102 /** Defines if interpreter is remote or not */
110 QSocketNotifier *notify;
111 /* IDs of my remote INT modules */
112 int RInstances[MAXINSTANCES];
113 /* Parent interpreter info */
124 ConnectEntry(char *s) {
134 class QKernel : public QFrame {
137 QMultiLineEdit *desktop;
148 virtual void resizeEvent(QResizeEvent *ev);
150 void WriteMessage(char* msg);
162 void UnlockConsole();
163 void MessageToNode();
166 void IntMessage(int);
167 void KillInterpreter();
174 virtual void closeEvent (QCloseEvent * e);
177 QList<InterpEntry> Interpreters;
178 QList<ConnectEntry> ConnectList;
179 QListBox *connections;
182 * number of working interpreters
187 * number of connected VLPs
189 int ActiveConnections;
207 QSocketNotifier *Net_Notify;
211 void LoadConfig(char *);
212 void RunGraphModule(char*);
214 InterpEntry *findINTbySocket(int);
215 InterpEntry *findINTbyID(int);
216 InterpEntry *RunIntModule(char *ss, int r);
217 void RemoteInstance(InterpEntry*, int);
218 void CloseInstances(InterpEntry*);
222 * Event invoked on program close.
223 * Closes application. Displays additional window to confirm exit.
225 void QKernel::closeEvent(QCloseEvent * e)
231 * Kernel program constructor.
232 * Prepares everything to work.
236 QFont f("Helvetica", 10, QFont::Bold);
237 QFont f1("Helvetica", 10, QFont::Normal);
238 QFont f2("Times Roman", 10, QFont::Normal);
243 sprintf(ss, "mkdir %s", REMOTE_PATH);
247 info_messages = TRUE;
248 wait_for_info = FALSE;
250 setCaption(PACKAGE_NAME);
251 setBackgroundColor(white);
253 bar = new QMenuBar(this);
255 p = new QPopupMenu();
257 p->insertItem("Execute", this, SLOT(Run_Prog()));
258 p->insertItem("Kill", this, SLOT(KillInterpreter()));
259 prid = bar->insertItem("&Program", p);
260 p1 = new QPopupMenu();
261 p1->insertItem("Message", this, SLOT(MessageToNode()));
262 p1->insertSeparator();
263 p1->insertItem("Connect", this, SLOT(Connect()));
264 p1->insertItem("Disconnect", this, SLOT(Disconnect()));
265 p1->insertItem("Info", this, SLOT(Info()));
267 mid = bar->insertItem("&Machine", p1);
269 p2 = new QPopupMenu();
270 cwid = p2->insertItem("Editor", this, SLOT(Edit()));
271 hid = p2->insertItem("Help", this, SLOT(Help()));
272 p2->insertSeparator();
273 optid = p2->insertItem("Options", this, SLOT(SetOptions()));
274 msgid = p2->insertItem("Info messages", this, SLOT(SetMessages()));
275 p2->setItemChecked(msgid, TRUE);
276 p2->insertSeparator();
277 lockid = p2->insertItem("Lock console", this, SLOT(LockConsole()));
278 unlockid = p2->insertItem("Unlock console", this,
279 SLOT(UnlockConsole()));
280 p2->setItemEnabled(unlockid, FALSE);
283 toolsid = bar->insertItem("&Tools", p2);
285 qid = bar->insertItem("&Quit", this, SLOT(QuitProc()));
288 desktop = new QMultiLineEdit(this, "desktop");
289 desktop->setAutoUpdate(TRUE);
290 desktop->setReadOnly(TRUE);
291 desktop->setFont(f1);
296 ActiveConnections = 0;
297 strcpy(LockPasswd, "");
298 LoadConfig("vlp.cfg");
301 Net_Notify = new QSocketNotifier(net_sock, QSocketNotifier::Read, this);
302 connect(Net_Notify, SIGNAL(activated(int)), this, SLOT(NetMessage()));
306 * Event invoked on resizing kernel application window.
307 * @copydoc QWidget::resizeEvent(QResizeEvent*)
309 void QKernel::resizeEvent(QResizeEvent *ev)
311 QFrame::resizeEvent(ev);
313 desktop->setGeometry(0, bar->height(), width(),
314 height() - bar->height());
318 * Displays window with information about not implemented functionality.
320 void QKernel::n_impl()
322 QMessageBox::information(this, "Function info", "This function is not "
323 "implemented yet...", "Ok");
327 * Loads configuration from the given file.
328 * @param fname Filename of the configuration file.
330 void QKernel::LoadConfig(char * fname)
333 config_setting_t *setting;
336 /* Hack for checking if file exists without using external libs.*/
337 FILE * file = fopen(fname, "rt");
339 fprintf(stderr, "Error: Cannot load configuration file %s!\n",
343 /* File exists, so file has been locked. Release it. */
347 /* Read the file. If there is an error, report it and exit. */
348 if (!config_read(&cfg, file)) {
349 fprintf(stderr, "%s! In file %s, line %d\n",
350 config_error_text(&cfg),
351 config_error_file(&cfg),
352 config_error_line(&cfg));
353 config_destroy(&cfg);
355 exit(3);/* from original code. */
358 setting = config_lookup(&cfg, "node_number");
360 NodeNumber = config_setting_get_int(setting);
362 fprintf(stderr, "%s! In file %s, '%s' was not found.\n",
363 "Warning", fname, "node_number");
364 config_destroy(&cfg);
369 setting = config_lookup(&cfg, "type");
371 /* same as strcmp(..) == 0 */
372 if (!strcmp(config_setting_get_string(setting), "explicit")) {
378 fprintf(stderr, "%s! In file %s, '%s' was not found.\n",
379 "Warning", fname, "type");
382 setting = config_lookup(&cfg, "host");
384 switch(config_setting_type(setting)) {
385 /* TODO: Deprecated. Made for back compatibility. */
386 case CONFIG_TYPE_STRING:
387 ConnectList.append(new ConnectEntry((char*)
388 config_setting_get_string(setting)));
390 case CONFIG_TYPE_ARRAY: {
391 int size = config_setting_length(setting);
392 for (int i = 0; i < size; i++) {
393 ConnectList.append(new ConnectEntry((char*)
394 config_setting_get_string_elem(setting,
400 fprintf(stderr, "%s! In file %s, bad entry type for %s."
401 " Will not be read.\n",
402 "Error", fname, "host");
405 fprintf(stderr, "%s! In file %s, '%s' was not found.\n",
406 "Warning", fname, "host");
409 setting = config_lookup(&cfg, "progdir");
411 strncpy(progdir, config_setting_get_string(setting), 256);
413 fprintf(stderr, "%s! In file %s, '%s' was not found.\n",
414 "Warning", fname, "progdir");
417 setting = config_lookup(&cfg, "homedir");
419 strncpy(HomeDir, config_setting_get_string(setting), 255);
421 fprintf(stderr, "%s! In file %s, '%s' was not found.\n",
422 "Warning", fname, "homedir");
425 config_destroy(&cfg);
431 * Additional window id displayed to set which code to execute.
433 void QKernel::Run_Prog()
436 QString s(QFileDialog::getOpenFileName(progdir, "*.log", this));
444 RunIntModule((char*)s.ascii(), 0);
449 * Invokes editor program
454 sprintf(cmd, "%s/modules/logedit %s %s %s %s %s %s &", HomeDir, HomeDir,
455 myargs[0], myargs[1], myargs[2], myargs[3], myargs[4]);
460 * Invokes help program
465 sprintf(cmd, "%s/modules/loghelp %s/doc %s %s %s %s %s &", HomeDir,
466 HomeDir, myargs[0], myargs[1], myargs[2], myargs[3], myargs[4]);
471 * Invokes graphics module
473 void QKernel::RunGraphModule(char *sk)
477 sprintf(cmd, "%s/modules/loggraph %s %s %s %s %s %s", HomeDir, sk,
478 myargs[0], myargs[1], myargs[2], myargs[3], myargs[4]);
481 if (system(cmd) != 0)
482 WriteMessage("Cannot connect GRAPH resources");
488 void QKernel::RunNetModule()
490 struct sockaddr_un svr;
494 sprintf(cmd, "%s/modules/lognet %s %s %s %s %s %s", HomeDir, NPATH,
495 myargs[0], myargs[1], myargs[2], myargs[3], myargs[4]);
498 /* -------- socket for NET module -------- */
500 sock = socket(AF_UNIX, SOCK_STREAM, 0);
501 bzero(&svr, sizeof(svr));
502 svr.sun_family = AF_UNIX;
503 strcpy(svr.sun_path, NPATH);
504 len = strlen(svr.sun_path) + sizeof(svr.sun_family);
505 bind(sock, (struct sockaddr*)&svr, len);
508 if (system(cmd) == 0) {
509 net_sock = accept(sock, (struct sockaddr*)0, (unsigned int*)0);
512 WriteMessage("NETWORK successfully connected");
513 fcntl(net_sock, F_SETFL, O_NONBLOCK|fcntl(net_sock,
516 setsockopt(net_sock, IPPROTO_TCP, TCP_NODELAY,
517 (char*)&on, sizeof(on));
519 WriteMessage("Cannot connect NETWORK resources");
520 WriteMessage("Exiting...");
526 WriteMessage("Cannot connect NETWORK resources");
527 WriteMessage("Exiting...");
534 * Connects to the specified address
535 * Additional window is displayed to connect to the specified address
537 void QKernel::Connect()
539 QDialog d(this, "", TRUE);
540 QLabel lab(&d, "IP Address:");
541 QLineEdit ed(&d, "");
542 QPushButton ob(&d, "");
543 QPushButton cb(&d, "");
546 d.setFont(QFont("Helvetica", 12, QFont::Bold));
547 ob.setGeometry(30, 60, 80, 30);
550 lab.setGeometry(10, 10, 60, 30);
551 lab.setText("Address");
552 ed.setGeometry(70, 10, 140, 30);
553 cb.setGeometry(130, 60, 80, 30);
554 cb.setText("Cancel");
557 connect(&ob, SIGNAL(clicked()), &d, SLOT(accept()));
558 connect(&cb, SIGNAL(clicked()), &d, SLOT(reject()));
560 m.msg_type = MSG_NET;
561 m.param.pword[0] = NET_CONNECT_TO;
562 strcpy(m.param.pstr, ed.text());
563 write(net_sock, &m, sizeof(MESSAGE));
568 * Disconnects from virtual machine
570 void QKernel::Disconnect()
575 WriteMessage("Disconnecting from virtual machine");
577 msg.msg_type = MSG_NET;
578 msg.param.pword[0] = NET_DISCONNECT;
579 write(net_sock, &msg, sizeof(MESSAGE));
583 * Quits process. Closes VLP. Shows additional window to confirm exit.
585 void QKernel::QuitProc()
589 if (QMessageBox::question(this, "Close VLP", "Terminate VLP ?",
590 QMessageBox::Yes, QMessageBox::No, 0) == QMessageBox::No) {
596 msg.msg_type = MSG_NET;
597 msg.param.pword[0] = NET_DISCONNECT;
598 write(net_sock, &msg, sizeof(MESSAGE));*/
601 msg.msg_type = MSG_NET;
602 msg.param.pword[0] = NET_EXIT;
603 write(net_sock, &msg, sizeof(MESSAGE));
604 /* ::close(net_sock);*/
610 * Adds IP address to the configuration.
611 * Additional window is displayed to add address to the list
613 void QKernel::AddAddress()
615 QDialog d(this, "", TRUE);
616 QLabel lab(&d, "IP Address:");
617 QLineEdit ed(&d, "");
618 QPushButton ob(&d, "");
619 QPushButton cb(&d, "");
622 ob.setGeometry(30, 60, 80, 30);
625 lab.setGeometry(10, 10, 60, 30);
626 lab.setText("Address");
627 ed.setGeometry(70, 10, 140, 30);
628 cb.setGeometry(130, 60, 80, 30);
629 cb.setText("Cancel");
631 connect(&ob, SIGNAL(clicked()), &d, SLOT(accept()));
632 connect(&cb, SIGNAL(clicked()), &d, SLOT(reject()));
634 if (strcmp(ed.text(), "") != 0) {
635 connections->insertItem(ed.text());
641 * Deletes current address from available connections.
643 void QKernel::DelAddress()
646 if (connections->currentItem() != -1)
647 connections->removeItem(connections->currentItem());
652 * Sends message to node.
653 * Additional window is displayed to set Node Number of node where send message,
654 * and textfield to enter message.
656 void QKernel::MessageToNode()
662 dlg = new QDialog(this, "Message", TRUE);
664 nodenr = new QLineEdit(dlg, "number");
665 nodenr->setGeometry(90, 10, 50, 30);
669 tmpQLabel = new QLabel(dlg, "Label_1");
670 tmpQLabel->setGeometry(10, 10, 77, 30);
671 tmpQLabel->setText("Node number:");
673 tmpQLabel = new QLabel(dlg, "Label_2");
674 tmpQLabel->setGeometry(10, 50, 70, 30);
675 tmpQLabel->setText("Message:");
678 msg = new QLineEdit(dlg, "LineEdit_1");
679 msg->setGeometry(80, 60, 330, 30);
683 ob = new QPushButton(dlg, "PushButton_1");
684 ob->setGeometry(230, 10, 80, 30);
686 ob->setDefault(TRUE);
689 cb = new QPushButton(dlg, "PushButton_2");
690 cb->setGeometry(330, 10, 80, 30);
691 cb->setText("Cancel");
692 dlg->resize(430, 110);
693 connect(ob, SIGNAL(clicked()), dlg, SLOT(accept()));
694 connect(cb, SIGNAL(clicked()), dlg, SLOT(reject()));
695 dlg->setCaption("Send message to node");
698 m.msg_type = MSG_NET;
699 m.param.pword[0] = NET_PROPAGATE;
700 m.param.pword[1] = MSG_VLP;
701 m.param.pword[2] = NodeNumber;
702 m.param.pword[4] = atoi(nodenr->text());
703 m.param.pword[6] = VLP_WRITE;
704 strcpy(m.param.pstr, msg->text());
705 write(net_sock, &m, sizeof(MESSAGE));
711 * Additional window is displayed to get ID of interpreter which should be
714 void QKernel::KillInterpreter()
721 dlg = new QDialog(this, "Message", TRUE);
723 nodenr = new QLineEdit(dlg, "number");
724 nodenr->setGeometry(90, 10, 50, 30);
728 tmpQLabel = new QLabel(dlg, "Label_1");
729 tmpQLabel->setGeometry(10, 10, 77, 30);
730 tmpQLabel->setText("Interp. ID:");
731 QPushButton* ob, *cb;
732 ob = new QPushButton(dlg, "PushButton_1");
733 ob->setGeometry( 160, 10, 80, 30);
735 ob->setDefault(TRUE);
736 cb = new QPushButton(dlg, "PushButton_2");
737 cb->setGeometry(260, 10, 80, 30);
738 cb->setText("Cancel");
739 dlg->resize(360, 50);
740 connect(ob, SIGNAL(clicked()), dlg, SLOT(accept()));
741 connect(cb, SIGNAL(clicked()), dlg, SLOT(reject()));
742 dlg->setCaption("Kill interpreter");
744 m.msg_type = MSG_INT;
745 m.param.pword[0] = INT_KILL;
746 pom = findINTbyID(atoi(nodenr->text()));
749 write(pom->sock, &m, sizeof(MESSAGE));
751 WriteMessage("This is a remote instance of "
755 WriteMessage("Interpreter not found");
761 * Sends message to the net module.
763 void QKernel::NetMessage()
766 /* TODO: It has to be rewritten */
772 cnt = read(net_sock, &msg, sizeof(MESSAGE));
773 if ((cnt > 0) && (msg.msg_type == MSG_NET)) {
774 switch(msg.param.pword[0]) {
776 WriteMessage(msg.param.pstr);
779 switch(msg.param.pword[1]) {
781 /* pom = find_link_by_ID(msg.param.pword[5]);
782 msg.msg_type = MSG_NET;
783 msg.param.pword[0] = NET_PROPAGATE;
784 send_int(pom, &msg);*/
787 switch(msg.param.pword[6]) {
789 QApplication::beep();
790 WriteMessage(CharLine);
792 "### Incoming Messsage ###");
793 sprintf(ss, "Mesg from Node %d: %s",
797 WriteMessage(CharLine);
799 case VLP_REMOTE_INSTANCE:
800 sprintf(ss, "%s/%s", REMOTE_PATH,
804 WriteMessage("Running program:");
807 pom = RunIntModule(ss, 1);
809 pom->p_ctx.node = msg.param.pword[2];
810 pom->p_ctx.program_id =
812 pom->RInstances[msg.param.pword[2]] = msg.param.pword[7];
815 case VLP_CLOSE_INSTANCE:
816 msg.msg_type = MSG_INT;
817 msg.param.pword[0] = INT_CLOSE_INSTANCE;
818 pom = findINTbyID(msg.param.pword[7]);
820 write(pom->sock, &msg,
823 m1.msg_type = MSG_VLP;
824 m1.param.pword[0] = VLP_INTERPRETER_DOWN;
825 m1.param.pword[1] = pom->ID;
829 WriteMessage("Instance not found");
835 case NET_CONNECTIONS:
836 ActiveConnections = msg.param.pword[1];
837 WriteMessage(msg.param.pstr);
842 /* TODO: It has to be rewritten */
844 QString poms, poms1, poms2;
845 poms.sprintf("%s", msg.param.pstr);
846 while (poms.length() > 0) {
847 cnt = poms.find(';');
849 poms1 = poms.left(cnt);
850 poms = poms.right(poms.length() - cnt - 1);
851 cnt = poms1.find('=');
853 poms2 = poms1.left(cnt);
857 sprintf(ss, "Node: %s Addr: %s", poms2.data(), poms1.data());
865 wait_for_info = FALSE;
866 WriteMessage(CharLine);
873 * Sends message to the interpreter program.
874 * @param sock Interpreter socket to whom the message will be send.
876 void QKernel::IntMessage(int sock)
882 cnt = read(sock, &msg, sizeof(MESSAGE));
883 e = findINTbySocket(sock);
884 if ((cnt > 0) && (e != NULL)) {
885 switch (msg.msg_type) {
887 if (msg.param.pword[0] == GRAPH_ALLOCATE) {
888 RunGraphModule(msg.param.pstr);
892 write(net_sock, &msg, sizeof(MESSAGE));
895 switch(msg.param.pword[0]) {
896 case VLP_REMOTE_INSTANCE_PLEASE:
897 RemoteInstance(e, msg.param.pword[2]);
902 switch(msg.param.pword[0]) {
907 m.msg_type = MSG_VLP;
908 m.param.pword[0] = VLP_INTERPRETER_DOWN;
909 m.param.pword[1] = e->ID;
910 write(net_sock, &m, sizeof(MESSAGE));
915 Interpreters.remove(e);
919 sprintf(ss, "%s : End of program "
920 "execution", msg.param.pstr);
925 msg.msg_type = MSG_INT;
926 msg.param.pword[0] = INT_CTX;
927 msg.param.pword[1] = NodeNumber;
928 msg.param.pword[2] = e->ID;
930 msg.param.pword[3] = e->p_ctx.node;
934 write(sock, &msg, sizeof(MESSAGE));
943 * Writes message to kernel logger.
944 * @parame msg String with message to log
946 void QKernel::WriteMessage(char *msg)
951 desktop->getCursorPosition(&x, &y);
956 desktop->setReadOnly(FALSE);
957 desktop->append(msg);
958 desktop->setReadOnly(TRUE);
959 desktop->setCursorPosition(desktop->numLines(), 1);
962 if (desktop->numLines() > 100) {
968 * Adds checkbox to menu item. It it is checked additional info messages are
971 void QKernel::SetMessages()
974 if (p2->isItemChecked(msgid)) {
975 p2->setItemChecked(msgid, FALSE);
978 p2->setItemChecked(msgid, TRUE);
982 /* bar->repaint(); */
986 * Allows to set options in GUI window.
987 * Additional window is displayed to set kernel options which are saved in
988 * vlp.cfg file in kernel executable directory.
990 void QKernel::SetOptions()
992 QDialog dlg(this, "Options", TRUE);
997 progs = new QLineEdit(&dlg, "progs");
998 progs->setGeometry(150, 20, 180, 30);
999 progs->setText(progdir);
1002 tmpQLabel = new QLabel(&dlg, "Label_1");
1003 tmpQLabel->setGeometry(30, 20, 120, 30);
1004 tmpQLabel->setText("Programs directory");
1007 tmpQFrame = new QFrame(&dlg, "Frame_2");
1008 tmpQFrame->setGeometry(10, 60, 380, 30);
1009 tmpQFrame->setFrameStyle(52);
1011 tmpQLabel = new QLabel(&dlg, "Label_2");
1012 tmpQLabel->setGeometry(10, 80, 340, 30);
1013 tmpQLabel->setText("Virtual Processor properties (activated after "
1014 "restarting VLP):");
1018 nn = new QLineEdit(&dlg, "LineEdit_2");
1019 nn->setGeometry(110, 110, 40, 30);
1020 sprintf(nns, "%d", NodeNumber);
1023 tmpQLabel = new QLabel(&dlg, "Label_3");
1024 tmpQLabel->setGeometry(20, 110, 90, 30);
1025 tmpQLabel->setText("Node number:");
1027 QRadioButton *exp, *reg;
1028 exp = new QRadioButton(&dlg, "RadioButton_3");
1029 exp->setGeometry(30, 170, 100, 30);
1030 exp->setText("Explicit");
1031 exp->setChecked(TRUE);
1033 reg = new QRadioButton(&dlg, "RadioButton_4");
1034 reg->setGeometry(30, 200, 100, 30);
1035 reg->setText("Registration");
1036 reg->setEnabled(FALSE);
1038 connections = new QListBox(&dlg, "ListBox_1");
1039 connections->setGeometry(170, 140, 130, 100);
1040 e = ConnectList.first();
1042 connections->insertItem(e->addr);
1043 e = ConnectList.next();
1046 tmpQLabel = new QLabel(&dlg, "Label_5");
1047 tmpQLabel->setGeometry(170, 110, 100, 30);
1048 tmpQLabel->setText("Connection list:");
1050 QPushButton *addbtn;
1051 QPushButton *delbtn;
1053 QPushButton *cancelbtn;
1054 addbtn = new QPushButton(&dlg, "PushButton_1");
1055 addbtn->setGeometry(310, 150, 60, 30);
1056 addbtn->setText("Add");
1057 delbtn = new QPushButton(&dlg, "PushButton_2");
1058 delbtn->setGeometry(310, 200, 60, 30);
1059 delbtn->setText("Del");
1060 connect(addbtn, SIGNAL(clicked()), this, SLOT(AddAddress()));
1061 connect(delbtn, SIGNAL(clicked()), this, SLOT(DelAddress()));
1062 okbtn = new QPushButton(&dlg, "PushButton_3");
1063 okbtn->setGeometry(80, 260, 100, 30);
1064 okbtn->setText("Ok");
1065 okbtn->setDefault(TRUE);
1066 cancelbtn = new QPushButton(&dlg, "PushButton_4");
1067 cancelbtn->setGeometry(210, 260, 100, 30);
1068 cancelbtn->setText("Cancel");
1069 connect(okbtn, SIGNAL(clicked()), &dlg, SLOT(accept()));
1070 connect(cancelbtn, SIGNAL(clicked()), &dlg, SLOT(reject()));
1071 QButtonGroup* group;
1072 group = new QButtonGroup(&dlg, "ButtonGroup_1");
1073 group->setGeometry(20, 150, 120, 90);
1074 group->setTitle("Connection type");
1075 group->setAlignment(1);
1077 group->insert(exp, 1);
1078 group->insert(reg, 2);
1080 dlg.resize(400, 310);
1083 config_setting_t *root;
1084 config_setting_t *setting;
1087 root = config_root_setting(&cfg);
1089 setting = config_setting_add(root, "progdir",
1090 CONFIG_TYPE_STRING);
1091 config_setting_set_string(setting, progs->text().ascii());
1092 strcpy(progdir, progs->text());
1094 setting = config_setting_add(root, "node_number",
1096 config_setting_set_int(setting, atoi(nn->text()));
1098 setting = config_setting_add(root, "homedir",
1099 CONFIG_TYPE_STRING);
1100 config_setting_set_string(setting, HomeDir);
1102 setting = config_setting_add(root, "type",
1103 CONFIG_TYPE_STRING);
1104 if (exp->isChecked()) {
1105 config_setting_set_string(setting, "explicit");
1107 config_setting_t *hosts = NULL;
1108 hosts = config_setting_add(root, "host",
1110 for(i = 0; i < connections->count(); i++) {
1111 setting = config_setting_add(hosts, NULL,
1112 CONFIG_TYPE_STRING);
1113 config_setting_set_string(setting,
1114 connections->text(i).ascii());
1117 config_setting_set_string(setting, "register");
1120 if (!config_write_file(&cfg, "vlp.cfg")) {
1121 fprintf(stderr, "Error while writing to file: %s.\n",
1124 config_destroy(&cfg);
1129 * Locks kernel program.
1130 * Additional window is displayed to enter password and retype it. If both are
1131 * same kernel window is locked.
1133 void QKernel::LockConsole()
1135 QDialog d(this, "Enter password", TRUE);
1136 QLabel lab(&d, "Password");
1137 QLineEdit ed(&d, "");
1138 QPushButton ob(&d, "");
1139 QPushButton cb(&d, "");
1141 d.setCaption("Lock console");
1142 ob.setGeometry(30, 60, 80, 30);
1144 ob.setDefault(TRUE);
1145 lab.setGeometry(10, 10, 60, 30);
1146 lab.setText("Password:");
1147 ed.setGeometry(70, 10, 140, 30);
1148 ed.setEchoMode(QLineEdit::Password);
1149 cb.setGeometry(130, 60, 80, 30);
1150 cb.setText("Cancel");
1152 connect(&ob, SIGNAL(clicked()), &d, SLOT(accept()));
1153 connect(&cb, SIGNAL(clicked()), &d, SLOT(reject()));
1156 if (strcmp(ed.text(), "") != 0) {
1157 strcpy(LockPasswd, ed.text());
1158 lab.setText("Retype:");
1161 if (strcmp(ed.text(), LockPasswd)==0) {
1162 bar->setItemEnabled(qid, FALSE);
1163 bar->setItemEnabled(prid, FALSE);
1164 bar->setItemEnabled(mid, FALSE);
1165 p2->setItemEnabled(unlockid, TRUE);
1166 p2->setItemEnabled(lockid, FALSE);
1167 p2->setItemEnabled(cwid, FALSE);
1168 p2->setItemEnabled(optid, FALSE);
1170 WriteMessage("CONSOLE LOCKED");
1173 QMessageBox msg(this);
1174 msg.setText("Not matching!");
1175 msg.setButtonText(0, "Close");
1179 strcpy(LockPasswd, "");
1186 * Unlocks kernel program.
1187 * Additional window is displayed to enter password. If it is correct, kernel
1188 * window is unlocked
1190 void QKernel::UnlockConsole()
1192 QDialog d(this, "Enter password", TRUE);
1193 QLabel lab(&d, "Password");
1194 QLineEdit ed(&d, "");
1195 QPushButton ob(&d, "");
1196 QPushButton cb(&d, "");
1198 ob.setGeometry(30, 60, 80, 30);
1200 ob.setDefault(TRUE);
1201 lab.setGeometry(10, 10, 60, 30);
1202 lab.setText("Password:");
1203 ed.setGeometry(70, 10, 140, 30);
1204 ed.setEchoMode(QLineEdit::Password);
1205 cb.setGeometry(130, 60, 80, 30);
1206 cb.setText("Cancel");
1208 connect(&ob, SIGNAL(clicked()), &d, SLOT(accept()));
1209 connect(&cb, SIGNAL(clicked()), &d, SLOT(reject()));
1212 if (strcmp(ed.text(), LockPasswd) == 0) {
1213 bar->setItemEnabled(qid, TRUE);
1214 bar->setItemEnabled(prid, TRUE);
1215 bar->setItemEnabled(mid, TRUE);
1216 p2->setItemEnabled(unlockid, FALSE);
1217 p2->setItemEnabled(lockid, TRUE);
1218 p2->setItemEnabled(cwid, TRUE);
1219 p2->setItemEnabled(optid, TRUE);
1221 WriteMessage("CONSOLE UNLOCKED");
1224 QMessageBox msg(this);
1225 msg.setText("Wrong password!");
1226 msg.setButtonText(0, "Close");
1233 * Writes init message in kernel
1235 void QKernel::InitMessage()
1237 WriteMessage("\n " PACKAGE_STRING ": READY \n");
1241 * Finds Interpreter by its socket
1242 * @param _id ID of the socket
1243 * @return returns pointer to the found interpreter slot
1245 InterpEntry *QKernel::findINTbySocket(int _id)
1248 pom = Interpreters.first();
1250 while (pom != NULL) {
1251 if (pom->sock == _id)
1254 pom = Interpreters.next();
1260 * Finds Interpreter by its ID.
1261 * @param _id ID of the interpreter
1262 * @return returns pointer to the found interpreter slot
1264 InterpEntry *QKernel::findINTbyID(int _id)
1267 pom = Interpreters.first();
1268 while (pom != NULL) {
1271 pom = Interpreters.next();
1278 * Connects interpreter
1279 * @param ss full filepath with filename but without extension of the loglan
1281 * @param r Interpreter execution mode. 0 if it will be local instance, 1 if
1283 * @return Returns pointer to newly created interpreter slot, or NULL on error.
1285 InterpEntry *QKernel::RunIntModule(char *ss, int r)
1287 char a[256], b[255];
1288 struct sockaddr_un svr;
1289 int len, sock, i, on;
1294 InterpEntry *newINT = NULL;
1300 WriteMessage("File not found: no .ccd file");
1309 WriteMessage("File not found: no .pcd file");
1314 newINT = new InterpEntry;
1315 for(i = 0; i < MAXINSTANCES; i++)
1316 newINT->RInstances[i] =- 1;
1318 strcpy(b, rindex(ss, '/'));
1319 for(i = 0; i < strlen(b); i++)
1321 if (info_messages) {
1322 sprintf(a, "%s : Start execution", b);
1328 newINT->ID = newint;
1329 strcpy(newINT->shortname, b);
1330 strcpy(newINT->fullname, ss);
1332 sprintf(a, "%s%d", IPATH, newint);
1333 sprintf(cmd, "%s/modules/logint %s %s", HomeDir, a, ss);
1336 sprintf(b, " %s %s %s %s %s", myargs[0], myargs[1], myargs[2],
1337 myargs[3], myargs[4]);
1341 sock = socket(AF_UNIX, SOCK_STREAM, 0);
1343 bzero(&svr, sizeof(svr));
1344 svr.sun_family = AF_UNIX;
1345 strcpy(svr.sun_path, a);
1346 len = strlen(svr.sun_path)+sizeof(svr.sun_family);
1347 bind(sock, (struct sockaddr*)&svr, len);
1350 newINT->sock = accept(sock, (struct sockaddr*)0, (unsigned int *)0);
1353 if (newINT->sock > 0) {
1354 fcntl(newINT->sock, F_SETFL,
1355 O_NONBLOCK|fcntl(newINT->sock, F_GETFL, 0));
1357 setsockopt(newINT->sock, IPPROTO_TCP, TCP_NODELAY, (char*)&on,
1364 bzero(&msg, sizeof(MESSAGE));
1365 msg.msg_type = MSG_VLP;
1366 msg.param.pword[0] = VLP_REGINT;
1367 msg.param.pword[1] = newINT->ID;
1368 sprintf(msg.param.pstr, "logi%d.net", newint);
1369 write(net_sock, &msg, sizeof(MESSAGE));
1371 Interpreters.append(newINT);
1372 newINT->notify = new QSocketNotifier(newINT->sock,
1373 QSocketNotifier::Read);
1374 connect(newINT->notify, SIGNAL(activated(int)), this,
1375 SLOT(IntMessage(int)));
1377 WriteMessage("INTERPRETER successfully connected");
1379 WriteMessage("Cannot connect interpreter");
1386 * Allocates remote instance of interpreter
1387 * @param interp Interpreter slot
1388 * @param on Node Number
1390 void QKernel::RemoteInstance(InterpEntry *interp, int on)
1395 m.msg_type = MSG_NET;
1396 m.param.pword[0] = NET_NODE_EXIST;
1397 m.param.pword[1] = on;
1398 m.param.pword[2] = interp->ID;
1399 write(net_sock, &m, sizeof(MESSAGE));
1400 bzero(&m, sizeof(MESSAGE));
1401 while((m.msg_type!=MSG_NET) && (m.param.pword[0]!=NET_NODE_EXIST))
1402 read(net_sock, &m, sizeof(MESSAGE));
1404 /* means node exists */
1405 if (m.param.pword[1] == 1) {
1406 m.msg_type = MSG_NET;
1407 m.param.pword[0] = NET_TRANSMIT_CODE;
1408 m.param.pword[1] = interp->ID;
1409 m.param.pword[2] = on;
1410 strcpy(m.param.pstr, interp->fullname);
1411 write(net_sock, &m, sizeof(MESSAGE));
1413 Net_Notify->setEnabled(FALSE);
1414 while ((m.msg_type != MSG_NET) ||
1415 (m.param.pword[0] != NET_TRANSMITTED))
1416 read(net_sock, &m, sizeof(MESSAGE));
1418 m.msg_type = MSG_NET;
1419 m.param.pword[0] = NET_PROPAGATE;
1420 m.param.pword[1] = MSG_VLP;
1421 m.param.pword[2] = NodeNumber;
1422 m.param.pword[3] = 0;
1423 m.param.pword[4] = on;
1424 m.param.pword[5] = 0;
1425 m.param.pword[6] = VLP_REMOTE_INSTANCE;
1426 m.param.pword[7] = interp->ID;
1427 strcpy(m.param.pstr, interp->shortname);
1428 write(net_sock, &m, sizeof(MESSAGE));
1430 read(net_sock, &m, sizeof(MESSAGE));
1432 if ((m.param.pword[0] == NET_PROPAGATE) &&
1433 (m.param.pword[6] == VLP_REMOTE_INSTANCE_OK)) {
1434 interp->RInstances[on] = m.param.pword[7];
1437 read(net_sock, &m, sizeof(MESSAGE));
1440 Net_Notify->setEnabled(TRUE);
1442 /*bzero(&m, sizeof(MESSAGE));*/
1443 m.msg_type = MSG_VLP;
1444 m.param.pword[0] = VLP_REMOTE_INSTANCE_HERE;
1445 m.param.pword[1] = interp->RInstances[on];
1446 write(interp->sock, &m, sizeof(MESSAGE));
1447 } else { /* There is no such a node! */
1448 sprintf(s, "Warning: Node number %d not found!", on);
1450 WriteMessage("Allocating O-process on the local node");
1451 bzero(&m, sizeof(MESSAGE));
1452 m.msg_type = MSG_VLP;
1453 m.param.pword[0] = VLP_REMOTE_INSTANCE_HERE;
1454 m.param.pword[1] = interp->ID;
1455 write(interp->sock, &m, sizeof(MESSAGE));
1460 * Closes all remote instances
1462 void QKernel::CloseInstances(InterpEntry *e)
1468 WriteMessage("Closing remote instances");
1470 for(i=0; i < MAXINSTANCES; i++)
1471 if (e->RInstances[i]>=0) {
1472 msg.msg_type = MSG_NET;
1473 msg.param.pword[0] = NET_PROPAGATE;
1474 msg.param.pword[1] = MSG_VLP;
1475 msg.param.pword[2] = NodeNumber;
1476 msg.param.pword[4] = i;
1477 msg.param.pword[6] = VLP_CLOSE_INSTANCE;
1478 msg.param.pword[7] = e->RInstances[i];
1479 write(net_sock, &msg, sizeof(MESSAGE));
1484 * Displays information about virtual machine
1486 void QKernel::Info()
1490 WriteMessage(CharLine);
1491 WriteMessage("### Virtual Machine Information ###");
1492 m.msg_type = MSG_NET;
1493 m.param.pword[0] = NET_GET_INFO;
1494 write(net_sock, &m, sizeof(MESSAGE));
1495 wait_for_info = TRUE;
1498 #include "kernel.moc"
1501 * Program main function
1502 * All program arguments but the first one (argv[0]: program name) are saved and
1503 * passed to all dependent programs on their invocation.
1504 * @param argc Number of program arguments
1505 * @param argv Program arguments
1507 int main(int argc, char **argv)
1510 for(i = 0; i < 5; i++) {
1511 strcpy(myargs[i], "");
1513 for(i = 1; i < argc; i++) {
1514 strcpy(myargs[i - 1], argv[i]);
1517 app = new QApplication(argc, argv);
1518 app->setStyle(new QWindowsStyle());
1520 app->setMainWidget(&kernel);
1522 kernel.InitMessage();