/************************************************************* * vt100 terminal emulator - XMODEM protocol support * v1.0 DBW 860621 Dave Wecker *************************************************************/ #define MODULE_XMODEM 1 #include "vt100.h" /************************************************************ * Send a string (using sendchar below) ************************************************************/ sendstring(s) char *s; { char c; while ((c = *s++) != '\000') sendchar(c); } /**************************************************************/ /* send char and read char functions for the xmodem function */ /************************************************************/ sendchar(ch) int ch; { rs_out[0] = ch; DoIO(Write_Request); } readchar() { unsigned char c; int rd,ch; rd = FALSE; while (rd == FALSE) { Wait((1L << Read_Request->IOSer.io_Message.mn_ReplyPort->mp_SigBit) | ( 1L << mywindow->UserPort->mp_SigBit)); if(CheckIO(Read_Request)) { WaitIO(Read_Request); ch=rs_in[0]; rd = TRUE; BeginIO(Read_Request); } if (NewMessage=(struct IntuiMessage *)GetMsg(mywindow->UserPort)) if ((NewMessage->Class) == RAWKEY) if ((NewMessage->Code) == 69) { emits("\nUser Cancelled Transfer"); break; } } if (rd == FALSE) { timeout = TRUE; emits("\nTimeout Waiting For Character\n"); } c = ch; return(c); } /**************************************/ /* xmodem send and recieve functions */ /************************************/ XMODEM_Read_File(file) char *file; { int firstchar, sectnum, sectcurr, sectcomp, errors, errorflag, findtype, exe; unsigned int checksum, j, bufptr,i; char numb[10]; bytes_xferred = 0L; if ((fd = creat(file, 0)) < 0) { emits("Cannot Open File\n"); return FALSE; } else emits("Receiving File\n\nType to abort transfer\n"); timeout=FALSE; sectnum = errors = bufptr = 0; findtype = TRUE; exe = FALSE; sendchar(NAK); firstchar = 0; while (firstchar != EOT && errors != ERRORMAX) { errorflag = FALSE; do /* get sync char */ { firstchar = readchar(); if (timeout == TRUE) return FALSE; } while (firstchar != SOH && firstchar != EOT); if (firstchar == SOH) { emits("Getting Block "); sprintf(numb, "%d", sectnum); emits(numb); emits("..."); sectcurr = readchar(); if (timeout == TRUE) return FALSE; sectcomp = readchar(); if (timeout == TRUE) return FALSE; if ((sectcurr + sectcomp) == 255) { if (sectcurr == (sectnum + 1 & 0xff)) { checksum = 0; for (j = bufptr; j < (bufptr + SECSIZ); j++) { bufr[j] = readchar(); if (findtype && sectcurr == 1 && j == 3) { findtype = FALSE; if (bufr[0] == 0x00 && bufr[1] == 0x00 && bufr[2] == 0x03 && bufr[3] == 0xF3) exe = TRUE; } if (timeout == TRUE) return FALSE; checksum = (checksum + bufr[j]) & 0xff; } if (checksum == readchar()) { errors = 0; sectnum++; bufptr += SECSIZ; bytes_xferred += SECSIZ; emits("verified\n"); if (bufptr == BufSize) { if (write(fd, bufr, BufSize-128) == EOF) { emits("\nError Writing File\n"); return FALSE; } bufptr = 128; for (j = 0; j < 128; j++) bufr[j] = bufr[(BufSize-128)+j]; } sendchar(ACK); } else { errorflag = TRUE; if (timeout == TRUE) return FALSE; } } else { if (sectcurr == (sectnum & 0xff)) { emits("\nReceived Duplicate Sector\n"); sendchar(ACK); } else errorflag = TRUE; } } else errorflag = TRUE; } if (errorflag == TRUE) { errors++; emits("\nError\n"); sendchar(NAK); } } /* end while */ if ((firstchar == EOT) && (errors < ERRORMAX)) { sendchar(ACK); if (exe) while (bufr[--bufptr] != 0xF2) ; else while (bufr[--bufptr] == 0) ; write(fd, bufr, ++bufptr); close(fd); return TRUE; } return FALSE; } XMODEM_Send_File(file) char *file; { int sectnum, bytes_to_send, size, attempts, c, i; unsigned checksum, j, bufptr; char numb[10]; timeout=FALSE; bytes_xferred = 0; if ((fd = open(file, 0)) < 0) { emits("Cannot Open Send File\n"); return FALSE; } else emits("Sending File\n\nType to abort transfer\n"); attempts = 0; sectnum = 1; /* wait for sync char */ j=1; while (((c = readchar()) != NAK) && (j++ < ERRORMAX)); if (j >= (ERRORMAX)) { emits("\nReceiver not sending NAKs\n"); return FALSE; } while ((bytes_to_send = read(fd, bufr, BufSize)) && attempts != RETRYMAX) { if (bytes_to_send == EOF) { emits("\nError Reading File\n"); return FALSE; } bufptr = 0; while (bytes_to_send > 0 && attempts != RETRYMAX) { attempts = 0; do { sendchar(SOH); sendchar(sectnum); sendchar(~sectnum); checksum = 0; size = SECSIZ <= bytes_to_send ? SECSIZ : bytes_to_send; bytes_to_send -= size; for (j = bufptr; j < (bufptr + SECSIZ); j++) if (j < (bufptr + size)) { sendchar(bufr[j]); checksum += bufr[j]; } else { sendchar(0); } sendchar(checksum & 0xff); attempts++; c = readchar(); if (timeout == TRUE) return FALSE; } while ((c != ACK) && (attempts != RETRYMAX)); bufptr += size; bytes_xferred += size; emits("Block "); sprintf(numb, "%d", sectnum); emits(numb); emits(" sent\n"); sectnum++; } } close(fd); if (attempts == RETRYMAX) { emits("\nNo Acknowledgment Of Sector, Aborting\n"); return FALSE; } else { attempts = 0; do { sendchar(EOT); attempts++; } while ((readchar() != ACK) && (attempts != RETRYMAX) && (timeout == FALSE)); if (attempts == RETRYMAX) emits("\nNo Acknowledgment Of End Of File\n"); } return TRUE; }