#include "k.h" /* * s e n d s w * * sendsw is the state tabel swticher for sending files. It loops * until either it is finished or an error is encountered. The * routines called by sensw are responsible for changing the state. */ sendsw() { state = 'S'; /* Send initiate is the start state */ numtry = 0; /* Say no tries yet */ gnxtfl(); #if debug fprintf(stderr,"sendsw -- sending %s\n",filestr); #endif while(TRUE) /* Do this as long as necessary */ { #if debug fprintf(stderr,"sendsw -- state is now %c\n",state); #endif switch(state) { case 'D': state = sdata(); /* Data-Send state */ break; case 'F': state = sfile(); /* File-Send */ break; case 'Z': state = seof(); /* End-of-File */ break; case 'S': state = sinit(); /* Send-Init */ break; case 'B': state = sbreak(); /* Break-Send */ break; case 'C': return (TRUE); /* Complete */ case 'A': return (FALSE); /* Abort */ default: return (FALSE); /* Unknown, abort */ } } } /* * s i n i t */ sinit() { int num, len; if (numtry++ > MAXTRY) /* If too many tries, abort */ return('A'); spar(packet); /* Fill up with init info */ spack('S',n,6,packet); /* Send an 'S' packet */ switch(rpack(&len,&num,recpkt)) /* What was the reply? */ { case 'N': /* NAK */ /* if (n != num--) */ return(state); /* NAK for next pack = ACK */ case 'Y': /* ACK */ { if (n != num) /* If wrong ACK, fail */ return(state); rpar(recpkt); /* Get the init info */ if (eol == 0) /* check and set defaults */ eol = '\n'; if (quote == 0) quote = '#'; numtry = 0; /* reset try counter */ n = (n+1)%64; /* and bump packet count */ fd = open(filestr,0); /* Open the file to read */ return('F'); /* switch state to F */ } case FALSE: /* Receive failure, fail */ return(state); default: /* Just abort */ return('A'); } } /* * s f i l e */ sfile() { int num, len; if (numtry++ > MAXTRY) /* If too many tries, abort */ return('A'); for (len=0; filestr[len] != '\0'; len++); /* count the length */ spack('F',n,len,filestr); /* send an 'F' packet */ switch(rpack(&len,&num,recpkt)) { /* What was the reply? */ case 'N': /* NAK */ if (n != num--) return(state); /* NAK for next packet = ACK */ case 'Y': /* ACK */ { if (n != num) /* If wrong ACK, fail */ return(state); numtry = 0; /* reset try counter */ n = (n+1)%64; /* and bump packet count */ size = bufill(packet); /* get first packet of data from file */ return('D'); /* switch state to D */ } case FALSE: /* receive failure, fail */ return(state); default: /* Just abort */ return('A'); } } /* * s d a t a */ sdata() { int num, len; if (numtry++ > MAXTRY) /* If too many tries, abort */ return('A'); spack('D',n,size,packet); /* send a 'D' packet */ switch(rpack(&len,&num,recpkt)) { /* What was the reply */ case 'N': /* NAK */ if (n != num--) return(state); /* NAK for next pack = ACK */ case 'Y': /* ACK */ { if (n != num) /* If wrong ACK, fail */ return(state); numtry = 0; /* reset try counter */ n = (n+1)%64; /* and bump packet count */ if ((size = bufill(packet)) == EOF) /* get the data from file */ return('Z'); /* if EOF set state to it */ return('D'); /* switch state to 'D' */ } case FALSE: /* receive failure, fail */ return(state); default: /* just abort */ return('A'); } } /* * s e o f */ seof() { int num, len; if (numtry++ > MAXTRY) /* If too many tries, abort */ return('A'); spack('Z',n,0,packet); /* Send a 'Z' packet */ switch(rpack(&len,&num,recpkt)) { /* What was the reply? */ case 'N': /* NAK */ if (n != num--) return(state); /* NAK for next packet=ACK */ case 'Y': /* ACK */ { if (n != num) /* if wrong ACK, fail */ return(state); numtry = 0; /* reset try counter */ n = (n+1)%64; /* and bump packet count */ close(fd); if (gnxtfl() == EOF) /* No more files go to break */ return('B'); fd = open(filestr,0); /* open the next file */ return('F'); /* switch state to F */ } case FALSE: /* Receive failure, fail */ return(state); default: /* just abort */ return('A'); } } /* * s b r e a k */ sbreak() { int num, len; if (numtry++ > MAXTRY) /* If too many tries abort */ return('A'); spack('B',n,0,packet); /* Send a B packet */ switch (rpack(&len,&num,recpkt)) { /* What was the reply? */ case 'N': /* NAK */ if (n != num--) return(state); /* NAK for next pack = ACK */ case 'Y': /* ACK */ { if (n != num) /* If wrong ACK, fail */ return(state); numtry = 0; /* reset try counter */ n = (n+1)%64; /* and bump packet count */ return('C'); /* switch state to C */ } case FALSE: /* receive failure, fail */ return(state); default: /* just abort */ return ('A'); } }