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

  1. /* xymodem.c */
  2.  
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #include <fcntl.h>
  7. #include <io.h>
  8. #include <conio.h>
  9. #include <sys\types.h>
  10. #include <sys\stat.h>
  11.  
  12. #include "pcl4c.h"
  13. #include "ascii.h"
  14. #include "term_io.h"
  15. #include "xypacket.h"
  16. #include "xymodem.h"
  17. #include "dir_io.h"
  18. #include "timing.h"
  19.  
  20. #define ABORT_CHAR CAN
  21.  
  22. #define FALSE 0
  23. #define TRUE !FALSE
  24.  
  25.  
  26. static int DataBits = WordLength8;
  27. static int StopBits = OneStopBit;
  28. static int Parity = NoParity;
  29.  
  30. static void Set8N1(int Port)
  31. {int  PSL;
  32.  PSL = SioRead(Port,3);
  33.  DataBits = 0x03 & PSL;
  34.  StopBits = 0x01 & (PSL>>2);
  35.  Parity = 0x07 & (PSL>>3);
  36.  /* set 8N1 */
  37.  SioParms(Port,NoParity,OneStopBit,WordLength8);
  38. }
  39.  
  40. static void RestorePSL(int Port)
  41. {/* restore old setting */
  42.  SioParms(Port,Parity,StopBits,DataBits);
  43. }
  44.  
  45. int TxyModem(
  46.    int Port,            /* COM port [0..3] */
  47.    char *Filename,      /* filename buffer */
  48.    char *Buffer,        /* data buffer */
  49.    int OneKflag,        /* if TRUE, use 1K blocks when possible */
  50.    int BatchFlag)       /* if TRUE, send filename in packet 0 */
  51. {int  i, k;
  52.  int  Code;
  53.  int  Handle;            /* file Handle */
  54.  long Tics;
  55.  char c;
  56.  int  p;
  57.  char PacketType;
  58.  char PacketNbr;
  59.  int  PacketSize = 128;
  60.  int  FirstPacket;
  61.  unsigned short CheckSum;
  62.  int Number1K = 0;       /* total # 1K packets */
  63.  int Number128 = 0;      /* total # 128 byte packets */
  64.  char NCGchar = NAK;
  65.  long FileSize;
  66.  char Temp[81];
  67.  int EmptyFlag = FALSE;
  68.  /* begin */
  69.  Set8N1(Port);
  70.  if(BatchFlag) if(Filename[0]=='\0') EmptyFlag = TRUE;
  71.  if(!EmptyFlag)
  72.      {/* Filename is not empty */
  73.       EmptyFlag = FALSE;
  74.       Handle = open(Filename,O_RDONLY|O_BINARY,S_IREAD);
  75.       if(Handle<0)
  76.           {strcpy(Temp,"Cannot open ");
  77.            strcat(Temp,Filename);
  78.            WriteMsg(Temp);
  79.            RestorePSL(Port);
  80.            return(FALSE);
  81.           }
  82.      }
  83.  WriteMsg("XYMODEM send: waiting for Receiver ");
  84.  while(kbhit()) getch();
  85.  /* compute # blocks */
  86.  if(!EmptyFlag)
  87.      {FileSize = filelength(Handle);
  88.       if(OneKflag) Number1K = (int) (FileSize / 1024L);
  89.       Number128 = (int) ((FileSize-1024L*(long)Number1K) / 128L);
  90.       if(128L*Number128+1024*Number1K < FileSize) Number128++;
  91.       sprintf(Temp,"%d 1024 & %d 128 byte packets",Number1K,Number128);
  92.       WriteMsg(Temp);
  93.      }
  94.  else
  95.      {/* empty file */
  96.       Number128 = 0;
  97.       Number1K = 0;
  98.       /*WriteMsg("Empty File");*/
  99.      }
  100.  /* clear comm port ( there may be several NAKs queued up ) */
  101.  SioRxClear(Port);
  102.  /* get receivers start up NAK, 'C', or 'G' */
  103.  if(!TxStartup(Port,&NCGchar))
  104.    {RestorePSL(Port);
  105.     return(FALSE);
  106.    }
  107.  /* loop over all packets */
  108.  SioDelay(ONE_SECOND/4);
  109.  if(BatchFlag) FirstPacket = 0;
  110.  else FirstPacket = 1;
  111.  Tics = SioTimer();
  112.  for(p=FirstPacket;p<=Number1K+Number128;p++)
  113.        {/* user aborts ? */
  114.         if(kbhit()) if((char)getch()==ABORT_CHAR)
  115.           {TxCAN(Port);
  116.            WriteMsg("Aborted by USER");
  117.            RestorePSL(Port);
  118.            return(FALSE);
  119.           }
  120.         /* issue message */
  121.         sprintf(Temp,"Packet %d",p);
  122.         WriteMsg(Temp);
  123.         /* load up Buffer */
  124.         if(p==0)
  125.               {/* Filename packet ! */
  126.                PacketSize = 128;
  127.                k = 0;
  128.                for(i=0;i<strlen(Filename);i++) Buffer[k++] = Filename[i];
  129.                Buffer[k++] = '\0';
  130.                sprintf(Temp,"%ld",FileSize);
  131.                for(i=0;i<strlen(Temp);i++) Buffer[k++] = Temp[i];
  132.                while(k<128) Buffer[k++] = '\0';
  133.               }
  134.         else /* p > 0 */
  135.               {/* DATA Packet: use 1K or 128 byte block ? */
  136.                if(p<=Number1K) PacketSize = 1024;
  137.                else PacketSize = 128;
  138.                /* read next block from disk */
  139.                Code = read(Handle,Buffer,PacketSize);
  140.                if(Code<=0)
  141.                      {SayError(Port,"Error on disk read");
  142.                       RestorePSL(Port);
  143.                       return(FALSE);
  144.                      }
  145.                for(i=Code;i<PacketSize;i++) Buffer[i] = 0x1a;
  146.               }
  147.         /* send this packet */
  148.         if(!TxPacket(Port,p,PacketSize,Buffer,NCGchar))
  149.            {RestorePSL(Port);
  150.             return(FALSE);
  151.            }
  152.         /* must 'restart' after non null packet 0 */
  153.         if(!EmptyFlag&&(p==0)) TxStartup(Port,&NCGchar);
  154.        } /* end -- for(p) */
  155.   WriteCPS(Tics,FileSize,Filename,FALSE);
  156.  /* done if empty packet 0 */
  157.  if(EmptyFlag)
  158.         {WriteMsg("Batch transfer complete");
  159.          RestorePSL(Port);
  160.          return(TRUE);
  161.         }
  162.  /* all done. send EOT up to 10 times */
  163.  close(Handle);
  164.  if(!TxEOT(Port))
  165.      {SayError(Port,"EOT not acknowledged");
  166.       RestorePSL(Port);
  167.       return(FALSE);
  168.      }
  169.  WriteMsg("Transfer Complete");
  170.  RestorePSL(Port);
  171.  return(TRUE);
  172. } /* end -- TxyModem */
  173.  
  174. int RxyModem(
  175.    int Port,          /* COM port [0..3] */
  176.    char *Filename,    /* filename buffer */
  177.    char *Buffer,      /* data buffer */
  178.    char NCGparm,      /* NAK, 'C', or 'G' */
  179.    int BatchFlag)     /* if TRUE, get filename from packet 0 */
  180. {int  i;
  181.  int  Handle;         /* file Handle */
  182.  int  p;              /* packet index */
  183.  int  Code;           /* return code */
  184.  int  FirstPacket;
  185.  char PacketNbr;
  186.  int  PacketSize;     /* 128 or 1024 */
  187.  long FileSize = 0;
  188.  long BytesRX = 0;
  189.  long BytesWanted;
  190.  char Temp[81];
  191.  long Tics;
  192.  int  EOTflag = FALSE;
  193.  char NCGchar;
  194.  /* begin */
  195.  NCGchar = NCGparm;
  196.  Set8N1(Port);
  197.  EOTflag = FALSE;
  198.  WriteMsg("XYMODEM Receive: Waiting for Sender ");
  199.  while(kbhit()) getch();
  200.  /* clear comm port */
  201.  SioRxClear(Port);
  202.  /* Send NAKs, 'C's, or 'G's */
  203.  if(!RxStartup(Port,&NCGchar))
  204.     {RestorePSL(Port);
  205.      return(FALSE);
  206.     }
  207.  /* open file unless BatchFlag is on */
  208.  if(BatchFlag) FirstPacket = 0;
  209.  else
  210.      {/* start with packet 1 */
  211.       FirstPacket = 1;
  212.       /* open file passed in Filename[] for write */
  213.       Handle = open(Filename,O_CREAT|O_TRUNC|O_WRONLY|O_BINARY,S_IWRITE);
  214.       if(Handle<0)
  215.           {strcpy(Temp,"Cannot open ");
  216.            strcat(Temp,Filename);
  217.            WriteMsg(Temp);
  218.            RestorePSL(Port);
  219.            return(FALSE);
  220.           }
  221.      }
  222.  Tics = SioTimer();
  223.  /* get each packet in turn */
  224.  for(p=FirstPacket;;p++)
  225.      {/* user aborts ? */
  226.       if(kbhit()) if((char)getch()==ABORT_CHAR)
  227.         {TxCAN(Port);
  228.          RestorePSL(Port);
  229.          return(FALSE);
  230.         }
  231.       /* issue message */
  232.       sprintf(Temp,"Packet %d",p);
  233.       WriteMsg(Temp);
  234.       /* get next packet */
  235.       if(!RxPacket(Port,p,&PacketSize,Buffer,NCGchar,&EOTflag))
  236.          {RestorePSL(Port);
  237.           return(FALSE);
  238.          }
  239.       if(p==0)
  240.          {/* copy Filename */
  241.           strcpy(Filename,Buffer);
  242.           /* done if null packet 0 */
  243.           if(Filename[0]=='\0')
  244.              {WriteMsg("Batch Transfer Complete");
  245.               RestorePSL(Port);
  246.               return(TRUE);
  247.              }
  248.         }
  249.       BytesRX += (long)PacketSize;
  250.       /* all done if EOT was received */
  251.       if(EOTflag)
  252.          {
  253.           if(FileSize>0L) BytesRX = FileSize;
  254.           WriteCPS(Tics,BytesRX,Filename,FALSE);
  255.           close(Handle);
  256.           WriteMsg("Transfer Complete");
  257.           RestorePSL(Port);
  258.           return(TRUE);
  259.          }
  260.       /* process packet */
  261.       if(p==0)
  262.          {/* open file using filename in packet 0 */
  263.           Handle = open(Filename,O_CREAT|O_TRUNC|O_WRONLY|O_BINARY,S_IWRITE);
  264.           if(Handle<0)
  265.              {strcat(Buffer," -- open failed");
  266.               WriteMsg(Buffer);
  267.               RestorePSL(Port);
  268.               return(FALSE);
  269.              }
  270.            /* get file length */
  271.            FileSize = atol(&Buffer[1+strlen(Buffer)]);
  272.            BytesWanted = FileSize;
  273.            /* must 'restart' after packet 0 */
  274.            RxStartup(Port,&NCGchar);
  275.           }
  276.       else /* DATA packet */
  277.           {/* write Buffer */
  278.            if(BatchFlag)
  279.               {if(BytesWanted<(long)PacketSize) i = (int) BytesWanted;
  280.                else i = PacketSize;
  281.                i = write(Handle,Buffer,i);
  282.                BytesWanted -= (long)i;
  283.               }
  284.            else write(Handle,Buffer,PacketSize);
  285.           } /* end -- else */
  286.      } /* end -- for(p) */
  287. } /* end - RxyModem */
  288.  
  289. int TxCAN(int Port)
  290. {int i;
  291.  for(i=0;i<6;i++) SioPutc(Port,CAN);
  292.  return(0);
  293. }
  294.  
  295. /* XMODEM send */
  296.  
  297. void XmodemTx(int Port,char *FileName,char *Buffer,int OneKflag)
  298. {if(!FetchName(FileName)) return;
  299.  TxyModem(Port,FileName,Buffer,OneKflag,FALSE);
  300. }
  301.  
  302. /* XMODEM receive */
  303.  
  304. void XmodemRx(int Port,char *FileName,char *Buffer,char NCGchar)
  305. {if(!FetchName(FileName)) return;
  306.  RxyModem(Port,FileName,Buffer,NCGchar,FALSE);
  307. }
  308.  
  309. /* YMODEM send */
  310.  
  311. void YmodemTx(int Port,char *FileSpec,char *Buffer)
  312. {char FileName[15];
  313.  if(!FetchName(FileSpec)) return;
  314.  if(FindFirst(FileSpec,FileName,NULL))
  315.    {TxyModem(Port,FileName,Buffer,TRUE,TRUE);
  316.     while(FindNext(FileName,NULL))
  317.       {SioDelay(1);
  318.        TxyModem(Port,FileName,Buffer,TRUE,TRUE);
  319.       }
  320.    }
  321.  /* send empty filename */
  322.  FileName[0] = '\0';
  323.  SioDelay(1);
  324.  TxyModem(Port,FileName,Buffer,TRUE,TRUE);
  325. }
  326.  
  327. /* YMODEM receive */
  328.  
  329. void YmodemRx(int Port,char *Buffer,char NCGchar)
  330. {char FileName[15];
  331.  do
  332.    {/* receive files till get empty filename */
  333.     RxyModem(Port,FileName,Buffer,NCGchar,TRUE);
  334.     if(kbhit()) return;
  335.    } while(FileName[0]!='\0');
  336. }
  337.