12 #include <netinet/in.h>
13 #include <arpa/inet.h>
19 static void load(char *);
20 static void initiate(int,char **);
21 int main(int,char **);
24 static void initiate();
30 int internal_sock,graph_sock,net_sock,connected=0;
31 struct sockaddr_un svr;
33 char ProgName[255],mygname[80], gname[80],mykname[80], nname[80], mynname[80];
38 ctx_struct parent_ctx;
40 int RInstance[255]; /* IDs of remote instances */
41 int DirConn[255]; /* Direct connection channels */
44 int fcol, bcol, curx=0, cury=0;
48 /* Macro to decode addressing modes : */
49 #define getargument(a, argnr) \
50 switch (eop->args[ argnr ]) \
52 case GLOBAL : a = M[ ic++ ]; break; \
53 case LOCAL : a = c1+M[ ic++ ]; break; \
54 case TEMPLOCAL : a = c2+M[ ic++ ]; break; \
55 case REMOTE : a = M[ M[ ic+1 ] ]+M[ ic ]; ic+=2; break;\
56 case INDIRECT : a = M[ M[ ic++ ] ]; break;\
57 case IMMEDIATE : a = ic++; break;\
58 case CONSTANT : a = M[ ic++ ]; break;\
59 case DOTACCESS : a = M[ display+M[ ic+1 ] ]+M[ ic ]; ic += 2; break;\
60 case NOARGUMENT : return; \
64 static void load(_filename) /* Load code and prototypes from file */
70 char filename[100]; /* should suffice on all systems */
72 strcpy( filename, _filename );
73 M = mallocate(memorysize+1); /* allocate main memory array */
74 if (M == NULL) abend("Memory size too large (use /m option)\n");
76 addext(filename, ".ccd");
77 if ((fp = fopen(filename, BINARYREAD)) == NULL)
79 fprintf(stderr,"Cannot open .ccd file\n");
83 ic = 0; /* read static data and code */
84 left = memorysize+1; /* from .ccd file */
87 if (left == 0) abend("Memory size too small (use /m option)\n");
88 n = min(IOBLOCK/sizeof(word), left);
89 n = fread((char *) &M[ ic ], sizeof(word), (int) n, fp);
92 } while (n != 0); /* now ic = number of words read */
95 /* Get various addresses passed by GENERATOR */
96 ipradr = M[ ic-5 ]; /* primitive type desctriptions */
97 temporary = M[ ic-4 ]; /* global temporary variables */
98 strings = M[ ic-3 ]; /* string constants */
99 lastprot = M[ ic-2 ]; /* last prototype number */
100 freem = M[ ic-1 ]; /* first free word in memory */
102 /* Read prototypes from .pcd file */
103 addext(filename, ".pcd");
104 if ((fp = fopen(filename, BINARYREAD)) == NULL)
106 fprintf(stderr,"Cannot open .pcd file\n");
109 for (n = MAINBLOCK; n <= lastprot; n++ )
111 cp = ballocate(sizeof(protdescr));
112 if (cp == NULL) abend("Memory size too large (use /m option)\n");
113 prototype[ n ] = (protdescr *) cp;
114 if (fread(cp, sizeof(protdescr), 1, fp) != 1)
115 abend("Cannot read .pcd file\n");
119 /* Open trace file */
122 addext(filename, ".trd");
123 if ((tracefile = fopen(filename, "w")) == NULL)
124 abend("Cannot open .trd file\n");
129 static void initiate(argc, argv) /* Establish configuration parameters */
141 if ( (argc==4) && (strcmp(argv[3],"r") == 0) ) remote = TRUE;else remote=FALSE;
151 strcpy(filename,argv[2]);
152 strcpy(ProgName,argv[2]);
154 strcpy(mynname,argv[1]);
155 strcat(mynname,".net");
157 sock = socket(AF_UNIX,SOCK_STREAM,0);
158 bzero(&svr, sizeof(svr));
159 svr.sun_family = AF_UNIX;
160 strcpy(svr.sun_path,mynname);
161 len = strlen(svr.sun_path)+sizeof(svr.sun_family);
162 bind(sock,(struct sockaddr*)&svr, len);
166 /* socket for graphic requests */
167 strcpy(mygname,argv[1]);
168 strcat(mygname,".gr");
172 /* socket for KERNEL communication */
173 internal_sock = socket(AF_UNIX,SOCK_STREAM,0);
174 bzero(&svr, sizeof(svr));
175 svr.sun_family = AF_UNIX;
176 strcpy(svr.sun_path,argv[1]);
177 strcpy(mykname,argv[1]);
178 len = strlen(svr.sun_path)+sizeof(svr.sun_family);
179 i=connect(internal_sock,(struct sockaddr*)&svr,len);
183 fcntl(internal_sock,F_SETFL, O_NONBLOCK|fcntl(internal_sock,F_GETFL,0));
188 close(internal_sock);
189 internal_sock = socket(AF_UNIX,SOCK_STREAM,0);
190 fcntl(internal_sock,F_SETFL, O_NONBLOCK|fcntl(internal_sock,F_GETFL,0));
191 i=connect(internal_sock,(struct sockaddr*)&svr,len);
194 setsockopt(internal_sock,IPPROTO_TCP,TCP_NODELAY,(char*)&on,sizeof(on));
196 /* socket for network requests */
197 FD_ZERO(&rset);FD_ZERO(&wset);
199 if (select(sock+1,&rset,&wset,0,0))
200 net_sock = accept(sock,(struct sockaddr*)0,(int *)0);
203 fcntl(net_sock,F_SETFL,O_NONBLOCK|fcntl(net_sock,F_GETFL,0));
204 setsockopt(net_sock,IPPROTO_TCP,TCP_NODELAY,(char*)&on,sizeof(on));
210 load(filename); /* load code and prototypes */
219 eop = (extopcode *)(M+ic); /* pointer to extended opcode in M */
220 lastic = ic; /* save ic for possible redecoding */
222 opcode = ((int) eop->opcode ) & 0xFF ;
228 /* -------------------------------------------------------------------- */
231 void send_to_graph(G_MESSAGE *msg)
233 write(graph_sock,msg,sizeof(G_MESSAGE));
236 int read_from_graph(G_MESSAGE *msg)
239 struct timeval tout={0,0};
241 FD_ZERO(&rset);FD_ZERO(&wset);
242 FD_SET(graph_sock,&rset);
245 if (select(graph_sock+1,&rset,&wset,0,(struct timeval *)&tout)>0)
247 if (FD_ISSET(graph_sock,&rset))
248 return(read(graph_sock,msg,sizeof(G_MESSAGE)));
253 int read_from_net(MESSAGE *msg)
256 struct timeval tout={0,0};
258 FD_ZERO(&rset);FD_ZERO(&wset);
259 FD_SET(net_sock,&rset);
262 if (select(net_sock+1,&rset,&wset,0,(struct timeval *)&tout)>0)
264 if (FD_ISSET(net_sock,&rset))
265 return(read(net_sock,msg,sizeof(MESSAGE)));
271 /* Get graphic resource number */
276 struct sockaddr_un svr;
281 sock = socket(AF_UNIX,SOCK_STREAM,0);
282 bzero(&svr,sizeof(svr));
283 svr.sun_family = AF_UNIX;
284 strcpy(svr.sun_path,mygname);
285 len = strlen(svr.sun_path)+sizeof(svr.sun_family);
286 bind(sock,(struct sockaddr*)&svr, len);
290 msg.msg_type = MSG_GRAPH;
291 msg.param.pword[0] = GRAPH_ALLOCATE;
292 strcpy(msg.param.pstr,mygname);
293 write(internal_sock,&msg,sizeof(MESSAGE));
294 bzero(&msg,sizeof(MESSAGE));
295 FD_ZERO(&rset);FD_ZERO(&wset);
297 if (select(sock+1,&rset,&wset,0,0))
298 graph_sock = accept(sock,(struct sockaddr*)0,(int*)0);
300 if (graph_sock == -1)
302 graphics=FALSE;return(0);
306 fcntl(graph_sock,F_SETFL, O_NONBLOCK|fcntl(graph_sock,F_GETFL,0));
307 setsockopt(graph_sock,IPPROTO_TCP,TCP_NODELAY,(char*)&on,sizeof(on));
311 } /* get_graph_res */
315 void writeln_str(char *s)
318 msg.msg_type = MSG_GRAPH;
319 msg.param.pword[1] = GraphRes;
320 msg.param.pword[2] = GRAPH_WRITE;
321 strcpy(msg.param.pstr,s);
324 strcpy(msg.param.pstr,"\n");
329 void write_str(char *s)
332 msg.msg_type = MSG_GRAPH;
333 msg.param.pword[1] = GraphRes;
334 msg.param.pword[0] = GRAPH_WRITE;
335 strcpy(msg.param.pstr,s);
340 void write_char(char a)
344 msg.msg_type = MSG_GRAPH;
345 msg.param.pword[1] = GraphRes;
346 msg.param.pword[0] = GRAPH_PUTCHAR;
360 msg.msg_type = MSG_GRAPH;
361 msg.param.pword[1] = GraphRes;
362 msg.param.pword[0] = GRAPH_READCHAR;
366 st = read_from_graph(&msg);
369 if ((msg.msg_type == MSG_GRAPH) &&
370 (msg.param.pword[0]==GRAPH_READCHAR_RESPONSE))
371 {ch = msg.param.pchar;break;}
385 msg.msg_type = MSG_GRAPH;
386 msg.param.pword[1] = GraphRes;
387 msg.param.pword[0] = GRAPH_READLN;
391 st = read_from_graph(&msg);
393 if ((msg.msg_type == MSG_GRAPH) && (msg.param.pword[0]== GRAPH_READLN_RESPONSE))
399 void read_str(char *s)
405 msg.msg_type = MSG_GRAPH;
406 msg.param.pword[1] = GraphRes;
407 msg.param.pword[0] = GRAPH_READSTR;
411 st = read_from_graph(&msg);
414 if ((msg.msg_type == MSG_GRAPH) &&
415 (msg.param.pword[0]==GRAPH_READSTR_RESPONSE))
416 { strcpy(ss,msg.param.pstr);break;}
424 /* send message to kernel */
425 void send_to_kernel(MESSAGE *msg)
427 write(internal_sock,msg,sizeof(MESSAGE));
430 /* send message to net */
431 /* 2010 returns 1 if ok and 0 if node desn't exists */
432 int send_to_net(MESSAGE *msg)
436 struct sockaddr_in svr;
440 k = msg->int_msg.control.receiver.node;
442 /* 2010 check if node exists */
443 m.msg_type = MSG_NET;
444 m.param.pword[0] = NET_NODE_EXIST;
445 m.param.pword[1] = k;
446 m.param.pword[2] = my_ctx.program_id;
447 write(net_sock,&m,sizeof(MESSAGE));
448 bzero(&m,sizeof(MESSAGE));
449 while( (m.msg_type!=MSG_NET) && (m.param.pword[0]!=NET_NODE_EXIST) )
450 read(net_sock,&m,sizeof(MESSAGE));
451 if (m.param.pword[1]!=1) return 0;
452 strcpy(addr,m.param.pstr);
454 if (RInstance[k]==-1)
456 bzero(&m,sizeof(MESSAGE));
457 m.msg_type = MSG_VLP;
458 m.param.pword[0] = VLP_REMOTE_INSTANCE_PLEASE;
459 m.param.pword[1] = my_ctx.program_id;
460 m.param.pword[2] = k;
462 bzero(&m,sizeof(MESSAGE));
466 read(internal_sock,&m,sizeof(MESSAGE));
467 if ( (m.msg_type == MSG_VLP) && (m.param.pword[0]==VLP_REMOTE_INSTANCE_HERE)) break;
470 /*printf("DEBUG: remote instance made with id: %d addr %s port %d\n",m.param.pword[1],addr, htons(m.param.pword[8]));*/
471 RInstance[k] = m.param.pword[1];
472 /* Make direct connection */
473 DirConn[k] = socket(AF_INET,SOCK_STREAM,0);
474 svr.sin_family = AF_INET;
475 svr.sin_addr.s_addr = inet_addr(addr);
476 svr.sin_port = htons(m.param.pword[8]);
477 len = connect(DirConn[k],(struct sockaddr*)&svr,sizeof(svr));
482 writeln_str("Cannot connect remote instance!");
486 fcntl(DirConn[k], F_SETFL,O_NONBLOCK | fcntl(DirConn[k], F_GETFL,0));
489 if (RInstance[k]!=-1)
492 write(DirConn[k],&(msg->int_msg),sizeof(message));
499 /* -------------------- Check for message on internal socket -------------*/
510 struct timeval tout={0,0};
515 /* ----------- Direct connection messages -----
521 FD_SET(DirConn[i],&DirSet);
522 if (maxDirSet<DirConn[i]) maxDirSet=DirConn[i];
525 if (select(maxDirSet+1,&DirSet,0,0,(struct timeval *)&tout)>0)
529 if ( (DirConn[i]!=-1) && (FD_ISSET(DirConn[i],&DirSet)) )
531 r=read(DirConn[i],&mx,sizeof(mx));
534 memcpy(globmsgqueue+msgtail,&mx,sizeof(message));
535 msgtail = (msgtail+1) % MAXMSGQUEUE;
541 -----------------------------------------*/
545 FD_SET(net_sock,&rset);
546 FD_SET(internal_sock,&rset);
547 if (net_sock>internal_sock) max = net_sock; else max = internal_sock;
552 FD_SET(DirConn[i],&rset);
553 if (max<DirConn[i]) max=DirConn[i];
557 if (select(max+1,&rset,0,0,(struct timeval *)&tout)>0)
563 if ( (DirConn[i]!=-1) && (FD_ISSET(DirConn[i],&rset)) )
565 /*printf("DEBUG: Interp has message on direct connection: type %d par %d\n",mx.control.type,mx.control.par); */
566 r=read(DirConn[i],&mx,sizeof(mx));
567 if (r>0 && r==sizeof(mx))
569 memcpy(globmsgqueue+msgtail,&mx,sizeof(message));
570 msgtail = (msgtail+1) % MAXMSGQUEUE;
579 if (FD_ISSET(net_sock,&rset))
581 r = read(net_sock, &m, sizeof(MESSAGE));
587 switch(m.param.pword[0])
590 /*printf("DEBUG: cint net_sock MSG_NET NET_PROPAGATE cmd %d\n",m.param.pword[6]);*/
591 memcpy(globmsgqueue+msgtail,&m.int_msg,sizeof(message));
592 msgtail = (msgtail+1) % MAXMSGQUEUE;
600 if (FD_ISSET(internal_sock,&rset))
602 r = read(internal_sock,&m,sizeof(MESSAGE));
609 switch(m.param.pword[0])
611 case INT_CLOSE_INSTANCE: endrun(0);
612 case INT_KILL: endrun(1);
616 if (m.param.pword[0] == NET_PROPAGATE)
618 /*printf("DEBUG: cint internal_sock MSG_NET NET_PROPAGATE cmd %d\n",m.param.pword[6]);*/
619 memcpy(globmsgqueue+msgtail,&m.int_msg,sizeof(message));
620 msgtail = (msgtail+1) % MAXMSGQUEUE;
639 m.msg_type = MSG_INT;
640 m.param.pword[0] = INT_CTX_REQ;
642 while ( (m.msg_type != MSG_INT) || (m.param.pword[0] != INT_CTX) )
643 read(internal_sock,&m,sizeof(MESSAGE));
645 my_ctx.node = m.param.pword[1];
646 my_ctx.program_id = m.param.pword[2];
649 parent_ctx.node = m.param.pword[3];
650 parent_ctx.program_id = m.param.pword[4];
651 RInstance[parent_ctx.node] = parent_ctx.program_id;
655 parent_ctx.node = my_ctx.node;
656 parent_ctx.program_id = my_ctx.program_id;
658 ournode = my_ctx.node;
659 // strcpy(nname,m.param.pstr);
660 // net_sock = open(nname,O_WRONLY);
661 m1.msg_type = MSG_GRAPH;
662 m1.param.pword[0] = GRAPH_SET_TITLE;
663 m1.param.pword[1] = GraphRes;
664 sprintf(m1.param.pstr,
665 "%s ID: %d",ProgName,my_ctx.program_id);
666 if (remote) strcat(m1.param.pstr," REMOTE instance");
675 struct sockaddr_in svr;
677 struct hostent *info;
681 msg.msg_type = MSG_NET;
682 msg.param.pword[0] = NET_PROPAGATE;
683 msg.param.pword[1] = MSG_VLP;
684 msg.param.pword[2] = my_ctx.node;
685 msg.param.pword[4] = parent_ctx.node;
686 msg.param.pword[6] = VLP_REMOTE_INSTANCE_OK;
687 msg.param.pword[7] = my_ctx.program_id;
689 sock = socket(AF_INET,SOCK_STREAM,0);
690 bzero(&svr,sizeof(svr));
691 svr.sin_family = AF_INET;
692 svr.sin_addr.s_addr = INADDR_ANY;
694 bind(sock, (struct sockaddr*)&svr, sizeof(svr));
697 getsockname(sock,(struct sockaddr*)&svr,&len);
698 msg.param.pword[8] = ntohs(svr.sin_port);
699 gethostname(name,&len);
700 info = (struct hostent*)gethostbyname(name);
701 bcopy((char*)info->h_addr,(char*)&svr.sin_addr,info->h_length);
702 sprintf(msg.param.pstr,"%s",inet_ntoa(svr.sin_addr));
703 send_to_kernel(&msg);
705 bzero(&svr,sizeof(svr));
706 DirConn[parent_ctx.node] = accept(sock,(struct sockaddr*)&svr,&len);
707 fcntl(DirConn[parent_ctx.node], F_SETFL,O_NONBLOCK | fcntl(DirConn[parent_ctx.node], F_GETFL,0));
714 initiate(argc, argv); /* initialize executor */
715 runsys(); /* initialize running system */
717 GraphRes = get_graph_res();
718 if ( GraphRes < 0 ) exit(12);
721 if (remote) send_ready();
724 setjmp(contenv); /* set label for continue long jump */
725 while (TRUE) /* repeat until exit() is called */
728 schedule(); /* reschedule current process */
731 decode(); /* fetch instruction */
732 execute(); /* and execute it */