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