home *** CD-ROM | disk | FTP | other *** search
/ Beijing Paradise BBS Backup / PARADISE.ISO / software / BBSDOORW / PPL4C11.ZIP / AMODEM.C < prev    next >
Encoding:
C/C++ Source or Header  |  1995-11-18  |  9.5 KB  |  298 lines

  1. /*
  2. **  ASCII text file transfer using XON / OFF flow control protocol.
  3. **  Transfer ASCII files only. Do not attempt to transfer binary files.
  4. */
  5.  
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <fcntl.h>
  9. #include <string.h>
  10. #include <io.h>
  11. #include <conio.h>
  12. #include <sys\types.h>
  13. #include <sys\stat.h>
  14.  
  15. #include "pcl4c.h"
  16. #include "ascii.h"
  17. #include "term_io.h"
  18. #include "xymodem.h"
  19. #include "amodem.h"
  20. #include "term.h"
  21. #include "win_io.h"
  22.  
  23. #define FALSE 0
  24. #define TRUE !FALSE
  25.  
  26. #define ONE_SECOND 18
  27.  
  28. char lastXchar;     /* last XON or XOFF sent */
  29.  
  30. int TxAscii(
  31.   int Port,            /* COM port [0..3] */
  32.   char Filename[],     /* filename buffer */
  33.   char Buffer[],       /* data buffer */
  34.   int Length,          /* size of Buffer */
  35.   int SyncFlag,        /* synchronize with XON 1st */
  36.   int CharPace,        /* millisecond delay after sending each character */
  37.   int TermChar,        /* termination character (0x00 ==> none) */
  38.   int EchoFlag)        /* do local echo if TRUE */
  39. {int i;
  40.  int Code;           /* return code */
  41.  int Handle;         /* file Handle */
  42.  char LastChar;      /* last character sent */
  43.  int TxChars = 0;    /* # characters transmitted */
  44.  int Count;          /* # bytes read from disk */
  45.  char Temp[81];      /* temporary buffer */
  46.  /* begin */
  47.  if(!FetchName(Filename)) return FALSE;
  48.  Handle = open(Filename,O_RDONLY|O_BINARY,S_IREAD);
  49.  if(Handle<0)
  50.      {strcpy(Temp,"Cannot open ");
  51.       strcat(Temp,Filename);
  52.       WriteMsg(Temp);
  53.       return FALSE;
  54.      }
  55.  /* do we wait for XON before starting ? */
  56.  if(SyncFlag)
  57.    {/* wait for incoming XON */
  58.     WriteMsg("ASCII: Waiting for XON");
  59.     while(1)
  60.        {if(SioBrkKey())
  61.           {WriteMsg("Canceled by USER");
  62.            return FALSE;
  63.           }
  64.         Code = CharGet(Port,ONE_SECOND);
  65.         if(Code==-1) continue;
  66.         if(Code<0) return FALSE;
  67.         if((char)Code==XON)
  68.            {WriteMsg("ASCII: initial XON received");
  69.             /* slight delay */
  70.             SioDelay(ONE_SECOND/2);
  71.             break;
  72.            }
  73.         /* received character not XON */
  74.         WinPutChar(SCR_WIN,(char)Code);
  75.        }
  76.    }
  77.  /* begin transfer */
  78.  lastXchar =  XON;
  79.  WriteMsg("ASCII: Starting send");
  80.  while(kbhit()) getch();
  81.  /* clear comm port */
  82.  SioRxClear(Port);
  83.  /* send ascii file ( stop at ^Z ) */
  84.  while(1)
  85.      {/* read next buffer from disk */
  86.       Count = read(Handle,Buffer,Length);
  87.       if(Count==0) break;
  88.       if(Count<0)
  89.           {SayError(Port,"Error on disk read");
  90.            return FALSE;
  91.           }
  92.       /* send one byte at a time */
  93.       for(i=0;i<Count;i++)
  94.           {/* User ABORTS ? */
  95.            if(UserAborts(Port)) return FALSE;
  96.            /* send byte */
  97.            LastChar = Buffer[i];
  98.            if(EchoFlag) WinPutChar(SCR_WIN,LastChar);
  99.            /* send the character */
  100.            CharPut(Port,LastChar);
  101.            if(CharPace>0) SioDelay(CharPace);
  102.            /* slight delay after each line */
  103.            if(LastChar==LF) SioDelay(4*(CharPace+1));
  104.            TxChars++;
  105.            /* ^Z marks the end of a text file */
  106.            if(LastChar==CTLZ) break;
  107.            /* check for incoming XON */
  108.            if(lastXchar==XON)
  109.                 {/* check for incoming XON / XOFF */
  110.                  Code = CharGet(Port,0);
  111.                  if(Code>0)
  112.                     {/* is byte a XOFF ? */
  113.                      if((char)Code==XOFF)
  114.                          {/* wait for XON */
  115.                           WriteMsg("XOFF received");
  116.                           lastXchar = XOFF;
  117.                           /* wait for XON */
  118.                           while(1)
  119.                               {/* user want to quit ? */
  120.                                if(SioBrkKey())
  121.                                    {WriteMsg("Canceled by USER");
  122.                                     return FALSE;
  123.                                    }
  124.                                Code = CharGet(Port,ONE_SECOND);
  125.                                if((char)Code==XON)
  126.                                    {WriteMsg("XON  received");
  127.                                     lastXchar = XON;
  128.                                     break;
  129.                                    }
  130.                               } /* end -- while */
  131.                          } /* end -- if(XOFF) */
  132.                     } /* end -- if(Code) */
  133.                 } /* end -- if(XON) */
  134.  
  135.           } /* end -- for(i) */
  136.      } /* end -- while */
  137.  close(Handle);
  138.  /* send termination character */
  139.  if(TermChar) CharPut(Port,(char)TermChar);
  140.  sprintf(Temp,"ASCII: %d chars sent.",TxChars);
  141.  WriteMsg(Temp);
  142.  return TRUE;
  143. } /* end -- TxAcsii */
  144.  
  145. int RxAscii(
  146.   int Port,            /* COM port [0..3] */
  147.   char Filename[],     /* filename buffer */
  148.   char Buffer[],       /* data buffer */
  149.   int Length,          /* length of data buffer */
  150.   int RxQueSize,       /* size of PCL receive buffer */
  151.   int SyncFlag,        /* synchronize with XON 1st */
  152.   int TermChar,        /* termination character (0x00 ==> none) */
  153.   int TimeOut,         /* delay (seconds) before assuming that sender is done */
  154.   int EchoFlag)        /* do local echo if TRUE */
  155. {int i;
  156.  int Handle;         /* file Handle */
  157.  int Code;           /* return code */
  158.  int lo;             /* receive queue low water mark */
  159.  int hi;             /* receive queue high water mark */
  160.  int Index;          /* buffer index */
  161.  int QueSize;        /* current PCL receive queue size */
  162.  int RxChars = 0;    /* # received chars */
  163.  int Count;          /* # characters written to disk */
  164.  char Temp[81];      /* temporary buffer */
  165.  long LastTime;      /* time last character was received */
  166.  /* begin */
  167.  lastXchar = XON;
  168.  lo = RxQueSize / 8;
  169.  hi = 5 * lo;
  170.  WriteMsg("ASCII: Starting receive ");
  171.  while(kbhit()) getch();
  172.  /* clear comm port */
  173.    /*SioRxClear(Port);*/
  174.  /* open file passed in Filename[] for write */
  175.  if(!FetchName(Filename)) return FALSE;
  176.  Handle = open(Filename,O_CREAT|O_TRUNC|O_WRONLY|O_BINARY,S_IWRITE);
  177.  if(Handle<0)
  178.      {strcpy(Temp,"Cannot open ");
  179.       strcat(Temp,Filename);
  180.       WriteMsg(Temp);
  181.       return FALSE;
  182.      }
  183.  /* sync with XON 1st ? */
  184.  if(SyncFlag)
  185.     {WriteMsg("ASCII: Sending initial XON");
  186.      while(1)
  187.         {CharPut(Port,XON);
  188.          Code = CharGet(Port,ONE_SECOND);
  189.          if(Code==-1) continue;
  190.          /* transmitter is sending ! */
  191.          SioUnGetc(Port,(char)Code);
  192.          break;
  193.         }
  194.     }
  195.  /* receive text */
  196.  LastTime = SioTimer();
  197.  Index = 0;
  198.  while(1)
  199.      {/* user want to quit ? */
  200.       if(SioBrkKey())
  201.           {WriteMsg("Canceled by USER");
  202.            return FALSE;
  203.           }
  204.       /* check on PCL receive queue size */
  205.       QueSize = SioRxQue(Port);
  206.       if((QueSize>hi)&&(lastXchar==XON))
  207.           {CharPut(Port,XOFF);
  208.            lastXchar = XOFF;
  209.            WriteMsg("sending XOFF(1)");
  210.            /*sprintf(Temp,"\nQueSize=%d lo=%d hi=%d\n",QueSize,lo,hi);*/
  211.            /*WriteMsg(Temp);*/
  212.           }
  213.       if((QueSize<lo)&&(lastXchar==XOFF))
  214.           {CharPut(Port,XON);
  215.            lastXchar = XON;
  216.            WriteMsg("sending XON ");
  217.           }
  218.       /* User ABORTS ? */
  219.       if(UserAborts(Port)) return FALSE;
  220.       /* get next byte */
  221.       Code = CharGet(Port,ONE_SECOND);
  222.       if(Code==-1)
  223.          {/* done if have exceeded timeout */
  224.           if(SioTimer()-LastTime>ONE_SECOND*TimeOut)
  225.             {/* sender must be done */
  226.              Buffer[Index] = CTLZ;
  227.              break;
  228.             }
  229.           continue;
  230.          }
  231.       /* ignore 1st character if it is a 0 */
  232.       if((RxChars==0)&&((char)Code=='\0')) continue;
  233.       LastTime = SioTimer();
  234.       /* ignore XON & XOFF ( since we are the receiver ) */
  235.       if((char)Code==XON) continue;
  236.       if((char)Code==XOFF) continue;
  237.       /* received a character */
  238.       Buffer[Index++] = (char)Code;
  239.       RxChars++;
  240.       /* TermChar marks the end of a text file */
  241.       if((char)Code==TermChar)
  242.           {/* replace TermChar with ^Z */
  243.            Buffer[Index-1] = CTLZ;
  244.            RxChars++;
  245.            break;
  246.           }
  247.       if(EchoFlag) WinPutChar(SCR_WIN,(char)Code);
  248.       if(Index==Length)
  249.           {/* send XOFF to transmitter */
  250.            CharPut(Port,XOFF);
  251.            lastXchar = XOFF;
  252.            WriteMsg("sending XOFF(2)");
  253.            /* write disk file */
  254.            Count = write(Handle,Buffer,Index);
  255.            if(Count<0)
  256.                {SayError(Port,"Disk write error");
  257.                 SioDelay(ONE_SECOND);
  258.                 return FALSE;
  259.                }
  260.            /* send XON to sender */
  261.            CharPut(Port,XON);
  262.            lastXchar = XON;
  263.            WriteMsg("sending XON ");
  264.            Index = 0;
  265.           } /* end -- if */
  266.      } /* end -- while */
  267.  /* write any remaining data in buffer */
  268.  if(Index>0)
  269.      {Count = write(Handle,Buffer,Index);
  270.       if(Count<0)
  271.           {SayError(Port,"Disk write error");
  272.            SioDelay(ONE_SECOND);
  273.            return FALSE;
  274.           }
  275.      } /* end -- if */
  276.  close(Handle);
  277.  sprintf(Temp,"ASCII: %d chars received.",RxChars);
  278.  WriteMsg(Temp);
  279.  return TRUE;
  280. } /* RxAscii */
  281.  
  282. int UserAborts(int Port)
  283. {char UserChar;
  284.  /* user aborts ? */
  285.  if(kbhit())
  286.     {UserChar = (char)getch();
  287.      if(UserChar==CAN)
  288.        {TxCAN(Port);
  289.         CharPut(Port,ETX);
  290.         WriteMsg("*** Canceled by USER ***");
  291.         return TRUE;
  292.        }
  293.      /* send user char */
  294.      CharPut(Port,UserChar);
  295.     }
  296.  return FALSE;
  297. } /* UserAborts */
  298.