Documentation fixes
[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         bind(sock, (struct sockaddr*)&svr, len);
200         listen(sock, 5);
201
202
203         /* socket for graphic requests */ 
204         strcpy(mygname, argv[1]);
205         strcat(mygname, ".gr");
206         unlink(mygname);
207
208         /* socket for KERNEL communication */  
209         internal_sock = socket(AF_UNIX, SOCK_STREAM, 0);
210         bzero(&svr, sizeof(svr));
211         svr.sun_family = AF_UNIX;
212         strcpy(svr.sun_path, argv[1]);
213         strcpy(mykname, argv[1]);
214         len = strlen(svr.sun_path) + sizeof(svr.sun_family);
215         i = connect(internal_sock, (struct sockaddr*)&svr, len);
216
217         if (i==0) {
218                 fcntl(internal_sock,F_SETFL, O_NONBLOCK |
219                                                 fcntl(internal_sock,F_GETFL,0));
220         }
221         else
222                 while (i!=0) {
223                         close(internal_sock);
224                         internal_sock = socket(AF_UNIX, SOCK_STREAM, 0);
225                         fcntl(internal_sock, F_SETFL, O_NONBLOCK |
226                                         fcntl(internal_sock, F_GETFL, 0));
227                         i = connect(internal_sock, (struct sockaddr*)&svr, len);
228                 }
229         on = 1;
230         setsockopt(internal_sock, IPPROTO_TCP, TCP_NODELAY, (char*)&on,
231                                                                 sizeof(on));
232
233         /* socket for network requests */
234         FD_ZERO(&rset);
235         FD_ZERO(&wset);
236         FD_SET(sock, &rset);
237         if (select(sock + 1, &rset, &wset, 0, 0))
238                 net_sock = accept(sock, (struct sockaddr*)0, (int *)0);
239
240         if (net_sock > 0) {
241                 fcntl(net_sock, F_SETFL, O_NONBLOCK |
242                                                 fcntl(net_sock, F_GETFL, 0));
243                 setsockopt(net_sock, IPPROTO_TCP, TCP_NODELAY, (char*)&on,
244                                                                 sizeof(on));
245
246         }
247         close(sock);
248
249         /* load code and prototypes */
250         if (filename != NULL)
251                 load(filename);
252         else
253                 usage();
254 }
255
256 /**
257  *
258  */
259 void decode() {
260         extopcode *eop;
261
262         /* pointer to extended opcode in M */
263         eop = (extopcode *)(M + ic);
264         /* save ic for possible redecoding */
265         lastic = ic;
266         ic += APOPCODE;
267         opcode = ((int) eop->opcode ) & 0xFF ;
268         getargument(a1, 0);
269         getargument(a2, 1);
270         getargument(a3, 2);
271 }
272
273 /**
274  * Sends message to graph module.
275  * @param msg Message to send.
276  */
277 void send_to_graph(G_MESSAGE *msg)
278 {
279         write(graph_sock, msg, sizeof(G_MESSAGE));
280 }
281
282 /**
283  * Reads message from graph module.
284  * @param msg Message to read.
285  */
286 int read_from_graph(G_MESSAGE *msg)
287 {
288         fd_set rset,wset;
289         struct timeval tout = {0, 0};
290
291         FD_ZERO(&rset);
292         FD_ZERO(&wset);
293         FD_SET(graph_sock, &rset);
294
295
296         if (select(graph_sock + 1, &rset, &wset, 0, (struct timeval *)&tout) > 0) {
297                 if (FD_ISSET(graph_sock, &rset))
298                         return(read(graph_sock,msg,sizeof(G_MESSAGE)));
299         }
300         return 0;
301 }
302
303 /**
304  * Reads message from net module.
305  *
306  * @param msg Message to read.
307  */
308 int read_from_net(MESSAGE *msg)
309 {
310         fd_set rset,wset;
311         struct timeval tout = {0, 0};
312
313         FD_ZERO(&rset);
314         FD_ZERO(&wset);
315         FD_SET(net_sock, &rset);
316
317
318         if (select(net_sock + 1, &rset, &wset, 0, (struct timeval *)&tout) > 0) {
319                 if (FD_ISSET(net_sock, &rset))
320                         return(read(net_sock, msg, sizeof(MESSAGE)));
321         }
322         return 0;
323 }
324
325
326 /**
327  * Gets graphic resource number
328  */
329 int get_graph_res()
330 {
331         MESSAGE msg;
332         int sock;
333         struct sockaddr_un svr;
334         int len, i, on;
335         fd_set rset, wset;
336
337         unlink(mygname);
338         sock = socket(AF_UNIX, SOCK_STREAM, 0);
339         bzero(&svr, sizeof(svr));
340         svr.sun_family = AF_UNIX;
341         strcpy(svr.sun_path, mygname);
342         len = strlen(svr.sun_path) + sizeof(svr.sun_family);
343         bind(sock, (struct sockaddr*)&svr, len);
344         listen(sock, 5);
345
346
347         msg.msg_type = MSG_GRAPH;
348         msg.param.pword[0] = GRAPH_ALLOCATE;
349         strcpy(msg.param.pstr, mygname);
350         write(internal_sock, &msg, sizeof(MESSAGE));
351         bzero(&msg, sizeof(MESSAGE));
352         FD_ZERO(&rset);
353         FD_ZERO(&wset);
354         FD_SET(sock, &rset);
355         if (select(sock+1, &rset, &wset, 0, 0))
356                 graph_sock = accept(sock, (struct sockaddr*)0, (int*)0);
357
358         if (graph_sock == -1) {
359                 graphics = FALSE;
360                 return 0;
361         }
362         on = 1;
363         close(sock);
364         fcntl(graph_sock, F_SETFL, O_NONBLOCK|fcntl(graph_sock, F_GETFL, 0));
365         setsockopt(graph_sock, IPPROTO_TCP, TCP_NODELAY, (char*)&on, sizeof(on));
366
367         return 1;
368 }
369
370
371 /**
372  * Writes string line (ended with new line character)
373  */
374 void writeln_str(char *s)
375 {
376         G_MESSAGE msg;
377         msg.msg_type = MSG_GRAPH;
378         msg.param.pword[1] = GraphRes;
379         msg.param.pword[2] = GRAPH_WRITE;
380         strcpy(msg.param.pstr, s);
381
382         send_to_graph(&msg);
383         strcpy(msg.param.pstr, "\n");
384         send_to_graph(&msg);
385 }
386
387 /**
388  * Writes string
389  *
390  * Passed string is send to graph module by G_MESSAGE packet using send_to_graph
391  *
392  * @param s String to write
393  */
394 void write_str(char *s)
395 {
396         G_MESSAGE msg;
397         msg.msg_type = MSG_GRAPH;
398         msg.param.pword[1] = GraphRes;
399         msg.param.pword[0] = GRAPH_WRITE;
400         strcpy(msg.param.pstr, s);
401         send_to_graph(&msg);
402 }
403
404 /**
405  * Writes char
406  *
407  * Passed char is send to graph module by G_MESSAGE packet using send_to_graph
408  *
409  * @param a Character to write
410  */
411 void write_char(char a)
412 {
413         G_MESSAGE msg;
414
415         msg.msg_type = MSG_GRAPH;
416         msg.param.pword[1] = GraphRes;
417         msg.param.pword[0] = GRAPH_PUTCHAR;
418         msg.param.pchar = a;
419         send_to_graph(&msg);
420 }
421
422
423 /**
424  * Reads char
425  * @return Read character
426  */
427 char read_char()
428 {
429         char ch;
430         G_MESSAGE msg;
431         int st;
432
433         msg.msg_type = MSG_GRAPH;
434         msg.param.pword[1] = GraphRes;
435         msg.param.pword[0] = GRAPH_READCHAR;
436         send_to_graph(&msg);
437         while(TRUE) {
438                 st = read_from_graph(&msg);
439                 if (st > 0) {
440                         if ((msg.msg_type == MSG_GRAPH) && 
441                                 (msg.param.pword[0] == GRAPH_READCHAR_RESPONSE)) 
442                                 {
443                                 ch = msg.param.pchar;
444                                 break;
445                         }
446                 }
447         }
448         return ch;
449 }
450
451 /**
452  * Reads line
453  */
454 void read_line()
455 {
456         G_MESSAGE msg;
457         int st;
458
459
460         msg.msg_type = MSG_GRAPH;
461         msg.param.pword[1] = GraphRes;
462         msg.param.pword[0] = GRAPH_READLN;
463         send_to_graph(&msg);
464         while(TRUE) {
465                 st = read_from_graph(&msg);
466                 if (st > 0)
467                         if ((msg.msg_type == MSG_GRAPH) &&
468                                 (msg.param.pword[0] == GRAPH_READLN_RESPONSE))
469                                 break;
470         }
471 }
472
473 /**
474  * Reads string
475  * @param s Buffer to store string.
476  */
477 void read_str(char *s)
478 {
479         char ss[255];
480         G_MESSAGE msg;
481         int st;
482
483         msg.msg_type = MSG_GRAPH;
484         msg.param.pword[1] = GraphRes;
485         msg.param.pword[0] = GRAPH_READSTR;
486         send_to_graph(&msg);
487         while(TRUE) {
488                 st = read_from_graph(&msg);
489                 if (st > 0) {
490                         if ((msg.msg_type == MSG_GRAPH) && 
491                                 (msg.param.pword[0] == GRAPH_READSTR_RESPONSE)) {
492                                 strcpy(ss, msg.param.pstr);
493                                 break;
494                         }
495                 }
496         }
497         strcpy(s, ss);
498 }
499
500 /**
501  * Sends message to kernel
502  * @param msg Message to send to kernel
503  */
504 void send_to_kernel(MESSAGE *msg)
505 {
506         write(internal_sock, msg, sizeof(MESSAGE));
507 }
508
509 /**
510  * Sends message to net
511  * @return Returns 1 if ok and 0 if node desn't exists (since 2010)
512  */
513 int send_to_net(MESSAGE *msg)
514 {
515         int k, len;
516         MESSAGE m;
517         struct sockaddr_in svr;
518         char addr[256];
519
520
521         k = msg->int_msg.control.receiver.node; 
522
523         /* 2010 check if node exists */
524         m.msg_type = MSG_NET;
525         m.param.pword[0] = NET_NODE_EXIST;
526         m.param.pword[1] = k;
527         m.param.pword[2] = my_ctx.program_id;
528         write(net_sock, &m, sizeof(MESSAGE));
529         bzero(&m, sizeof(MESSAGE));
530          while((m.msg_type != MSG_NET) && (m.param.pword[0] != NET_NODE_EXIST))
531                 read(net_sock, &m, sizeof(MESSAGE));
532
533         if (m.param.pword[1] != 1)
534                 return 0;
535
536         strcpy(addr, m.param.pstr);
537
538         if (RInstance[k] == -1) {
539                 bzero(&m,sizeof(MESSAGE));
540                 m.msg_type = MSG_VLP;
541                 m.param.pword[0] = VLP_REMOTE_INSTANCE_PLEASE;
542                 m.param.pword[1] = my_ctx.program_id;
543                 m.param.pword[2] = k;
544                 send_to_kernel(&m);
545                 bzero(&m, sizeof(MESSAGE));
546
547                 while(1) {
548                         read(internal_sock, &m, sizeof(MESSAGE));
549                         if ((m.msg_type == MSG_VLP) &&
550                                 (m.param.pword[0] == VLP_REMOTE_INSTANCE_HERE))
551                                 break;
552                 }
553
554                 /*printf("DEBUG: remote instance made with id: "
555                         "%d addr %s port %d\n", m.param.pword[1], addr,
556                         htons(m.param.pword[8]));*/
557                 RInstance[k] = m.param.pword[1];
558                 /* Make direct connection */
559                 DirConn[k] = socket(AF_INET, SOCK_STREAM, 0);
560                 svr.sin_family = AF_INET;
561                 svr.sin_addr.s_addr = inet_addr(addr);
562                 svr.sin_port = htons(m.param.pword[8]);
563                 len = connect(DirConn[k], (struct sockaddr*)&svr, sizeof(svr));
564                 if (len!=0) {
565                         RInstance[k] = -1;
566
567                         writeln_str("Cannot connect remote instance!");
568                 } else {
569                         fcntl(DirConn[k], F_SETFL, O_NONBLOCK |
570                                                 fcntl(DirConn[k], F_GETFL, 0));
571                 }
572         }
573         if (RInstance[k] != -1) {
574                 write(DirConn[k], &(msg->int_msg), sizeof(message));
575         } 
576         return 1;
577 }
578
579 /* -------------------- Check for message on internal socket -------------*/
580
581 void get_internal()
582 {
583         MESSAGE m, m1;
584         message mx;
585
586         int r, max, i;
587         char s[80];
588         fd_set rset;
589         struct timeval tout = {0, 0};
590
591  /* 2010 */
592  /* ----------- Direct connection messages -----
593         FD_ZERO(&DirSet);
594         maxDirSet = 0;
595         for(i = 0; i < 255; i++)
596                 if (DirConn[i]!=-1) {
597                         FD_SET(DirConn[i], &DirSet);
598                         if (maxDirSet<DirConn[i])
599                                 maxDirSet=DirConn[i];
600                 }
601
602         if (select(maxDirSet + 1, &DirSet, 0, 0, (struct timeval *)&tout) > 0) {
603                 for(i = 0; i < 255; i++) {
604                         if ((DirConn[i] != -1) &&
605                                         (FD_ISSET(DirConn[i], &DirSet))) {
606                                 r = read(DirConn[i], &mx, sizeof(mx));
607                                 if (r > 0) {
608                                         memcpy(globmsgqueue + msgtail,&mx,
609                                                         sizeof(message));
610                                         msgtail = (msgtail + 1) % MAXMSGQUEUE;
611                                         msgready++;
612                                 }
613                         }
614                 }
615         }
616 -----------------------------------------*/
617
618         FD_ZERO(&rset);
619         FD_SET(net_sock, &rset);
620         FD_SET(internal_sock, &rset); 
621         if (net_sock > internal_sock)
622                 max = net_sock;
623         else
624                 max = internal_sock;
625         /* 2010 */
626         for(i = 0; i < 255; i++) {
627                 if (DirConn[i] != -1) {
628                         FD_SET(DirConn[i], &rset);
629                         if (max < DirConn[i])
630                                 max = DirConn[i];
631                 }
632         }
633
634         if (select(max + 1, &rset, 0, 0, (struct timeval *)&tout) > 0) {
635                 /* 2010 */
636                 for(i = 0; i < 255; i++) {
637                         if ((DirConn[i] != -1) && (FD_ISSET(DirConn[i], &rset))) {
638                                 /*
639                                 printf("DEBUG: Interp has message on "
640                                         "direct connection: type %d par %d\n",
641                                                 mx.control.type,mx.control.par);
642                                 */
643                                 r = read(DirConn[i], &mx, sizeof(mx));
644                                 if (r > 0 && r == sizeof(mx)) {
645                                         memcpy(globmsgqueue + msgtail, &mx,
646                                                         sizeof(message));
647                                         msgtail = (msgtail+1) % MAXMSGQUEUE;
648                                         msgready++;
649                                 } 
650                         }
651                 }
652
653                 if (FD_ISSET(net_sock,&rset)) {
654                         r = read(net_sock, &m, sizeof(MESSAGE));
655                 
656                         if (r>0) {
657                                 switch(m.msg_type) {
658                                 case MSG_NET:
659                                         switch(m.param.pword[0]) {
660                                         case NET_PROPAGATE:
661                                         /*
662                                         printf("DEBUG: cint net_sock MSG_NET "
663                                                 "NET_PROPAGATE cmd %d\n",
664                                                         m.param.pword[6]);*/
665                                                 memcpy(globmsgqueue + msgtail,
666                                                         &m.int_msg,
667                                                         sizeof(message));
668                                                 msgtail = (msgtail + 1) %
669                                                                 MAXMSGQUEUE;
670                                                 msgready++;
671                                                 break;
672                                         };
673                                         break;
674                                 }
675                         }
676                 }
677
678                 if (FD_ISSET(internal_sock, &rset)) {
679                         r = read(internal_sock, &m, sizeof(MESSAGE));
680
681                         if (r > 0) {
682                                 switch(m.msg_type) {
683                                 case MSG_INT:
684                                         switch(m.param.pword[0]) {
685                                         case INT_CLOSE_INSTANCE:
686                                                 endrun(0);
687                                         case INT_KILL:
688                                                 endrun(1);
689                                         default:
690                                                 break;
691                                         }
692                                 case MSG_NET:
693                                         if (m.param.pword[0] == NET_PROPAGATE) {
694                                                 /*
695                                                 printf("DEBUG: cint internal_sock MSG_NET NET_PROPAGATE cmd %d\n",m.param.pword[6]);*/
696                                                 memcpy(globmsgqueue + msgtail,
697                                                         &m.int_msg,
698                                                         sizeof(message));
699                                                 msgtail = (msgtail+1) %
700                                                                 MAXMSGQUEUE;
701                                                 msgready++;
702                                         };
703                                         break;
704                                 }
705                         }
706                 }
707         }
708 }
709
710
711 void request_id()
712 {
713         MESSAGE m;
714         G_MESSAGE m1; 
715
716         m.msg_type = MSG_INT;
717         m.param.pword[0] = INT_CTX_REQ;
718         send_to_kernel(&m);
719         while ((m.msg_type != MSG_INT) || (m.param.pword[0] != INT_CTX))
720                 read(internal_sock, &m, sizeof(MESSAGE));
721
722         my_ctx.node = m.param.pword[1];
723         my_ctx.program_id = m.param.pword[2];
724         if (remote) {
725                 parent_ctx.node = m.param.pword[3];
726                 parent_ctx.program_id = m.param.pword[4];
727                 RInstance[parent_ctx.node] = parent_ctx.program_id;
728         } else {
729                 parent_ctx.node = my_ctx.node;
730                 parent_ctx.program_id = my_ctx.program_id;
731         }
732         ournode = my_ctx.node;
733         /* strcpy(nname,m.param.pstr);*/
734         /* net_sock = open(nname,O_WRONLY);*/
735         m1.msg_type = MSG_GRAPH;
736         m1.param.pword[0] = GRAPH_SET_TITLE;
737         m1.param.pword[1] = GraphRes;
738         sprintf(m1.param.pstr, "%s      ID: %d", ProgName, my_ctx.program_id);
739
740         if (remote)
741                 strcat(m1.param.pstr, "  REMOTE instance");
742         send_to_graph(&m1);
743 }
744
745 /**
746  * Sends MESSAGE
747  */
748 void send_ready()
749 {
750         int sock, len;
751         struct sockaddr_in svr;
752         char name[255];
753         struct hostent *info;
754
755         MESSAGE msg;
756         msg.msg_type = MSG_NET;
757         msg.param.pword[0] = NET_PROPAGATE;
758         msg.param.pword[1] = MSG_VLP;
759         msg.param.pword[2] = my_ctx.node;
760         msg.param.pword[4] = parent_ctx.node;
761         msg.param.pword[6] = VLP_REMOTE_INSTANCE_OK;
762         msg.param.pword[7] = my_ctx.program_id;
763
764         sock = socket(AF_INET, SOCK_STREAM, 0);
765         bzero(&svr, sizeof(svr));
766         svr.sin_family = AF_INET;
767         svr.sin_addr.s_addr = INADDR_ANY;
768         svr.sin_port = 0;
769         bind(sock, (struct sockaddr*)&svr, sizeof(svr));
770         listen(sock, 5);
771         len = sizeof(svr);
772         getsockname(sock,(struct sockaddr*)&svr, &len);
773         msg.param.pword[8] = ntohs(svr.sin_port);
774         gethostname(name, &len);
775         info = (struct hostent*)gethostbyname(name);
776         bcopy((char*)info->h_addr, (char*)&svr.sin_addr, info->h_length);
777         sprintf(msg.param.pstr, "%s", inet_ntoa(svr.sin_addr));
778         send_to_kernel(&msg);
779
780         bzero(&svr, sizeof(svr));
781         DirConn[parent_ctx.node] = accept(sock, (struct sockaddr*)&svr, &len);
782         fcntl(DirConn[parent_ctx.node], F_SETFL, O_NONBLOCK |
783                                 fcntl(DirConn[parent_ctx.node], F_GETFL, 0));
784 }
785
786 /**
787  *      strcpy(filename, argv[2]);
788  *      strcpy(ProgName, argv[2]);
789  *
790  * @param argv[1] = base name of this interpreter instance.
791  *           For network there is created argv[1].net socket
792  *           For graphics there is created argv[1].gr socket
793  * @param argv[2] = up to 80 characters string (with terminating \0). It is used to
794  *           load selected program
795  * @param argv[3] = if exists and is equal to 'r', this is a remote call
796  */
797 int main(int argc, char **argv)
798 {
799         /* initialize executor */
800         initiate(argc, argv);
801         /* initialize running system */
802         runsys();
803         init_scheduler();
804         GraphRes = get_graph_res();
805         if (GraphRes < 0)
806                 exit(12);
807
808         request_id();
809         if (remote)
810                 send_ready(); 
811
812         /* set label for continue long jump */
813         setjmp(contenv);
814         /* repeat until exit() is called */
815         while (TRUE) {
816                 get_internal();
817                 /* reschedule current process */
818                 schedule();
819                 if (ready != 0) {
820                         /* fetch instruction */
821                         decode();
822                         /* and execute it */
823                         execute();
824                 }
825         }
826         return 0;
827 }
828