ENV #include #include #include #include #include #include #include /* Added returns of -1 on error, 0 for Okay. -Kdz */ xx_getserv(host,num,sock,rc) char *host; int *num; int *sock; int *rc; { struct sockaddr_in sin; struct servent *sp; struct hostent *hp; int s,i=0; char server[5]; int flag=0; /* better check NULL, too. -Kdz */ if ( (num == NULL) || (*num > 40) || (*num < 1) ) { printf("Error in getserv: server number unknown\n"); *rc = 1; return(-1); } s = socket(AF_INET,SOCK_STREAM,0); setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char *) 0,0); if ( (hp = gethostbyname(host)) == NULL ) { printf("Error in getserv: %s: unknown host\n",host); *rc = 2; close(s); return(-1); } else printf("sox.U DEBUG: hp = %x\n",hp); sprintf(server,"jak%d",*num); if ( (sp = getservbyname(server,"tcp")) == NULL ) { printf("Error in getserv: for %d server %s unknown on %s\n", ntohl(xx_my_id.proc_table_indx),server,host); *rc = 3; close(s); return(-1); } bzero( (char *) &sin, sizeof(sin) ); bcopy( hp->h_addr, (char *) &sin.sin_addr, hp->h_length ); sin.sin_family = hp->h_addrtype; sin.sin_port = sp->s_port; if (flag = connect( s, (char *) &sin, sizeof(sin))) { perror("Error in getserv connect"); *rc = 4; close(s); return(-1); } *sock = s; *rc = 0; return(0); } xx_sendserv(sock,proc_id,msg_type,msgtype_len,msg,length,ack) int sock; PROC_ID *proc_id; int msg_type,msgtype_len; char *msg; int length,ack; { int n=0; struct xx_msg_rec *buff,buff2; PROC_ID temp; buff = &buff2; WHO_AM_I(&temp); bcopy(proc_id,&(buff->target),sizeof(PROC_ID)); bcopy(&temp,&(buff->sender),sizeof(PROC_ID)); buff->ack = htonl(ack); buff->msg_type = htonl(msg_type); if ( msg ) { n = length ? length : msgtype_len; bcopy(msg,buff->data,n); } buff->length = htonl(n); if ( send(sock,buff, sizeof(struct xx_msg_rec)-(MSG_BUFF_SIZE-n), 0) == -1 ) { perror("Error in xx_sendserv send"); return(-1); } /* printf("Slave: %d just sent msg to %d size %d\n",ntohl(xx_my_id.proc_table_indx),ntohl(proc_id->proc_table_indx),n); */ return(0); } xx_recvserv(sock,bufr,ln,rc) int sock; char *bufr; int *ln; int *rc; { /* got rid of unneeded temps. -Kdz */ if ( (*rc = recv(sock,bufr,*ln,0)) == -1 ) { printf("Error in recvserv for %d\n",ntohl(xx_my_id.proc_table_indx)); *rc = 2; return(-1); } return(0); } xx_makeserv(soc_id) int soc_id; { int rc,ln,f,flag,unix_id; int soc2,port; int pid; struct sockaddr_in from; struct sockaddr_in sin; struct servent *sp; struct xx_msg_rec buf; char server[5]; extern int errno; bzero( (char *) &sin, sizeof(sin) ); if ((f = socket(AF_INET,SOCK_STREAM,0)) == -1) { printf("Error in makeserv: socket() error %d\n",errno); exit(errno); } if (setsockopt(f,SOL_SOCKET,SO_REUSEADDR,(char *) 0,0) == -1) { printf("Error in makeserv: setsocketopt() error %d\n",errno); exit(errno); } flag = 1; /* Locate an available port */ for (port = 2;( (port < 39) && flag );port++) { sprintf(server,"jak%d",port); sp = getservbyname(server,"tcp"); if ( sp == NULL ) { printf("Error in makeserv: server unknown\n"); close(f); exit(errno); } sin.sin_port = sp->s_port; flag = bind( f, (char *) &sin, sizeof(sin) ); if ((flag != 0) && (errno != EADDRINUSE)) { perror("Makeserv: error in bind errno = %d\n",errno); close(f); exit(); } if ( port > 39 ) { printf("Error in makeserv: no ports available\n"); exit(); } } if ( listen(f,5) != 0 ) { close(f); printf ("Makeserv: error in listen %d\n",errno); exit(); } /* Send port info to master */ ln = sizeof(struct xx_msg_rec) - MSG_BUFF_SIZE; buf.msg_type = htonl(--port); send(soc_id,(char *) &buf,ln,rc); /* put port info in parent's proc table entry */ xx_cmem->active_processes[ntohl(xx_my_id.proc_table_indx)]->port= port; /* loop */ for (;;) { ln = sizeof(from); soc2 = accept( f, &from, &ln ); while ( soc2 < 0 ) { if ( errno == 4) { soc2 = accept( f, &from, &ln ); } else { close(f); printf ("Ser: error in accept %d\n",errno); exit(); } } /* creat listener */ if ( (unix_id = fork()) ==0 ) { close(f); xx_listener(soc2); } *(xx_pt_upid++) = unix_id; close(soc2); } } xx_listener(soc_id) int soc_id; { struct xx_msg_rec *buf_pt; struct xx_msg_rec buf; struct xx_process *p1; struct xx_msg *xx_m1; char rest[MSG_BUFF_SIZE]; int target_indx; int msg_length; int bytes; int more; int ln; buf_pt = &buf; for (;;) { bytes = 0; ln = sizeof(struct xx_msg_rec) - (MSG_BUFF_SIZE*sizeof(char)); while ( bytes < ln ) { more = recv(soc_id,rest,ln-bytes,0); if ( more == -1 ) { perror("Error in xx_listener header recv"); return; } bcopy(rest,((char *) buf_pt)+bytes,more); bytes += more; } msg_length = htonl(buf_pt->length); bytes = 0; while ( bytes < msg_length ) { more = recv(soc_id,rest,msg_length-bytes,0); if ( more == -1 ) { perror("Error in xx_listener message recv"); return; } bcopy(rest,buf_pt->data+bytes,more); bytes += more; } /* Now stuff message into queue */ xx_msgbuf(&xx_m1,msg_length); xx_m1->sender = buf_pt->sender; xx_m1->link = 0; xx_m1->type = ntohl(buf_pt->msg_type); xx_m1->ack = ntohl(buf_pt->ack); target_indx = ntohl(buf_pt->target.proc_table_indx); p1 = xx_cmem->active_processes[target_indx]; if (p1 == 0) { printf ("Listener: no entry for id = %d \n", ntohl(buf_pt->target.proc_table_indx)); exit(); } xx_msgcpy(buf_pt->data,msg_length,&p1,xx_m1); } } xx_connect(proc_id) PROC_ID *proc_id; { int n,so,i,rc; struct xx_process *p1; n = ntohl(proc_id->port); xx_getserv(proc_id->host,&n,&so,&rc); p1 = (struct xx_process *) G_MALLOC(sizeof(struct xx_process)); xx_cmem->active_processes[ntohl(proc_id->proc_table_indx)] = p1; p1->socket_id = so; p1->port = ntohl(proc_id->port); MONINIT(p1->msg_q_monitor,1) p1->first_msg = p1->last_msg = 0; /* for (i=0;i<64;i++) p1->host[i] = proc_id->host[i]; */ bcopy(proc_id->host,p1->host,64); } /* using Network-Byte Order instead of strings. -Kdz */ xx_copy_ntoh(xx_pt1,xx_pt2) PROC_ID *xx_pt1; struct xx_proc_id *xx_pt2; { int xx_i; xx_pt1->proc_table_indx = ntohl(xx_pt2->proc_table_indx); xx_pt1->port = ntohl(xx_pt2->port); /* for (xx_i=0;xx_i<64;xx_i++) xx_pt1->host[xx_i] = xx_pt2->host[xx_i];*/ bcopy(xx_pt2->host,xx_pt1->host,64); } xx_copy_hton(xx_pt1,xx_pt2) PROC_ID *xx_pt2; struct xx_proc_id *xx_pt1; { int xx_i; /* sprintf(xx_pt1->proc_table_indx,"%d",xx_pt2->proc_table_indx); sprintf(xx_pt1->port,"%d",xx_pt2->port); */ xx_pt2->proc_table_indx = htonl(xx_pt1->proc_table_indx); xx_pt2->port = htonl(xx_pt1->port); bcopy(xx_pt2->host,xx_pt1->host,64); /* for (xx_i=0;xx_i<64;xx_i++) xx_pt1->host[xx_i] = xx_pt2->host[xx_i]; */ } xx_cmp_id(xx_pt1,xx_pt2) PROC_ID *xx_pt1,*xx_pt2; { return(xx_pt1->proc_table_indx == xx_pt2->proc_table_indx); } xx_copy_id(xx_pt1,xx_pt2) PROC_ID *xx_pt1,*xx_pt2; { /* USE bcopy instead -kdz */ /* int xx_i; xx_pt1->proc_table_indx = xx_pt2->proc_table_indx; xx_pt1->port = xx_pt2->port; for (xx_i=0;xx_i<64;xx_i++) xx_pt1->host[xx_i] = xx_pt2->host[xx_i]; */ bcopy(xx_pt2, xx_pt1, sizeof(PROC_ID) ); } xx_cleanup() { int i; struct xx_process *p1; union wait status; /* printf("Cleanup: for %d \n",ntohl(xx_my_id.proc_table_indx)); */ for (i=0;iactive_processes[i]; if (((int)p1>1) && (i != ntohl(xx_my_id.proc_table_indx)) && (i !=0)) { if ( p1->upid ) { if ( kill(p1->upid,9) == -1 ) { printf ("Error %d in cleanup killing process %d\n", errno,p1->upid); } else if (wait(&status) == -1) printf("Cleanup: error in wait for %d \n",ntohl(xx_my_id.proc_table_indx)); } } } } xx_handler(sig,code,scp) int sig,code; struct sigcontext *scp; { int pid; jmp_buf env; union wait status; scp = (struct sigcontext *) malloc(sizeof(struct sigcontext)); if ( (pid = wait(&status)) == -1) { printf("Ser: handler failed %d\n",errno); }; /* printf ("Ser: in handler on signal %d \n",sig); printf("Ser: return from wait for %d \n",pid); */ longjmp(env,pid); } xx_kill_daemon() { union wait status; if ( kill(xx_daemon,9) == -1 ) { printf ("Error %d in cleanup killing process %d\n", errno,xx_daemon); } else if (wait(&status) == -1) printf("Cleanup: error in wait for %d \n",ntohl(xx_my_id.proc_table_indx)); } xx_kill_grandkids() { int i; union wait status; /* */ xx_pt_upid = xx_upid; printf("Cleanup: for %d \n",ntohl(xx_my_id.proc_table_indx)); while ( *(xx_pt_upid) ) { if ( kill(*(xx_pt_upid),9) == -1 ) { printf ("Error %d in cleanup killing process %d\n", errno,*(xx_pt_upid)); } xx_pt_upid++; } }