#include "k.h" /* * r e c s w */ recsw(istate) char istate; { state = istate; /* send-initiate or file receive */ /* is the start state */ numtry = 0; /* say no tries yet */ #if debug fprintf(stderr,"recsw -- initial state is %c\n",state); #endif while(TRUE) { #if debug fprintf(stderr,"recsw -- state is now %c\n",state); #endif switch(state) /* do this for as long as necessary */ { case 'D': state = rdata(); /* data receive state */ break; case 'F': state = rfile(); /* file receive state */ break; case 'R': state = rinit(); /* send initiate state */ break; case 'C': return(TRUE); /* complete state */ case 'A': return(FALSE); /* unknown state, abort */ } } } /* * r i n i t */ rinit() { int len, num; if (numtry++ > MAXTRY) return('A'); /* abort if to many tries */ switch(rpack(&len,&num,packet)) /* get a packet */ { case 'S': /* send-init */ { n = num; /* synchronize packet numbers */ rpar(packet); /* get the init data */ spar(packet); /* fill up packet with init info */ spack('Y',n,6,packet); /* ACK with my parameters */ oldtry = numtry; /* save old try count */ numtry = 0; /* and start a new counter */ n = (n+1)%64; /* bump packet number */ return('F'); /* OK, now enter file-send state */ } case FALSE: return (state); /* we didn't receive a packet */ default: return('A'); /* unknown type, abort */ } } /* * r f i l e */ rfile() { int num, len; if (numtry++ > MAXTRY) return('A'); /* abort if too many tries */ switch(rpack(&len,&num,packet)) /* get packet */ { case 'S': /* send-init */ { if (oldtry++ > MAXTRY) return('A'); /* if too many retries, abort */ if (num == n-1) /* check packet number */ { spar(packet); /* get the init params */ spack('Y',num,6,packet); /* it's right, ACK it */ numtry = 0; /* reset try counter */ return(state); } else return('A'); /* sorry, wrong number */ } case 'Z': /* end-of-file */ { if (oldtry++ > MAXTRY) return('A'); if (num == n-1) /* acknowledge good packet */ { spack('Y',num,0,0); numtry = 0; return(state); } else return('A'); /* or abort on bad one */ } case 'F': /* file-header */ { if (num != n) return('A'); getfil(packet); /* open the file */ spack('Y',n,0,0); /* acknowledge */ oldtry = numtry; numtry = 0; n = (n+1)%64; return('D'); /* switch to data state */ } case 'B': /* break transmission */ { if (num != n) return ('A'); spack('Y',n,0,0); /* say OK */ return('C'); /* and go to complete state */ } case FALSE: return(state); default: return ('A'); } } /* * r d a t a */ rdata() { int num, len; if (numtry++ > MAXTRY) return('A'); /* abort if too many tries */ switch(rpack(&len,&num,packet)) /* get packet */ { case 'D': /* data */ { if (num != n) /* right packet? */ { /* no */ if (oldtry++ > MAXTRY) return('A'); /* if too many tries */ if (num == n-1) /* check packet number */ { spar(packet); /* get the init params */ spack('Y',num,6,packet); /* it's right, ACK it */ numtry = 0; /* reset try counter */ return(state); } else return('A'); /* sorry wrong number */ } /* data with right packet number */ bufemp(packet,fd,len); /* write out the packet */ spack('Y',n,0,0); /* right packet, acknowledge */ oldtry = numtry; numtry = 0; n = (n+1)%64; return('D'); /* remain in data state */ } case 'F': /* file-send */ { if (oldtry++ > MAXTRY) return('A'); if (num == n-1) /* acknowledge good packet */ { spack('Y',num,0,0); numtry = 0; return(state); } else return('A'); /* or abort on bad one */ } case 'Z': /* end-of-file */ { if (num != n) return('A'); spack('Y',n,0,0); /* say OK */ close(fd); /* close up the file */ n = (n+1)%64; return('F'); /* and go to file state */ } case FALSE: return(state); default: return('A'); } }