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