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