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