03bc54642800052ba2b18b3730f21149699756a3
[vlp.git] / src / int / cint.c
1 #include "depend.h"
2 #include "genint.h"
3 #include "int.h"
4 #include "process.h"
5 #include "intproto.h"
6 #include "socu.h"
7 #include <fcntl.h>
8 #include <sys/stat.h>
9 #include <sys/time.h>
10 #include <netinet/in.h>
11 #include <arpa/inet.h>
12 #include <errno.h>
13 #include <netdb.h>
14 // #include <qthread.h>
15
16 #ifndef NO_PROTOTYPES
17 static void load(char *);
18 static void initiate(int,char **);
19 int main(int,char **);
20 #else
21 static void load();
22 static void initiate();
23 int main();
24 #endif
25
26 /**
27  * @file
28  * @brief Compiler and interpreter code
29  */
30
31 int internal_sock, graph_sock, net_sock, connected = 0;
32 struct sockaddr_un svr;
33 int GraphRes=-1;
34 char ProgName[255], mygname[80], gname[80], mykname[80], nname[80], mynname[80];
35 fd_set DirSet;
36 int maxDirSet;
37
38 ctx_struct my_ctx;
39 ctx_struct parent_ctx;
40
41 /**
42  * IDs of remote instances
43  */
44 int RInstance[255];
45
46 /**
47  * Direct connection channels
48  */
49 int DirConn[255];
50
51 /**
52  * Graphic variables
53  */
54 int fcol, bcol, curx=0, cury=0;
55
56
57 /**
58  * Macro to decode addressing modes:
59  */
60 #define getargument(a, argnr)                                       \
61     switch (eop->args[ argnr ])                                     \
62     {                                                               \
63         case GLOBAL     : a = M[ ic++ ];             break;         \
64         case LOCAL      : a = c1+M[ ic++ ];          break;         \
65         case TEMPLOCAL  : a = c2+M[ ic++ ];          break;         \
66         case REMOTE     : a = M[ M[ ic+1 ] ]+M[ ic ];  ic+=2; break;\
67         case INDIRECT   : a = M[ M[ ic++ ] ];                 break;\
68         case IMMEDIATE  : a = ic++;                           break;\
69         case CONSTANT  : a = M[ ic++ ];                       break;\
70         case DOTACCESS : a = M[ display+M[ ic+1 ] ]+M[ ic ];  ic += 2; break;\
71         case NOARGUMENT : return;                          \
72     }
73
74 /**
75  * Loads code and prototypes from files
76  * Files have following extensions:
77  * .ccd - compiler code
78  * .pcd - program code
79  * .trd - traced debug
80  * @param _filename Filename of file to read.
81  */
82 static void load(char *_filename)
83 {
84         FILE *fp;
85         char *cp;
86         word n, left;
87         /* should suffice on all systems */
88         char filename[100];
89
90         strcpy(filename, _filename);
91         /* allocate main memory array */
92         M = mallocate(memorysize + 1);
93         if (M == NULL)
94                 abend("Memory size too large (use /m option)\n");
95
96         addext(filename, ".ccd");
97         if ((fp = fopen(filename, BINARYREAD)) == NULL) {
98                 fprintf(stderr, "Cannot open .ccd file\n");
99                 endrun(10);
100         };
101
102         /* read static data and code from .ccd file */
103         ic = 0;
104         left = memorysize + 1;
105         do {
106                 if (left == 0)
107                         abend("Memory size too small (use /m option)\n");
108                 n = min(IOBLOCK / sizeof(word), left);
109                 n = fread((char *) &M[ ic ], sizeof(word), (int) n, fp);
110                 ic += n;
111                 left -= n;
112         } while (n != 0);
113         /* now ic = number of words read */
114
115         fclose(fp);
116         
117         /* Get various addresses passed by GENERATOR */
118         
119         /* primitive type desctriptions */
120         ipradr = M[ic - 5];
121         /* global temporary variables */
122         temporary = M[ic - 4];
123         /* string constants */
124         strings = M[ic - 3];
125         /* last prototype number */
126         lastprot = M[ic - 2];
127         /* first free word in memory */
128         freem = M[ic - 1];
129
130         /* Read prototypes from .pcd file */
131         addext(filename, ".pcd");
132         if ((fp = fopen(filename, BINARYREAD)) == NULL) {
133                 fprintf(stderr,"Cannot open .pcd file\n");
134                 endrun(10); 
135         }
136         for (n = MAINBLOCK; n <= lastprot; n++) {
137                 cp = ballocate(sizeof(protdescr));
138                 if (cp == NULL)
139                         abend("Memory size too large (use /m option)\n");
140                 prototype[n] = (protdescr *) cp;
141
142                 if (fread(cp, sizeof(protdescr), 1, fp) != 1)
143                         abend("Cannot read .pcd file\n");
144         }
145         fclose(fp);
146
147         /* Open trace file */
148         if (debug) {
149                 addext(filename, ".trd");
150                 if ((tracefile = fopen(filename, "w")) == NULL)
151                         abend("Cannot open .trd file\n");
152         }
153 }
154
155 /**
156  * Establishes configuration parameters
157  * Creates two sockets for program run
158  *
159  * @param argc number of passed values in argv array
160  * @param argv[1] 
161  * @param argv[2] 
162  * @param argv[3] if value is equal to: "r", sets global #remote variable to
163  *               TRUE, FALSE otherwise
164  */
165 static void initiate(int argc, char **argv)
166 {
167         long m;
168         int len,i,on;
169         char filename[80];
170         int sock;
171         fd_set rset, wset;
172
173         ournode = 0;
174         network = TRUE;
175         if ((argc == 4) && (strcmp(argv[3], "r") == 0))
176                 remote = TRUE;
177         else
178                 remote = FALSE;
179         
180         for(i = 0; i < 255; i++) {
181                 RInstance[i] = -1;
182                 DirConn[i] = -1;
183         }
184
185         FD_ZERO(&DirSet);
186         maxDirSet = 0;
187  
188         strcpy(filename, argv[2]);
189         strcpy(ProgName, argv[2]);
190
191         strcpy(mynname, argv[1]);
192         strcat(mynname, ".net");
193         unlink(mynname);
194         sock = socket(AF_UNIX, SOCK_STREAM, 0);
195         bzero(&svr, sizeof(svr));
196         svr.sun_family = AF_UNIX;
197         strcpy(svr.sun_path, mynname);
198         len = strlen(svr.sun_path) + sizeof(svr.sun_family);
199         fprintf(stderr, "logint: Binding to socket: %s\n", svr.sun_path);
200         bind(sock, (struct sockaddr*)&svr, len);
201         listen(sock, 5);
202
203
204         /* socket for graphic requests */ 
205         strcpy(mygname, argv[1]);
206         strcat(mygname, ".gr");
207         unlink(mygname);
208
209         /* socket for KERNEL communication */  
210         internal_sock = socket(AF_UNIX, SOCK_STREAM, 0);
211         bzero(&svr, sizeof(svr));
212         svr.sun_family = AF_UNIX;
213         strcpy(svr.sun_path, argv[1]);
214         strcpy(mykname, argv[1]);
215         len = strlen(svr.sun_path) + sizeof(svr.sun_family);
216         fprintf(stderr, "logint: Connecting to socket: %s\n", svr.sun_path);
217         i = connect(internal_sock, (struct sockaddr*)&svr, len);
218
219         if (i==0) {
220                 fcntl(internal_sock,F_SETFL, O_NONBLOCK |
221                                                 fcntl(internal_sock,F_GETFL,0));
222         }
223         else {
224                 while (i!=0) {
225                         close(internal_sock);
226                         internal_sock = socket(AF_UNIX, SOCK_STREAM, 0);
227                         fcntl(internal_sock, F_SETFL, O_NONBLOCK |
228                                         fcntl(internal_sock, F_GETFL, 0));
229                         i = connect(internal_sock, (struct sockaddr*)&svr, len);
230                 }
231         }
232         on = 1;
233         setsockopt(internal_sock, IPPROTO_TCP, TCP_NODELAY, (char*)&on,
234                                                                 sizeof(on));
235
236         /* socket for network requests */
237         FD_ZERO(&rset);
238         FD_ZERO(&wset);
239         FD_SET(sock, &rset);
240         if (select(sock + 1, &rset, &wset, 0, 0))
241                 net_sock = accept(sock, (struct sockaddr*)0, (int *)0);
242
243         if (net_sock > 0) {
244                 fcntl(net_sock, F_SETFL, O_NONBLOCK |
245                                                 fcntl(net_sock, F_GETFL, 0));
246                 setsockopt(net_sock, IPPROTO_TCP, TCP_NODELAY, (char*)&on,
247                                                                 sizeof(on));
248
249         }
250         close(sock);
251
252         /* load code and prototypes */
253         if (filename != NULL) {
254                 fprintf(stderr, "logint: loading code: %s\n", filename);
255                 load(filename);
256         }
257         else {
258                 usage();
259         }
260 }
261
262 /**
263  *
264  */
265 void decode() {
266         extopcode *eop;
267
268         /* pointer to extended opcode in M */
269         eop = (extopcode *)(M + ic);
270         /* save ic for possible redecoding */
271         lastic = ic;
272         ic += APOPCODE;
273         opcode = ((int) eop->opcode ) & 0xFF ;
274         getargument(a1, 0);
275         getargument(a2, 1);
276         getargument(a3, 2);
277 }
278
279 /**
280  * Sends message to graph module.
281  * @param msg Message to send.
282  */
283 void send_to_graph(G_MESSAGE *msg)
284 {
285         write(graph_sock, msg, sizeof(G_MESSAGE));
286 }
287
288 /**
289  * Reads message from graph module.
290  * @param msg Message to read.
291  */
292 int read_from_graph(G_MESSAGE *msg)
293 {
294         fd_set rset,wset;
295         struct timeval tout = {0, 0};
296
297         FD_ZERO(&rset);
298         FD_ZERO(&wset);
299         FD_SET(graph_sock, &rset);
300
301
302         if (select(graph_sock + 1, &rset, &wset, 0, (struct timeval *)&tout) > 0) {
303                 if (FD_ISSET(graph_sock, &rset))
304                         return(read(graph_sock,msg,sizeof(G_MESSAGE)));
305         }
306         return 0;
307 }
308
309 /**
310  * Reads message from net module.
311  *
312  * @param msg Message to read.
313  */
314 int read_from_net(MESSAGE *msg)
315 {
316         fd_set rset,wset;
317         struct timeval tout = {0, 0};
318
319         FD_ZERO(&rset);
320         FD_ZERO(&wset);
321         FD_SET(net_sock, &rset);
322
323
324         if (select(net_sock + 1, &rset, &wset, 0, (struct timeval *)&tout) > 0) {
325                 if (FD_ISSET(net_sock, &rset))
326                         return(read(net_sock, msg, sizeof(MESSAGE)));
327         }
328         return 0;
329 }
330
331
332 /**
333  * Gets graphic resource number
334  */
335 int get_graph_res()
336 {
337         MESSAGE msg;
338         int sock;
339         struct sockaddr_un svr;
340         int len, i, on;
341         fd_set rset, wset;
342
343         unlink(mygname);
344         sock = socket(AF_UNIX, SOCK_STREAM, 0);
345         bzero(&svr, sizeof(svr));
346         svr.sun_family = AF_UNIX;
347         strcpy(svr.sun_path, mygname);
348         len = strlen(svr.sun_path) + sizeof(svr.sun_family);
349         bind(sock, (struct sockaddr*)&svr, len);
350         listen(sock, 5);
351
352
353         msg.msg_type = MSG_GRAPH;
354         msg.param.pword[0] = GRAPH_ALLOCATE;
355         strcpy(msg.param.pstr, mygname);
356         write(internal_sock, &msg, sizeof(MESSAGE));
357         bzero(&msg, sizeof(MESSAGE));
358         FD_ZERO(&rset);
359         FD_ZERO(&wset);
360         FD_SET(sock, &rset);
361         if (select(sock+1, &rset, &wset, 0, 0))
362                 graph_sock = accept(sock, (struct sockaddr*)0, (int*)0);
363
364         if (graph_sock == -1) {
365                 graphics = FALSE;
366                 return 0;
367         }
368         on = 1;
369         close(sock);
370         fcntl(graph_sock, F_SETFL, O_NONBLOCK|fcntl(graph_sock, F_GETFL, 0));
371         setsockopt(graph_sock, IPPROTO_TCP, TCP_NODELAY, (char*)&on, sizeof(on));
372
373         return 1;
374 }
375
376
377 /**
378  * Writes string line (ended with new line character)
379  */
380 void writeln_str(char *s)
381 {
382         G_MESSAGE msg;
383         msg.msg_type = MSG_GRAPH;
384         msg.param.pword[1] = GraphRes;
385         msg.param.pword[2] = GRAPH_WRITE;
386         strcpy(msg.param.pstr, s);
387
388         send_to_graph(&msg);
389         strcpy(msg.param.pstr, "\n");
390         send_to_graph(&msg);
391 }
392
393 /**
394  * Writes string
395  *
396  * Passed string is send to graph module by G_MESSAGE packet using send_to_graph
397  *
398  * @param s String to write
399  */
400 void write_str(char *s)
401 {
402         G_MESSAGE msg;
403         msg.msg_type = MSG_GRAPH;
404         msg.param.pword[1] = GraphRes;
405         msg.param.pword[0] = GRAPH_WRITE;
406         strcpy(msg.param.pstr, s);
407         send_to_graph(&msg);
408 }
409
410 /**
411  * Writes char
412  *
413  * Passed char is send to graph module by G_MESSAGE packet using send_to_graph
414  *
415  * @param a Character to write
416  */
417 void write_char(char a)
418 {
419         G_MESSAGE msg;
420
421         msg.msg_type = MSG_GRAPH;
422         msg.param.pword[1] = GraphRes;
423         msg.param.pword[0] = GRAPH_PUTCHAR;
424         msg.param.pchar = a;
425         send_to_graph(&msg);
426 }
427
428
429 /**
430  * Reads char
431  * @return Read character
432  */
433 char read_char()
434 {
435         char ch;
436         G_MESSAGE msg;
437         int st;
438
439         msg.msg_type = MSG_GRAPH;
440         msg.param.pword[1] = GraphRes;
441         msg.param.pword[0] = GRAPH_READCHAR;
442         send_to_graph(&msg);
443         while(TRUE) {
444                 st = read_from_graph(&msg);
445                 if (st > 0) {
446                         if ((msg.msg_type == MSG_GRAPH) && 
447                                 (msg.param.pword[0] == GRAPH_READCHAR_RESPONSE)) 
448                                 {
449                                 ch = msg.param.pchar;
450                                 break;
451                         }
452                 }
453         }
454         return ch;
455 }
456
457 /**
458  * Reads line
459  */
460 void read_line()
461 {
462         G_MESSAGE msg;
463         int st;
464
465
466         msg.msg_type = MSG_GRAPH;
467         msg.param.pword[1] = GraphRes;
468         msg.param.pword[0] = GRAPH_READLN;
469         send_to_graph(&msg);
470         while(TRUE) {
471                 st = read_from_graph(&msg);
472                 if (st > 0)
473                         if ((msg.msg_type == MSG_GRAPH) &&
474                                 (msg.param.pword[0] == GRAPH_READLN_RESPONSE))
475                                 break;
476         }
477 }
478
479 /**
480  * Reads string
481  * @param s Buffer to store string.
482  */
483 void read_str(char *s)
484 {
485         char ss[255];
486         G_MESSAGE msg;
487         int st;
488
489         msg.msg_type = MSG_GRAPH;
490         msg.param.pword[1] = GraphRes;
491         msg.param.pword[0] = GRAPH_READSTR;
492         send_to_graph(&msg);
493         while(TRUE) {
494                 st = read_from_graph(&msg);
495                 if (st > 0) {
496                         if ((msg.msg_type == MSG_GRAPH) && 
497                                 (msg.param.pword[0] == GRAPH_READSTR_RESPONSE)) {
498                                 strcpy(ss, msg.param.pstr);
499                                 break;
500                         }
501                 }
502         }
503         strcpy(s, ss);
504 }
505
506 /**
507  * Sends message to kernel
508  * @param msg Message to send to kernel
509  */
510 void send_to_kernel(MESSAGE *msg)
511 {
512         write(internal_sock, msg, sizeof(MESSAGE));
513 }
514
515 /**
516  * Sends message to net
517  * @return Returns 1 if ok and 0 if node desn't exists (since 2010)
518  */
519 int send_to_net(MESSAGE *msg)
520 {
521         int k, len;
522         MESSAGE m;
523         struct sockaddr_in svr;
524         char addr[256];
525
526
527         k = msg->int_msg.control.receiver.node; 
528
529         /* 2010 check if node exists */
530         m.msg_type = MSG_NET;
531         m.param.pword[0] = NET_NODE_EXIST;
532         m.param.pword[1] = k;
533         m.param.pword[2] = my_ctx.program_id;
534         write(net_sock, &m, sizeof(MESSAGE));
535         bzero(&m, sizeof(MESSAGE));
536          while((m.msg_type != MSG_NET) && (m.param.pword[0] != NET_NODE_EXIST))
537                 read(net_sock, &m, sizeof(MESSAGE));
538
539         if (m.param.pword[1] != 1)
540                 return 0;
541
542         strcpy(addr, m.param.pstr);
543
544         if (RInstance[k] == -1) {
545                 bzero(&m,sizeof(MESSAGE));
546                 m.msg_type = MSG_VLP;
547                 m.param.pword[0] = VLP_REMOTE_INSTANCE_PLEASE;
548                 m.param.pword[1] = my_ctx.program_id;
549                 m.param.pword[2] = k;
550                 send_to_kernel(&m);
551                 bzero(&m, sizeof(MESSAGE));
552
553                 while(1) {
554                         read(internal_sock, &m, sizeof(MESSAGE));
555                         if ((m.msg_type == MSG_VLP) &&
556                                 (m.param.pword[0] == VLP_REMOTE_INSTANCE_HERE))
557                                 break;
558                 }
559
560                 /*printf("DEBUG: remote instance made with id: "
561                         "%d addr %s port %d\n", m.param.pword[1], addr,
562                         htons(m.param.pword[8]));*/
563                 RInstance[k] = m.param.pword[1];
564                 /* Make direct connection */
565                 DirConn[k] = socket(AF_INET, SOCK_STREAM, 0);
566                 svr.sin_family = AF_INET;
567                 svr.sin_addr.s_addr = inet_addr(addr);
568                 svr.sin_port = htons(m.param.pword[8]);
569                 len = connect(DirConn[k], (struct sockaddr*)&svr, sizeof(svr));
570                 if (len!=0) {
571                         RInstance[k] = -1;
572
573                         writeln_str("Cannot connect remote instance!");
574                 } else {
575                         fcntl(DirConn[k], F_SETFL, O_NONBLOCK |
576                                                 fcntl(DirConn[k], F_GETFL, 0));
577                 }
578         }
579         if (RInstance[k] != -1) {
580                 write(DirConn[k], &(msg->int_msg), sizeof(message));
581         } 
582         return 1;
583 }
584
585 /* -------------------- Check for message on internal socket -------------*/
586
587 void get_internal()
588 {
589         MESSAGE m, m1;
590         message mx;
591
592         int r, max, i;
593         char s[80];
594         fd_set rset;
595         struct timeval tout = {0, 0};
596
597  /* 2010 */
598  /* ----------- Direct connection messages -----
599         FD_ZERO(&DirSet);
600         maxDirSet = 0;
601         for(i = 0; i < 255; i++)
602                 if (DirConn[i]!=-1) {
603                         FD_SET(DirConn[i], &DirSet);
604                         if (maxDirSet<DirConn[i])
605                                 maxDirSet=DirConn[i];
606                 }
607
608         if (select(maxDirSet + 1, &DirSet, 0, 0, (struct timeval *)&tout) > 0) {
609                 for(i = 0; i < 255; i++) {
610                         if ((DirConn[i] != -1) &&
611                                         (FD_ISSET(DirConn[i], &DirSet))) {
612                                 r = read(DirConn[i], &mx, sizeof(mx));
613                                 if (r > 0) {
614                                         memcpy(globmsgqueue + msgtail,&mx,
615                                                         sizeof(message));
616                                         msgtail = (msgtail + 1) % MAXMSGQUEUE;
617                                         msgready++;
618                                 }
619                         }
620                 }
621         }
622 -----------------------------------------*/
623
624         FD_ZERO(&rset);
625         FD_SET(net_sock, &rset);
626         FD_SET(internal_sock, &rset); 
627         if (net_sock > internal_sock)
628                 max = net_sock;
629         else
630                 max = internal_sock;
631         /* 2010 */
632         for(i = 0; i < 255; i++) {
633                 if (DirConn[i] != -1) {
634                         FD_SET(DirConn[i], &rset);
635                         if (max < DirConn[i])
636                                 max = DirConn[i];
637                 }
638         }
639
640         if (select(max + 1, &rset, 0, 0, (struct timeval *)&tout) > 0) {
641                 /* 2010 */
642                 for(i = 0; i < 255; i++) {
643                         if ((DirConn[i] != -1) && (FD_ISSET(DirConn[i], &rset))) {
644                                 /*
645                                 printf("DEBUG: Interp has message on "
646                                         "direct connection: type %d par %d\n",
647                                                 mx.control.type,mx.control.par);
648                                 */
649                                 r = read(DirConn[i], &mx, sizeof(mx));
650                                 if (r > 0 && r == sizeof(mx)) {
651                                         memcpy(globmsgqueue + msgtail, &mx,
652                                                         sizeof(message));
653                                         msgtail = (msgtail+1) % MAXMSGQUEUE;
654                                         msgready++;
655                                 } 
656                         }
657                 }
658
659                 if (FD_ISSET(net_sock,&rset)) {
660                         r = read(net_sock, &m, sizeof(MESSAGE));
661                 
662                         if (r>0) {
663                                 switch(m.msg_type) {
664                                 case MSG_NET:
665                                         switch(m.param.pword[0]) {
666                                         case NET_PROPAGATE:
667                                         /*
668                                         printf("DEBUG: cint net_sock MSG_NET "
669                                                 "NET_PROPAGATE cmd %d\n",
670                                                         m.param.pword[6]);*/
671                                                 memcpy(globmsgqueue + msgtail,
672                                                         &m.int_msg,
673                                                         sizeof(message));
674                                                 msgtail = (msgtail + 1) %
675                                                                 MAXMSGQUEUE;
676                                                 msgready++;
677                                                 break;
678                                         };
679                                         break;
680                                 }
681                         }
682                 }
683
684                 if (FD_ISSET(internal_sock, &rset)) {
685                         r = read(internal_sock, &m, sizeof(MESSAGE));
686
687                         if (r > 0) {
688                                 switch(m.msg_type) {
689                                 case MSG_INT:
690                                         switch(m.param.pword[0]) {
691                                         case INT_CLOSE_INSTANCE:
692                                                 endrun(0);
693                                         case INT_KILL:
694                                                 endrun(1);
695                                         default:
696                                                 break;
697                                         }
698                                 case MSG_NET:
699                                         if (m.param.pword[0] == NET_PROPAGATE) {
700                                                 /*
701                                                 printf("DEBUG: cint internal_sock MSG_NET NET_PROPAGATE cmd %d\n",m.param.pword[6]);*/
702                                                 memcpy(globmsgqueue + msgtail,
703                                                         &m.int_msg,
704                                                         sizeof(message));
705                                                 msgtail = (msgtail+1) %
706                                                                 MAXMSGQUEUE;
707                                                 msgready++;
708                                         };
709                                         break;
710                                 }
711                         }
712                 }
713         }
714 }
715
716
717 void request_id()
718 {
719         MESSAGE m;
720         G_MESSAGE m1; 
721
722         m.msg_type = MSG_INT;
723         m.param.pword[0] = INT_CTX_REQ;
724         send_to_kernel(&m);
725         while ((m.msg_type != MSG_INT) || (m.param.pword[0] != INT_CTX))
726                 read(internal_sock, &m, sizeof(MESSAGE));
727
728         my_ctx.node = m.param.pword[1];
729         my_ctx.program_id = m.param.pword[2];
730         if (remote) {
731                 parent_ctx.node = m.param.pword[3];
732                 parent_ctx.program_id = m.param.pword[4];
733                 RInstance[parent_ctx.node] = parent_ctx.program_id;
734         } else {
735                 parent_ctx.node = my_ctx.node;
736                 parent_ctx.program_id = my_ctx.program_id;
737         }
738         ournode = my_ctx.node;
739         /* strcpy(nname,m.param.pstr);*/
740         /* net_sock = open(nname,O_WRONLY);*/
741         m1.msg_type = MSG_GRAPH;
742         m1.param.pword[0] = GRAPH_SET_TITLE;
743         m1.param.pword[1] = GraphRes;
744         sprintf(m1.param.pstr, "%s      ID: %d", ProgName, my_ctx.program_id);
745
746         if (remote)
747                 strcat(m1.param.pstr, "  REMOTE instance");
748         send_to_graph(&m1);
749 }
750
751 /**
752  * Sends MESSAGE
753  */
754 void send_ready()
755 {
756         int sock, len;
757         struct sockaddr_in svr;
758         char name[255];
759         struct hostent *info;
760
761         MESSAGE msg;
762         msg.msg_type = MSG_NET;
763         msg.param.pword[0] = NET_PROPAGATE;
764         msg.param.pword[1] = MSG_VLP;
765         msg.param.pword[2] = my_ctx.node;
766         msg.param.pword[4] = parent_ctx.node;
767         msg.param.pword[6] = VLP_REMOTE_INSTANCE_OK;
768         msg.param.pword[7] = my_ctx.program_id;
769
770         sock = socket(AF_INET, SOCK_STREAM, 0);
771         bzero(&svr, sizeof(svr));
772         svr.sin_family = AF_INET;
773         svr.sin_addr.s_addr = INADDR_ANY;
774         svr.sin_port = 0;
775         bind(sock, (struct sockaddr*)&svr, sizeof(svr));
776         listen(sock, 5);
777         len = sizeof(svr);
778         getsockname(sock,(struct sockaddr*)&svr, &len);
779         msg.param.pword[8] = ntohs(svr.sin_port);
780         gethostname(name, &len);
781         info = (struct hostent*)gethostbyname(name);
782         bcopy((char*)info->h_addr, (char*)&svr.sin_addr, info->h_length);
783         sprintf(msg.param.pstr, "%s", inet_ntoa(svr.sin_addr));
784         send_to_kernel(&msg);
785
786         bzero(&svr, sizeof(svr));
787         DirConn[parent_ctx.node] = accept(sock, (struct sockaddr*)&svr, &len);
788         fcntl(DirConn[parent_ctx.node], F_SETFL, O_NONBLOCK |
789                                 fcntl(DirConn[parent_ctx.node], F_GETFL, 0));
790 }
791
792 /**
793  *      strcpy(filename, argv[2]);
794  *      strcpy(ProgName, argv[2]);
795  *
796  * @param argv[1] = base name of this interpreter instance.
797  *           For network there is created argv[1].net socket
798  *           For graphics there is created argv[1].gr socket
799  * @param argv[2] = up to 80 characters string (with terminating \0). It is used to
800  *           load selected program
801  * @param argv[3] = if exists and is equal to 'r', this is a remote call
802  */
803 int main(int argc, char **argv)
804 {
805         fprintf(stderr, "logint: initializing\n");
806         /* initialize executor */
807         initiate(argc, argv);
808         /* initialize running system */
809         fprintf(stderr, "logint: runsys\n");
810         runsys();
811         fprintf(stderr, "logint: initializing scheduler\n");
812         init_scheduler();
813         fprintf(stderr, "logint: acquiring GRAPH resource\n");
814         GraphRes = get_graph_res();
815         if (GraphRes < 0) {
816                 fprintf(stderr, "logint:  > acquiring GRAPH resource failed\n");
817                 exit(12);
818         }
819
820         request_id();
821         if (remote)
822                 send_ready(); 
823
824         /* set label for continue long jump */
825         setjmp(contenv);
826         /* repeat until exit() is called */
827         while (TRUE) {
828                 get_internal();
829                 /* reschedule current process */
830                 schedule();
831                 if (ready != 0) {
832                         /* fetch instruction */
833                         decode();
834                         /* and execute it */
835                         execute();
836                 }
837         }
838         return 0;
839 }
840