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