1 /**************************************************************
3 Copyright (C) 1997 Oskar Swida
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License
7 as published by the Free Software Foundation; either version 2
8 of the License, or (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 NOTE: This software is using the free software license of
23 the QT library v.1.30 from Troll Tech AS.
24 See the file LICENSE.QT.
27 To contact the author, write:
28 e-mail: swida@aragorn.pb.bialystok.pl
30 ************************************************************/
34 //#include <qwindow.h>
62 #include <qwindowsstyle.h>
72 #include <netinet/in.h>
74 #include <libconfig.h>
79 #define REMOTE_PATH "REMOTE"
81 #define MAXINSTANCES 256
89 char CharLine[25]="________________________";
93 /* --------------- interpreter slot -----------------*/
96 int ID; // INT identifier
97 bool remote; // Am I remote ?
98 char fullname[255],shortname[255]; // Program name
100 QSocketNotifier *notify;
101 int RInstances[MAXINSTANCES]; // IDs of my remote INT modules
102 ctx_struct p_ctx; // parent INT info
104 /*++++++++++++++++++++++++++++++++++++++++++*/
106 /*----------------- connection slot -------------*/
110 ConnectEntry(char *s) {strcpy(addr,s);};
113 /* ++++++++++++++++++++++++++++++++++++++++++ */
118 /* ---------------------------------------------------------- */
119 /* KERNEL CLASS DEFINITION */
120 /* ---------------------------------------------------------- */
122 class QKernel : public QFrame {
125 QMultiLineEdit *desktop;
127 QPopupMenu *p,*p1,*p2;
129 int NodeNumber,ConType;
133 virtual void resizeEvent( QResizeEvent *ev );
135 void WriteMessage(char* msg);
147 void UnlockConsole();
148 void MessageToNode();
151 void IntMessage(int);
152 void KillInterpreter();
159 virtual void closeEvent ( QCloseEvent * e );
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;
169 int lockid,unlockid,qid,cwid,
170 optid,prid,mid,msgid,toolsid,hid;
173 QSocketNotifier *Net_Notify;
177 void LoadConfig(char *);
178 void RunGraphModule(char*);
180 InterpEntry *findINTbySocket(int);
181 InterpEntry *findINTbyID(int);
182 InterpEntry *RunIntModule(char *ss,int r);
183 void RemoteInstance(InterpEntry*,int);
184 void CloseInstances(InterpEntry*);
186 /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
188 void QKernel::closeEvent ( QCloseEvent * e )
195 QFont f("Helvetica",10,QFont::Bold);
196 QFont f1("Helvetica",10,QFont::Normal);
197 QFont f2("Times Roman",10,QFont::Normal);
202 sprintf(ss,"mkdir %s",REMOTE_PATH);
209 setCaption("Virtual LOGLAN Processor");
210 setBackgroundColor(white);
212 bar = new QMenuBar(this);
214 p = new QPopupMenu();
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()));
226 mid = bar->insertItem("&Machine",p1);
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);
241 toolsid = bar->insertItem("&Tools",p2);
243 qid = bar->insertItem("&Quit",this,SLOT(QuitProc()));
246 desktop = new QMultiLineEdit(this,"desktop");
247 desktop->setAutoUpdate(TRUE);
248 desktop->setReadOnly(TRUE);
249 desktop->setFont(f1);
254 ActiveConnections = 0;
255 strcpy(LockPasswd,"");
256 LoadConfig("vlp.cfg");
259 Net_Notify = new QSocketNotifier(net_sock,QSocketNotifier::Read,this);
260 connect(Net_Notify,SIGNAL(activated(int)),this,SLOT(NetMessage()));
263 void QKernel::resizeEvent( QResizeEvent *ev )
265 QFrame::resizeEvent(ev);
267 desktop->setGeometry(0, bar->height(), width(), height() - bar->height());
270 void QKernel::n_impl()
272 QMessageBox::information(this,"Function info","This function is not implemented yet...","Ok");
276 /* ########### load configuration from file ############# */
278 void QKernel::LoadConfig(char * fname)
281 config_setting_t *setting;
284 /* Hack for checking if file exists without using external libs.*/
285 FILE * file = fopen(fname, "rt");
287 fprintf(stderr, "Error: Cannot load configuration file %s!\n", fname);
290 /* File exists, so file has been locked. Release it. */
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);
302 exit(3);/* from original code. */
305 setting = config_lookup(&cfg, "node_number");
307 NodeNumber = config_setting_get_int(setting);
309 fprintf(stderr, "%s! In file %s, '%s' was not found.\n",
313 config_destroy(&cfg);
318 setting = config_lookup(&cfg, "type");
320 ConType = (strcmp(config_setting_get_string(setting), "explicit") == 0) ? 1 : 2;
322 fprintf(stderr, "%s! In file %s, '%s' was not found.\n",
328 setting = config_lookup(&cfg, "host");
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)));
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)));
340 fprintf(stderr, "%s! In file %s, bad entry type for %s. Will not be read.\n",
346 fprintf(stderr, "%s! In file %s, '%s' was not found.\n",
352 setting = config_lookup(&cfg, "progdir");
354 strncpy(progdir, config_setting_get_string(setting), 256);
356 fprintf(stderr, "%s! In file %s, '%s' was not found.\n",
362 setting = config_lookup(&cfg, "homedir");
364 strncpy(HomeDir, config_setting_get_string(setting), 255);
366 fprintf(stderr, "%s! In file %s, '%s' was not found.\n",
372 config_destroy(&cfg);
375 /* +++++++++++++++++++++++++++++++++++++++++++++++ */
377 void QKernel::Run_Prog()
380 QString s(QFileDialog::getOpenFileName(progdir, "*.log", this));
388 RunIntModule((char*)s.ascii(),0);
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]);
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]);
410 void QKernel::RunGraphModule(char *sk)
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]);
419 WriteMessage("Cannot connect GRAPH resources");
424 void QKernel::RunNetModule()
426 struct sockaddr_un svr;
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]);
434 /* -------- socket for NET module -------- */
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);
444 if(system(cmd) == 0) {
445 net_sock = accept(sock,(struct sockaddr*)0,(unsigned int*)0);
448 WriteMessage("NETWORK successfully connected");
449 fcntl(net_sock,F_SETFL, O_NONBLOCK|fcntl(net_sock,F_GETFL,0));
451 setsockopt(net_sock,IPPROTO_TCP,TCP_NODELAY,(char*)&on,sizeof(on));
453 WriteMessage("Cannot connect NETWORK resources");
454 WriteMessage("Exiting...");
460 WriteMessage("Cannot connect NETWORK resources");
461 WriteMessage("Exiting...");
467 void QKernel::Connect()
469 QDialog d(this,"",TRUE);
470 QLabel lab(&d,"IP Address:");
472 QPushButton ob(&d,""),cb(&d,"");
475 d.setFont(QFont("Helvetica",12,QFont::Bold));
476 ob.setGeometry( 30, 60, 80, 30 );
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 );
486 connect(&ob,SIGNAL(clicked()),&d,SLOT(accept()));
487 connect(&cb,SIGNAL(clicked()),&d,SLOT(reject()));
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));
496 void QKernel::Disconnect()
501 WriteMessage("Disconnecting from virtual machine");
503 msg.msg_type = MSG_NET;
504 msg.param.pword[0] = NET_DISCONNECT;
505 write(net_sock, &msg, sizeof(MESSAGE));
508 void QKernel::QuitProc()
512 if (QMessageBox::question(this,"Close VLP","Terminate VLP ?",QMessageBox::Yes,QMessageBox::No,0) == QMessageBox::No )
517 msg.msg_type = MSG_NET;
518 msg.param.pword[0] = NET_DISCONNECT;
519 write(net_sock,&msg,sizeof(MESSAGE));*/
522 msg.msg_type = MSG_NET;
523 msg.param.pword[0] = NET_EXIT;
524 write(net_sock,&msg,sizeof(MESSAGE));
525 /* ::close(net_sock);*/
531 void QKernel::AddAddress()
533 QDialog d(this,"",TRUE);
534 QLabel lab(&d,"IP Address:");
536 QPushButton ob(&d,""),cb(&d,"");
539 ob.setGeometry( 30, 60, 80, 30 );
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()));
551 if (strcmp(ed.text(),"")!=0) {
552 connections->insertItem(ed.text());
557 void QKernel::DelAddress()
560 if(connections->currentItem() != -1)
561 connections->removeItem(connections->currentItem());
565 void QKernel::MessageToNode()
571 dlg = new QDialog(this,"Message",TRUE);
573 nodenr = new QLineEdit(dlg,"number");
574 nodenr->setGeometry( 90, 10, 50, 30 );
578 tmpQLabel = new QLabel( dlg, "Label_1" );
579 tmpQLabel->setGeometry( 10, 10, 77, 30 );
580 tmpQLabel->setText( "Node number:" );
582 tmpQLabel = new QLabel( dlg, "Label_2" );
583 tmpQLabel->setGeometry( 10, 50, 70, 30 );
584 tmpQLabel->setText( "Message:" );
587 msg = new QLineEdit( dlg, "LineEdit_1" );
588 msg->setGeometry( 80, 60, 330, 30 );
592 ob = new QPushButton( dlg, "PushButton_1" );
593 ob->setGeometry(230, 10, 80, 30 );
595 ob->setDefault(TRUE);
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");
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));
618 void QKernel::KillInterpreter()
625 dlg = new QDialog(this,"Message",TRUE);
627 nodenr = new QLineEdit(dlg,"number");
628 nodenr->setGeometry( 90, 10, 50, 30 );
632 tmpQLabel = new QLabel( dlg, "Label_1" );
633 tmpQLabel->setGeometry( 10, 10, 77, 30 );
634 tmpQLabel->setText( "Interp. ID:" );
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");
648 m.msg_type = MSG_INT;
649 m.param.pword[0] = INT_KILL;
650 pom = findINTbyID(atoi(nodenr->text()));
653 write(pom->sock,&m,sizeof(MESSAGE));
654 else WriteMessage("This is a remote instance of a program!");
657 WriteMessage("Interpreter not found");
664 void QKernel::NetMessage()
671 cnt = read(net_sock, &msg, sizeof(MESSAGE));
672 if((cnt > 0) && (msg.msg_type == MSG_NET)) {
673 switch(msg.param.pword[0]) {
675 WriteMessage(msg.param.pstr);
678 switch(msg.param.pword[1]) {
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);*/
686 switch(msg.param.pword[6]) {
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);
693 WriteMessage(CharLine);
695 case VLP_REMOTE_INSTANCE:
696 sprintf(ss,"%s/%s",REMOTE_PATH,msg.param.pstr);
698 WriteMessage("Running program:");
701 pom = RunIntModule(ss,1);
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];
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]);
713 write(pom->sock,&msg,sizeof(MESSAGE));
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));
720 WriteMessage("Instance not found");
726 case NET_CONNECTIONS: ActiveConnections = msg.param.pword[1];
727 WriteMessage(msg.param.pstr);
733 QString poms,poms1,poms2;
734 poms.sprintf("%s",msg.param.pstr);
735 while (poms.length()>0) {
738 poms1=poms.left(cnt);
739 poms=poms.right(poms.length()-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());
753 WriteMessage(CharLine);
759 void QKernel::IntMessage(int sock)
765 cnt = read(sock,&msg,sizeof(MESSAGE));
766 e = findINTbySocket(sock);
767 if ((cnt > 0) && (e != NULL)) {
768 switch (msg.msg_type) {
770 if (msg.param.pword[0] == GRAPH_ALLOCATE) {
771 RunGraphModule(msg.param.pstr);
775 write(net_sock, &msg, sizeof(MESSAGE));
778 switch(msg.param.pword[0]) {
779 case VLP_REMOTE_INSTANCE_PLEASE:
780 RemoteInstance(e,msg.param.pword[2]);
785 switch(msg.param.pword[0]) {
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));
798 Interpreters.remove(e);
801 sprintf(ss,"%s : End of program execution",msg.param.pstr);
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;
811 msg.param.pword[3] = e->p_ctx.node;
812 msg.param.pword[4] = e->p_ctx.program_id;
814 write(sock, &msg, sizeof(MESSAGE));
817 break; /* switch param.pword[0] */
822 void QKernel::WriteMessage(char *msg)
827 desktop->getCursorPosition(&x,&y);
832 desktop->setReadOnly(FALSE);
833 desktop->append(msg);
834 desktop->setReadOnly(TRUE);
835 desktop->setCursorPosition(desktop->numLines(),1);
838 if (desktop->numLines()>100) {
843 void QKernel::SetMessages()
846 if (p2->isItemChecked(msgid)) {
847 p2->setItemChecked(msgid,FALSE);
850 p2->setItemChecked(msgid,TRUE);
854 /* bar->repaint(); */
857 void QKernel::SetOptions()
859 QDialog dlg(this,"Options",TRUE);
864 progs = new QLineEdit( &dlg, "progs" );
865 progs->setGeometry( 150, 20, 180, 30 );
866 progs->setText(progdir);
869 tmpQLabel = new QLabel( &dlg, "Label_1" );
870 tmpQLabel->setGeometry( 30, 20, 120, 30 );
871 tmpQLabel->setText( "Programs directory" );
874 tmpQFrame = new QFrame( &dlg, "Frame_2" );
875 tmpQFrame->setGeometry( 10, 60, 380, 30 );
876 tmpQFrame->setFrameStyle( 52 );
878 tmpQLabel = new QLabel( &dlg, "Label_2" );
879 tmpQLabel->setGeometry( 10, 80, 340, 30 );
880 tmpQLabel->setText( "Virtual Processor properties (activated after restarting VLP):" );
884 nn = new QLineEdit( &dlg, "LineEdit_2" );
885 nn->setGeometry( 110, 110, 40, 30 );
886 sprintf(nns,"%d",NodeNumber);
889 tmpQLabel = new QLabel( &dlg, "Label_3" );
890 tmpQLabel->setGeometry( 20, 110, 90, 30 );
891 tmpQLabel->setText( "Node number:" );
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 );
899 reg = new QRadioButton( &dlg, "RadioButton_4" );
900 reg->setGeometry( 30, 200, 100, 30 );
901 reg->setText( "Registration" );
902 reg->setEnabled(FALSE);
904 connections = new QListBox( &dlg, "ListBox_1" );
905 connections->setGeometry( 170, 140, 130, 100 );
906 e = ConnectList.first();
908 connections->insertItem(e->addr);
909 e = ConnectList.next();
912 tmpQLabel = new QLabel( &dlg, "Label_5" );
913 tmpQLabel->setGeometry( 170, 110, 100, 30 );
914 tmpQLabel->setText( "Connection list:" );
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()));
935 group = new QButtonGroup( &dlg, "ButtonGroup_1" );
936 group->setGeometry( 20, 150, 120, 90 );
937 group->setTitle( "Connection type" );
938 group->setAlignment( 1 );
940 group->insert(exp,1);
941 group->insert(reg,2);
943 dlg.resize( 400, 310 );
946 config_setting_t *root, *setting;
949 root = config_root_setting(&cfg);
951 setting = config_setting_add(root, "progdir", CONFIG_TYPE_STRING);
952 config_setting_set_string(setting, progs->text().ascii());
953 strcpy(progdir,progs->text());
955 setting = config_setting_add(root, "node_number", CONFIG_TYPE_INT);
956 config_setting_set_int(setting, atoi(nn->text()));
958 setting = config_setting_add(root, "homedir", CONFIG_TYPE_STRING);
959 config_setting_set_string(setting, HomeDir);
961 setting = config_setting_add(root, "type", CONFIG_TYPE_STRING);
962 if (exp->isChecked()) {
963 config_setting_set_string(setting, "explicit");
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());
972 config_setting_set_string(setting, "register");
975 if(!config_write_file(&cfg, "vlp.cfg")) {
976 fprintf(stderr, "Error while writing to file: %s.\n", "vlp.cfg");
978 config_destroy(&cfg);
982 void QKernel::LockConsole()
984 QDialog d(this,"Enter password",TRUE);
985 QLabel lab(&d,"Password");
987 QPushButton ob(&d,""),cb(&d,"");
989 d.setCaption("Lock console");
990 ob.setGeometry( 30, 60, 80, 30 );
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()));
1004 if (strcmp(ed.text(),"")!=0) {
1005 strcpy(LockPasswd,ed.text());
1006 lab.setText("Retype:");
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);
1018 WriteMessage("CONSOLE LOCKED");
1021 QMessageBox msg(this);
1022 msg.setText("Not matching!");
1023 msg.setButtonText(0,"Close");
1027 strcpy(LockPasswd,"");
1033 void QKernel::UnlockConsole()
1035 QDialog d(this,"Enter password",TRUE);
1036 QLabel lab(&d,"Password");
1037 QLineEdit ed(&d,"");
1038 QPushButton ob(&d,""),cb(&d,"");
1040 ob.setGeometry( 30, 60, 80, 30 );
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()));
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);
1063 WriteMessage("CONSOLE UNLOCKED");
1066 QMessageBox msg(this);
1067 msg.setText("Wrong password!");
1068 msg.setButtonText(0,"Close");
1074 void QKernel::InitMessage()
1076 WriteMessage("\n Virtual LOGLAN Processor - ver 1.9: READY \n");
1081 InterpEntry *QKernel::findINTbySocket(int _id)
1084 pom = Interpreters.first();
1086 while (pom != NULL) {
1087 if (pom->sock == _id)
1090 pom = Interpreters.next();
1095 InterpEntry *QKernel::findINTbyID(int _id)
1098 pom = Interpreters.first();
1099 while (pom != NULL) {
1102 pom = Interpreters.next();
1108 /* ------------------ Connect INT module -----------------*/
1110 InterpEntry *QKernel::RunIntModule(char *ss, int r)
1113 struct sockaddr_un svr;
1119 InterpEntry *newINT;
1128 if (cf == NULL) {WriteMessage("File not found: no .ccd file");return(NULL);}
1134 if (cf == NULL) {WriteMessage("File not found: no .pcd file");return(NULL);}
1137 newINT = new InterpEntry;
1138 for(i=0;i<MAXINSTANCES;i++) newINT->RInstances[i]=-1;
1140 strcpy(b,rindex(ss,'/'));
1141 for(i=0;i<strlen(b);i++)
1145 sprintf(a,"%s : Start execution",b);
1149 newint = freeINTid; freeINTid++;
1150 newINT->ID = newint;
1151 strcpy(newINT->shortname,b);
1152 strcpy(newINT->fullname,ss);
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]);
1162 sock = socket(AF_UNIX,SOCK_STREAM,0);
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);
1171 newINT->sock = accept(sock,(struct sockaddr*)0,(unsigned int *)0);
1178 fcntl(newINT->sock,F_SETFL,
1179 O_NONBLOCK|fcntl(newINT->sock,F_GETFL,0));
1181 setsockopt(newINT->sock,IPPROTO_TCP,TCP_NODELAY,(char*)&on,sizeof(on));
1182 if (r) newINT->remote = 1;else newINT->remote=0;
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));
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");
1197 else WriteMessage("Cannot connect interpreter");
1203 /* ---------------------------------------------------------*/
1204 /* Allocate remote instance */
1206 void QKernel::RemoteInstance(InterpEntry *interp, int on)
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));
1221 if (m.param.pword[1]==1) /* means node exists */
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));
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));
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));
1247 read(net_sock,&m,sizeof(MESSAGE));
1250 if ( (m.param.pword[0]==NET_PROPAGATE) && (m.param.pword[6] == VLP_REMOTE_INSTANCE_OK))
1252 interp->RInstances[on] = m.param.pword[7];
1255 read(net_sock,&m,sizeof(MESSAGE));
1258 Net_Notify->setEnabled(TRUE);
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));
1266 else /* There is no such a node! */
1268 sprintf(s,"Warning: Node number %d not found!",on);
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));
1280 /*-----------------------------------------------*/
1281 /* Close all remote instances */
1283 void QKernel::CloseInstances(InterpEntry *e)
1289 WriteMessage("Closing remote instances");
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));
1305 void QKernel::Info()
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;
1317 #include "kernel.moc"
1319 int main( int argc, char **argv )
1322 for(i=0; i < 5; i++) {
1323 strcpy(myargs[i],"");
1325 for(i=1; i < argc; i++) {
1326 strcpy(myargs[i-1],argv[i]);
1329 app = new QApplication(argc, argv);
1330 app->setStyle(new QWindowsStyle());
1332 app->setMainWidget(&kernel);