home *** CD-ROM | disk | FTP | other *** search
- /*
- ** ASCII text file transfer using XON / OFF flow control protocol.
- ** Transfer ASCII files only. Do not attempt to transfer binary files.
- */
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <fcntl.h>
- #include <string.h>
- #include <io.h>
- #include <conio.h>
- #include <sys\types.h>
- #include <sys\stat.h>
-
- #include "pcl4c.h"
- #include "ascii.h"
- #include "term_io.h"
- #include "xymodem.h"
- #include "amodem.h"
- #include "term.h"
- #include "win_io.h"
-
- #define FALSE 0
- #define TRUE !FALSE
-
- #define ONE_SECOND 18
-
- char lastXchar; /* last XON or XOFF sent */
-
- int TxAscii(
- int Port, /* COM port [0..3] */
- char Filename[], /* filename buffer */
- char Buffer[], /* data buffer */
- int Length, /* size of Buffer */
- int SyncFlag, /* synchronize with XON 1st */
- int CharPace, /* millisecond delay after sending each character */
- int TermChar, /* termination character (0x00 ==> none) */
- int EchoFlag) /* do local echo if TRUE */
- {int i;
- int Code; /* return code */
- int Handle; /* file Handle */
- char LastChar; /* last character sent */
- int TxChars = 0; /* # characters transmitted */
- int Count; /* # bytes read from disk */
- char Temp[81]; /* temporary buffer */
- /* begin */
- if(!FetchName(Filename)) return FALSE;
- Handle = open(Filename,O_RDONLY|O_BINARY,S_IREAD);
- if(Handle<0)
- {strcpy(Temp,"Cannot open ");
- strcat(Temp,Filename);
- WriteMsg(Temp);
- return FALSE;
- }
- /* do we wait for XON before starting ? */
- if(SyncFlag)
- {/* wait for incoming XON */
- WriteMsg("ASCII: Waiting for XON");
- while(1)
- {if(SioBrkKey())
- {WriteMsg("Canceled by USER");
- return FALSE;
- }
- Code = CharGet(Port,ONE_SECOND);
- if(Code==-1) continue;
- if(Code<0) return FALSE;
- if((char)Code==XON)
- {WriteMsg("ASCII: initial XON received");
- /* slight delay */
- SioDelay(ONE_SECOND/2);
- break;
- }
- /* received character not XON */
- WinPutChar(SCR_WIN,(char)Code);
- }
- }
- /* begin transfer */
- lastXchar = XON;
- WriteMsg("ASCII: Starting send");
- while(kbhit()) getch();
- /* clear comm port */
- SioRxClear(Port);
- /* send ascii file ( stop at ^Z ) */
- while(1)
- {/* read next buffer from disk */
- Count = read(Handle,Buffer,Length);
- if(Count==0) break;
- if(Count<0)
- {SayError(Port,"Error on disk read");
- return FALSE;
- }
- /* send one byte at a time */
- for(i=0;i<Count;i++)
- {/* User ABORTS ? */
- if(UserAborts(Port)) return FALSE;
- /* send byte */
- LastChar = Buffer[i];
- if(EchoFlag) WinPutChar(SCR_WIN,LastChar);
- /* send the character */
- CharPut(Port,LastChar);
- if(CharPace>0) SioDelay(CharPace);
- /* slight delay after each line */
- if(LastChar==LF) SioDelay(4*(CharPace+1));
- TxChars++;
- /* ^Z marks the end of a text file */
- if(LastChar==CTLZ) break;
- /* check for incoming XON */
- if(lastXchar==XON)
- {/* check for incoming XON / XOFF */
- Code = CharGet(Port,0);
- if(Code>0)
- {/* is byte a XOFF ? */
- if((char)Code==XOFF)
- {/* wait for XON */
- WriteMsg("XOFF received");
- lastXchar = XOFF;
- /* wait for XON */
- while(1)
- {/* user want to quit ? */
- if(SioBrkKey())
- {WriteMsg("Canceled by USER");
- return FALSE;
- }
- Code = CharGet(Port,ONE_SECOND);
- if((char)Code==XON)
- {WriteMsg("XON received");
- lastXchar = XON;
- break;
- }
- } /* end -- while */
- } /* end -- if(XOFF) */
- } /* end -- if(Code) */
- } /* end -- if(XON) */
-
- } /* end -- for(i) */
- } /* end -- while */
- close(Handle);
- /* send termination character */
- if(TermChar) CharPut(Port,(char)TermChar);
- sprintf(Temp,"ASCII: %d chars sent.",TxChars);
- WriteMsg(Temp);
- return TRUE;
- } /* end -- TxAcsii */
-
- int RxAscii(
- int Port, /* COM port [0..3] */
- char Filename[], /* filename buffer */
- char Buffer[], /* data buffer */
- int Length, /* length of data buffer */
- int RxQueSize, /* size of PCL receive buffer */
- int SyncFlag, /* synchronize with XON 1st */
- int TermChar, /* termination character (0x00 ==> none) */
- int TimeOut, /* delay (seconds) before assuming that sender is done */
- int EchoFlag) /* do local echo if TRUE */
- {int i;
- int Handle; /* file Handle */
- int Code; /* return code */
- int lo; /* receive queue low water mark */
- int hi; /* receive queue high water mark */
- int Index; /* buffer index */
- int QueSize; /* current PCL receive queue size */
- int RxChars = 0; /* # received chars */
- int Count; /* # characters written to disk */
- char Temp[81]; /* temporary buffer */
- long LastTime; /* time last character was received */
- /* begin */
- lastXchar = XON;
- lo = RxQueSize / 8;
- hi = 5 * lo;
- WriteMsg("ASCII: Starting receive ");
- while(kbhit()) getch();
- /* clear comm port */
- /*SioRxClear(Port);*/
- /* open file passed in Filename[] for write */
- if(!FetchName(Filename)) return FALSE;
- Handle = open(Filename,O_CREAT|O_TRUNC|O_WRONLY|O_BINARY,S_IWRITE);
- if(Handle<0)
- {strcpy(Temp,"Cannot open ");
- strcat(Temp,Filename);
- WriteMsg(Temp);
- return FALSE;
- }
- /* sync with XON 1st ? */
- if(SyncFlag)
- {WriteMsg("ASCII: Sending initial XON");
- while(1)
- {CharPut(Port,XON);
- Code = CharGet(Port,ONE_SECOND);
- if(Code==-1) continue;
- /* transmitter is sending ! */
- SioUnGetc(Port,(char)Code);
- break;
- }
- }
- /* receive text */
- LastTime = SioTimer();
- Index = 0;
- while(1)
- {/* user want to quit ? */
- if(SioBrkKey())
- {WriteMsg("Canceled by USER");
- return FALSE;
- }
- /* check on PCL receive queue size */
- QueSize = SioRxQue(Port);
- if((QueSize>hi)&&(lastXchar==XON))
- {CharPut(Port,XOFF);
- lastXchar = XOFF;
- WriteMsg("sending XOFF(1)");
- /*sprintf(Temp,"\nQueSize=%d lo=%d hi=%d\n",QueSize,lo,hi);*/
- /*WriteMsg(Temp);*/
- }
- if((QueSize<lo)&&(lastXchar==XOFF))
- {CharPut(Port,XON);
- lastXchar = XON;
- WriteMsg("sending XON ");
- }
- /* User ABORTS ? */
- if(UserAborts(Port)) return FALSE;
- /* get next byte */
- Code = CharGet(Port,ONE_SECOND);
- if(Code==-1)
- {/* done if have exceeded timeout */
- if(SioTimer()-LastTime>ONE_SECOND*TimeOut)
- {/* sender must be done */
- Buffer[Index] = CTLZ;
- break;
- }
- continue;
- }
- /* ignore 1st character if it is a 0 */
- if((RxChars==0)&&((char)Code=='\0')) continue;
- LastTime = SioTimer();
- /* ignore XON & XOFF ( since we are the receiver ) */
- if((char)Code==XON) continue;
- if((char)Code==XOFF) continue;
- /* received a character */
- Buffer[Index++] = (char)Code;
- RxChars++;
- /* TermChar marks the end of a text file */
- if((char)Code==TermChar)
- {/* replace TermChar with ^Z */
- Buffer[Index-1] = CTLZ;
- RxChars++;
- break;
- }
- if(EchoFlag) WinPutChar(SCR_WIN,(char)Code);
- if(Index==Length)
- {/* send XOFF to transmitter */
- CharPut(Port,XOFF);
- lastXchar = XOFF;
- WriteMsg("sending XOFF(2)");
- /* write disk file */
- Count = write(Handle,Buffer,Index);
- if(Count<0)
- {SayError(Port,"Disk write error");
- SioDelay(ONE_SECOND);
- return FALSE;
- }
- /* send XON to sender */
- CharPut(Port,XON);
- lastXchar = XON;
- WriteMsg("sending XON ");
- Index = 0;
- } /* end -- if */
- } /* end -- while */
- /* write any remaining data in buffer */
- if(Index>0)
- {Count = write(Handle,Buffer,Index);
- if(Count<0)
- {SayError(Port,"Disk write error");
- SioDelay(ONE_SECOND);
- return FALSE;
- }
- } /* end -- if */
- close(Handle);
- sprintf(Temp,"ASCII: %d chars received.",RxChars);
- WriteMsg(Temp);
- return TRUE;
- } /* RxAscii */
-
- int UserAborts(int Port)
- {char UserChar;
- /* user aborts ? */
- if(kbhit())
- {UserChar = (char)getch();
- if(UserChar==CAN)
- {TxCAN(Port);
- CharPut(Port,ETX);
- WriteMsg("*** Canceled by USER ***");
- return TRUE;
- }
- /* send user char */
- CharPut(Port,UserChar);
- }
- return FALSE;
- } /* UserAborts */