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