Fixed all indents. Made spaces in conditionals. Tried to limit line with to 80 charac...
[vlp.git] / src / kernel / kernel.cpp
1 /**************************************************************
2
3   Copyright (C) 1997  Oskar Swida
4
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.
9
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.
14
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.
18
19
20
21
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.
25
26  
27   To contact the author, write:
28      e-mail: swida@aragorn.pb.bialystok.pl
29
30 ************************************************************/
31
32
33 #include <qpixmap.h>
34 //#include <qwindow.h>
35 #include <qapp.h>
36 #include <qframe.h>
37 #include <qmlined.h>
38 #include <qpainter.h>
39 #include <qcolor.h>
40 #include <qbrush.h>
41 #include <qmenubar.h>
42 #include <qpopmenu.h>
43 #include <qfont.h>
44 #include <qmsgbox.h>
45 #include <qfiledlg.h>
46 #include <qtabdlg.h>
47 #include <qstring.h>
48 #include <qrect.h>
49 #include <qdialog.h>
50 #include <qbttngrp.h>
51 #include <qlabel.h>
52 #include <qlined.h>
53 #include <qlistbox.h>
54 #include <qpushbt.h>
55 #include <qradiobt.h>
56 #include <qlist.h>
57 #include <qfile.h>
58 #include <qcursor.h>
59 #include <qcombo.h>
60 #include <qsocknot.h>
61 #include <qdir.h>
62 #include <qwindowsstyle.h>
63
64 #include <stdio.h>
65 #include <stdlib.h>
66 #include <unistd.h>
67 #include <fcntl.h>
68
69 #include "genint1.h"
70 #include "comm.h"
71 #include "socu.h"
72 #include <netinet/in.h>
73
74 #include <libconfig.h>
75
76 #define GPATH "loggr"
77 #define IPATH "logi"
78 #define NPATH "logn"
79 #define REMOTE_PATH "REMOTE"
80 #define MAXINTERP 20
81 #define MAXINSTANCES 256 
82
83
84 #define MESG_COL        0
85 #define WARN_COL        1
86 #define NORM_COL        2
87
88
89 char CharLine[25] = "________________________";
90 char myargs[5][255];
91
92
93 /* --------------- interpreter slot -----------------*/
94 class InterpEntry {
95 public:
96         /* INT identifier */
97         int ID;
98         /* Am I remote ? */
99         bool remote;
100         /* Program name */
101         char fullname[255];
102         char shortname[255];
103         
104         /* Socket */
105         int sock;
106         QSocketNotifier *notify;
107         /* IDs of my remote INT modules */
108         int RInstances[MAXINSTANCES];
109         /* parent INT info */
110         ctx_struct p_ctx;
111 };
112 /*++++++++++++++++++++++++++++++++++++++++++*/
113
114 /*----------------- connection slot -------------*/
115 class ConnectEntry {
116 public:
117         char addr[256];
118         
119         ConnectEntry(char *s) {
120                 strcpy(addr, s);
121         };
122 };
123
124 /* ++++++++++++++++++++++++++++++++++++++++++  */
125
126 QApplication *app;
127
128
129 /* ---------------------------------------------------------- */
130 /*                 KERNEL CLASS DEFINITION                    */
131 /* ---------------------------------------------------------- */
132
133 class QKernel : public QFrame {
134         Q_OBJECT
135 public:
136         QMultiLineEdit *desktop;                        
137         QMenuBar *bar;  
138         QPopupMenu *p;
139         QPopupMenu *p1;
140         QPopupMenu *p2;
141         char progdir[256];                              
142         int NodeNumber;
143         int ConType;
144
145         QKernel();
146
147         virtual void resizeEvent(QResizeEvent *ev);
148
149         void WriteMessage(char* msg);
150         void InitMessage();
151
152 public slots:
153         void n_impl();
154         void Run_Prog();
155         void Edit();
156         void Help();
157         void SetOptions();
158         void AddAddress();
159         void DelAddress();
160         void LockConsole();
161         void UnlockConsole();
162         void MessageToNode();
163         void QuitProc();
164         void NetMessage();
165         void IntMessage(int);
166         void KillInterpreter();
167         void Disconnect();
168         void SetMessages();
169         void Connect();
170         void Info();
171
172 protected:
173         virtual void closeEvent (QCloseEvent * e);
174
175 private:
176         QList<InterpEntry> Interpreters;         
177         QList<ConnectEntry> ConnectList;
178         QListBox *connections;
179         
180         /**
181          * number of working interpreters
182          */
183         int Tasks;
184         
185         /**
186          * number of connected VLPs
187          */
188         int ActiveConnections;
189         bool LOCKED;
190         bool synchro;
191         bool wait_for_info;
192         char LockPasswd[25];
193         int lockid
194         int unlockid
195         int qid;
196         int cwid;
197         int optid;
198         int prid;
199         int mid;
200         int msgid;
201         int toolsid;
202         int hid;
203         
204         int net_sock;
205         int freeINTid;
206         QSocketNotifier *Net_Notify;
207         char HomeDir[255];
208         bool info_messages;
209
210         void LoadConfig(char *);
211         void RunGraphModule(char*);
212         void RunNetModule();
213         InterpEntry *findINTbySocket(int);
214         InterpEntry *findINTbyID(int);
215         InterpEntry *RunIntModule(char *ss, int r);
216         void RemoteInstance(InterpEntry*, int);
217         void CloseInstances(InterpEntry*);
218 };
219 /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
220
221 void QKernel::closeEvent (QCloseEvent * e)
222 {
223         e->ignore();
224 }
225
226 QKernel::QKernel()
227 {
228         QFont f("Helvetica", 10, QFont::Bold);
229         QFont f1("Helvetica", 10, QFont::Normal);
230         QFont f2("Times Roman", 10, QFont::Normal);
231         QDir q(REMOTE_PATH);
232         char ss[255];
233
234         if (!q.exists()) {
235                 sprintf(ss, "mkdir %s", REMOTE_PATH);
236                 system(ss);
237         } 
238
239         info_messages = TRUE;
240         wait_for_info = FALSE;
241
242         setCaption("Virtual LOGLAN Processor");
243         setBackgroundColor(white);
244
245         bar = new QMenuBar(this);
246         bar->setFont(f); 
247         p = new QPopupMenu();
248         p->setFont(f2);
249         p->insertItem("Execute", this, SLOT(Run_Prog()));
250         p->insertItem("Kill", this, SLOT(KillInterpreter()));
251         prid = bar->insertItem("&Program", p);
252         p1 = new QPopupMenu();
253         p1->insertItem("Message", this, SLOT(MessageToNode()));
254         p1->insertSeparator();
255         p1->insertItem("Connect", this, SLOT(Connect()));
256         p1->insertItem("Disconnect", this, SLOT(Disconnect()));
257         p1->insertItem("Info", this, SLOT(Info()));
258         p1->setFont(f);
259         mid = bar->insertItem("&Machine", p1);
260
261         p2 = new QPopupMenu();
262         cwid = p2->insertItem("Editor", this, SLOT(Edit()));
263         hid = p2->insertItem("Help", this, SLOT(Help()));
264         p2->insertSeparator(); 
265         optid = p2->insertItem("Options", this, SLOT(SetOptions()));
266         msgid = p2->insertItem("Info messages", this, SLOT(SetMessages()));
267         p2->setItemChecked(msgid, TRUE);
268         p2->insertSeparator(); 
269         lockid = p2->insertItem("Lock console", this, SLOT(LockConsole()));
270         unlockid = p2->insertItem("Unlock console", this, 
271                                                         SLOT(UnlockConsole()));
272         p2->setItemEnabled(unlockid, FALSE);
273         LOCKED = FALSE;
274         p2->setFont(f);
275         toolsid = bar->insertItem("&Tools", p2);
276
277         qid = bar->insertItem("&Quit", this, SLOT(QuitProc()));
278         p->setFont(f);
279
280         desktop = new QMultiLineEdit(this, "desktop");
281         desktop->setAutoUpdate(TRUE);
282         desktop->setReadOnly(TRUE);
283         desktop->setFont(f1);
284
285         resize(400, 200);
286         Tasks = 0;
287         freeINTid = 1;
288         ActiveConnections = 0;
289         strcpy(LockPasswd, "");
290         LoadConfig("vlp.cfg");
291         RunNetModule();
292
293         Net_Notify = new QSocketNotifier(net_sock, QSocketNotifier::Read, this);
294         connect(Net_Notify, SIGNAL(activated(int)), this, SLOT(NetMessage()));
295 }
296
297 void QKernel::resizeEvent(QResizeEvent *ev)
298 {
299         QFrame::resizeEvent(ev);
300         if (desktop)
301                 desktop->setGeometry(0, bar->height(), width(), 
302                                                 height() - bar->height());
303 }
304
305 void QKernel::n_impl()
306 {
307         QMessageBox::information(this, "Function info", "This function is not "
308                                                 "implemented yet...", "Ok");
309 }
310
311
312 /* ###########     load configuration from file  ############# */
313
314 void QKernel::LoadConfig(char * fname)
315 {
316         config_t cfg;
317         config_setting_t *setting;
318         const char *str;
319
320         /* Hack for checking if file exists without using external libs.*/
321         FILE * file = fopen(fname, "rt");
322         if (!file) {
323                 fprintf(stderr, "Error: Cannot load configuration file %s!\n", 
324                                                                         fname);
325                 exit(3);
326         }
327         /* File exists, so file has been locked. Release it. */
328
329         config_init(&cfg);
330
331         /* Read the file. If there is an error, report it and exit. */
332         if (!config_read(&cfg, file)) {
333                 fprintf(stderr, "%s! In file %s, line %d\n", 
334                         config_error_text(&cfg), 
335                         config_error_file(&cfg), 
336                         config_error_line(&cfg));
337                 config_destroy(&cfg);
338                 fclose(file);
339                 exit(3);/* from original code. */
340         }
341
342         setting = config_lookup(&cfg, "node_number");
343         if (setting) {
344                 NodeNumber = config_setting_get_int(setting);
345         } else {
346                 fprintf(stderr, "%s! In file %s, '%s' was not found.\n", 
347                                         "Warning", fname, "node_number");
348                 config_destroy(&cfg);
349                 fclose(file);
350                 exit(3);
351         }
352
353         setting = config_lookup(&cfg, "type");
354         if (setting) {
355                 /* same as strcmp(..) == 0 */
356                 if (!strcmp(config_setting_get_string(setting), "explicit")) {
357                         ConType = 1;
358                 } else {
359                         ConType = 2;
360                 }
361         } else {
362                 fprintf(stderr, "%s! In file %s, '%s' was not found.\n", 
363                                                 "Warning", fname, "type");
364         }
365
366         setting = config_lookup(&cfg, "host");
367         if (setting) {
368                 switch(config_setting_type(setting)) {
369                 /* TODO: Deprecated. Made for back compatibility. */
370                 case CONFIG_TYPE_STRING:
371                         ConnectList.append(new ConnectEntry((char*)
372                                         config_setting_get_string(setting)));
373                         break;
374                 case CONFIG_TYPE_ARRAY:
375                         int length = config_setting_length(setting);
376                         for (int i = 0; i < length; i++) {
377                                 ConnectList.append(new ConnectEntry((char*)
378                                         config_setting_get_string_elem(setting,
379                                                                         i)));
380                         }
381                         break;
382                 default:
383                         fprintf(stderr, "%s! In file %s, bad entry type for %s."
384                                                         " Will not be read.\n", 
385                                                         "Error", fname, "host");
386                 }
387         } else {
388                 fprintf(stderr, "%s! In file %s, '%s' was not found.\n", 
389                                                 "Warning", fname, "host");
390         }
391
392         setting = config_lookup(&cfg, "progdir");
393         if (setting){
394                 strncpy(progdir, config_setting_get_string(setting), 256);
395         } else {
396                 fprintf(stderr, "%s! In file %s, '%s' was not found.\n", 
397                                                 "Warning", fname, "progdir");
398         }
399
400         setting = config_lookup(&cfg, "homedir");
401         if (setting) {
402                 strncpy(HomeDir, config_setting_get_string(setting), 255);
403         } else {
404                 fprintf(stderr, "%s! In file %s, '%s' was not found.\n", 
405                                                 "Warning", fname, "homedir");
406         }
407
408         config_destroy(&cfg);
409         fclose(file);
410 }
411 /* +++++++++++++++++++++++++++++++++++++++++++++++ */
412
413 void QKernel::Run_Prog()
414 {
415         int i;
416         QString s(QFileDialog::getOpenFileName(progdir, "*.log", this));
417         
418         if (!s.isNull()) {
419                 i = s.find(".log");
420                 
421                 if (i > 0)
422                         s.remove(i, 4);
423                         
424                 RunIntModule((char*)s.ascii(), 0);
425         }
426 }
427
428 void QKernel::Edit()
429 {
430         char cmd[255];
431         sprintf(cmd, "%s/modules/logedit %s %s %s %s %s %s &", HomeDir, HomeDir, 
432                         myargs[0], myargs[1], myargs[2], myargs[3], myargs[4]);
433         system(cmd);
434 }
435
436 void QKernel::Help()
437 {
438         char cmd[255];
439         sprintf(cmd, "%s/modules/loghelp %s/doc %s %s %s %s %s &", HomeDir, 
440                 HomeDir, myargs[0], myargs[1], myargs[2], myargs[3], myargs[4]);
441         system(cmd);
442 }
443
444
445 void QKernel::RunGraphModule(char *sk)
446 {
447         char cmd[255];
448
449         sprintf(cmd, "%s/modules/loggraph %s %s %s %s %s %s", HomeDir, sk, 
450                         myargs[0], myargs[1], myargs[2], myargs[3], myargs[4]);
451         strcat(cmd, " &");
452
453         if (system(cmd) != 0)
454                 WriteMessage("Cannot connect GRAPH resources");
455 }
456
457
458
459 void QKernel::RunNetModule()
460 {
461         struct sockaddr_un svr;
462         int len, on;
463         int sock;
464         char cmd[255];
465         sprintf(cmd, "%s/modules/lognet %s %s %s %s %s %s", HomeDir, NPATH, 
466                         myargs[0], myargs[1], myargs[2], myargs[3], myargs[4]);
467         strcat(cmd, " &");
468
469         /* -------- socket for NET module -------- */
470         unlink(NPATH);
471         sock = socket(AF_UNIX, SOCK_STREAM, 0);
472         bzero(&svr, sizeof(svr));
473         svr.sun_family = AF_UNIX;
474         strcpy(svr.sun_path, NPATH);
475         len = strlen(svr.sun_path) + sizeof(svr.sun_family);
476         bind(sock, (struct sockaddr*)&svr, len);      
477         listen(sock, 5);
478
479         if (system(cmd) == 0) {
480                 net_sock = accept(sock, (struct sockaddr*)0, (unsigned int*)0);
481                 // close(sock); 
482                 if (net_sock != 0) {
483                         WriteMessage("NETWORK successfully connected");
484                         fcntl(net_sock, F_SETFL, O_NONBLOCK|fcntl(net_sock,
485                                                                 F_GETFL, 0));
486                         on=1;
487                         setsockopt(net_sock, IPPROTO_TCP, TCP_NODELAY,
488                                                         (char*)&on, sizeof(on)); 
489                 } else {
490                         WriteMessage("Cannot connect NETWORK resources");
491                         WriteMessage("Exiting...");
492                         sleep(2);
493                         QuitProc(); 
494                 }
495         /* system OK */
496         } else {
497                 WriteMessage("Cannot connect NETWORK resources");
498                 WriteMessage("Exiting...");
499                 sleep(2);
500                 QuitProc(); 
501         }
502 }
503
504 void QKernel::Connect()
505 {
506         QDialog d(this, "", TRUE);
507         QLabel lab(&d, "IP Address:");
508         QLineEdit ed(&d, "");
509         QPushButton ob(&d, "");
510         QPushButton cb(&d, "");
511         MESSAGE m;
512
513         d.setFont(QFont("Helvetica", 12, QFont::Bold)); 
514         ob.setGeometry(30, 60, 80, 30);
515         ob.setText("Ok");
516         ob.setDefault(TRUE);
517         lab.setGeometry(10, 10, 60, 30);
518         lab.setText("Address");
519         ed.setGeometry(70, 10, 140, 30);
520         cb.setGeometry(130, 60, 80, 30);
521         cb.setText("Cancel");
522         d.resize(240, 100);
523
524         connect(&ob, SIGNAL(clicked()), &d, SLOT(accept()));
525         connect(&cb, SIGNAL(clicked()), &d, SLOT(reject()));
526         if (d.exec()) {
527                 m.msg_type = MSG_NET;
528                 m.param.pword[0] = NET_CONNECT_TO;
529                 strcpy(m.param.pstr, ed.text());
530                 write(net_sock, &m, sizeof(MESSAGE)); 
531         }
532 }
533
534 void QKernel::Disconnect()
535 {
536         MESSAGE msg;
537
538         if (info_messages)
539                 WriteMessage("Disconnecting from virtual machine");
540
541         msg.msg_type = MSG_NET;
542         msg.param.pword[0] = NET_DISCONNECT;
543         write(net_sock, &msg, sizeof(MESSAGE));
544 }
545
546 void QKernel::QuitProc()
547 {
548         MESSAGE msg;
549
550         if (QMessageBox::question(this, "Close VLP", "Terminate VLP ?", 
551                 QMessageBox::Yes, QMessageBox::No, 0) == QMessageBox::No) {
552                 return;
553         }
554         
555         if (!LOCKED) {
556                 /* 
557                 msg.msg_type = MSG_NET;
558                 msg.param.pword[0] = NET_DISCONNECT;
559                 write(net_sock, &msg, sizeof(MESSAGE));*/
560                 delete Net_Notify;
561
562                 msg.msg_type = MSG_NET;
563                 msg.param.pword[0] = NET_EXIT;
564                 write(net_sock, &msg, sizeof(MESSAGE));
565                 /*  ::close(net_sock);*/
566                 app->quit();
567         }
568 }
569
570 void QKernel::AddAddress()
571 {
572         QDialog d(this, "", TRUE);
573         QLabel lab(&d, "IP Address:");
574         QLineEdit ed(&d, "");
575         QPushButton ob(&d, "");
576         QPushButton cb(&d, "");
577
578         if (connections) {
579                 ob.setGeometry(30, 60, 80, 30);
580                 ob.setText("Ok");
581                 ob.setDefault(TRUE);
582                 lab.setGeometry(10, 10, 60, 30);
583                 lab.setText("Address");
584                 ed.setGeometry(70, 10, 140, 30);
585                 cb.setGeometry(130, 60, 80, 30);
586                 cb.setText("Cancel");
587                 d.resize(240, 100);
588                 connect(&ob, SIGNAL(clicked()), &d, SLOT(accept()));
589                 connect(&cb, SIGNAL(clicked()), &d, SLOT(reject())); 
590                 if (d.exec())
591                         if (strcmp(ed.text(), "") != 0) {
592                                 connections->insertItem(ed.text());
593                         }
594         }
595 }
596
597 void QKernel::DelAddress()
598 {
599         if (connections) {
600                 if (connections->currentItem() != -1)
601                         connections->removeItem(connections->currentItem());
602         }
603 }
604
605 void QKernel::MessageToNode()
606 {
607         QDialog *dlg;
608         QLineEdit *nodenr;
609         MESSAGE m;
610
611         dlg = new QDialog(this, "Message", TRUE);
612
613         nodenr = new QLineEdit(dlg, "number");
614         nodenr->setGeometry(90, 10, 50, 30);
615         nodenr->setText("");
616
617         QLabel *tmpQLabel;
618         tmpQLabel = new QLabel(dlg, "Label_1");
619         tmpQLabel->setGeometry(10, 10, 77, 30);
620         tmpQLabel->setText("Node number:");
621
622         tmpQLabel = new QLabel(dlg, "Label_2");
623         tmpQLabel->setGeometry(10, 50, 70, 30);
624         tmpQLabel->setText("Message:");
625
626         QLineEdit *msg;
627         msg = new QLineEdit(dlg, "LineEdit_1");
628         msg->setGeometry(80, 60, 330, 30);
629         msg->setText("");
630
631         QPushButton *ob;
632         ob = new QPushButton(dlg, "PushButton_1");
633         ob->setGeometry(230, 10, 80, 30);
634         ob->setText("Send");
635         ob->setDefault(TRUE);
636         
637         QPushButton *cb;
638         cb = new QPushButton(dlg, "PushButton_2");
639         cb->setGeometry(330, 10, 80, 30);
640         cb->setText("Cancel");
641         dlg->resize(430, 110);
642         connect(ob, SIGNAL(clicked()), dlg, SLOT(accept()));
643         connect(cb, SIGNAL(clicked()), dlg, SLOT(reject())); 
644         dlg->setCaption("Send message to node");
645
646         if (dlg->exec()) {
647                 m.msg_type = MSG_NET;
648                 m.param.pword[0] = NET_PROPAGATE;
649                 m.param.pword[1] = MSG_VLP;
650                 m.param.pword[2] = NodeNumber;
651                 m.param.pword[4] = atoi(nodenr->text());
652                 m.param.pword[6] = VLP_WRITE;
653                 strcpy(m.param.pstr, msg->text());
654                 write(net_sock, &m, sizeof(MESSAGE));
655         }
656 }
657
658 void QKernel::KillInterpreter()
659 {
660         QDialog *dlg;
661         QLineEdit *nodenr;
662         MESSAGE m;
663         InterpEntry *pom;
664
665         dlg = new QDialog(this, "Message", TRUE);
666
667         nodenr = new QLineEdit(dlg, "number"); 
668         nodenr->setGeometry(90, 10, 50, 30);
669         nodenr->setText("");
670
671         QLabel* tmpQLabel;
672         tmpQLabel = new QLabel(dlg, "Label_1");
673         tmpQLabel->setGeometry(10, 10, 77, 30);
674         tmpQLabel->setText("Interp. ID:");
675         QPushButton* ob, *cb;
676         ob = new QPushButton(dlg, "PushButton_1");
677         ob->setGeometry( 160, 10, 80, 30);
678         ob->setText("Kill");
679         ob->setDefault(TRUE);
680         cb = new QPushButton(dlg, "PushButton_2");
681         cb->setGeometry(260, 10, 80, 30);
682         cb->setText("Cancel");
683         dlg->resize(360, 50);
684         connect(ob, SIGNAL(clicked()), dlg, SLOT(accept()));
685         connect(cb, SIGNAL(clicked()), dlg, SLOT(reject())); 
686         dlg->setCaption("Kill interpreter");
687         if (dlg->exec()) {
688                 m.msg_type = MSG_INT;
689                 m.param.pword[0] = INT_KILL;
690                 pom = findINTbyID(atoi(nodenr->text()));
691                 if (pom != NULL) {
692                         if (!(pom->remote))
693                                 write(pom->sock, &m, sizeof(MESSAGE));
694                         else
695                                 WriteMessage("This is a remote instance of "
696                                                                 "a program!");
697                 }
698                 else {
699                         WriteMessage("Interpreter not found");
700                 }
701         }
702 }
703
704
705
706 void QKernel::NetMessage()
707 {
708         
709         /* TODO: It has to be rewritten */
710         MESSAGE msg;
711         int cnt;
712         char ss[255];
713         InterpEntry *pom;
714
715         cnt = read(net_sock, &msg, sizeof(MESSAGE));
716         if ((cnt > 0) && (msg.msg_type == MSG_NET)) {
717                 switch(msg.param.pword[0]) {
718                 case NET_CSWRITELN:
719                         WriteMessage(msg.param.pstr);
720                         break;
721                 case NET_PROPAGATE: 
722                         switch(msg.param.pword[1]) {
723                         case MSG_INT:
724                                 /*  pom = find_link_by_ID(msg.param.pword[5]);
725                                 msg.msg_type = MSG_NET;
726                                 msg.param.pword[0] = NET_PROPAGATE;   
727                                 send_int(pom, &msg);*/
728                                 break;
729                         case MSG_VLP:
730                                 switch(msg.param.pword[6]) {
731                                 case VLP_WRITE:
732                                         QApplication::beep();
733                                         WriteMessage(CharLine);
734                                         WriteMessage(
735                                                 "### Incoming Messsage ###");
736                                         sprintf(ss, "Mesg from Node %d: %s",
737                                                         msg.param.pword[2],
738                                                         msg.param.pstr);
739                                         WriteMessage(ss);
740                                         WriteMessage(CharLine);
741                                         break;
742                                 case VLP_REMOTE_INSTANCE:
743                                         sprintf(ss, "%s/%s", REMOTE_PATH,
744                                                                 msg.param.pstr);
745
746                                         if (info_messages) { 
747                                                 WriteMessage("Running program:");
748                                                 WriteMessage(ss);
749                                         }
750                                         pom = RunIntModule(ss, 1);
751                                         if (pom != NULL) {
752                                                 pom->p_ctx.node = msg.param.pword[2];
753                                                 pom->p_ctx.program_id = 
754                                                         msg.param.pword[7];
755                                                 pom->RInstances[msg.param.pword[2]] = msg.param.pword[7];
756                                         }
757                                         break;
758                                 case VLP_CLOSE_INSTANCE:
759                                         msg.msg_type = MSG_INT;
760                                         msg.param.pword[0] = INT_CLOSE_INSTANCE;
761                                         pom = findINTbyID(msg.param.pword[7]);
762                                         if (pom != NULL) {
763                                                 write(pom->sock, &msg,
764                                                         sizeof(MESSAGE));
765                                                 MESSAGE m1;
766                                                 m1.msg_type = MSG_VLP;
767                                                 m1.param.pword[0] = VLP_INTERPRETER_DOWN;
768                                                 m1.param.pword[1] = pom->ID;
769                                                 write(net_sock, &m1,
770                                                         sizeof(MESSAGE));
771                                         } else {
772                                                 WriteMessage("Instance not found"); 
773                                         }
774                                         break; 
775                                 } /* VLP switch */        
776                         }/* switch */
777                         break;
778                 case NET_CONNECTIONS:
779                         ActiveConnections = msg.param.pword[1];
780                         WriteMessage(msg.param.pstr);
781                         if (!synchro) 
782                                 synchro = TRUE;
783                         break;
784                 case NET_INFO:
785                         /* TODO: It has to be rewritten */
786                         if (wait_for_info) {
787                                 QString poms, poms1, poms2;
788                                 poms.sprintf("%s", msg.param.pstr);
789                                 while (poms.length() > 0) {
790                                         cnt = poms.find(';');
791                                         if (cnt!=-1) {
792                                                 poms1 = poms.left(cnt);
793                                                 poms = poms.right(poms.length() - cnt - 1);
794                                                 cnt = poms1.find('=');
795                                                 if (cnt != -1) {
796                                                         poms2 = poms1.left(cnt);
797                                                         poms1 = poms1.right(
798                                                                 poms1.length() -
799                                                                 cnt - 1);
800                                                         sprintf(ss, "Node: %s Addr: %s", poms2.data(), poms1.data());
801                                                         WriteMessage(ss); 
802                                                 }
803                                         } 
804                                 }
805                         } 
806                         break;
807                 case NET_INFO_END:
808                         wait_for_info = FALSE;
809                         WriteMessage(CharLine);
810                         break;
811                 } /* switch */
812         }
813 }
814
815 void QKernel::IntMessage(int sock)
816 {
817         MESSAGE msg;
818         int cnt;
819         InterpEntry *e;
820
821         cnt = read(sock, &msg, sizeof(MESSAGE));
822         e = findINTbySocket(sock);
823         if ((cnt > 0) && (e != NULL)) {
824                 switch (msg.msg_type) { 
825                 case MSG_GRAPH:
826                         if (msg.param.pword[0] == GRAPH_ALLOCATE) {
827                                 RunGraphModule(msg.param.pstr);
828                         }
829                         break;
830                 case MSG_NET:
831                         write(net_sock, &msg, sizeof(MESSAGE));
832                         break;
833                 case MSG_VLP:
834                         switch(msg.param.pword[0]) {
835                         case VLP_REMOTE_INSTANCE_PLEASE:
836                                 RemoteInstance(e, msg.param.pword[2]);
837                                 break;
838                         }/* switch */
839                         break;
840                 case MSG_INT:
841                         switch(msg.param.pword[0]) {
842                         case INT_EXITING:
843                                 char ss[255];
844
845                                 MESSAGE m;
846                                 m.msg_type = MSG_VLP;
847                                 m.param.pword[0] = VLP_INTERPRETER_DOWN;
848                                 m.param.pword[1] = e->ID;
849                                 write(net_sock, &m, sizeof(MESSAGE));
850                                 if (e->remote == 0)
851                                         CloseInstances(e);
852                                 delete e->notify;
853                                 ::close(e->sock);   
854                                 Interpreters.remove(e);
855                                 delete e;
856
857                                 if (info_messages) {
858                                         sprintf(ss, "%s : End of program "
859                                                 "execution", msg.param.pstr);
860                                         WriteMessage(ss);
861                                 }
862                                 break;
863                         case INT_CTX_REQ:
864                                 msg.msg_type = MSG_INT;
865                                 msg.param.pword[0] = INT_CTX;
866                                 msg.param.pword[1] = NodeNumber;
867                                 msg.param.pword[2] = e->ID;
868                                 if (e->remote) {
869                                         msg.param.pword[3] = e->p_ctx.node;
870                                         msg.param.pword[4] = 
871                                                         e->p_ctx.program_id;
872                                 }
873                                 write(sock, &msg, sizeof(MESSAGE)); 
874                                 break;
875                         };
876                         break; /* switch param.pword[0] */
877                 } /* switch type */
878         } /* if */
879 }
880
881 void QKernel::WriteMessage(char *msg)
882 {
883         int x;
884         int y;
885
886         desktop->getCursorPosition(&x, &y);
887         if (x > 100) {
888                 desktop->clear();
889         }
890         
891         desktop->setReadOnly(FALSE);
892         desktop->append(msg);
893         desktop->setReadOnly(TRUE);
894         desktop->setCursorPosition(desktop->numLines(), 1);
895         desktop->repaint();
896         
897         if (desktop->numLines() > 100) {
898                 desktop->clear();
899         }
900 }
901
902 void QKernel::SetMessages()
903 {
904         if (p2 != NULL) {
905                 if (p2->isItemChecked(msgid)) {
906                         p2->setItemChecked(msgid, FALSE);
907                         info_messages=FALSE;
908                 } else {
909                         p2->setItemChecked(msgid, TRUE);  
910                         info_messages=TRUE;
911                 }
912         } /* !=NULL */
913         /* bar->repaint(); */
914 }
915
916 void QKernel::SetOptions()
917 {
918         QDialog dlg(this, "Options", TRUE);
919         ConnectEntry *e;
920         unsigned int i;
921
922         QLineEdit* progs;
923         progs = new QLineEdit(&dlg, "progs");
924         progs->setGeometry(150, 20, 180, 30);
925         progs->setText(progdir);
926
927         QLabel* tmpQLabel;
928         tmpQLabel = new QLabel(&dlg, "Label_1");
929         tmpQLabel->setGeometry(30, 20, 120, 30);
930         tmpQLabel->setText("Programs directory");
931
932         QFrame* tmpQFrame;
933         tmpQFrame = new QFrame(&dlg, "Frame_2");
934         tmpQFrame->setGeometry(10, 60, 380, 30);
935         tmpQFrame->setFrameStyle(52);
936
937         tmpQLabel = new QLabel(&dlg, "Label_2");
938         tmpQLabel->setGeometry(10, 80, 340, 30);
939         tmpQLabel->setText("Virtual Processor properties (activated after "
940                                                         "restarting VLP):");
941
942         QLineEdit *nn;
943         char nns[256];
944         nn = new QLineEdit(&dlg, "LineEdit_2");
945         nn->setGeometry(110, 110, 40, 30);
946         sprintf(nns, "%d", NodeNumber);
947         nn->setText(nns);
948
949         tmpQLabel = new QLabel(&dlg, "Label_3");
950         tmpQLabel->setGeometry(20, 110, 90, 30);
951         tmpQLabel->setText("Node number:");
952
953         QRadioButton *exp, *reg;
954         exp = new QRadioButton(&dlg, "RadioButton_3");
955         exp->setGeometry(30, 170, 100, 30);
956         exp->setText("Explicit");
957         exp->setChecked(TRUE);
958
959         reg = new QRadioButton(&dlg, "RadioButton_4");
960         reg->setGeometry(30, 200, 100, 30);
961         reg->setText("Registration");
962         reg->setEnabled(FALSE);
963
964         connections = new QListBox(&dlg, "ListBox_1");
965         connections->setGeometry(170, 140, 130, 100);
966         e = ConnectList.first();
967         while(e != NULL) {
968                 connections->insertItem(e->addr);
969                 e = ConnectList.next();
970         }
971
972         tmpQLabel = new QLabel(&dlg, "Label_5");
973         tmpQLabel->setGeometry(170, 110, 100, 30);
974         tmpQLabel->setText("Connection list:");
975
976         QPushButton *addbtn;
977         QPushButton *delbtn;
978         QPushButton *okbtn;
979         QPushButton *cancelbtn;
980         addbtn = new QPushButton(&dlg, "PushButton_1");
981         addbtn->setGeometry(310, 150, 60, 30);
982         addbtn->setText("Add");
983         delbtn = new QPushButton(&dlg, "PushButton_2");
984         delbtn->setGeometry(310, 200, 60, 30);
985         delbtn->setText("Del");
986         connect(addbtn, SIGNAL(clicked()), this, SLOT(AddAddress()));
987         connect(delbtn, SIGNAL(clicked()), this, SLOT(DelAddress()));
988         okbtn = new QPushButton(&dlg, "PushButton_3");
989         okbtn->setGeometry(80, 260, 100, 30);
990         okbtn->setText("Ok");
991         okbtn->setDefault(TRUE);
992         cancelbtn = new QPushButton(&dlg, "PushButton_4");
993         cancelbtn->setGeometry(210, 260, 100, 30);
994         cancelbtn->setText("Cancel");
995         connect(okbtn, SIGNAL(clicked()), &dlg, SLOT(accept()));
996         connect(cancelbtn, SIGNAL(clicked()), &dlg, SLOT(reject()));        
997         QButtonGroup* group;
998         group = new QButtonGroup(&dlg, "ButtonGroup_1");
999         group->setGeometry(20, 150, 120, 90);
1000         group->setTitle("Connection type");
1001         group->setAlignment(1);
1002         group->lower();
1003         group->insert(exp, 1);
1004         group->insert(reg, 2);  
1005
1006         dlg.resize(400, 310);
1007         if (dlg.exec()) {
1008                 config_t cfg;
1009                 config_setting_t *root;
1010                 config_setting_t *setting;
1011                 config_init(&cfg);
1012
1013                 root = config_root_setting(&cfg);
1014
1015                 setting = config_setting_add(root, "progdir",
1016                                                         CONFIG_TYPE_STRING);
1017                 config_setting_set_string(setting, progs->text().ascii());
1018                 strcpy(progdir, progs->text());
1019
1020                 setting = config_setting_add(root, "node_number",
1021                                                         CONFIG_TYPE_INT);
1022                 config_setting_set_int(setting, atoi(nn->text()));
1023
1024                 setting = config_setting_add(root, "homedir",
1025                                                         CONFIG_TYPE_STRING);
1026                 config_setting_set_string(setting, HomeDir);
1027
1028                 setting = config_setting_add(root, "type",
1029                                                         CONFIG_TYPE_STRING);
1030                 if (exp->isChecked()) {
1031                         config_setting_set_string(setting, "explicit");
1032
1033                         config_setting_t *hosts = NULL;
1034                         hosts = config_setting_add(root, "host",
1035                                                         CONFIG_TYPE_ARRAY);
1036                         for(i = 0; i < connections->count(); i++) {
1037                                 setting = config_setting_add(hosts, NULL,
1038                                                         CONFIG_TYPE_STRING);
1039                                 config_setting_set_string(setting,
1040                                                 connections->text(i).ascii());
1041                         }
1042                 } else {
1043                         config_setting_set_string(setting, "register");
1044                 }
1045
1046                 if (!config_write_file(&cfg, "vlp.cfg")) {
1047                         fprintf(stderr, "Error while writing to file: %s.\n", 
1048                                                                 "vlp.cfg");
1049                 }
1050                 config_destroy(&cfg);
1051         }
1052 }
1053
1054 void QKernel::LockConsole()
1055 {
1056         QDialog d(this, "Enter password", TRUE);
1057         QLabel lab(&d, "Password");
1058         QLineEdit ed(&d, "");
1059         QPushButton ob(&d, "");
1060         QPushButton cb(&d, "");
1061
1062         d.setCaption("Lock console"); 
1063         ob.setGeometry(30, 60, 80, 30);
1064         ob.setText("Ok");
1065         ob.setDefault(TRUE);
1066         lab.setGeometry(10, 10, 60, 30);
1067         lab.setText("Password:");
1068         ed.setGeometry(70, 10, 140, 30);
1069         ed.setEchoMode(QLineEdit::Password);
1070         cb.setGeometry(130, 60, 80, 30);
1071         cb.setText("Cancel");
1072         d.resize(240, 100);
1073         connect(&ob, SIGNAL(clicked()), &d, SLOT(accept()));
1074         connect(&cb, SIGNAL(clicked()), &d, SLOT(reject())); 
1075
1076         if (d.exec()) {
1077                 if (strcmp(ed.text(), "") != 0) {
1078                         strcpy(LockPasswd, ed.text());
1079                         lab.setText("Retype:");
1080                         ed.setText("");
1081                         if (d.exec()) {
1082                                 if (strcmp(ed.text(), LockPasswd)==0) {
1083                                         bar->setItemEnabled(qid, FALSE);
1084                                         bar->setItemEnabled(prid, FALSE);
1085                                         bar->setItemEnabled(mid, FALSE);
1086                                         p2->setItemEnabled(unlockid, TRUE);
1087                                         p2->setItemEnabled(lockid, FALSE);
1088                                         p2->setItemEnabled(cwid, FALSE);
1089                                         p2->setItemEnabled(optid, FALSE);
1090                                         bar->repaint();
1091                                         WriteMessage("CONSOLE LOCKED");
1092                                         LOCKED = TRUE;
1093                                 } else {
1094                                         QMessageBox msg(this);
1095                                         msg.setText("Not matching!");
1096                                         msg.setButtonText(0, "Close");
1097                                         msg.show();
1098                                 }   
1099                         } else {
1100                                 strcpy(LockPasswd, "");
1101                         }
1102                 }
1103         }
1104 }
1105
1106 void QKernel::UnlockConsole()
1107 {
1108         QDialog d(this, "Enter password", TRUE);
1109         QLabel lab(&d, "Password");
1110         QLineEdit ed(&d, "");
1111         QPushButton ob(&d, "");
1112         QPushButton cb(&d, "");
1113
1114         ob.setGeometry(30, 60, 80, 30);
1115         ob.setText("Ok");
1116         ob.setDefault(TRUE);
1117         lab.setGeometry(10, 10, 60, 30);
1118         lab.setText("Password:");
1119         ed.setGeometry(70, 10, 140, 30);
1120         ed.setEchoMode(QLineEdit::Password);
1121         cb.setGeometry(130, 60, 80, 30);
1122         cb.setText("Cancel");
1123         d.resize(240, 100);
1124         connect(&ob, SIGNAL(clicked()), &d, SLOT(accept()));
1125         connect(&cb, SIGNAL(clicked()), &d, SLOT(reject())); 
1126
1127         if (d.exec()) {
1128                 if (strcmp(ed.text(), LockPasswd) == 0) {
1129                         bar->setItemEnabled(qid, TRUE);
1130                         bar->setItemEnabled(prid, TRUE);
1131                         bar->setItemEnabled(mid, TRUE);
1132                         p2->setItemEnabled(unlockid, FALSE);
1133                         p2->setItemEnabled(lockid, TRUE);
1134                         p2->setItemEnabled(cwid, TRUE);
1135                         p2->setItemEnabled(optid, TRUE);
1136                         bar->repaint();
1137                         WriteMessage("CONSOLE UNLOCKED");
1138                         LOCKED = FALSE;         
1139                 } else {
1140                         QMessageBox msg(this);
1141                         msg.setText("Wrong password!");
1142                         msg.setButtonText(0, "Close");
1143                         msg.show();
1144                 }      
1145         }
1146 }
1147
1148 void QKernel::InitMessage()
1149 {
1150         WriteMessage("\n Virtual LOGLAN Processor - ver 1.9: READY \n");
1151 }
1152
1153 InterpEntry *QKernel::findINTbySocket(int _id)
1154 {
1155         InterpEntry *pom;
1156         pom = Interpreters.first();
1157
1158         while (pom != NULL) {
1159                 if (pom->sock == _id)
1160                         break;
1161
1162                 pom = Interpreters.next();
1163         }
1164         return(pom);
1165 }
1166
1167 InterpEntry *QKernel::findINTbyID(int _id)
1168 {
1169         InterpEntry *pom;
1170         pom = Interpreters.first();
1171         while (pom != NULL) {
1172                 if (pom->ID == _id)
1173                         break;
1174                 pom = Interpreters.next();
1175         }
1176         return(pom);
1177 }
1178
1179
1180 /* ------------------ Connect INT module -----------------*/
1181
1182 InterpEntry *QKernel::RunIntModule(char *ss, int r)
1183 {
1184         char a[256], b[255];
1185         struct sockaddr_un svr;
1186         int len, sock, i, on;
1187         int newint=-1;
1188         char cmd[255];
1189         FILE *cf;
1190         MESSAGE msg;
1191         InterpEntry *newINT = NULL;
1192
1193         strcpy(a, ss);
1194         strcat(a, ".ccd");
1195         cf = fopen(a, "r");
1196         if (cf == NULL) {
1197                 WriteMessage("File not found: no .ccd file");
1198                 return(NULL);
1199         }
1200         fclose(cf);
1201
1202         strcpy(a, ss);
1203         strcat(a, ".pcd");
1204         cf = fopen(a, "r");
1205         if (cf == NULL) {
1206                 WriteMessage("File not found: no .pcd file");
1207                 return(NULL);
1208         }
1209         fclose(cf);
1210
1211         newINT = new InterpEntry;
1212         for(i = 0; i < MAXINSTANCES; i++) 
1213                 newINT->RInstances[i] =- 1;
1214
1215         strcpy(b, rindex(ss, '/'));
1216         for(i = 0; i < strlen(b); i++)
1217                 b[i] = b[i+1];
1218         if (info_messages) {
1219                 sprintf(a, "%s : Start execution", b);
1220                 WriteMessage(a); 
1221         }
1222
1223         newint = freeINTid;
1224         freeINTid++;
1225         newINT->ID = newint;
1226         strcpy(newINT->shortname, b);
1227         strcpy(newINT->fullname, ss);
1228
1229         sprintf(a, "%s%d", IPATH, newint);
1230         sprintf(cmd, "%s/modules/logint %s %s", HomeDir, a, ss);
1231         if (r) 
1232                 strcat(cmd, " r");
1233         sprintf(b, " %s %s %s %s %s", myargs[0], myargs[1], myargs[2],
1234                                                         myargs[3], myargs[4]);
1235         strcat(cmd, b);
1236         strcat(cmd, " &");
1237
1238         sock = socket(AF_UNIX, SOCK_STREAM, 0);
1239         unlink(a);
1240         bzero(&svr, sizeof(svr));
1241         svr.sun_family = AF_UNIX;
1242         strcpy(svr.sun_path, a);
1243         len = strlen(svr.sun_path)+sizeof(svr.sun_family);
1244         bind(sock, (struct sockaddr*)&svr, len);
1245         listen(sock, 5);
1246         system(cmd); 
1247         newINT->sock = accept(sock, (struct sockaddr*)0, (unsigned int *)0);
1248         //::close(sock);
1249
1250         if (newINT->sock > 0) { 
1251                 fcntl(newINT->sock, F_SETFL, 
1252                                 O_NONBLOCK|fcntl(newINT->sock, F_GETFL, 0));
1253                 on=1; 
1254                 setsockopt(newINT->sock, IPPROTO_TCP, TCP_NODELAY, (char*)&on,
1255                                                                 sizeof(on)); 
1256                 if (r)
1257                         newINT->remote = 1;
1258                 else 
1259                         newINT->remote = 0;
1260
1261                 bzero(&msg, sizeof(MESSAGE));
1262                 msg.msg_type = MSG_VLP;
1263                 msg.param.pword[0] = VLP_REGINT;
1264                 msg.param.pword[1] = newINT->ID;
1265                 sprintf(msg.param.pstr, "logi%d.net", newint);
1266                 write(net_sock, &msg, sizeof(MESSAGE)); 
1267
1268                 Interpreters.append(newINT);
1269                 newINT->notify = new QSocketNotifier(newINT->sock,
1270                                                         QSocketNotifier::Read);
1271                 connect(newINT->notify, SIGNAL(activated(int)), this,
1272                                                         SLOT(IntMessage(int)));
1273                 if (info_messages)
1274                         WriteMessage("INTERPRETER successfully connected");
1275         } else {
1276                 WriteMessage("Cannot connect interpreter");
1277         }
1278
1279         return newINT;
1280 }
1281
1282 /* ---------------------------------------------------------*/
1283 /*            Allocate remote instance                      */
1284
1285 void QKernel::RemoteInstance(InterpEntry *interp, int on)
1286 {
1287         MESSAGE m;
1288         char s[255];
1289
1290         m.msg_type = MSG_NET;
1291         m.param.pword[0] = NET_NODE_EXIST;
1292         m.param.pword[1] = on;
1293         m.param.pword[2] = interp->ID;
1294         write(net_sock, &m, sizeof(MESSAGE));
1295         bzero(&m, sizeof(MESSAGE));
1296         while((m.msg_type!=MSG_NET) && (m.param.pword[0]!=NET_NODE_EXIST))
1297                 read(net_sock, &m, sizeof(MESSAGE));
1298
1299          /* means node exists */
1300         if (m.param.pword[1] == 1) {
1301                 m.msg_type = MSG_NET;
1302                 m.param.pword[0] = NET_TRANSMIT_CODE;
1303                 m.param.pword[1] = interp->ID;
1304                 m.param.pword[2] = on;
1305                 strcpy(m.param.pstr, interp->fullname);
1306                 write(net_sock, &m, sizeof(MESSAGE));
1307
1308                 Net_Notify->setEnabled(FALSE);
1309                 while ((m.msg_type != MSG_NET) ||
1310                         (m.param.pword[0] != NET_TRANSMITTED))
1311                         read(net_sock, &m, sizeof(MESSAGE));
1312
1313                 m.msg_type = MSG_NET;
1314                 m.param.pword[0] = NET_PROPAGATE;
1315                 m.param.pword[1] = MSG_VLP;
1316                 m.param.pword[2] = NodeNumber;
1317                 m.param.pword[3] = 0;
1318                 m.param.pword[4] = on;
1319                 m.param.pword[5] = 0;
1320                 m.param.pword[6] = VLP_REMOTE_INSTANCE;
1321                 m.param.pword[7] = interp->ID;
1322                 strcpy(m.param.pstr, interp->shortname);
1323                 write(net_sock, &m, sizeof(MESSAGE));
1324
1325                 read(net_sock, &m, sizeof(MESSAGE));
1326                 while (1) {
1327                         if ((m.param.pword[0] == NET_PROPAGATE) &&
1328                                 (m.param.pword[6] == VLP_REMOTE_INSTANCE_OK)) {
1329                                 interp->RInstances[on] = m.param.pword[7];
1330                                 break;
1331                         }
1332                         read(net_sock, &m, sizeof(MESSAGE));  
1333                 }
1334
1335                 Net_Notify->setEnabled(TRUE);
1336
1337                 /*bzero(&m, sizeof(MESSAGE));*/
1338                 m.msg_type = MSG_VLP;
1339                 m.param.pword[0] = VLP_REMOTE_INSTANCE_HERE;
1340                 m.param.pword[1] = interp->RInstances[on];
1341                 write(interp->sock, &m, sizeof(MESSAGE));
1342         } else { /* There is no such a node! */
1343                 sprintf(s, "Warning: Node number %d not found!", on); 
1344                 WriteMessage(s);
1345                 WriteMessage("Allocating O-process on the local node");
1346                 bzero(&m, sizeof(MESSAGE));
1347                 m.msg_type = MSG_VLP;
1348                 m.param.pword[0] = VLP_REMOTE_INSTANCE_HERE;
1349                 m.param.pword[1] = interp->ID;
1350                 write(interp->sock, &m, sizeof(MESSAGE));
1351         }
1352 }
1353
1354
1355 /*-----------------------------------------------*/
1356 /*           Close all remote instances         */
1357
1358 void QKernel::CloseInstances(InterpEntry *e)
1359 {
1360         MESSAGE msg;
1361         int i;
1362
1363         if (info_messages)
1364                 WriteMessage("Closing remote instances");
1365
1366         for(i=0; i < MAXINSTANCES; i++)
1367                 if (e->RInstances[i]>=0) {
1368                         msg.msg_type = MSG_NET;
1369                         msg.param.pword[0] = NET_PROPAGATE;
1370                         msg.param.pword[1] = MSG_VLP;
1371                         msg.param.pword[2] = NodeNumber;
1372                         msg.param.pword[4] = i;
1373                         msg.param.pword[6] = VLP_CLOSE_INSTANCE;
1374                         msg.param.pword[7] = e->RInstances[i];
1375                         write(net_sock, &msg, sizeof(MESSAGE));
1376                 }
1377 }
1378
1379
1380 void QKernel::Info()
1381 {
1382         MESSAGE m;
1383
1384         WriteMessage(CharLine);
1385         WriteMessage("### Virtual Machine Information ###");
1386         m.msg_type = MSG_NET;
1387         m.param.pword[0] = NET_GET_INFO;
1388         write(net_sock, &m, sizeof(MESSAGE));
1389         wait_for_info = TRUE;
1390 }
1391
1392 #include "kernel.moc"
1393
1394 int main(int argc, char **argv)
1395 {
1396         int i;
1397         for(i=0; i < 5; i++) {
1398                 strcpy(myargs[i], "");
1399         }
1400         for(i=1; i < argc; i++) {
1401                 strcpy(myargs[i-1], argv[i]);
1402         }
1403
1404         app = new QApplication(argc, argv);
1405         app->setStyle(new QWindowsStyle());
1406         QKernel kernel;
1407         app->setMainWidget(&kernel);
1408         draw.show();
1409         draw.InitMessage();
1410         return app->exec();
1411 }