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/qpixmap.h>
34 //#include <qwindow.h>
35 #include <QtGui/qapplication.h>
36 #include <QtGui/qframe.h>
37 #include <Qt3Support/q3multilineedit.h>
38 #include <QtGui/qpainter.h>
39 #include <QtGui/qcolor.h>
40 #include <QtGui/qbrush.h>
41 #include <QtGui/qmenubar.h>
42 #include <Qt3Support/q3popupmenu.h>
43 #include <QtGui/qfont.h>
44 #include <QtGui/qmessagebox.h>
45 #include <QtGui/qfiledialog.h>
46 // #include <qtabdlg.h>
47 #include <QtCore/qstring.h>
48 #include <QtCore/qrect.h>
49 #include <QtGui/qdialog.h>
50 #include <QtGui/qbuttongroup.h>
51 #include <QtGui/qlabel.h>
52 #include <Qt3Support/q3multilineedit.h>
53 #include <Qt3Support/q3listbox.h>
54 #include <QtGui/qpushbutton.h>
55 #include <QtGui/qradiobutton.h>
56 #include <QtCore/qlist.h>
57 #include <QtCore/qfile.h>
58 #include <QtGui/qcursor.h>
59 #include <QtGui/qcombobox.h>
60 #include <QtCore/qsocketnotifier.h>
61 #include <QtCore/qdir.h>
62 #include <QtGui/qwindowsstyle.h>
72 #include <netinet/in.h>
74 #include <libconfig.h>
79 #define REMOTE_PATH "REMOTE"
81 #define MAXINSTANCES 256
89 char CharLine[25] = "________________________";
97 /** Interpreter identifier */
99 /** Defines if interpreter is remote or not */
107 QSocketNotifier *notify;
108 /* IDs of my remote INT modules */
109 int RInstances[MAXINSTANCES];
110 /* Parent interpreter info */
121 ConnectEntry(char *s) {
131 class QKernel : public QFrame {
134 Q3MultiLineEdit *desktop;
145 virtual void resizeEvent(QResizeEvent *ev);
147 void WriteMessage(char* msg);
159 void UnlockConsole();
160 void MessageToNode();
163 void IntMessage(int);
164 void KillInterpreter();
171 virtual void closeEvent (QCloseEvent * e);
174 QList<InterpEntry*> Interpreters;
175 QList<ConnectEntry*> ConnectList;
176 Q3ListBox *connections;
179 * number of working interpreters
184 * number of connected VLPs
186 int ActiveConnections;
204 QSocketNotifier *Net_Notify;
208 void LoadConfig(char *);
209 void RunGraphModule(char*);
211 InterpEntry *findINTbySocket(int);
212 InterpEntry *findINTbyID(int);
213 InterpEntry *RunIntModule(char *ss, int r);
214 void RemoteInstance(InterpEntry*, int);
215 void CloseInstances(InterpEntry*);
219 * Event invoked on program close.
220 * @copydoc QWidget::closeEvent(QCloseEvent*)
222 void QKernel::closeEvent(QCloseEvent * e)
228 * Kernel program constructor.
229 * Prepares everything to work.
233 QFont f("Helvetica", 10, QFont::Bold);
234 QFont f1("Helvetica", 10, QFont::Normal);
235 QFont f2("Times Roman", 10, QFont::Normal);
240 sprintf(ss, "mkdir %s", REMOTE_PATH);
244 info_messages = TRUE;
245 wait_for_info = FALSE;
247 // setCaption("Virtual LOGLAN Processor");// @TODO: Restore?
248 // setBackgroundColor(white);
250 QAction *execute = new QAction("Execute", this);
251 connect(execute, SIGNAL(triggered()), this, SLOT(Run_Prog()));
252 QAction *kill = new QAction("Kill", this);
253 connect(kill, SIGNAL(triggered()), this, SLOT(KillInterpreter()));
256 program = menuBar()->addMenu("&Program");
257 program->addAction(execute);
258 program->addAction(kill);
260 bar = new QMenuBar(this);
264 // p = new Q3PopupMenu();
266 // p->insertItem("Execute", this, SLOT(Run_Prog()));
267 // p->insertItem("Kill", this, SLOT(KillInterpreter()));
268 // prid = bar->insertItem("&Program", p);
269 p1 = new Q3PopupMenu();
270 p1->insertItem("Message", this, SLOT(MessageToNode()));
271 p1->insertSeparator();
272 p1->insertItem("Connect", this, SLOT(Connect()));
273 p1->insertItem("Disconnect", this, SLOT(Disconnect()));
274 p1->insertItem("Info", this, SLOT(Info()));
276 mid = bar->insertItem("&Machine", p1);
278 p2 = new Q3PopupMenu();
279 cwid = p2->insertItem("Editor", this, SLOT(Edit()));
280 hid = p2->insertItem("Help", this, SLOT(Help()));
281 p2->insertSeparator();
282 optid = p2->insertItem("Options", this, SLOT(SetOptions()));
283 msgid = p2->insertItem("Info messages", this, SLOT(SetMessages()));
284 p2->setItemChecked(msgid, TRUE);
285 p2->insertSeparator();
286 lockid = p2->insertItem("Lock console", this, SLOT(LockConsole()));
287 unlockid = p2->insertItem("Unlock console", this,
288 SLOT(UnlockConsole()));
289 p2->setItemEnabled(unlockid, FALSE);
292 toolsid = bar->insertItem("&Tools", p2);
294 qid = bar->insertItem("&Quit", this, SLOT(QuitProc()));
297 desktop = new Q3MultiLineEdit(this, "desktop");
298 desktop->setAutoUpdate(TRUE);
299 desktop->setReadOnly(TRUE);
300 desktop->setFont(f1);
305 ActiveConnections = 0;
306 strcpy(LockPasswd, "");
307 LoadConfig("vlp.cfg");
310 Net_Notify = new QSocketNotifier(net_sock, QSocketNotifier::Read, this);
311 connect(Net_Notify, SIGNAL(activated(int)), this, SLOT(NetMessage()));
315 * Event invoked on resizing kernel application window.
316 * @copydoc QWidget::resizeEvent(QResizeEvent*)
318 void QKernel::resizeEvent(QResizeEvent *ev)
320 QFrame::resizeEvent(ev);
322 desktop->setGeometry(0, bar->height(), width(),
323 height() - bar->height());
327 * Displays window with information about not implemented functionality.
329 void QKernel::n_impl()
331 QMessageBox::information(this, "Function info", "This function is not "
332 "implemented yet...", "Ok");
336 * Loads configuration from the given file.
337 * @param fname Filename of the configuration file.
339 void QKernel::LoadConfig(char * fname)
342 config_setting_t *setting;
345 /* Hack for checking if file exists without using external libs.*/
346 FILE * file = fopen(fname, "rt");
348 fprintf(stderr, "Error: Cannot load configuration file %s!\n",
352 /* File exists, so file has been locked. Release it. */
356 /* Read the file. If there is an error, report it and exit. */
357 if (!config_read(&cfg, file)) {
358 fprintf(stderr, "%s! In file %s, line %d\n",
359 config_error_text(&cfg),
360 config_error_file(&cfg),
361 config_error_line(&cfg));
362 config_destroy(&cfg);
364 exit(3);/* from original code. */
367 setting = config_lookup(&cfg, "node_number");
369 NodeNumber = config_setting_get_int(setting);
371 fprintf(stderr, "%s! In file %s, '%s' was not found.\n",
372 "Warning", fname, "node_number");
373 config_destroy(&cfg);
378 setting = config_lookup(&cfg, "type");
380 /* same as strcmp(..) == 0 */
381 if (!strcmp(config_setting_get_string(setting), "explicit")) {
387 fprintf(stderr, "%s! In file %s, '%s' was not found.\n",
388 "Warning", fname, "type");
391 setting = config_lookup(&cfg, "host");
393 switch(config_setting_type(setting)) {
394 /* TODO: Deprecated. Made for back compatibility. */
395 case CONFIG_TYPE_STRING:
396 ConnectList.append(new ConnectEntry((char*)
397 config_setting_get_string(setting)));
399 case CONFIG_TYPE_ARRAY: {
400 int size = config_setting_length(setting);
401 for (int i = 0; i < size; i++) {
402 ConnectList.append(new ConnectEntry((char*)
403 config_setting_get_string_elem(setting,
409 fprintf(stderr, "%s! In file %s, bad entry type for %s."
410 " Will not be read.\n",
411 "Error", fname, "host");
414 fprintf(stderr, "%s! In file %s, '%s' was not found.\n",
415 "Warning", fname, "host");
418 setting = config_lookup(&cfg, "progdir");
420 strncpy(progdir, config_setting_get_string(setting), 256);
422 fprintf(stderr, "%s! In file %s, '%s' was not found.\n",
423 "Warning", fname, "progdir");
426 setting = config_lookup(&cfg, "homedir");
428 strncpy(HomeDir, config_setting_get_string(setting), 255);
430 fprintf(stderr, "%s! In file %s, '%s' was not found.\n",
431 "Warning", fname, "homedir");
434 config_destroy(&cfg);
440 * Additional window id displayed to set which code to execute.
442 void QKernel::Run_Prog()
445 QString s(QFileDialog::getOpenFileName(progdir, "*.log", this));
453 RunIntModule((char*)s.ascii(), 0);
458 * Invokes editor program
463 sprintf(cmd, "%s/modules/logedit %s %s %s %s %s %s &", HomeDir, HomeDir,
464 myargs[0], myargs[1], myargs[2], myargs[3], myargs[4]);
469 * Invokes help program
474 sprintf(cmd, "%s/modules/loghelp %s/doc %s %s %s %s %s &", HomeDir,
475 HomeDir, myargs[0], myargs[1], myargs[2], myargs[3], myargs[4]);
480 * Invokes graphics module
482 void QKernel::RunGraphModule(char *sk)
486 sprintf(cmd, "%s/modules/loggraph %s %s %s %s %s %s", HomeDir, sk,
487 myargs[0], myargs[1], myargs[2], myargs[3], myargs[4]);
490 if (system(cmd) != 0)
491 WriteMessage("Cannot connect GRAPH resources");
497 void QKernel::RunNetModule()
499 struct sockaddr_un svr;
503 sprintf(cmd, "%s/modules/lognet %s %s %s %s %s %s", HomeDir, NPATH,
504 myargs[0], myargs[1], myargs[2], myargs[3], myargs[4]);
507 /* -------- socket for NET module -------- */
509 sock = socket(AF_UNIX, SOCK_STREAM, 0);
510 bzero(&svr, sizeof(svr));
511 svr.sun_family = AF_UNIX;
512 strcpy(svr.sun_path, NPATH);
513 len = strlen(svr.sun_path) + sizeof(svr.sun_family);
514 bind(sock, (struct sockaddr*)&svr, len);
517 if (system(cmd) == 0) {
518 net_sock = accept(sock, (struct sockaddr*)0, (unsigned int*)0);
521 WriteMessage("NETWORK successfully connected");
522 fcntl(net_sock, F_SETFL, O_NONBLOCK|fcntl(net_sock,
525 setsockopt(net_sock, IPPROTO_TCP, TCP_NODELAY,
526 (char*)&on, sizeof(on));
528 WriteMessage("Cannot connect NETWORK resources");
529 WriteMessage("Exiting...");
535 WriteMessage("Cannot connect NETWORK resources");
536 WriteMessage("Exiting...");
543 * Connects to the specified address
544 * Additional window is displayed to connect to the specified address
546 void QKernel::Connect()
549 QLabel lab("IP Address:", &d);
550 QLineEdit ed(&d, "");
555 d.setFont(QFont("Helvetica", 12, QFont::Bold));
556 ob.setGeometry(30, 60, 80, 30);
559 lab.setGeometry(10, 10, 60, 30);
560 lab.setText("Address");
561 ed.setGeometry(70, 10, 140, 30);
562 cb.setGeometry(130, 60, 80, 30);
563 cb.setText("Cancel");
566 connect(&ob, SIGNAL(clicked()), &d, SLOT(accept()));
567 connect(&cb, SIGNAL(clicked()), &d, SLOT(reject()));
569 m.msg_type = MSG_NET;
570 m.param.pword[0] = NET_CONNECT_TO;
571 strcpy(m.param.pstr, ed.text());
572 write(net_sock, &m, sizeof(MESSAGE));
577 * Disconnects from virtual machine
579 void QKernel::Disconnect()
584 WriteMessage("Disconnecting from virtual machine");
586 msg.msg_type = MSG_NET;
587 msg.param.pword[0] = NET_DISCONNECT;
588 write(net_sock, &msg, sizeof(MESSAGE));
592 * Quits process. Closes VLP. Shows additional window to confirm exit.
594 void QKernel::QuitProc()
598 if (QMessageBox::question(this, "Close VLP", "Terminate VLP ?",
599 QMessageBox::Yes, QMessageBox::No, 0) == QMessageBox::No) {
605 msg.msg_type = MSG_NET;
606 msg.param.pword[0] = NET_DISCONNECT;
607 write(net_sock, &msg, sizeof(MESSAGE));*/
610 msg.msg_type = MSG_NET;
611 msg.param.pword[0] = NET_EXIT;
612 write(net_sock, &msg, sizeof(MESSAGE));
613 /* ::close(net_sock);*/
619 * Adds IP address to the configuration.
620 * Additional window is displayed to add address to the list
622 void QKernel::AddAddress()
625 QLabel lab("IP Address:", &d);
626 QLineEdit ed(&d, "");
631 ob.setGeometry(30, 60, 80, 30);
634 lab.setGeometry(10, 10, 60, 30);
635 lab.setText("Address");
636 ed.setGeometry(70, 10, 140, 30);
637 cb.setGeometry(130, 60, 80, 30);
638 cb.setText("Cancel");
640 connect(&ob, SIGNAL(clicked()), &d, SLOT(accept()));
641 connect(&cb, SIGNAL(clicked()), &d, SLOT(reject()));
643 if (strcmp(ed.text(), "") != 0) {
644 connections->insertItem(ed.text());
650 * Deletes current address from available connections.
652 void QKernel::DelAddress()
655 if (connections->currentItem() != -1)
656 connections->removeItem(connections->currentItem());
661 * Sends message to node.
662 * Additional window is displayed to set Node Number of node where send message,
663 * and textfield to enter message.
665 void QKernel::MessageToNode()
671 dlg = new QDialog(this);
673 nodenr = new QLineEdit(dlg);
674 nodenr->setGeometry(90, 10, 50, 30);
678 tmpQLabel = new QLabel(dlg);
679 tmpQLabel->setGeometry(10, 10, 77, 30);
680 tmpQLabel->setText("Node number:");
682 tmpQLabel = new QLabel(dlg);
683 tmpQLabel->setGeometry(10, 50, 70, 30);
684 tmpQLabel->setText("Message:");
687 msg = new QLineEdit(dlg);
688 msg->setGeometry(80, 60, 330, 30);
692 ob = new QPushButton(dlg);
693 ob->setGeometry(230, 10, 80, 30);
695 ob->setDefault(TRUE);
698 cb = new QPushButton(dlg);
699 cb->setGeometry(330, 10, 80, 30);
700 cb->setText("Cancel");
701 dlg->resize(430, 110);
702 connect(ob, SIGNAL(clicked()), dlg, SLOT(accept()));
703 connect(cb, SIGNAL(clicked()), dlg, SLOT(reject()));
704 dlg->setCaption("Send message to node");
707 m.msg_type = MSG_NET;
708 m.param.pword[0] = NET_PROPAGATE;
709 m.param.pword[1] = MSG_VLP;
710 m.param.pword[2] = NodeNumber;
711 m.param.pword[4] = atoi(nodenr->text());
712 m.param.pword[6] = VLP_WRITE;
713 strcpy(m.param.pstr, msg->text());
714 write(net_sock, &m, sizeof(MESSAGE));
720 * Additional window is displayed to get ID of interpreter which should be
723 void QKernel::KillInterpreter()
730 dlg = new QDialog(this);
732 nodenr = new QLineEdit(dlg);
733 nodenr->setGeometry(90, 10, 50, 30);
737 tmpQLabel = new QLabel(dlg);
738 tmpQLabel->setGeometry(10, 10, 77, 30);
739 tmpQLabel->setText("Interp. ID:");
740 QPushButton* ob, *cb;
741 ob = new QPushButton(dlg);
742 ob->setGeometry( 160, 10, 80, 30);
744 ob->setDefault(TRUE);
745 cb = new QPushButton(dlg);
746 cb->setGeometry(260, 10, 80, 30);
747 cb->setText("Cancel");
748 dlg->resize(360, 50);
749 connect(ob, SIGNAL(clicked()), dlg, SLOT(accept()));
750 connect(cb, SIGNAL(clicked()), dlg, SLOT(reject()));
751 dlg->setCaption("Kill interpreter");
753 m.msg_type = MSG_INT;
754 m.param.pword[0] = INT_KILL;
755 pom = findINTbyID(atoi(nodenr->text()));
758 write(pom->sock, &m, sizeof(MESSAGE));
760 WriteMessage("This is a remote instance of "
764 WriteMessage("Interpreter not found");
770 * Sends message to the net module.
772 void QKernel::NetMessage()
775 /* TODO: It has to be rewritten */
781 cnt = read(net_sock, &msg, sizeof(MESSAGE));
782 if ((cnt > 0) && (msg.msg_type == MSG_NET)) {
783 switch(msg.param.pword[0]) {
785 WriteMessage(msg.param.pstr);
788 switch(msg.param.pword[1]) {
790 /* pom = find_link_by_ID(msg.param.pword[5]);
791 msg.msg_type = MSG_NET;
792 msg.param.pword[0] = NET_PROPAGATE;
793 send_int(pom, &msg);*/
796 switch(msg.param.pword[6]) {
798 QApplication::beep();
799 WriteMessage(CharLine);
801 "### Incoming Messsage ###");
802 sprintf(ss, "Mesg from Node %d: %s",
806 WriteMessage(CharLine);
808 case VLP_REMOTE_INSTANCE:
809 sprintf(ss, "%s/%s", REMOTE_PATH,
813 WriteMessage("Running program:");
816 pom = RunIntModule(ss, 1);
818 pom->p_ctx.node = msg.param.pword[2];
819 pom->p_ctx.program_id =
821 pom->RInstances[msg.param.pword[2]] = msg.param.pword[7];
824 case VLP_CLOSE_INSTANCE:
825 msg.msg_type = MSG_INT;
826 msg.param.pword[0] = INT_CLOSE_INSTANCE;
827 pom = findINTbyID(msg.param.pword[7]);
829 write(pom->sock, &msg,
832 m1.msg_type = MSG_VLP;
833 m1.param.pword[0] = VLP_INTERPRETER_DOWN;
834 m1.param.pword[1] = pom->ID;
838 WriteMessage("Instance not found");
844 case NET_CONNECTIONS:
845 ActiveConnections = msg.param.pword[1];
846 WriteMessage(msg.param.pstr);
851 /* TODO: It has to be rewritten */
853 QString poms, poms1, poms2;
854 poms.sprintf("%s", msg.param.pstr);
855 while (poms.length() > 0) {
856 cnt = poms.find(';');
858 poms1 = poms.left(cnt);
859 poms = poms.right(poms.length() - cnt - 1);
860 cnt = poms1.find('=');
862 poms2 = poms1.left(cnt);
866 sprintf(ss, "Node: %s Addr: %s", poms2.data(), poms1.data());
874 wait_for_info = FALSE;
875 WriteMessage(CharLine);
882 * Sends message to the interpreter program.
883 * @param sock Interpreter socket to whom the message will be send.
885 void QKernel::IntMessage(int sock)
891 cnt = read(sock, &msg, sizeof(MESSAGE));
892 e = findINTbySocket(sock);
893 if ((cnt > 0) && (e != NULL)) {
894 switch (msg.msg_type) {
896 if (msg.param.pword[0] == GRAPH_ALLOCATE) {
897 RunGraphModule(msg.param.pstr);
901 write(net_sock, &msg, sizeof(MESSAGE));
904 switch(msg.param.pword[0]) {
905 case VLP_REMOTE_INSTANCE_PLEASE:
906 RemoteInstance(e, msg.param.pword[2]);
911 switch(msg.param.pword[0]) {
916 m.msg_type = MSG_VLP;
917 m.param.pword[0] = VLP_INTERPRETER_DOWN;
918 m.param.pword[1] = e->ID;
919 write(net_sock, &m, sizeof(MESSAGE));
924 Interpreters.remove(e);
928 sprintf(ss, "%s : End of program "
929 "execution", msg.param.pstr);
934 msg.msg_type = MSG_INT;
935 msg.param.pword[0] = INT_CTX;
936 msg.param.pword[1] = NodeNumber;
937 msg.param.pword[2] = e->ID;
939 msg.param.pword[3] = e->p_ctx.node;
943 write(sock, &msg, sizeof(MESSAGE));
952 * Writes message to kernel logger.
953 * @parame msg String with message to log
955 void QKernel::WriteMessage(char *msg)
960 desktop->getCursorPosition(&x, &y);
965 desktop->setReadOnly(FALSE);
966 desktop->append(msg);
967 desktop->setReadOnly(TRUE);
968 desktop->setCursorPosition(desktop->numLines(), 1);
971 if (desktop->numLines() > 100) {
977 * Adds checkbox to menu item. It it is checked additional info messages are
980 void QKernel::SetMessages()
983 if (p2->isItemChecked(msgid)) {
984 p2->setItemChecked(msgid, FALSE);
987 p2->setItemChecked(msgid, TRUE);
991 /* bar->repaint(); */
995 * Allows to set options in GUI window.
996 * Additional window is displayed to set kernel options which are saved in
997 * vlp.cfg file in kernel executable directory.
999 void QKernel::SetOptions()
1006 progs = new QLineEdit(&dlg, "progs");
1007 progs->setGeometry(150, 20, 180, 30);
1008 progs->setText(progdir);
1011 tmpQLabel = new QLabel(&dlg);
1012 tmpQLabel->setGeometry(30, 20, 120, 30);
1013 tmpQLabel->setText("Programs directory");
1016 tmpQFrame = new QFrame(&dlg);
1017 tmpQFrame->setGeometry(10, 60, 380, 30);
1018 tmpQFrame->setFrameStyle(52);
1020 tmpQLabel = new QLabel(&dlg);
1021 tmpQLabel->setGeometry(10, 80, 340, 30);
1022 tmpQLabel->setText("Virtual Processor properties (activated after "
1023 "restarting VLP):");
1027 nn = new QLineEdit(&dlg, "LineEdit_2");
1028 nn->setGeometry(110, 110, 40, 30);
1029 sprintf(nns, "%d", NodeNumber);
1032 tmpQLabel = new QLabel(&dlg);
1033 tmpQLabel->setGeometry(20, 110, 90, 30);
1034 tmpQLabel->setText("Node number:");
1036 QRadioButton *exp, *reg;
1037 exp = new QRadioButton(&dlg);
1038 exp->setGeometry(30, 170, 100, 30);
1039 exp->setText("Explicit");
1040 exp->setChecked(TRUE);
1042 reg = new QRadioButton(&dlg);
1043 reg->setGeometry(30, 200, 100, 30);
1044 reg->setText("Registration");
1045 reg->setEnabled(FALSE);
1047 connections = new Q3ListBox(&dlg);
1048 connections->setGeometry(170, 140, 130, 100);
1049 e = ConnectList.first();
1051 connections->insertItem(e->addr);
1052 e = ConnectList.takeFirst();
1055 tmpQLabel = new QLabel(&dlg);
1056 tmpQLabel->setGeometry(170, 110, 100, 30);
1057 tmpQLabel->setText("Connection list:");
1059 QPushButton *addbtn;
1060 QPushButton *delbtn;
1062 QPushButton *cancelbtn;
1063 addbtn = new QPushButton(&dlg);
1064 addbtn->setGeometry(310, 150, 60, 30);
1065 addbtn->setText("Add");
1066 delbtn = new QPushButton(&dlg);
1067 delbtn->setGeometry(310, 200, 60, 30);
1068 delbtn->setText("Del");
1069 connect(addbtn, SIGNAL(clicked()), this, SLOT(AddAddress()));
1070 connect(delbtn, SIGNAL(clicked()), this, SLOT(DelAddress()));
1071 okbtn = new QPushButton(&dlg);
1072 okbtn->setGeometry(80, 260, 100, 30);
1073 okbtn->setText("Ok");
1074 okbtn->setDefault(TRUE);
1075 cancelbtn = new QPushButton(&dlg);
1076 cancelbtn->setGeometry(210, 260, 100, 30);
1077 cancelbtn->setText("Cancel");
1078 connect(okbtn, SIGNAL(clicked()), &dlg, SLOT(accept()));
1079 connect(cancelbtn, SIGNAL(clicked()), &dlg, SLOT(reject()));
1080 QButtonGroup* group;
1081 group = new QButtonGroup(&dlg);
1082 group->setGeometry(20, 150, 120, 90);
1083 group->setTitle("Connection type");
1084 group->setAlignment(1);
1086 group->insert(exp, 1);
1087 group->insert(reg, 2);
1089 dlg.resize(400, 310);
1092 config_setting_t *root;
1093 config_setting_t *setting;
1096 root = config_root_setting(&cfg);
1098 setting = config_setting_add(root, "progdir",
1099 CONFIG_TYPE_STRING);
1100 config_setting_set_string(setting, progs->text().ascii());
1101 strcpy(progdir, progs->text());
1103 setting = config_setting_add(root, "node_number",
1105 config_setting_set_int(setting, atoi(nn->text()));
1107 setting = config_setting_add(root, "homedir",
1108 CONFIG_TYPE_STRING);
1109 config_setting_set_string(setting, HomeDir);
1111 setting = config_setting_add(root, "type",
1112 CONFIG_TYPE_STRING);
1113 if (exp->isChecked()) {
1114 config_setting_set_string(setting, "explicit");
1116 config_setting_t *hosts = NULL;
1117 hosts = config_setting_add(root, "host",
1119 for(i = 0; i < connections->count(); i++) {
1120 setting = config_setting_add(hosts, NULL,
1121 CONFIG_TYPE_STRING);
1122 config_setting_set_string(setting,
1123 connections->text(i).ascii());
1126 config_setting_set_string(setting, "register");
1129 if (!config_write_file(&cfg, "vlp.cfg")) {
1130 fprintf(stderr, "Error while writing to file: %s.\n",
1133 config_destroy(&cfg);
1138 * Locks kernel program.
1139 * Additional window is displayed to enter password and retype it. If both are
1140 * same kernel window is locked.
1142 void QKernel::LockConsole()
1145 QLabel lab("Password", &d);
1146 QLineEdit ed(&d, "");
1150 d.setCaption("Lock console");
1151 ob.setGeometry(30, 60, 80, 30);
1153 ob.setDefault(TRUE);
1154 lab.setGeometry(10, 10, 60, 30);
1155 lab.setText("Password:");
1156 ed.setGeometry(70, 10, 140, 30);
1157 ed.setEchoMode(QLineEdit::Password);
1158 cb.setGeometry(130, 60, 80, 30);
1159 cb.setText("Cancel");
1161 connect(&ob, SIGNAL(clicked()), &d, SLOT(accept()));
1162 connect(&cb, SIGNAL(clicked()), &d, SLOT(reject()));
1165 if (strcmp(ed.text(), "") != 0) {
1166 strcpy(LockPasswd, ed.text());
1167 lab.setText("Retype:");
1170 if (strcmp(ed.text(), LockPasswd)==0) {
1171 // bar->setItemEnabled(qid, FALSE);
1172 // bar->setItemEnabled(prid, FALSE);
1173 // bar->setItemEnabled(mid, FALSE);
1174 // p2->setItemEnabled(unlockid, TRUE);
1175 // p2->setItemEnabled(lockid, FALSE);
1176 // p2->setItemEnabled(cwid, FALSE);
1177 // p2->setItemEnabled(optid, FALSE);
1179 WriteMessage("CONSOLE LOCKED");
1182 QMessageBox msg(this);
1183 msg.setText("Not matching!");
1184 msg.setButtonText(0, "Close");
1188 strcpy(LockPasswd, "");
1195 * Unlocks kernel program.
1196 * Additional window is displayed to enter password. If it is correct, kernel
1197 * window is unlocked
1199 void QKernel::UnlockConsole()
1202 QLabel lab("Password", &d);
1203 QLineEdit ed(&d, "");
1207 ob.setGeometry(30, 60, 80, 30);
1209 ob.setDefault(TRUE);
1210 lab.setGeometry(10, 10, 60, 30);
1211 lab.setText("Password:");
1212 ed.setGeometry(70, 10, 140, 30);
1213 ed.setEchoMode(QLineEdit::Password);
1214 cb.setGeometry(130, 60, 80, 30);
1215 cb.setText("Cancel");
1217 connect(&ob, SIGNAL(clicked()), &d, SLOT(accept()));
1218 connect(&cb, SIGNAL(clicked()), &d, SLOT(reject()));
1221 if (strcmp(ed.text(), LockPasswd) == 0) {
1222 // bar->setItemEnabled(qid, TRUE);
1223 // bar->setItemEnabled(prid, TRUE);
1224 // bar->setItemEnabled(mid, TRUE);
1225 // p2->setItemEnabled(unlockid, FALSE);
1226 // p2->setItemEnabled(lockid, TRUE);
1227 // p2->setItemEnabled(cwid, TRUE);
1228 // p2->setItemEnabled(optid, TRUE);
1230 WriteMessage("CONSOLE UNLOCKED");
1233 QMessageBox msg(this);
1234 msg.setText("Wrong password!");
1235 msg.setButtonText(0, "Close");
1242 * Writes init message in kernel
1244 void QKernel::InitMessage()
1246 WriteMessage("\n Virtual LOGLAN Processor - ver 1.9: READY \n");
1250 * Finds Interpreter by its socket
1251 * @param _id ID of the socket
1252 * @return returns pointer to the found interpreter slot
1254 InterpEntry *QKernel::findINTbySocket(int _id)
1257 pom = Interpreters.first();
1259 while (pom != NULL) {
1260 if (pom->sock == _id)
1263 pom = Interpreters.takeFirst();
1269 * Finds Interpreter by its ID.
1270 * @param _id ID of the interpreter
1271 * @return returns pointer to the found interpreter slot
1273 InterpEntry *QKernel::findINTbyID(int _id)
1276 pom = Interpreters.first();
1277 while (pom != NULL) {
1280 pom = Interpreters.takeFirst();
1287 * Connects interpreter
1288 * @param ss full filepath with filename but without extension of the loglan
1290 * @param r Interpreter execution mode. 0 if it will be local instance, 1 if
1292 * @return Returns pointer to newly created interpreter slot, or NULL on error.
1294 InterpEntry *QKernel::RunIntModule(char *ss, int r)
1296 char a[256], b[255];
1297 struct sockaddr_un svr;
1298 int len, sock, i, on;
1303 InterpEntry *newINT = NULL;
1309 WriteMessage("File not found: no .ccd file");
1318 WriteMessage("File not found: no .pcd file");
1323 newINT = new InterpEntry;
1324 for(i = 0; i < MAXINSTANCES; i++)
1325 newINT->RInstances[i] =- 1;
1327 strcpy(b, rindex(ss, '/'));
1328 for(i = 0; i < strlen(b); i++)
1330 if (info_messages) {
1331 sprintf(a, "%s : Start execution", b);
1337 newINT->ID = newint;
1338 strcpy(newINT->shortname, b);
1339 strcpy(newINT->fullname, ss);
1341 sprintf(a, "%s%d", IPATH, newint);
1342 sprintf(cmd, "%s/modules/logint %s %s", HomeDir, a, ss);
1345 sprintf(b, " %s %s %s %s %s", myargs[0], myargs[1], myargs[2],
1346 myargs[3], myargs[4]);
1350 sock = socket(AF_UNIX, SOCK_STREAM, 0);
1352 bzero(&svr, sizeof(svr));
1353 svr.sun_family = AF_UNIX;
1354 strcpy(svr.sun_path, a);
1355 len = strlen(svr.sun_path)+sizeof(svr.sun_family);
1356 bind(sock, (struct sockaddr*)&svr, len);
1359 newINT->sock = accept(sock, (struct sockaddr*)0, (unsigned int *)0);
1362 if (newINT->sock > 0) {
1363 fcntl(newINT->sock, F_SETFL,
1364 O_NONBLOCK|fcntl(newINT->sock, F_GETFL, 0));
1366 setsockopt(newINT->sock, IPPROTO_TCP, TCP_NODELAY, (char*)&on,
1373 bzero(&msg, sizeof(MESSAGE));
1374 msg.msg_type = MSG_VLP;
1375 msg.param.pword[0] = VLP_REGINT;
1376 msg.param.pword[1] = newINT->ID;
1377 sprintf(msg.param.pstr, "logi%d.net", newint);
1378 write(net_sock, &msg, sizeof(MESSAGE));
1380 Interpreters.append(newINT);
1381 newINT->notify = new QSocketNotifier(newINT->sock,
1382 QSocketNotifier::Read);
1383 connect(newINT->notify, SIGNAL(activated(int)), this,
1384 SLOT(IntMessage(int)));
1386 WriteMessage("INTERPRETER successfully connected");
1388 WriteMessage("Cannot connect interpreter");
1395 * Allocates remote instance of interpreter
1396 * @param interp Interpreter slot
1397 * @param on Node Number
1399 void QKernel::RemoteInstance(InterpEntry *interp, int on)
1404 m.msg_type = MSG_NET;
1405 m.param.pword[0] = NET_NODE_EXIST;
1406 m.param.pword[1] = on;
1407 m.param.pword[2] = interp->ID;
1408 write(net_sock, &m, sizeof(MESSAGE));
1409 bzero(&m, sizeof(MESSAGE));
1410 while((m.msg_type!=MSG_NET) && (m.param.pword[0]!=NET_NODE_EXIST))
1411 read(net_sock, &m, sizeof(MESSAGE));
1413 /* means node exists */
1414 if (m.param.pword[1] == 1) {
1415 m.msg_type = MSG_NET;
1416 m.param.pword[0] = NET_TRANSMIT_CODE;
1417 m.param.pword[1] = interp->ID;
1418 m.param.pword[2] = on;
1419 strcpy(m.param.pstr, interp->fullname);
1420 write(net_sock, &m, sizeof(MESSAGE));
1422 Net_Notify->setEnabled(FALSE);
1423 while ((m.msg_type != MSG_NET) ||
1424 (m.param.pword[0] != NET_TRANSMITTED))
1425 read(net_sock, &m, sizeof(MESSAGE));
1427 m.msg_type = MSG_NET;
1428 m.param.pword[0] = NET_PROPAGATE;
1429 m.param.pword[1] = MSG_VLP;
1430 m.param.pword[2] = NodeNumber;
1431 m.param.pword[3] = 0;
1432 m.param.pword[4] = on;
1433 m.param.pword[5] = 0;
1434 m.param.pword[6] = VLP_REMOTE_INSTANCE;
1435 m.param.pword[7] = interp->ID;
1436 strcpy(m.param.pstr, interp->shortname);
1437 write(net_sock, &m, sizeof(MESSAGE));
1439 read(net_sock, &m, sizeof(MESSAGE));
1441 if ((m.param.pword[0] == NET_PROPAGATE) &&
1442 (m.param.pword[6] == VLP_REMOTE_INSTANCE_OK)) {
1443 interp->RInstances[on] = m.param.pword[7];
1446 read(net_sock, &m, sizeof(MESSAGE));
1449 Net_Notify->setEnabled(TRUE);
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->RInstances[on];
1455 write(interp->sock, &m, sizeof(MESSAGE));
1456 } else { /* There is no such a node! */
1457 sprintf(s, "Warning: Node number %d not found!", on);
1459 WriteMessage("Allocating O-process on the local node");
1460 bzero(&m, sizeof(MESSAGE));
1461 m.msg_type = MSG_VLP;
1462 m.param.pword[0] = VLP_REMOTE_INSTANCE_HERE;
1463 m.param.pword[1] = interp->ID;
1464 write(interp->sock, &m, sizeof(MESSAGE));
1469 * Closes all remote instances
1471 void QKernel::CloseInstances(InterpEntry *e)
1477 WriteMessage("Closing remote instances");
1479 for(i=0; i < MAXINSTANCES; i++)
1480 if (e->RInstances[i]>=0) {
1481 msg.msg_type = MSG_NET;
1482 msg.param.pword[0] = NET_PROPAGATE;
1483 msg.param.pword[1] = MSG_VLP;
1484 msg.param.pword[2] = NodeNumber;
1485 msg.param.pword[4] = i;
1486 msg.param.pword[6] = VLP_CLOSE_INSTANCE;
1487 msg.param.pword[7] = e->RInstances[i];
1488 write(net_sock, &msg, sizeof(MESSAGE));
1493 * Displays information about virtual machine
1495 void QKernel::Info()
1499 WriteMessage(CharLine);
1500 WriteMessage("### Virtual Machine Information ###");
1501 m.msg_type = MSG_NET;
1502 m.param.pword[0] = NET_GET_INFO;
1503 write(net_sock, &m, sizeof(MESSAGE));
1504 wait_for_info = TRUE;
1507 #include "kernel.moc"
1510 * Program main function
1511 * All program arguments but the first one (argv[0]: program name) are saved and
1512 * passed to all dependent programs on their invocation.
1513 * @param argc Number of program arguments
1514 * @param argv Program arguments
1516 int main(int argc, char **argv)
1519 for(i = 0; i < 5; i++) {
1520 strcpy(myargs[i], "");
1522 for(i = 1; i < argc; i++) {
1523 strcpy(myargs[i - 1], argv[i]);
1526 app = new QApplication(argc, argv);
1527 app->setStyle(new QWindowsStyle());
1529 app->setMainWidget(&kernel);
1531 kernel.InitMessage();