home *** CD-ROM | disk | FTP | other *** search
- /* xymodem.c */
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <fcntl.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 "xypacket.h"
- #include "xymodem.h"
- #include "dir_io.h"
- #include "timing.h"
-
- #define ABORT_CHAR CAN
-
- #define FALSE 0
- #define TRUE !FALSE
-
-
- static int DataBits = WordLength8;
- static int StopBits = OneStopBit;
- static int Parity = NoParity;
-
- static void Set8N1(int Port)
- {int PSL;
- PSL = SioRead(Port,3);
- DataBits = 0x03 & PSL;
- StopBits = 0x01 & (PSL>>2);
- Parity = 0x07 & (PSL>>3);
- /* set 8N1 */
- SioParms(Port,NoParity,OneStopBit,WordLength8);
- }
-
- static void RestorePSL(int Port)
- {/* restore old setting */
- SioParms(Port,Parity,StopBits,DataBits);
- }
-
- int TxyModem(
- int Port, /* COM port [0..3] */
- char *Filename, /* filename buffer */
- char *Buffer, /* data buffer */
- int OneKflag, /* if TRUE, use 1K blocks when possible */
- int BatchFlag) /* if TRUE, send filename in packet 0 */
- {int i, k;
- int Code;
- int Handle; /* file Handle */
- long Tics;
- char c;
- int p;
- char PacketType;
- char PacketNbr;
- int PacketSize = 128;
- int FirstPacket;
- unsigned short CheckSum;
- int Number1K = 0; /* total # 1K packets */
- int Number128 = 0; /* total # 128 byte packets */
- char NCGchar = NAK;
- long FileSize;
- char Temp[81];
- int EmptyFlag = FALSE;
- /* begin */
- Set8N1(Port);
- if(BatchFlag) if(Filename[0]=='\0') EmptyFlag = TRUE;
- if(!EmptyFlag)
- {/* Filename is not empty */
- EmptyFlag = FALSE;
- Handle = open(Filename,O_RDONLY|O_BINARY,S_IREAD);
- if(Handle<0)
- {strcpy(Temp,"Cannot open ");
- strcat(Temp,Filename);
- WriteMsg(Temp);
- RestorePSL(Port);
- return(FALSE);
- }
- }
- WriteMsg("XYMODEM send: waiting for Receiver ");
- while(kbhit()) getch();
- /* compute # blocks */
- if(!EmptyFlag)
- {FileSize = filelength(Handle);
- if(OneKflag) Number1K = (int) (FileSize / 1024L);
- Number128 = (int) ((FileSize-1024L*(long)Number1K) / 128L);
- if(128L*Number128+1024*Number1K < FileSize) Number128++;
- sprintf(Temp,"%d 1024 & %d 128 byte packets",Number1K,Number128);
- WriteMsg(Temp);
- }
- else
- {/* empty file */
- Number128 = 0;
- Number1K = 0;
- /*WriteMsg("Empty File");*/
- }
- /* clear comm port ( there may be several NAKs queued up ) */
- SioRxClear(Port);
- /* get receivers start up NAK, 'C', or 'G' */
- if(!TxStartup(Port,&NCGchar))
- {RestorePSL(Port);
- return(FALSE);
- }
- /* loop over all packets */
- SioDelay(ONE_SECOND/4);
- if(BatchFlag) FirstPacket = 0;
- else FirstPacket = 1;
- Tics = SioTimer();
- for(p=FirstPacket;p<=Number1K+Number128;p++)
- {/* user aborts ? */
- if(kbhit()) if((char)getch()==ABORT_CHAR)
- {TxCAN(Port);
- WriteMsg("Aborted by USER");
- RestorePSL(Port);
- return(FALSE);
- }
- /* issue message */
- sprintf(Temp,"Packet %d",p);
- WriteMsg(Temp);
- /* load up Buffer */
- if(p==0)
- {/* Filename packet ! */
- PacketSize = 128;
- k = 0;
- for(i=0;i<strlen(Filename);i++) Buffer[k++] = Filename[i];
- Buffer[k++] = '\0';
- sprintf(Temp,"%ld",FileSize);
- for(i=0;i<strlen(Temp);i++) Buffer[k++] = Temp[i];
- while(k<128) Buffer[k++] = '\0';
- }
- else /* p > 0 */
- {/* DATA Packet: use 1K or 128 byte block ? */
- if(p<=Number1K) PacketSize = 1024;
- else PacketSize = 128;
- /* read next block from disk */
- Code = read(Handle,Buffer,PacketSize);
- if(Code<=0)
- {SayError(Port,"Error on disk read");
- RestorePSL(Port);
- return(FALSE);
- }
- for(i=Code;i<PacketSize;i++) Buffer[i] = 0x1a;
- }
- /* send this packet */
- if(!TxPacket(Port,p,PacketSize,Buffer,NCGchar))
- {RestorePSL(Port);
- return(FALSE);
- }
- /* must 'restart' after non null packet 0 */
- if(!EmptyFlag&&(p==0)) TxStartup(Port,&NCGchar);
- } /* end -- for(p) */
- WriteCPS(Tics,FileSize,Filename,FALSE);
- /* done if empty packet 0 */
- if(EmptyFlag)
- {WriteMsg("Batch transfer complete");
- RestorePSL(Port);
- return(TRUE);
- }
- /* all done. send EOT up to 10 times */
- close(Handle);
- if(!TxEOT(Port))
- {SayError(Port,"EOT not acknowledged");
- RestorePSL(Port);
- return(FALSE);
- }
- WriteMsg("Transfer Complete");
- RestorePSL(Port);
- return(TRUE);
- } /* end -- TxyModem */
-
- int RxyModem(
- int Port, /* COM port [0..3] */
- char *Filename, /* filename buffer */
- char *Buffer, /* data buffer */
- char NCGparm, /* NAK, 'C', or 'G' */
- int BatchFlag) /* if TRUE, get filename from packet 0 */
- {int i;
- int Handle; /* file Handle */
- int p; /* packet index */
- int Code; /* return code */
- int FirstPacket;
- char PacketNbr;
- int PacketSize; /* 128 or 1024 */
- long FileSize = 0;
- long BytesRX = 0;
- long BytesWanted;
- char Temp[81];
- long Tics;
- int EOTflag = FALSE;
- char NCGchar;
- /* begin */
- NCGchar = NCGparm;
- Set8N1(Port);
- EOTflag = FALSE;
- WriteMsg("XYMODEM Receive: Waiting for Sender ");
- while(kbhit()) getch();
- /* clear comm port */
- SioRxClear(Port);
- /* Send NAKs, 'C's, or 'G's */
- if(!RxStartup(Port,&NCGchar))
- {RestorePSL(Port);
- return(FALSE);
- }
- /* open file unless BatchFlag is on */
- if(BatchFlag) FirstPacket = 0;
- else
- {/* start with packet 1 */
- FirstPacket = 1;
- /* open file passed in Filename[] for write */
- 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);
- RestorePSL(Port);
- return(FALSE);
- }
- }
- Tics = SioTimer();
- /* get each packet in turn */
- for(p=FirstPacket;;p++)
- {/* user aborts ? */
- if(kbhit()) if((char)getch()==ABORT_CHAR)
- {TxCAN(Port);
- RestorePSL(Port);
- return(FALSE);
- }
- /* issue message */
- sprintf(Temp,"Packet %d",p);
- WriteMsg(Temp);
- /* get next packet */
- if(!RxPacket(Port,p,&PacketSize,Buffer,NCGchar,&EOTflag))
- {RestorePSL(Port);
- return(FALSE);
- }
- if(p==0)
- {/* copy Filename */
- strcpy(Filename,Buffer);
- /* done if null packet 0 */
- if(Filename[0]=='\0')
- {WriteMsg("Batch Transfer Complete");
- RestorePSL(Port);
- return(TRUE);
- }
- }
- BytesRX += (long)PacketSize;
- /* all done if EOT was received */
- if(EOTflag)
- {
- if(FileSize>0L) BytesRX = FileSize;
- WriteCPS(Tics,BytesRX,Filename,FALSE);
- close(Handle);
- WriteMsg("Transfer Complete");
- RestorePSL(Port);
- return(TRUE);
- }
- /* process packet */
- if(p==0)
- {/* open file using filename in packet 0 */
- Handle = open(Filename,O_CREAT|O_TRUNC|O_WRONLY|O_BINARY,S_IWRITE);
- if(Handle<0)
- {strcat(Buffer," -- open failed");
- WriteMsg(Buffer);
- RestorePSL(Port);
- return(FALSE);
- }
- /* get file length */
- FileSize = atol(&Buffer[1+strlen(Buffer)]);
- BytesWanted = FileSize;
- /* must 'restart' after packet 0 */
- RxStartup(Port,&NCGchar);
- }
- else /* DATA packet */
- {/* write Buffer */
- if(BatchFlag)
- {if(BytesWanted<(long)PacketSize) i = (int) BytesWanted;
- else i = PacketSize;
- i = write(Handle,Buffer,i);
- BytesWanted -= (long)i;
- }
- else write(Handle,Buffer,PacketSize);
- } /* end -- else */
- } /* end -- for(p) */
- } /* end - RxyModem */
-
- int TxCAN(int Port)
- {int i;
- for(i=0;i<6;i++) SioPutc(Port,CAN);
- return(0);
- }
-
- /* XMODEM send */
-
- void XmodemTx(int Port,char *FileName,char *Buffer,int OneKflag)
- {if(!FetchName(FileName)) return;
- TxyModem(Port,FileName,Buffer,OneKflag,FALSE);
- }
-
- /* XMODEM receive */
-
- void XmodemRx(int Port,char *FileName,char *Buffer,char NCGchar)
- {if(!FetchName(FileName)) return;
- RxyModem(Port,FileName,Buffer,NCGchar,FALSE);
- }
-
- /* YMODEM send */
-
- void YmodemTx(int Port,char *FileSpec,char *Buffer)
- {char FileName[15];
- if(!FetchName(FileSpec)) return;
- if(FindFirst(FileSpec,FileName,NULL))
- {TxyModem(Port,FileName,Buffer,TRUE,TRUE);
- while(FindNext(FileName,NULL))
- {SioDelay(1);
- TxyModem(Port,FileName,Buffer,TRUE,TRUE);
- }
- }
- /* send empty filename */
- FileName[0] = '\0';
- SioDelay(1);
- TxyModem(Port,FileName,Buffer,TRUE,TRUE);
- }
-
- /* YMODEM receive */
-
- void YmodemRx(int Port,char *Buffer,char NCGchar)
- {char FileName[15];
- do
- {/* receive files till get empty filename */
- RxyModem(Port,FileName,Buffer,NCGchar,TRUE);
- if(kbhit()) return;
- } while(FileName[0]!='\0');
- }