Fixed compile errors in kernel.
[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 size = config_setting_length(setting);
376                         for (int i = 0; i < size; i++) {
377                                 ConnectList.append(new ConnectEntry((char*)
378                                         config_setting_get_string_elem(setting,
379                                                                         i)));
380                         }
381                         break;
382                 }
383                 default:
384                         fprintf(stderr, "%s! In file %s, bad entry type for %s."
385                                                         " Will not be read.\n", 
386                                                         "Error", fname, "host");
387                 }
388         } else {
389                 fprintf(stderr, "%s! In file %s, '%s' was not found.\n", 
390                                                 "Warning", fname, "host");
391         }
392
393         setting = config_lookup(&cfg, "progdir");
394         if (setting){
395                 strncpy(progdir, config_setting_get_string(setting), 256);
396         } else {
397                 fprintf(stderr, "%s! In file %s, '%s' was not found.\n", 
398                                                 "Warning", fname, "progdir");
399         }
400
401         setting = config_lookup(&cfg, "homedir");
402         if (setting) {
403                 strncpy(HomeDir, config_setting_get_string(setting), 255);
404         } else {
405                 fprintf(stderr, "%s! In file %s, '%s' was not found.\n", 
406                                                 "Warning", fname, "homedir");
407         }
408
409         config_destroy(&cfg);
410         fclose(file);
411 }
412 /* +++++++++++++++++++++++++++++++++++++++++++++++ */
413
414 void QKernel::Run_Prog()
415 {
416         int i;
417         QString s(QFileDialog::getOpenFileName(progdir, "*.log", this));
418         
419         if (!s.isNull()) {
420                 i = s.find(".log");
421                 
422                 if (i > 0)
423                         s.remove(i, 4);
424                         
425                 RunIntModule((char*)s.ascii(), 0);
426         }
427 }
428
429 void QKernel::Edit()
430 {
431         char cmd[255];
432         sprintf(cmd, "%s/modules/logedit %s %s %s %s %s %s &", HomeDir, HomeDir, 
433                         myargs[0], myargs[1], myargs[2], myargs[3], myargs[4]);
434         system(cmd);
435 }
436
437 void QKernel::Help()
438 {
439         char cmd[255];
440         sprintf(cmd, "%s/modules/loghelp %s/doc %s %s %s %s %s &", HomeDir, 
441                 HomeDir, myargs[0], myargs[1], myargs[2], myargs[3], myargs[4]);
442         system(cmd);
443 }
444
445
446 void QKernel::RunGraphModule(char *sk)
447 {
448         char cmd[255];
449
450         sprintf(cmd, "%s/modules/loggraph %s %s %s %s %s %s", HomeDir, sk, 
451                         myargs[0], myargs[1], myargs[2], myargs[3], myargs[4]);
452         strcat(cmd, " &");
453
454         if (system(cmd) != 0)
455                 WriteMessage("Cannot connect GRAPH resources");
456 }
457
458
459
460 void QKernel::RunNetModule()
461 {
462         struct sockaddr_un svr;
463         int len, on;
464         int sock;
465         char cmd[255];
466         sprintf(cmd, "%s/modules/lognet %s %s %s %s %s %s", HomeDir, NPATH, 
467                         myargs[0], myargs[1], myargs[2], myargs[3], myargs[4]);
468         strcat(cmd, " &");
469
470         /* -------- socket for NET module -------- */
471         unlink(NPATH);
472         sock = socket(AF_UNIX, SOCK_STREAM, 0);
473         bzero(&svr, sizeof(svr));
474         svr.sun_family = AF_UNIX;
475         strcpy(svr.sun_path, NPATH);
476         len = strlen(svr.sun_path) + sizeof(svr.sun_family);
477         bind(sock, (struct sockaddr*)&svr, len);      
478         listen(sock, 5);
479
480         if (system(cmd) == 0) {
481                 net_sock = accept(sock, (struct sockaddr*)0, (unsigned int*)0);
482                 // close(sock); 
483                 if (net_sock != 0) {
484                         WriteMessage("NETWORK successfully connected");
485                         fcntl(net_sock, F_SETFL, O_NONBLOCK|fcntl(net_sock,
486                                                                 F_GETFL, 0));
487                         on=1;
488                         setsockopt(net_sock, IPPROTO_TCP, TCP_NODELAY,
489                                                         (char*)&on, sizeof(on)); 
490                 } else {
491                         WriteMessage("Cannot connect NETWORK resources");
492                         WriteMessage("Exiting...");
493                         sleep(2);
494                         QuitProc(); 
495                 }
496         /* system OK */
497         } else {
498                 WriteMessage("Cannot connect NETWORK resources");
499                 WriteMessage("Exiting...");
500                 sleep(2);
501                 QuitProc(); 
502         }
503 }
504
505 void QKernel::Connect()
506 {
507         QDialog d(this, "", TRUE);
508         QLabel lab(&d, "IP Address:");
509         QLineEdit ed(&d, "");
510         QPushButton ob(&d, "");
511         QPushButton cb(&d, "");
512         MESSAGE m;
513
514         d.setFont(QFont("Helvetica", 12, QFont::Bold)); 
515         ob.setGeometry(30, 60, 80, 30);
516         ob.setText("Ok");
517         ob.setDefault(TRUE);
518         lab.setGeometry(10, 10, 60, 30);
519         lab.setText("Address");
520         ed.setGeometry(70, 10, 140, 30);
521         cb.setGeometry(130, 60, 80, 30);
522         cb.setText("Cancel");
523         d.resize(240, 100);
524
525         connect(&ob, SIGNAL(clicked()), &d, SLOT(accept()));
526         connect(&cb, SIGNAL(clicked()), &d, SLOT(reject()));
527         if (d.exec()) {
528                 m.msg_type = MSG_NET;
529                 m.param.pword[0] = NET_CONNECT_TO;
530                 strcpy(m.param.pstr, ed.text());
531                 write(net_sock, &m, sizeof(MESSAGE)); 
532         }
533 }
534
535 void QKernel::Disconnect()
536 {
537         MESSAGE msg;
538
539         if (info_messages)
540                 WriteMessage("Disconnecting from virtual machine");
541
542         msg.msg_type = MSG_NET;
543         msg.param.pword[0] = NET_DISCONNECT;
544         write(net_sock, &msg, sizeof(MESSAGE));
545 }
546
547 void QKernel::QuitProc()
548 {
549         MESSAGE msg;
550
551         if (QMessageBox::question(this, "Close VLP", "Terminate VLP ?", 
552                 QMessageBox::Yes, QMessageBox::No, 0) == QMessageBox::No) {
553                 return;
554         }
555         
556         if (!LOCKED) {
557                 /* 
558                 msg.msg_type = MSG_NET;
559                 msg.param.pword[0] = NET_DISCONNECT;
560                 write(net_sock, &msg, sizeof(MESSAGE));*/
561                 delete Net_Notify;
562
563                 msg.msg_type = MSG_NET;
564                 msg.param.pword[0] = NET_EXIT;
565                 write(net_sock, &msg, sizeof(MESSAGE));
566                 /*  ::close(net_sock);*/
567                 app->quit();
568         }
569 }
570
571 void QKernel::AddAddress()
572 {
573         QDialog d(this, "", TRUE);
574         QLabel lab(&d, "IP Address:");
575         QLineEdit ed(&d, "");
576         QPushButton ob(&d, "");
577         QPushButton cb(&d, "");
578
579         if (connections) {
580                 ob.setGeometry(30, 60, 80, 30);
581                 ob.setText("Ok");
582                 ob.setDefault(TRUE);
583                 lab.setGeometry(10, 10, 60, 30);
584                 lab.setText("Address");
585                 ed.setGeometry(70, 10, 140, 30);
586                 cb.setGeometry(130, 60, 80, 30);
587                 cb.setText("Cancel");
588                 d.resize(240, 100);
589                 connect(&ob, SIGNAL(clicked()), &d, SLOT(accept()));
590                 connect(&cb, SIGNAL(clicked()), &d, SLOT(reject())); 
591                 if (d.exec())
592                         if (strcmp(ed.text(), "") != 0) {
593                                 connections->insertItem(ed.text());
594                         }
595         }
596 }
597
598 void QKernel::DelAddress()
599 {
600         if (connections) {
601                 if (connections->currentItem() != -1)
602                         connections->removeItem(connections->currentItem());
603         }
604 }
605
606 void QKernel::MessageToNode()
607 {
608         QDialog *dlg;
609         QLineEdit *nodenr;
610         MESSAGE m;
611
612         dlg = new QDialog(this, "Message", TRUE);
613
614         nodenr = new QLineEdit(dlg, "number");
615         nodenr->setGeometry(90, 10, 50, 30);
616         nodenr->setText("");
617
618         QLabel *tmpQLabel;
619         tmpQLabel = new QLabel(dlg, "Label_1");
620         tmpQLabel->setGeometry(10, 10, 77, 30);
621         tmpQLabel->setText("Node number:");
622
623         tmpQLabel = new QLabel(dlg, "Label_2");
624         tmpQLabel->setGeometry(10, 50, 70, 30);
625         tmpQLabel->setText("Message:");
626
627         QLineEdit *msg;
628         msg = new QLineEdit(dlg, "LineEdit_1");
629         msg->setGeometry(80, 60, 330, 30);
630         msg->setText("");
631
632         QPushButton *ob;
633         ob = new QPushButton(dlg, "PushButton_1");
634         ob->setGeometry(230, 10, 80, 30);
635         ob->setText("Send");
636         ob->setDefault(TRUE);
637         
638         QPushButton *cb;
639         cb = new QPushButton(dlg, "PushButton_2");
640         cb->setGeometry(330, 10, 80, 30);
641         cb->setText("Cancel");
642         dlg->resize(430, 110);
643         connect(ob, SIGNAL(clicked()), dlg, SLOT(accept()));
644         connect(cb, SIGNAL(clicked()), dlg, SLOT(reject())); 
645         dlg->setCaption("Send message to node");
646
647         if (dlg->exec()) {
648                 m.msg_type = MSG_NET;
649                 m.param.pword[0] = NET_PROPAGATE;
650                 m.param.pword[1] = MSG_VLP;
651                 m.param.pword[2] = NodeNumber;
652                 m.param.pword[4] = atoi(nodenr->text());
653                 m.param.pword[6] = VLP_WRITE;
654                 strcpy(m.param.pstr, msg->text());
655                 write(net_sock, &m, sizeof(MESSAGE));
656         }
657 }
658
659 void QKernel::KillInterpreter()
660 {
661         QDialog *dlg;
662         QLineEdit *nodenr;
663         MESSAGE m;
664         InterpEntry *pom;
665
666         dlg = new QDialog(this, "Message", TRUE);
667
668         nodenr = new QLineEdit(dlg, "number"); 
669         nodenr->setGeometry(90, 10, 50, 30);
670         nodenr->setText("");
671
672         QLabel* tmpQLabel;
673         tmpQLabel = new QLabel(dlg, "Label_1");
674         tmpQLabel->setGeometry(10, 10, 77, 30);
675         tmpQLabel->setText("Interp. ID:");
676         QPushButton* ob, *cb;
677         ob = new QPushButton(dlg, "PushButton_1");
678         ob->setGeometry( 160, 10, 80, 30);
679         ob->setText("Kill");
680         ob->setDefault(TRUE);
681         cb = new QPushButton(dlg, "PushButton_2");
682         cb->setGeometry(260, 10, 80, 30);
683         cb->setText("Cancel");
684         dlg->resize(360, 50);
685         connect(ob, SIGNAL(clicked()), dlg, SLOT(accept()));
686         connect(cb, SIGNAL(clicked()), dlg, SLOT(reject())); 
687         dlg->setCaption("Kill interpreter");
688         if (dlg->exec()) {
689                 m.msg_type = MSG_INT;
690                 m.param.pword[0] = INT_KILL;
691                 pom = findINTbyID(atoi(nodenr->text()));
692                 if (pom != NULL) {
693                         if (!(pom->remote))
694                                 write(pom->sock, &m, sizeof(MESSAGE));
695                         else
696                                 WriteMessage("This is a remote instance of "
697                                                                 "a program!");
698                 }
699                 else {
700                         WriteMessage("Interpreter not found");
701                 }
702         }
703 }
704
705
706
707 void QKernel::NetMessage()
708 {
709         
710         /* TODO: It has to be rewritten */
711         MESSAGE msg;
712         int cnt;
713         char ss[255];
714         InterpEntry *pom;
715
716         cnt = read(net_sock, &msg, sizeof(MESSAGE));
717         if ((cnt > 0) && (msg.msg_type == MSG_NET)) {
718                 switch(msg.param.pword[0]) {
719                 case NET_CSWRITELN:
720                         WriteMessage(msg.param.pstr);
721                         break;
722                 case NET_PROPAGATE: 
723                         switch(msg.param.pword[1]) {
724                         case MSG_INT:
725                                 /*  pom = find_link_by_ID(msg.param.pword[5]);
726                                 msg.msg_type = MSG_NET;
727                                 msg.param.pword[0] = NET_PROPAGATE;   
728                                 send_int(pom, &msg);*/
729                                 break;
730                         case MSG_VLP:
731                                 switch(msg.param.pword[6]) {
732                                 case VLP_WRITE:
733                                         QApplication::beep();
734                                         WriteMessage(CharLine);
735                                         WriteMessage(
736                                                 "### Incoming Messsage ###");
737                                         sprintf(ss, "Mesg from Node %d: %s",
738                                                         msg.param.pword[2],
739                                                         msg.param.pstr);
740                                         WriteMessage(ss);
741                                         WriteMessage(CharLine);
742                                         break;
743                                 case VLP_REMOTE_INSTANCE:
744                                         sprintf(ss, "%s/%s", REMOTE_PATH,
745                                                                 msg.param.pstr);
746
747                                         if (info_messages) { 
748                                                 WriteMessage("Running program:");
749                                                 WriteMessage(ss);
750                                         }
751                                         pom = RunIntModule(ss, 1);
752                                         if (pom != NULL) {
753                                                 pom->p_ctx.node = msg.param.pword[2];
754                                                 pom->p_ctx.program_id = 
755                                                         msg.param.pword[7];
756                                                 pom->RInstances[msg.param.pword[2]] = msg.param.pword[7];
757                                         }
758                                         break;
759                                 case VLP_CLOSE_INSTANCE:
760                                         msg.msg_type = MSG_INT;
761                                         msg.param.pword[0] = INT_CLOSE_INSTANCE;
762                                         pom = findINTbyID(msg.param.pword[7]);
763                                         if (pom != NULL) {
764                                                 write(pom->sock, &msg,
765                                                         sizeof(MESSAGE));
766                                                 MESSAGE m1;
767                                                 m1.msg_type = MSG_VLP;
768                                                 m1.param.pword[0] = VLP_INTERPRETER_DOWN;
769                                                 m1.param.pword[1] = pom->ID;
770                                                 write(net_sock, &m1,
771                                                         sizeof(MESSAGE));
772                                         } else {
773                                                 WriteMessage("Instance not found"); 
774                                         }
775                                         break; 
776                                 } /* VLP switch */        
777                         }/* switch */
778                         break;
779                 case NET_CONNECTIONS:
780                         ActiveConnections = msg.param.pword[1];
781                         WriteMessage(msg.param.pstr);
782                         if (!synchro) 
783                                 synchro = TRUE;
784                         break;
785                 case NET_INFO:
786                         /* TODO: It has to be rewritten */
787                         if (wait_for_info) {
788                                 QString poms, poms1, poms2;
789                                 poms.sprintf("%s", msg.param.pstr);
790                                 while (poms.length() > 0) {
791                                         cnt = poms.find(';');
792                                         if (cnt!=-1) {
793                                                 poms1 = poms.left(cnt);
794                                                 poms = poms.right(poms.length() - cnt - 1);
795                                                 cnt = poms1.find('=');
796                                                 if (cnt != -1) {
797                                                         poms2 = poms1.left(cnt);
798                                                         poms1 = poms1.right(
799                                                                 poms1.length() -
800                                                                 cnt - 1);
801                                                         sprintf(ss, "Node: %s Addr: %s", poms2.data(), poms1.data());
802                                                         WriteMessage(ss); 
803                                                 }
804                                         } 
805                                 }
806                         } 
807                         break;
808                 case NET_INFO_END:
809                         wait_for_info = FALSE;
810                         WriteMessage(CharLine);
811                         break;
812                 } /* switch */
813         }
814 }
815
816 void QKernel::IntMessage(int sock)
817 {
818         MESSAGE msg;
819         int cnt;
820         InterpEntry *e;
821
822         cnt = read(sock, &msg, sizeof(MESSAGE));
823         e = findINTbySocket(sock);
824         if ((cnt > 0) && (e != NULL)) {
825                 switch (msg.msg_type) { 
826                 case MSG_GRAPH:
827                         if (msg.param.pword[0] == GRAPH_ALLOCATE) {
828                                 RunGraphModule(msg.param.pstr);
829                         }
830                         break;
831                 case MSG_NET:
832                         write(net_sock, &msg, sizeof(MESSAGE));
833                         break;
834                 case MSG_VLP:
835                         switch(msg.param.pword[0]) {
836                         case VLP_REMOTE_INSTANCE_PLEASE:
837                                 RemoteInstance(e, msg.param.pword[2]);
838                                 break;
839                         }/* switch */
840                         break;
841                 case MSG_INT:
842                         switch(msg.param.pword[0]) {
843                         case INT_EXITING:
844                                 char ss[255];
845
846                                 MESSAGE m;
847                                 m.msg_type = MSG_VLP;
848                                 m.param.pword[0] = VLP_INTERPRETER_DOWN;
849                                 m.param.pword[1] = e->ID;
850                                 write(net_sock, &m, sizeof(MESSAGE));
851                                 if (e->remote == 0)
852                                         CloseInstances(e);
853                                 delete e->notify;
854                                 ::close(e->sock);   
855                                 Interpreters.remove(e);
856                                 delete e;
857
858                                 if (info_messages) {
859                                         sprintf(ss, "%s : End of program "
860                                                 "execution", msg.param.pstr);
861                                         WriteMessage(ss);
862                                 }
863                                 break;
864                         case INT_CTX_REQ:
865                                 msg.msg_type = MSG_INT;
866                                 msg.param.pword[0] = INT_CTX;
867                                 msg.param.pword[1] = NodeNumber;
868                                 msg.param.pword[2] = e->ID;
869                                 if (e->remote) {
870                                         msg.param.pword[3] = e->p_ctx.node;
871                                         msg.param.pword[4] = 
872                                                         e->p_ctx.program_id;
873                                 }
874                                 write(sock, &msg, sizeof(MESSAGE)); 
875                                 break;
876                         };
877                         break; /* switch param.pword[0] */
878                 } /* switch type */
879         } /* if */
880 }
881
882 void QKernel::WriteMessage(char *msg)
883 {
884         int x;
885         int y;
886
887         desktop->getCursorPosition(&x, &y);
888         if (x > 100) {
889                 desktop->clear();
890         }
891         
892         desktop->setReadOnly(FALSE);
893         desktop->append(msg);
894         desktop->setReadOnly(TRUE);
895         desktop->setCursorPosition(desktop->numLines(), 1);
896         desktop->repaint();
897         
898         if (desktop->numLines() > 100) {
899                 desktop->clear();
900         }
901 }
902
903 void QKernel::SetMessages()
904 {
905         if (p2 != NULL) {
906                 if (p2->isItemChecked(msgid)) {
907                         p2->setItemChecked(msgid, FALSE);
908                         info_messages=FALSE;
909                 } else {
910                         p2->setItemChecked(msgid, TRUE);  
911                         info_messages=TRUE;
912                 }
913         } /* !=NULL */
914         /* bar->repaint(); */
915 }
916
917 void QKernel::SetOptions()
918 {
919         QDialog dlg(this, "Options", TRUE);
920         ConnectEntry *e;
921         unsigned int i;
922
923         QLineEdit* progs;
924         progs = new QLineEdit(&dlg, "progs");
925         progs->setGeometry(150, 20, 180, 30);
926         progs->setText(progdir);
927
928         QLabel* tmpQLabel;
929         tmpQLabel = new QLabel(&dlg, "Label_1");
930         tmpQLabel->setGeometry(30, 20, 120, 30);
931         tmpQLabel->setText("Programs directory");
932
933         QFrame* tmpQFrame;
934         tmpQFrame = new QFrame(&dlg, "Frame_2");
935         tmpQFrame->setGeometry(10, 60, 380, 30);
936         tmpQFrame->setFrameStyle(52);
937
938         tmpQLabel = new QLabel(&dlg, "Label_2");
939         tmpQLabel->setGeometry(10, 80, 340, 30);
940         tmpQLabel->setText("Virtual Processor properties (activated after "
941                                                         "restarting VLP):");
942
943         QLineEdit *nn;
944         char nns[256];
945         nn = new QLineEdit(&dlg, "LineEdit_2");
946         nn->setGeometry(110, 110, 40, 30);
947         sprintf(nns, "%d", NodeNumber);
948         nn->setText(nns);
949
950         tmpQLabel = new QLabel(&dlg, "Label_3");
951         tmpQLabel->setGeometry(20, 110, 90, 30);
952         tmpQLabel->setText("Node number:");
953
954         QRadioButton *exp, *reg;
955         exp = new QRadioButton(&dlg, "RadioButton_3");
956         exp->setGeometry(30, 170, 100, 30);
957         exp->setText("Explicit");
958         exp->setChecked(TRUE);
959
960         reg = new QRadioButton(&dlg, "RadioButton_4");
961         reg->setGeometry(30, 200, 100, 30);
962         reg->setText("Registration");
963         reg->setEnabled(FALSE);
964
965         connections = new QListBox(&dlg, "ListBox_1");
966         connections->setGeometry(170, 140, 130, 100);
967         e = ConnectList.first();
968         while(e != NULL) {
969                 connections->insertItem(e->addr);
970                 e = ConnectList.next();
971         }
972
973         tmpQLabel = new QLabel(&dlg, "Label_5");
974         tmpQLabel->setGeometry(170, 110, 100, 30);
975         tmpQLabel->setText("Connection list:");
976
977         QPushButton *addbtn;
978         QPushButton *delbtn;
979         QPushButton *okbtn;
980         QPushButton *cancelbtn;
981         addbtn = new QPushButton(&dlg, "PushButton_1");
982         addbtn->setGeometry(310, 150, 60, 30);
983         addbtn->setText("Add");
984         delbtn = new QPushButton(&dlg, "PushButton_2");
985         delbtn->setGeometry(310, 200, 60, 30);
986         delbtn->setText("Del");
987         connect(addbtn, SIGNAL(clicked()), this, SLOT(AddAddress()));
988         connect(delbtn, SIGNAL(clicked()), this, SLOT(DelAddress()));
989         okbtn = new QPushButton(&dlg, "PushButton_3");
990         okbtn->setGeometry(80, 260, 100, 30);
991         okbtn->setText("Ok");
992         okbtn->setDefault(TRUE);
993         cancelbtn = new QPushButton(&dlg, "PushButton_4");
994         cancelbtn->setGeometry(210, 260, 100, 30);
995         cancelbtn->setText("Cancel");
996         connect(okbtn, SIGNAL(clicked()), &dlg, SLOT(accept()));
997         connect(cancelbtn, SIGNAL(clicked()), &dlg, SLOT(reject()));        
998         QButtonGroup* group;
999         group = new QButtonGroup(&dlg, "ButtonGroup_1");
1000         group->setGeometry(20, 150, 120, 90);
1001         group->setTitle("Connection type");
1002         group->setAlignment(1);
1003         group->lower();
1004         group->insert(exp, 1);
1005         group->insert(reg, 2);  
1006
1007         dlg.resize(400, 310);
1008         if (dlg.exec()) {
1009                 config_t cfg;
1010                 config_setting_t *root;
1011                 config_setting_t *setting;
1012                 config_init(&cfg);
1013
1014                 root = config_root_setting(&cfg);
1015
1016                 setting = config_setting_add(root, "progdir",
1017                                                         CONFIG_TYPE_STRING);
1018                 config_setting_set_string(setting, progs->text().ascii());
1019                 strcpy(progdir, progs->text());
1020
1021                 setting = config_setting_add(root, "node_number",
1022                                                         CONFIG_TYPE_INT);
1023                 config_setting_set_int(setting, atoi(nn->text()));
1024
1025                 setting = config_setting_add(root, "homedir",
1026                                                         CONFIG_TYPE_STRING);
1027                 config_setting_set_string(setting, HomeDir);
1028
1029                 setting = config_setting_add(root, "type",
1030                                                         CONFIG_TYPE_STRING);
1031                 if (exp->isChecked()) {
1032                         config_setting_set_string(setting, "explicit");
1033
1034                         config_setting_t *hosts = NULL;
1035                         hosts = config_setting_add(root, "host",
1036                                                         CONFIG_TYPE_ARRAY);
1037                         for(i = 0; i < connections->count(); i++) {
1038                                 setting = config_setting_add(hosts, NULL,
1039                                                         CONFIG_TYPE_STRING);
1040                                 config_setting_set_string(setting,
1041                                                 connections->text(i).ascii());
1042                         }
1043                 } else {
1044                         config_setting_set_string(setting, "register");
1045                 }
1046
1047                 if (!config_write_file(&cfg, "vlp.cfg")) {
1048                         fprintf(stderr, "Error while writing to file: %s.\n", 
1049                                                                 "vlp.cfg");
1050                 }
1051                 config_destroy(&cfg);
1052         }
1053 }
1054
1055 void QKernel::LockConsole()
1056 {
1057         QDialog d(this, "Enter password", TRUE);
1058         QLabel lab(&d, "Password");
1059         QLineEdit ed(&d, "");
1060         QPushButton ob(&d, "");
1061         QPushButton cb(&d, "");
1062
1063         d.setCaption("Lock console"); 
1064         ob.setGeometry(30, 60, 80, 30);
1065         ob.setText("Ok");
1066         ob.setDefault(TRUE);
1067         lab.setGeometry(10, 10, 60, 30);
1068         lab.setText("Password:");
1069         ed.setGeometry(70, 10, 140, 30);
1070         ed.setEchoMode(QLineEdit::Password);
1071         cb.setGeometry(130, 60, 80, 30);
1072         cb.setText("Cancel");
1073         d.resize(240, 100);
1074         connect(&ob, SIGNAL(clicked()), &d, SLOT(accept()));
1075         connect(&cb, SIGNAL(clicked()), &d, SLOT(reject())); 
1076
1077         if (d.exec()) {
1078                 if (strcmp(ed.text(), "") != 0) {
1079                         strcpy(LockPasswd, ed.text());
1080                         lab.setText("Retype:");
1081                         ed.setText("");
1082                         if (d.exec()) {
1083                                 if (strcmp(ed.text(), LockPasswd)==0) {
1084                                         bar->setItemEnabled(qid, FALSE);
1085                                         bar->setItemEnabled(prid, FALSE);
1086                                         bar->setItemEnabled(mid, FALSE);
1087                                         p2->setItemEnabled(unlockid, TRUE);
1088                                         p2->setItemEnabled(lockid, FALSE);
1089                                         p2->setItemEnabled(cwid, FALSE);
1090                                         p2->setItemEnabled(optid, FALSE);
1091                                         bar->repaint();
1092                                         WriteMessage("CONSOLE LOCKED");
1093                                         LOCKED = TRUE;
1094                                 } else {
1095                                         QMessageBox msg(this);
1096                                         msg.setText("Not matching!");
1097                                         msg.setButtonText(0, "Close");
1098                                         msg.show();
1099                                 }   
1100                         } else {
1101                                 strcpy(LockPasswd, "");
1102                         }
1103                 }
1104         }
1105 }
1106
1107 void QKernel::UnlockConsole()
1108 {
1109         QDialog d(this, "Enter password", TRUE);
1110         QLabel lab(&d, "Password");
1111         QLineEdit ed(&d, "");
1112         QPushButton ob(&d, "");
1113         QPushButton cb(&d, "");
1114
1115         ob.setGeometry(30, 60, 80, 30);
1116         ob.setText("Ok");
1117         ob.setDefault(TRUE);
1118         lab.setGeometry(10, 10, 60, 30);
1119         lab.setText("Password:");
1120         ed.setGeometry(70, 10, 140, 30);
1121         ed.setEchoMode(QLineEdit::Password);
1122         cb.setGeometry(130, 60, 80, 30);
1123         cb.setText("Cancel");
1124         d.resize(240, 100);
1125         connect(&ob, SIGNAL(clicked()), &d, SLOT(accept()));
1126         connect(&cb, SIGNAL(clicked()), &d, SLOT(reject())); 
1127
1128         if (d.exec()) {
1129                 if (strcmp(ed.text(), LockPasswd) == 0) {
1130                         bar->setItemEnabled(qid, TRUE);
1131                         bar->setItemEnabled(prid, TRUE);
1132                         bar->setItemEnabled(mid, TRUE);
1133                         p2->setItemEnabled(unlockid, FALSE);
1134                         p2->setItemEnabled(lockid, TRUE);
1135                         p2->setItemEnabled(cwid, TRUE);
1136                         p2->setItemEnabled(optid, TRUE);
1137                         bar->repaint();
1138                         WriteMessage("CONSOLE UNLOCKED");
1139                         LOCKED = FALSE;         
1140                 } else {
1141                         QMessageBox msg(this);
1142                         msg.setText("Wrong password!");
1143                         msg.setButtonText(0, "Close");
1144                         msg.show();
1145                 }      
1146         }
1147 }
1148
1149 void QKernel::InitMessage()
1150 {
1151         WriteMessage("\n Virtual LOGLAN Processor - ver 1.9: READY \n");
1152 }
1153
1154 InterpEntry *QKernel::findINTbySocket(int _id)
1155 {
1156         InterpEntry *pom;
1157         pom = Interpreters.first();
1158
1159         while (pom != NULL) {
1160                 if (pom->sock == _id)
1161                         break;
1162
1163                 pom = Interpreters.next();
1164         }
1165         return(pom);
1166 }
1167
1168 InterpEntry *QKernel::findINTbyID(int _id)
1169 {
1170         InterpEntry *pom;
1171         pom = Interpreters.first();
1172         while (pom != NULL) {
1173                 if (pom->ID == _id)
1174                         break;
1175                 pom = Interpreters.next();
1176         }
1177         return(pom);
1178 }
1179
1180
1181 /* ------------------ Connect INT module -----------------*/
1182
1183 InterpEntry *QKernel::RunIntModule(char *ss, int r)
1184 {
1185         char a[256], b[255];
1186         struct sockaddr_un svr;
1187         int len, sock, i, on;
1188         int newint=-1;
1189         char cmd[255];
1190         FILE *cf;
1191         MESSAGE msg;
1192         InterpEntry *newINT = NULL;
1193
1194         strcpy(a, ss);
1195         strcat(a, ".ccd");
1196         cf = fopen(a, "r");
1197         if (cf == NULL) {
1198                 WriteMessage("File not found: no .ccd file");
1199                 return(NULL);
1200         }
1201         fclose(cf);
1202
1203         strcpy(a, ss);
1204         strcat(a, ".pcd");
1205         cf = fopen(a, "r");
1206         if (cf == NULL) {
1207                 WriteMessage("File not found: no .pcd file");
1208                 return(NULL);
1209         }
1210         fclose(cf);
1211
1212         newINT = new InterpEntry;
1213         for(i = 0; i < MAXINSTANCES; i++) 
1214                 newINT->RInstances[i] =- 1;
1215
1216         strcpy(b, rindex(ss, '/'));
1217         for(i = 0; i < strlen(b); i++)
1218                 b[i] = b[i+1];
1219         if (info_messages) {
1220                 sprintf(a, "%s : Start execution", b);
1221                 WriteMessage(a); 
1222         }
1223
1224         newint = freeINTid;
1225         freeINTid++;
1226         newINT->ID = newint;
1227         strcpy(newINT->shortname, b);
1228         strcpy(newINT->fullname, ss);
1229
1230         sprintf(a, "%s%d", IPATH, newint);
1231         sprintf(cmd, "%s/modules/logint %s %s", HomeDir, a, ss);
1232         if (r) 
1233                 strcat(cmd, " r");
1234         sprintf(b, " %s %s %s %s %s", myargs[0], myargs[1], myargs[2],
1235                                                         myargs[3], myargs[4]);
1236         strcat(cmd, b);
1237         strcat(cmd, " &");
1238
1239         sock = socket(AF_UNIX, SOCK_STREAM, 0);
1240         unlink(a);
1241         bzero(&svr, sizeof(svr));
1242         svr.sun_family = AF_UNIX;
1243         strcpy(svr.sun_path, a);
1244         len = strlen(svr.sun_path)+sizeof(svr.sun_family);
1245         bind(sock, (struct sockaddr*)&svr, len);
1246         listen(sock, 5);
1247         system(cmd); 
1248         newINT->sock = accept(sock, (struct sockaddr*)0, (unsigned int *)0);
1249         //::close(sock);
1250
1251         if (newINT->sock > 0) { 
1252                 fcntl(newINT->sock, F_SETFL, 
1253                                 O_NONBLOCK|fcntl(newINT->sock, F_GETFL, 0));
1254                 on=1; 
1255                 setsockopt(newINT->sock, IPPROTO_TCP, TCP_NODELAY, (char*)&on,
1256                                                                 sizeof(on)); 
1257                 if (r)
1258                         newINT->remote = 1;
1259                 else 
1260                         newINT->remote = 0;
1261
1262                 bzero(&msg, sizeof(MESSAGE));
1263                 msg.msg_type = MSG_VLP;
1264                 msg.param.pword[0] = VLP_REGINT;
1265                 msg.param.pword[1] = newINT->ID;
1266                 sprintf(msg.param.pstr, "logi%d.net", newint);
1267                 write(net_sock, &msg, sizeof(MESSAGE)); 
1268
1269                 Interpreters.append(newINT);
1270                 newINT->notify = new QSocketNotifier(newINT->sock,
1271                                                         QSocketNotifier::Read);
1272                 connect(newINT->notify, SIGNAL(activated(int)), this,
1273                                                         SLOT(IntMessage(int)));
1274                 if (info_messages)
1275                         WriteMessage("INTERPRETER successfully connected");
1276         } else {
1277                 WriteMessage("Cannot connect interpreter");
1278         }
1279
1280         return newINT;
1281 }
1282
1283 /* ---------------------------------------------------------*/
1284 /*            Allocate remote instance                      */
1285
1286 void QKernel::RemoteInstance(InterpEntry *interp, int on)
1287 {
1288         MESSAGE m;
1289         char s[255];
1290
1291         m.msg_type = MSG_NET;
1292         m.param.pword[0] = NET_NODE_EXIST;
1293         m.param.pword[1] = on;
1294         m.param.pword[2] = interp->ID;
1295         write(net_sock, &m, sizeof(MESSAGE));
1296         bzero(&m, sizeof(MESSAGE));
1297         while((m.msg_type!=MSG_NET) && (m.param.pword[0]!=NET_NODE_EXIST))
1298                 read(net_sock, &m, sizeof(MESSAGE));
1299
1300          /* means node exists */
1301         if (m.param.pword[1] == 1) {
1302                 m.msg_type = MSG_NET;
1303                 m.param.pword[0] = NET_TRANSMIT_CODE;
1304                 m.param.pword[1] = interp->ID;
1305                 m.param.pword[2] = on;
1306                 strcpy(m.param.pstr, interp->fullname);
1307                 write(net_sock, &m, sizeof(MESSAGE));
1308
1309                 Net_Notify->setEnabled(FALSE);
1310                 while ((m.msg_type != MSG_NET) ||
1311                         (m.param.pword[0] != NET_TRANSMITTED))
1312                         read(net_sock, &m, sizeof(MESSAGE));
1313
1314                 m.msg_type = MSG_NET;
1315                 m.param.pword[0] = NET_PROPAGATE;
1316                 m.param.pword[1] = MSG_VLP;
1317                 m.param.pword[2] = NodeNumber;
1318                 m.param.pword[3] = 0;
1319                 m.param.pword[4] = on;
1320                 m.param.pword[5] = 0;
1321                 m.param.pword[6] = VLP_REMOTE_INSTANCE;
1322                 m.param.pword[7] = interp->ID;
1323                 strcpy(m.param.pstr, interp->shortname);
1324                 write(net_sock, &m, sizeof(MESSAGE));
1325
1326                 read(net_sock, &m, sizeof(MESSAGE));
1327                 while (1) {
1328                         if ((m.param.pword[0] == NET_PROPAGATE) &&
1329                                 (m.param.pword[6] == VLP_REMOTE_INSTANCE_OK)) {
1330                                 interp->RInstances[on] = m.param.pword[7];
1331                                 break;
1332                         }
1333                         read(net_sock, &m, sizeof(MESSAGE));  
1334                 }
1335
1336                 Net_Notify->setEnabled(TRUE);
1337
1338                 /*bzero(&m, sizeof(MESSAGE));*/
1339                 m.msg_type = MSG_VLP;
1340                 m.param.pword[0] = VLP_REMOTE_INSTANCE_HERE;
1341                 m.param.pword[1] = interp->RInstances[on];
1342                 write(interp->sock, &m, sizeof(MESSAGE));
1343         } else { /* There is no such a node! */
1344                 sprintf(s, "Warning: Node number %d not found!", on); 
1345                 WriteMessage(s);
1346                 WriteMessage("Allocating O-process on the local node");
1347                 bzero(&m, sizeof(MESSAGE));
1348                 m.msg_type = MSG_VLP;
1349                 m.param.pword[0] = VLP_REMOTE_INSTANCE_HERE;
1350                 m.param.pword[1] = interp->ID;
1351                 write(interp->sock, &m, sizeof(MESSAGE));
1352         }
1353 }
1354
1355
1356 /*-----------------------------------------------*/
1357 /*           Close all remote instances         */
1358
1359 void QKernel::CloseInstances(InterpEntry *e)
1360 {
1361         MESSAGE msg;
1362         int i;
1363
1364         if (info_messages)
1365                 WriteMessage("Closing remote instances");
1366
1367         for(i=0; i < MAXINSTANCES; i++)
1368                 if (e->RInstances[i]>=0) {
1369                         msg.msg_type = MSG_NET;
1370                         msg.param.pword[0] = NET_PROPAGATE;
1371                         msg.param.pword[1] = MSG_VLP;
1372                         msg.param.pword[2] = NodeNumber;
1373                         msg.param.pword[4] = i;
1374                         msg.param.pword[6] = VLP_CLOSE_INSTANCE;
1375                         msg.param.pword[7] = e->RInstances[i];
1376                         write(net_sock, &msg, sizeof(MESSAGE));
1377                 }
1378 }
1379
1380
1381 void QKernel::Info()
1382 {
1383         MESSAGE m;
1384
1385         WriteMessage(CharLine);
1386         WriteMessage("### Virtual Machine Information ###");
1387         m.msg_type = MSG_NET;
1388         m.param.pword[0] = NET_GET_INFO;
1389         write(net_sock, &m, sizeof(MESSAGE));
1390         wait_for_info = TRUE;
1391 }
1392
1393 #include "kernel.moc"
1394
1395 int main(int argc, char **argv)
1396 {
1397         int i;
1398         for(i=0; i < 5; i++) {
1399                 strcpy(myargs[i], "");
1400         }
1401         for(i=1; i < argc; i++) {
1402                 strcpy(myargs[i-1], argv[i]);
1403         }
1404
1405         app = new QApplication(argc, argv);
1406         app->setStyle(new QWindowsStyle());
1407         QKernel kernel;
1408         app->setMainWidget(&kernel);
1409         kernel.show();
1410         kernel.InitMessage();
1411         return app->exec();
1412 }