Removed back AppConfiguration class. Postponed its implementation.
[vlp.git] / src / net / lognet.cpp
1 #include "genint1.h"
2 #include "comm.h"
3
4 #include <sys/socket.h>
5 #include <sys/un.h>
6 #include <netinet/in.h>
7 #include <errno.h>
8 #include <netdb.h>
9 #include <arpa/inet.h>
10
11 #include <sys/types.h>
12 #include <sys/time.h>
13 #include <stdlib.h>
14 #include <stdio.h>
15 #include <fcntl.h>
16 #include <signal.h>
17 #include <sys/stat.h>
18 #include <string.h>
19 #include <qlist.h>
20 #include <qfile.h>
21 #include <qstring.h>
22 #include <qstringlist.h>
23 #include <unistd.h>
24
25 #include <libconfig.h>
26
27 #define REMOTE_PATH "REMOTE"
28 #define MAXLINKS 30
29 #define LOGPORT 3600
30 #define CODEPORT 3700
31 #define CODEPORT1 3800
32 #define MAXINTERP 10
33 #define FILE_BUFFER_SIZE 2048
34  
35
36
37 // ************** Interpreter slot *******************
38 class INTlink
39 {
40  public:
41   int sock,ID;
42   bool connected;
43   INTlink();
44
45 };
46
47 INTlink::INTlink()
48 {
49  connected=FALSE;
50  sock=0;
51 }
52
53
54 // ********************  Network slot ********************
55 class NETlink
56 {
57  public:
58  int sock;
59  bool connected,code_transmit;
60  char addr[255];
61
62  int node_number;
63  int aliases[5];
64
65  FILE *CodeFile;
66  char CodeName[255];
67  long CodeSize;
68
69
70  NETlink();
71 };
72
73 NETlink::NETlink()
74 {
75  int i;
76  for(i=0;i<5;i++) aliases[i]=-1;
77  connected=FALSE;
78  sock=0;
79  code_transmit=FALSE;
80 }
81
82
83
84
85 //********************** NET Module ****************************
86
87 class NETMOD
88 {
89 public:
90  int kernel_sock,listen_sock;
91  bool all_connected,local_mode;
92  int to_connect,MyNode;
93  char kername[256];
94
95
96  QList<INTlink> Interpreters; // List of the Interpeter slots
97  QList<NETlink> Links;       //  List of the Network slots
98
99  NETMOD(char*);
100
101  void load_config(char*);    
102  void write_at_console(char*);
103  void send_to_kernel(MESSAGE*);
104  void sock_reopen(NETlink*);
105  void send_connect_info(NETlink*);
106  void send_accept_info(NETlink*);
107  void send_to_node(NETlink*,MESSAGE*);
108  void send_to_int(MESSAGE*);
109  void send_code_ack(NETlink*);
110  void send_to_all(MESSAGE *);
111
112  NETlink *findNETlink(int node);
113  INTlink *findINTlink(int id);
114  void transmit_file(int ton, char *fname, int fromINT);
115  void propagate_msg(MESSAGE *msg);
116  void check_node(int,int);
117
118  void run();
119  void exit_sequence();
120  void disconnect_seq();
121  void connect_seq(char*);
122  void accept_connection();
123  void get_internal();
124  void remote_messages(); 
125  void check_links();
126  void get_message(NETlink*);
127  void conn_info(int);
128
129  void doitall(); // 2010
130 };
131
132
133 NETMOD::NETMOD(char *kernel_name)
134 {
135  int i,len,on;
136  struct sockaddr_in svr;
137  struct sockaddr_un svr1;
138  MESSAGE m;
139  char s[256];
140
141
142  Links.clear();
143  Interpreters.clear();
144
145  bzero(&svr, sizeof(svr)); 
146  listen_sock = socket(AF_INET, SOCK_STREAM, 0);
147  svr.sin_family = AF_INET;
148  svr.sin_addr.s_addr = INADDR_ANY;
149  svr.sin_port = htons(LOGPORT);
150  bind(listen_sock, (struct sockaddr*)&svr, sizeof(svr));
151  listen(listen_sock,5);
152  fcntl(listen_sock, F_SETFL,O_NONBLOCK | fcntl(listen_sock, F_GETFL,0));
153
154  to_connect=0;
155  all_connected=FALSE;
156  load_config("vlp.cfg");
157
158  kernel_sock = socket(AF_UNIX,SOCK_STREAM,0);
159  bzero(&svr1,sizeof(svr1));
160  svr1.sun_family = AF_UNIX;
161  strcpy(svr1.sun_path,kernel_name);
162  strcpy(kername,kernel_name);
163  len = strlen(svr1.sun_path)+sizeof(svr1.sun_family);
164  i = connect(kernel_sock,(struct sockaddr*)&svr1,len);
165  if (i==0)
166  fcntl(kernel_sock,F_SETFL, O_NONBLOCK|fcntl(kernel_sock,F_GETFL,0));
167  on=1;
168  setsockopt(kernel_sock,IPPROTO_TCP,TCP_NODELAY,(char*)&on,sizeof(on));
169  m.msg_type = MSG_NET;
170  m.param.pword[0] = NET_NODE;
171  m.param.pword[1] = MyNode;
172  send_to_kernel(&m);
173
174  // if (regme) regme_sequence();
175
176  if (to_connect > 0){
177  write_at_console("Connecting remote VLPs...");  
178  while (!all_connected) check_links();
179                     }
180  sprintf(s,"Local node number %d",MyNode);
181  write_at_console(s);
182 }
183
184 // #####################  Load configuration ##########################
185
186 void NETMOD::load_config(char *fname)
187 {
188   config_t cfg;
189   const char *str;
190   int on,k=0;
191   NETlink *pomlink;
192
193   config_init(&cfg);
194   
195   
196   /* Hack for checking if file exists without using external libs.*/
197   FILE * file = fopen(fname, "r");
198   if (!file) {
199     fprintf(stderr, "Error: Cannot load configuration file %s!\n", fname);
200     write_at_console("Cannot load configuration file!");
201     fclose(file);
202     exit(3);
203   }
204   
205   /* Read the file. If there is an error, report it and exit. */
206   if(!config_read(&cfg, file)) 
207   {
208     fprintf(stderr, "%s: In file %s, line %d\n",
209         config_error_text(&cfg),
210         config_error_file(&cfg),
211         config_error_line(&cfg));
212     config_destroy(&cfg);
213     fclose(file);
214     exit(3);/* from original code. */
215   }
216   
217   if(config_lookup_int(&cfg, "node_number", &MyNode))
218   {
219     if (MyNode==-1) {
220       write_at_console("Node number must be specified");
221       config_destroy(&cfg);
222       fclose(file);
223       exit(1);
224     };
225   }
226   else
227   {
228     fprintf(stderr, "%s! In file %s, '%s' was not found.\n",
229         "Warning",
230         fname,
231         "node_number");
232     config_destroy(&cfg);
233     fclose(file);
234     exit(1);
235   }
236
237   if(config_lookup_string(&cfg, "host", &str)) {
238     k++;
239     pomlink = new NETlink;
240     strcpy(pomlink->addr, str);
241     pomlink->connected = FALSE;
242     pomlink->sock = socket(AF_INET, SOCK_STREAM, 0); 
243     fcntl(pomlink->sock, F_SETFL,O_NONBLOCK | fcntl(pomlink->sock,F_GETFL,0));
244     on=1; 
245     setsockopt(pomlink->sock,IPPROTO_TCP,TCP_NODELAY,(char*)&on,sizeof(on)); 
246     Links.append(pomlink); 
247     to_connect++;
248   }
249   else {
250     fprintf(stderr, "%s! In file %s, '%s' was not found.\n",
251         "Warning",
252         fname,
253         "host");
254   }
255
256   config_destroy(&cfg);
257   fclose(file);
258
259   if (k==0) all_connected=TRUE;
260 }
261
262
263
264 void NETMOD::write_at_console(char *s)
265 {
266  MESSAGE msg;
267
268  msg.msg_type = MSG_NET;
269  msg.param.pword[0] = NET_CSWRITELN;
270  strcpy(msg.param.pstr,s);
271  send_to_kernel(&msg);
272 }
273
274 void NETMOD::send_to_kernel(MESSAGE *msg)
275 {
276  write(kernel_sock,msg,sizeof(MESSAGE));
277 }
278
279 void NETMOD::send_to_node(NETlink *lnk, MESSAGE *msg)
280 {
281  msg->msg_type = MSG_NET;
282 // msg2netmsg(msg);
283 if (lnk->sock)
284  write(lnk->sock,msg,sizeof(MESSAGE));
285 }
286
287 void NETMOD::send_to_int(MESSAGE *msg)
288 {
289  INTlink *pomlink;
290  
291  pomlink = findINTlink(msg->param.pword[5]);
292  if (pomlink!=NULL) write(pomlink->sock,msg,sizeof(MESSAGE));
293 }
294
295
296
297 void NETMOD::accept_connection()
298 {
299  unsigned int sz;
300  int nsock, on;
301  struct sockaddr_in svr;
302  fd_set rset,wset;
303  struct timeval tout = {0,0};
304  NETlink *pomlink;
305
306  FD_ZERO(&rset);FD_ZERO(&wset);
307  FD_SET(listen_sock,&rset);
308  
309  if (select(listen_sock+1,&rset,&wset,0,(struct timeval *)&tout)>0)
310   if (FD_ISSET(listen_sock,&rset))
311  {
312  
313 /* accept connection on listen socket */
314  sz = sizeof(svr);
315  bzero(&svr, sizeof(svr));
316  nsock = accept(listen_sock, (struct sockaddr*)&svr, &sz);   
317
318  if (nsock>0)
319   {
320     
321    /* i<0 someone wants to connect us */
322       
323        pomlink = new NETlink;
324        strcpy(pomlink->addr,inet_ntoa(svr.sin_addr));
325        pomlink->sock = nsock;
326        pomlink->connected = TRUE;
327        fcntl(pomlink->sock, F_SETFL,O_NONBLOCK | fcntl(pomlink->sock, 
328            F_GETFL,0));
329        on=1;
330        setsockopt(pomlink->sock,IPPROTO_TCP,TCP_NODELAY,(char*)&on,sizeof(on));
331        Links.append(pomlink);
332   } /* nsock > 0 */
333 } /* ISSET */ 
334 }
335
336
337 void NETMOD::check_node(int n, int sc)
338 {
339  MESSAGE m;
340  NETlink *pomlink;
341  
342  m.msg_type = MSG_NET;
343  m.param.pword[0] = NET_NODE_EXIST;
344  
345  pomlink = Links.first();
346  m.param.pword[1] = 0;
347  while (pomlink!=NULL)
348  {
349   if ( pomlink->node_number==n )
350    {
351      m.param.pword[1] = 1;
352      strcpy(m.param.pstr,pomlink->addr);
353      break;
354    }
355   pomlink = Links.next();
356  }
357  write(sc,&m,sizeof(MESSAGE));
358 }
359
360
361 // ************* Internal message from kernel or INT *******************
362
363 void NETMOD::get_internal()
364 {
365  int nr,nrset;
366  MESSAGE msg;
367  int si, sj;
368  fd_set readset,writeset;
369  struct timeval tout={0,0};
370  INTlink *pomlink;
371  struct sockaddr_un svr;
372
373  
374  
375  FD_ZERO(&readset);FD_ZERO(&writeset);
376  FD_SET(kernel_sock,&readset);
377  nrset=kernel_sock;
378
379  pomlink = Interpreters.first();
380  while (pomlink!=NULL)
381  {
382   FD_SET(pomlink->sock,&readset);
383   if (nrset<pomlink->sock) nrset=pomlink->sock;
384   pomlink=Interpreters.next();
385  }
386
387  if (select(nrset+1,&readset,&writeset,0,(struct timeval *)&tout)>0)
388  { 
389  
390 /* Check request sockets */
391  pomlink = Interpreters.first();
392  while (pomlink!=NULL)
393  {
394    if (FD_ISSET(pomlink->sock,&readset))
395    {
396      nr = read(pomlink->sock,&msg,sizeof(MESSAGE));
397      if (nr>0)
398       {
399           if (msg.msg_type == MSG_NET)
400              switch(msg.param.pword[0])
401                {
402                  case NET_PROPAGATE:propagate_msg(&msg);break;
403                  case NET_NODE_EXIST:check_node(msg.param.pword[1],pomlink->sock);break;
404                  case NET_GET_INFO: conn_info(pomlink->sock);break;
405                  case NET_NODES_NUM: msg.param.pword[0]=NET_NODES_NUM_RESPONSE;
406                                      msg.param.pword[1]=Links.count();
407                                      write(pomlink->sock,&msg,sizeof(MESSAGE));
408                                      break; 
409                }/* switch */
410       }
411    } /* ISSET */
412    pomlink=Interpreters.next();
413  } // while
414  
415 /* Check internal socket */
416  if (FD_ISSET(kernel_sock,&readset))
417  {
418   nr = read(kernel_sock, &msg, sizeof(MESSAGE));
419   if (nr>0)
420   {
421    if (msg.msg_type == MSG_NET)
422    {
423      switch(msg.param.pword[0])
424      { 
425        case NET_TRANSMIT_CODE:
426                  transmit_file(msg.param.pword[2],msg.param.pstr,msg.param.pword[1]);  
427                  break;
428        case NET_EXIT: { disconnect_seq();exit_sequence();}
429                    break;
430        case NET_GET_INFO: conn_info(kernel_sock);break;                          
431        case NET_PROPAGATE:propagate_msg(&msg);break;
432        case NET_DISCONNECT:disconnect_seq();
433                    break;            
434        case NET_NODE_EXIST: check_node(msg.param.pword[1],kernel_sock);break;
435        case NET_CONNECT_TO: connect_seq(msg.param.pstr);
436
437         } /* end switch */
438     } /* MSg_NET */
439
440    if (msg.msg_type == MSG_VLP)
441     switch(msg.param.pword[0])
442     {
443      case VLP_REGINT:
444         {
445            pomlink = new INTlink;
446            pomlink->sock = socket(AF_UNIX,SOCK_STREAM,0);
447            bzero(&svr,sizeof(svr));
448            svr.sun_family = AF_UNIX;
449            strcpy(svr.sun_path,msg.param.pstr);
450            si = strlen(svr.sun_path)+sizeof(svr.sun_family);
451            sj = connect(pomlink->sock,(struct sockaddr*)&svr,si);
452            if (sj==0)
453             fcntl(pomlink->sock,F_SETFL, O_NONBLOCK|
454                    fcntl(pomlink->sock,F_GETFL,0));
455            int on=1;
456            setsockopt(pomlink->sock,IPPROTO_TCP,TCP_NODELAY,(char*)&on,sizeof(on));
457            pomlink->ID = msg.param.pword[1];
458            pomlink->connected=TRUE;
459            Interpreters.append(pomlink);
460
461          };break;
462      case VLP_INTERPRETER_DOWN:
463         {
464           pomlink = findINTlink(msg.param.pword[1]);
465           if (pomlink!=NULL)
466           {
467            close(pomlink->sock);
468            Interpreters.remove(pomlink);
469           } 
470          };break;
471             
472      break;
473     } /* MSg_VLP */
474    }
475   }/* ISSET */
476  } /* select >0 */  
477
478
479 }
480
481 void NETMOD::get_message(NETlink *lnk)
482 {
483  int nr;
484  MESSAGE msg;
485  char pomstr[80];
486  int rdbt,rd,sz,j,psock;
487  struct sockaddr_in svr;
488  unsigned char buffer[FILE_BUFFER_SIZE];
489  protdescr proto;
490
491 if (lnk->connected)
492 {
493   nr = read(lnk->sock,&msg, sizeof(MESSAGE));
494   if (nr>0)
495    {
496 //     netmsg2msg(&msg);
497      if (msg.msg_type == MSG_NET)
498       {
499         switch(msg.param.pword[0])
500         {
501          case NET_CCD_START:
502                      
503                      lnk->code_transmit = TRUE;
504                      sprintf(pomstr,"%s/%s",REMOTE_PATH,msg.param.pstr);
505                      strcat(pomstr,".ccd");
506                      lnk->CodeFile = fopen(pomstr,"wb");
507                      if ( lnk->CodeFile == NULL) { write_at_console("Cannot open file\n");
508                      lnk->code_transmit=FALSE;}
509                      lnk->CodeSize=msg.param.pword[1];  
510                      psock = socket(AF_INET, SOCK_STREAM, 0); 
511                      bzero(&svr, sizeof(svr));
512                      svr.sin_family = AF_INET;
513                      svr.sin_port = htons(CODEPORT);
514                      svr.sin_addr.s_addr = inet_addr(lnk->addr);
515                      j = connect(psock, (struct sockaddr*)&svr, sizeof(svr));
516                      if ( j==0) 
517                      {
518                       //fcntl(psock, F_SETFL,O_NONBLOCK | fcntl(psock, F_GETFL,0));
519                        sz=0;
520                        while (sz<lnk->CodeSize)
521                        {
522                          rd = read(psock,&buffer,sizeof(buffer));
523                          rdbt = fwrite(&buffer,sizeof(unsigned char),rd,lnk->CodeFile);
524                          sz=sz+rd; 
525                         }
526                        close(psock);
527                        fclose(lnk->CodeFile);
528                       }
529                      
530                      break;
531
532          case NET_PCD_START:
533                      
534                      lnk->code_transmit = TRUE;
535                      sprintf(pomstr,"%s/%s",REMOTE_PATH,msg.param.pstr);
536                      strcat(pomstr,".pcd");
537                      lnk->CodeFile = fopen(pomstr,"wb");
538                      if ( lnk->CodeFile == NULL) { write_at_console("Cannot open file\n");
539                      lnk->code_transmit=FALSE;}
540                      lnk->CodeSize=msg.param.pword[1];  
541                      psock = socket(AF_INET, SOCK_STREAM, 0); 
542                      bzero(&svr, sizeof(svr));
543                      svr.sin_family = AF_INET;
544                      svr.sin_port = htons(CODEPORT1);
545                      svr.sin_addr.s_addr = inet_addr(lnk->addr);
546                      j = connect(psock, (struct sockaddr*)&svr, sizeof(svr));
547                      if ( j==0) 
548                      {
549                       //fcntl(psock, F_SETFL,O_NONBLOCK | fcntl(psock, F_GETFL,0));
550                        sz=0;
551                        while (sz<lnk->CodeSize)
552                        {
553                          rd = read(psock,&proto,sizeof(proto));
554                          rdbt = fwrite(&proto,sizeof(unsigned char),rd,lnk->CodeFile);
555                          sz=sz+rd; 
556                         }
557                        close(psock);
558                        fclose(lnk->CodeFile);
559                       }
560                      
561                      break;
562
563          case NET_CONNECT:
564                      
565                      sprintf(pomstr,"Node: %d Addr: %s",msg.param.pword[1],
566                      lnk->addr);
567                      lnk->node_number = msg.param.pword[1];
568                      write_at_console(pomstr);
569                      send_accept_info(lnk);
570                      break;
571          case NET_ACCEPT:
572                     
573                     sprintf(pomstr,"Node: %d Addr: %s",msg.param.pword[1],
574                     lnk->addr);
575                     lnk->node_number = msg.param.pword[1];
576                     write_at_console(pomstr);
577                     break;
578          case NET_DISCONNECT:
579                     
580                     sprintf(pomstr,"Node: %d disconnected",msg.param.pword[1]);
581                     write_at_console(pomstr);
582                     ::close(lnk->sock);
583                     Links.remove(lnk);
584                     delete(lnk);
585                     break; 
586          case NET_PROPAGATE:
587                
588                if (msg.param.pword[1] == MSG_VLP) send_to_kernel(&msg);
589                else if (msg.param.pword[1] == MSG_INT) send_to_int(&msg);
590                break;            
591
592                 } /* end switch */
593         
594        }   
595      } /* nr > 0 */
596
597 } /* end if used */
598 }
599
600
601
602 void NETMOD::remote_messages()
603 {
604  int max;
605  fd_set rset,wset;
606  struct timeval tout={0,0};
607  NETlink *pomlink;
608  
609  FD_ZERO(&rset);FD_ZERO(&wset);
610  max=0;
611  
612  pomlink = Links.first();
613  while (pomlink!=NULL)
614  {
615   if (pomlink->connected)
616   {
617     FD_SET(pomlink->sock,&rset);
618     if  (max<pomlink->sock) max=pomlink->sock;
619   }
620   pomlink=Links.next();
621  }
622  
623  if (select(max+1,&rset,&wset,0,(struct timeval *)&tout)>0)
624  {
625   pomlink=Links.first();
626   while (pomlink!=NULL)
627   {
628    if (FD_ISSET(pomlink->sock,&rset)) get_message(pomlink);
629    pomlink=Links.next();
630   }
631  }  
632
633 }
634
635
636 /******************************    2010 ********************************************/
637 void NETMOD::doitall() {
638  unsigned int sz;
639  int nsock,max=0,on, nr, si, sj;
640  struct sockaddr_in svr;
641  fd_set rset;
642  NETlink *pomlink;
643  INTlink *pomlink2;
644  struct sockaddr_un svr2;
645  MESSAGE msg;
646
647
648  FD_ZERO(&rset);
649  FD_SET(listen_sock,&rset);
650  max = listen_sock;
651  FD_SET(kernel_sock,&rset);
652  if (max<kernel_sock) { max=kernel_sock;}
653  pomlink2 = Interpreters.first();
654  while (pomlink2!=NULL)
655  {
656   FD_SET(pomlink2->sock,&rset);
657   if (max<pomlink2->sock) max=pomlink2->sock;
658   pomlink2=Interpreters.next();
659  }
660  pomlink = Links.first();
661  while (pomlink!=NULL)
662  {
663   if (pomlink->connected)
664   {
665     FD_SET(pomlink->sock,&rset);
666     if  (max<pomlink->sock) max=pomlink->sock;
667   }
668   pomlink=Links.next();
669  }
670   
671  // odczyt
672  if (select(max+1,&rset,0,0,NULL) > 0) {
673     // accept connection
674        if (FD_ISSET(listen_sock,&rset))
675         {
676           /* accept connection on listen socket */
677           sz = sizeof(svr);
678           bzero(&svr, sizeof(svr));
679           nsock = accept(listen_sock, (struct sockaddr*)&svr, &sz);   
680           if (nsock>0)
681           {   
682             pomlink = new NETlink;
683             strcpy(pomlink->addr,inet_ntoa(svr.sin_addr));
684             pomlink->sock = nsock;
685             pomlink->connected = TRUE;
686             fcntl(pomlink->sock, F_SETFL,O_NONBLOCK | fcntl(pomlink->sock,F_GETFL,0));
687             on=1;
688             setsockopt(pomlink->sock,IPPROTO_TCP,TCP_NODELAY,(char*)&on,sizeof(on));
689             Links.append(pomlink);
690            } /* nsock > 0 */
691         } /* ISSET */ 
692
693     // get internal message
694        /* Check request sockets */
695        pomlink2 = Interpreters.first();
696        while (pomlink2!=NULL)
697        {
698          if (FD_ISSET(pomlink2->sock,&rset))
699          {
700            nr = read(pomlink2->sock,&msg,sizeof(MESSAGE));
701            if (nr>0)
702            {
703              if (msg.msg_type == MSG_NET)
704                switch(msg.param.pword[0])
705                {
706                  case NET_PROPAGATE:propagate_msg(&msg); break;
707                  case NET_NODE_EXIST:check_node(msg.param.pword[1],pomlink2->sock);break;
708                  case NET_GET_INFO: conn_info(pomlink2->sock);break;
709                  case NET_NODES_NUM: msg.param.pword[0]=NET_NODES_NUM_RESPONSE;
710                                      msg.param.pword[1]=Links.count();
711                                      write(pomlink2->sock,&msg,sizeof(MESSAGE));
712                                      break; 
713                }/* switch */
714            }
715          } /* ISSET */
716          pomlink2=Interpreters.next();
717        } // while
718        /* Check internal socket */
719        if (FD_ISSET(kernel_sock,&rset))
720        {
721           nr = read(kernel_sock, &msg, sizeof(MESSAGE));
722           if (nr>0)
723           {
724             if (msg.msg_type == MSG_NET)
725             {
726               switch(msg.param.pword[0])
727               { 
728                  case NET_TRANSMIT_CODE:
729                  
730                  transmit_file(msg.param.pword[2],msg.param.pstr,msg.param.pword[1]);  
731                  
732                  break;
733                  case NET_EXIT: {  disconnect_seq();exit_sequence();}
734                  break;
735                  case NET_GET_INFO: conn_info(kernel_sock);break;                          
736                  case NET_PROPAGATE:propagate_msg(&msg);break;
737                  case NET_DISCONNECT:disconnect_seq();
738                    break;            
739                  case NET_NODE_EXIST: check_node(msg.param.pword[1],kernel_sock);break;
740                  case NET_CONNECT_TO: connect_seq(msg.param.pstr);
741               } /* end switch */
742             } /* MSG_NET */
743             if (msg.msg_type == MSG_VLP)
744               switch(msg.param.pword[0])
745               {
746                  case VLP_REGINT:
747                  {
748                     
749                     pomlink2 = new INTlink;
750                     pomlink2->sock = socket(AF_UNIX,SOCK_STREAM,0);
751                     bzero(&svr2,sizeof(svr2));
752                     svr2.sun_family = AF_UNIX;
753                     strcpy(svr2.sun_path,msg.param.pstr);
754                     si = strlen(svr2.sun_path)+sizeof(svr2.sun_family);
755                     sj = connect(pomlink2->sock,(struct sockaddr*)&svr2,si);
756                     if (sj==0)
757                       fcntl(pomlink2->sock,F_SETFL, O_NONBLOCK|fcntl(pomlink2->sock,F_GETFL,0));
758                     int on=1;
759                     setsockopt(pomlink2->sock,IPPROTO_TCP,TCP_NODELAY,(char*)&on,sizeof(on));
760                     pomlink2->ID = msg.param.pword[1];
761                     pomlink2->connected=TRUE;
762                     Interpreters.append(pomlink2);
763                     
764                  };break;
765                  case VLP_INTERPRETER_DOWN:
766                  { 
767                    
768                    pomlink2 = findINTlink(msg.param.pword[1]);
769                    if (pomlink2!=NULL)
770                    {
771                      close(pomlink2->sock);
772                      Interpreters.remove(pomlink2);
773                    } 
774                  };break;                       
775               } /* MSg_VLP */
776            } // nr > 0
777        }/* ISSET */
778
779     // get remote message
780
781     pomlink=Links.first();
782     while (pomlink!=NULL)
783     {
784       if (FD_ISSET(pomlink->sock,&rset)) get_message(pomlink);
785       pomlink=Links.next();
786     }
787  } // select 
788
789
790 }
791 /******************************    END 2010 ********************************************/
792
793
794
795 void NETMOD::propagate_msg(MESSAGE *msg)
796 {
797  char ss[255];
798  NETlink *pomlink;
799  
800  pomlink = findNETlink(msg->param.pword[4]);
801  if ((pomlink!=NULL)&&(pomlink->connected))
802   send_to_node(pomlink,msg);
803  else { 
804        if (msg->param.pword[1]==MSG_INT)
805        {
806         send_to_int(msg);
807         }
808        else
809        {
810        sprintf(ss,"Not connected to Node %d",msg->param.pword[4]);  
811        write_at_console(ss);
812        }
813       }      
814
815 }
816
817
818 void NETMOD::connect_seq(char *a)
819 {
820  NETlink *pom;
821  struct sockaddr_in svr;
822  int j,on;
823
824
825  pom=Links.first();
826  while (pom!=NULL)
827  {
828   if (strcmp(pom->addr,a)==0) return;
829   pom=Links.next();
830   }
831      pom = new NETlink;
832      strcpy(pom->addr,a);
833      pom->connected = FALSE;
834      pom->sock = socket(AF_INET, SOCK_STREAM, 0); 
835      bzero(&svr, sizeof(svr));
836      svr.sin_family = AF_INET;
837      svr.sin_port = htons(LOGPORT);
838      svr.sin_addr.s_addr = inet_addr(pom->addr);
839      j = connect(pom->sock, (struct sockaddr*)&svr, sizeof(svr));
840      if ( j==0) 
841           { pom->connected = TRUE;
842            fcntl(pom->sock, F_SETFL,O_NONBLOCK | fcntl(pom->sock, 
843            F_GETFL,0));
844            on=1;
845            setsockopt(pom->sock,IPPROTO_TCP,TCP_NODELAY,(char*)&on,sizeof(on));
846            send_connect_info(pom);
847            Links.append(pom); 
848           }
849       else write_at_console("Connection failed");
850 }
851
852 void NETMOD::check_links()
853 {
854
855 int j=1;
856 struct sockaddr_in svr;
857 NETlink *pomlink;
858
859 /* connect to all other nodes */
860 if (!all_connected)
861 {
862  pomlink=Links.first();
863  while (pomlink!=NULL)
864  {
865  if ( !(pomlink->connected) )
866  {
867    bzero(&svr, sizeof(svr));
868    svr.sin_family = AF_INET;
869    svr.sin_port = htons(LOGPORT);
870    svr.sin_addr.s_addr = inet_addr(pomlink->addr);
871   
872    j = connect(pomlink->sock, (struct sockaddr*)&svr, sizeof(svr));
873    if ( j==0) 
874           { pomlink->connected = TRUE;
875            fcntl(pomlink->sock, F_SETFL,O_NONBLOCK | fcntl(pomlink->sock, 
876            F_GETFL,0));
877            send_connect_info(pomlink);
878
879            }
880    if (errno == ECONNREFUSED) 
881            sock_reopen(pomlink);
882  } // not connected
883   pomlink=Links.next();
884  } //while
885
886 }//if
887 all_connected=TRUE;
888 pomlink=Links.first();
889 while(pomlink!=NULL)
890 {
891  if (pomlink->connected==FALSE) {all_connected=FALSE;break;}
892  pomlink=Links.next();
893 }
894
895 }
896
897 void NETMOD::sock_reopen(NETlink *lnk)
898 {
899  int on=1;
900
901  close(lnk->sock);
902  lnk->sock = socket(AF_INET, SOCK_STREAM, 0); 
903  fcntl(lnk->sock, F_SETFL,O_NONBLOCK | fcntl(lnk->sock, 
904            F_GETFL,0));
905  setsockopt(lnk->sock,IPPROTO_TCP,TCP_NODELAY,(char*)&on,sizeof(on));
906 }
907
908
909 // **************** Acknowledges *************************
910
911 void NETMOD::send_connect_info(NETlink *lnk)
912 {
913  MESSAGE m;
914
915  m.param.pword[0] = NET_CONNECT;
916  m.param.pword[1] = MyNode;
917  m.msg_type = MSG_NET;
918 // msg2netmsg(&m);
919  if (lnk->sock)
920  write(lnk->sock,&m,sizeof(MESSAGE));
921 }
922
923 void NETMOD::send_accept_info(NETlink *lnk)
924 {
925  MESSAGE m;
926
927  m.param.pword[0] = NET_ACCEPT;
928  m.param.pword[1] = MyNode;
929  m.msg_type = MSG_NET;
930 // msg2netmsg(&m);
931  if (lnk->sock)
932  write(lnk->sock,&m,sizeof(MESSAGE));
933 }
934
935 void NETMOD::send_code_ack(NETlink *lnk)
936 {
937 MESSAGE m;
938
939  m.param.pword[0] = NET_CODESTREAM_OK;
940  m.msg_type = MSG_NET;
941 // msg2netmsg(&m);
942  if (lnk->sock)
943  write(lnk->sock,&m,sizeof(MESSAGE));
944 }
945
946
947 void NETMOD::send_to_all(MESSAGE *msg)
948 {
949  NETlink *pomlink;
950  pomlink=Links.first();
951  while (pomlink!=NULL)
952  {
953   write(pomlink->sock,msg,sizeof(MESSAGE));
954   pomlink=Links.next();
955  }
956 }
957
958
959
960
961 void NETMOD::run()
962 {
963   while(1)
964  {
965   /*accept_connection();
966   get_internal();
967   remote_messages(); */
968   // 2010
969   doitall();
970  }
971 }
972
973 void NETMOD::exit_sequence()
974 {
975  NETlink *pomlink;
976
977  ::close(kernel_sock);
978  ::close(listen_sock);
979  unlink(kername);
980  pomlink = Links.first();
981  while (pomlink!=NULL)
982  {
983   ::close(pomlink->sock);
984   pomlink=Links.next();
985   }
986  exit(0);
987 }
988
989 void NETMOD::disconnect_seq()
990 {
991  MESSAGE m;
992  NETlink *p;
993
994  bzero(&m,sizeof(MESSAGE));
995  m.msg_type = MSG_NET;
996  m.param.pword[0] = NET_DISCONNECT;
997  m.param.pword[1] = MyNode;
998
999  p=Links.first();
1000  while(p!=NULL)
1001  {
1002   send_to_node(p,&m);
1003   p=Links.next();
1004  }
1005  p=Links.first();
1006  while(p!=NULL)
1007  {
1008   ::close(p->sock);
1009   p=Links.next();
1010  }
1011  Links.clear();
1012 }
1013
1014 NETlink *NETMOD::findNETlink(int node)
1015 {
1016  NETlink *pomlink;
1017  pomlink=Links.first();
1018  while(pomlink!=NULL)
1019  {
1020   if (pomlink->node_number == node) return(pomlink);
1021   pomlink=Links.next();
1022  } 
1023  return(pomlink);
1024 }
1025
1026 INTlink *NETMOD::findINTlink(int id)
1027 {
1028  INTlink *pomlink;
1029  pomlink=Interpreters.first();
1030  while(pomlink!=NULL)
1031  {
1032   if (pomlink->ID == id) return(pomlink);
1033   pomlink=Interpreters.next();
1034  } 
1035  return(pomlink);
1036 }
1037
1038
1039 /* ----------------    Sending code to a remote node -------------- */
1040
1041 void NETMOD::transmit_file(int ton, char *fname, int fromINT)
1042 {
1043  FILE *f;
1044  MESSAGE msg;
1045  char fn[80];
1046  char b[255];
1047  unsigned char buffer[FILE_BUFFER_SIZE];
1048  protdescr proto;
1049  int i,tsock,sock;
1050  unsigned int sz;
1051  NETlink *outlink;
1052  struct sockaddr_in svr;
1053  fd_set rset,wset;
1054
1055
1056 // **************** CCD FILE
1057
1058  strcpy(fn,fname);
1059  strcat(fn,".ccd");
1060  f = fopen(fn,"rb");
1061  if (f!=NULL)
1062  {
1063  fseek(f,0,SEEK_END);
1064  msg.param.pword[1] = ftell(f);
1065  fclose(f);
1066  f = fopen(fn,"rb");
1067  
1068  strcpy(b,rindex(fname,'/'));
1069  for(i=0;i<strlen(b);i++)
1070    b[i] = b[i+1];
1071  msg.param.pword[0] = NET_CCD_START;
1072  strcpy(msg.param.pstr,b);
1073
1074  outlink = findNETlink(ton);
1075  if (outlink==NULL) exit(1);
1076  bzero(&svr,sizeof(svr));
1077  sock = socket(AF_INET,SOCK_STREAM,0);
1078  svr.sin_family = AF_INET;
1079  svr.sin_addr.s_addr = INADDR_ANY;
1080  svr.sin_port = htons(CODEPORT);
1081  bind(sock, (struct sockaddr*)&svr, sizeof(svr));
1082  listen(sock,5);   
1083  send_to_node(outlink, &msg);
1084  sz=sizeof(svr);
1085  FD_ZERO(&rset);FD_ZERO(&wset);
1086  FD_SET(sock,&rset);
1087  if (select(sock+1,&rset,&wset,0,0))
1088   if (FD_ISSET(sock,&rset))
1089     tsock = accept(sock, (struct sockaddr*)&svr,&sz );
1090  if (tsock>0)
1091  {
1092   close(sock);
1093   while (!feof(f))
1094    {
1095     i = fread(&buffer,1,sizeof(buffer),f);
1096     write(tsock,&buffer,i);
1097     FD_ZERO(&rset);FD_ZERO(&wset);
1098     FD_SET(tsock,&wset);
1099     select(tsock+1,&rset,&wset,0,0);
1100     }
1101   close(tsock);
1102  }
1103  fclose(f);
1104  } // f!=NULL
1105   else
1106      {
1107     sprintf(b,"Cannot open file to send %s\n",fname);
1108     write_at_console(b);
1109    }
1110
1111
1112 // *************** PCD FILE
1113  
1114  strcpy(fn,fname);
1115  strcat(fn,".pcd");
1116  f = fopen(fn,"r");
1117   if (f!=NULL)
1118  {
1119  fseek(f,0,SEEK_END);
1120  msg.param.pword[1] = ftell(f);
1121  fclose(f);
1122  f = fopen(fn,"rb");
1123  
1124  strcpy(b,rindex(fname,'/'));
1125  for(i=0;i<strlen(b);i++)
1126    b[i] = b[i+1];
1127  msg.param.pword[0] = NET_PCD_START;
1128  strcpy(msg.param.pstr,b);
1129
1130  outlink = findNETlink(ton);
1131  if (outlink==NULL) exit(1);
1132  bzero(&svr,sizeof(svr));
1133  sock = socket(AF_INET,SOCK_STREAM,0);
1134  svr.sin_family = AF_INET;
1135  svr.sin_addr.s_addr = INADDR_ANY;
1136  svr.sin_port = htons(CODEPORT1);
1137  bind(sock, (struct sockaddr*)&svr, sizeof(svr));
1138  listen(sock,5);   
1139  send_to_node(outlink, &msg);
1140  sz=sizeof(svr);
1141  FD_ZERO(&rset);FD_ZERO(&wset);
1142  FD_SET(sock,&rset);
1143  if (select(sock+1,&rset,&wset,0,0))
1144   if (FD_ISSET(sock,&rset))
1145     tsock = accept(sock, (struct sockaddr*)&svr,&sz );
1146  if (tsock>0)
1147  {
1148   close(sock);
1149   while (!feof(f))
1150    {
1151     i = fread(&proto,1,sizeof(proto),f);
1152     write(tsock,&proto,i);
1153     FD_ZERO(&rset);FD_ZERO(&wset);
1154     FD_SET(tsock,&wset);
1155     select(tsock+1,&rset,&wset,0,0);
1156     }
1157   close(tsock);
1158  }
1159  fclose(f);
1160  } // f!=NULL
1161   else
1162    {
1163     sprintf(b,"Cannot open file to send %s\n",fname);
1164     write_at_console(b);
1165    }
1166  
1167
1168  msg.msg_type = MSG_NET; 
1169  msg.param.pword[0] = NET_TRANSMITTED;
1170  msg.param.pword[1] = fromINT;
1171  send_to_kernel(&msg);
1172  
1173
1174 }
1175
1176
1177
1178 void NETMOD::conn_info(int sk)
1179 {
1180  NETlink *pom;
1181  MESSAGE m;
1182  int k=0;
1183  char poms[255];
1184
1185  m.msg_type = MSG_NET;
1186  m.param.pword[0] = NET_INFO;
1187  strcpy(m.param.pstr,"");
1188  pom=Links.first();
1189  while (pom!=NULL)
1190  {
1191   sprintf(poms,"%d=%s;",pom->node_number,pom->addr);
1192   strcat(m.param.pstr,poms);
1193   k++;
1194   if (k==12)
1195   {
1196     m.param.pword[1]=12;
1197     write(sk,&m,sizeof(MESSAGE));
1198     k=0;
1199    }
1200   pom=Links.next();
1201  }
1202  if (k>0)
1203   {
1204    m.param.pword[1]=k;
1205    write(sk,&m,sizeof(MESSAGE));
1206    }
1207   m.msg_type = MSG_NET;
1208   m.param.pword[0] = NET_INFO_END;
1209   write(sk,&m,sizeof(MESSAGE));
1210 }
1211
1212 int main(int argc,char **argv)
1213 {
1214  NETMOD netter(argv[1]);
1215  netter.run();
1216  return 0;
1217 }