1 /**************************************************************
3 Copyright (C) 1997 Oskar Swida
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License
7 as published by the Free Software Foundation; either version 2
8 of the License, or (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 NOTE: This software is using the free software license of
23 the QT library v.1.30 from Troll Tech AS.
24 See the file LICENSE.QT.
27 To contact the author, write:
28 e-mail: swida@aragorn.pb.bialystok.pl
30 ************************************************************/
33 #include <QtGui/QApplication>
34 #include <QtGui/QMainWindow>
35 #include <QtGui/QTextEdit>
36 #include <QtGui/QMenuBar>
37 #include <QtGui/QMessageBox>
38 #include <QtGui/QFileDialog>
39 #include <QtGui/QDialog>
40 #include <QtCore/QString>
41 #include <QtGui/QLabel>
42 #include <QtGui/QLineEdit>
43 #include <QtGui/QPushButton>
44 #include <QtGui/QRadioButton>
45 #include <QtGui/QGroupBox>
46 #include <QtGui/QVBoxLayout>
47 #include <QtCore/QList>
48 #include <QtGui/QListWidget>
51 #include <QtCore/QSocketNotifier>
52 #include <QtGui/QCloseEvent>
62 #include <netinet/in.h>
64 #include <libconfig.h>
67 #include "kernelwindow.h"
70 /* File resides in top directory (where are Makefiles)*/
71 #include "../../config.h"
74 char CharLine[25] = "________________________";
80 * Event invoked on program close.
81 * Closes application. Displays additional window to confirm exit.
83 void QKernel::closeEvent(QCloseEvent * e)
88 on_actionQuit_triggered();
92 void QKernel::setLocked(bool locked)
96 actionQuit->setDisabled(locked);
98 actionExecute->setDisabled(locked);
99 actionKill->setDisabled(locked);
100 actionMessage->setDisabled(locked);
101 actionConnect->setDisabled(locked);
102 actionDisconnect->setDisabled(locked);
103 actionInfo->setDisabled(locked);
106 /* Enable only menu entry for unlocking */
107 actionEditor->setDisabled(locked);
108 actionOptions->setDisabled(locked);
109 actionLock_console->setDisabled(locked);
110 actionUnlock_console->setDisabled(!locked);
114 * Kernel program constructor.
115 * Prepares everything to work.
125 sprintf(ss, "mkdir %s", REMOTE_PATH);
129 info_messages = TRUE;
130 wait_for_info = FALSE;
132 setWindowTitle(PACKAGE_NAME);
138 ActiveConnections = 0;
139 strcpy(LockPasswd, "");
140 LoadConfig("vlp.cfg");
143 Net_Notify = new QSocketNotifier(net_sock, QSocketNotifier::Read, this);
144 connect(Net_Notify, SIGNAL(activated(int)), this, SLOT(NetMessage()));
148 * Displays window with information about not implemented functionality.
150 void QKernel::n_impl()
152 QMessageBox::information(this, "Function info", "This function is not "
153 "implemented yet...", "Ok");
157 * Loads configuration from the given file.
158 * @param fname Filename of the configuration file.
160 void QKernel::LoadConfig(char * fname)
163 config_setting_t *setting;
166 /* Hack for checking if file exists without using external libs.*/
167 FILE * file = fopen(fname, "rt");
169 fprintf(stderr, "Error: Cannot load configuration file %s!\n",
173 /* File exists, so file has been locked. Release it. */
177 /* Read the file. If there is an error, report it and exit. */
178 if (!config_read(&cfg, file)) {
179 fprintf(stderr, "%s! In file %s, line %d\n",
180 config_error_text(&cfg),
181 config_error_file(&cfg),
182 config_error_line(&cfg));
183 config_destroy(&cfg);
188 setting = config_lookup(&cfg, "node_number");
190 NodeNumber = config_setting_get_int(setting);
192 fprintf(stderr, "%s! In file %s, '%s' was not found.\n",
193 "Warning", fname, "node_number");
194 config_destroy(&cfg);
199 setting = config_lookup(&cfg, "type");
201 /* same as strcmp(..) == 0 */
202 if (!strcmp(config_setting_get_string(setting), "explicit")) {
208 fprintf(stderr, "%s! In file %s, '%s' was not found.\n",
209 "Warning", fname, "type");
212 setting = config_lookup(&cfg, "host");
214 switch(config_setting_type(setting)) {
215 /* TODO: Deprecated. Made for back compatibility. */
216 case CONFIG_TYPE_STRING:
217 ConnectList.append(new ConnectEntry((char*)
218 config_setting_get_string(setting)));
220 case CONFIG_TYPE_ARRAY: {
221 int size = config_setting_length(setting);
222 for (int i = 0; i < size; i++) {
223 ConnectList.append(new ConnectEntry((char*)
224 config_setting_get_string_elem(setting,
230 fprintf(stderr, "%s! In file %s, bad entry type for %s."
231 " Will not be read.\n",
232 "Error", fname, "host");
235 fprintf(stderr, "%s! In file %s, '%s' was not found.\n",
236 "Warning", fname, "host");
239 setting = config_lookup(&cfg, "progdir");
241 strncpy(progdir, config_setting_get_string(setting), 256);
243 fprintf(stderr, "%s! In file %s, '%s' was not found.\n",
244 "Warning", fname, "progdir");
247 setting = config_lookup(&cfg, "homedir");
249 strncpy(HomeDir, config_setting_get_string(setting), 255);
251 fprintf(stderr, "%s! In file %s, '%s' was not found.\n",
252 "Warning", fname, "homedir");
255 config_destroy(&cfg);
261 * Additional window id displayed to set which code to execute.
263 void QKernel::on_actionExecute_triggered()
266 QString s = QFileDialog::getOpenFileName(this, "Execute", progdir, "*.log");
269 i = s.indexOf(".log");
274 RunIntModule((char*)s.toAscii().data(), 0);
279 * Invokes editor program
281 void QKernel::on_actionEditor_triggered()
284 sprintf(cmd, "%s/modules/logedit %s %s %s %s %s %s &", HomeDir, HomeDir,
285 myargs[0], myargs[1], myargs[2], myargs[3], myargs[4]);
290 * Invokes help program
292 void QKernel::on_actionHelp_triggered()
295 sprintf(cmd, "%s/modules/loghelp %s/doc %s %s %s %s %s &", HomeDir,
296 HomeDir, myargs[0], myargs[1], myargs[2], myargs[3], myargs[4]);
301 * Invokes graphics module
303 void QKernel::RunGraphModule(char *sk)
307 sprintf(cmd, "%s/modules/loggraph %s %s %s %s %s %s &", HomeDir,
308 sk, myargs[0], myargs[1], myargs[2], myargs[3], myargs[4]);
310 if (system(cmd) != 0)
311 WriteMessage("Cannot connect GRAPH resources");
317 void QKernel::RunNetModule()
319 struct sockaddr_un svr;
323 sprintf(cmd, "%s/modules/lognet %s %s %s %s %s %s &", HomeDir,
324 NPATH, myargs[0], myargs[1], myargs[2], myargs[3], myargs[4]);
326 /* -------- socket for NET module -------- */
328 sock = socket(AF_UNIX, SOCK_STREAM, 0);
329 bzero(&svr, sizeof(svr));
330 svr.sun_family = AF_UNIX;
331 strcpy(svr.sun_path, NPATH);
332 len = strlen(svr.sun_path) + sizeof(svr.sun_family);
333 bind(sock, (struct sockaddr*)&svr, len);
336 if (system(cmd) == 0) {
337 net_sock = accept(sock, (struct sockaddr*)0, (unsigned int*)0);
340 WriteMessage("NETWORK successfully connected");
341 fcntl(net_sock, F_SETFL, O_NONBLOCK|fcntl(net_sock,
344 setsockopt(net_sock, IPPROTO_TCP, TCP_NODELAY,
345 (char*)&on, sizeof(on));
347 WriteMessage("Cannot connect NETWORK resources");
348 WriteMessage("Exiting...");
350 on_actionQuit_triggered();
354 WriteMessage("Cannot connect NETWORK resources");
355 WriteMessage("Exiting...");
357 on_actionQuit_triggered();
362 * Connects to the specified address
363 * Additional window is displayed to connect to the specified address
365 void QKernel::on_actionConnect_triggered()
367 QDialog d(this, Qt::Dialog);
368 QLabel lab("IP Address:", &d);
369 QLineEdit ed("", &d);
370 QPushButton ob("", &d);
371 QPushButton cb("", &d);
374 ob.setGeometry(30, 60, 80, 30);
377 lab.setGeometry(10, 10, 60, 30);
378 lab.setText("Address");
379 ed.setGeometry(70, 10, 140, 30);
380 cb.setGeometry(130, 60, 80, 30);
381 cb.setText("Cancel");
384 connect(&ob, SIGNAL(clicked()), &d, SLOT(accept()));
385 connect(&cb, SIGNAL(clicked()), &d, SLOT(reject()));
387 m.msg_type = MSG_NET;
388 m.param.pword[0] = NET_CONNECT_TO;
389 strcpy(m.param.pstr, ed.text().toAscii().data());
390 write(net_sock, &m, sizeof(MESSAGE));
395 * Disconnects from virtual machine
397 void QKernel::on_actionDisconnect_triggered()
402 WriteMessage("Disconnecting from virtual machine");
404 msg.msg_type = MSG_NET;
405 msg.param.pword[0] = NET_DISCONNECT;
406 write(net_sock, &msg, sizeof(MESSAGE));
410 * Quits process. Closes VLP. Shows additional window to confirm exit.
412 void QKernel::on_actionQuit_triggered()
416 QMessageBox::StandardButton response;
417 response = QMessageBox::question(this, "Close VLP", "Terminate VLP ?",
418 QMessageBox::Ok | QMessageBox::Cancel);
421 if (response == QMessageBox::Cancel) {
425 msg.msg_type = MSG_NET;
426 msg.param.pword[0] = NET_DISCONNECT;
427 write(net_sock, &msg, sizeof(MESSAGE));*/
430 msg.msg_type = MSG_NET;
431 msg.param.pword[0] = NET_EXIT;
432 write(net_sock, &msg, sizeof(MESSAGE));
433 /* ::close(net_sock);*/
434 QApplication::instance()->quit();
438 * Adds IP address to the configuration.
439 * Additional window is displayed to add address to the list
441 void QKernel::AddAddress()
443 QDialog d(this, Qt::Dialog);
444 QLabel lab("IP Address:", &d);
445 QLineEdit ed("", &d);
446 QPushButton ob("", &d);
447 QPushButton cb("", &d);
450 ob.setGeometry(30, 60, 80, 30);
453 lab.setGeometry(10, 10, 60, 30);
454 lab.setText("Address");
455 ed.setGeometry(70, 10, 140, 30);
456 cb.setGeometry(130, 60, 80, 30);
457 cb.setText("Cancel");
459 connect(&ob, SIGNAL(clicked()), &d, SLOT(accept()));
460 connect(&cb, SIGNAL(clicked()), &d, SLOT(reject()));
462 if (strcmp(ed.text().toAscii().data(), "") != 0) {
463 connections->addItem(ed.text());
469 * Deletes current address from available connections.
471 void QKernel::DelAddress()
474 if (connections->currentRow() != -1) {
475 /* TODO: Checki if this work correctly after porting */
476 connections->removeItemWidget(connections->currentItem());
482 * Sends message to node.
483 * Additional window is displayed to set Node Number of node where send message,
484 * and textfield to enter message.
486 void QKernel::on_actionMessage_triggered()
492 dlg = new QDialog(this, Qt::Dialog);
493 dlg->setWindowTitle("Send message to node");
495 nodenr = new QLineEdit("number", dlg);
496 nodenr->setGeometry(90, 10, 50, 30);
500 tmpQLabel = new QLabel("Node number:", dlg);
501 tmpQLabel->setGeometry(10, 10, 77, 30);
503 tmpQLabel = new QLabel("Message:", dlg);
504 tmpQLabel->setGeometry(10, 50, 70, 30);
507 msg = new QLineEdit("", dlg);
508 msg->setGeometry(80, 60, 330, 30);
511 ob = new QPushButton("Send", dlg);
512 ob->setGeometry(230, 10, 80, 30);
513 ob->setDefault(TRUE);
516 cb = new QPushButton("Cancel", dlg);
517 cb->setGeometry(330, 10, 80, 30);
518 dlg->resize(430, 110);
519 connect(ob, SIGNAL(clicked()), dlg, SLOT(accept()));
520 connect(cb, SIGNAL(clicked()), dlg, SLOT(reject()));
523 m.msg_type = MSG_NET;
524 m.param.pword[0] = NET_PROPAGATE;
525 m.param.pword[1] = MSG_VLP;
526 m.param.pword[2] = NodeNumber;
527 m.param.pword[4] = atoi(nodenr->text().toAscii().data());
528 m.param.pword[6] = VLP_WRITE;
529 strcpy(m.param.pstr, msg->text().toAscii().data());
530 write(net_sock, &m, sizeof(MESSAGE));
536 * Additional window is displayed to get ID of interpreter which should be
539 void QKernel::on_actionKill_triggered()
546 dlg = new QDialog(this, Qt::Dialog);
547 dlg->setWindowTitle("Kill interpreter");
549 nodenr = new QLineEdit("", dlg);
550 nodenr->setGeometry(90, 10, 50, 30);
552 QLabel * tmpQLabel = new QLabel("Interp. ID:", dlg);
553 tmpQLabel->setGeometry(10, 10, 77, 30);
555 QPushButton * ob = new QPushButton("Kill", dlg);
556 ob->setGeometry( 160, 10, 80, 30);
557 ob->setDefault(TRUE);
559 QPushButton * cb = new QPushButton("Cancel", dlg);
560 cb->setGeometry(260, 10, 80, 30);
561 dlg->resize(360, 50);
563 connect(ob, SIGNAL(clicked()), dlg, SLOT(accept()));
564 connect(cb, SIGNAL(clicked()), dlg, SLOT(reject()));
567 m.msg_type = MSG_INT;
568 m.param.pword[0] = INT_KILL;
569 pom = findINTbyID(atoi(nodenr->text().toAscii().data()));
572 write(pom->sock, &m, sizeof(MESSAGE));
574 WriteMessage("This is a remote instance of "
578 WriteMessage("Interpreter not found");
584 * Sends message to the net module.
586 void QKernel::NetMessage()
589 /* TODO: It has to be rewritten */
595 cnt = read(net_sock, &msg, sizeof(MESSAGE));
596 if ((cnt > 0) && (msg.msg_type == MSG_NET)) {
597 switch(msg.param.pword[0]) {
599 WriteMessage(msg.param.pstr);
602 switch(msg.param.pword[1]) {
604 /* pom = find_link_by_ID(msg.param.pword[5]);
605 msg.msg_type = MSG_NET;
606 msg.param.pword[0] = NET_PROPAGATE;
607 send_int(pom, &msg);*/
610 switch(msg.param.pword[6]) {
612 QApplication::beep();
613 WriteMessage(CharLine);
615 "### Incoming Messsage ###");
616 sprintf(ss, "Mesg from Node %d: %s",
620 WriteMessage(CharLine);
622 case VLP_REMOTE_INSTANCE:
623 sprintf(ss, "%s/%s", REMOTE_PATH,
627 WriteMessage("Running program:");
630 pom = RunIntModule(ss, 1);
632 pom->p_ctx.node = msg.param.pword[2];
633 pom->p_ctx.program_id =
635 pom->RInstances[msg.param.pword[2]] = msg.param.pword[7];
638 case VLP_CLOSE_INSTANCE:
639 msg.msg_type = MSG_INT;
640 msg.param.pword[0] = INT_CLOSE_INSTANCE;
641 pom = findINTbyID(msg.param.pword[7]);
643 write(pom->sock, &msg,
646 m1.msg_type = MSG_VLP;
647 m1.param.pword[0] = VLP_INTERPRETER_DOWN;
648 m1.param.pword[1] = pom->ID;
652 WriteMessage("Instance not found");
658 case NET_CONNECTIONS:
659 ActiveConnections = msg.param.pword[1];
660 WriteMessage(msg.param.pstr);
665 /* TODO: It has to be rewritten */
667 QString poms, poms1, poms2;
668 poms.sprintf("%s", msg.param.pstr);
669 while (poms.length() > 0) {
670 cnt = poms.indexOf(';');
672 poms1 = poms.left(cnt);
673 poms = poms.right(poms.length() - cnt - 1);
674 cnt = poms1.indexOf('=');
676 poms2 = poms1.left(cnt);
680 sprintf(ss, "Node: %s Addr: %s", poms2.data(), poms1.data());
688 wait_for_info = FALSE;
689 WriteMessage(CharLine);
696 * Sends message to the interpreter program.
697 * @param sock Interpreter socket to whom the message will be send.
699 void QKernel::IntMessage(int sock)
705 cnt = read(sock, &msg, sizeof(MESSAGE));
706 e = findINTbySocket(sock);
707 if ((cnt > 0) && (e != NULL)) {
708 switch (msg.msg_type) {
710 if (msg.param.pword[0] == GRAPH_ALLOCATE) {
711 RunGraphModule(msg.param.pstr);
715 write(net_sock, &msg, sizeof(MESSAGE));
718 switch(msg.param.pword[0]) {
719 case VLP_REMOTE_INSTANCE_PLEASE:
720 RemoteInstance(e, msg.param.pword[2]);
725 switch(msg.param.pword[0]) {
730 m.msg_type = MSG_VLP;
731 m.param.pword[0] = VLP_INTERPRETER_DOWN;
732 m.param.pword[1] = e->ID;
733 write(net_sock, &m, sizeof(MESSAGE));
738 /* TODO: Check this */
739 Interpreters.removeOne(e);
743 sprintf(ss, "%s : End of program "
744 "execution", msg.param.pstr);
749 msg.msg_type = MSG_INT;
750 msg.param.pword[0] = INT_CTX;
751 msg.param.pword[1] = NodeNumber;
752 msg.param.pword[2] = e->ID;
754 msg.param.pword[3] = e->p_ctx.node;
758 write(sock, &msg, sizeof(MESSAGE));
767 * Writes message to kernel logger.
768 * @parame msg String with message to log
770 void QKernel::WriteMessage(char *msg)
774 x = desktop->textCursor().blockNumber();
775 y = desktop->textCursor().columnNumber();
781 desktop->setReadOnly(FALSE);
782 desktop->append(msg);
783 desktop->setReadOnly(TRUE);
785 QTextCursor tmpCursor = desktop->textCursor();
786 tmpCursor.movePosition(QTextCursor::End, QTextCursor::MoveAnchor);
787 desktop->setTextCursor(tmpCursor);
791 if (desktop->document()->blockCount() > 100) {
797 * Adds checkbox to menu item. If it is checked additional info messages are
800 void QKernel::on_actionInfo_messages_triggered()
802 if (toolsMenu != NULL) {
803 actionInfo_messages->setChecked(!actionInfo_messages->isChecked());
804 // actionInfo_messages->toggle();
805 info_messages = actionInfo_messages->isChecked();
806 fprintf(stderr, "Info is checked? %s\n", actionInfo_messages->isChecked() ? "yes" : "no");
808 // menuBar()->repaint();
812 * Allows to set options in GUI window.
813 * Additional window is displayed to set kernel options which are saved in
814 * vlp.cfg file in kernel executable directory.
816 void QKernel::on_actionOptions_triggered()
818 QDialog dlg(this, Qt::Dialog);
819 dlg.setWindowTitle("Options");
824 progs = new QLineEdit(progdir, &dlg);
825 progs->setGeometry(150, 20, 180, 30);
828 tmpQLabel = new QLabel("Programs directory", &dlg);
829 tmpQLabel->setGeometry(30, 20, 120, 30);
832 tmpQFrame = new QFrame(&dlg);
833 tmpQFrame->setGeometry(10, 60, 380, 30);
834 tmpQFrame->setFrameStyle(52);
836 tmpQLabel = new QLabel("Virtual Processor properties (activated after "
837 "restarting VLP):", &dlg);
838 tmpQLabel->setGeometry(10, 80, 340, 30);
842 sprintf(nns, "%d", NodeNumber);
843 nn = new QLineEdit(nns, &dlg);
844 nn->setGeometry(110, 110, 40, 30);
846 tmpQLabel = new QLabel("Node number:", &dlg);
847 tmpQLabel->setGeometry(20, 110, 90, 30);
849 QRadioButton *exp, *reg;
850 exp = new QRadioButton("Explicit", &dlg);
851 exp->setGeometry(30, 170, 100, 30);
852 exp->setChecked(TRUE);
854 reg = new QRadioButton("Registration", &dlg);
855 reg->setGeometry(30, 200, 100, 30);
856 reg->setEnabled(FALSE);
858 connections = new QListWidget(&dlg);
859 connections->setGeometry(170, 140, 130, 100);
861 for (int i = 0; i < ConnectList.size(); i++) {
862 e = ConnectList.at(i);
863 connections->addItem(e->addr);
866 tmpQLabel = new QLabel("Connection list:", &dlg);
867 tmpQLabel->setGeometry(170, 110, 100, 30);
872 QPushButton *cancelbtn;
873 addbtn = new QPushButton("Add", &dlg);
874 addbtn->setGeometry(310, 150, 60, 30);
875 connect(addbtn, SIGNAL(clicked()), this, SLOT(AddAddress()));
877 delbtn = new QPushButton("Del", &dlg);
878 delbtn->setGeometry(310, 200, 60, 30);
879 connect(delbtn, SIGNAL(clicked()), this, SLOT(DelAddress()));
881 okbtn = new QPushButton("Ok", &dlg);
882 okbtn->setGeometry(80, 260, 100, 30);
883 okbtn->setDefault(TRUE);
884 connect(okbtn, SIGNAL(clicked()), &dlg, SLOT(accept()));
886 cancelbtn = new QPushButton("Cancel", &dlg);
887 cancelbtn->setGeometry(210, 260, 100, 30);
888 connect(cancelbtn, SIGNAL(clicked()), &dlg, SLOT(reject()));
891 group = new QGroupBox("Connection type", &dlg);
892 group->setGeometry(20, 150, 120, 90);
893 group->setAlignment(Qt::AlignLeft);
896 QVBoxLayout *vbox = new QVBoxLayout();
897 vbox->addWidget(exp);
898 vbox->addWidget(reg);
900 group->setLayout(vbox);
902 dlg.resize(400, 310);
905 config_setting_t *root;
906 config_setting_t *setting;
909 root = config_root_setting(&cfg);
911 setting = config_setting_add(root, "progdir",
913 config_setting_set_string(setting, progs->text().toAscii().data());
914 strcpy(progdir, progs->text().toAscii().data());
916 setting = config_setting_add(root, "node_number",
918 config_setting_set_int(setting, atoi(nn->text().toAscii().data()));
920 setting = config_setting_add(root, "homedir",
922 config_setting_set_string(setting, HomeDir);
924 setting = config_setting_add(root, "type",
926 if (exp->isChecked()) {
927 config_setting_set_string(setting, "explicit");
929 config_setting_t *hosts = NULL;
930 hosts = config_setting_add(root, "host",
932 for(i = 0; i < connections->count(); i++) {
933 setting = config_setting_add(hosts, NULL,
935 config_setting_set_string(setting,
936 connections->item(i)->text().toAscii().data());
939 config_setting_set_string(setting, "register");
942 if (!config_write_file(&cfg, "vlp.cfg")) {
943 fprintf(stderr, "Error while writing to file: %s.\n",
946 config_destroy(&cfg);
951 * Locks kernel program.
952 * Additional window is displayed to enter password and retype it. If both are
953 * same kernel window is locked.
955 void QKernel::on_actionLock_console_triggered()
957 LockDialog lockDialog(this);
959 if (lockDialog.exec()) {
960 QString password = lockDialog.getPassword();
961 if (lockDialog.getPassword().size() > 0) {
962 strcpy(LockPasswd, password.toAscii().data());
965 if (lockDialog.exec()) {
966 password = lockDialog.getPassword();
967 if (password == LockPasswd) {
969 WriteMessage("CONSOLE LOCKED");
971 QMessageBox msg(this);
972 msg.setText("Not matching!");
973 msg.setButtonText(0, "Close");
975 strcpy(LockPasswd, "");
978 strcpy(LockPasswd, "");
985 * Unlocks kernel program.
986 * Additional window is displayed to enter password. If it is correct, kernel
989 void QKernel::on_actionUnlock_console_triggered()
991 QDialog d(this, Qt::Dialog);
992 d.setWindowTitle("Enter password");
994 QLabel lab("Password:", &d);
995 lab.setGeometry(10, 10, 60, 30);
997 QLineEdit ed("", &d);
998 ed.setGeometry(70, 10, 140, 30);
999 ed.setEchoMode(QLineEdit::Password);
1001 QPushButton ob("Ok", &d);
1002 ob.setGeometry(30, 60, 80, 30);
1003 ob.setDefault(TRUE);
1004 connect(&ob, SIGNAL(clicked()), &d, SLOT(accept()));
1006 QPushButton cb("Cancel", &d);
1007 cb.setGeometry(130, 60, 80, 30);
1008 connect(&cb, SIGNAL(clicked()), &d, SLOT(reject()));
1013 if (strcmp(ed.text().toAscii().data(), LockPasswd) == 0) {
1015 WriteMessage("CONSOLE UNLOCKED");
1017 QMessageBox msg(this);
1018 msg.setText("Wrong password!");
1019 msg.setButtonText(0, "Close");
1026 * Writes init message in kernel
1028 void QKernel::InitMessage()
1030 WriteMessage("\n " PACKAGE_STRING ": READY \n");
1034 * Finds Interpreter by its socket
1035 * @param _id ID of the socket
1036 * @return returns pointer to the found interpreter slot. NULL otherwise
1038 InterpEntry *QKernel::findINTbySocket(int _id)
1040 InterpEntry *pom = NULL;
1042 for (int i = 0; i < Interpreters.size(); i++) {
1043 if (Interpreters.at(i)->sock == _id) {
1044 pom = Interpreters.at(i);
1053 * Finds Interpreter by its ID.
1054 * @param _id ID of the interpreter
1055 * @return returns pointer to the found interpreter slot. NULL otherwise
1057 InterpEntry *QKernel::findINTbyID(int _id)
1059 InterpEntry *pom = NULL;
1061 for (int i = 0; i < Interpreters.size(); i++) {
1062 if (Interpreters.at(i)->ID == _id) {
1063 pom = Interpreters.at(i);
1073 * Connects interpreter
1074 * @param ss full filepath with filename but without extension of the loglan
1076 * @param r Interpreter execution mode. 0 if it will be local instance, 1 if
1078 * @return Returns pointer to newly created interpreter slot, or NULL on error.
1080 InterpEntry *QKernel::RunIntModule(char *ss, int r)
1082 char a[256], b[255];
1083 struct sockaddr_un svr;
1084 int len, sock, i, on;
1089 InterpEntry *newINT = NULL;
1095 WriteMessage("File not found: no .ccd file");
1104 WriteMessage("File not found: no .pcd file");
1109 newINT = new InterpEntry;
1110 for(i = 0; i < MAXINSTANCES; i++)
1111 newINT->RInstances[i] =- 1;
1113 strcpy(b, rindex(ss, '/'));
1114 for(i = 0; i < strlen(b); i++)
1116 if (info_messages) {
1117 sprintf(a, "%s : Start execution", b);
1123 newINT->ID = newint;
1124 strcpy(newINT->shortname, b);
1125 strcpy(newINT->fullname, ss);
1127 sprintf(a, "%s%d", IPATH, newint);
1128 sprintf(cmd, "%s/modules/logint %s %s", HomeDir, a, ss);
1131 sprintf(b, " %s %s %s %s %s", myargs[0], myargs[1], myargs[2],
1132 myargs[3], myargs[4]);
1136 sock = socket(AF_UNIX, SOCK_STREAM, 0);
1138 bzero(&svr, sizeof(svr));
1139 svr.sun_family = AF_UNIX;
1140 strcpy(svr.sun_path, a);
1141 len = strlen(svr.sun_path)+sizeof(svr.sun_family);
1142 bind(sock, (struct sockaddr*)&svr, len);
1145 newINT->sock = accept(sock, (struct sockaddr*)0, (unsigned int *)0);
1148 if (newINT->sock > 0) {
1149 fcntl(newINT->sock, F_SETFL,
1150 O_NONBLOCK|fcntl(newINT->sock, F_GETFL, 0));
1152 setsockopt(newINT->sock, IPPROTO_TCP, TCP_NODELAY, (char*)&on,
1159 bzero(&msg, sizeof(MESSAGE));
1160 msg.msg_type = MSG_VLP;
1161 msg.param.pword[0] = VLP_REGINT;
1162 msg.param.pword[1] = newINT->ID;
1163 sprintf(msg.param.pstr, "logi%d.net", newint);
1164 write(net_sock, &msg, sizeof(MESSAGE));
1166 Interpreters.append(newINT);
1167 newINT->notify = new QSocketNotifier(newINT->sock,
1168 QSocketNotifier::Read);
1169 connect(newINT->notify, SIGNAL(activated(int)), this,
1170 SLOT(IntMessage(int)));
1172 WriteMessage("INTERPRETER successfully connected");
1174 WriteMessage("Cannot connect interpreter");
1181 * Allocates remote instance of interpreter
1182 * @param interp Interpreter slot
1183 * @param on Node Number
1185 void QKernel::RemoteInstance(InterpEntry *interp, int on)
1190 m.msg_type = MSG_NET;
1191 m.param.pword[0] = NET_NODE_EXIST;
1192 m.param.pword[1] = on;
1193 m.param.pword[2] = interp->ID;
1194 write(net_sock, &m, sizeof(MESSAGE));
1195 bzero(&m, sizeof(MESSAGE));
1196 while((m.msg_type!=MSG_NET) && (m.param.pword[0]!=NET_NODE_EXIST))
1197 read(net_sock, &m, sizeof(MESSAGE));
1199 /* means node exists */
1200 if (m.param.pword[1] == 1) {
1201 m.msg_type = MSG_NET;
1202 m.param.pword[0] = NET_TRANSMIT_CODE;
1203 m.param.pword[1] = interp->ID;
1204 m.param.pword[2] = on;
1205 strcpy(m.param.pstr, interp->fullname);
1206 write(net_sock, &m, sizeof(MESSAGE));
1208 Net_Notify->setEnabled(FALSE);
1209 while ((m.msg_type != MSG_NET) ||
1210 (m.param.pword[0] != NET_TRANSMITTED))
1211 read(net_sock, &m, sizeof(MESSAGE));
1213 m.msg_type = MSG_NET;
1214 m.param.pword[0] = NET_PROPAGATE;
1215 m.param.pword[1] = MSG_VLP;
1216 m.param.pword[2] = NodeNumber;
1217 m.param.pword[3] = 0;
1218 m.param.pword[4] = on;
1219 m.param.pword[5] = 0;
1220 m.param.pword[6] = VLP_REMOTE_INSTANCE;
1221 m.param.pword[7] = interp->ID;
1222 strcpy(m.param.pstr, interp->shortname);
1223 write(net_sock, &m, sizeof(MESSAGE));
1225 read(net_sock, &m, sizeof(MESSAGE));
1227 if ((m.param.pword[0] == NET_PROPAGATE) &&
1228 (m.param.pword[6] == VLP_REMOTE_INSTANCE_OK)) {
1229 interp->RInstances[on] = m.param.pword[7];
1232 read(net_sock, &m, sizeof(MESSAGE));
1235 Net_Notify->setEnabled(TRUE);
1237 /*bzero(&m, sizeof(MESSAGE));*/
1238 m.msg_type = MSG_VLP;
1239 m.param.pword[0] = VLP_REMOTE_INSTANCE_HERE;
1240 m.param.pword[1] = interp->RInstances[on];
1241 write(interp->sock, &m, sizeof(MESSAGE));
1242 } else { /* There is no such a node! */
1243 sprintf(s, "Warning: Node number %d not found!", on);
1245 WriteMessage("Allocating O-process on the local node");
1246 bzero(&m, sizeof(MESSAGE));
1247 m.msg_type = MSG_VLP;
1248 m.param.pword[0] = VLP_REMOTE_INSTANCE_HERE;
1249 m.param.pword[1] = interp->ID;
1250 write(interp->sock, &m, sizeof(MESSAGE));
1255 * Closes all remote instances
1257 void QKernel::CloseInstances(InterpEntry *e)
1263 WriteMessage("Closing remote instances");
1265 for(i=0; i < MAXINSTANCES; i++)
1266 if (e->RInstances[i]>=0) {
1267 msg.msg_type = MSG_NET;
1268 msg.param.pword[0] = NET_PROPAGATE;
1269 msg.param.pword[1] = MSG_VLP;
1270 msg.param.pword[2] = NodeNumber;
1271 msg.param.pword[4] = i;
1272 msg.param.pword[6] = VLP_CLOSE_INSTANCE;
1273 msg.param.pword[7] = e->RInstances[i];
1274 write(net_sock, &msg, sizeof(MESSAGE));
1279 * Displays information about virtual machine
1281 void QKernel::on_actionInfo_triggered()
1285 WriteMessage(CharLine);
1286 WriteMessage("### Virtual Machine Information ###");
1287 m.msg_type = MSG_NET;
1288 m.param.pword[0] = NET_GET_INFO;
1289 write(net_sock, &m, sizeof(MESSAGE));
1290 wait_for_info = TRUE;
1294 * Program main function
1295 * All program arguments but the first one (argv[0]: program name) are saved and
1296 * passed to all dependent programs on their invocation.
1297 * @param argc Number of program arguments
1298 * @param argv Program arguments
1300 int main(int argc, char **argv)
1303 for(i = 0; i < 5; i++) {
1304 strcpy(myargs[i], "");
1306 for(i = 1; i < argc; i++) {
1307 strcpy(myargs[i - 1], argv[i]);
1310 QApplication * app = new QApplication(argc, argv);
1313 kernel.InitMessage();